play_asf.c

来自「1. 8623L平台」· C语言 代码 · 共 1,567 行 · 第 1/4 页

C
1,567
字号
			}		}	} 	else {		RMDBGLOG((READ_DBG, "read %lu bytes\n", buffersize));		status = RMReadFile(pSendContext->f_bitstream, buffer, buffersize, &count);		if (status == RM_OK && pSendContext && pSendContext->asf_packetSize && pSendContext->isContentEncrypted && buffersize != count) {			RMDBGLOG((ENABLE, "ERROR: buffersize=%lu, count=%lu, status=%d\n", buffersize, count, (int)status));			count = (count/pSendContext->asf_packetSize)*pSendContext->asf_packetSize;			RMDBGLOG((ENABLE,"SOLVE: count=%lu, asf_packet_size=%lu\n", count, pSendContext->asf_packetSize));			//			status = RM_ERRORENDOFFILE;		}	}	*bytesRead = count;	RMDBGLOG((DISABLE, "buf: %02x %02x %02x %02x %02x %02x %02x %02x \n", 		  buffer[0],		  buffer[1],		  buffer[2],		  buffer[3],		  buffer[4],		  buffer[5],		  buffer[6],		  buffer[7]));	return status;	}#ifdef WITH_MONORMstatus asf_get_video_duration(void *context, RMuint32 *time_sec){	struct asf_context *pSendContext = (struct asf_context *)context;	if(pSendContext == NULL)		return RM_ERROR;	if (!pSendContext->filePropSET)		return RM_ERROR;	else {		if (pSendContext->Duration >= 1000)			*time_sec = pSendContext->Duration / 1000;		else			*time_sec = 0;		if (*time_sec == 0)			return RM_ERROR;		RMDBGLOG((ENABLE, "asf_get_video_duration: %lu s\n", *time_sec));		return RM_OK;	}}RMstatus asf_get_playback_position(void *context, RMuint32 *time_sec){	struct asf_context *pSendContext = (struct asf_context *)context;	RMstatus err = RM_OK;	if(pSendContext == NULL)		return RM_ERROR;	if (pSendContext->VideoStreamFound) {		RMuint64 videoPTS;		err = RUAGetProperty(pSendContext->pRUA, pSendContext->dcc_info->SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &videoPTS, sizeof(videoPTS));		if (err != RM_OK) {			RMDBGLOG((ENABLE, "error getting current display pts property, error %lu\n", (RMuint32)err));			return RM_ERROR;		}		if (pSendContext->video_vop_tir == 90000)			videoPTS *= 2;		*time_sec = (RMuint32) round_int_div(videoPTS, (RMuint32) pSendContext->video_vop_tir);		if (*time_sec == 0)			return RM_ERROR;				RMDBGLOG((ENABLE, "asf_get_playback_position: %lu s (video)\n", *time_sec));		return RM_OK;	}	else if (pSendContext->AudioStreamFound) {		RMuint32 audioPTS;		struct DCCAudioSourceHandle audioHandle;				if (pSendContext->dcc_info->pMultipleAudioSource) {			err = DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(pSendContext->dcc_info->pMultipleAudioSource, 0, &audioHandle);			if (err != RM_OK)				return RM_ERROR;						err = RUAGetProperty(pSendContext->pRUA, audioHandle.moduleID, RMAudioDecoderPropertyID_CurrentPTS, &audioPTS, sizeof(audioPTS));			if (err != RM_OK) {				RMDBGLOG((ENABLE, "error getting current pts property for audio, error %lu\n", (RMuint32)err));				return RM_ERROR;			}			*time_sec = (RMuint32) round_int_div((RMuint64)audioPTS, (RMuint32) pSendContext->audio_vop_tir);			if (*time_sec == 0)				return RM_ERROR;						RMDBGLOG((ENABLE, "asf_get_playback_position: %lu s (audio only)\n", *time_sec));			return RM_OK;		}	}			return RM_OK;}RMstatus asf_get_audio_languageId(void *context, RMasfdemuxLanguageID * languageID){	struct asf_context *pSendContext = (struct asf_context *)context;	if(pSendContext == NULL)		return RM_ERROR;	if (pSendContext->langPropSET) {		if ((languageID) &&  (languageID->languageIDIndex < MAX_NUMBER_OF_AUDIO_STREAMS)) {			RMDBGLOG((ENABLE, "asf_get_audio_languageId: index %lu\n", languageID->languageIDIndex));			languageID->languageIDCount = pSendContext->lang[languageID->languageIDIndex].languageIDCount;			languageID->languageIDLength = pSendContext->lang[languageID->languageIDIndex].languageIDLength;			languageID->languageID = pSendContext->lang[languageID->languageIDIndex].languageID;			return RM_OK;		}	}	return RM_ERROR;}RMstatus asf_get_current_audio_stream(void *context, RMuint32 *stream){	struct asf_context *pSendContext = (struct asf_context *)context;	if(pSendContext == NULL)		return RM_ERROR;	*stream = (RMuint32)pSendContext->audio_stream_index;	RMDBGLOG((ENABLE, "asf_get_current_audio_stream: %lu\n", *stream));	return RM_OK;}RMstatus asf_get_audio_stream_count(void *context, RMuint32 *count){	struct asf_context *pSendContext = (struct asf_context *)context;	*count = (RMuint32)pSendContext->audioStreams;	RMDBGLOG((ENABLE, "asf_get_audio_stream_count: %lu\n", *count));	return RM_OK;}RMstatus asf_get_real_seek_position(void *context, RMuint32 time_sec, RMuint32 *true_time_sec){	struct asf_context *pSendContext = (struct asf_context *)context;	RMuint64 position;	RMuint32 time = time_sec * 1000;	if(pSendContext == NULL)		return RM_ERROR;	position = RMASFVDemuxSeekToTime(pSendContext->vASFDemux, &time);	if (position == 0) {		RMDBGLOG((ENABLE, "asf_get_real_seek_position: error seeking\n"));		return RM_ERROR;	}	*true_time_sec = time / 1000;	RMDBGLOG((ENABLE, "asf_get_real_seek_position: seek to %lu s will seek to %lu s\n", time_sec, *true_time_sec));	return RM_OK;}#endif //WITH_MONO#ifdef WITH_MONOint main_asf(struct mono_info *mono){#elseint main(int argc, char *argv[]){	/*for MONO compatibility, always access these variables through the global pointers*/	struct playback_cmdline playback_options; /*access through play_opt*/	struct display_cmdline  display_options;/*access through disp_opt*/	struct video_cmdline video_options;	struct audio_cmdline audio_options[MAX_AUDIO_DECODER_INSTANCES]; /*access through audio_opt*/	struct dh_context dh_info = {0,};#endif //WITH_MONO	struct asf_context SendContext = {0,};	RMstatus err = RM_OK;	RMint32 rc = 0;	RMint32 error = 0;	struct dcc_context dcc_info = {0,};	struct stream_options_s stream_options;	RMuint32 NTimes = 0;	struct RMfifo wmapro_fifo;	RMuint8  *wmapro_fifo_buffer=NULL;	RMuint8  *wmapro_fifo_buffer_original=NULL;	struct RM_PSM_Context PSMContext;	/* #### Begin DTCP code #### */	struct dtcp_cookie *dtcpCookieHandle = NULL;         /* #### End DTCP code #### */	RMDBGLOG((ENABLE, "wmaprofifobuffer @ %p\n"		  "wmaprofifobufferorig @ %p\n",		  wmapro_fifo_buffer,		  wmapro_fifo_buffer_original));	if((err = asf_init(&SendContext,#ifdef WITH_MONO			   0,			   NULL,			   NULL,			   NULL,			   NULL,			   NULL,#else			   argc,			   argv,			   &playback_options,			   &display_options,			   &video_options,			   audio_options,#endif				   &stream_options,#ifdef WITH_MONO			   NULL,#else			   &dh_info,#endif			   &PSMContext,			   &dcc_info,#ifdef WITH_MONO			   mono,#else			   NULL,#endif			   process_key_sub,			   &wmapro_fifo,			   &wmapro_fifo_buffer,			   &wmapro_fifo_buffer_original,			   dtcpCookieHandle,			   KEYFLAGS,			   FALSE)) != RM_OK){		fprintf(stderr, "ERROR WHILE INITIALIZING : %s\n", RMstatusToString(err));		goto exit_with_error;	}	RMDBGLOG((ENABLE, "wmaprofifobuffer @ %p\n"		  "wmaprofifobufferorig @ %p\n",		  wmapro_fifo_buffer,		  wmapro_fifo_buffer_original));#ifndef WITH_MONO	display_key_usage(KEYFLAGS);#endif	RM_PSM_SetState(SendContext.PSMcontext, &(SendContext.dcc_info), RM_PSM_Playing);	// main do-while	do {		RMuint8 *buffer = NULL;		enum RM_PSM_State PlaybackStatus;		if (SendContext.play_opt->start_pause) {			RMDBGLOG((ENABLE, "start in pause mode!\n"));			/* required, because if we do 'next' the decoder *must* be running */			err = asf_Play(&SendContext, RM_DEVICES_VIDEO, /*DCCVideoPlayIFrame*/DCCVideoPlayFwd);			if (RMFAILED(err)) {				fprintf(stderr, "Cannot start decoders %d\n", err);				goto cleanup;			}						err = asf_Pause(&SendContext, RM_DEVICES_VIDEO);			if (RMFAILED(err)) {				fprintf(stderr, "Cannot pause decoders %d\n", err);				goto cleanup;			}			RM_PSM_SetState(SendContext.PSMcontext, &(SendContext.dcc_info), RM_PSM_Paused);		}				/* 		   do not change PSM state in case there is no start_pause. 		   Otherwise after pressing STOP the application play again immediately		*/		SendContext.play_opt->start_pause = FALSE;		RMDBGLOG((ENABLE, "mainloop\n"));		SendContext.IFrameFSMState = RMasfIFrameFSM_Disabled;		SendContext.firstIFrame = FALSE;		SendContext.video_decoder_initialized = FALSE;		SendContext.audio_decoder_initialized = FALSE;		SendContext.FirstSystemTimeStamp = TRUE;		SendContext.prev_video_media_object_number = -1;		SendContext.video_frame_counter = 0;		SendContext.VideoByteCounter = 0;		SendContext.video_last_pts = 0;		SendContext.prev_audio_media_object_number = -1;		SendContext.audio_frame_counter = 0;		SendContext.AudioByteCounter = 0;		SendContext.start_ms = SendContext.play_opt->start_ms;				SendContext.isTrickMode = FALSE;		SendContext.isIFrameMode = FALSE;		SendContext.audioSamplesDropped = FALSE;		SendContext.gotoRequest=RMProcess_key_goto_none;        		if (SendContext.isVC1) {			SendContext.getStartCodeBuffer = TRUE;			SendContext.addSeqHeader = TRUE;			SendContext.addEntryHeader = TRUE;			SendContext.addFrameHeader = TRUE;		}				if (!SendContext.linear_playback) {			RMint64 position = 0;			/* seek to first packet, at position [headerSize+50] */			RMSeekFile(SendContext.f_bitstream, SendContext.asf_Header_Object_Size+50, 				   RM_FILE_SEEK_START);			/* presets the demux to start parsing first packet */			RMASFVDemuxResetState(SendContext.vASFDemux);			/* Check current position only if seek is supported */			RMGetCurrentPositionOfFile (SendContext.f_bitstream, &position);			RMDBGLOG((ENABLE, "current position %lld\n", position));		}		DCCSTCSetTime(dcc_info.pStcSource, SendContext.stc_offset_ms*((RMint64)(SendContext.video_vop_tir/1000)), SendContext.video_vop_tir);		DCCSTCSetSpeed(dcc_info.pStcSource, SendContext.play_opt->speed_N, SendContext.play_opt->speed_M);		PlaybackStatus = RM_PSM_GetState(SendContext.PSMcontext, &(SendContext.dcc_info));		if ((PlaybackStatus != RM_PSM_Paused) && (PlaybackStatus != RM_PSM_Stopped)) {			RMDBGLOG((ENABLE, "setting play state\n"));			RM_PSM_SetState(SendContext.PSMcontext, &(SendContext.dcc_info), RM_PSM_Playing);			}		else {			PROCESS_KEY(FALSE, TRUE);			update_hdmi(SendContext.dcc_info, SendContext.disp_opt, &(SendContext.audio_opt[0]));		}	mainloop_seek:		RMDBGLOG((ENABLE, "mainloop_seek\n"));				if (!SendContext.linear_playback) {			// the following call will configure the decoders, after that we can 'pause' them			err = asf_Play(&SendContext, RM_DEVICES_AUDIO | RM_DEVICES_VIDEO, DCCVideoPlayFwd);			if (err != RM_OK)				goto exit_with_error;						/* do prebufferization only when in playing state */			if (RM_PSM_GetState(SendContext.PSMcontext, &(SendContext.dcc_info)) == RM_PSM_Playing) {								asf_Pause(&SendContext, RM_DEVICES_STC | RM_DEVICES_VIDEO | RM_DEVICES_AUDIO);								RM_PSM_SetState(SendContext.PSMcontext, &(SendContext.dcc_info), RM_PSM_Prebuffering);				fprintf(stderr, "prebuffering\n");			}		}		#ifdef WITH_MONO		RMDCCInfo(&dcc_info); // pass DCC context to application#endif		/* wake up disks if necessary */		switch (SendContext.play_opt->disk_ctrl_state) {		case DISK_CONTROL_STATE_DISABLE:		case DISK_CONTROL_STATE_RUNNING:			break;		case DISK_CONTROL_STATE_SLEEPING:			if (SendContext.play_opt->disk_ctrl_callback) {				RMuint32 poll_count = DISK_CONTROL_MAX_WAKEUP_COUNT;				

⌨️ 快捷键说明

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