📄 asfdemux_callback.c
字号:
struct emhwlib_info PTSInfo; PTSInfo.ValidFields = TIME_STAMP_INFO; PTSInfo.TimeStamp = (RMuint64)Presentation_Time; if ((!pSendContext->isWMAPRO) && (asf_ResyncAudio(pSendContext, &PTSInfo) == RM_SKIP_TO_RESYNC)) goto return_from_callback; if ((pSendContext->actions.asyncCmd == RM_AUDIO_STREAM_CHANGE) && (pSendContext->actions.asyncCmdPending)) { RMbool status; RMDBGLOG((ENABLE, "got async cmd switch audio stream\n")); pSendContext->actions.asyncCmd = RM_NONE; pSendContext->actions.asyncCmdPending = FALSE; status = SwitchAudio(pSendContext, Media_Object_Number); if (status == TRUE) goto return_from_callback; } break; } }#if 0 if (PlaybackStatus == RM_PSM_Paused) { if (SendData) RMDBGLOG((ENABLE, "sending %s data in pause\n", (dataType == RM_STREAM_VIDEO) ? "video":"audio")); else RMDBGLOG((ENABLE, "skip %s data in pause\n", (dataType == RM_STREAM_VIDEO) ? "video":"audio")); }#endif if (((PlaybackStatus == RM_PSM_Slow) || (PlaybackStatus == RM_PSM_Fast)) && (SendData) && (dataType == RM_STREAM_AUDIO) ) { RMDBGLOG((ENABLE, "sending audio while in trickmodes\n")); } 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, pts %lu\n", Media_Object_Number, size, Presentation_Time)); pSendContext->PrevVideoMON = Media_Object_Number; pSendContext->IFrameFSMState = RMasfIFrameFSM_WaitIFrameMONChange; SetPTS = TRUE; } else { RMDBGLOG((TRICKDBG, "++skip payload MON %lu, size %ld until KEY & OFF=0, pts %lu\n", Media_Object_Number, size, Presentation_Time)); 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) { Info.ValidFields = TIME_STAMP_INFO; Info.TimeStamp = (RMuint64)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; pSendContext->lastVideoPTS = 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->VideoStreamFound) { 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(PlaybackStatus == RM_PSM_Playing) RMDBGLOG((ENABLE, " %ld\n", diff)); } if ( (diff < 0) && (diff < pSendContext->min_diff-100) ) { pSendContext->min_diff = diff; if(PlaybackStatus == RM_PSM_Playing) RMDBGLOG((ENABLE, " %ld\n", diff)); } } } } if (!SendPTS) { pInfo = NULL; size_info = 0; } if ((pSendContext->CurrentDisplayPTS) && (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((ENABLE, "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((ENABLE, "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((ENABLE, "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((ENABLE, "dropping audio frame MON=%lu, size=%lu, pts=%lu < DisplayPTS(%llu)\n", Media_Object_Number, size, Presentation_Time, pSendContext->CurrentDisplayPTS)); goto return_from_callback; } } if ( pSendContext->FirstSystemTimeStamp && pInfo && (pInfo->ValidFields & TIME_STAMP_INFO)) { if ( (!pSendContext->PrerollSET) && 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; } }#ifndef WITH_MONO if ((dataType == RM_STREAM_VIDEO) && SendData && pSendContext->play_opt->savems) { RMstatus err; RMuint64 pts = (pInfo == NULL) ? (RMuint64)-1 : pInfo->TimeStamp; RMuint64 dummy; RMuint8 *buffer = (RMuint8*)&dummy; RMuint64ToLeBuf(pts, buffer); err = dump_data_into_file(pSendContext->play_opt, RMVDEMUX_VIDEO, buffer, sizeof(RMuint64), Presentation_Time, Presentation_Time_valid, 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot dump pts data %d\n", err)); goto return_from_callback; } RMDBGLOG((ENABLE, "dumped pts %lld (0x%llx)\n", pts, pts)); }#endif // WITH_MONO if ((pSendContext->audio_vop_tir != 1000) && (dataType == RM_STREAM_AUDIO)) { RMuint64 pts = (pInfo == NULL) ? 0 : pInfo->TimeStamp; RMuint64 scaledPTS; scaledPTS = (pts * pSendContext->audio_vop_tir) / 1000; RMDBGLOG((SENDDBG, "scaling audio pts %llu thru a factor %lu/1000 -> %llu\n", pts, pSendContext->audio_vop_tir, scaledPTS)); if (pInfo) pInfo->TimeStamp = scaledPTS; } if ((pSendContext->video_vop_tir != 1000) && (dataType == RM_STREAM_VIDEO)) { RMuint64 pts = (pInfo == NULL) ? 0 : pInfo->TimeStamp; RMuint64 scaledPTS; scaledPTS = (pts * pSendContext->video_vop_tir) / 1000; RMDBGLOG((SENDDBG, "scaling video pts %llu thru a factor %lu/1000 -> %llu\n", pts, pSendContext->video_vop_tir, scaledPTS)); if (pInfo) pInfo->TimeStamp = scaledPTS; } if ( pSendContext->FirstSystemTimeStamp && pInfo && (pInfo->ValidFields & TIME_STAMP_INFO)) { RMint64 firstPTS = 0; RMuint32 timeScale = (dataType == RM_STREAM_VIDEO) ? pSendContext->video_vop_tir : pSendContext->audio_vop_tir; RMDBGLOG((ENABLE, "FirstSystemTimeStamp for %s = %llu(0x%llx) at %ld/sec = %lu s\n", dataType == RM_STREAM_VIDEO ? "video":"audio", pInfo->TimeStamp, pInfo->TimeStamp, timeScale, (RMuint32)pInfo->TimeStamp / timeScale)); if(pSendContext->isWMAPRO) { //this is correct because wmapro has timescale = 1000 firstPTS = (RMint64)pInfo->TimeStamp + (RMint64)pSendContext->start_ms - (RMint64)(pSendContext->audio_vop_tir>>1); RMDBGLOG((ENABLE, "Set STC at least %ld clicks before PTS for WMAPRO decoding \n", pSendContext->audio_vop_tir>>1)); RMDBGLOG((ENABLE, "firstPTS %lld %s\n", firstPTS, (firstPTS < 0) ? ">>> timer is negative!":"")); } else { RMuint32 startms = (pSendContext->start_ms * timeScale) / 1000; RMuint32 offset = (300 * timeScale) / 1000; firstPTS = (RMint64)pInfo->TimeStamp + (RMint64)startms - (RMint64)offset; 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->stc_offset_ms*((RMint64)(timeScale/1000)), timeScale); pSendContext->FirstSystemTimeStamp = FALSE; RMDBGLOG((ENABLE, "vpts-apts[ms]= 0\n")); } /* senddata for video and wma audio */ if (SendData) {#ifdef CHECK_BUFFER_4_VIDEO int cWait = 0;#endif if (pInfo && (dataType == RM_STREAM_VIDEO)) { RMuint64 diff; diff = (RMuint64)pInfo->TimeStamp - pSendContext->lastVideoPTS; RMDBGLOG((DISABLE, "MON %3lu last pts %8llu current %8llu diff %4llu\n", Media_Object_Number, pSendContext->lastVideoPTS, pInfo->TimeStamp, diff)); pSendContext->lastVideoPTS = pInfo->TimeStamp; } if (PlaybackStatus == RM_PSM_Prebuffering) RMDBGPRINT((ENABLE, "%s", dataType == RM_STREAM_VIDEO ? "v":"a")); RMDBGLOG((SENDDBG, "sending MON(%lu) %s, size %lu, pts %llu = 0x%llx (%s), %s, %lu\n", Media_Object_Number, dataType == RM_STREAM_VIDEO ? "video":"audio", size, pInfo == NULL ? 0:pInfo->TimeStamp, 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 ((Is_Key_Frame) && (!Offset_Into_Media_Object) && (dataType == RM_STREAM_VIDEO)) RMDBGLOG((IFRAMEDBG, "sending video keyframe MON(%lu) size %lu, pts %llu = 0x%llx (%s), %lu\n", Media_Object_Number, size, pInfo == NULL ? 0:pInfo->TimeStamp, pInfo == NULL ? 0:pInfo->TimeStamp, pInfo == NULL ? "no pts" : (pInfo->ValidFields & TIME_STAMP_INFO ? "valid":""), Offset_Into_Media_Object)); // send VC1 start codes if ((dataType == RM_STREAM_VIDEO) && (pSendContext->isVC1)) { if (pSendContext->getStartCodeBuffer) { if (pSendContext->startCodeBuffer) { RMDBGLOG((VC1_STARTCODE_DBG, "releasing startCodeBuffer @0x%08lx, bytes left %lu\n", (RMuint32)pSendContext->startCodeBuffer, pSendContext->startCodeBufferLeft)); RUAReleaseBuffer(pSendContext->pDMA, pSendContext->startCodeBuffer); } while(RUAGetBuffer(pSendContext->pDMA, &(pSendContext->startCodeBuffer), GETBUFFER_TIMEOUT_US) != RM_OK) { RMDBGLOG((ENABLE, "cant get buffer for VC1 startcode\n")); PROCESS_KEY_INCALLBACK(TRUE,FALSE); } pSendContext->startCodeBufferSize = (1 << pSendContext->play_opt->dmapool_log2size); pSendContext->startCodeBufferLeft = (1 << pSendContext->play_opt->dmapool_log2size); RMDBGLOG((VC1_STARTCODE_DBG, "got a new startCodeBuffer @0x%08lx, size %lu\n", (RMuint32)pSendContext->startCodeBuffer, pSendContext->startCodeBufferSize)); pSendContext->getStartCodeBuffer = FALSE; } // check for start code presence in bitstream from ASF if ((buf[0] == 0) && (buf[1] == 0) && (buf[2] == 1)) { if (buf[3] == 0x0F) { // all start codes are already present in the bitstream // dont add any pSendContext->addSeqHeader = FALSE; pSendContext->addEntryHeader = FALSE; pSendContext->addFrameHeader = FALSE; } else if (buf[3] == 0x0E) { // dont add entryHeader nor frameHeader pSendContext->addEntryHeader = FALSE; pSendContext->addFrameHeader = FALSE; } else if (buf[3] == 0x0D) { // dont add frameHeader pSendContext->addFrameHeader = FALSE; } // no start code present, add them (default) } dumpedFrameSize += size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -