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.