使用mp4v2封装mp4

news/2024/11/20 4:44:46/

编译环境: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》。

转载请注明出处,如有错漏之处,敬请指正。


http://www.ppmy.cn/news/287161.html

相关文章

mp4box-h264-ftyp-moov-mvhd-thkd-avcC-sps-pps 详解

1、mp4文件&#xff0c;是由多个Box或FullBox组成 2、 Box&#xff0c;每个Box由Header和Data组成&#xff0c;FullBox&#xff0c;是Box的扩展&#xff0c;Box结构的基础上在Header中增加8bits version和24bits flags 3、 Header&#xff0c;包含了整个Box的长度size和类型t…

常用视频格式转换nv12,i420,i444,p010

文章目录 视频存储格式NV12转I420NV12转I444P010转I420 视频存储格式 P010格式与NV12格式一样&#xff0c;区别就是两个字节存一个像素值。 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y …

百度领航团零基础Python-Day1

百度领航团零基础Python-Day1 文章目录 简介安装执行python代码语法基础第一个 Python 程序基本数据类型Python数据类型转换算术运算符条件语句循环语句for 循环 作业 课程链接&#xff1a;https://aistudio.baidu.com/aistudio/course/introduce/7073 简介 python是一种解释性…

树莓派中的 IM 私有云支持多少并发?

美信拓扑技术分享系列 0x01。关注「美信拓扑」微信公众号&#xff0c;第一时间阅读本系列后续文章&#xff0c;了解美信拓扑IM的协议、架构和源码。 4000人同时在线&#xff0c;这是美信拓扑 IM 私有云的数据。是的&#xff0c;只需要一个400块的树莓派4B。注意&#xff0c;这不…

砸冰箱维权是“公益秀”

先引用一篇老罗的《秋菊男的故事》&#xff0c;这篇文章最早刊登在《独唱团》上。 十四年前......这是一个真实的故事。十四年前&#xff0c;我在东北老家延吉市的一个外语培训机构学过一段时间的许国璋英语。这是一个韩国人开的私立学校&#xff0c;名字 很土&#xff0c;叫三…

钱大妈,一家卖猪肉的广告公司

文 | 易不二 来源 | 螳螂财经&#xff08;ID:TanglangFin&#xff09; “中国的一个小区一般有3000户就是1万人&#xff0c;一万人在欧美是一个大型的小镇。在欧美&#xff0c;一个小镇就会有一家大卖场很多的商业配套。所以你们可以试想中国未来的小区会迸发出什么样的红利&…

一篇文章入门python基础

python python入门 人生苦短&#xff0c;我用python python的特点&#xff1a;简洁性、易读性、可扩展性 my_number3200 guess_numberinput("这台冰箱多少钱&#xff1f;") guess_numberint(guess_number) while guess_number!my_number:if guess_number<my_nu…

一个女人究竟该花多少钱?

奥斯卡王尔德说&#xff1a;“量入为出的人是最缺乏想象力的。”这话放在朱迪思莱文&#xff08;Judith Levine&#xff09;身上可不太公平。 最近&#xff0c;美国作家朱迪思莱文的新著《不买东西》&#xff08;Not Buying It&#xff09;在英国出版&#xff0c;有趣的是&…