play_asf.c
来自「1. 8623L平台」· C语言 代码 · 共 1,567 行 · 第 1/4 页
C
1,567 行
RMDBGLOG((ENABLE, "Should seek to %ld s\n", seekTo)); // must be in milliseconds seekTo *= 1000;#ifndef EM86XX_DEBUG_AUDIO asf_Stop(pSendContext, RM_DEVICES_STC | RM_DEVICES_AUDIO | RM_DEVICES_VIDEO);#endif position = RMASFVDemuxSeek(pSendContext->vASFDemux, &seekTo); if (position == 0) { RMDBGLOG((ENABLE, "seek failed, restarting\n")); RMSeekFile(pSendContext->f_bitstream, pSendContext->asf_Header_Object_Size+50, RM_FILE_SEEK_START); /* presets the demux to start parsing first packet */ RMASFVDemuxResetState(pSendContext->vASFDemux); seekTo = 0; } else RMSeekFile(pSendContext->f_bitstream, position, RM_FILE_SEEK_START); RMGetCurrentPositionOfFile (pSendContext->f_bitstream, &position); RMDBGLOG((ENABLE, "Seeked to %ld s, pos %llu\n", seekTo/1000, position)); pSendContext->FirstSystemTimeStamp = TRUE; if ((pSendContext->isWMAPRO) && (pSendContext->audio_parameters[pSendContext->audio_stream_index].enabled)) { if (pSendContext->vDecoder != NULL) { RMDBGLOG((ENABLE, "close wmapro decoder\n")); RMWMAProVDecoderClose(pSendContext->vDecoder); RMDBGLOG((ENABLE, "open wmapro decoder\n")); RMWMAProVDecoderOpen(pSendContext->vDecoder); } else RMDBGLOG((ENABLE, "no wmapro decoder created!\n")); } pSendContext->IFrameFSMState = RMasfIFrameFSM_Disabled; pSendContext->SeekAudio = TRUE; pSendContext->SeekVideo = TRUE; pSendContext->audioSamplesDropped = FALSE;#ifndef EM86XX_DEBUG_AUDIO /* the stc will be put into "play" mode with the first pts */ asf_Play(pSendContext, RM_DEVICES_AUDIO | RM_DEVICES_VIDEO, DCCVideoPlayFwd);#endif#if 0 { RMstatus err; /* restart recording data after the seek */ RMDBGLOG((ENABLE, "restarting save data\n")); err = close_save_files(pSendContext->play_opt); if (RMFAILED(err)) { fprintf(stderr, "Cannot close files used to save data %d\n", err); return RM_ERROR; } err = open_save_files(pSendContext->play_opt); if (RMFAILED(err)) { fprintf(stderr, "cannot open files to save data %d\n", err); return RM_ERROR; } }#endif return RM_OK;}static RMstatus asf_InitIFrameTrickMode(struct asf_context* pSendContext){ RMstatus err = RM_OK; RMint64 position = 0; RMuint32 size, packet; RMint32 N; RMuint32 M; enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(pSendContext->PSMcontext, &(pSendContext->dcc_info)); DCCSTCGetSpeed(pSendContext->dcc_info->pStcSource, &N, &M); RMDBGLOG((ENABLE, "Init IFrame trickmode, speed is %ld/%lu\n", N, M)); if (PlaybackStatus == RM_PSM_IForward) pSendContext->IFrameDirection = 1; else if (PlaybackStatus == RM_PSM_IRewind) pSendContext->IFrameDirection = -1; else { RMDBGLOG((ENABLE, "cant determine iframe trickmode playback direction, defaulting to forward!")); pSendContext->IFrameDirection = 1; } { RMuint64 currentPTS; RUAGetProperty(pSendContext->pRUA, pSendContext->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &(pSendContext->CurrentDisplayPTS), sizeof(RMuint64)); if (pSendContext->video_vop_tir == 90000) pSendContext->CurrentDisplayPTS *= 2; RMDBGLOG((ENABLE, "updated display pts %llu s\n", pSendContext->CurrentDisplayPTS)); currentPTS = round_int_div(pSendContext->CurrentDisplayPTS, (RMuint32) pSendContext->video_vop_tir); RMDBGLOG((ENABLE, "has to find position of time %llu s\n", currentPTS)); asf_seek(pSendContext, currentPTS); RMGetCurrentPositionOfFile(pSendContext->f_bitstream, &position); RMDBGLOG((ENABLE, "setting start position to %llu\n", position)); pSendContext->CurrentDisplayPTS = 0; } RMDBGLOG((ENABLE, "playing trickmode...direction %s\n", (pSendContext->IFrameDirection >= 0) ? "forward":"backward")); err = RMASFVDemuxSetTrickModeDirection(pSendContext->vASFDemux, pSendContext->IFrameDirection); if (err != RM_OK) return RM_ERROR; err = RMASFVDemuxInitTrickMode(pSendContext->vASFDemux, (RMuint64 *)&position); if (err != RM_OK) return RM_ERROR; /* skip the IFrame we just seeked to */ err = RMASFVDemuxGetNextIFrame(pSendContext->vASFDemux, (RMuint64 *)&position, &size, &packet); if (err != RM_OK) return RM_ERROR; RMSeekFile(pSendContext->f_bitstream, position, RM_FILE_SEEK_START); RMDBGLOG((ENABLE, "skipping one iframe at pos %llu, size %lu, packet %lu\n", position, size, packet)); RMDBGLOG((ENABLE, "flush video...\n")); asf_Stop(pSendContext, RM_DEVICES_VIDEO); pSendContext->IFrameSize = 0; pSendContext->IFrameFSMState = RMasfIFrameFSM_Init; pSendContext->SeekAudio = FALSE; pSendContext->SeekVideo = FALSE; asf_Play(pSendContext, RM_DEVICES_VIDEO | RM_DEVICES_STC, DCCVideoPlayIFrame);#if 0 { RMstatus err; /* restart recording data after the seek */ RMDBGLOG((ENABLE, "restarting save data\n")); err = close_save_files(pSendContext->play_opt); if (RMFAILED(err)) { fprintf(stderr, "Cannot close files used to save data %d\n", err); return RM_ERROR; } err = open_save_files(pSendContext->play_opt); if (RMFAILED(err)) { fprintf(stderr, "cannot open files to save data %d\n", err); return RM_ERROR; } }#endif return RM_OK;}static RMstatus asf_ResumeFromIFrameTrickMode(struct asf_context * pSendContext){ RMstatus err = RM_OK; RMuint64 time; RMuint64 roundUpTime; err = RUAGetProperty(pSendContext->pRUA, pSendContext->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &time, sizeof(time)); if (pSendContext->video_vop_tir == 90000) time *= 2; RMDBGLOG((ENABLE, "resume from trickmode at %llu in %ld units\n", time, pSendContext->video_vop_tir)); pSendContext->CurrentDisplayPTS = (time * 1000) / pSendContext->video_vop_tir; roundUpTime = time / pSendContext->video_vop_tir; if ((time - (roundUpTime * pSendContext->video_vop_tir)) > 0) roundUpTime++; RMDBGLOG((ENABLE, "seeking to %llu ms => adj time is %llu\n", time, roundUpTime)); asf_seek(pSendContext, roundUpTime); DCCSTCSetSpeed(pSendContext->dcc_info->pStcSource, pSendContext->play_opt->speed_N, pSendContext->play_opt->speed_M); //asf_Stop(pSendContext, RM_DEVICES_STC); asf_Pause(pSendContext, RM_DEVICES_STC | RM_DEVICES_VIDEO | RM_DEVICES_AUDIO); RM_PSM_SetState(pSendContext->PSMcontext, &(pSendContext->dcc_info), RM_PSM_Prebuffering); return RM_OK;}static RMstatus asf_FastAudioRecovery(struct asf_context * pSendContext){ RMstatus err = RM_OK; RMuint64 time; RMuint64 roundUpTime; if ((!pSendContext->audioSamplesDropped) && (pSendContext->sendAudioTrickmode)) { RMDBGLOG((ENABLE, "FastAudioRecovery: -sat was also enabled and there were no audio samples dropped during trickmodes, ignore\n")); return RM_OK; } else if (pSendContext->sendAudioTrickmode) RMDBGLOG((ENABLE, "FastAudioRecovery: -sat was also enabled but we dropped audio samples\n")); err = RUAGetProperty(pSendContext->pRUA, pSendContext->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &time, sizeof(time)); if (pSendContext->video_vop_tir == 90000) time *= 2; RMDBGLOG((ENABLE, "FastAudioRecovery: resume from trickmode at %llu in %ld units\n", time, pSendContext->video_vop_tir)); roundUpTime = time / pSendContext->video_vop_tir; if ((time - (roundUpTime * pSendContext->video_vop_tir)) > 0) roundUpTime++; RMDBGLOG((ENABLE, "seeking to %llu ms => adj time is %llu\n", time, roundUpTime)); asf_seek(pSendContext, roundUpTime); DCCSTCSetSpeed(pSendContext->dcc_info->pStcSource, pSendContext->play_opt->speed_N, pSendContext->play_opt->speed_M); //asf_Stop(pSendContext, RM_DEVICES_STC); asf_Pause(pSendContext, RM_DEVICES_STC | RM_DEVICES_VIDEO | RM_DEVICES_AUDIO); RM_PSM_SetState(pSendContext->PSMcontext, &(pSendContext->dcc_info), RM_PSM_Prebuffering); return RM_OK;}static RMstatus restartAudioDecoder(struct asf_context * pSendContext){ RMuint64 stc; if (!pSendContext->audio_parameters[pSendContext->audio_stream_index].enabled) return RM_ERROR; RMDBGLOG((ENABLE, "restart audio decoder\n"));#ifndef EM86XX_DEBUG_AUDIO asf_Stop(pSendContext, RM_DEVICES_AUDIO);#endif if (pSendContext->isWMAPRO) { if (pSendContext->vDecoder != NULL) { RMDBGLOG((ENABLE, "close wmapro decoder\n")); RMWMAProVDecoderClose(pSendContext->vDecoder); RMDBGLOG((ENABLE, "open wmapro decoder\n")); RMWMAProVDecoderOpen(pSendContext->vDecoder); } else RMDBGLOG((ENABLE, "no wmapro decoder created!\n")); } pSendContext->audio_decoder_initialized = FALSE; //get the time in 1000th units because presentation time from ASF is always in 1/1000 DCCSTCGetTime(pSendContext->dcc_info->pStcSource, &stc, 1000); RMDBGLOG((ENABLE, ">> stc is %llu\n", stc)); if ((!pSendContext->VideoStreamFound) && (pSendContext->AudioStreamFound)) { RMuint64 time; pSendContext->accurateAudioSeekTo = stc; time = stc / 1000; time -= 2; RMDBGLOG((ENABLE, "seeking to %llu s\n", time)); if ((RMint64)time >= 0) asf_seek(pSendContext, time); else asf_seek(pSendContext, 0); DCCSTCSetSpeed(pSendContext->dcc_info->pStcSource, pSendContext->play_opt->speed_N, pSendContext->play_opt->speed_M); RM_PSM_SetState(pSendContext->PSMcontext, &(pSendContext->dcc_info), RM_PSM_Playing); RMDBGLOG((ENABLE, "accurate audio seek to %llu\n", stc)); asf_Stop(pSendContext, RM_DEVICES_STC); }#ifndef EM86XX_DEBUG_AUDIO asf_Play(pSendContext, RM_DEVICES_AUDIO, 0);#endif return RM_OK;}static RMstatus readBitstream(struct asf_context *pSendContext, RMuint8 *buffer, RMuint32 *bytesRead){ RMstatus status; RMuint64 position; RMuint32 size, packet; RMuint32 count; RMuint32 buffersize; RMuint32 alignedPacket; enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(pSendContext->PSMcontext, &(pSendContext->dcc_info)); buffersize = (1 << pSendContext->play_opt->dmapool_log2size); if (pSendContext->drmError) { RMDBGLOG((ENABLE, "there was a decryption error, abort playback\n")); return RM_DRM_DECRYPTION_FAILED; } /* The Microsoft Janus DRM requires ASF data packets to be contiguous for decryption. * If the file is Janus encrypted, an integer multiple of ASF data packets will be * read into the RUA buffer (i.e. the read size is truncated). If the file is not * Janus encrypted, the entire RUA buffer will be filled. */ if (pSendContext && pSendContext->asf_packetSize && pSendContext->isContentEncrypted) { /* In case we play the file completely sequentially, the * asf_packetSize is not known at the first read, since we * haven't parsed the stream yet, so use default size if * asf_packetSize == 0 */ alignedPacket = (buffersize/pSendContext->asf_packetSize)*pSendContext->asf_packetSize; buffersize = alignedPacket; if (((RMuint32) (1 << pSendContext->play_opt->dmapool_log2size)) < pSendContext->asf_packetSize) { RMDBGLOG((ENABLE, "** Read Buffers too small\n")); return RM_ERROR; } } if ((PlaybackStatus != RM_PSM_Playing) && (PlaybackStatus != RM_PSM_Prebuffering)) { if (pSendContext->isIFrameMode) { if (pSendContext->IFrameSize == 0) { RMuint32 sizeToRead; status = RMASFVDemuxGetNextIFrame(pSendContext->vASFDemux, &position, &size, &packet); RMDBGLOG((TRICKDBG, "got iframe at pos(%llu), size(%lu), packet(%lu)\n", position, size, packet)); if (status != RM_OK) { RMDBGLOG((ENABLE, "error getting next iframe\n")); return status; } RMSeekFile(pSendContext->f_bitstream, position, RM_FILE_SEEK_START); pSendContext->IFrameFSMState = RMasfIFrameFSM_Init; pSendContext->IFrameSize = size; sizeToRead = RMmin(buffersize, size); RMDBGLOG((READ_DBG, "read %lu bytes\n", sizeToRead)); status = RMReadFile(pSendContext->f_bitstream, buffer, sizeToRead, &count); pSendContext->IFrameSize -= (RMint32)count; if (pSendContext->IFrameSize <= 0) pSendContext->IFrameSize = 0; RMDBGLOG((TRICKDBG, "filled buffer with %lu bytes, should read %lu, left %lu\n", count, sizeToRead, pSendContext->IFrameSize)); } else { RMuint32 sizeToRead = RMmin(buffersize, (RMuint32)pSendContext->IFrameSize); RMDBGLOG((READ_DBG, "read %lu bytes\n", sizeToRead)); status = RMReadFile(pSendContext->f_bitstream, buffer, sizeToRead, &count); pSendContext->IFrameSize -= (RMint32)count; if (pSendContext->IFrameSize <= 0) pSendContext->IFrameSize = 0; RMDBGLOG((TRICKDBG, "filled buffer with %lu bytes, should read %lu, left %lu\n", count, sizeToRead, pSendContext->IFrameSize)); } } else if ((!pSendContext->VideoStreamFound) && (pSendContext->AudioStreamFound)) return RM_SKIP_DATA; else { RMDBGLOG((READ_DBG, "read %lu bytes\n", buffersize)); status = RMReadFile(pSendContext->f_bitstream, buffer, buffersize, &count); if (status == RM_OK && pSendContext && pSendContext->asf_packetSize && pSendContext->isContentEncrypted && buffersize != count) { RMDBGLOG((ENABLE, "ERROR: buffersize=%lu, count=%lu, status=%d\n", buffersize, count, (int)status)); count = (count/pSendContext->asf_packetSize)*pSendContext->asf_packetSize; RMDBGLOG((ENABLE,"SOLVE: count=%lu, asf_packet_size=%lu\n", count, pSendContext->asf_packetSize)); status = RM_ERRORENDOFFILE;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?