zoukankan      html  css  js  c++  java
  • MP4文件格式分析及分割实现(附源码)

                   MP4文件格式分析                  

      MP4(MPEG-4 Part 14)是一种常见的多媒体容器格式,它是在“ISO/IEC 14496-14”标准文件中定义的,属于MPEG-4的一部分,是“ISO/IEC 14496-12(MPEG-4 Part 12 ISO base media file format)”标准中所定义的媒体格式的一种实现,后者定义了一种通用的媒体文件结构标准。MP4是一种描述较为全面的容器格式,被认为可以在其中嵌入任何形式的数据,各种编码的视频、音频等都不在话下,不过我们常见的大部分的MP4文件存放的AVC(H.264)MPEG-4(Part 2)编码的视频和AAC编码的音频。MP4格式的官方文件后缀名是“.mp4”,还有其他的以mp4为基础进行的扩展或者是缩水版本的格式,包括:M4V,3GP,F4V等。

     

      一个mp4文件有可能包含非常多的box(全部大约70多个),在很大程度上增加了解析的复杂性。如果要全部解析必要性不是很大。大部分mp4文件没有那么多的box类型,下图就是一个简化了的,常见的mp4文件结构:

    下图是节点box详细说明:

    下面我们将对以上主要box的解析进行详细说明:

    1. 一级box

      一级box主要包含ftyp、moov、free、mdat等等。

    1.1 ftyp box

    结构:

    /********************************************************************************************
    **                            File Type Box (ftyp)
    **
    --------------------------------------------------------------------------------------------
    **        字段名称              |    长度(bytes)   |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize               |    4            |        box的长度
    **        boxtype               |    4            |        box的类型
    **        major_brand           |    4            |
    **        minor_version         |    4            |        版本号
    **        compatible_brands     |    4 * N        |        本文件遵从的多种协议(ismo, iso2, mp41)
    ********************************************************************************************/

    运行结果:

    1.2 moov box

    结构:

    /********************************************************************************************
    **        字段名称            |    长度(bytes)   |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize            |    4            |        box的长度
    **        boxtype            |    4            |        box的类型
    ********************************************************************************************/

    1.3 free box

    结构:

    /********************************************************************************************
    **        字段名称            |    长度(bytes)   |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize            |    4            |        box的长度
    **        boxtype            |    4            |        box的类型
    ********************************************************************************************/

    1.4 mdat box

    结构:

    /********************************************************************************************
    **        字段名称             |    长度(bytes)    |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize             |    4             |        box的长度
    **        boxtype             |    4             |        box的类型
    **                                               |        后面全是真实数据
    ********************************************************************************************/

    运行结果:

    2. 二级box

      本节所说的二级box皆为moov的子box,主要包含mvhd、trak、udat等等。

    2.1 mvhd box

    结构:

    /************************************************************************************************************
    **                                            mvhd
    **
    --------------------------------------------------------------------------------------------
    **        字段名称              |    长度(bytes)   |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize               |    4            |        box的长度
    **        boxtype               |    4            |        box的类型
    **        version               |    1            |        box版本,0或1,一般为0(以下字节数均按version = 0)
    **        flags                 |    3            |        
    **        creation time         |    4            |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
    **        modification time     |    4            |        修改时间
    **        time scale            |    4            |        文件媒体在1秒时间内的刻度值,可以理解为1秒长度的时间单元数
    **        duration              |    4            |        该track的时间长度,用duration和time scale值可以计算track时长
    **        rate                  |    4            |        推荐播放速率,高16位和低16位分别为小数点整数部分和小数部分,即[16.16] 格式.该值为1.0 (0x00010000)
    **        volume                |    2            |        与rate类似,[8.8] 格式,1.0(0x0100)表示最大音量
    **        reserved              |    10           |        保留位
    **        matrix                |    36           |        视频变换矩阵
    **        pre-defined           |    24           |        
    **        next track id         |    4            |        下一个track使用的id号
    ************************************************************************************************************/

    运行结果:

    2.2 trak box

    结构:

    /********************************************************************************************
    **        字段名称            |    长度(bytes)   |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize            |    4            |        box的长度
    **        boxtype            |    4            |        box的类型
    ********************************************************************************************/

    2.3 udat box

    结构:

    /************************************************************************************************************
    **           udat
    **
    --------------------------------------------------------------------------------------------
    **  字段名称 | 长度(bytes)  |  有关描述
    --------------------------------------------------------------------------------------------
    **  boxsize     | 4        |  box的长度
    **  boxtype     | 4        |  box的类型
    **                    |  用户自定义数据解析
    ************************************************************************************************************/

    运行结果:

    3. 三级box

      本节所说的三级box皆为trak的子box,主要包含tkhd、mdia等。

    3.1 tkhd box

    结构:

    /************************************************************************************************************
    **                                        tkhd
    **
    -------------------------------------------------------------------------------------------------------------
    **        字段名称               |    长度(bytes)   |        有关描述
    -------------------------------------------------------------------------------------------------------------
    **        boxsize                |    4            |        box的长度
    **        boxtype                |    4            |        box的类型
    **        version                |    1            |        box版本,0或1,一般为0。(以下字节数均按version = 0)
    **        flags                  |    3            |        按位或操作结果值,预定义如下;
                                                             0x000001 track_enabled,否则该track不被播放;
                                                             0x000002 track_in_movie,表示该track在播放中被引用;
                                                             0x000004 track_in_preview,表示该track在预览时被引用。
                                                             一般该值为7,如果一个媒体所有track均未设置track_in_movie和track_in_preview,将被理解为所有track均设置了这两项;
                                                             对于hint track,该值为0;
    **        creation_time          |    4            |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
    **        modification_time      |    4            |        修改时间
    **        track_id               |    4            |        id号 不能重复且不能为0
    **        reserved               |    4            |        保留位
    **        duration               |    4            |        track的时间长度
    **        reserved               |    8            |        保留位
    **        layer                  |    2            |        视频层,默认为0,值小的在上层
    **        alternate_group        |    2            |        track分组信息,默认为0表示该track未与其他track有群组关系
    **        volume                 |    2            |        [8.8] 格式,如果为音频track,1.0(0x0100)表示最大音量;否则为0
    **        reserved               |    2            |        保留位
    **        matrix                 |    36           |        视频变换矩阵
    **        width                  |    4            |        宽
    **        height                 |    4            |        高,均为[16.16] 格式值 与sample描述中的实际画面大小比值,用于播放时的展示宽高
    ************************************************************************************************************/

    运行结果:

    3.2 mdia box

    结构:

    /********************************************************************************************
    **        字段名称            |    长度(bytes)   |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize            |    4            |        box的长度
    **        boxtype            |    4            |        box的类型
    ********************************************************************************************/

    4. 四级box

      本节所说的四级box皆为mdia的子box,主要包含mdhd、hdlr、minf等。

    4.1 mdhd box

    结构:

    /************************************************************************************************************
    **                                        tkhd
    **
    -------------------------------------------------------------------------------------------------------------
    **        字段名称              |      长度(bytes)   |        有关描述
    -------------------------------------------------------------------------------------------------------------
    **        boxsize               |    4                |        box的长度
    **        boxtype               |    4                |        box的类型
    **        version               |    1           |        box版本0或1 一般为0 (以下字节数均按version=0)
    **        flags                 |    3                |        
    **        creation_time         |    4                |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
    **        modification_time     |    4                |        修改时间
    **        time_scale            |    4                |        
    **        duration              |    4               |        track的时间长度
    **        language              |    2               |        媒体语言码,最高位为0 后面15位为3个字符[见ISO 639-2/T标准中定义]
    **        pre-defined           |    2                |        保留位
    ************************************************************************************************************/

    结果:

    4.2 hdlr box

    结构:

    /************************************************************************************************************
    **                                        hdlr
    **
    -------------------------------------------------------------------------------------------------------------
    **        字段名称               |    长度(bytes)    |        有关描述
    -------------------------------------------------------------------------------------------------------------
    **        boxsize                |    4             |        box的长度
    **        boxtype                |    4             |        box的类型
    **        version                |    1             |        box版本0或1 一般为0 (以下字节数均按version=0)
    **        flags                  |    3             |
    **        pre-defined            |    4             |
    **        handler type           |    4             |        在media box中,该值为4个字符
                                                              "vide"— video track
                                                              "soun"— audio track
                                                              "hint"— hint track
    **        reserved               |    12            |
    **        name                   |    不定           |        track type name,以‘’结尾的字符串
    ************************************************************************************************************/

    结果:

    4.3 minf box

    结构:

    /********************************************************************************************
    **        字段名称            |    长度(bytes)   |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize            |    4            |        box的长度
    **        boxtype            |    4            |        box的类型
    ********************************************************************************************/

    5. 五级box

      本节所说的五级box皆为minf的子box,主要包含header box(vmhd/smhd/hmld/nmld)、stbl等。

    5.1 header box

    本处的headerbox会根据前面的handler type数值选择哪个box。 

    "vide"—vmhd 视频

    "soun"— smhd 音频

    "hint"—hmhd 忽略

    vmhd结构:

    /************************************************************************************************************
    **                                        vmhd
    **
    -------------------------------------------------------------------------------------------------------------
    **        字段名称            |    长度(bytes)    |        有关描述
    -------------------------------------------------------------------------------------------------------------
    **        boxsize                |    4            |        box的长度
    **        boxtype                |    4            |        box的类型
    **        version                |    1            |        box版本0或1 一般为0 (以下字节数均按version=0)
    **        flags                |    3            |
    **        graphics_mode        |    4            |        视频合成模式,为0时拷贝原始图像,否则与opcolor进行合成
    **        opcolor                |    2 ×3        |        {red,green,blue}
    ************************************************************************************************************/

    结果:

    5.2 stbl box

    结构:

    /********************************************************************************************
    **        字段名称            |    长度(bytes)   |        有关描述
    --------------------------------------------------------------------------------------------
    **        boxsize            |    4            |        box的长度
    **        boxtype            |    4            |        box的类型
    ********************************************************************************************/

    6. 六级box

      本节所说的六级box皆为stbl的子box,主要包含stsd、stts、stsz、stsc、stss、stco等,这些也是mp4文件设计的精髓所在,主要控制chunk、sample、mdat之间的映射关系。

    6.1 stsd box

    stsd: Sample Description Box,解析stsd可获得coding类型、视频宽高、音频samplesize、channelcount这些和解码器有关信息。

    6.2 stts box

    stts: Decoding Time to Sample Box,时间戳和Sample映射表

    上图是一个video trak,说明该视频包含87帧数据,每帧包含512个采样。

    总共512*87=44544个采样,和我们前面mdhd box的Duration完全一致。

    Duration / TimeScale = 44544 / 12288 = 3.625秒 正是我们的视频播放长度。

    12288 / 512 = 24 p/s (帧率)。

    6.3 stsz box

    stsz, stz2: Sample Size Boxes,每个Sample大小的表

    一共87帧 每帧的字节大小。

    6.4 stsc box

    stsc: Sample to chunk 的映射表。

    前面说了一共87帧数据,放在83个chunk中。1~82个chunk每个里面放1帧,第83个chunk放了5帧。

    6.5 stss box

    stss: 关键帧索引表。

    第1、13、25、37、49、61、73、85.... 这些帧都是关键帧。

    每12帧就有一个关键帧, 前面我们计算得知fps是24。由此可知该视频关键帧间隔为0.5秒。

    6.6 stco box

    'stco','co64': Chunk位置偏移表

    一共83个chunk,记录在mdat真实数据中的字节偏移量。

    下图为第三方MP4文件解析结果:

     

     

    MP4文件格式解析源码:https://github.com/kingsunc/AVFileParse

    搞清楚stbl的映射关系后 我们就可以进行MP4文件的分割实现(也就是所谓的点播拖动)。

    MP4分割实现源码:https://github.com/kingsunc/AVFileParse/tree/master/Mp4_Segment

     

     

  • 相关阅读:
    搭建自己的 github.io 博客
    转:华为副总裁一封信:透露年薪千万的工作感悟,太震撼了!
    SNF开发平台WinForm之五-高级查询使用说明-SNF快速开发平台3.3-Spring.Net.Framework
    SNF开发平台WinForm之四-开发-主细表管理页面-SNF快速开发平台3.3-Spring.Net.Framework
    SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework
    SNF开发平台WinForm之二-开发-单表表单管理页面-SNF快速开发平台3.3-Spring.Net.Framework
    SNF开发平台WinForm之一-开发-单表表格编辑管理页面-SNF快速开发平台3.3-Spring.Net.Framework
    C#基础总结之八面向对象知识点总结-继承与多态-接口
    C#基础总结之七面向对象知识点总结1
    C#基础总结之六 DataTable (临时表/数据源) 和Datatable 名片练习
  • 原文地址:https://www.cnblogs.com/Kingfans/p/7170478.html
Copyright © 2011-2022 走看看