专栏首页天天P图攻城狮Android音视频系列:视频容器操作篇 -- mp4容器打包实现

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

经过视频编码后的帧数据,需要放到视频容器里,才能成为一个常规的视频文件。我们以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图攻城狮”,那上面将陆续公开分享我们的技术实践,期待一起交流学习!

加入我们

本文分享自微信公众号 - 天天P图攻城狮(ttpic_dev),作者:tao

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS 图像处理系列 - 基于GPUImage的滤镜实现及优化

    我们知道,对于图像处理中,滤镜效果是一种最普遍也最有效的图像优化方式。通过对图像进行不同的滤镜效果的处理,可以得到各种绚丽的图片。

    天天P图攻城狮
  • 灭霸都不会的马赛克还原技术@天天P图

    你去看复联4了吗?最近肯定很多小伙伴都多少有收到这样的「亲切」问候。复联4在周三凌晨上映了,鉴于首映在零点,又是非周末,还TM的需要看3个小时,开发小哥哥想了想...

    天天P图攻城狮
  • 终端图像处理系列 - OpenGL ES 2.0 - 3D基础(矩阵投影)

    Overview 移动设备的屏幕是二维平面,要想把一个三维场景渲染在手机二维屏幕上,需要利用OpenGL中的矩阵投射,将三维空间中的点映射到二维平面上。三维矩阵...

    天天P图攻城狮
  • 【基础篇】hexo博客搭建教程

    不要担心,本系列教程将会实现你白嫖的愿望,连服务器都不需要买,就算没有任何编程基础也可以学会的搭建博客教程

    huanhao
  • M41T11-RTC(实时时钟)

    一、理论准备 1. 主要器件:STM8单片机、M41T11时钟IC、32.768kHz晶振等。 2. 外围设备:烧录工具ST-Link/v2、串口、5v供电SA...

    Christal_R
  • 【通信专栏】STM32单片机/I2C通信(上篇)

    想来单片机这块儿除了USART串口通信外,常见的便是I2C通信了,因为I2C通信 硬件连接简单,可扩展性强,但是这种硬件连线的简洁,是以协议的复杂来弥补的。I2...

    周旋
  • CTF从入门到提升(六)order_by注入及例题分享

    我们都知道常规的注入,比如id=100这种类型可以查询出一篇文章,如果把100换成99+1它一样可以查出,因为它会做计算。order_by 去判断列数的时候,如...

    牛油果
  • 手把手教你用Java打造一款简单考试系统(下篇)

    随着移动互联网的发展,网络给我们带来的是无穷的信息,也带来了便利。与传统考试模式相对比,在线考试具有很多优越性、它可以将传统考试过程中的试卷组织、传送、收集、评...

    Python进阶者
  • Zookeeper集群安装

    cd /usr/local/src/ tar -C /usr/local/ -xzf zookeeper-3.5.4.tar.gz cd /usr/local/...

    HUC思梦
  • linux系统安装zookeeper 服务的方法

    5、进入到 /usr/local/services/zookeeper/zookeeper-3.4.9/conf 目录中:

    砸漏

扫码关注云+社区

领取腾讯云代金券