ffmpeg源码分析及mp4文件解析

 

一.mp4文件的组织


1. mp4文件的box(ffmpeg中叫atom)


mp4是由一系列的box组成的,每个box的header是8个字节(4字节的长度,4字节的type)
第一个box比较特殊,其type类型为ftyp,还包含一个sub-type

0000000: 0000 0020 6674 7970 6973 6f6d 0000 0200 ... ftypisom....
0000010: 6973 6f6d 6973 6f32 6176 6331 6d70 3431 isomiso2avc1mp41
0000020: 0000 0008 6672 6565 0609 6f8e 6d64 6174 ....free..o.mdat
0000030: 0000 028c 0605 ffff 88dc 45e9 bde6 d948 ..........E....H
0000040: b796 2cd8 20d9 23ee ef78 3236 3420 2d20 ..,. .#..x264 - 
0000050: 636f 7265 2031 3030 202d 2048 2e32 3634 core 100 - H.264 
0000060: 2f4d 5045 472d 3420 4156 4320 636f 6465 /MPEG-4 AVC code

0000 0020 6674 7970  --> 第1个box的长度为0x20, type=ftyp
6973 6f6d  -->其sub-type=isom
0000 0008 6672 6565  --> 第2个box的长度为0x08, type=free
0609 6f8e 6d64 6174   --> 第3个box的长度为0x06096F8E, type=mdat
由此可以看出第4个box:
0x06096F8E+0x08+0x20=0x06096FB6处是第4个box
000c ca81 6d6f 6f76    --> 第4个box的长度是0x0cca81, type=moov

 

1.2 计算文件的大小


所以整个文件的大小为 0x20+0x08+0x0x06096F8E+0x0cca81=0x6163A37=102119991
cong@msi:/work/ffmpeg/ffmpeg-3.0.1$ ls -l ../san.mp4
-rw-rw-r-- 1 cong cong 102119991 Sep 10  2015 ../san.mp4
1.3 关于box-type:

box-type可以是如下一个:

"ftyp", "mdat", "moov", "pnot", "udta", "uuid", "moof", "free", "skip", "jP2 ", "wide", "load", "ctab", "imap", "matt", "kmat", "clip", "crgn", "sync", "chap", "tmcd", "scpt", "ssrc", "PICT".

sub-type可以取如下一个:

sub-type which must be one of values: "avc1", "iso2", "isom", "mmp4", "mp41", "mp42", "mp71", "msnv", "ndas", "ndsc", "ndsh", "ndsm", "ndsp", "ndss", "ndxc","ndxh", "ndxm", "ndxp", "ndxs".

 

1.4总结


一个mov文件就是由ftyp free mdat moov这四个部分组成
ftyp --> 格式
free --> 不关心
mdat --> 音视频数据
moov --> 包含一系列次级box:一个mvhd及多个trak

 

1.5 如下图所示:



清楚了

 

二. BOX的具体解析


2.1FileTypeBox--> ftype解析

0000000: 0000 0020 6674 7970 6973 6f6d 0000 0200 ... ftypisom....
0000010: 6973 6f6d 6973 6f32 6176 6331 6d70 3431 isomiso2avc1mp41

0000 0020 6674 7970  --> 第1个box的长度为0x20, type=ftyp
6973 6f6d                     --> major_brand: isom
0000 0200                    --> minor_verion: isom的版本号
6973 6f6d 6973 6f32 6176 6331 6d70 3431--> 兼容isom iso2 avc1 mp41这四个协议

ISO14496-12 的 4.3.2 Syntax 
aligned(8) class FileTypeBox extends Box(‘ftyp’) { unsigned int(32) major_brand; unsigned int(32) minor_version; unsigned int(32) compatible_brands[]; // to end of the box 
}

没有ftyp后面就不知道用什么去解析这个媒体文件


2.2 Free Space Box -->free解析


没啥作用

ISO14496-12 的8.24.2 Syntax 
aligned(8) class FreeSpaceBox extends Box(free_type) { unsigned int(8) data[]; 
}

2.3 Media Data Box -->mdat解析


这个box里面全部都是数据

ISO14496-12 的8.2.2 Syntax 
aligned(8) class MediaDataBox extends Box(‘mdat’) { bit(8) data[]; 
}

2.4 Movie Box  -->moov解析 (很复杂)

