1、将代码拷贝到sample_comm_venc.c中。
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("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;
}
}
2、将函数SAMPLE_COMM_VENC_MP4函数插入到获取数据流之后
s32Ret = HI_MPI_VENC_GetStream(i, &stStream, HI_TRUE);//获取视频流
if (HI_SUCCESS != s32Ret)
{
free(stStream.pstPack);
stStream.pstPack = NULL;
SAMPLE_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", s32Ret);
break;
}
SAMPLE_COMM_VENC_MP4(&stStream);//将h264视频流封装到mp4中。
3、编译和运行sample_venc,就可以得到一个完整的mp4文件了。
总体来说移植mp4v2并不难,关键是要理解关键API的用法和参数含义。
这里的mp4是没有声音的,因为没有将声音封装进去,后面的文章会将声音和视频一起放进mp4。