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

📄 play_gt.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 5 页
字号:
	do {		enum RM_PSM_State FSMstate;		RMuint8 *buf;				if (context.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, /*DCCVideoPlayIFrame*/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);		context.play_opt->start_pause = FALSE;		RMDBGLOG((ENABLE, "putting the rotation ucode in play\n"));		RMDBGLOG((ENABLE, "PLAYING=================================\n"));			mainloop:		RMDBGLOG((ENABLE, "mainloop\n"));		if (RMSeekFile(file, 0, RM_FILE_SEEK_START) == RM_ERRORSEEKFILE) {			RMDBGLOG((ENABLE,"seeking file to beginning\n"));			goto cleanup;		}		context.byte_counter = 0;		context.FirstPTS = 0;			mainloop_no_seek:		RMDBGLOG((ENABLE, "mainloop_no_seek\n"));		/* do not set this property when start for the first time */		if (context.initVideo == TRUE) {#if STORE_SEQ_HEADER_LOCALLY			resendheader = TRUE;#else			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;#endif //STORE_SEQ_HEADER_LOCALLY		}		context.FirstSystemTimeStamp = TRUE;		context.highSpeedIFrameMode = FALSE;		context.trickMode = FALSE;		context.iframeMode = FALSE;		FSMstate = RM_PSM_GetState(context.PSMcontext, &(context.dcc_info));		if ((FSMstate != RM_PSM_Paused) && (FSMstate != RM_PSM_Stopped)) {				RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Playing);		}		else {			PROCESS_KEY(FALSE, TRUE);		}		RMDBGLOG((ENABLE, "DCCSTCSetSpeed %lx %lx\n", context.play_opt->speed_N, context.play_opt->speed_M));		DCCSTCSetSpeed(dcc_info.pStcSource, context.play_opt->speed_N, context.play_opt->speed_M);		/* do prebufferization only when in playing state */		FSMstate = RM_PSM_GetState(context.PSMcontext, &(context.dcc_info));		if (FSMstate == RM_PSM_Playing) {			/* required, because if we start straight into pause mode, we cant send buffers (weird)	*/			err = Play(&context, RM_DEVICES_VIDEO, DCCVideoPlayFwd);			if (RMFAILED(err)) {				fprintf(stderr, "Cannot start decoders %d\n", err);				goto cleanup;			}						/* ...for prebuffering */			err = Pause(&context, RM_DEVICES_VIDEO | RM_DEVICES_STC);			if (RMFAILED(err)) {				fprintf(stderr, "Cannot pause decoders %d\n", err);				goto cleanup;			}						RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Prebuffering);			context.prebuf_level = 0;		}#ifdef WITH_MONO		RMDCCInfo(&dcc_info); // pass DCC context to application#endif		/* wake up disks if necessary */		switch (context.play_opt->disk_ctrl_state) {		case DISK_CONTROL_STATE_DISABLE:		case DISK_CONTROL_STATE_RUNNING:			break;		case DISK_CONTROL_STATE_SLEEPING:			if(context.play_opt->disk_ctrl_callback && context.play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_RUN) == RM_OK)				context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_RUNNING;			break;		}		while (1) { // additional 'while' used for taking care of commands issued during EOSWait			while (1) {				RMuint32 count;				RMstatus status;				struct emhwlib_info Info;			#ifdef	SEND_IBC				if (!ibc_sent && (context.byte_counter >= HARDCODE_BYTECOUNT)) {					SendInbandCommand(&context);					ibc_sent = TRUE;				}#endif				/* first, try to fill up the CC fifo */			#ifndef WITH_MONO				update_hdmi(&dcc_info, context.disp_opt, NULL);#endif								PROCESS_KEY(FALSE, TRUE);							get_buffer:				switch (context.play_opt->disk_ctrl_state) {				case DISK_CONTROL_STATE_DISABLE:				case DISK_CONTROL_STATE_SLEEPING:					break;				case DISK_CONTROL_STATE_RUNNING:					if (dmabuffer_index > 0) {						dmabuffer_index--;						buf = dmabuffer_array[dmabuffer_index];						goto fill_buffer;					}					break;				}								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) */					check_prebuf_state(&context, 0);					switch (context.play_opt->disk_ctrl_state) {					case DISK_CONTROL_STATE_DISABLE:					case DISK_CONTROL_STATE_SLEEPING:						break;					case DISK_CONTROL_STATE_RUNNING:						if(context.play_opt->disk_ctrl_callback && context.play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_SLEEP) == RM_OK)							context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_SLEEPING;						break;					}					PROCESS_KEY(FALSE, TRUE);				}								check_prebuf_state(&context, (RMuint32) (1 << context.play_opt->dmapool_log2size));					switch (context.play_opt->disk_ctrl_state) {				case DISK_CONTROL_STATE_DISABLE:				case DISK_CONTROL_STATE_RUNNING:					break;				case DISK_CONTROL_STATE_SLEEPING:					dmabuffer_array[dmabuffer_index] = buf;					dmabuffer_index ++;					if (dmabuffer_index + context.play_opt->disk_ctrl_low_level >= context.play_opt->dmapool_count) {						if(context.play_opt->disk_ctrl_callback && context.play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_RUN) == RM_OK)							context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_RUNNING;					}					goto get_buffer;				}							fill_buffer:				if ((!trickSizeToSend) && (dcc_info.seek_supported)) {					trickSizeToSend = (RMuint32) (context.fileSize / (context.play_opt->duration / 500)); //there are roughly 2 iframes per second					trickBuffersToSend = trickSizeToSend >> context.play_opt->dmapool_log2size;					RMDBGLOG((ENABLE, "size %llu, duration %lu s, iframeSize %lu, buffers %lu (of %lu bytes)\n", 						  context.fileSize, 						  (RMuint32)(context.play_opt->duration / 1000), 						  trickSizeToSend,						  trickBuffersToSend,						  (1 << context.play_opt->dmapool_log2size)));									}				#if STORE_SEQ_HEADER_LOCALLY				/* 				   if we have to resend the sequence header, we copy it into the buffer				   before sending it to the video decoder and then read from the file				   till filling the buffer, otherwise, we just read the file into the				   buffer.				*/				if (resendheader == TRUE && headerread == TRUE) {					RMint32 i;										for (i = 0; i < HeaderSize ; i++) { 						*(buf+i) = header[i]; 					}					status = RMReadFile(file, buf+HeaderSize, (1 << context.play_opt->dmapool_log2size)-(HeaderSize), &count);										resendheader = FALSE;				} 				else {#endif //STORE_SEQ_HEADER_LOCALLY										if (context.highSpeedIFrameMode) {						RMint64 position;						RMuint64 seekto;																		if (trickBuffersSent >= trickBuffersToSend)							trickBuffersSent = 0;												if (trickBuffersSent == 0) {							RMGetCurrentPositionOfFile(file, &position);							seekto = position + (RMuint64) context.highSpeedIFrameSpeed * trickBuffersToSend * (1<<(context.play_opt->dmapool_log2size));							RMDBGLOG((DISABLE, "pos %llu, seekto %llu\n", position, seekto));							status = RMSeekFile(file, seekto, RM_FILE_SEEK_START);							if (status != RM_OK) {								perror("error seeking in fwd trickmode, assume EOS\n");								if (buf != NULL) {									RUAReleaseBuffer(pDMA, buf);									buf = NULL;								}								break;							}						}						status = RMReadFile(file, buf, (1 << context.play_opt->dmapool_log2size), &count);												trickBuffersSent++;						RMDBGLOG((ENABLE, "sent buffer %lu, speed %lux\n", trickBuffersSent, context.highSpeedIFrameSpeed));											}					else {						if (context.video_opt->MSflag) {							RMint64 position;							RMuint64 dummy;							RMuint8 *buffer = (RMuint8*)&dummy;							RMGetCurrentPositionOfFile (file, &position);							status = RMReadFile(file, buffer, sizeof(RMuint64), &count);							if (status == RM_ERRORENDOFFILE) {								if (buf != NULL) {									RUAReleaseBuffer(pDMA, buf);									buf = NULL;								}								RMDBGLOG((ENABLE, "BREAKKKKKKK\n"));								break;							}							else if ((status != RM_OK) || (count != sizeof(RMuint64))) {								fprintf(stderr, "read error while reading pts!\n");								if (buf != NULL) {									RUAReleaseBuffer(pDMA, buf);									buf = NULL;								}								goto cleanup;							}							MSPts = RMleBufToUint64(buffer);							status = RMReadFile(file, buffer, sizeof(RMuint32), &count);							if (status == RM_ERRORENDOFFILE) {								if (buf != NULL) {									RUAReleaseBuffer(pDMA, buf);									buf = NULL;								}								RMDBGLOG((ENABLE, "BREAKKKKKKKx\n"));								break;							}							else if ((status != RM_OK) || (count != sizeof(RMuint32))) {								fprintf(stderr, "read error while reading frame length!\n");								if (buf != NULL) {									RUAReleaseBuffer(pDMA, buf);									buf = NULL;								}								goto cleanup;							}							MSLength = RMleBufToUint32(buffer);							RMDBGLOG((DISABLE, "pos %llu (%llx); MSLength= %ld ; MSPts = %lld (bufferSize %ld) \n",								  position, 								  position,								  MSLength, 								  MSPts, 								  (RMuint32)(1 << context.play_opt->dmapool_log2size) ));							//MSPts *= 90000;							//MSPts /= 1000;														if (MSLength > (RMuint32)(1 << context.play_opt->dmapool_log2size)) {								RMDBGLOG((ENABLE, "Buffer overflow!\n"));								if (buf != NULL) {									RUAReleaseBuffer(pDMA, buf);									buf = NULL;								}								goto cleanup;							}														status = RMReadFile(file, buf, MSLength, &count);												} else {							status = RMReadFile(file, buf, (1 << context.play_opt->dmapool_log2size), &count);						}					}#if STORE_SEQ_HEADER_LOCALLY				}#endif //STORE_SEQ_HEADER_LOCALLY								if (status == RM_ERRORREADFILE) {					RMDBGLOG((ENABLE, "reading file"));					if (buf != NULL) {						RUAReleaseBuffer(pDMA, buf);						buf = NULL;					}					goto cleanup;				}								if (status == RM_ERRORENDOFFILE) {					if (buf != NULL) {						RUAReleaseBuffer(pDMA, buf);						buf = NULL;					}					RMDBGLOG((ENABLE, "BREAKKKKKKKx\n"));					break;				}				#if STORE_SEQ_HEADER_LOCALLY				/* parse the buffer and store the header */				if (headerread == FALSE) {					headerread = StoreHeader(&context, buf, header, &HeaderSize, (1 << context.play_opt->dmapool_log2size));					if (headerread)						RMDBGLOG((ENABLE, "stored SeqHeader, %lu bytes\n", HeaderSize));				}#endif //STORE_SEQ_HEADER_LOCALLY								/* 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 (context.byte_counter == 0) {					/* set the VopInfo property */					if (context.video_opt->MSflag == TRUE) {						RMuint32 timeScale;						DCCSTCGetTimeResolution(dcc_info.pStcSource, DCC_Video, &timeScale);						DCCSTCSetTime(dcc_info.pStcSource, context.play_opt->send_video_pts ? MSPts : 0, timeScale);					} else {						DCCSTCSetTime(dcc_info.pStcSource, context.play_opt->STC_initial_value, 90000);												Info.ValidFields = 0;						/* Info.TimeStamp = 0; */												/* one shouldn't admit that first decoded picture has a PTS equal to 0 */						/* for instance, closed gops starting with IB...BP (B frames only have backward references)  */						/* give decoding order B....B I P */						/* where I is the first decoded picture AND however doesn't have PTS = 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);										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;				}								if (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Prebuffering) {					RMDBGPRINT((ENABLE, "."));				}								if (context.video_opt->MSflag == TRUE) {					if ((RMint64) MSPts != -1) {						Info.ValidFields = context.play_opt->send_video_pts ? TIME_STAMP_INFO:0;						I

⌨️ 快捷键说明

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