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

📄 play_video.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
				/* 				   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;								}								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;								}								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;					}					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;						Info.TimeStamp = MSPts;					} else						Info.ValidFields = 0;					RMDBGLOG((DISABLE, "MSPts = %lld (0x%llx) pts= %lld (0x%llx) (valid %lu) byte_counter=0x%lx\n", 						  MSPts, 						  MSPts,						  Info.TimeStamp, 						  Info.TimeStamp,						  Info.ValidFields,						  context.byte_counter));				}				RMDBGLOG((SENDDBG, "sending %lu bytes, pts %llu, valid %lu\n", count, Info.TimeStamp, (RMuint32)Info.ValidFields));				if (Info.ValidFields)					context.last_video_pts = Info.TimeStamp;				while (RUASendData(dcc_info.pRUA, dcc_info.video_decoder, pDMA, buf, count, &Info, sizeof(Info)) != RM_OK) {					struct RUAEvent e;					/* see previous comment on RUAGetBuffer */					check_prebuf_state(&context, 0);					PROCESS_KEY(TRUE, TRUE);										e.ModuleID = dcc_info.video_decoder;					e.Mask = RUAEVENT_XFER_FIFO_READY;					RUAWaitForMultipleEvents(dcc_info.pRUA, &e, 1, COMMON_TIMEOUT_US, NULL);				}				context.bitrate += count * 8;				context.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);				buf = NULL;							} //while(1)			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;			}			err = WaitForEOS(&context, &actions);			{				RMuint64 stc;				DCCSTCGetTime(dcc_info.pStcSource, &stc, 90000);								RMDBGLOG((ENABLE, "Timer duration %llu ms\n", stc/90));			}			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 (context.play_opt->loop_count > 0)			context.play_opt->loop_count --;		/* if there is another loop, stop devices */		if ((context.play_opt->loop_count > 0) || (context.play_opt->waitexit != TRUE) || (context.play_opt->infinite_loop))			Stop(&context, RM_DEVICES_VIDEO | RM_DEVICES_STC);		if( context.video_opt->display_cc ) {			/* left over cc must be cleaned when there is a pts discontinuity */			err = RUASetProperty(dcc_info.pRUA, dcc_info.ccfifo_in_id, RMCCFifoPropertyID_Flush, NULL, 0, 0);			if( err != RM_OK ) {				RMDBGLOG(( ENABLE, "cannot flush cc fifo, exit \n" )); 				goto cleanup;			}		}	} while ((context.play_opt->loop_count > 0) || (context.play_opt->infinite_loop));	 cleanup:	if (file)		RMCloseFile(file);	if( context.play_opt->waitexit ) {		RMascii key;		Stop(&context, RM_DEVICES_STC);		fprintf(stderr, "press q key again if you really want to stop & quit\n");		while ( !(RMGetKeyNoWait(&key) && ((key == 'q') || (key =='Q'))) );		Stop(&context, RM_DEVICES_VIDEO | RM_DEVICES_STC);	}#ifndef WITH_MONO		RMTermExit();#endif	if (err != RM_OK) {		fprintf(stderr, "quitting due to error %s (%d)...\n", RMstatusToString(err), err);		//error = err; //exit with error	}	RMDBGLOG((ENABLE, "closing...\n"));#ifdef WITH_MONO	RMDCCInfo(NULL); // invalidate DCC context#endif	if (context.dmabuffer_array) {		RMuint32 i;		for (i = 0; i < context.dmabuffer_index; i++) {			RUAReleaseBuffer(pDMA, context.dmabuffer_array[i]);			RMDBGLOG((ENABLE, "released buffer[%lu] @ 0x%08lx\n", i, context.dmabuffer_array[i]));		}		RMFree(context.dmabuffer_array);		context.dmabuffer_index = 0;		context.dmabuffer_array = NULL;	}		if (context.bcc_enabled)	{		RMDBGLOG((DEBUG, "Closing external closed caption subsystem...\n"));		bcc_close(context.pbcc, dcc_info.pRUA);		context.bcc_enabled = FALSE;		RMDBGLOG((DEBUG, "Done closing external closed caption subsystem.\n"));	}	if (dcc_info.pStcSource) {		Stop(&context, RM_DEVICES_STC);		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"));#ifndef WITH_MONO		clear_display_options(&dcc_info, context.disp_opt);#endif /*WITH_MONO*/	}	clear_video_options(&dcc_info, context.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"));	}#ifndef WITH_MONO	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;	}#endif /*WITH_MONO*/	return 0;}

⌨️ 快捷键说明

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