6096fb0: 9002 1900 2380 000c ca81 6d6f 6f76 0000 ....#.....moov..
6096fc0: 006c 6d76 6864 0000 0000 7c25 b080 7c25 .lmvhd....|%..|%
6096fd0: b080 0000 03e8 0014 6995 0001 0000 0100 ........i.......
6096fe0: 0000 0000 0000 0000 0000 0001 0000 0000 ................
6096ff0: 0000 0000 0000 0000 0000 0001 0000 0000 ................
6097000: 0000 0000 0000 0000 0000 4000 0000 0000 ..........@.....
6097010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
6097020: 0000 0000 0000 0000 0003 0005 bf9d 7472 ..............tr
6097030: 616b 0000 005c 746b 6864 0000 000f 7c25 ak...\tkhd....|%
6097040: b080 7c25 b080 0000 0001 0000 0000 0014 ..|%............
6097050: 6595 0000 0000 0000 0000 0000 0000 0000 e...............
6097060: 0000 0001 0000 0000 0000 0000 0000 0000  ................
6097070: 0000 0001 0000 0000 0000 0000 0000 0000  ................
6097080: 0000 4000 0000 01d6 0000 0160 0000 0000  ..@........`....
6097090: 0024 6564 7473 0000 001c 656c 7374 0000  .$edts....elst..
60970a0: 0000 0000 0001 0014 6595 0000 03e9 0001  ........e.......
60970b0: 0000 0005 bf15 6d64 6961 0000 0020 6d64  ......mdia... md

000c ca81 6d6f 6f76    --> moov的长度是0x0cca81, type=moov
0000 006c 6d76 6864  --> mvhd的长度是0x6c    ,type=mvhd
0000 0000                    --> version=0x0
7c25 b080 7c25 b080  --> create_time=modify_time=0x7c25b080
0000 03e8                    --> timescale=0x3e8=1000  
0014 6995                    --> duration=0x146995(单位是time_units)
0001 0000                    --> rate=0x00010000
0100                             --> volume=0x0100
0005 bf9d 7472 616b   --> track的长度是0x5bf9d,type=trak
0000 005c 746b 6864  --> tkhd的长度是0x5c, type=tkhd
0000                             -->version
000F                             --> flag
7c25 b080 7c25 b080  -->create_time=modify_time=0x7c25b080
0000 0001                    --> trackID=1
0000 0000                    --> reserve
0014 6595                    --> duration=0x146595
0000 0000                    --> reserved
0000 0000                    --> reserved
0000 0000                    --> layer+group
0000 0000                    --> volum+resever
0001 0000 0000 0000 0000 0000   matrix
0000 0000 0001 0000 0000 0000 
0000 0000 0000  0000 4000 0000 
01d6 0000 0160 0000   -->  width=0x1d6 height=0x160(这儿都需要向右移16位)
0000 0024 6564 7473   -->edts的长度是0x24,type=edts

注意: 
a.媒体文件在播放过程中用的时间单位,是由timescale计算出来的
一个time units=1s/timescale=1ms,这儿1 time_unts=1ms
b.通过duration可计算媒体的播放时间 0x146995*1ms=1337749ms=1337.749s,对上了


附1.mvhd

ISO14496-12 的8.3.2 Syntax 
aligned(8) class MovieHeaderBox extends FullBox(‘mvhd’, version, 0) { 
if (version==1) { unsigned int(64) creation_time; unsigned int(64) modification_time; unsigned int(32) timescale; unsigned int(64) duration; 
} else { // version==0 unsigned int(32) creation_time; unsigned int(32) modification_time; unsigned int(32) timescale; unsigned int(32) duration; 
} 
template int(32) rate = 0x00010000; // typically 1.0 
template int(16) volume = 0x0100; // typically, full volume 
const bit(16) reserved = 0; 
const unsigned int(32)[2] reserved = 0; 
template int(32)[9] matrix = { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 }; 
// Unity matrix 
bit(32)[6] pre_defined = 0; 
unsigned int(32) next_track_ID; 
}

附2.trak

 

8.5.2 Syntax aligned(8) class TrackHeaderBox 
extends FullBox(‘tkhd’, version, flags){ if (version==1) { unsigned int(64) creation_time; unsigned int(64) modification_time; unsigned int(32) track_ID; const unsigned int(32) reserved = 0; unsigned int(64) duration; } else { // version==0 unsigned int(32) creation_time; unsigned int(32) modification_time; unsigned int(32) track_ID; const unsigned int(32) reserved = 0; unsigned int(32) duration; } const unsigned int(32)[2] reserved = 0; template int(16) layer = 0; template int(16) alternate_group = 0; template int(16) volume = {if track_is_audio 0x0100 else 0}; const unsigned int(16) reserved = 0; template int(32)[9] matrix= { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 }; // unity matrix unsigned int(32) width; unsigned int(32) height; 
}

 


三.ffmpeg中对mp4的处理


3.1 对mp4文件的probe --> 在libavformat/mov.c中


有两个宏需要关注一下:

#define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24))# define AV_RL32(x) \(((uint32_t)((const uint8_t*)(x))[3] << 24) | \(((const uint8_t*)(x))[2] << 16) | \(((const uint8_t*)(x))[1] << 8) | \((const uint8_t*)(x))[0])

这两个宏都是把4个char组成一个int

3.2 mov_probe

static int mov_probe(AVProbeData *p)
{int64_t offset;uint32_t tag;int score = 0;int moov_offset = -1;dbmsg();/* check file header */offset = 0;for (;;) {tag = AV_RL32(p->buf + offset + 4);    //将p->buf+4即‘f’ ‘t’ 'y' 'p'组成一个intswitch(tag) {                          //判断这个int是不是ftypcase MKTAG('f','t','y','p'):score = AVPROBE_SCORE_MAX;     //如果是的话score=100,说明就是mov格式的文件break;}}return score;
}

精简一下mov_probe,其实就是判断第一个box是不是ftyp,若是则就是mov格式的了。


3.3.1 对ftype的读取

static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{//读4个字节的major_brand,并存到dict中ffio_read_size(pb, type, 4);av_dict_set(&c->fc->metadata, "major_brand", type, 0);//读4个字节的minor_ver,并存到dict中minor_ver = avio_rb32(pb);av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);//读剩余的字节,即comp_brands_str,并存到dict中comp_brand_size = atom.size - 8;    //atom.size己经是去除8字节头,余下的sizeffio_read_size(pb, comp_brands_str, comp_brand_size);comp_brands_str[comp_brand_size] = 0;av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);return 0;
}

3.3.2 对free的读取

static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{//没什么作用,只是读取出来,把文件指针指向下一下box而己avio_read(pb, content, FFMIN(sizeof(content), atom.size));return 0;
}

3.3.3对mdat的读取

static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{//mdat更简单,只把标志设置了一下c->found_mdat=1;return 0; /* now go for moov */
}

3.3.4对moov的读取

 


三.附录: ISO/IEC 14496 MPEG的协议标准


转自: http://blog.csdn.net/yu_yuan_1314/article/details/9406587

  1. ISO/IEC 14496是MPEG专家组制定的MPEG-4标准于1998年10月公布第1版,1999年1月成为国际标准,1999年12月公布了第2版,2000年初成为国际标准。
  2. 全文分为27个部分:
  3. (1)ISO/IEC 14496-1系统部分,描述视频和音频数据流的控制、同步以及混合方式(即混流 Multiplexing,简写为MUX)。
  4. (2)ISO/IEC 14496-2视频部分,定义了一个对各种视觉信息(包括自然视频、静止纹理、计算机合成图形等等)的编解码器。(例如XviD编码就属于MPEG-4 Part 2)。
  5. (3)ISO/IEC 14496-3音频部分,定义了一个对各种音频信号进行编码的编解码器的集合。包括高级音频编码(Advanced Audio Coding,缩写为AAC)的若干变形和其他一些音频/语音编码工具。
  6. (4)ISO/IEC 14496-4一致性部分,定义了比特流和设备的一致性条件,用来测试MPEG-4的实现。
  7. (5)ISO/IEC 14496-5参考软件,提供了用于演示功能和说明本标准其他部分功能的软件。
  8. (6)ISO/IEC 14496-6多媒体传送整体框架DMIF,这是MPEG-4应用层与传输网络的接口,定义了通信协议,使MPEG-4系统的数据流能进入各种传输网络。还包含一个存储格式MP4,用于存储编码的场景。
  9. (7) ISO/IEC 14496-7优化的参考软件,提供了对实现进行优化的例子(这里的实现指的是第五部分)。
  10. (8)ISO/IEC 14496-8在IP网络上传输,定义了在IP网络上传输MPEG-4内容的方式。
  11. (9)ISO/IEC 14496-9参考硬件描述,提供了用于演示怎样在硬件上实现本标准其他部分功能的硬件设计方案
  12. (10)ISO/IEC 14496-10高级视频编码AVC,定义了一个视频编解码器(codec)。AVC和XviD都属于MPEG-4编码,但由于AVC属于MPEG-4 Part 10,在技术特性上比属于MPEG-4 Part2的XviD要先进。另外,它和ITU-T H.264标准是一致的,故又称为H.264。
  13. (11)ISO/IEC 14496-11场景描述和应用引擎。
  14. (12)ISO/IEC 14496-12ISO媒体文件格式,定义了一个存储媒体内容的文件格式。
  15. (13)ISO/IEC 14496-13知识产权管理和保护(IPMP:Intellectual Property Management and Protection)扩展。
  16. (14)ISO/IEC 14496-14MP4文件格式,定义了基于第十二部分的用于存储MPEG-4内容的容器文件格式。
  17. (15)ISO/IEC 14496-15AVC文件格式,定义了基于第十二部分的用于存储第十部分的视频内容的文件格式。
  18. (16)ISO/IEC 14496-16动画框架扩展AFX(Animation Framework eXtension)。
  19. (17)ISO/IEC 14496-17同步文本字幕格式。
  20. (18)ISO/IEC 14496-18字体压缩和流式传输(针对公开字体格式)。
  21. (19)ISO/IEC 14496-19合成材质流(Synthesized Texture Stream)。
  22. (20)ISO/IEC 14496-20简单场景表示(LASeR for Lightweight Scene Representation)。
  23. (21)ISO/IEC 14496-21用于描绘(Rendering)的MPEG-J拓展。
  24. (22)ISO/IEC 14496-22开放字体格式(Open Font Format)。
  25. (23)ISO/IEC 14496-2符号化音乐表示(Symbolic Music Representation)。
  26. (24)ISO/IEC 14496-24音频与系统交互作用(Audio and systems interaction)。
  27. (25)ISO/IEC 14496-253D图形压缩模型(3D Graphics Compression Model)。
  28. (26)ISO/IEC 14496-26音频一致性检查:定义了测试音频数据与ISO/IEC 14496-3是否一致的方法(Audio conformance)。
  29. (27)ISO/IEC 14496-273D图形一致性检查:定义了测试3D图形数据与ISO/IEC 14496-11:2005, ISO/IEC 14496-16:2006, ISO/IEC 14496-21:2006, 和 ISO/IEC 14496-25:2009是否一致的方法(3D Graphics conformance)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285455.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++库(Google Breakpad)

Google Breakpad是什么&#xff1f; 一个开源的多平台崩溃报告系统。 Google breakpad是一个非常实用的跨平台的崩溃转储和分析模块&#xff0c;它支持Windows&#xff0c;Linux和Mac和Solaris。由于他本身跨平台&#xff0c;所以很大程度上减少了我们在平台移植时的工作&#…

java eleven进度条

2019独角兽企业重金招聘Python工程师标准>>> 一个矩形组件 MethodDescribleJProgrssBar()不带进度字符&#xff0c;最小值0最大值100的水平进度条JProgressBar(int orient)VERTICAL/HORIZONTALJProgressBar(int in,int max)指定最大最小的水平进度条JProgressBar(in…

Docker:多阶段构建 ASP.NET Core 应用镜像

本文选自『.NET大牛之路』知识星球&#xff0c;发布于2022年05月25日。今天我们一起来写 Dockerfile 构建一个 ASP.NET Core 应用镜像&#xff0c;同时还会将镜像发布到 Docker Hub 仓库。1创建示例 Web 应用程序为了演示&#xff0c;我们先创建一个 ASP.NET Core 应用程序&…

[转]【JAVA各版本特性】JAVA 1.0

闲来想了解下各版本之间的特性&#xff0c;搜索没有最新的特性说明&#xff0c;故想写一份。废话不多说。 JDK Version 1.0 1996-01-23 Oak(橡树) 初代版本&#xff0c;伟大的一个里程碑&#xff0c;但是是纯解释运行&#xff0c;使用外挂JIT&#xff0c;性能比较差&#xff0…

北京Uber优步司机奖励政策(3月11日)

滴快车单单2.5倍&#xff0c;注册地址&#xff1a;http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单&#xff1a;http://www.cnblogs.com/mfryf/p/4612609.html 优步奖励低/不挣钱/怎么办?看这里&#xff1a;http://www.cnblogs.com/mfry…

【招聘(广州)】成功易(广州).Net Core中高级开发工程师

成功易&#xff08;广州&#xff09;信息技术有限公司简介成功易是一家集团性公司&#xff0c;创立于2002年&#xff0c;总部位于北京&#xff0c;旗下拥有7家子公司。广州成功易成立于2019年&#xff0c;人员逐渐增长150人&#xff0c;组织架构完善&#xff0c; 我们是腾讯广告…

xcode 设置快捷键 整行上下移动

2019独角兽企业重金招聘Python工程师标准>>> 设置整行代码上下移动&#xff1a;找到Xcode中的自带的配置文件&#xff1a;/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/IDETextKeyBindingSet.plist用文本编辑IDETextKeyBind…

用.Net Core接入微信公众号开发

Part1前言最近想写一点基于.Net Core微信公众号开发的文章Part2测试公众号申请测试公众号申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?tsandbox/login微信公众号开发文档:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html通过微…

腾讯、百度、小米等7家互联网各大厂的中台建设怎么样了?

中台是真正为前台而生的平台&#xff08;可以是技术平台&#xff0c;业务能力甚至是组织机构&#xff09;&#xff0c;它存在的唯一目的就是更好的服务前台规模化创新&#xff0c;进而更好的响应服务引领用户&#xff0c;使企业真正做到自身能力与用户需求的持续对接。 以下转载…

JAVA基础知识之网络编程——-基于AIO的异步Socket通信

异步IO 下面摘子李刚的《疯狂JAVA讲义》 按照POSIX标准来划分IO&#xff0c;分为同步IO和异步IO。对于IO操作分为两步&#xff0c;1&#xff09;程序发出IO请求。 2&#xff09;完成实际的IO操作。 阻塞IO和非阻塞IO都是针对第一步来划分的&#xff0c;如果发出IO请求会阻塞线程…

基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能

系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客&#xff1f;基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.N…

EditPlus 文件查找功能:在指定文件夹,用正则查寻包含指定内容的文件,指定文件类型,并排除特殊文件名文件

单击菜单栏上的【Search】&#xff08;查找&#xff09;&#xff0c;选择【Find in Files】&#xff08;在文件中查找&#xff09;命令&#xff1a; 查找项&#xff1a;正则查找video标签&#xff0c;src为不包含http的mp4 <video src"([^http].*\.mp4)" width&q…

NOIP2016普及组第三题——海港

题目描述 小K是一个海港的海关工作人员&#xff0c;每天都有许多船只到达海港&#xff0c;船上通常有很多来自不同国家的乘客。 小K对这些到达海港的船只非常感兴趣&#xff0c;他按照时间记录下了到达海港的每一艘船只情况&#xff1b;对于第i艘到达的船&#xff0c;他记录了这…

7z-linux下解决中文名乱码的终极办法

为什么80%的码农都做不了架构师&#xff1f;>>> linux上安装7z主要是为了解决中文文件名乱码的问题&#xff0c;压缩率还是其次原因 具体安装看参考网址&#xff0c;建议用源码方式安装 官网下载地址&#xff1a;http://www.7-zip.org/download.html 源文件项目地址…

工具箱之 IKVM.NET 项目新进展

在各种群里经常讨论的一个事情是.NET 如何调用 Java 的实现&#xff0c;最常见的场景之一就是在加解密方面Java提供的密钥&#xff0c;C#无法解密&#xff0c; C#中byte范围是[0,255]&#xff0c;而Java中的byte范围是[-128,127]&#xff0c;由于密码生成器是java所独有的&…

一天一种设计模式之六-----工厂方法模式

2019独角兽企业重金招聘Python工程师标准>>> 一.工厂方法模式 工厂方法模式属于创建型模式。工厂方法模式定义&#xff1a;定义一个用于创建对象的借口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到了他的子类。一般工厂类会有一个工厂的接…

[转]IPython介绍

1. IPython介绍 ipython是一个python的交互式shell&#xff0c;比默认的python shell好用得多&#xff0c;支持变量自动补全&#xff0c;自动缩进&#xff0c;支持bash shell命令&#xff0c;内置了许多很有用的功能和函数。学习ipython将会让我们以一种更高的效率来使用python…

.NET MAUI in Mac

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;4分钟&#xff09;概要本篇文章主要分享MAUI在m1芯片的设备上运行和支持情况&#xff0c;将我们写好的MAUI程序编译为支持mac平台的版本。在m1芯片刚刚出来的时候有很多开发工具和应用程序对m1芯片的支持不是很友好&a…

前端开发中的SEO

前端开发中的SEO 什么是SEO SEO由英文Search Engine Optimization缩写而来&#xff0c;中文意译为“搜索引擎优化”。SEO是指从自然搜索结果获得网站流量的技术和过程&#xff0c;是在了解搜索引擎自然排名机制的基础上&#xff0c;对网站进行内部及外部的调整优化&#xff0c;…

C# 自定义并动态切换光标

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;唐宋元明清的博客原文地址&#xff1a;https://www.cnblogs.com/kybs0/p/14873136.html系统有很多光标类型 &#xff1a;Cursors 类 (System.Windows.Input) | Microsoft Docs[1]本章介绍如…