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

Sample Table Box(stbl)

来一张典型的stbl结构图:
常见子box

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这些和解码器有关信息。

  1. aligned(8) class SampleDescriptionBox (unsigned int(32) handler_type)
  2. extends FullBox('stsd', 0, 0){
  3. int i ;
  4. unsigned int(32) entry_count;
  5. for (i = 1 ; i u entry_count ; i++){
  6. switch (handler_type){
  7. case ‘soun’: // for audio tracks
  8. AudioSampleEntry();
  9. break;
  10. case ‘vide’: // for video tracks
  11. VisualSampleEntry();
  12. break;
  13. case ‘hint’: // Hint track
  14. HintSampleEntry();
  15. break;
  16. }
  17. }
  18. }
  1. aligned(8) abstract class SampleEntry (unsigned int(32) format)
  2. extends Box(format){
  3. const unsigned int(8)[6] reserved = 0;
  4. unsigned int(16) data_reference_index;
  5. }
  6. class HintSampleEntry() extends SampleEntry (protocol) {
  7. unsigned int(8) data [];
  8. }
  9. // Visual Sequences
  10. class VisualSampleEntry(codingname) extends SampleEntry (codingname){
  11. unsigned int(16) pre_defined = 0;
  12. const unsigned int(16) reserved = 0;
  13. unsigned int(32)[3] pre_defined = 0;
  14. unsigned int(16) width;
  15. unsigned int(16) height;
  16. template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
  17. template unsigned int(32) vertresolution = 0x00480000; // 72 dpi
  18. const unsigned int(32) reserved = 0;
  19. template unsigned int(16) frame_count = 1;
  20. string[32] compressorname;
  21. template unsigned int(16) depth = 0x0018;
  22. int(16) pre_defined = -1;
  23. }
  24. // Audio Sequences
  25. class AudioSampleEntry(codingname) extends SampleEntry (codingname){
  26. const unsigned int(32)[2] reserved = 0;
  27. template unsigned int(16) channelcount = 2;
  28. template unsigned int(16) samplesize = 16;
  29. unsigned int(16) pre_defined = 0;
  30. const unsigned int(16) reserved = 0 ;
  31. template unsigned int(32) samplerate = {timescale of media}<<16;
  32. }

2.解析stsz box 可以获得一个sample size的表

  1. aligned(8) class SampleSizeBox extends FullBox(‘stsz’, version = 0, 0) {
  2. unsigned int(32) sample_size;
  3. unsigned int(32) sample_count;
  4. if (sample_size==0) {
  5. for (i=1; i u sample_count; i++) {
  6. unsigned int(32) entry_size;
  7. }
  8. }
  9. }

3.解析stts

  1. aligned(8) class TimeToSampleBox
  2. extends FullBox(’stts’, version = 0, 0) {
  3. unsigned int(32) entry_count;
  4. int i;
  5. for (i=0; i < entry_count; i++) {
  6. unsigned int(32) sample_count;
  7. unsigned int(32) sample_delta;
  8. }
  9. }

4.解析stsc 还原Sample 与chunk的映射表

Sample 是存储的最基本单元,mp4把Sample 存在chunk中。chunk的长度、chunk的大小、chunk中Sample的数量及大小都是不定的。

通过解析这部分box来还原这个映射表。

  1. aligned(8) class SampleToChunkBox
  2. extends FullBox(‘stsc’, version = 0, 0) {
  3. unsigned int(32) entry_count;
  4. for (i=1; i u entry_count; i++) {
  5. unsigned int(32) first_chunk;
  6. unsigned int(32) samples_per_chunk;
  7. unsigned int(32) sample_description_index;
  8. }
  9. }

每个entry 表示着一组数据,entry_count 表示这数量。这一组其实是相同类型的chunk。

first_chunk 表示 这一组相同类型的chunk中 的第一个chunk数。

这些chunk 中包含的Sample 数量,即samples_per_chunk 是一致的。

每个Sample 可以通过sample_description_index 去stsd box 找到描述信息。

看ffmpeg中mov_read_stsc() 它把这些数据放在一个结构体数组中备用。

  1. static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
  2. {
  3. AVStream *st;
  4. MOVStreamContext *sc;
  5. unsigned int i, entries;
  6. if (c->fc->nb_streams < 1)
  7. return 0;
  8. st = c->fc->streams[c->fc->nb_streams-1];
  9. sc = st->priv_data;
  10. avio_r8(pb); /* version */
  11. avio_rb24(pb); /* flags */
  12. entries = avio_rb32(pb);
  13. av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
  14. if (!entries)
  15. return 0;
  16. if (entries >= UINT_MAX / sizeof(*sc->stsc_data))
  17. return AVERROR_INVALIDDATA;
  18. sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
  19. if (!sc->stsc_data)
  20. return AVERROR(ENOMEM);
  21. for (i = 0; i < entries && !pb->eof_reached; i++) {
  22. sc->stsc_data[i].first = avio_rb32(pb);
  23. sc->stsc_data[i].count = avio_rb32(pb);
  24. sc->stsc_data[i].id = avio_rb32(pb);
  25. }
  26. sc->stsc_count = i;
  27. if (pb->eof_reached)
  28. return AVERROR_EOF;
  29. return 0;
  30. }

在获得完整的映射表,我们还需要chunk总个数信息。这些信息放在‘stco’, ‘co64’中。

5.解析‘stco’, ‘co64’

“stco”定义了每个thunk在媒体流中的位置。位置有两种可能,32位的和64位的,后者对非常大的电影很有用。

