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

📄 play_vdemux.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
	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); 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;	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;	}	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					if (dataType == RMVDEMUX_VIDEO)						prevVpts = Info.TimeStamp;									if (dataType == RMVDEMUX_AUDIO)						prevApts = Info.TimeStamp;#endif				}				else if (!(play_opt->send_audio_pts || play_opt->send_audio_pts)) {					Info.TimeStamp = 0;					RMDBGLOG((ENABLE, "No PTS -> Init FirstSystemTimeStamp = %llu\n", Info.TimeStamp));					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					prevVpts = Info.TimeStamp;					prevApts = Info.TimeStamp;#endif				}				else					RMDBGLOG((ENABLE, "waiting for valid PTS\n"));			}		}		//fprintf( stderr, "send buffer5  0x%lx, sendbuffer 0x%lx length 0x%lx\n", decoder, send_buffer, send_length );		if ((pSendContext->waitForValidAudioPTS) && (dataType == RMVDEMUX_AUDIO) && (send_pts)) {			if (Info.ValidFields & TIME_STAMP_INFO) {				RMDBGLOG((ENABLE, "first valid audio PTS %llu(0x%09llx), start sending audio\n",Info.TimeStamp,Info.TimeStamp));				pSendContext->waitForValidAudioPTS = FALSE;#ifdef PTS_DISCONTINUITY_DETECTION				prevApts = Info.TimeStamp;#endif			}			else {				// dont send audio with invalid pts				RMDBGLOG((ENABLE, "audio pts not valid\n"));				if (isPtsValid) {					repack_pts_valid = TRUE;					repack_pts = PTS;				}				goto end_data_callback;			}		}		if ((pSendContext->waitForValidVideoPTS) && (dataType == RMVDEMUX_VIDEO) && (send_pts)) {			if (Info.ValidFields & TIME_STAMP_INFO) {				RMDBGLOG((ENABLE, "first valid video PTS %llu(0x%09llx), start sending video\n",Info.TimeStamp,Info.TimeStamp));				pSendContext->waitForValidVideoPTS = FALSE;#ifdef PTS_DISCONTINUITY_DETECTION				prevVpts = Info.TimeStamp;#endif			}			else {				// dont send video with invalid pts				RMDBGLOG((ENABLE, "video pts not valid\n"));				if (isPtsValid) {					repack_pts_valid = TRUE;					repack_pts = PTS;				}				goto end_data_callback;			}		}#ifdef PTS_DISCONTINUITY_DETECTION		if (Info.ValidFields & TIME_STAMP_INFO) {			RMint64 diff = 0;			if ((pSendContext->fakePrevPts) && (dataType == RMVDEMUX_AUDIO)) {				RMDBGPRINT((ENABLE, "Set prevAPTS to 0x%09llx\n", Info.TimeStamp));				prevApts = Info.TimeStamp;				pSendContext->fakePrevPts = FALSE;			}			if ((dataType == RMVDEMUX_VIDEO) && (prevVpts != 0xffffffffffffffffll)) {				diff = Info.TimeStamp - prevVpts;				prevVpts = Info.TimeStamp;				RMDBGPRINT((DISABLE, "Vpts = %9llx %8lx (%lx)\n", Info.TimeStamp, pSendContext->video_byte_counter, file_offset));			} 			else if ((dataType == RMVDEMUX_AUDIO) && (prevApts != 0xffffffffffffffffll)) {				diff = Info.TimeStamp - prevApts;				prevApts = Info.TimeStamp;				RMDBGPRINT((DISABLE, "Apts = %9llx %8lx (%lx)\n", Info.TimeStamp, pSendContext->audio_byte_counter, file_offset));			}			if ((diff < -PTS_DISCONTINUITY_RANGE) || (diff > PTS_DISCONTINUITY_RANGE)) {				struct InbandCommand_type InbandCmd;				RMDBGPRINT((ENABLE, "%spts discontinuity = %9llx -> %9llx\n", (dataType == RMVDEMUX_VIDEO)?"V":"A", Info.TimeStamp-diff, Info.TimeStamp));				DCCSTCSetDiscontinuity(pSendContext->dcc_info->pStcSource, Info.TimeStamp-2*90000, 90000);								InbandCmd.Tag = INBAND_COMMAND_TAG_DISCONTINUITY | INBAND_COMMAND_ACTION_STOP;				InbandCmd.Coordinate = 0;				RUASetProperty(pSendContext->pRUA, pSendContext->dcc_info->video_decoder, RMGenericPropertyID_InbandCommand, &InbandCmd, sizeof(InbandCmd), 0);				RUASetProperty(pSendContext->pRUA, pSendContext->dcc_info->audio_decoder, RMGenericPropertyID_InbandCommand, &InbandCmd, sizeof(InbandCmd), 0);			}		}#endif	// PTS_DISCONTINUITY_DETECTION		if (PlaybackStatus == RM_PSM_Prebuffering) {			RMDBGPRINT((ENABLE, "%s", dataType == RMVDEMUX_AUDIO ? "a":"v"));		}		{			RMuint64 stc;			DCCSTCGetTime(pSendContext->dcc_info->pStcSource, &stc, 90000);			RMDBGLOG((SENDDBG, "sending %s, %lu, pts %llu(0x%09llx) %s stc %llu(0x%09llx)\n", 				  dataType == RMVDEMUX_AUDIO ? "audio":"video",				  send_length,				  Info.TimeStamp,				  Info.TimeStamp,				  Info.ValidFields & TIME_STAMP_INFO ? "valid":"",				  stc,				  stc));		}		if (Info.ValidFields & TIME_STAMP_INFO) {			static RMint64 max_diff = 0, min_diff = 0;			RMint64 diff;			if ( (prevVpts != 0xffffffffffffffffll) && (prevApts != 0xffffffffffffffffll) ) {				diff = (RMint64)(prevVpts - prevApts) / (RMint64)90; /* diff in miliseconds */				RMDBGLOG((DISABLE, "diff %lld %llx %llx\n", diff, prevVpts, prevApts));				if ( (diff < -100) || (diff > 100)) {					if ( (diff > 0) && (diff > max_diff+100) ) {						max_diff = diff;						RMDBGLOG((ENABLE, " %lld\n", diff));					}					if ( (diff < 0) && (diff < min_diff-100) ) {						min_diff = diff;						RMDBGLOG((ENABLE, " %lld\n", diff));					}				}			}		}				while( RUASendData(pSendContext->pRUA, decoder, pSendContext->pDMA, send_buffer, send_length, (void*)&Info, sizeof(Info)) != RM_OK ) {			struct RUAEvent e;			check_prebuf_state(pSendContext, 0);			PROCESS_KEY_INSIDE_FUNCTION();			PlaybackStatus = RM_PSM_GetState(pSendContext->PSMcontext, &(pSendContext->dcc_info));			/* skip audio in trickmode */			if ((dataType == RMVDEMUX_AUDIO) && 			    ((PlaybackStatus == RM_PSM_Slow) || (PlaybackStatus == RM_PSM_Fast) || (PlaybackStatus == RM_PSM_NextPic)))				goto end_data_callback;			e.ModuleID = decoder;			e.Mask = RUAEVENT_XFER_FIFO_READY;			RUAWaitForMultipleEvents(pSendContext->pRUA, &e, 1, SENDDATA_TIMEOUT_US, NULL);		}				if ( pbyte_counter )			*pbyte_counter = *pbyte_counter + send_length;					/* sendind data may fill-up the xfer fifo, so we reset the event */		{			struct RUAEvent e;						e.ModuleID = decoder;			e.Mask = RUAEVENT_XFER_FIFO_READY;			RUAResetEvent(pSendContext->pRUA, &e);		}	}		if (pSendContext->repack_sample) {		RMuint32 val;		val = RMmax(length, REPACK_SIZE);		if ((repack_offset + val) > (RMuint32) (1<<play_opt->dmapool_log2size)) {			RUAReleaseBuffer(pSendContext->pDMA, repack_buffer);			repack_buffer = (RMuint8 *) NULL;			repack_offset = 0;		}		if (repack_buffer == NULL) {			while (RUAGetBuffer(pSendContext->pDMA, &repack_buffer,  GETBUFFER_TIMEOUT_US) != RM_OK) {				PROCESS_KEY_INSIDE_FUNCTION();				RMDBGLOG((DISABLE, "Wait for a buffer\n"));			}		}		memcpy(repack_buffer + repack_offset + repack_size, buffer, length);		repack_size += length;		if (isPtsValid) {			repack_pts_valid = TRUE;			repack_pts = PTS;		}	}		 end_data_callback:	switch (dataType) {	case RMVDEMUX_VIDEO:		pSendContext->video_repack_buf = repack_buffer;		pSendContext->video_repack_offset = repack_offset;		pSendContext->video_repack_size = repack_size;		pSendContext->video_repack_pts = repack_pts;		pSendContext->video_repack_pts_valid = repack_pts_valid;		break;	case RMVDEMUX_AUDIO:		pSendContext->audio_repack_buf = repack_buffer;		pSendContext->audio_repack_offset = repack_offset;		pSendContext->audio_repack_size = repack_size;		pSendContext->audio_repack_pts = repack_pts;		pSendContext->audio_repack_pts_valid = repack_pts_valid;		break;	case RMVDEMUX_SUBPICTURE:		pSendContext->spu_repack_buf = repack_buffer;

⌨️ 快捷键说明

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