MP4封装解析

本文详细解析了MP4封装格式的内部结构,包括关键节点如ftyp、moov、track,以及关键部分如stts、stss、ctts等的作用。作者还通过实例展示了如何通过这些元素计算视频的时长和播放顺序。
摘要由CSDN通过智能技术生成

前言

MP4封装格式比较常见,但是有些会有问题,下面解析一下具体信息

正文

工具

比较好的是mp4在线工具

MP4主要结构
MP4主要结构类似于树状图。每个节点开头都有8位,前四位记录大小,后四位标记节点类型。根节点一般包含四个字节点(ftyp,free,mdat,moov)。

  • ftyp(File Type Box)一般在文件的开始位置,描述的文件的版本、兼容协议等。
  • mdat 多媒体的存储位置
  • free预留位置,没用
  • moov 关键信息,记录多媒体轨道和索引信息

moov关键的是track。track节点中包含了tkhd,记录track信息。供播放器显示多媒体信息。media记录关键索引信息,解码器搜寻sample位置。
meida中的mdhd记录识别的总时长,以及时间粒度。供后边分析pts和cts等操作。minf节点中的stbl才是真的记录采样点的位置信息。以及计算方法。
这里有个比较重要的概念。chunk。他是一些编码后的数据,成为一簇。方便管理以及避免错误的干扰
下面解析一个750s的视频,有130个chunk。45008帧数据,

stsd

描述,不重要,

stts

描述数据帧的时间间隔。因为间隔大部分一样,所以是统计信息,

相同时间间隔个数 时间间隔(单位是moov-trak-media-mdhd-timescale的信息)

比如一个典型的数据是:

entry_count1
samples{“sample_count”:45008,“sample_delta”:1001}

显示当前轨道,所有帧时长是一样的。都是16.683毫秒,帧率是59.94005994005994

而timescale是1/60000.所以总时长是 45008 * 1001 /timescale(60000) = 750.8834 秒。时长应该是 750秒。130个chunk。

stss

entry_count130
sync_samples.01
sync_samples.1207
sync_samples.2397
sync_samples.3713
sync_samples.4939
sync_samples.51139
sync_samples.61437

用来记录关键帧。方便快速seek

ctts用来记录视频帧和显示时间的间隔。主要是解决视频向后参考关键帧。音频一般情况下只有一条,

entry_count2
samples.0{“sample_count”:1,“composition_offset”:1001}
samples.1{“sample_count”:32339,“composition_offset”:0}

视频比较复杂:
如下

entry_count36456
samples.0{“sample_count”:1,“composition_offset”:1001}
samples.1{“sample_count”:1,“composition_offset”:3003}
samples.2{“sample_count”:2,“composition_offset”:0}
samples.3{“sample_count”:3,“composition_offset”:1001}
samples.4{“sample_count”:1,“composition_offset”:2002}
samples.5{“sample_count”:1,“composition_offset”:0}
samples.6{“sample_count”:1,“composition_offset”:1001}
samples.7{“sample_count”:1,“composition_offset”:2002}
samples.8{“sample_count”:1,“composition_offset”:0}
samples.9{“sample_count”:4,“composition_offset”:1001}
samples.10{“sample_count”:1,“composition_offset”:2002}

这个sample顺序cts是根据stts来计算的,根据之前分析,则sample则根据顺序排列

index cts dts

101001
210014004
320022002
430033003
540045005
650056006
760067007
870079009
980088008
10900910010
111001012012
131101111011
141201213013

比较明显,第二帧数据,应该在第四个时刻显示,但是第三,和第四帧解码需要第二帧,所以先解码第二帧,根据pts修正显示时刻。

stsc

sample-chunk映射表。

entry_count61
chunks.0{“first_chunk”:1,“samples_per_chunk”:206,“sample_description_index”:1}
chunks.1{“first_chunk”:2,“samples_per_chunk”:190,“sample_description_index”:1}
chunks.2{“first_chunk”:3,“samples_per_chunk”:316,“sample_description_index”:1}
chunks.59{“first_chunk”:62,“samples_per_chunk”:420,“sample_description_index”:1}
chunks.60{“first_chunk”:130,“samples_per_chunk”:458,“sample_description_index”:1}

这是记录chunk 一共130个。每个chunk可能有不同的sample。比如第一个有206 62到 130 的chunk每个里面有458个。

stsz

每个sample的字节大小

sample_count45008
sample_size.0513
sample_size.1270
sample_size.285
sample_size.389
sample_size.41258
sample_size.51581

stco

每个chunk在文件中的偏移

entry_count130
chunk_offset.048
chunk_offset.11011504
chunk_offset.23302476
chunk_offset.129213665857

这些用来记录关键的chunk的位置,具体每个sample参考sample具体的位置

后记

MP4的解析基本完成。原理还是比较 简单,以后如果写完解码器,自己就手写一个解封装模块,实现必要的功能

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值