📄 play_multiple_audio.c
字号:
#define DELTA_PTS 100 // 1 sec #define CONTIGUOUS_LENGHT 0x100000 // 1 MB RMuint32 dataType = 0; RMbool SetPTS = FALSE; RMbool SendPTS = FALSE; RMbool SendData = FALSE; RMuint32 PrevMON = 0; RMuint32 decoder = 0; // dummy init RMbool *seeking = &(pSendContext->SeekVideo); RMuint32 *previousMON = &(pSendContext->PrevVideoMON); if (pSendContext->ignoreCallback) { if (pSendContext->cmd == RM_QUIT) { RMDBGLOG((ENABLE, "callback called when 'quit' command was issued\n")); goto return_from_callback; } if (pSendContext->cmd == RM_STOP) { RMDBGLOG((ENABLE, "callback called when 'stop' command was issued\n")); goto return_from_callback; } if (pSendContext->cmd == RM_STOP_SEEK_ZERO) { RMDBGLOG((ENABLE, "callback called when 'seekzero' command was issued\n")); goto return_from_callback; } if ((pSendContext->dcc_info->state == RM_PLAYING_TRICKMODE) && ((pSendContext->dcc_info->trickmode_id == RM_TRICKMODE_FWD_IFRAME) || (pSendContext->dcc_info->trickmode_id == RM_TRICKMODE_RWD_IFRAME)) ) { RMDBGLOG((ENABLE, "callback called when 'iframe' command was issued\n")); goto return_from_callback; } if ((pSendContext->cmd == RM_SEEK) && (pSendContext->dcc_info->seek_supported)) { RMDBGLOG((ENABLE, "callback called when 'seek' command was issued\n")); goto return_from_callback; } RMDBGLOG((ENABLE, "********** ignoring Callback!! *********\n")); goto return_from_callback; } if (pSendContext->drmError != 0) { RMDBGLOG((ENABLE, "there was a decryption error, callback ignored\n")); goto return_from_callback; } if ((pSendContext->isContentEncrypted) && (bytes_left != 0)) RMDBGLOG((ENABLE, "non aligned read, offset %ld!\n", bytes_left)); RMDBGLOG((PAYLOADDBG,"ST:%02d,MON:%04d,Key:%01d,time:%05d.%03d, size:%05d, left:%05d, offset:%05d \n", (int)Stream_Number, (int)Media_Object_Number, (int)Is_Key_Frame, (int)(Presentation_Time/1000), (int)(Presentation_Time%1000), (int)size, (int)bytes_left, (int)Offset_Into_Media_Object)); if (Stream_Number == pSendContext->video_stream_index) dataType = RM_STREAM_VIDEO; else if (Stream_Number == pSendContext->audio_stream_index) dataType = RM_STREAM_AUDIO; else goto return_from_callback; // Decrypt packet, if necessary if (pSendContext->isContentEncrypted) { if ((pSendContext->drmError = WMDRM_decrypt_packet(buf, size)) != 0) { RMASFVDemuxSetDRMError(pSendContext->vASFDemux, pSendContext->drmError); RMDBGLOG((ENABLE, "DECRYPTION FAILED\n")); goto return_from_callback; } } /* adjust PTS if necessary */ if ((pSendContext->PrerollSET) && (pSendContext->Preroll)) { RMDBGLOG((DISABLE, "pts %llu, adjusted pts %llu\n", (RMuint64)Presentation_Time, (RMuint64)Presentation_Time - pSendContext->Preroll)); Presentation_Time = Presentation_Time - (RMuint32)pSendContext->Preroll; } /* accurate audio seek, required for WMA FFWD trickmode */ if (dataType == RM_STREAM_AUDIO) { if (pSendContext->accurateAudioSeekTo > (RMuint64)Presentation_Time) { RMDBGLOG((ENABLE, "skipping audio %lu < %llu\n", Presentation_Time, pSendContext->accurateAudioSeekTo)); goto return_from_callback; } else if (pSendContext->accurateAudioSeekTo != 0) { RMDBGLOG((ENABLE, "start sending audio %lu\n", Presentation_Time)); pSendContext->accurateAudioSeekTo = 0; } } switch (dataType) { case RM_STREAM_VIDEO: { if (!pSendContext->SendVideoData) goto return_from_callback; SendPTS = pSendContext->SendVideoPts; PrevMON = pSendContext->prev_video_media_object_number; pSendContext->VideoByteCounter += size; pSendContext->prev_video_media_object_number = Media_Object_Number; decoder = pSendContext->dcc_info->video_decoder; SendData = TRUE; seeking = &(pSendContext->SeekVideo); previousMON = &(pSendContext->PrevVideoMON); break; } case RM_STREAM_AUDIO: { if (!pSendContext->SendAudioData) goto return_from_callback; SendPTS = pSendContext->SendAudioPts; PrevMON = pSendContext->prev_audio_media_object_number; decoder = pSendContext->dcc_info->audio_decoder; if (!pSendContext->compressed_audio) pSendContext->AudioByteCounter += size; pSendContext->prev_audio_media_object_number = Media_Object_Number; Is_Key_Frame = 1; seeking = &(pSendContext->SeekAudio); previousMON = &(pSendContext->PrevAudioMON); SendData = ((pSendContext->compressed_audio) || (pSendContext->dcc_info->state == RM_PLAYING_TRICKMODE)) ? FALSE : TRUE; if (pSendContext->dcc_info->state != RM_PLAYING_TRICKMODE) { if (ResyncAudio(pSendContext, Presentation_Time) == RM_SKIP_TO_RESYNC) goto return_from_callback; if (pSendContext->dcc_info->state == RM_AUDIO_STREAM_CHANGE) { RMbool status; status = SwitchAudio(pSendContext, Media_Object_Number); if (status == TRUE) goto return_from_callback; } } break; } } if (*seeking) { if ((Is_Key_Frame) && (Offset_Into_Media_Object == 0)) { RMDBGLOG((ENABLE, ">>first %s payload after a seek, MON %lu, size %ld, pts %lu\n", (dataType == RM_STREAM_VIDEO) ? "video":"audio", Media_Object_Number, size, Presentation_Time)); *previousMON = Media_Object_Number; SetPTS = TRUE; } else goto return_from_callback; *seeking = FALSE; } if ((pSendContext->isIFrameMode) && (dataType == RM_STREAM_VIDEO)) { switch (pSendContext->IFrameFSMState) { case RMasfIFrameFSM_Disabled: { break; } case RMasfIFrameFSM_Init: { if ((Is_Key_Frame) && (Offset_Into_Media_Object == 0)) { RMDBGLOG((TRICKDBG, ">>this payload will be sent, MON %lu, size %ld\n", Media_Object_Number, size)); pSendContext->PrevVideoMON = Media_Object_Number; pSendContext->IFrameFSMState = RMasfIFrameFSM_WaitIFrameMONChange; SetPTS = TRUE; } else { RMDBGLOG((TRICKDBG, "++skip payload MON %lu, size %ld until KEY & OFF=0\n", Media_Object_Number, size)); goto return_from_callback; } break; } case RMasfIFrameFSM_WaitIFrameMONChange: { if (pSendContext->PrevVideoMON != Media_Object_Number) { RMDBGLOG((TRICKDBG,"++skipping video because IFrame MON(%lu) changed to %lu, size %lu\n", pSendContext->PrevVideoMON, Media_Object_Number, size)); pSendContext->IFrameFSMState = RMasfIFrameFSM_SkipNext; goto return_from_callback; } break; } case RMasfIFrameFSM_SkipNext: { RMDBGLOG((TRICKDBG,"++skippingNEXT video because IFrame MON(%lu) changed to %lu, size %lu\n", pSendContext->PrevVideoMON, Media_Object_Number, size)); goto return_from_callback; break; } default: { goto return_from_callback; } } } else if (pSendContext->isIFrameMode) { // skip all other streams goto return_from_callback; } RMDBGLOG((DISABLE, "prevMON %s is %lu pts %lu\n", (dataType == RM_STREAM_VIDEO) ? "video":"audio", PrevMON, Presentation_Time)); // do not resend pts at each subpacket if ( ((Media_Object_Number_valid && (Media_Object_Number != PrevMON)) || (SetPTS)) && (SendPTS) ) { Info.ValidFields = TIME_STAMP_INFO; Info.TimeStamp = Presentation_Time; pInfo = &Info; size_info = sizeof(Info); if (dataType == RM_STREAM_VIDEO) { pSendContext->video_last_pts = Presentation_Time; pSendContext->video_time_stamp = Presentation_Time; } else if (dataType == RM_STREAM_AUDIO) pSendContext->audio_time_stamp = Presentation_Time; if ( pSendContext->FirstSystemTimeStamp ) { pSendContext->min_diff = 0; pSendContext->max_diff = 0; if (dataType == RM_STREAM_VIDEO) pSendContext->audio_time_stamp = pSendContext->video_time_stamp; else pSendContext->video_time_stamp = pSendContext->audio_time_stamp; } if (!pSendContext->isAudioOnlyFile) { diff = pSendContext->video_time_stamp - pSendContext->audio_time_stamp; RMDBGLOG((DISABLE, "diff %lu\n", diff)); if ( (diff < -DELTA_PTS) || (diff > DELTA_PTS)) { if ( (diff > 0) && (diff > pSendContext->max_diff+100) ) { pSendContext->max_diff = diff; if(pSendContext->dcc_info->trickmode_id == RM_NO_TRICKMODE) RMDBGLOG((ENABLE, " %ld\n", diff)); } if ( (diff < 0) && (diff < pSendContext->min_diff-100) ) { pSendContext->min_diff = diff; if(pSendContext->dcc_info->trickmode_id == RM_NO_TRICKMODE) RMDBGLOG((ENABLE, " %ld\n", diff)); } } } } else { pInfo = NULL; size_info = 0; } if ( pSendContext->FirstSystemTimeStamp && pInfo && (pInfo->ValidFields & TIME_STAMP_INFO) && (pSendContext->dcc_info->state != RM_PLAYING_TRICKMODE)) { if (!pSendContext->PrerollSET) { if (pSendContext->Preroll) { if (pInfo->TimeStamp < pSendContext->Preroll) { RMDBGLOG((ENABLE, "First PTS (%llu) < Preroll (%llu), adjusting Preroll to %llu so first PTS=0\n", pInfo->TimeStamp, pSendContext->Preroll, pInfo->TimeStamp)); pSendContext->Preroll = pInfo->TimeStamp; pInfo->TimeStamp = 0; } else { RMDBGLOG((ENABLE, "Preroll is %llu, First PTS %llu needs to be adjusted to %llu\n", pSendContext->Preroll, pInfo->TimeStamp, pInfo->TimeStamp - pSendContext->Preroll)); pInfo->TimeStamp -= pSendContext->Preroll; } pSendContext->PrerollSET = TRUE; } } RMDBGLOG((ENABLE, "FirstSystemTimeStamp for %s = %llu(0x%llx) at %ld/sec\n", dataType == RM_STREAM_VIDEO ? "video":"audio", pInfo->TimeStamp, pInfo->TimeStamp, pSendContext->video_vop_tir)); if(pSendContext->compressed_audio) { RMint64 firstPTS = (RMint64)pInfo->TimeStamp + (RMint64)pSendContext->start_ms - (RMint64)(pSendContext->video_vop_tir>>5); RMDBGLOG((ENABLE, "Set STC at least %ld clicks before PTS for WMAPRO decoding (video)\n", pSendContext->video_vop_tir>>5)); RMDBGLOG((ENABLE, "firstPTS %lld %s\n", firstPTS, (firstPTS < 0) ? ">>> timer is negative!":"")); DCCSTCSetTime(pSendContext->dcc_info->pStcSource, RMmax(0, (RMuint64)firstPTS), pSendContext->video_vop_tir); } else { RMint64 firstPTS = (RMint64)pInfo->TimeStamp + (RMint64)pSendContext->start_ms - (RMint64)300; RMDBGLOG((ENABLE, "timer will be set to %lld %s\n", firstPTS, (firstPTS < 0) ? ">>> timer is negative!":"")); DCCSTCSetTime(pSendContext->dcc_info->pStcSource, RMmax(0, (RMuint64)firstPTS), pSendContext->video_vop_tir); //DCCSTCSetTime(pSendContext->dcc_info->pStcSource, pInfo->TimeStamp + pSendContext->start_ms, pSendContext->video_vop_tir); } DCCSTCPlay(pSendContext->dcc_info->pStcSource); pSendContext->FirstSystemTimeStamp = FALSE; RMDBGLOG((ENABLE, "vpts-apts[ms]= 0\n")); } if ((pSendContext->CurrentDisplayPTS) && (pSendContext->IFrameDirection > 0) && (dataType == RM_STREAM_VIDEO)) { if ((Presentation_Time >= pSendContext->CurrentDisplayPTS) && (Is_Key_Frame) && (Offset_Into_Media_Object == 0)) { pSendContext->CurrentDisplayPTS = 0; pSendContext->SeekAudio = TRUE; pSendContext->IgnoreAudio = FALSE; RMDBGLOG((PAYLOADDBG, "will send video MON=%lu, size=%lu, pts=%lu %s, %lu\n", Media_Object_Number, size, Presentation_Time, Is_Key_Frame == 1 ? "key":"", Offset_Into_Media_Object)); } else { RMDBGLOG((PAYLOADDBG, "dropping video frame MON=%lu, size=%lu, pts=%lu < DisplayPTS(%llu), %s, %lu\n", Media_Object_Number, size, Presentation_Time, pSendContext->CurrentDisplayPTS, Is_Key_Frame == 1 ? "key":"", Offset_Into_Media_Object)); pSendContext->IgnoreAudio = TRUE; goto return_from_callback; } } if ((pSendContext->CurrentDisplayPTS) && (dataType == RM_STREAM_AUDIO)) { if ((Presentation_Time >= pSendContext->CurrentDisplayPTS) && (Is_Key_Frame) && (Offset_Into_Media_Object == 0) && (pSendContext->IgnoreAudio == FALSE)) { pSendContext->CurrentDisplayPTS = 0; RMDBGLOG((PAYLOADDBG, "will send audio MON=%lu, size=%lu, pts=%lu %s, %lu\n", Media_Object_Number, size, Presentation_Time, Is_Key_Frame == 1 ? "key":"", Offset_Into_Media_Object)); } else { RMDBGLOG((PAYLOADDBG, "dropping audio frame MON=%lu, size=%lu, pts=%lu < DisplayPTS(%llu)\n", Media_Object_Number, size, Presentation_Time, pSendContext->CurrentDisplayPTS)); goto return_from_callback; } } /* senddata for video and wma audio */ if (SendData) { RMDBGLOG((SENDDBG, "sending MON(%lu) %s, size %lu, pts %llu (%s), %s, %lu\n", Media_Object_Number, dataType == RM_STREAM_VIDEO ? "video":"audio", size, pInfo == NULL ? 0:pInfo->TimeStamp, pInfo == NULL ? "no pts":(pInfo->ValidFields & TIME_STAMP_INFO ? "valid":""), Is_Key_Frame == 1 ? "key":"", Offset_Into_Media_Object)); if (RUASendData(pSendContext->pRUA, decoder, pSendContext->pDMA, buf, size, pInfo, size_info) != RM_OK) { PMAAddEvents(e,&nEvents,RUAEVENT_XFER_FIFO_READY,decoder); fprintf(stderr,"\nWMA send data failed"); } goto callback_end; //callback end } /* wmapro decoding and senddata */ if ((dataType == RM_STREAM_AUDIO) && /*(PlaybackStatus == RM_PSM_Playing) &&*/ (pSendContext->compressed_audio)) { struct wmapro_buffer_info *buf_info; RMuint32 wr1, wr2, size1; while (RMfifo_get_writable_size(pSendContext->wmapro_fifo, &wr1, &size1, &wr2) < sizeof(struct wmapro_buffer_info)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -