📄 play_avi_push.c
字号:
RMDBGLOG((ENABLE, ">> resync timer (%llu) with videoDecoder current PTS (%llu)\n", CurrentSTC, videoPTS)); DCCSTCSetTime(avi_info->dcc_info->pStcSource, videoPTS, avi_info->vopTimeIncrementResolution); return err;}static RMstatus Stop(struct avi_context *avi_info, RMuint32 decoder_flags){ RMstatus err = RM_OK; if ((play_opt->send_video) && (decoder_flags & RM_DEVICES_VIDEO)) { RMbool keep_sequence = TRUE; if (play_opt->disk_ctrl_state != DISK_CONTROL_STATE_DISABLE) { while (avi_info->dmabuffer_index > 0) { avi_info->dmabuffer_index--; if (avi_info->dmabuffer_array[avi_info->dmabuffer_index]) { RMDBGLOG((ENABLE, "releasing buffer index %lu buffer %p\n", avi_info->dmabuffer_index, avi_info->dmabuffer_array[avi_info->dmabuffer_index])); RUAReleaseBuffer(avi_info->pDMA, avi_info->dmabuffer_array[avi_info->dmabuffer_index]); } } } err = DCCStopVideoSource(avi_info->dcc_info->pVideoSource, DCCStopMode_LastFrame); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot stop video decoder %d\n", err)); return err; } RMDBGLOG((ENABLE, "video stopped\n")); err = RUASetProperty(avi_info->dcc_info->pRUA, avi_info->dcc_info->video_decoder, RMVideoDecoderPropertyID_StorePreviousVideoHeader, &keep_sequence, sizeof(keep_sequence), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error setting video decoder to keep sequence header on Stop %d\n", err)); return err; } avi_info->frameIsIFrame = TRUE; } if ((play_opt->send_audio) && (decoder_flags & RM_DEVICES_AUDIO)) { if (avi_info->dcc_info->pMultipleAudioSource) { err = DCCStopMultipleAudioSource(avi_info->dcc_info->pMultipleAudioSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error stopping audio source %d\n", err)); return err; } RMDBGLOG((ENABLE, "audio stopped\n")); } } if (decoder_flags & RM_DEVICES_STC) { RMDBGLOG((ENABLE, "stc stopped\n")); DCCSTCStop(avi_info->dcc_info->pStcSource); } if (avi_info->monitorFIFOs) { RMDBGLOG((ENABLE, "FIFO STATUS after stop\n")); monitorFIFO(avi_info, TRUE); RMDBGLOG((ENABLE, "**********************\n")); } return err;}static RMstatus Play(struct avi_context *avi_info, RMuint32 decoder_flags, enum DCCVideoPlayCommand mode){ RMstatus err = RM_OK; if (avi_info->monitorFIFOs) { RMDBGLOG((ENABLE, "FIFO STATUS before play\n")); monitorFIFO(avi_info, TRUE); RMDBGLOG((ENABLE, "***********************\n")); } if ((play_opt->send_video) && (decoder_flags & RM_DEVICES_VIDEO)) { RMDBGLOG((ENABLE, "video started\n")); err = DCCPlayVideoSource(avi_info->dcc_info->pVideoSource, mode); } if ((play_opt->send_audio) && (decoder_flags & RM_DEVICES_AUDIO)) { if (avi_info->dcc_info->pMultipleAudioSource) { RMDBGLOG((ENABLE, "audio started\n")); err = DCCPlayMultipleAudioSource(avi_info->dcc_info->pMultipleAudioSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error starting audio source %d\n", err)); return err; } } } if (decoder_flags & RM_DEVICES_STC) { DCCSTCPlay(avi_info->dcc_info->pStcSource); } return err;}static RMstatus Pause(struct avi_context *avi_info, RMuint32 decoder_flags){ RMstatus err = RM_OK; if ((play_opt->send_video) && (decoder_flags & RM_DEVICES_VIDEO)) { RMDBGLOG((ENABLE, "pause video\n")); err = DCCPauseVideoSource(avi_info->dcc_info->pVideoSource); } if ((play_opt->send_audio) && (decoder_flags & RM_DEVICES_AUDIO)) { if (avi_info->dcc_info->pMultipleAudioSource) { RMDBGLOG((ENABLE, "pause audio\n")); err = DCCPauseMultipleAudioSource(avi_info->dcc_info->pMultipleAudioSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error starting audio source %d\n", err)); return err; } } } if (decoder_flags & RM_DEVICES_STC) { DCCSTCStop(avi_info->dcc_info->pStcSource); } return err;}static RMstatus local_seek(struct avi_context *avi_info, RMuint64 time_us){ RMuint64 offset = 0; RMuint64 audioTimeBytes, audioTimeFrames, videoTime; RMstatus err = RM_OK; RMuint32 j, i=avi_info->currentAudioIndex; RMDBGLOG((ENABLE,"Got seek command to %llu\n", time_us)); if (avi_info->switching_audio) { err = switch_audio(avi_info); if (RMFAILED(err)) return err; } Stop(avi_info, RM_DEVICES_VIDEO | RM_DEVICES_AUDIO | RM_DEVICES_STC); if (avi_info->audio_stream_count) { for (j=0 ; j<avi_info->audio_stream_count ; j++) { /* last i = avi_info->dcc_info->selectAudioStream */ i = (avi_info->currentAudioIndex + j + 1) % avi_info->audio_stream_count; RMaviPushSelectAudioStream(avi_info->pAvi, i); err = RMAviPushSeekMovi (avi_info->pAvi, time_us, &offset, &audioTimeBytes, &audioTimeFrames, &videoTime); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "seekMovi (%lu) failed - seek to 0\n", avi_info->dcc_info->seek_time)); err = RMAviPushSeekMovi (avi_info->pAvi, 0, &offset, &audioTimeBytes, &audioTimeFrames, &videoTime); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "seekMovi failed to seek to 0\n")); return err; } } if (avi_info->audio_info[i].audio_VBR) avi_info->audio_info[i].audioPTS = avi_info->audio_info[i].audioFormat.nBlockAlign * audioTimeFrames; else avi_info->audio_info[i].audioPTS = (RMuint64)((RMuint64)audioTimeBytes * (RMuint64)avi_info->audio_info[i].audioTimeScale) / 1000000; avi_info->audio_info[i].audioByteCounter = audioTimeBytes * avi_info->audio_info[i].audioFormat.nAvgBytesPerSec / 1000000; avi_info->audio_info[i].audioFrameCounter = audioTimeFrames; } } else { RMDBGLOG((ENABLE, "video only stream\n")); err = RMAviPushSeekMovi (avi_info->pAvi, time_us, &offset, &audioTimeBytes, &audioTimeFrames, &videoTime); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "seekMovi (%lu) failed - seek to 0\n", avi_info->dcc_info->seek_time)); err = RMAviPushSeekMovi (avi_info->pAvi, 0, &offset, &audioTimeBytes, &audioTimeFrames, &videoTime); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "seekMovi failed to seek to 0\n")); return err; } } } avi_info->videoFrameCounter = videoTime; RMDBGLOG((ENABLE, "Seeking to offset %lu\n", offset)); err = RMSeekFile(avi_info->avi_file, offset, RM_FILE_SEEK_START); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error seeking file to %lu\n", offset)); return err; } RMDBGLOG((ENABLE, "old movi index %lu\n", avi_info->movi_index)); RMAviPushGetMoviIndexFromPosition(avi_info->pAvi, offset, &(avi_info->movi_index)); RMDBGLOG((ENABLE, "new movi index %lu\n", avi_info->movi_index));#if 0 if (avi_info->audio_info[i].audioTimeScale) { RMDBGLOG((ENABLE, "Setting time to %llu/%lu\n", avi_info->audio_info[i].audioPTS, avi_info->audio_info[i].audioTimeScale)); DCCSTCSetTime(avi_info->dcc_info->pStcSource, avi_info->audio_info[i].audioPTS, avi_info->audio_info[i].audioTimeScale); } else { RMDBGLOG((ENABLE, "should set time according to first video PTS\n")); }#endif avi_info->frameIsIFrame = TRUE; return RM_OK;}static enum goto_state local_process_key(struct avi_context *avi_info, RMbool getkey){ RMstatus err; enum RM_PSM_State FSMstate; struct RUAEvent e; RMuint32 index, i; if (avi_info->monitorFIFOs) monitorFIFO(avi_info, FALSE); if (avi_info->switching_audio) { if (avi_info->dcc_info->pMultipleAudioSource) { struct DCCAudioSourceHandle audioHandle; /* wait for 1st decoder to process the inband command */ DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(avi_info->dcc_info->pMultipleAudioSource, 0, &audioHandle); e.ModuleID = audioHandle.moduleID; e.Mask = RUAEVENT_INBAND_COMMAND; err = RUAWaitForMultipleEvents(avi_info->pRUA, &e, 1, 0, &index); if (err == RM_OK) { /* now wait for all other decoders to finish. It should occurs pretty soon */ for (i=1 ; i<audioInstances ; i++) { DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(avi_info->dcc_info->pMultipleAudioSource, i, &audioHandle); do { e.ModuleID = audioHandle.moduleID; e.Mask = RUAEVENT_INBAND_COMMAND; err = RUAWaitForMultipleEvents(avi_info->pRUA, &e, 1, COMMON_TIMEOUT_US, &index); } while (err == RM_PENDING); } err = switch_audio(avi_info); return (RMFAILED(err)) ? LABEL_ERROR : LABEL_NONE; } } } if (getkey) { FSMstate = RM_PSM_GetState(avi_info->PSMcontext, &(avi_info->dcc_info)); if ((FSMstate == RM_PSM_Stopped) || (FSMstate == RM_PSM_Paused)) { switch (play_opt->disk_ctrl_state) { case DISK_CONTROL_STATE_DISABLE: case DISK_CONTROL_STATE_SLEEPING: break; case DISK_CONTROL_STATE_RUNNING: if(play_opt->disk_ctrl_callback && play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_SLEEP) == RM_OK) play_opt->disk_ctrl_state = DISK_CONTROL_STATE_SLEEPING; break; } } err = process_command(avi_info->PSMcontext, &(avi_info->dcc_info), &actions); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while processing key %d\n", err)); return LABEL_ERROR; } } FSMstate = RM_PSM_GetState(avi_info->PSMcontext, &(avi_info->dcc_info)); if (actions.toDoActions & RM_PSM_RESYNC_TIMER) SyncTimerWithDecoderPTS(avi_info); if (actions.toDoActions & RM_PSM_DEMUX_NORMAL) { avi_info->iframe = FALSE; avi_info->read_size = 0; } if (actions.toDoActions & RM_PSM_FLUSH_VIDEO) { err = Stop(avi_info, RM_DEVICES_VIDEO); } if (actions.toDoActions & RM_PSM_DEMUX_IFRAME) { RMint64 position = 0; RMuint64 wantedTime; RMuint64 videoPTS = 0; if (avi_info->dcc_info->SurfaceID != 0) { err = RUAGetProperty(avi_info->pRUA, avi_info->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &videoPTS, sizeof(videoPTS)); if (err != RM_OK) { RMDBGLOG((ENABLE, "error %d while getting CurrentDisplayPTS\n", err)); return LABEL_ERROR; } } if (avi_info->vopTimeIncrementResolution == 90000) videoPTS *= 2; wantedTime = (RMuint64)(videoPTS*1000000)/avi_info->vopTimeIncrementResolution; err = local_seek(avi_info, wantedTime); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot seek to current display time\n")); return LABEL_ERROR; } err = RMGetCurrentPositionOfFile (avi_info->avi_file, &position); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get current position in avi file %d\n", err)); return LABEL_ERROR; } RMAviPushInitIFrame(avi_info->pAvi, position); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot seek into avi index %d\n", err)); return LABEL_ERROR; } avi_info->iframe = TRUE; } if (actions.toDoActions & RM_PSM_FIRST_PTS) { RMDBGLOG((ENABLE, "firstPTS Nothing to do\n")); avi_info->firstPTS = TRUE; avi_info->frameIsIFrame = TRUE; } if (actions.performedActions & RM_PSM_VIDEO_STOPPED) { RMbool keep_sequence = TRUE; RMDBGLOG((ENABLE, "video stopped\n")); err = RUASetProperty(avi_info->dcc_info->pRUA, avi_info->dcc_info->video_decoder, RMVideoDecoderPropertyID_StorePreviousVideoHeader, &keep_sequence, sizeof(keep_sequence), 0); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error setting video decoder to keep sequence header on Stop %d\n", err)); return LABEL_ERROR; } avi_info->sendVideoData = FALSE; avi_info->frameIsIFrame = TRUE; } if (actions.performedActions & RM_PSM_AUDIO_STOPPED) { RMDBGLOG((ENABLE, "audio stopped. Nothing to do\n")); avi_info->sendAudioData = FALSE; } if (((FSMstate == RM_PSM_IForward) || (FSMstate == RM_PSM_IRewind)) && (actions.cmdProcessed)) { if (avi_info->dcc_info->pVideoSource) { err = Play(avi_info, RM_DEVICES_VIDEO | RM_DEVICES_STC, DCCVideoPlayIFrame); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error playing video source %d\n", err)); return LABEL_ERROR; } } } if ((actions.cmd == RM_QUIT) && (!actions.cmdProcessed)) { RMDBGLOG((ENABLE, "Got quit command\n")); return LABEL_QUIT; } if ((actions.cmd == RM_STOP) || (actions.toDoActions & RM_PSM_DEMUX_NORMAL)) { RMuint64 wantedTime; RMuint64 videoPTS = 0; RMDBGLOG((ENABLE,"Got stop command\n")); if (avi_info->dcc_info->SurfaceID != 0) { err = RUAGetProperty(avi_info->pRUA, avi_info->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &videoPTS, sizeof(videoPTS)); if (err != RM_OK) { RMDBGLOG((ENABLE, "error %d while getting CurrentDisplayPTS\n", err)); return LABEL_ERROR; } } if (avi_info->vopTimeIncrementResolution == 90000) videoPTS *= 2; wantedTime = (RMuint64)(videoPTS*1000000)/avi_info->vopTimeIncrementResolution; err = local_seek(avi_info, wantedTime); return (RMFAILED(err)) ? LABEL_ERROR : LABEL_STOP; } if ((actions.cmd == RM_STOP_SEEK_ZERO) && (!actions.cmdProcessed)) { RMDBGLOG((ENABLE,"Got stop seek zero command\n")); err = Stop(avi_info, RM_DEVICES_VIDEO | RM_DEVICES_AUDIO | RM_DEVICES_STC); RM_PSM_SetState(avi_info->PSMcontext, &(avi_info->dcc_info), RM_PSM_Stopped); return (RMFAILED(err)) ? LABEL_ERROR : LABEL_STOP_SEEK_ZERO; } if ((actions.cmd == RM_SEEK) && (!actions.cmdProcessed)){ RMuint64 wantedTime = (RMuint64)(avi_info->dcc_info->seek_time); /* convert time to us */ wantedTime *= 1000000; err = close_save_files(play_opt); err = open_save_files(play_opt); err = local_seek(avi_info, wantedTime); RM_PSM_SetState(avi_info->PSMcontext, &(avi_info->dcc_info), RM_PSM_Playing); return (RMFAILED(err)) ? LABEL_ERROR : LABEL_STOP; } if ((actions.asyncCmd == RM_AUDIO_STREAM_CHANGE) && (actions.asyncCmdPending)) { struct InbandCommand_type InbandCmd; RMDBGLOG((ENABLE, "got async cmd switch audio stream\n")); actions.asyncCmd = RM_NONE; actions.asyncCmdPending = FALSE; if (avi_info->dcc_info->selectAudioStream == -1) { avi_info->currentAudioIndex++; avi_info->currentAudioIndex = avi_info->currentAudioIndex % avi_info->audio_stream_count; } else { avi_info->currentAudioIndex = avi_info->dcc_info->selectAudioStream; } if (avi_info->switching_audio) { /* do nothing! */ return LABEL_NONE; } if (avi_info->dcc_info->pMultipleAudioSource) { struct DCCAudioSourceHandle audioHandle;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -