【多媒体封装格式详解】---MP4【4】
前面介绍过的几种格式flv、mkv、asf等。他们音视频的数据包一般都是按照文件的顺序交叉安放。你解析完头部信息后。剩下的一般就按照文件顺序一个数据包一个数据包的解析就行了。但是MP4完全不是这种概念。他的媒体信息和数据是分开存放的。就是你想获得数据之前必须要解析出每个帧数据所有的位置。mp4存放这个帧信息的是放在stbl这个box里。而真实的数据放在mdat中。接下来就讲讲stbl与mdat的对应关系。
Sample Table Box(stbl)

stts: Decoding Time to Sample Box 时间戳和Sample映射表
stsd: Sample Description Box
stsz, stz2: Sample Size Boxes 每个Sample大小的表。
stsc: Sample to chunk 的映射表。
‘stco’, ‘co64’: Chunk位置偏移表
stss:关键帧index。
1.解析stsd可获得coding类型、视频宽高、音频samplesize、channelcount这些和解码器有关信息。
- aligned(8) class SampleDescriptionBox (unsigned int(32) handler_type)
- extends FullBox('stsd', 0, 0){
- int i ;
- unsigned int(32) entry_count;
- for (i = 1 ; i u entry_count ; i++){
- switch (handler_type){
- case ‘soun’: // for audio tracks
- AudioSampleEntry();
- break;
- case ‘vide’: // for video tracks
- VisualSampleEntry();
- break;
- case ‘hint’: // Hint track
- HintSampleEntry();
- break;
- }
- }
- }
- aligned(8) abstract class SampleEntry (unsigned int(32) format)
- extends Box(format){
- const unsigned int(8)[6] reserved = 0;
- unsigned int(16) data_reference_index;
- }
- class HintSampleEntry() extends SampleEntry (protocol) {
- unsigned int(8) data [];
- }
- // Visual Sequences
- class VisualSampleEntry(codingname) extends SampleEntry (codingname){
- unsigned int(16) pre_defined = 0;
- const unsigned int(16) reserved = 0;
- unsigned int(32)[3] pre_defined = 0;
- unsigned int(16) width;
- unsigned int(16) height;
- template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
- template unsigned int(32) vertresolution = 0x00480000; // 72 dpi
- const unsigned int(32) reserved = 0;
- template unsigned int(16) frame_count = 1;
- string[32] compressorname;
- template unsigned int(16) depth = 0x0018;
- int(16) pre_defined = -1;
- }
- // Audio Sequences
- class AudioSampleEntry(codingname) extends SampleEntry (codingname){
- const unsigned int(32)[2] reserved = 0;
- template unsigned int(16) channelcount = 2;
- template unsigned int(16) samplesize = 16;
- unsigned int(16) pre_defined = 0;
- const unsigned int(16) reserved = 0 ;
- template unsigned int(32) samplerate = {timescale of media}<<16;
- }
2.解析stsz box 可以获得一个sample size的表
- aligned(8) class SampleSizeBox extends FullBox(‘stsz’, version = 0, 0) {
- unsigned int(32) sample_size;
- unsigned int(32) sample_count;
- if (sample_size==0) {
- for (i=1; i u sample_count; i++) {
- unsigned int(32) entry_size;
- }
- }
- }
3.解析stts
- aligned(8) class TimeToSampleBox
- extends FullBox(’stts’, version = 0, 0) {
- unsigned int(32) entry_count;
- int i;
- for (i=0; i < entry_count; i++) {
- unsigned int(32) sample_count;
- unsigned int(32) sample_delta;
- }
- }
4.解析stsc 还原Sample 与chunk的映射表

Sample 是存储的最基本单元,mp4把Sample 存在chunk中。chunk的长度、chunk的大小、chunk中Sample的数量及大小都是不定的。
通过解析这部分box来还原这个映射表。
- aligned(8) class SampleToChunkBox
- extends FullBox(‘stsc’, version = 0, 0) {
- unsigned int(32) entry_count;
- for (i=1; i u entry_count; i++) {
- unsigned int(32) first_chunk;
- unsigned int(32) samples_per_chunk;
- unsigned int(32) sample_description_index;
- }
- }
每个entry 表示着一组数据,entry_count 表示这数量。这一组其实是相同类型的chunk。
first_chunk 表示 这一组相同类型的chunk中 的第一个chunk数。
这些chunk 中包含的Sample 数量,即samples_per_chunk 是一致的。
每个Sample 可以通过sample_description_index 去stsd box 找到描述信息。
看ffmpeg中mov_read_stsc() 它把这些数据放在一个结构体数组中备用。
- static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
- {
- AVStream *st;
- MOVStreamContext *sc;
- unsigned int i, entries;
- if (c->fc->nb_streams < 1)
- return 0;
- st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
- avio_r8(pb); /* version */
- avio_rb24(pb); /* flags */
- entries = avio_rb32(pb);
- av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
- if (!entries)
- return 0;
- if (entries >= UINT_MAX / sizeof(*sc->stsc_data))
- return AVERROR_INVALIDDATA;
- sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
- if (!sc->stsc_data)
- return AVERROR(ENOMEM);
- for (i = 0; i < entries && !pb->eof_reached; i++) {
- sc->stsc_data[i].first = avio_rb32(pb);
- sc->stsc_data[i].count = avio_rb32(pb);
- sc->stsc_data[i].id = avio_rb32(pb);
- }
- sc->stsc_count = i;
- if (pb->eof_reached)
- return AVERROR_EOF;
- return 0;
- }
在获得完整的映射表,我们还需要chunk总个数信息。这些信息放在‘stco’, ‘co64’中。
5.解析‘stco’, ‘co64’
“stco”定义了每个thunk在媒体流中的位置。位置有两种可能,32位的和64位的,后者对非常大的电影很有用。
32位
- aligned(8) class ChunkOffsetBox
- extends FullBox(‘stco’, version = 0, 0) {
- unsigned int(32) entry_count;
- for (i=1; i u entry_count; i++) {
- unsigned int(32) chunk_offset;
- }
- }
64位
- aligned(8) class ChunkLargeOffsetBox
- extends FullBox(‘co64’, version = 0, 0) {
- unsigned int(32) entry_count;
- for (i=1; i u entry_count; i++) {
- unsigned int(64) chunk_offset;
- }
- }
从这个box我们就可以获得 chunk 的总数量,entry_count。
from:http://blog.csdn.net/tx3344/article/details/8506131
1.解析‘stco’, ‘co64’我们有了chunk 表,知道了chunk 的总数及每个chunk所在文件的位置。
2.解析stsc 配合着上面的chunk表,我们就能弄个Sample与chunk的关系表。我们也就能获得每个Sample的位置信息。
3.配合上面的stts 时间表和解码器信息等。搞出ES流已经不成问题了。
4.想获得关键帧的index,需要解析stss’
- aligned(8) class SyncSampleBox
- extends FullBox(‘stss’, version = 0, 0) {
- unsigned int(32) entry_count;
- int i;
- for (i=0; i < entry_count; i++) {
- unsigned int(32) sample_number;
- }
- }
【多媒体封装格式详解】---MP4【4】的更多相关文章
- 多媒体封装格式详解---MP4
MP4文件格式详解——结构概述 http://blog.csdn.net/pirateleo/article/details/7061452 一.基本概念 1. 文件,由许多Box和FullBox组成 ...
- 【多媒体封装格式详解】--- AAC ADTS格式分析
ADTS全称是(Audio Data Transport Stream),是AAC的一种十分常见的传输格式. 记得第一次做demux的时候,把AAC音频的ES流从FLV封装格式中抽出来送给硬件解码器时 ...
- (转)【多媒体封装格式详解】--- AAC ADTS格式分析
出自:http://blog.csdn.net/tx3344/article/details/7414543 http://www.it6655.com/2012/08/aac-adts-html ...
- 【多媒体封装格式详解】---MKV
http://blog.csdn.net/tx3344/article/details/8162656# http://blog.csdn.net/tx3344/article/details/817 ...
- FLV视频封装格式详解
FLV视频封装格式详解 分类: FFMpeg编解码 2012-04-04 21:13 1378人阅读 评论(2) 收藏 举报 flvheaderaudiovideocodecfile 目录(?)[-] ...
- H.264标准(一)mp4封装格式详解
在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...
- 【转】FLV视频封装格式详解
Overview Flash Video(简称FLV),是一种流行的网络格式.目前国内外大部分视频分享网站都是采用的这种格式. File Structure 从整个文件上开看,FLV是由The FLV ...
- 以太网帧格式、IP数据报格式、TCP段格式+UDP段格式 详解
转载:http://www.cnblogs.com/lifan3a/articles/6649970.html 以太网帧格式.IP数据报格式.TCP段格式+UDP段格式 详解 1.ISO开放系统有 ...
- java分享第十五天(log4j 格式详解)
log4j 格式详解 log4j.rootLogger=日志级别,appender1, appender2, -. 日志级别:ALL<DEBUG<INFO<WARN<ERRO ...
随机推荐
- [设计模式] 19 观察者模式 Observer Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.当一个 ...
- Memcache安全配置
Memcache安全配置 瞌睡龙 · 2014/01/20 17:59 0x00 Memcache简介 Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash ...
- 别让安全问题拖慢了 DevOps!
DEVSECOPS 所面临的挑战 敏捷开发和 DevOps 方法的出现使软件开发的速度与质量都有所提升,但它们不经意地也为安全机构增压不少.从前的安全策略是基于静态数据的,而在产品上线前才应用这些策略 ...
- C/C++框架和库
http://blog.csdn.net/xiaoxiaoyeyaya/article/details/42541419 值得学习的C语言开源项目 - 1. Webbench Webbench是一个在 ...
- [SQL Server 系] -- 模糊查询
SQL Server中的通配符有下面四种 通配符 说明 % 包含零个或多个字符的任意字符串 _(下划线) 任意单个字符 [ ] 任意在指定范围或集合中的单个字符 [^ ] 任意不在指定范围或集合中的单 ...
- C++ Primer笔记整理
1. 迭代器:迭代器是一种对象,它可以看做是游标,用来遍历标准模板库中的部分或者全部元素. 每个迭代器指向容器中确定的地址,此外,迭代器还提供一些基本操作符:*.++.==.!=.=. 2. 模板:是 ...
- Filter(过滤器)常见应用
孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(四十六)——Filter(过滤器)常见应用 一.统一全站字符编码 通过配置参数charset指明使用何种字符编码,以处理Html F ...
- dubbo与zookeeper安装手册
原文 示例提供者安装 (+) (#) 安装: wget http://code.alibabatech.com/mvn/releases/com/alibaba/dubbo-demo-provider ...
- VC程序查错之内存访问异常
作者:langouster 先来看下面这张图,相信很多程序员都见过类似. ---------------------------test1.exe - 应用程序错误------------------ ...
- 一个酷炫的,基于HTML5,Jquery和Css的全屏焦点图特效,兼容各种浏览器
基于HTML5和CSS的焦点图特效,梅花图案的背景很有中国特色,而且还会动哦,效果超炫,推荐下载! 演示图 html代码 <!DOCTYPE html PUBLIC "-//W3C// ...