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

📄 play_vdemux.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
		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;	NTimes++;	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) {		eos_bit_field |= EOS_BIT_FIELD_AUDIO;	}		return WaitForEOSWithCommand(context->PSMcontext, &(context->dcc_info), pActions, eos_bit_field);}// thread functionvoid *main_vdemux( void * context_data ){	struct display_context disp_info;	struct DCCVideoSource *pVideoSource = NULL;	struct DCCAudioSource *pAudioSource = NULL;	struct RUABufferPool *pDMA = NULL;	ExternalRMvdemux demux;	struct demux_context context;	RMstatus err;	RMfile file = NULL;	RMuint32 videoscaler_id = 0;	RMuint8 *repack_buf = (RMuint8 *) NULL;		void **dmabuffer_array = (void **) NULL;	RMuint32 dmabuffer_index = 0;	RMuint32 error = 0;	struct RM_PSM_Context PSMContext;	RMMemset(&context, 0, sizeof(struct demux_context));	{		struct context_per_task * task = (struct context_per_task *)context_data;				dcc_info.disp_info = &disp_info;		play_opt = task->play_opt;		video_opt = task->video_opt;		audio_opt = task->audio_opt;		demux_opt = task->demux_opt;		disp_opt = task->disp_opt;		dcc_info.pRUA = task->pRUA;		dcc_info.pDCC = task->dcc_info->pDCC;		dcc_info.disp_info = NULL;		videoscaler_id = 0; //mono->video_scaler;		dcc_info.route = DCCRoute_Main;				RMDBGLOG((ENABLE, "created thread play_opt %lx, video_opt %lx, audio_opt %lx, disp_opt %lx, videoscaler %d\n", 			play_opt, video_opt, audio_opt, demux_opt, videoscaler_id ));				RMMemcpy( &dcc_info, task->dcc_info, sizeof( struct dcc_context ) );		pVideoSource = task->dcc_info->pVideoSource;		pAudioSource = task->dcc_info->pMultipleAudioSource->AudioSourceHandles[0].pAudioSource;		dcc_info.pAudioSource = dcc_info.pMultipleAudioSource->AudioSourceHandles[0].pAudioSource;				// the software demux thread has its own demux context with the main thread				context.pRUA = dcc_info.pRUA; // share the same rua,  however use separate pDMA for transfer		context.dcc_info = &dcc_info; // separate copy of dcc		context.PSMcontext = &PSMContext; 				play_opt->prebuf_max = 1*1024*1024;  // force a limit on prebuffering		context.repack_sample = TRUE; 		demux_opt->repack_sample = TRUE;	}	// create software demux	if(demux_opt->system_type != RM_SYSTEM_UNKNOWN) {		err = RMCreateVdemux(&demux);		if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Cannot create demux %d\n", err));			goto exit_with_error;		}		//RMvdemuxSetType(demux, demux_opt->system_type);		RMvdemuxSetType(demux, RM_SYSTEM_MPEG2_TRANSPORT);		RMDBGLOG((ENABLE, "Cannot set system type %d.  ", err, demux_opt->system_type ));		RMDBGLOG((ENABLE, "Force system type to %d\n", err, RM_SYSTEM_MPEG2_TRANSPORT ));				RMvdemuxSetCallbackData(demux, PESCallback, &context);		RMvdemuxSetAudioCallbacks(demux, AC3DTSCallback, LPCMCallback, aobPcm_callback, mlp_callback);	}	else {		demux = (ExternalRMvdemux)NULL;		RMDBGLOG((ENABLE, "System Type Unknown, exiting\n"));		err = RM_ERROR;		goto exit_with_error;	}	dcc_info.chip_num = play_opt->chip_num;	RMDBGLOG((ENABLE, "disk_ctrl_low_level %d, disk_ctrl_log2_block_size %d, disk_ctrl_max_mem %d \n",				 (int)play_opt->disk_ctrl_low_level, (int)play_opt->disk_ctrl_log2_block_size, (int)play_opt->disk_ctrl_max_mem ));	/* if HD control is enabled and mode is auto, setup parameters */	if ((play_opt->disk_ctrl_low_level) &&	    (play_opt->disk_ctrl_log2_block_size) &&	    (play_opt->disk_ctrl_max_mem)) {		RMuint32 bufferSize = 0;		RMuint32 bufferCount = 0;		RMuint32 log2BlockSize = play_opt->disk_ctrl_log2_block_size;		RMuint32 maxBufferingMem = play_opt->disk_ctrl_max_mem;		bufferSize = (1 << log2BlockSize);		bufferCount = maxBufferingMem >> log2BlockSize;			play_opt->dmapool_count = bufferCount;		play_opt->dmapool_log2size = log2BlockSize;			if (play_opt->disk_ctrl_low_level >= bufferCount)			play_opt->disk_ctrl_low_level = bufferCount >> 1;			video_opt->fifo_size = 4 * (1024 * 1024);		audio_opt->fifo_size = 2 * (1024 * 1024);		fprintf(stderr, ">> low level %lu => %lu bytes bufferized (+ bitstreamFIFO)\n", 			play_opt->disk_ctrl_low_level,			play_opt->disk_ctrl_low_level * bufferSize);			video_opt->xfer_count = (bufferSize / 512) * bufferCount;		audio_opt->xfer_count = (bufferSize / 512) * bufferCount;		err = setup_disk_control_parameters(&dcc_info, play_opt, audio_opt, video_opt, NULL);		if (err != RM_OK) {			fprintf(stderr, "Error %d trying to setup HD control params\n", err);			goto exit_with_error;		}	}	switch (play_opt->disk_ctrl_state) {	case DISK_CONTROL_STATE_DISABLE:		break;	case DISK_CONTROL_STATE_SLEEPING:	case DISK_CONTROL_STATE_RUNNING:		dmabuffer_array = (void **) RMMalloc(sizeof(void*) * play_opt->dmapool_count);		dmabuffer_index = 0;		if (dmabuffer_array == NULL) {			RMDBGLOG((ENABLE, "Cannot allocate dmapool array! Disable disk control\n"));			play_opt->disk_ctrl_state = DISK_CONTROL_STATE_DISABLE;		}		break;	}	// dmapool must be created after the module open in case we do no copy transfers */	RMDBGLOG((ENABLE, "Open pool %lu, %lu  0x%x\n", play_opt->dmapool_count, play_opt->dmapool_log2size, pDMA ));	err = RUAOpenPool(dcc_info.pRUA, 0, play_opt->dmapool_count, play_opt->dmapool_log2size, RUA_POOL_DIRECTION_SEND, &pDMA);	if (RMFAILED(err)) {		RMuint32 poolSize = play_opt->dmapool_count << play_opt->dmapool_log2size;		fprintf(stderr, "Error cannot open dmapool %d\n\n"			"requested %lu bytes of dmapool (%lu buffers of %lu bytes), make sure you\n"			"loaded llad with the right parameters. For example:\n"			"max_dmapool_memory_size >= %lu max_dmabuffer_log2_size >= %lu\n\n",			err,			poolSize,			play_opt->dmapool_count,			(RMuint32)(1<<play_opt->dmapool_log2size),			poolSize,			play_opt->dmapool_log2size);		goto exit_with_error;	}	RMDBGLOG((ENABLE, "Opened pool 0x%lx\n", pDMA ));	dcc_info.pVideoSource = pVideoSource;	dcc_info.pAudioSource = pAudioSource;	dcc_info.trickmode_id = RM_NO_TRICKMODE;	dcc_info.seek_supported = FALSE;	err = DCCGetVideoDecoderSourceInfo(pVideoSource, &(dcc_info.video_decoder), &(dcc_info.spu_decoder), &(dcc_info.video_timer));	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error getting video decoder source information %d\n", err));		goto exit_with_error;	}	err = DCCGetAudioDecoderSourceInfo(pAudioSource, &(dcc_info.audio_decoder), &(dcc_info.audio_engine), &(dcc_info.audio_timer));	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error getting audio decoder source information %d\n", err));		goto exit_with_error;	}	context.pRUA = dcc_info.pRUA;	context.pDMA = pDMA;	context.repack_sample = demux_opt->repack_sample;	context.enable_spu = enable_spu;	context.cmd = 0;	context.start_90khz = play_opt->start_ms * 90;	context.dcc_info = &dcc_info;	context.PSMcontext = &PSMContext;	PSMContext.validPSMContexts = 1;	PSMContext.currentActivePSMContext = 1;	PSMContext.keyflags = KEYFLAGS;	file = open_stream( alt_filename, RM_FILE_OPEN_READ, 0);	if (file == NULL) {		fprintf(stderr, "Cannot open file %s\n", alt_filename);		goto exit_with_error;	}	err = RMSizeOfOpenFile(file, &(context.file_size));	if (err != RM_OK) {		RMDBGLOG((ENABLE, "Cannot find file size\n"));		context.file_size = (RMint64) -1;	}	RMDBGLOG((ENABLE, "file: %s, size %llu, duration %llu\n", alt_filename, context.file_size, play_opt->duration / 1000));	if (play_opt->duration)		fprintf(stderr, "duration %llu secs\n", play_opt->duration / 1000);	dcc_info.RM_PSM_commands = RM_PSM_ENABLE_PLAY;	dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_STOP;	dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_PAUSE;	dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SPEED;	dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_FASTER;	dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SLOWER;	dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_NEXTPIC;	if ((play_opt->duration > 1000) && (context.file_size > 0)) {		RMDBGLOG((ENABLE, "seek and iframe mode enabled\n"));		dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SEEK;				dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_IFWD;		dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_IRWD;		context.dcc_info->seek_supported = TRUE;		context.dcc_info->iframe_supported = TRUE;	}	/* correct pids according to audio codec and system type */	if ((demux_opt->system_type == RM_SYSTEM_MPEG2_DVD) || (demux_opt->system_type == RM_SYSTEM_MPEG2_PROGRAM)) {		if (demux_opt->audio_pid == 0) {/* If audio PID==PES ID is not provided by user use audio codec option to detect */			demux_opt->audio_pid = (audio_opt->Codec == AudioDecoder_Codec_MPEG1) ? 0xC0:0xBD;		}		if (audio_opt->Codec == AudioDecoder_Codec_MPEG1) {			if ( demux_opt->audio_pid != (0xC0 + demux_opt->audio_subid)) {				RMDBGPRINT((ENABLE, "\n***************** audio_pid audio_subid conflict *****************\n"));				RMDBGPRINT((ENABLE, "*** for mpeg audio select either audio_pid, either audio_subid ***\n"));				RMDBGPRINT((ENABLE, "******************************************************************\n\n"));			}			demux_opt->audio_pid = 0xC0 + demux_opt->audio_subid;		}	}	RMTermInit(TRUE);    // don't allow ctrl-C and the like ...	RMSignalInit(NULL, NULL);  // ... but catch other termination signals to call RMTermExit()	repack_buf = (RMuint8 *) RMMalloc(1<<DMA_BUFFER_SIZE_LOG2);	if (repack_buf == NULL)		goto cleanup;	do {		RMuint8 *buf = NULL;		enum RM_PSM_State PlaybackStatus;		RMDBGLOG((ENABLE, "do-while\n"));		if (play_opt->start_pause) {			RMDBGLOG((ENABLE, "start in pause mode!\n"));			/* required, because if we do 'next' the decoder *must* be running */			err = Play(&context, RM_DEVICES_VIDEO, DCCVideoPlayFwd);			if (RMFAILED(err)) {				fprintf(stderr, "Cannot start decoders %d\n", err);				goto cleanup;			}						err = Pause(&context, RM_DEVICES_VIDEO);			if (RMFAILED(err)) {				fprintf(stderr, "Cannot pause decoders %d\n", err);				goto cleanup;			}			RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Paused);		}		else 			RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Playing);		play_opt->start_pause = FALSE;	mainloop:				RMDBGLOG((ENABLE, "mainloop\n"));		file_offset = 0;		err = RMSeekFile(file, start_file_position, RM_FILE_SEEK_START);		if (err != RM_OK) {			RMDBGLOG((ENABLE, "Error seeking file to beginning %d\n", err));			goto cleanup;		}		{			struct EMhwlibDisplayTimeInterval time_interval;			time_interval.Mode = EMhwlibDisplayIntervalMode_Start;			time_interval.StartPTSLo = (RMuint32)(start_time_stamp);			time_interval.StartPTSHi = (RMuint32)(start_time_stamp>>32);			time_interval.EndPTSLo = 0;			time_interval.EndPTSHi = 0;			while( (err = RUASetProperty(context.dcc_info->pRUA, context.dcc_info->SurfaceID, RMGenericPropertyID_DisplayTimeInterval, &(time_interval), sizeof(time_interval), 0)) == RM_PENDING )				;			if (RMFAILED(err) && (err != RM_INVALIDMODE)) {				RMDBGLOG((ENABLE, "Cannot set time interval\n"));				goto cleanup;			}			RMDBGLOG((ENABLE, "Time Interval: %d, 0x%lx%lx\n", time_interval.Mode, time_interval.StartPTSHi, time_interval.StartPTSLo)); 				}		mainloop_no_seek:		RMDBGLOG((ENABLE, "mainloop_noseek\n"));		if (actions.cmd == RM_SEEK) {			RMint64 seek_pos;			seek_pos = (dcc_info.seek_time * context.file_size * 1000) / (play_opt->duration);			RMDBGLOG((ENABLE, "seeking to %lu s, pos %llu\n", dcc_info.seek_time, seek_pos)); 			if (RMSeekFile(file, seek_pos, RM_FILE_SEEK_START) != RM_OK) {				RMDBGLOG((ENABLE, "Error: seeking file to position %lu s, %lld kB\n", dcc_info.seek_time, seek_pos/1024));				goto cleanup;			}		}		context.FirstSystemTimeStamp = TRUE;		context.ResumeFromTrickMode = FALSE;		context.audio_byte_counter = 0;		context.video_byte_counter = 0;		context.audio_repack_buf = (RMuint8 *) NULL;		context.video_repack_buf = (RMuint8 *) NULL;		context.spu_repack_buf = (RMuint8 *) NULL;		context.audio_repack_offset = 0;		context.video_repack_offset = 0;		context.spu_repack_offset = 0;		context.audio_repack_size = 0;		context.video_repack_size = 0;

⌨️ 快捷键说明

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