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

📄 play_mp4.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
														e.ModuleID = pSendContext->dcc_info->video_decoder;							e.Mask = RUAEVENT_XFER_FIFO_READY;							RUAWaitForMultipleEvents(pSendContext->pRUA, &e, 1, COMMON_TIMEOUT_US, NULL);							RMDBGLOG((ENABLE, "waiting to send video startcode\n"));						}						else {							RMDBGLOG((ENABLE, "waiting to send video startcode\n"));							return status;						}					}				}								status = dump_data_into_file(pSendContext->play_opt, 							     RMVDEMUX_VIDEO, 							     videoDMAStartCodeBuffer, 							     4, 							     pSendContext->video_Info.TimeStamp, 							     (pSendContext->video_Info.ValidFields & TIME_STAMP_INFO), 							     pSendContext->video_Info.FirstAccessUnitPointer);				if (RMFAILED(status)) {					RMDBGLOG((ENABLE, "Cannot dump data %d\n", status));					return status;				}								pSendContext->h264sendStartCode = FALSE;								// required for prebuffering routine				pSendContext->videoDataSent += 4;				pSendContext->startCodeDMABufferOffset += 4;				if (pSendContext->startCodeDMABufferOffset + DMABUFFER_UNUSED_BLOCK_SIZE >= sizeBuffer) {					RMDBGLOG((DBG, "release buffer 0x%lx startcode %lu\n", (RMuint32)pSendContext->startCodeDMABuffer, pSendContext->startCodeDMABufferOffset));					RUAReleaseBuffer(pSendContext->pDMA, pSendContext->startCodeDMABuffer);					pSendContext->startCodeDMABuffer = NULL;					pSendContext->startCodeDMABufferOffset = 0;				}				RMDBGLOG((H264_SC_DBG, "sent startcode\n"));				if (pSendContext->SendVideoData) {					RMDBGLOG((SENDDBG, "sent H264 video startcode : frameCount %lu totalBytes %lu pts %lld ( 0x%llx ) %s\n",						  pSendContext->videoFrameCount,						  pSendContext->videoDataSent,						  pSendContext->video_Info.TimeStamp,						  pSendContext->video_Info.TimeStamp,						  (pSendContext->video_Info.ValidFields & TIME_STAMP_INFO) ? "valid":""));									}				// dont send pts with subsequent packets				pSendContext->video_Info.ValidFields = 0;				pSendContext->video_Info.TimeStamp = 0;			}					// read avcPkt size			if (pSendContext->h264readPacketSize) {								while (sample->size) {					*(pSendContext->h264PktLenBuf) = *(sample->buf);										pSendContext->h264PktLenBuf++;										sample->size--;					sample->buf++;										pSendContext->h264LengthSize--;					if (!pSendContext->h264LengthSize)						break;				}								if (!pSendContext->h264LengthSize) {					pSendContext->h264readPacketSize = FALSE;										RMGetH264LengthSize(pSendContext->mp4tV, &(pSendContext->h264LengthSize));										pSendContext->h264PktLenBuf -= pSendContext->h264LengthSize;										switch (pSendContext->h264LengthSize) {					case 2:						pSendContext->h264PktLen = RMbeBufToUint16(pSendContext->h264PktLenBuf);						break;					case 3:						pSendContext->h264PktLen = RMbeBufToUint24(pSendContext->h264PktLenBuf);						break;					case 4:						pSendContext->h264PktLen = RMbeBufToUint32(pSendContext->h264PktLenBuf);						break;					default:						RMDBGLOG((ENABLE, "ERROR! unhandled h264LengthSize %lu\n", pSendContext->h264LengthSize));						return RM_ERROR;					}					RMDBGLOG((H264_SC_DBG, "read h264 packet size %lu (0x%lx)\n", pSendContext->h264PktLen, pSendContext->h264PktLen));					pSendContext->h264BytesLeft = pSendContext->h264PktLen;				}				if (!sample->size) {					RMDBGLOG((ENABLE, "get new sample\n"));					return RM_OK; 				}			}							// send the rest of the buffer			sizeToSend = RMmin(pSendContext->h264BytesLeft, sample->size);					if (pSendContext->SendVideoData) {				status = RUASendData(pSendContext->pRUA, 						     pSendContext->dcc_info->video_decoder, 						     pSendContext->pDMA, 						     sample->buf, 						     sizeToSend, 						     &pSendContext->video_Info, 						     sizeof(pSendContext->video_Info));								if (status != RM_OK) {					if (status == RM_PENDING) {						RMDBGLOG((ENABLE, "video transfer pending\n"));						pSendContext->videoTransferPending = TRUE;					}					return status;				}				pSendContext->videoTransferPending = FALSE;			}						status = dump_data_into_file(pSendContext->play_opt, 						     RMVDEMUX_VIDEO, 						     sample->buf, 						     sizeToSend, 						     pSendContext->video_Info.TimeStamp, 						     (pSendContext->video_Info.ValidFields & TIME_STAMP_INFO), 						     pSendContext->video_Info.FirstAccessUnitPointer);			if (RMFAILED(status)) {				RMDBGLOG((ENABLE, "Cannot dump data %d\n", status));			}						pSendContext->h264BytesLeft -= sizeToSend;			sample->size -= sizeToSend;			sample->buf  += sizeToSend;						// required for prebuffering routine			pSendContext->videoDataSent += sizeToSend;			RMDBGLOG((H264_SC_DBG, "send payload (%5lu/%5lu), sampleSize %5lu, bytesLeft %5lu\n",				  sizeToSend,				  pSendContext->h264PktLen,				  sample->size,				  pSendContext->h264BytesLeft));						if (!pSendContext->h264BytesLeft) {				pSendContext->h264sendStartCode = TRUE;				pSendContext->h264readPacketSize = TRUE;			}			if (pSendContext->SendVideoData) {				RMDBGLOG((SENDDBG, "sent a video packet (flags %lu) frameCount %lu size %ld / %lu (total %lu ) pts %lld ( 0x%llx ) %s\n", 					  pSendContext->videosample.flags,					  pSendContext->videoFrameCount,					  sizeToSend,					  pSendContext->videoSampleSize, 					  pSendContext->videoDataSent,					  pSendContext->video_Info.TimeStamp,					  pSendContext->video_Info.TimeStamp,					  (pSendContext->video_Info.ValidFields & TIME_STAMP_INFO) ? "valid":""));							}		}		return RM_OK;	}	// else, just send the packets coming from the MP4 parser	if (pSendContext->SendVideoData) {		status = RUASendData(pSendContext->pRUA, 				     pSendContext->dcc_info->video_decoder, 				     pSendContext->pDMA, 				     pSendContext->videosample.buf, 				     pSendContext->videosample.size, 				     &pSendContext->video_Info, 				     sizeof(pSendContext->video_Info));				if (status != RM_OK) {			if (status == RM_PENDING) {				RMDBGLOG((ENABLE, "video transfer pending\n"));				pSendContext->videoTransferPending = TRUE;			}			return status;		}		pSendContext->videoTransferPending = FALSE;	}		status = dump_data_into_file(pSendContext->play_opt, 				     RMVDEMUX_VIDEO, 				     pSendContext->videosample.buf, 				     pSendContext->videosample.size, 				     pSendContext->video_Info.TimeStamp, 				     (pSendContext->video_Info.ValidFields & TIME_STAMP_INFO), 				     pSendContext->video_Info.FirstAccessUnitPointer);	if (RMFAILED(status)) {		RMDBGLOG((ENABLE, "Cannot dump data %d\n", status));	}		{		RMuint8 picType = 0xFF;		// check MPEG4 picture type, 0=I;1=P;2=B;3=S		if ((pSendContext->videosample.size > 5) && (!pSendContext->isH264)) {			RMuint8 *dummy = pSendContext->videosample.buf;			RMuint8 byte;			if ((dummy[0] == 0) &&			    (dummy[1] == 0) &&			    (dummy[2] == 1) &&			    (dummy[3] == 0xb6)) {				byte = dummy[4];				byte &= 0xC0;				byte >>= 6;				picType = byte;			}		}				if (pSendContext->SendVideoData) {			RMDBGLOG((SENDDBG, "sent a packet video %s dma 0x%08X, sample 0x%08X, size %ld, total %lu, pts %lld(0x%llx) %s\n", 				  (picType == 0) ? "(picType: I)": ((picType == 1) ? "(picType: P)": ((picType == 2) ? "(picType: B)":"")),				  pSendContext->pDMA, 				  pSendContext->videosample.buf, 				  pSendContext->videosample.size, 				  pSendContext->videoDataSent,				  pSendContext->video_Info.TimeStamp,				  pSendContext->video_Info.TimeStamp,				  (pSendContext->video_Info.ValidFields & TIME_STAMP_INFO) ? "valid":""));					}	}		// required for prebuffering routine	pSendContext->videoDataSent += pSendContext->videosample.size;	return RM_OK;}static RMstatus send_MP4_video(struct SendMP4DataContext * pSendContext){	RMstatus status;	RMuint64 pts;	RMbool notEOS = TRUE;	//enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(pSendContext->PSMcontext, &(pSendContext->dcc_info));		if (pSendContext->videoTransferPending)		goto send_data;	pSendContext->videosample.buf = pSendContext->videoDMABuffer + pSendContext->videoDMABufferOffset;		pSendContext->videosample.size = (1<<pSendContext->dmaBufferSizeLog2) - pSendContext->videoDMABufferOffset;		if (pSendContext->play_opt->disk_ctrl_state == DISK_CONTROL_STATE_SLEEPING)		RMDBGLOG((ENABLE, "trying to read from a suspended drive!!\n"));	if (pSendContext->isIFrameMode && pSendContext->IFrameDirection > 0) {		notEOS = RMGetNextMP4RandomAccessSample(pSendContext->mp4tV, &(pSendContext->videosample), pSendContext->videosample.size);	}	else if (pSendContext->isIFrameMode && pSendContext->IFrameDirection < 0) {		notEOS = RMGetPrevMP4RandomAccessSample(pSendContext->mp4tV, &(pSendContext->videosample), pSendContext->videosample.size);	}	else		notEOS = RMGetNextMP4Sample(pSendContext->mp4tV, &(pSendContext->videosample), pSendContext->videosample.size);		if (!notEOS) {		RMDBGLOG((ENABLE,"Failed to get Video sample -> end of video stream\n"));		pSendContext->videoEOS = TRUE;		return RM_EOS;	}		RMDBGLOG((DISABLE, "got video sample of size %ld\n", pSendContext->videosample.size));	pSendContext->videoSampleSize = pSendContext->videosample.size;	pSendContext->video_Info.TimeStamp = 0;	pSendContext->video_Info.ValidFields = 0;	if (pSendContext->videosample.flags & MP4_AU_START) {		pSendContext->videoFrameCount++;	}	//RMDBGLOG((ENABLE, "[%lu] sample size %lu flags %lu\n", pSendContext->videoFrameCount, pSendContext->videoSampleSize, pSendContext->videosample.flags));	if (pSendContext->videosample.flags & MP4_CTS_VALID) {				pSendContext->video_Info.ValidFields = TIME_STAMP_INFO;				pts = RMuint64from2RMuint32(pSendContext->videosample.CTS_MSB, pSendContext->videosample.CTS_LSB);		pSendContext->video_Info.TimeStamp = pts;		if (pSendContext->video_vop_tir != pSendContext->VideoCTSTimeScale) {			pSendContext->video_Info.TimeStamp = round_int_div(pts * pSendContext->video_vop_tir, pSendContext->VideoCTSTimeScale);			RMDBGLOG((DISABLE, "video pts scaling! old %lld => %lld thru a factor %ld/%ld\n",				  pts,				  pSendContext->video_Info.TimeStamp,				  pSendContext->video_vop_tir,				  pSendContext->VideoCTSTimeScale));		} 		else			RMDBGLOG((DISABLE, "setting pts to %llu\n", pts));		if (pSendContext->videosample.DTS_MSB != pSendContext->videosample.CTS_MSB) {			RMuint64 dts;			RMuint64 cts;			/*			  this is a hack for some h264 mov files which contain "invalid" pts			  bug #5606			*/			dts = (RMuint64)pSendContext->videosample.DTS_MSB;			dts <<= 32;			dts |= pSendContext->videosample.DTS_LSB;			cts = (RMuint64)pSendContext->videosample.CTS_MSB;			cts <<= 32;			cts |= pSendContext->videosample.CTS_LSB;			RMDBGLOG((DISABLE, "dont send invalid pts. DTSh %08lx DTSl %08lx = %09llx CTSh %08lx CTSl %08lx = %09llx lastPTS %llx scale %lu\n",				  pSendContext->videosample.DTS_MSB,				  pSendContext->videosample.DTS_LSB,				  dts,				  pSendContext->videosample.CTS_MSB,				  pSendContext->videosample.CTS_LSB,				  cts,				  pSendContext->lastVideoPTS,				  pSendContext->video_vop_tir));			pSendContext->video_Info.TimeStamp = 0;			pSendContext->video_Info.ValidFields = 0;		} 					if (pSendContext->video_Info.TimeStamp)			pSendContext->lastVideoPTS = (1000 * pSendContext->video_Info.TimeStamp) / pSendContext->video_vop_tir;	}	if (!pSendContext->SendVideoPts) {		pSendContext->video_Info.TimeStamp = 0;		pSendContext->video_Info.ValidFields = 0;	}	RMDBGLOG((DISABLE, "[%lu] sample size %lu flags %lu pts 0x%llx valid %lu\n", 		  pSendContext->videoFrameCount, 		  pSendContext->videoSampleSize, 		  pSendContext->videosample.flags,		  pSendContext->video_Info.TimeStamp,		  pSendContext->video_Info.ValidFields));	// happens only once	if (!pSendContext->video_ptsScalingMsg) {		if (pSendContext->video_vop_tir != pSendContext->VideoCTSTimeScale) {			RMDBGLOG((ENABLE, ">>>video pts scaling! thru a factor %ld/%ld\n",				  pSendContext->video_vop_tir,				  pSendContext->VideoCTSTimeScale));		}		else			RMDBGLOG((ENABLE, ">>> no video pts scaling required\n"));		pSendContext->video_ptsScalingMsg = TRUE;	}					if (pSendContext->FirstSystemTimeStamp) {		if (pSendContext->video_Info.ValidFields & TIME_STAMP_INFO) {			RMuint64 dummyPTS = pSendContext->video_Info.TimeStamp;			RMDBGLOG((ENABLE, "FirstSystemTimeStamp from video = %lld (0x%llX) at %ld/sec = %llu s\n",				  dummyPTS,				  dummyPTS,				  pSendContext->video_vop_tir,				  dummyPTS / pSendContext->video_vop_tir));							pSendContext->FirstSystemTimeStamp = FALSE;			RMDBGLOG((ENABLE, "setting timers\n"));			DCCSTCSetTime(pSendContext->dcc_info->pStcSource, dummyPTS, pSendContext->video_vop_tir);#if PLAY_TIMERS			if ((PlaybackStatus != RM_PSM_Prebuffering) && (PlaybackStatus != RM_PSM_Paused) && (PlaybackStatus != RM_PSM_Stopped))				DCCSTCPlay(pSendContext->dcc_info->pStcSource);#endif		} 		else {			if (pSendContext->forceTimersToZero) {				RMDBGLOG((ENABLE, ">>> no pts, force timers to zero\n"));				DCCSTCSetTime(pSendContext->dcc_info->pStcSource, 0, pSendContext->video_vop_tir);#if PLAY_TIMERS				if ((PlaybackStatus != RM_PSM_Prebuffering) && (PlaybackStatus != RM_PSM_Paused) && (PlaybackStatus != RM_PSM_Stopped))					DCCSTCPlay(pSendContext->dcc_info->pStcSource);#endif				pSendContext->FirstSystemTimeStamp = FALSE;			}			else {				RMDBGLOG((ENABLE, "waiting for first time stamp to be detected, timer not set!!!, video skipped\n"));				return RM_OK;			}		}	}			RMDBGLOG((DISABLE, "about to send a packet video dma 0x%08X, sample 0x%08X, size %ld, pts %lld(0x%llx) %s\n", 		  pSendContext->pDMA, 		  pSendContext->videosample.buf, 		  pSendContext->videosample.size, 		  pSendContext->video_Info.TimeStamp,		  pSendContext->video_Info.TimeStamp,		  (pSendContext->video_Info.ValidFields & TIME_STAMP_INFO) ? "valid":""));	pSendContext->videoDMABufferOffset += pSendContext->videosample.size; send_data:	if (pSendContext->videosample.size != 0) {		status = send_video_payload(pSendContext);		if (status != RM_OK)			return status;	}	else {		RMDBGLOG((ENABLE, "got video sample of size 0!\n"));	}			return RM_OK;}#define SPU_SAMPLES_QUEUE_SIZE 10	#ifdef WITH_MONOstatic void flush_spu_fifo(struct SendMP4DataContext * pSendContext){	struct spu_fifo_entry_type *buf_info = NULL;	RMuint32 rd1, rd2;	RMuint32 size1;	RMDBGLOG((SPU_DBG, "flush_spu_fifo\n"));#ifndef

⌨️ 快捷键说明

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