32位

  1. aligned(8) class ChunkOffsetBox
  2. extends FullBox(‘stco’, version = 0, 0) {
  3. unsigned int(32) entry_count;
  4. for (i=1; i u entry_count; i++) {
  5. unsigned int(32) chunk_offset;
  6. }
  7. }

64位

  1. aligned(8) class ChunkLargeOffsetBox
  2. extends FullBox(‘co64’, version = 0, 0) {
  3. unsigned int(32) entry_count;
  4. for (i=1; i u entry_count; i++) {
  5. unsigned int(64) chunk_offset;
  6. }
  7. }

从这个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’

    1. aligned(8) class SyncSampleBox
    2. extends FullBox(‘stss’, version = 0, 0) {
    3. unsigned int(32) entry_count;
    4. int i;
    5. for (i=0; i < entry_count; i++) {
    6. unsigned int(32) sample_number;
    7. }
    8. }

【多媒体封装格式详解】---MP4【4】的更多相关文章

  1. 多媒体封装格式详解---MP4

    MP4文件格式详解——结构概述 http://blog.csdn.net/pirateleo/article/details/7061452 一.基本概念 1. 文件,由许多Box和FullBox组成 ...

  2. 【多媒体封装格式详解】--- AAC ADTS格式分析

    ADTS全称是(Audio Data Transport Stream),是AAC的一种十分常见的传输格式. 记得第一次做demux的时候,把AAC音频的ES流从FLV封装格式中抽出来送给硬件解码器时 ...

  3. (转)【多媒体封装格式详解】--- AAC ADTS格式分析

     出自:http://blog.csdn.net/tx3344/article/details/7414543 http://www.it6655.com/2012/08/aac-adts-html ...

  4. 【多媒体封装格式详解】---MKV

    http://blog.csdn.net/tx3344/article/details/8162656# http://blog.csdn.net/tx3344/article/details/817 ...

  5. FLV视频封装格式详解

    FLV视频封装格式详解 分类: FFMpeg编解码 2012-04-04 21:13 1378人阅读 评论(2) 收藏 举报 flvheaderaudiovideocodecfile 目录(?)[-] ...

  6. H.264标准(一)mp4封装格式详解

    在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...

  7. 【转】FLV视频封装格式详解

    Overview Flash Video(简称FLV),是一种流行的网络格式.目前国内外大部分视频分享网站都是采用的这种格式. File Structure 从整个文件上开看,FLV是由The FLV ...

  8. 以太网帧格式、IP数据报格式、TCP段格式+UDP段格式 详解

    转载:http://www.cnblogs.com/lifan3a/articles/6649970.html 以太网帧格式.IP数据报格式.TCP段格式+UDP段格式 详解   1.ISO开放系统有 ...

  9. java分享第十五天(log4j 格式详解)

    log4j 格式详解  log4j.rootLogger=日志级别,appender1, appender2, -. 日志级别:ALL<DEBUG<INFO<WARN<ERRO ...

随机推荐

  1. 导致Asp.Net站点重启的10个原因 ,记录重启原因

    Asp.Net站点有时候会莫名其妙的重启,什么原因导致的却不得而知,经过一番折腾后,我总结了导致Asp.Net站点重启的10个原因 1. 回收应用程序池会导致站点重启,记录的原因是: HostingE ...

  2. 在smarty模板中取不到Cookie的值解决方案

    在原生PHP中我们用:setcookie()来设置Cookie变量,用$_COOKIE这个全局变量来读取Cookie.例如 if(!isset($_COOKIE['user'])) { setcook ...

  3. sql2008安装时提示重启计算机失败解决方法

    安装sql 2008的时候,在检测安装环境中有一项是”重新启动计算机”显示的结果是“失败”.上网看了半天,找到了解决方案,虽然我没弄明白具体原因,但问题是解决了,解决方案如下: 一.Windows+R ...

  4. 【设计模式六大原则1】单一职责原则(Single Responsibility Principle)

        http://blog.csdn.net/zhengzhb/article/category/926691/1 图片素材来源,java学习手册 ps.内容为自己整理   定义:不要存在多于一个 ...

  5. Unity3d修改FBX文件的动画名方法

    问题描述:FBX文件导入Unity3d后的动画名字一般都是 “Take 001”并且无法修改!如何修改它呢? 解决方法:解决方法其实很简单,只要你按照Unity3d的FBX文件命名规则,压根就不会存在 ...

  6. POJ1008Maya Calendar

    http://poj.org/problem?id=1008&lang=default&change=true 这个题倒是不难,就是麻烦一点,但是还WA了几次都是因为处理天数的时候没处 ...

  7. mac 设置 ll 等alias 并永久生效

    往上看了在.bash_profile中配置 然后 source  的方法, 试过了, 只是当前的终端有效,当电脑重启或者关闭终端就失效了,只好看看 mac 的 profile 代码 # System- ...

  8. MAC OS JAVA环境变量配置

    在  /etc/profile 中 加上这些 #临时提权 sudo su #输入密码 vi /etc/profile #配置JAVA_HOME,此处路径根据自己的版本填写 JAVA_HOME=&quo ...

  9. 【动态规划】流水作业调度问题与Johnson法则

    1.问题描述:     n个作业{1,2,…,n}要在由2台机器M1和M2组成的流水线上完成加工.每个作业加工的顺序都是先在M1上加工,然后在M2上加工.M1和M2加工作业i所需的时间分别为ai和bi ...

  10. BeanFactory 和 ApplicationContext

    Spring通过一个配置文件描述Bean及Bean直接的依赖关系,利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系.Sprig的IoC容器在完成这些底层工作的基础上,还提供了Bea ...