前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android音视频系列:视频容器操作篇 -- mp4容器打包实现

Android音视频系列:视频容器操作篇 -- mp4容器打包实现

作者头像
天天P图攻城狮
修改2019-05-16 17:04:13
1.8K0
修改2019-05-16 17:04:13
举报

经过视频编码后的帧数据,需要放到视频容器里,才能成为一个常规的视频文件。我们以mp4容器为例子,聊一聊代码层面上帧数据如何放到mp4容器里。

一个友好的mp4视频结构,如下图,ftyp是基本信息,moov是头部信息,mdat是帧数据。moov在mdat前面,支持流媒体边下边播。

开源代码库mp4v2,作为mp4容器操作工具,是如何实现帧数据的容器打包的呢?

下面是mp4标准定义的box结构。

在mp4v2里,用MP4Atom对象定义一个box。虚拟出root box,是MP4RootAtom对象,继承自MP4Atom。

MP4RootAtom

MP4AtomArray是MP4Atom组成的动态数组,动态指数组长度可以动态增长。

函数调用经历以下流程:

一、

----- MP4Create(pFileName, 0);

1. 创建m_pRootAtom1. 创建m_pRootAtom

MP4Atom::CreateAtom()第3个形参是const char* type,取NULL,就意味着创建MP4RootAtom。

Generate()会主动创建它的第一个孩子,moov atom。现在是这样子的:

2. 创建ftyp atom

说到这个InsertChildAtom()就很牛逼了,它把ftyp atom插入child atom array的0位置,已有的元素并不会被覆盖,而是偏移。

现在是这样子的:

3. 创建mdat atom

add_ftyp是为1的,mdat atom被插入child atom array的1位置。现在成了这样子:

4. 创建free atom,并把ftyp atom和free atom写入文件。

MP4RootAtom::BeginWrite()做了这个事情。

注意最后一行,往文件里写mdat的序曲正式拉开了。

二、

---- MP4AddH264VideoTrack()

---- MP4AddH264SequenceParameterSet()

---- MP4AddH264PictureParameterSet()

---- MP4WriteSample()

5. pps, sps, nal数据,都会写到mdat里。

三、

---- MP4Close()

6. 核心数据mdat写完了,会写上moov和free。

MP4RootAtom:FinishWrite()做了这个事情。

于是乎我们得到了这样的视频:

可以看到,现在视频的结构里,有两个问题,一是存在冗余的free box,一是moov在mdat后面。

四、

---- MP4Optimize()

提供了Optimize()接口,可以做到把上面的视频转变为:

7. 读入文件的所有一级atom

8. 写入ftyp和moov

MP4RootAtom::BeginOptimalWrite()做了这个事情:

最后一行开始写mdat。

9. 写入mdat

至此,moov调整到了mdat前面,一个友好的mp4结构就打包完成了。

回头思考一下,既然moov需要在mdat前面,那么为什么mp4v2打包的过程,要反过来把moov写在mdat之后呢?

因为在mdat写完之前,moov的长度是不确定的。所以为了不影响往文件里写mdat,就把moov挪到了mdat后面,等mdat写完之后,再写入moov。

作者简介:tao, 天天P图 AND 工程师


文章后记

天天 P 图是由腾讯公司开发的业内领先的图像处理,相机美拍的 APP。欢迎扫码或搜索关注我们的微信公众号:“天天P图攻城狮”,那上面将陆续公开分享我们的技术实践,期待一起交流学习!

加入我们

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 天天P图攻城狮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档