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 + -
显示快捷键?