编译环境:Ubuntu16.04 64位
交叉编译工具:arm-hisiv500-linux-gcc
文章目录
- 1. 交叉编译mp4v2
- 2. sample代码
- 2.1 创建文件
- 2.2 关闭文件
- 2.3 写数据
1. 交叉编译mp4v2
下载合适版本的mp2v2源码,我下载的是2.0.0的bz包mp4v2_2.0.0~dfsg0.orig.tar.bz2
tar jxf mp4v2_2.0.0~dfsg0.orig.tar.bz2
cd mp4v2-2.0.0;./configure --host=arm-hisiv500-linux CC=arm-hisiv500-linux-gcc CXX=arm-hisiv500-linux-g++ --disable-debug
make
生成的libmp4v2.a在目录.libs
头文件位于include/mp4v2目录,头文件需要拷贝完全,代码中仅需要包含mp4v2.h
#include "mp4v2/mp4v2.h"
注意:移植后,链接libmp4v2.a需要加上-lstdc++选项。
2. sample代码
注意:代码基于hi3519平台。
2.1 创建文件
MP4FileHandle hMP4File = MP4CreateEx(fileName, 0, 1, 1, 0, 0, 0, 0);
MP4SetTimeScale(hMP4File, 90000);
2.2 关闭文件
MP4Close(hMP4File, 0);
2.3 写数据
typedef struct _MP4ENC_NaluUnit
{int type;int size;unsigned char *data;
}MP4ENC_NaluUnit;typedef struct _MP4ENC_INFO
{unsigned int u32FrameRate;unsigned int u32Width;unsigned int u32Height;unsigned int u32Profile;
}MP4ENC_INFO;static HI_S32 Sample_MP4_ReadNalu(HI_U8 *pPack, HI_U32 nPackLen, unsigned int offSet, MP4ENC_NaluUnit *pNaluUnit)
{int i = offSet;while (i < nPackLen){if (pPack[i++] == 0x00 && pPack[i++] == 0x00 && pPack[i++] == 0x00 && pPack[i++] == 0x01)// 开始码{int pos = i;while (pos < nPackLen){if (pPack[pos++] == 0x00 && pPack[pos++] == 0x00 && pPack[pos++] == 0x00 && pPack[pos++] == 0x01)break;}if (pos == nPackLen)pNaluUnit->size = pos - i;elsepNaluUnit->size = (pos - 4) - i;pNaluUnit->type = pPack[i] & 0x1f;pNaluUnit->data = (unsigned char *)&pPack[i];return (pNaluUnit->size + i - offSet);}}return 0;
}static HI_S32 Sample_MP4_WRITE(MP4FileHandle hFile, MP4TrackId *pTrackId,VENC_STREAM_S *pstStream, MP4ENC_INFO *stMp4Info)
{int i = 0;for (i = 0; i < pstStream->u32PackCount; i++){HI_U8 *pPack = pstStream->pstPack[i].pu8Addr + pstStream->pstPack[i].u32Offset;HI_U32 nPackLen = pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset;MP4ENC_NaluUnit stNaluUnit;memset(&stNaluUnit, 0, sizeof(stNaluUnit));int nPos = 0, nLen = 0;while ((nLen = Sample_MP4_ReadNalu(pPack, nPackLen, nPos, &stNaluUnit)) != 0){switch (stNaluUnit.type){case H264E_NALU_SPS:if (*pTrackId == MP4_INVALID_TRACK_ID){*pTrackId = MP4AddH264VideoTrack(hFile, 90000, 90000 / stMp4Info->u32FrameRate, stMp4Info->u32Width, stMp4Info->u32Height, stNaluUnit.data[1], stNaluUnit.data[2], stNaluUnit.data[3], 3);if (*pTrackId == MP4_INVALID_TRACK_ID){return HI_FAILURE;}MP4SetVideoProfileLevel(hFile, stMp4Info->u32Profile);MP4AddH264SequenceParameterSet(hFile,*pTrackId,stNaluUnit.data,stNaluUnit.size);}break;case H264E_NALU_PPS:if (*pTrackId == MP4_INVALID_TRACK_ID){break;}MP4AddH264PictureParameterSet(hFile,*pTrackId,stNaluUnit.data,stNaluUnit.size);break;case H264E_NALU_IDRSLICE:case H264E_NALU_PSLICE:{if (*pTrackId == MP4_INVALID_TRACK_ID){break;}int nDataLen = stNaluUnit.size + 4;unsigned char *data = (unsigned char *)malloc(nDataLen);data[0] = stNaluUnit.size >> 24;data[1] = stNaluUnit.size >> 16;data[2] = stNaluUnit.size >> 8;data[3] = stNaluUnit.size & 0xff;memcpy(data + 4, stNaluUnit.data, stNaluUnit.size);if (!MP4WriteSample(hFile, *pTrackId, data, nDataLen, MP4_INVALID_DURATION, 0, 1)){free(data);return HI_FAILURE;}free(data);}break;default :break;}nPos += nLen;}}return HI_SUCCESS;
}
以上代码没有封装音频,可以稍作修改,用作其他平台。
mp4v2貌似不支持h265,后续将使用其他的开源库做封装,详见我的另一篇博客《使用gpac封装mp4》。
转载请注明出处,如有错漏之处,敬请指正。