⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 play_demux.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
			}		}	}	return err;}// used for prebufferingstatic RMstatus Pause(struct demux_context * pSendContext, RMuint32 devices){	RMstatus err = RM_OK;		if (devices & RM_DEVICES_VIDEO) {		if (pSendContext->dcc_info->pVideoSource) {			RMDBGLOG((ENABLE, "PAUSE: video decoder\n"));			err = DCCPauseVideoSource(pSendContext->dcc_info->pVideoSource);			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "Cannot pause video decoder %d\n", err));				return err;			}		}	}	if (devices & RM_DEVICES_AUDIO) {		if (pSendContext->dcc_info->pAudioSource) {			RMDBGLOG((ENABLE, "PAUSE: audio decoder\n"));			err = DCCPauseAudioSource(pSendContext->dcc_info->pAudioSource);			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "Cannot pause video decoder %d\n", err));				return err;			}		}	}	if (devices & RM_DEVICES_STC) {		RMDBGLOG((ENABLE, "PAUSE: stc\n"));		DCCSTCStop(pSendContext->dcc_info->pStcSource);	}	return err;}static RMstatus SyncTimerWithDecoderPTS(struct demux_context *pSendContext){	RMuint64 videoPTS;	RMuint64 CurrentSTC;	RMstatus err = RM_OK;	RMuint32 timeScale;	/* we have to obtain the timeScale because in mpeg4 elementary 	   streams, the time scale is not guaranteed to be 90KHz 	*/	DCCSTCGetTimeResolution(pSendContext->dcc_info->pStcSource, DCC_Video, &timeScale);	DCCSTCGetTime(pSendContext->dcc_info->pStcSource, &CurrentSTC, timeScale);	err = RUAGetProperty(pSendContext->pRUA, pSendContext->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &videoPTS, sizeof(videoPTS));	if (err != RM_OK) {		RMDBGLOG((ENABLE, "error %d while getting CurrentDisplayPTS\n", err));		return err;	}	/* for MPEG1/2, timeScale 90000, videoPTS unit is 45000 always,	   for MPEG4, timeScale is the same than videoPTS unit.	   Note however, that we're just checking the value of timeScale, so	   if we're in MPEG4 and timeScale 90000, this wont work. Also note that	   this happens with elementary streams which are to be handled by	   play_video not play_demux. 	*/	if (timeScale == 90000)		videoPTS *= 2;		RMDBGLOG((ENABLE, ">> resync timer (%llu) with videoDecoder current PTS (%llu), unit %lu\n", CurrentSTC, videoPTS, timeScale));	DCCSTCSetTime(pSendContext->dcc_info->pStcSource, videoPTS, timeScale);#ifdef PTS_DISCONTINUITY_DETECTION	pSendContext->fakePrevPts = TRUE;#endif	return RM_OK;	}static RMbool check_prebuf_state(struct demux_context *pSendContext, RMuint32 buffersize){	RMbool quit_prebuf;	enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(pSendContext->PSMcontext, &(pSendContext->dcc_info));		if (PlaybackStatus != RM_PSM_Prebuffering)		return FALSE;	/* if fail in getbuffer/senddata force quitting prebuffering state */	quit_prebuf = ((buffersize == 0) || ((play_opt->prebuf_max > 0) && (pSendContext->prebufferedBytes >= play_opt->prebuf_max))) ? TRUE : FALSE;	pSendContext->prebufferedBytes += buffersize;			if (quit_prebuf) {		RMDBGLOG((ENABLE, "exit prebuffering state, enter play state (bufsize %lu, prebuffered %lu)\n", buffersize, pSendContext->prebufferedBytes));		if (manutest != TRUE)			fprintf(stderr, "now playing\n");		RM_PSM_SetState(pSendContext->PSMcontext, &(pSendContext->dcc_info), RM_PSM_Playing);		DCCSTCSetTime(pSendContext->dcc_info->pStcSource, pSendContext->realFirstPTS, 90000);		Play(pSendContext, RM_DEVICES_STC | RM_DEVICES_VIDEO | RM_DEVICES_AUDIO, DCCVideoPlayFwd);		pSendContext->prebufferedBytes = 0;		return TRUE;	}	return FALSE;}static void flush_repacked_sample(void *context){	struct demux_context *pSendContext = (struct demux_context *) context;	RMuint8 *send_buffer = (RMuint8 *) NULL;	RMuint32 send_length = 0;	RMuint32 decoder;	struct emhwlib_info Info;	/* flush video data */	if ( ! play_opt->send_video)		goto flush_audio;	if (pSendContext->video_repack_buf == NULL)		goto flush_audio;	decoder = pSendContext->dcc_info->video_decoder;	send_buffer = pSendContext->video_repack_buf + pSendContext->video_repack_offset;	send_length = pSendContext->video_repack_size;	Info.ValidFields = (pSendContext->video_repack_pts_valid) ? TIME_STAMP_INFO : 0;	Info.TimeStamp = pSendContext->video_repack_pts;	while (RUASendData(pSendContext->pRUA, decoder, pSendContext->pDMA, send_buffer, send_length, (void*)&Info, sizeof(Info)) != RM_OK) {		struct RUAEvent e;		PROCESS_KEY_INSIDE_FUNCTION();		e.ModuleID = decoder;		e.Mask = RUAEVENT_XFER_FIFO_READY;		RUAWaitForMultipleEvents(pSendContext->pRUA, &e, 1, SENDDATA_TIMEOUT_US, NULL);	}	RUAReleaseBuffer(pSendContext->pDMA, send_buffer);	pSendContext->video_repack_buf = NULL;		 flush_audio:	/* flush audio data */	if ( ! play_opt->send_audio)		goto flush_spu;	if (pSendContext->audio_repack_buf == NULL)		goto flush_spu;	if (pSendContext->isTrickMode)		goto flush_spu;		decoder = pSendContext->dcc_info->audio_decoder;	send_buffer = pSendContext->audio_repack_buf + pSendContext->audio_repack_offset;	send_length = pSendContext->audio_repack_size;	Info.ValidFields = (pSendContext->audio_repack_pts_valid) ? TIME_STAMP_INFO : 0;	Info.TimeStamp = pSendContext->audio_repack_pts;	while (RUASendData(pSendContext->pRUA, decoder, pSendContext->pDMA, send_buffer, send_length, (void*)&Info, sizeof(Info)) != RM_OK) {		struct RUAEvent e;				PROCESS_KEY_INSIDE_FUNCTION();		e.ModuleID = decoder;		e.Mask = RUAEVENT_XFER_FIFO_READY;		RUAWaitForMultipleEvents(pSendContext->pRUA, &e, 1, SENDDATA_TIMEOUT_US, NULL);	}	RUAReleaseBuffer(pSendContext->pDMA, send_buffer);	pSendContext->audio_repack_buf = NULL;	 flush_spu:	/* flush spu data */	if ( ! play_opt->send_spu)		return;#ifdef	ENABLE_SPU_OP	if (! pSendContext->enable_spu) {		return;	}#else	return;#endif	if (pSendContext->spu_repack_buf == NULL)		return;	decoder = pSendContext->dcc_info->spu_decoder;	send_buffer = pSendContext->spu_repack_buf + pSendContext->spu_repack_offset;	send_length = pSendContext->spu_repack_size;	Info.ValidFields = (pSendContext->spu_repack_pts_valid) ? TIME_STAMP_INFO : 0;	Info.TimeStamp = pSendContext->spu_repack_pts;	while (RUASendData(pSendContext->pRUA, decoder, pSendContext->pDMA, send_buffer, send_length, (void*)&Info, sizeof(Info)) != RM_OK) {		struct RUAEvent e;		PROCESS_KEY_INSIDE_FUNCTION();		e.ModuleID = decoder;		e.Mask = RUAEVENT_XFER_FIFO_READY;		RUAWaitForMultipleEvents(pSendContext->pRUA, &e, 1, SENDDATA_TIMEOUT_US, NULL);	}	RUAReleaseBuffer(pSendContext->pDMA, send_buffer);	pSendContext->spu_repack_buf = NULL; return_from_callback:	return;}static void PESCallback(RMuint8 *buffer, RMuint32 length, RMuint64 PTS, RMbool isPtsValid,			RMvdemuxDataType dataType, RMuint64 PESOffset, void *context){	static RMascii *decoder_name[] = {"video", "audio", "spu"};	RMascii *string;	struct demux_context *pSendContext = (struct demux_context *) context;	RMuint32 decoder;	struct emhwlib_info Info;	RMbool send_data = FALSE;	RMuint8 *send_buffer = (RMuint8 *) NULL;	RMuint32 send_length = 0;	RMuint8 *repack_buffer;	RMuint64 repack_pts;	RMuint32 repack_offset, repack_size;	RMbool repack_pts_valid;	RMuint32 send_pts;	RMstatus err;	RMuint32 *pbyte_counter = 0;	RMuint32 first_access_unit_pointer = 0;	RMbool isFirstAccessUnitValid = FALSE;	enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(pSendContext->PSMcontext, &(pSendContext->dcc_info));#ifdef PTS_DISCONTINUITY_DETECTION	static RMuint64 prevVpts = 0xffffffffffffffffll;	static RMuint64 prevApts = 0xffffffffffffffffll;#endif	if (pSendContext->ignoreCallback) {		if ((actions.cmd == RM_QUIT) && (!actions.cmdProcessed)) {			RMDBGLOG((ENABLE, "callback called when 'quit' command was issued\n"));			goto return_from_callback;		}		if ((PlaybackStatus == RM_PSM_Stopped) && (actions.cmdProcessed)) {			RMDBGLOG((ENABLE, "callback called when 'stop' command was issued\n"));			goto return_from_callback;		}		if ((actions.cmd == RM_STOP_SEEK_ZERO)  && (!actions.cmdProcessed)) {			RMDBGLOG((ENABLE, "callback called when 'seekzero' command was issued\n"));			goto return_from_callback;		}		if ((actions.cmd == RM_SEEK) && (!actions.cmdProcessed)) {				RMDBGLOG((ENABLE, "callback called when 'seek' command was issued\n"));			goto return_from_callback;		}		if (((actions.cmd == RM_IFWD) || (actions.cmd == RM_IRWD)) && (actions.cmdProcessed)) {				RMDBGLOG((ENABLE, "callback called when 'iframe' command was issued\n"));			goto return_from_callback;		}		RMDBGLOG((ENABLE, "********** ignoring Callback!! *********, cmd %lu, processed %lu\n", actions.cmd, actions.cmdProcessed));		goto return_from_callback;	}	switch (dataType) {	case RMVDEMUX_AUDIO:		if (pSendContext->audio_first_access_unit_pointer_valid) {			isFirstAccessUnitValid = TRUE;			first_access_unit_pointer = pSendContext->audio_first_access_unit_pointer;			pSendContext->audio_first_access_unit_pointer_valid = FALSE;		}		break;	default:		isFirstAccessUnitValid = FALSE;		first_access_unit_pointer = 0;		break;	}	/* uncomment to save only when in iframe mode (debug purposes)	   if (pSendContext->dcc_info->trickmode_id == RM_TRICKMODE_RWD_IFRAME) { */		err = dump_data_into_file(play_opt, dataType, buffer, length, PTS, isPtsValid, first_access_unit_pointer);		if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Cannot dump data %d\n", err));			return;		}		/* } */		switch (dataType) {	case RMVDEMUX_VIDEO:		if ( ! play_opt->send_video)			return ;		decoder = pSendContext->dcc_info->video_decoder;		string = decoder_name[0];		send_pts = play_opt->send_video_pts;		repack_buffer = pSendContext->video_repack_buf;		repack_offset = pSendContext->video_repack_offset;		repack_size = pSendContext->video_repack_size;		repack_pts = pSendContext->video_repack_pts;		repack_pts_valid = pSendContext->video_repack_pts_valid;		pbyte_counter = &pSendContext->video_byte_counter;//		printf("Sending %lu bytes of video data\n", length);		break;	case RMVDEMUX_AUDIO:		if ( ! play_opt->send_audio)			return ;		if ((PlaybackStatus != RM_PSM_Playing) && (PlaybackStatus != RM_PSM_Paused) && (PlaybackStatus != RM_PSM_Prebuffering))			return;	       		decoder = pSendContext->dcc_info->audio_decoder;		string = decoder_name[1];		send_pts = play_opt->send_audio_pts;		repack_buffer = pSendContext->audio_repack_buf;		repack_offset = pSendContext->audio_repack_offset;		repack_size = pSendContext->audio_repack_size;		repack_pts = pSendContext->audio_repack_pts;		repack_pts_valid = pSendContext->audio_repack_pts_valid;		pbyte_counter = &pSendContext->audio_byte_counter;//		printf("Sending Audio data\n");		break;	case RMVDEMUX_SUBPICTURE:		if ( ! play_opt->send_spu)			return ;#ifdef	ENABLE_SPU_OP		if (! pSendContext->enable_spu) {			RMDBGPRINT((ENABLE, "disabled spu\n"));			return;		}#else		return;#endif		decoder = pSendContext->dcc_info->spu_decoder;		string = decoder_name[2];		send_pts = play_opt->send_spu_pts;		repack_buffer = pSendContext->spu_repack_buf;		repack_offset = pSendContext->spu_repack_offset;		repack_size = pSendContext->spu_repack_size;		repack_pts = pSendContext->spu_repack_pts;		repack_pts_valid = pSendContext->spu_repack_pts_valid;		break;	case RMVDEMUX_NAVIGATION:		RMDBGPRINT((ENABLE, "navigation\n"));		return;	default:		RMDBGPRINT((ENABLE, "Unknown data type %d\n", dataType));		return;	}	if ((pSendContext->repack_sample) && (repack_size>0) && 	    ((isPtsValid) || (repack_offset + length > (RMuint32) (1<<play_opt->dmapool_log2size)) || (repack_size + length > REPACK_SIZE))) {	    send_buffer = repack_buffer + repack_offset;		send_length = repack_size;		Info.ValidFields = (repack_pts_valid && send_pts) ? TIME_STAMP_INFO : 0;		Info.TimeStamp = repack_pts;		send_data = TRUE;				repack_offset += repack_size;		repack_size = 0;		repack_pts = 0;		repack_pts_valid = FALSE;	}	else if (!pSendContext->repack_sample) {		send_buffer = buffer;		send_length = length;		Info.ValidFields = ((isPtsValid && send_pts) ? TIME_STAMP_INFO : 0) | (isFirstAccessUnitValid ? FIRST_ACCESS_UNIT_POINTER_INFO : 0);		Info.TimeStamp = PTS;		Info.FirstAccessUnitPointer = first_access_unit_pointer;		send_data = TRUE;	}	if (send_data) {		if (1/*(PlaybackStatus == RM_PSM_Playing) || (PlaybackStatus == RM_PSM_Paused) || (PlaybackStatus == RM_PSM_NextPic)*/) {			if (pSendContext->FirstSystemTimeStamp) {				if (Info.ValidFields & TIME_STAMP_INFO) {					RMDBGLOG((ENABLE, "FirstSystemTimeStamp from %s = %llu = 0x%llx (0x%llx)\n", string, Info.TimeStamp, Info.TimeStamp, Info.TimeStamp/2));					pSendContext->realFirstPTS = (RMint64) (Info.TimeStamp + pSendContext->start_90khz);					// set the STC to 1sec before the real value, so that we dont the first frame when prebuffering					DCCSTCSetTime(pSendContext->dcc_info->pStcSource, (RMuint64)(pSendContext->realFirstPTS - 90000), 90000);					pSendContext->FirstSystemTimeStamp = FALSE;#ifdef PTS_DISCONTINUITY_DETECTION

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -