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

📄 play_mp4.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 5 页
字号:
		else {			RMuint32 nextSampleSize;			RMGetMP4TrackNextSampleSize(pSendContext->mp4tV, &nextSampleSize);								RMDBGLOG((H264_SC_DBG, "%02x %02x %02x %02x this sample size %6lu next %6lu flags %2lu\n", 				  sample->buf[0],				  sample->buf[1],				  sample->buf[2],				  sample->buf[3],				  sample->size,				  nextSampleSize,				  sample->flags));		}					if (sample->flags & MP4_AU_START) {						pSendContext->h264sendStartCode = TRUE;			pSendContext->h264readPacketSize = TRUE;			/* 			   clear the flag because if sending part of the sample returns pending, we'll get called again			   and we shouldn't send the startcode again			*/			sample->flags &= ~MP4_AU_START;		}				while (sample->size) {			RMuint32 sizeToSend;			RMDBGLOG((H264_SC_DBG, "available buffer count: %lu\n", RUAGetAvailableBufferCount(pSendContext->pDMA)));						// send startcode						if (pSendContext->h264sendStartCode) {				// get a DMA buffer				if (!pSendContext->startCodeDMABuffer) {					get_buffer(pSendContext, &(pSendContext->startCodeDMABuffer));					if (pSendContext->processKeyResultValid) {						RMDBGLOG((ENABLE, "a key was pressed during H264 startcode buffer wait"));						// a key was pressed, return to main_loop to process it						return RM_PENDING;					}					pSendContext->startCodeDMABufferOffset = 0;					RMDBGLOG((DBG, "setting new buffer for video startcodes 0x%lx\n", (RMuint32)pSendContext->startCodeDMABuffer));				}				videoDMAStartCodeBuffer = pSendContext->startCodeDMABuffer + pSendContext->startCodeDMABufferOffset;				pSendContext->videoTransferPending = FALSE;								// set StartCode (4bytes)				RMuint32ToBeBuf(0x00000001, videoDMAStartCodeBuffer);								if (pSendContext->SendVideoData) {					// send startcode with PTS from the sample					while (1) {						status = RUASendData(pSendContext->pRUA, 								     pSendContext->dcc_info->video_decoder, 								     pSendContext->pDMA, 								     videoDMAStartCodeBuffer, 								     4, 								     &pSendContext->video_Info, 								     sizeof(pSendContext->video_Info));						if (status == RM_OK) 							break;						/* handle end of prebufferisation here */						else if (status == RM_PENDING) {							struct RUAEvent e;														check_prebuf_state(pSendContext, 0);														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->videoBitrateCounter += 4 * 8;				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;			pSendContext->videoBitrateCounter += sizeToSend * 8;			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;	pSendContext->videoBitrateCounter += pSendContext->videosample.size * 8;	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;					if (pSendContext->videosample.DTS_MSB != pSendContext->videosample.CTS_MSB) {			RMuint64 dts;			RMuint64 cts;			RMint32 diff = 0;			//  this is a hack for some h264 mov files which contain "invalid" pts			//  bug #5606			  				// some debug:			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, "invalid pts from CTS. 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));										/*			  the hack: 			  if following condition is satisfied, compute a pts from emulated CTS			  where emulated CTS = DTS + diff			  and diff = CTS_LSB - DTS_LSB (just to make sure delay between DTS and CTS is respected in final pts			*/						if ((pSendContext->videosample.DTS_MSB == 0) && (pSendContext->videosample.CTS_MSB == 1))				diff = pSendContext->videosample.CTS_LSB - pSendContext->videosample.DTS_LSB;						// emulated cts			cts = (RMuint64)pSendContext->videosample.DTS_MSB;			cts <<= 32;			cts |= pSendContext->videosample.DTS_LSB  + diff ;			RMDBGLOG((DISABLE, "send pts based on emulated CTS: DTSh %08lx DTSl %08lx ->  0x%09llx\n",				  pSendContext->videosample.DTS_MSB,				  pSendContext->videosample.DTS_LSB + diff,				  cts));			pts = RMuint64from2RMuint32(pSendContext->videosample.DTS_MSB, pSendContext->videosample.DTS_LSB + diff);		} else			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

⌨️ 快捷键说明

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