mpp sample_venc_mp4


原文链接: mpp sample_venc_mp4

mp4v2封装h264成mp4
编译mp4v2,海思hi3518

./configure --host=arm-hisiv300-linux CC=arm-hisiv300-linux-gcc CXX=arm-hisiv300-linux-g++ --disable-debug --prefix=$PATH/tmp

so文件拷贝到lib目录下。

把include 目录下的mp4v2 拷贝到hi3518sdk的include 目录下。 修改venc下的makefile文件 加上 -lmp4v2 如果找不到头文件加上-I 到include目录或者include/mp4v2

可以做个参考 ,格式就不分析了。

typedef enum hiH264E_NALU_TYPE_E
{
     H264E_NALU_PSLICE = 1,                         /*PSLICE types*/
     H264E_NALU_ISLICE = 5,                         /*ISLICE types*/
     H264E_NALU_SEI    = 6,                         /*SEI types*/
     H264E_NALU_SPS    = 7,                         /*SPS types*/
     H264E_NALU_PPS    = 8,                         /*PPS types*/
     H264E_NALU_IPSLICE = 9,
     H264E_NALU_BUTT        
} H264E_NALU_TYPE_E;

HI_S32 SAMPLE_COMM_VENC_MP4(VENC_STREAM_S *stStream)
{
	static int nRecordFlag = 0x00;
	static int recording = 0x1;
	static int spsflag = 0;
	static int ppsflag = 0;
	static MP4TrackId video = 0;
	static MP4FileHandle hMP4File = NULL;

	static char recordfish = 0x1;
	
	int j = 0;
	int len = 0;
	char *pData = NULL;
	char isSyncSample = 0;
	
	if(recordfish == 0x00){
		return 0;
	}

	if(hMP4File == NULL){
		hMP4File = MP4CreateEx("/usr/mmc/test.mp4",0, 1, 1, 0, 0, 0, 0);			//文件存储路径
		if (hMP4File == MP4_INVALID_FILE_HANDLE)	{
			printf("open file fialed.\n");
			return -1;
		}
	
		MP4SetTimeScale(hMP4File, 90000);
	}
	
	if(recording && stStream->u32Seq > 30)//丢弃前30帧,也可以不丢弃
	{			
		if(stStream->u32PackCount >= 3)//从I帧开始编码,保证文件开始就能播放
		{			
			nRecordFlag = 1;
		}
	
		if(nRecordFlag){
			for(j = 0;j < stStream->u32PackCount;j++){
				len 	= stStream->pstPack[j].u32Len - stStream->pstPack[j].u32Offset;
				pData	= (stStream->pstPack[j].pu8Addr + stStream->pstPack[j].u32Offset);						
	
				if(stStream->pstPack[j].DataType.enH264EType == H264E_NALU_SPS){
					if(spsflag == 0x00){
						spsflag = 0x1;
						//写sps
						printf("Write sps =================\n");	
	
	
						video = MP4AddH264VideoTrack(hMP4File, 90000, 90000 / 30, 1280, 720,
																pData[4+1], //sps[1] AVCProfileIndication
																pData[4+2], //sps[2] profile_compat
																pData[4+3], //sps[3] AVCLevelIndication
																3); // 4 bytes length before each NAL unit
							MP4SetVideoProfileLevel(hMP4File, 0x7F);
							MP4AddH264SequenceParameterSet(hMP4File, video, pData+4, len-4);										
					}
					
					continue;
				}
				
				if(stStream->pstPack[j].DataType.enH264EType == H264E_NALU_PPS){
					if(ppsflag == 0x00){
						ppsflag = 0x1;
						//写pps									
						printf("Write pps -------------------\n");										
						MP4AddH264PictureParameterSet(hMP4File, video, pData+4, len-4);
					}
					
					continue;
				}
	
				isSyncSample = (stStream->pstPack[j].DataType.enH264EType == H264E_NALU_ISLICE)	?  (1) : (0);
				pData[0] = (len - 4) >> 24;
				pData[1] = (len - 4) >> 16;
				pData[2] = (len - 4) >> 8;
				pData[3] = len - 4; 							
	
				printf("Write date type = %d  isSyncSample = %d\n",stStream->pstPack[j].DataType.enH264EType,isSyncSample);								
	
				MP4WriteSample(hMP4File, video, pData, len , MP4_INVALID_DURATION, 0, isSyncSample);
	
				
			}					
		}
	}
	
	if((recording && stStream->u32Seq > 900))
	{		//控制文件时长
		recording = 0x00;
		printf("Close mp4 file\n");						
		MP4Close(hMP4File, 0);
		hMP4File = NULL;
		video = 0;
		recordfish = 0x00;
	}

}

打印信息为

Write sps =================
Write pps -------------------
Write date type = 6 isSyncSample = 0
Write date type = 5 isSyncSample = 1
Write date type = 1 isSyncSample = 0
Write date type = 1 isSyncSample = 0
Write date type = 1 isSyncSample = 0
Write date type = 1 isSyncSample = 0
Write date type = 1 isSyncSample = 0
Write date type = 1 isSyncSample = 0
Write date type = 1 isSyncSample = 0
中间部分被删除
Write date type = 1 isSyncSample = 0
Write date type = 1 isSyncSample = 0
Write date type = 6 isSyncSample = 0
Write date type = 5 isSyncSample = 1
Write date type = 1 isSyncSample = 0
Close mp4 file
先一个6 在一个5 , 5 是I帧,同步帧。开始的时候 是一个sps 和pps.

`