play_asf.c
来自「1. 8623L平台」· C语言 代码 · 共 1,567 行 · 第 1/4 页
C
1,567 行
/* * * Copyright (c) Sigma Designs, Inc. 2002. All rights reserved. * *//** @file play_asf.c @brief sample application to access the Mambo chip and test DMA transfers @author Julien Soulier @ingroup dccsamplecode*//* ****************************************************************************************** This file is part of libsamples library, therefore *NO* static variables should be defined *******************************************************************************************//* PCM on ASF see bug 4917 VC1 on ASF see bug 4826 MPEG2 on ASF see bug 5529*/#define RELEASE_BUFFER_ENABLE DISABLE#ifdef CHECK_BUFFER_PTS#define CHECK_BUFFER_4_FREAD 1#define CHECK_BUFFER_4_AUDIO 1#define CHECK_BUFFER_4_VIDEO 1#endif#define _LARGEFILE64_SOURCE 1 // Required for large files (> 4GB)#include "sample_os.h"#define ALLOW_OS_CODE 1#include "../dcc/include/dcc.h"#include "../rmasfdemux/include/rmasfdemuxapi.h"#include "../rmasfdemux/include/wmdrm.h"#include "../rmasfdemux/include/wmdrmopl.h"#include "common.h"#include "../rmwmaprodecoder/include/rmwmaprodefine.h"#include "../rmwmaprodecoder/include/rmwmaprodecoderapi.h"/* #### Begin CARDEA code #### */#include "rmupnp/rmlibwmdrmnd/include/ms_cardea.h"/* #### End CARDEA code #### *//* ################## Begin DTCP code ################### */#if (EM86XX_CHIP == EM86XX_CHIPID_TANGO15)#include "../rmdtcp/include/dtcp_session.h"#else#include "../rmdtcpapi/include/dtcp_session.h"#endif/* ############### End DTCP code ####################### */#include "bcc.h"#include "asfdemux_common.h"#define WAIT_COMMAND_TIMEOUT_US (TIMEOUT_10MS) // 10 ms#define WAIT_EOS_TIMEOUT_US 20000000 // 20 sec#define KEYFLAGS (SET_KEY_DISPLAY | SET_KEY_PLAYBACK | SET_KEY_AUDIO | SET_KEY_DEBUG | SET_KEY_SPI)// uncomment next line for debug information//#define DISPLAY_VIDEO_STREAM_PAYLOAD_INFO// uncomment next line to save all input compressed frames into separate files//#define SAVE_INPUT_FRAMES#define READ_DBG DISABLE#define MAX_INDEX_NUMBER 5#define INDEX_BUFFER_SIZE (200 * 1024)/* prototypes */static RMstatus restartAudioDecoder(struct asf_context * pSendContext);static RMuint64 round_int_div(RMuint64 numerator, RMuint32 divisor);static RMstatus asf_FastAudioRecovery(struct asf_context * pSendContext);static RMstatus asf_ResumeFromIFrameTrickMode(struct asf_context * pSendContext);static RMstatus asf_seek(struct asf_context * pSendContext, RMuint64 time);static RMstatus asf_InitIFrameTrickMode(struct asf_context* pSendContext);static enum RMasfProcess_key_goto process_key_sub(void *context, RMuint8 release, RMuint8 getkey, RMuint8 incallback, RMuint32 dataType){ struct asf_context *pProcessContext = (struct asf_context *)context; RMuint32 i; RMstatus err; RMuint32 dummy; RMuint8 *buffer = (RMuint8*)&dummy; enum RM_PSM_State OldPlaybackState = RM_PSM_GetState(pProcessContext->PSMcontext, &(pProcessContext->dcc_info)); enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(pProcessContext->PSMcontext, &(pProcessContext->dcc_info)); RMuint8 got_key=0; if (getkey) { if ((OldPlaybackState == RM_PSM_Stopped) || (OldPlaybackState == RM_PSM_Paused)) { switch (pProcessContext->play_opt->disk_ctrl_state) { case DISK_CONTROL_STATE_DISABLE: case DISK_CONTROL_STATE_SLEEPING: break; case DISK_CONTROL_STATE_RUNNING: if(pProcessContext->play_opt->disk_ctrl_callback && pProcessContext->play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_SLEEP) == RM_OK) pProcessContext->play_opt->disk_ctrl_state = DISK_CONTROL_STATE_SLEEPING; break; } } RMDBGLOG((KEYDBG, "process_key\n")); err = process_command(pProcessContext->PSMcontext, &(pProcessContext->dcc_info), &pProcessContext->actions); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error while processing key %d\n", err)); return RMProcess_key_goto_cleanup; } if ((pProcessContext->actions.performedActions) || (pProcessContext->actions.toDoActions) || (pProcessContext->actions.cmd != RM_NONE)) got_key=1; } if (pProcessContext->actions.toDoActions & RM_PSM_RESYNC_TIMER) { RMDBGLOG((ENABLE, "resyncTimer\n")); asf_SyncTimerWithDecoderPTS(pProcessContext); pProcessContext->actions.toDoActions &= ~RM_PSM_RESYNC_TIMER; } if (pProcessContext->actions.toDoActions & RM_PSM_FLUSH_VIDEO) { RMDBGLOG((ENABLE, "flushVIDEO\n")); asf_Stop(pProcessContext, RM_DEVICES_VIDEO); pProcessContext->actions.toDoActions &= ~RM_PSM_FLUSH_VIDEO; } if (pProcessContext->actions.toDoActions & RM_PSM_DEMUX_NORMAL) { RMDBGLOG((ENABLE, "demuxNormal\n")); if (RMFAILED(asf_ResumeFromIFrameTrickMode(pProcessContext))) { RMDBGLOG((ENABLE,"Error during resume from trickmode, abort.\n")); return RMProcess_key_goto_cleanup; } pProcessContext->isIFrameMode = FALSE; pProcessContext->actions.toDoActions &= ~RM_PSM_DEMUX_NORMAL; } if (pProcessContext->actions.toDoActions & RM_PSM_DEMUX_IFRAME) { RMDBGLOG((ENABLE, "demuxIFrame\n")); if (release) { if (buffer != NULL) { RMDBGLOG((ENABLE, "release a buffer\n")); RUAReleaseBuffer(pProcessContext->pDMA, buffer); buffer = NULL; } else RMDBGLOG((ENABLE, "no buffer to release\n")); } if (RMFAILED(asf_InitIFrameTrickMode(pProcessContext))) { RMDBGLOG((ENABLE,"Error during init trickmode, abort.\n")); return RMProcess_key_goto_cleanup; } pProcessContext->isIFrameMode = TRUE; pProcessContext->ignoreCallback = FALSE; pProcessContext->actions.toDoActions &= ~RM_PSM_DEMUX_IFRAME; } if (pProcessContext->actions.toDoActions & RM_PSM_FIRST_PTS) { RMDBGLOG((ENABLE, "firstPTS\n")); /*pProcessContext->FirstSystemTimeStamp = TRUE;*/ pProcessContext->actions.toDoActions &= ~RM_PSM_FIRST_PTS; } if (pProcessContext->actions.toDoActions & RM_PSM_NORMAL_PLAY) { RMDBGLOG((ENABLE, "normal play\n")); if ((pProcessContext->audio_parameters[pProcessContext->audio_stream_index].enabled) && (pProcessContext->AudioStreamFound) && (pProcessContext->sendAudioTrickmode)) { RMDBGLOG((ENABLE, "******* reset audio timer routing\n")); routeAudioTimerToDisplayPTS(pProcessContext->dcc_info, FALSE); unMuteAudio(pProcessContext->dcc_info); } if ((pProcessContext->play_opt->fast_audio_recovery) && (pProcessContext->VideoStreamFound) && !(pProcessContext->linear_playback)) asf_FastAudioRecovery(pProcessContext); pProcessContext->actions.toDoActions &= ~RM_PSM_NORMAL_PLAY; } \ if (pProcessContext->actions.performedActions & RM_PSM_VIDEO_STOPPED) { RMDBGLOG((ENABLE, "video stopped\n")); pProcessContext->video_decoder_initialized = FALSE; if (pProcessContext->isVC1) { RMDBGLOG((ENABLE, "codec: VC1 Advanced Profile, will add seqHeader to bitstream\n")); pProcessContext->addSeqHeader = TRUE; } pProcessContext->actions.performedActions &= ~RM_PSM_VIDEO_STOPPED; } if (pProcessContext->actions.performedActions & RM_PSM_AUDIO_STOPPED) { RMDBGLOG((ENABLE, "audio stopped\n")); asf_Stop(pProcessContext, RM_DEVICES_AUDIO); pProcessContext->actions.performedActions &= ~RM_PSM_AUDIO_STOPPED; } if (pProcessContext->actions.performedActions & RM_PSM_STC_STOPPED) { RMDBGLOG((ENABLE, "stc stopped\n")); pProcessContext->actions.performedActions &= ~RM_PSM_STC_STOPPED; } if ((pProcessContext->actions.cmd == RM_QUIT) && (!pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE, "got quit\n")); pProcessContext->ignoreCallback = FALSE; pProcessContext->actions.cmdProcessed = TRUE; if (incallback) pProcessContext->ignoreCallback = TRUE; return RMProcess_key_goto_cleanup; } if ((!pProcessContext->audio_decoder_initialized) && (OldPlaybackState != RM_PSM_Playing) && (RM_PSM_GetState(pProcessContext->PSMcontext, &(pProcessContext->dcc_info)) == RM_PSM_Playing)) { RMDBGLOG((ENABLE, "restart audio decoder due to play\n")); restartAudioDecoder(pProcessContext); RMDBGLOG((ENABLE, "syncTimer\n")); asf_SyncTimerWithDecoderPTS(pProcessContext); if ((pProcessContext->AudioStreamFound) && (!pProcessContext->VideoStreamFound)) return RMProcess_key_goto_mainloop_seek; } if ((RM_PSM_GetState(pProcessContext->PSMcontext, &(pProcessContext->dcc_info)) == RM_PSM_Stopped) && (pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE,"Got stop command\n")); pProcessContext->ignoreCallback = FALSE; pProcessContext->isIFrameMode = FALSE; pProcessContext->video_decoder_initialized = FALSE; pProcessContext->audio_decoder_initialized = FALSE; pProcessContext->FirstSystemTimeStamp = TRUE; if (incallback) pProcessContext->ignoreCallback = TRUE; if (pProcessContext->linear_playback) { RMDBGLOG((ENABLE, "linear playback is enabled, 'stop' is 'quit' because we cannot seek\n")); pProcessContext->actions.cmdProcessed = TRUE; return RMProcess_key_goto_cleanup; } return RMProcess_key_goto_wmapro_decoder_delete; } \ if ((pProcessContext->actions.cmd == RM_STOP_SEEK_ZERO) && (!pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE,"Got stop seek zero command\n")); if (release) { if (buffer != NULL) { RMDBGLOG((ENABLE, "release a buffer\n")); RUAReleaseBuffer(pProcessContext->pDMA, buffer); buffer = NULL; } else RMDBGLOG((ENABLE, "no buffer to release\n")); } asf_Stop(pProcessContext, RM_DEVICES_STC | RM_DEVICES_AUDIO | RM_DEVICES_VIDEO); RM_PSM_SetState(pProcessContext->PSMcontext, &(pProcessContext->dcc_info), RM_PSM_Stopped); pProcessContext->ignoreCallback = FALSE; pProcessContext->isIFrameMode = FALSE; pProcessContext->video_decoder_initialized = FALSE; pProcessContext->audio_decoder_initialized = FALSE; pProcessContext->FirstSystemTimeStamp = TRUE; pProcessContext->actions.cmdProcessed = TRUE; if (incallback) pProcessContext->ignoreCallback = TRUE; if (pProcessContext->linear_playback) { RMDBGLOG((ENABLE, "linear playback is enabled, 'stop' is 'quit' because we cannot seek\n")); return RMProcess_key_goto_cleanup; } return RMProcess_key_goto_wmapro_decoder_delete; } if ((pProcessContext->actions.cmd == RM_SEEK) && (!pProcessContext->actions.cmdProcessed)){ RMDBGLOG((ENABLE,"Got seek command\n")); if (release) { if (buffer != NULL) { RMDBGLOG((ENABLE, "release a buffer\n")); RUAReleaseBuffer(pProcessContext->pDMA, buffer); buffer = NULL; } else RMDBGLOG((ENABLE, "no buffer to release\n")); } if (RMFAILED(asf_seek(pProcessContext, pProcessContext->dcc_info->seek_time))) { RMDBGLOG((ENABLE,"Error during seek, abort.\n")); return RMProcess_key_goto_cleanup; } RM_PSM_SetState(pProcessContext->PSMcontext, &(pProcessContext->dcc_info), RM_PSM_Playing); DCCSTCSetSpeed(pProcessContext->dcc_info->pStcSource, pProcessContext->play_opt->speed_N, pProcessContext->play_opt->speed_M); pProcessContext->ignoreCallback = FALSE; pProcessContext->isIFrameMode = FALSE; pProcessContext->actions.cmdProcessed = TRUE; if (incallback) pProcessContext->ignoreCallback = TRUE; return RMProcess_key_goto_mainloop_seek; } if ((pProcessContext->actions.cmd == RM_DUALMODE_CHANGE) && (!pProcessContext->actions.cmdProcessed)) { fprintf(stderr, "Changing DualMode to :"); switch(pProcessContext->audio_opt[0].OutputDualMode) { case DualMode_LeftMono: fprintf(stderr, " RightMono\n"); pProcessContext->audio_opt[0].OutputDualMode = DualMode_RightMono; break; case DualMode_RightMono: fprintf(stderr, " MixMono\n"); pProcessContext->audio_opt[0].OutputDualMode = DualMode_MixMono; break; case DualMode_MixMono: fprintf(stderr, " Stereo\n"); pProcessContext->audio_opt[0].OutputDualMode = DualMode_Stereo; break; case DualMode_Stereo: fprintf(stderr, " LeftMono\n"); pProcessContext->audio_opt[0].OutputDualMode = DualMode_LeftMono; break; default: fprintf(stderr, " Unknown dual mode\n"); break; } for (i=0; i < pProcessContext->audioInstances; i++) { pProcessContext->audio_opt[i].OutputDualMode = pProcessContext->audio_opt[0].OutputDualMode; err = apply_audio_decoder_options_onthefly(pProcessContext->dcc_info, &(pProcessContext->audio_opt[i])); if (RMFAILED(err)) { fprintf(stderr, "Error applying audio decoder options on the fly %d\n", err); } } pProcessContext->actions.cmdProcessed = TRUE; } if (incallback){ if ((dataType == RM_STREAM_AUDIO) && (PlaybackStatus != RM_PSM_Playing) && (PlaybackStatus != RM_PSM_Paused) && (PlaybackStatus != RM_PSM_Prebuffering) && (pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE, "trickmode during audio callback\n")); if (!pProcessContext->sendAudioTrickmode) { RMDBGLOG((ENABLE, "ignoring audio payload\n")); pProcessContext->ignoreCallback = TRUE; return RMProcess_key_goto_nojump_but_exit; } RMDBGLOG((ENABLE, "sending audio while in trickmodes\n")); } if (((PlaybackStatus == RM_PSM_IForward) || (PlaybackStatus == RM_PSM_IRewind)) && (pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE, "iframe trick during callback\n")); pProcessContext->ignoreCallback = TRUE; return RMProcess_key_goto_nojump_but_exit; } if (((PlaybackStatus == RM_PSM_Slow) || (PlaybackStatus == RM_PSM_Fast)) && (pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE, "trickmodes during callback\n")); pProcessContext->isTrickMode = TRUE; pProcessContext->ignoreCallback = FALSE; asf_SyncTimerWithDecoderPTS(pProcessContext); } } pProcessContext->ignoreCallback = FALSE; if (pProcessContext->monitorFIFOs) asf_monitorFIFO(pProcessContext, FALSE); // No goto request if (got_key) return RMProcess_key_goto_got_key_but_noaction; else return 0; }/* function implementation */static RMuint64 round_int_div(RMuint64 numerator, RMuint32 divisor) { RMuint64 temp; temp = numerator / divisor; if ((numerator % divisor) * 2 > divisor) temp++; return temp;}static RMstatus asf_seek(struct asf_context * pSendContext, RMuint64 time){ RMuint32 seekTo; RMint64 position; seekTo = (RMuint32) time;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?