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

📄 play_simple_video.c

📁 Sigma SMP8634 Mrua v. 2.8.2.0
💻 C
📖 第 1 页 / 共 2 页
字号:
	err = DCCGetScalerModuleID(dcc_info.pDCC, dcc_info.route, DCCSurface_Video, videoscaler_id, &(dcc_info.SurfaceID));	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot get surface to display video source %d\n", err));		goto cleanup;	}	err = DCCSetSurfaceSource(dcc_info.pDCC, dcc_info.SurfaceID, pVideoSource);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot set the surface source %d\n", err));		goto cleanup;	}	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 cleanup;	}	dcc_info.pVideoSource = pVideoSource;	dcc_info.state = (play_opt->start_pause) ? RM_PAUSED : RM_PLAYING;	dcc_info.trickmode_id = RM_NO_TRICKMODE;	dcc_info.seek_supported = FALSE;	dcc_info.iframe_supported = FALSE;     	// apply the fixed vop rate if required	err = apply_video_decoder_options(&dcc_info, video_opt);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error applying video_decoder_options %d\n", err));		goto cleanup;	}		set_default_out_window(&(dcc_info.disp_info->out_window));	set_default_out_window(&(dcc_info.disp_info->osd_window[0]));	set_default_out_window(&(dcc_info.disp_info->osd_window[1]));	dcc_info.disp_info->active_window = &(dcc_info.disp_info->out_window);	dcc_info.disp_info->video_enable = TRUE;	err = apply_display_options(&dcc_info, disp_opt);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot set display options %d\n", err));		goto cleanup;	}	display_key_usage(KEYFLAGS);	/* dmapool must be created after the module open in case we do no copy transfers */ 	err = RUAOpenPool(dcc_info.pRUA, 0/*dcc_info.video_decoder*/, DMA_BUFFER_COUNT, DMA_BUFFER_SIZE_LOG2, RUA_POOL_DIRECTION_SEND, &pDMA);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error cannot open dmapool %d\n", err));		goto cleanup;	}	context.pDMA = pDMA;	file = open_stream(play_opt->filename, RM_FILE_OPEN_READ, 0);	if (file == NULL) {		RMDBGLOG((ENABLE, "Cannot open file %s\n", play_opt->filename));		goto cleanup;	}	context.f_bitstream = file;	RMSizeOfOpenFile(file, &context.fileSize);	RMDBGLOG((ENABLE, "file: %s, size %llu, duration %llu s \n", play_opt->filename, context.fileSize, 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;	dcc_info.trick_supported = TRUE;	if ((play_opt->duration > 1000) && (context.fileSize > 0)) {		RMDBGLOG((ENABLE, "seek, ffwd and iframe modes enabled\n"));				dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SEEK;				dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_IFWD;		dcc_info.seek_supported = TRUE;		dcc_info.iframe_supported = TRUE;	}	context.dcc_info = &dcc_info;	context.PSMcontext = &PSMContext;	PSMContext.validPSMContexts = 1;	PSMContext.currentActivePSMContext = 1;	PSMContext.keyflags = KEYFLAGS;	RMTermInit(TRUE);    // don't allow ctrl-C and the like ...	RMSignalInit(NULL, NULL);  // ... but catch other termination signals to call RMTermExit()	do {		//RMuint32 cmd;		/* required in order to start playing right away, otherwise, if state is stopped, process_command will block		   until an exit of stop is issued */		RM_PSM_SetState(&PSMContext, &(context.dcc_info), RM_PSM_Playing);				mainloop:		if (RMSeekFile(file, 0, RM_FILE_SEEK_START) == RM_ERRORSEEKFILE) {			RMDBGLOG((ENABLE,"seeking file to beginning\n"));			goto cleanup;		}		byte_counter = 0;	mainloop_no_seek:		if (dcc_info.state == RM_PLAYING_TRICKMODE) { 			dcc_info.state = RM_PLAYING;			dcc_info.trickmode_id = RM_NO_TRICKMODE;		}		context.FirstSystemTimeStamp = TRUE;		context.FirstPTS = 0;		if (NTimes) {	// first time in loop no need to stop			Stop(&context, RM_DEVICES_VIDEO | RM_DEVICES_STC);			err = RUAResetPool(pDMA);	// needed for no dram copy version on standalone			if (RMFAILED(err)) {				RMDBGLOG((ENABLE, "Error cannot reset dmapool\n"));				goto cleanup;			}		}		RMDBGLOG((ENABLE, "DCCSTCSetSpeed %lx %lx\n", play_opt->speed_N, play_opt->speed_M));		DCCSTCSetSpeed(dcc_info.pStcSource, play_opt->speed_N, play_opt->speed_M);		Play(&context, RM_DEVICES_VIDEO, DCCVideoPlayFwd);		while (1) { // additional 'while' used for taking care of commands issued during EOSWait			RMuint8 *buf;			while (1) {				RMuint32 count;				RMstatus status;				struct emhwlib_info Info;								/* do not set this property when start for the first time */				if (context.initVideo == TRUE) {					RMbool keep_sequence = TRUE;					err = RUASetProperty(dcc_info.pRUA, dcc_info.video_decoder, RMVideoDecoderPropertyID_StorePreviousVideoHeader, &keep_sequence, sizeof(keep_sequence), 0);					if (RMFAILED(err)) {						RMDBGLOG((ENABLE, "Error setting video decoder to keep sequence header on Stop %d\n", err));						return err;					}					RMDBGLOG((ENABLE, "init video decoder\n"));					context.initVideo = FALSE;				}								PROCESS_KEY(FALSE, TRUE);								while (RUAGetBuffer(pDMA, &buf,  COMMON_TIMEOUT_US) != RM_OK) {					/* this has a double purpose: 					   1) in mpeg4 elementary streams, the video decoder is able to recover the PTS from the					   stream. When doing Stop/Play, after the Play the video decoder will find the correct PTS, 					   since we cant set the STC to that value because it's unknown to us, there would be a delay					   until STC (set to zero) meets the PTS the decoder got.					   The solution is to prebufferize (thus the decoder will get the PTS and we can obtain it					   thru a property, and then set the STC accordingly)					   2) prebuffering, because we dont start playing until fifo's are full (unintended purpose) */					if ((!context.isSTCRunning) &&					    (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) != RM_PSM_Paused) &&					    (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) != RM_PSM_Stopped)){						RMuint64 pts;						RMuint32 timeScale;						err = RUAGetProperty(dcc_info.pRUA, dcc_info.video_decoder, RMVideoDecoderPropertyID_LastDecodedPTS, &pts, sizeof(pts));						if (RMFAILED(err)) {							RMDBGLOG((ENABLE, "Cannot get video PTS\n"));							pts = 0;						}						DCCSTCGetTimeResolution(dcc_info.pStcSource, DCC_Video, &timeScale);						RMDBGLOG((ENABLE, "next pts %llu, unit %lu\n", pts, timeScale));						DCCSTCSetTime(dcc_info.pStcSource, pts, timeScale);						RMDBGLOG((ENABLE, "start STC\n")); 						Play(&context, RM_DEVICES_STC, 0);						context.isSTCRunning = TRUE;					}					PROCESS_KEY(FALSE, TRUE);				}									{						{							status = RMReadFile(file, buf, (1<<DMA_BUFFER_SIZE_LOG2), &count);							RMDBGLOG((ENABLE, "ReadFile to buf %p\n", buf));													}					}								if (status == RM_ERRORREADFILE) {					RMDBGLOG((ENABLE, "reading file"));					if (buf != NULL)						RUAReleaseBuffer(pDMA, buf);					goto cleanup;				}								if (status == RM_ERRORENDOFFILE) {					if (buf != NULL)						RUAReleaseBuffer(pDMA, buf);					break;				}								/* fast forward may have been too fast for the decoder. Must set the STC				   to the current picture in display to avoid skipping frames to catch STC 				*/				if (byte_counter == 0) {					DCCSTCSetTime(dcc_info.pStcSource, 0, 90000);					//DCCSTCPlay(dcc_info.pStcSource);										Info.ValidFields = TIME_STAMP_INFO;					Info.TimeStamp = 0;				} else if ((context.ResyncTimer) && (!context.FirstPTS)) {					RMuint64 stc;					RMuint32 timeScale;					RMuint64 currentSTC;										err = RUAGetProperty(dcc_info.pRUA, dcc_info.SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &stc, sizeof(stc));					if (RMFAILED(err)) {						RMDBGLOG((ENABLE, "Cannot get video PTS\n"));					}										DCCSTCGetTimeResolution(dcc_info.pStcSource, DCC_Video, &timeScale);					if (timeScale == 90000)						stc *= 2;					DCCSTCGetTime(dcc_info.pStcSource, &currentSTC, timeScale);					RMDBGLOG((ENABLE, "resync STC(%llu) to %llu, timeScale %lu\n", currentSTC, stc, timeScale));					DCCSTCSetTime(dcc_info.pStcSource, stc, timeScale);					//DCCSTCPlay(dcc_info.pStcSource);					Info.ValidFields = TIME_STAMP_INFO;					Info.TimeStamp = stc;										context.ResyncTimer = FALSE;				} else if (context.FirstPTS) { //after a seek					RMDBGLOG((ENABLE, "first pts %lu\n", context.FirstPTS));					DCCSTCSetTime(dcc_info.pStcSource, context.FirstPTS, 90000);					Info.ValidFields = TIME_STAMP_INFO;					Info.TimeStamp = context.FirstPTS;					context.FirstPTS = 0;					context.FirstSystemTimeStamp = FALSE;				}				else {					Info.ValidFields = 0;					Info.TimeStamp = 0;				}												RMDBGLOG((SENDDBG, "sending %lu bytes, pts %llu, valid %lu\n", count, Info.TimeStamp, (RMuint32)Info.ValidFields));				while (RUASendData(dcc_info.pRUA, dcc_info.video_decoder, pDMA, buf, count, &Info, sizeof(Info)) != RM_OK) {					struct RUAEvent e;					/* see comment on RUAGetBuffer */					if ((!context.isSTCRunning) &&					    (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) != RM_PSM_Paused) &&					    (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) != RM_PSM_Stopped)) {						RMuint64 pts;						RMuint32 timeScale;						err = RUAGetProperty(dcc_info.pRUA, dcc_info.video_decoder, RMVideoDecoderPropertyID_LastDecodedPTS, &pts, sizeof(pts));						if (RMFAILED(err)) {							RMDBGLOG((ENABLE, "Cannot get video PTS\n"));							pts = 0;						}						DCCSTCGetTimeResolution(dcc_info.pStcSource, DCC_Video, &timeScale);						RMDBGLOG((ENABLE, "next pts %llu, unit %lu\n", pts, timeScale));						DCCSTCSetTime(dcc_info.pStcSource, pts, timeScale);						RMDBGLOG((ENABLE, "start STC\n")); 						Play(&context, RM_DEVICES_STC, 0);						context.isSTCRunning = TRUE;					}					PROCESS_KEY(TRUE, TRUE);										e.ModuleID = dcc_info.video_decoder;					e.Mask = RUAEVENT_XFER_FIFO_READY;					while (RUAWaitForMultipleEvents(dcc_info.pRUA, &e, 1, COMMON_TIMEOUT_US, NULL) != RM_OK) {						PROCESS_KEY(TRUE, TRUE);					}				}				byte_counter += count;								/* sendind data may fill-up the xfer fifo, so we reset the event */				{					struct RUAEvent e;										e.ModuleID = dcc_info.video_decoder;					e.Mask = RUAEVENT_XFER_FIFO_READY;					RUAResetEvent(dcc_info.pRUA, &e);				}								RUAReleaseBuffer(pDMA, buf);							} //while(1)			if (!context.isSTCRunning){				/* in case the file is shorter than the DMA pool set the STC in play state */				RMuint64 pts;				RMuint32 timeScale;				err = RUAGetProperty(dcc_info.pRUA, dcc_info.video_decoder, RMVideoDecoderPropertyID_LastDecodedPTS, &pts, sizeof(pts));				if (RMFAILED(err)) {					RMDBGLOG((ENABLE, "Cannot get video PTS\n"));					pts = 0;				}				DCCSTCGetTimeResolution(dcc_info.pStcSource, DCC_Video, &timeScale);				RMDBGLOG((ENABLE, "next pts %llu, unit %lu\n", pts, timeScale));				DCCSTCSetTime(dcc_info.pStcSource, pts, timeScale);				RMDBGLOG((ENABLE, "start STC\n"));				Play(&context, RM_DEVICES_STC, 0);				context.isSTCRunning = TRUE;			}			err = WaitForEOS(&context, &actions);			{				RMuint64 stc;				DCCSTCGetTime(dcc_info.pStcSource, &stc, 90000);								RMDBGLOG((ENABLE, "Timer duration %llu s\n", stc/90000));			}			if (err == RM_KEY_WHILE_WAITING_EOS) {				RMDBGLOG((ENABLE, "command while waiting for EOS\n"));				err = RM_OK;				PROCESS_KEY(FALSE, FALSE);			}			else {#ifdef WITH_MONO				/* callback to signal EOS to curacao/mono */				RMEOSCallback(); 				break;#else				break;	// EOS#endif			}		} // additional while				if (play_opt->loop_count > 0)			play_opt->loop_count --;	} while ((play_opt->loop_count > 0) || (play_opt->infinite_loop));	 cleanup:	if (file)		RMCloseFile(file);	if( play_opt->waitexit ) {		RMascii key;		RMDBGLOG((ENABLE, "press q key again if you really want to stop & quit\n"));		while ( !(RMGetKeyNoWait(&key) && ((key == 'q') || (key =='Q'))) );	}	RMTermExit();		if (dcc_info.pStcSource) {		RMDBGLOG((DEBUG, "Closing STC...\n"));		err = DCCSTCClose(dcc_info.pStcSource);		if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Error cannot close STC %d\n", err));		}		RMDBGLOG((DEBUG, "Done closing STC.\n"));	}	if (pVideoSource) {		RMDBGLOG((DEBUG, "Stopping video source...\n"));		err = DCCStopVideoSource(pVideoSource, DCCStopMode_LastFrame);		if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Cannot stop video decoder %d\n", err));		}		RMDBGLOG((DEBUG, "Done stopping video source.\n"));		RMDBGLOG((DEBUG, "Closing video source...\n"));		err = DCCCloseVideoSource(pVideoSource);		if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Error cannot close video decoder %d\n", err));		}		RMDBGLOG((DEBUG, "Done closing video source.\n"));	}	clear_video_options(&dcc_info, video_opt);		if (pDMA) {		RMDBGLOG((DEBUG, "Closing RUA DMA pool...\n"));		err = RUAClosePool(pDMA);		if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Error cannot close dmapool %d\n", err));		}		RMDBGLOG((DEBUG, "Done closing RUA DMA pool.\n"));	}	err = DCCClose(dcc_info.pDCC);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot close DCC %d\n", err));	}	err = RUADestroyInstance(dcc_info.pRUA);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot destroy RUA instance %d\n", err));		return -1;	}	return 0;}

⌨️ 快捷键说明

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