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

📄 play_demux.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
					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"));			}		}		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;//				if (dataType == RMVDEMUX_VIDEO)					RUASetProperty(pSendContext->pRUA, pSendContext->dcc_info->video_decoder, RMGenericPropertyID_InbandCommand, &InbandCmd, sizeof(InbandCmd), 0);//				if (dataType == RMVDEMUX_AUDIO)					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;					if ( 0 && (Info.ValidFields & TIME_STAMP_INFO) ) {			RMuint32 pts;			err = RUAGetProperty(pSendContext->pRUA, decoder, RMGenericPropertyID_LastTransferredHwPts,				&pts, sizeof(pts));			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "RMGenericPropertyID_LastTransferredHwPts Error %d on decoder 0x%lx\n", err, decoder));			}			else {				RMDBGLOG((ENABLE, " %s in queue =  %ld ms\n",					string, (((RMuint32)Info.TimeStamp/2) - pts)/45));			}		}				/* 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;		pSendContext->spu_repack_offset = repack_offset;		pSendContext->spu_repack_size = repack_size;		pSendContext->spu_repack_pts = repack_pts;		pSendContext->spu_repack_pts_valid = repack_pts_valid;		break;	default:		RMDBGLOG((ENABLE, "Invalid data type %d\n", dataType));		return;	} return_from_callback:		return;}static void AC3DTSCallback(RMuint8 numberOfFrameHeaders, RMuint16 firstAccessUnitPointer, void *context){	struct demux_context *pSendContext = (struct demux_context *) context;	//RMDBGPRINT((ENABLE, "AC3DTSCallback: firstAccessUnitPointer= %x\n", firstAccessUnitPointer));	pSendContext->audio_first_access_unit_pointer_valid = TRUE;	pSendContext->audio_first_access_unit_pointer = firstAccessUnitPointer;	return;}static void LPCMCallback(RMuint8 numberOfFrameHeaders, RMuint16 firstAccessUnitPointer, RMuint32 frequency,			 RMuint8 numberOfChannels, RMvdemuxQuantization quantizationWordLength, void *context){	struct demux_context *pSendContext = (struct demux_context *) context;	//RMDBGPRINT((ENABLE, "LPCMCallback: firstAccessUnitPointer= %x\n", firstAccessUnitPointer));	pSendContext->audio_first_access_unit_pointer_valid = TRUE;	pSendContext->audio_first_access_unit_pointer = firstAccessUnitPointer;	return;}static void aobPcm_callback (RMuint16 firstAccessUnitPointer, 			     RMvdemuxQuantization quantizationGr1,			     RMvdemuxQuantization quantizationGr2,			     RMuint32 samplingFreqGr1,			     RMuint32 samplingFreqGr2,			     RMuint8 bitShift,			     RMuint8 channelAssign,			     void * context){}	static void mlp_callback (RMuint16 firstAccessUnitPointer, 			  RMuint8 forwardAUSearchPointer,			  RMuint8 backwardAUSearchPointer,			  void *context){}static RMstatus WaitForEOS(struct demux_context *context, struct RM_PSM_Actions *pActions){	RMuint32 eos_bit_field = 0;	enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(context->PSMcontext, &(context->dcc_info));	NTimes++;	if (verbose_stderr != 0)		fprintf(stderr, "File ready %ld times, waiting for EOS\n", NTimes);	if (context->video_byte_counter > 0) {		eos_bit_field |= EOS_BIT_FIELD_VIDEO;	}	if ((context->audio_byte_counter > 0) && 	    ((PlaybackStatus == RM_PSM_Playing) ||	     (PlaybackStatus == RM_PSM_Prebuffering))) {		eos_bit_field |= EOS_BIT_FIELD_AUDIO;	}		return WaitForEOSWithCommand(context->PSMcontext, &(context->dcc_info), pActions, eos_bit_field);}static RMstatus InitUserDataProcessing(struct demux_context *pcontext){	RMstatus err;		switch(user_data_app_mode) {	case user_data_dma_full_buffer:	case user_data_dma_no_delay:	case user_data_dma_minimum_size:	case user_data_dma_exact_size:	    {		struct Receive_type Receive;		Receive.pRUA = pcontext->pRUA;		Receive.targetModule = EMHWLIB_TARGET_MODULE(VideoDecoder, EMHWLIB_MODULE_INDEX(pcontext->dcc_info->video_decoder), 1);		Receive.buffer_count = 4;		Receive.buffer_size_log2 = 12;	// 4k per buffer -> 16M		err = DCCOpenReceive(&Receive, &pcontext->pReceive, &pcontext->pDmaUserData);		if (user_data_app_mode == user_data_dma_no_delay) {			struct EMhwlibReadBufferCompletion bc;			bc.mode = EMhwlibReadBufferCompletionMode_NoDelay; /* complete the buffer as soon as the microcode sent data */			bc.threshold = 0; /* ignored */			err = RUASetProperty(pcontext->pRUA, Receive.targetModule, RMGenericPropertyID_ReadBufferCompletion, &bc, sizeof(bc), 0);			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "RMGenericPropertyID_ReadBufferCompletion Error %d\n", err));				return err;			}		}		else if (user_data_app_mode == user_data_dma_minimum_size) {			struct EMhwlibReadBufferCompletion bc;			bc.mode = EMhwlibReadBufferCompletionMode_MinimumSize; /* complete the buffer when the buffer has more than the threshold value */			bc.threshold = 256;			err = RUASetProperty(pcontext->pRUA, Receive.targetModule, RMGenericPropertyID_ReadBufferCompletion, &bc, sizeof(bc), 0);			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "RMGenericPropertyID_ReadBufferCompletion Error %d\n", err));				return err;			}		}		else if (user_data_app_mode == user_data_dma_exact_size) {			struct EMhwlibReadBufferCompletion bc;			bc.mode = EMhwlibReadBufferCompletionMode_ExactSize; /* complete the buffer when the buffer has exactly the threshold value */			bc.threshold = 256;			err = RUASetProperty(pcontext->pRUA, Receive.targetModule, RMGenericPropertyID_ReadBufferCompletion, &bc, sizeof(bc), 0);			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "RMGenericPropertyID_ReadBufferCompletion Error %d\n", err));				return err;			}		}		break;	    }	case user_data_get_chunk256_without_dma:		break;	case user_data_rua_mapping_without_dma:	    {		struct gbus_fifo *fifo;		struct UserDataFIFOInfo udfi;		if (pllad == NULL) {			pllad = llad_open("0");			pgbus = gbus_open(pllad);		}		err = RUAGetProperty(pcontext->pRUA, VideoDecoder, RMVideoDecoderPropertyID_UserDataFIFOInfo,			&udfi, sizeof(udfi));		fifo = (struct gbus_fifo *)udfi.ContainerAddress;		pcontext->user_data_fifo_base = gbus_read_uint32(pgbus, (RMuint32) &(fifo->base));		pcontext->user_data_fifo_size = gbus_read_uint32(pgbus, (RMuint32) &(fifo->size));		if ( (pcontext->user_data_fifo_base == 0) || (pcontext->user_data_fifo_size == 0) ) {			fprintf(stderr, "USER_DATA ERROR: user_data_fifo_base or user_data_fifo_size is NULL\n");			return RM_ERROR;		}		pcontext->user_data_fifo_container = udfi.ContainerAddress;		RMDBGLOG((DISABLE, "user_data_fifo_container=%lx base=%lx size=%lx\n",			pcontext->user_data_fifo_container, pcontext->user_data_fifo_base, pcontext->user_data_fifo_size));		err = RUALock(pcontext->pRUA, pcontext->user_data_fifo_base, pcontext->user_data_fifo_size);		if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "USER_DATA ERROR: Unable to lock output!\n"));		}		pcontext->pmapped_user_data_fifo_base = RUAMap(pcontext->pRUA, pcontext->user_data_fifo_base, pcontext->user_data_fifo_size);		break;	    }	case no_user_data:	default:		return RM_OK;	}		pcontext->f_record = fopen("userdata.bin", "wb");	if (pcontext->f_record == NULL)		RMDBGLOG((ENABLE, "Error opening userdata.bin"));	pcontext->f_record_size = 0;	return RM_OK;}static void SaveUserData(struct demux_context *pcontext){	RMstatus err;	RMuint32 targetModule = EMHWLIB_TARGET_MODULE(VideoDecoder, EMHWLIB_MODULE_INDEX(pcontext->dcc_info->video_decoder), 1);	struct RUAEvent e;	e.ModuleID = pcontext->dcc_info->video_decoder;		switch(user_data_app_mode) {	case user_data_dma_full_buffer:	case user_data_dma_no_delay:

⌨️ 快捷键说明

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