zoukankan      html  css  js  c++  java
  • mp4文件解析(纯c解析代码)

     参考链接:1. mp4文件格式解析 https://www.cnblogs.com/ranson7zop/p/7889272.html

          2. MP4文件格式分析及分割实现(附源码) https://blog.csdn.net/u013898698/article/details/77152347

       1 #include <stdio.h>
       2 #include <stdlib.h>
       3 #include <string.h>
       4 
       5 #define PRINTF_DEBUG
       6 
       7 #define BOX_TYPE_FTYPE "ftyp"
       8 #define BOX_TYPE_MOOV "moov"
       9 #define BOX_TYPE_MVHD "mvhd"
      10 #define BOX_TYPE_TRAK "trak"
      11 #define BOX_TYPE_TKHD "tkhd"
      12 #define BOX_TYPE_EDTS "edts"
      13 #define BOX_TYPE_MDIA "mdia"
      14 #define BOX_TYPE_MDHD "mdhd"
      15 #define BOX_TYPE_HDLR "hdlr"
      16 #define BOX_TYPE_MINF "minf"
      17 #define BOX_TYPE_VMHD "vmhd"
      18 #define BOX_TYPE_DINF "dinf"
      19 #define BOX_TYPE_DREF "dref"
      20 #define BOX_TYPE_STBL "stbl"
      21 #define BOX_TYPE_STSD "stsd"
      22 #define BOX_TYPE_STTS "stts"
      23 #define BOX_TYPE_STSS "stss"
      24 #define BOX_TYPE_STSC "stsc"
      25 #define BOX_TYPE_STSZ "stsz"
      26 #define BOX_TYPE_STCO "stco"
      27 #define BOX_TYPE_UDTA "udta"
      28 
      29 #define MAX_BOX_SIZE_LEN 4
      30 #define MAX_BOX_TYPE_LEN 4
      31 #define MAX_HANDLER_TYPE_LEN 4
      32 #define MAX_FTYP_BRABDS_LEN 4
      33 #define MAX_FTYP_BRABDS_NUM 4
      34 #define MAX_STTS_ENTRY_NUM 8
      35 #define MAX_STSS_ENTRY_NUM 8
      36 #define MAX_STSC_ENTRY_NUM 100
      37 #define MAX_STSZ_ENTRY_NUM 100 /* now parse 100 frame */
      38 #define MAX_STCO_ENTRY_NUM 100 
      39 #define MAX_MVHD_RESERVED_LEN 10
      40 #define MAX_PRE_DEFINE_LEN 24
      41 #define MAX_MATRIX_LEN 36
      42 #define MAX_HDLR_NAME_LEN 100
      43 
      44 
      45 typedef struct t_box_header
      46 {
      47     int boxSize;
      48     
      49     unsigned char boxType[MAX_BOX_TYPE_LEN+1];
      50     
      51     long largeBoxSize; /* if boxSize=1 use, if boxSize=0, end of file */
      52 } T_BOX_HEADER;
      53 
      54 /********************************************************************************************
      55 **                            File Type Box (ftyp): file type, 表明文件类型
      56 **
      57 --------------------------------------------------------------------------------------------
      58 **        字段名称              |    长度(bytes)   |        有关描述
      59 --------------------------------------------------------------------------------------------
      60 **        boxsize               |    4            |        box的长度
      61 **        boxtype               |    4            |        box的类型
      62 **        major_brand           |    4            |
      63 **        minor_version         |    4            |        版本号
      64 **        compatible_brands     |    4 * N        |        本文件遵从的多种协议(ismo, iso2, mp41)
      65 ********************************************************************************************/
      66 typedef struct t_box4ftyp_brand
      67 {
      68     unsigned char brands[MAX_FTYP_BRABDS_LEN+1];
      69 } T_BOX4FTYP_BRAN;
      70 
      71 typedef struct t_box4ftyp
      72 {
      73     unsigned char major_brand[MAX_FTYP_BRABDS_LEN+1];
      74     
      75     int minor_version;
      76     
      77     T_BOX4FTYP_BRAN compatible_brands[MAX_FTYP_BRABDS_NUM];
      78 } T_BOX4FTYP;
      79 
      80 /************************************************************************************************************
      81 **                                            mvhd: movie header, 文件的总体信息: 时长, 创建时间等
      82 **
      83 --------------------------------------------------------------------------------------------
      84 **        字段名称              |    长度(bytes)   |        有关描述
      85 --------------------------------------------------------------------------------------------
      86 **        boxsize               |    4            |        box的长度
      87 **        boxtype               |    4            |        box的类型
      88 **        version               |    1            |        box版本,0或1,一般为0(以下字节数均按version = 0)
      89 **        flags                 |    3            |        
      90 **        creation time         |    4            |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
      91 **        modification time     |    4            |        修改时间
      92 **        time scale            |    4            |        文件媒体在1秒时间内的刻度值,可以理解为1秒长度的时间单元数
      93 **        duration              |    4            |        该track的时间长度,用duration和time scale值可以计算track时长
      94 **        rate                  |    4            |        推荐播放速率,高16位和低16位分别为小数点整数部分和小数部分,即[16.16] 格式.该值为1.0 (0x00010000)
      95 **        volume                |    2            |        与rate类似,[8.8] 格式,1.0(0x0100)表示最大音量
      96 **        reserved              |    10           |        保留位
      97 **        matrix                |    36           |        视频变换矩阵
      98 **        pre-defined           |    24           |        
      99 **        next track id         |    4            |        下一个track使用的id号
     100 ** 
     101 if (version==1) 
     102 {
     103     unsigned int(64) creation_time;
     104     unsigned int(64) modification_time;
     105     unsigned int(32) timescale;
     106     unsigned int(64) duration;
     107 } 
     108 else 
     109 {
     110     unsigned int(32) creation_time;
     111     unsigned int(32) modification_time;
     112     unsigned int(32) timescale;
     113     unsigned int(32) duration;
     114 }
     115 ************************************************************************************************************/
     116 typedef struct t_box4mvhd
     117 {
     118     int creation_time;
     119     int modification_time;
     120     int timescale;
     121     int duration;
     122     float rate;
     123     float volume;
     124     int next_track_id;
     125 } T_BOX4MVHD;
     126 
     127 /************************************************************************************************************
     128 **                                        tkhd: track header, track的总体信息, 如时长, 宽高等
     129 **
     130 -------------------------------------------------------------------------------------------------------------
     131 **        字段名称               |    长度(bytes)   |        有关描述
     132 -------------------------------------------------------------------------------------------------------------
     133 **        boxsize                |    4            |        box的长度
     134 **        boxtype                |    4            |        box的类型
     135 **        version                |    1            |        box版本,0或1,一般为0。(以下字节数均按version = 0)
     136 **        flags                  |    3            |        按位或操作结果值,预定义如下;
     137                                                          0x000001 track_enabled,否则该track不被播放;
     138                                                          0x000002 track_in_movie,表示该track在播放中被引用;
     139                                                          0x000004 track_in_preview,表示该track在预览时被引用。
     140                                                          一般该值为7,如果一个媒体所有track均未设置track_in_movie和track_in_preview,将被理解为所有track均设置了这两项;
     141                                                          对于hint track,该值为0;
     142 **        creation_time          |    4            |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
     143 **        modification_time      |    4            |        修改时间
     144 **        track_id               |    4            |        id号 不能重复且不能为0
     145 **        reserved               |    4            |        保留位
     146 **        duration               |    4            |        track的时间长度
     147 **        reserved               |    8            |        保留位
     148 **        layer                  |    2            |        视频层,默认为0,值小的在上层
     149 **        alternate_group        |    2            |        track分组信息,默认为0表示该track未与其他track有群组关系
     150 **        volume                 |    2            |        [8.8] 格式,如果为音频track,1.0(0x0100)表示最大音量;否则为0
     151 **        reserved               |    2            |        保留位
     152 **        matrix                 |    36           |        视频变换矩阵
     153 **        width                  |    4            |        宽
     154 **        height                 |    4            |        高,均为[16.16] 格式值 与sample描述中的实际画面大小比值,用于播放时的展示宽高
     155 if (version==1) 
     156 {
     157     unsigned int(64) creation_time;
     158     unsigned int(64) modification_time;
     159     unsigned int(32) track_ID;
     160     const unsigned int(32) reserved = 0;
     161     unsigned int(64) duration;
     162 } 
     163 else 
     164 {
     165     unsigned int(32) creation_time;
     166     unsigned int(32) modification_time;
     167     unsigned int(32) track_ID;
     168     const unsigned int(32) reserved = 0;
     169     unsigned int(32) duration;
     170 }
     171 ************************************************************************************************************/
     172 typedef struct t_box4tkhd
     173 {
     174     int flags;
     175     int creation_time;
     176     int modification_time;
     177     int track_id;
     178     int duration;
     179     int layer;
     180     int alternate_group;
     181     float volume;
     182     float width;
     183     float height;
     184 } T_BOX4TKHD;
     185 
     186 /************************************************************************************************************
     187 **                                        mdhd: 包含了了该track的总体信息, mdhd和tkhd 内容大致都是一样的.
     188 **
     189 -------------------------------------------------------------------------------------------------------------
     190 **        字段名称              |      长度(bytes)   |        有关描述
     191 -------------------------------------------------------------------------------------------------------------
     192 **        boxsize               |    4                |        box的长度
     193 **        boxtype               |    4                |        box的类型
     194 **        version               |    1         |        box版本0或1 一般为0 (以下字节数均按version=0)
     195 **        flags                 |    3                |        
     196 **        creation_time         |    4                |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
     197 **        modification_time     |    4                |        修改时间
     198 **        time_scale            |    4                |        
     199 **        duration              |    4               |        track的时间长度
     200 **        language              |    2               |        媒体语言码,最高位为0 后面15位为3个字符[见ISO 639-2/T标准中定义]
     201 **        pre-defined           |    2                |        保留位
     202 
     203 ** tkhd通常是对指定的track设定相关属性和内容, 而mdhd是针对于独立的media来设置的, 一般情况下二者相同.
     204 ************************************************************************************************************/
     205 typedef struct t_box4mdhd
     206 {
     207     int creation_time;
     208     int modification_time;
     209     int timescale;
     210     int duration;
     211     short language;
     212 } T_BOX4MDHD;
     213 
     214 /************************************************************************************************************
     215 **                                        hdlr: Handler Reference Box, 媒体的播放过程信息, 该box也可以被包含在meta box(meta)中
     216 **
     217 -------------------------------------------------------------------------------------------------------------
     218 **        字段名称               |    长度(bytes)    |        有关描述
     219 -------------------------------------------------------------------------------------------------------------
     220 **        boxsize                |    4             |        box的长度
     221 **        boxtype                |    4             |        box的类型
     222 **        version                |    1             |        box版本0或1 一般为0 (以下字节数均按version=0)
     223 **        flags                  |    3             |
     224 **        pre-defined            |    4             |
     225 **        handler type           |    4             |        在media box中,该值为4个字符
     226                                                           "vide"— video track
     227                                                           "soun"— audio track
     228                                                           "hint"— hint track
     229 **        reserved               |    12            |
     230 **        name                   |    不定           |        track type name,以‘’结尾的字符串
     231 ************************************************************************************************************/
     232 typedef struct t_box4hdlr
     233 {
     234     unsigned char handler_type[MAX_HANDLER_TYPE_LEN+1];
     235     unsigned char name[MAX_HDLR_NAME_LEN+1];
     236 } T_BOX4HDLR;
     237 
     238 /************************************************************************************************************
     239 **                                        vmhd: Video Media Header Box
     240 **
     241 -------------------------------------------------------------------------------------------------------------
     242 **        字段名称            |    长度(bytes)    |        有关描述
     243 -------------------------------------------------------------------------------------------------------------
     244 **        boxsize                |    4            |        box的长度
     245 **        boxtype                |    4            |        box的类型
     246 **        version                |    1            |        box版本0或1 一般为0 (以下字节数均按version=0)
     247 **        flags                     |    3            |
     248 **        graphics_mode          |    4            |        视频合成模式,为0时拷贝原始图像,否则与opcolor进行合成
     249 **        opcolor                |    2 ×3         |        {red,green,blue}
     250 
     251 "vide"—vmhd 视频
     252 "soun"— smhd 音频
     253 "hint"—hmhd 忽略
     254 ************************************************************************************************************/
     255 typedef struct t_box4vmhd
     256 {
     257     int graphics_mode;
     258 } T_BOX4VMHD;
     259 
     260 /************************************************************************************************************
     261 **                                        dref: data reference box
     262 **
     263 -------------------------------------------------------------------------------------------------------------
     264 **        字段名称               |    长度(bytes)    |        有关描述
     265 -------------------------------------------------------------------------------------------------------------
     266 **        boxsize                |    4             |        box的长度
     267 **        boxtype                |    4             |        box的类型
     268 **        version                |    1             |        box版本0或1 一般为0 (以下字节数均按version=0)
     269 **        flags                  |    3             |
     270 **        entry count            |    4             |         "url"或"urn"表的元素个数
     271 **        "url"或"urn"列表       |    不定          |
     272 
     273 ** "dref"下会包含若干个"url"或"urn", 这些box组成一个表, 用来定位track数据. 简单的说, track可以被分成若干段,
     274    每一段都可以根据"url"或"urn"指向的地址来获取数据, sample描述中会用这些片段的序号将这些片段组成一个完整的track.
     275    一般情况下, 当数据被完全包含在文件中时, "url"或"urn"中的定位字符串是空的.
     276 ************************************************************************************************************/
     277 typedef struct t_box4dref
     278 {
     279     int entry_count;
     280 } T_BOX4DREF;
     281 
     282 /************************************************************************************************************
     283 **                                        stsd: Sample Description Box
     284 **
     285 -------------------------------------------------------------------------------------------------------------
     286 **        字段名称               |    长度(bytes)    |        有关描述
     287 -------------------------------------------------------------------------------------------------------------
     288 **        boxsize                |    4             |        box的长度
     289 **        boxtype                |    4             |        box的类型
     290 **        version                |    1             |        box版本0或1 一般为0 (以下字节数均按version=0)
     291 **        entry count            |    4             |         "url"或"urn"表的元素个数
     292 
     293 ** box header和version字段后会有一个entry count字段, 根据entry的个数, 每个entry会有type信息, 如"vide", "sund"等,
     294    根据type不同sample description会提供不同的信息, 例如对于video track, 会有"VisualSampleEntry"类型信息, 
     295    对于audio track会有"AudioSampleEntry"类型信息. 视频的编码类型, 宽高, 长度, 音频的声道, 采样等信息都会出现在这个box中
     296 ************************************************************************************************************/
     297 typedef struct t_box4stsd
     298 {
     299     int entry_count;
     300     
     301     //TODO
     302 } T_BOX4STSD;
     303 
     304 /************************************************************************************************************
     305 **                                        stts: Time To Sample Box
     306 **
     307 -------------------------------------------------------------------------------------------------------------
     308 **        字段名称               |    长度(bytes)    |        有关描述
     309 -------------------------------------------------------------------------------------------------------------
     310 **        boxsize                |    4             |        box的长度
     311 **        boxtype                |    4             |        box的类型
     312 **        version                |    1             |        box版本,0或1,一般为0(以下字节数均按version = 0)
     313 **        flags                  |    3             | 
     314 **        entry count            |    4             |         sample_count和sample_delta的个数
     315 **        sample_count           |    4             |         
     316 **        sample_delta           |    4             |         
     317 
     318 ** "stts”"存储了sample的duration, 描述了sample时序的映射方法, 我们通过它可以找到任何时间的sample. "stts"可以
     319    包含一个压缩的表来映射时间和sample序号, 用其他的表来提供每个sample的长度和指针. 表中每个条目提供了在同一个
     320    时间偏移量里面连续的sample序号, 以及samples的偏移量. 递增这些偏移量, 就可以建立一个完整的time to sample表.
     321    
     322    例: 说明该视频包含87帧数据(sample_count), 每帧包含512个采样(sample_delta). 总共512*87=44544个采样,
     323        和我们前面mdhd box的Duration完全一致。
     324        Duration/TimeScale = 44544/12288 = 3.625s, 正是我们的视频播放长度.
     325        12288/512 = 24 p/s (帧率)
     326 ************************************************************************************************************/
     327 typedef struct t_box4stts_entry
     328 {
     329     int sample_count;
     330     int sample_delta;
     331 } T_BOX4STTS_ENTRY;
     332 
     333 typedef struct t_box4stts
     334 {
     335     int entry_count;
     336     
     337     T_BOX4STTS_ENTRY entrys[MAX_STTS_ENTRY_NUM];
     338 } T_BOX4STTS;
     339 
     340 /************************************************************************************************************
     341 **                                        stss: Sync Sample Box
     342 **
     343 -------------------------------------------------------------------------------------------------------------
     344 **        字段名称               |    长度(bytes)    |        有关描述
     345 -------------------------------------------------------------------------------------------------------------
     346 **        boxsize                |    4             |        box的长度
     347 **        boxtype                |    4             |        box的类型
     348 **        version                |    1             |        box版本,0或1,一般为0(以下字节数均按version = 0)
     349 **        flags                  |    3             | 
     350 **        entry count            |    4             |         sample_num的个数
     351 **        sample_num                |    4             |         
     352 
     353 ** "stss"确定media中的关键帧. 对于压缩媒体数据, 关键帧是一系列压缩序列的开始帧, 其解压缩时不依赖以前的帧, 
     354    而后续帧的解压缩将依赖于这个关键帧. "stss"可以非常紧凑的标记媒体内的随机存取点, 它包含一个sample序号表, 
     355    表内的每一项严格按照sample的序号排列, 说明了媒体中的哪一个sample是关键帧. 如果此表不存在, 说明每一个sample
     356    都是一个关键帧, 是一个随机存取点.
     357 ************************************************************************************************************/
     358 typedef struct t_box4stss_entry
     359 {
     360     int sample_num;
     361 } T_BOX4STSS_ENTRY;
     362 
     363 typedef struct t_box4stss
     364 {
     365     int entry_count;
     366     
     367     T_BOX4STSS_ENTRY entrys[MAX_STSS_ENTRY_NUM];
     368 } T_BOX4STSS;
     369 
     370 /************************************************************************************************************
     371 **                                        stsc: Sample To Chunk Box
     372 **
     373 -------------------------------------------------------------------------------------------------------------
     374 **        字段名称               |    长度(bytes)    |        有关描述
     375 -------------------------------------------------------------------------------------------------------------
     376 **        boxsize                |    4             |        box的长度
     377 **        boxtype                |    4             |        box的类型
     378 **        version                |    1             |        box版本,0或1,一般为0(以下字节数均按version = 0)
     379 **        flags                  |    3             | 
     380 **        entry count            |    4             |         entry的个数
     381 **        first_chunk            |    4             |        
     382 **        samples_per_chunk      |    4             |
     383 **        sample_des_index       |    4             |
     384 
     385 ** 用chunk组织sample可以方便优化数据获取, 一个thunk包含一个或多个sample. "stsc"中用一个表描述了sample与chunk的映射关系,
     386    查看这张表就可以找到包含指定sample的thunk, 从而找到这个sample. 
     387 ************************************************************************************************************/
     388 typedef struct t_box4stsc_entry
     389 {
     390     int first_chunk;
     391     int samples_per_chunk;
     392     int sample_description_index;
     393 } T_BOX4STSC_ENTRY;
     394 
     395 typedef struct t_box4stsc
     396 {
     397     int entry_count;
     398     
     399     T_BOX4STSC_ENTRY entrys[MAX_STSC_ENTRY_NUM];
     400 } T_BOX4STSC;
     401 
     402 /************************************************************************************************************
     403 **                                        stsz: Sample To Chunk Box
     404 **
     405 -------------------------------------------------------------------------------------------------------------
     406 **        字段名称               |    长度(bytes)    |        有关描述
     407 -------------------------------------------------------------------------------------------------------------
     408 **        boxsize                |    4             |        box的长度
     409 **        boxtype                |    4             |        box的类型
     410 **        version                |    1             |        box版本,0或1,一般为0(以下字节数均按version = 0)
     411 **        flags                  |    3             | 
     412 **        sample_size            |    4             |
     413 **        sample_count           |    4             |         entry的个数
     414 **        entry_size             |    4             |
     415 
     416 **  "stsz"定义了每个sample的大小, 包含了媒体中全部sample的数目和一张给出每个sample大小的表. 这个box相对来说体积是比较大的.
     417 ************************************************************************************************************/
     418 typedef struct t_box4stsz_entry
     419 {
     420     int entry_size;
     421 } T_BOX4STSZ_ENTRY;
     422 
     423 typedef struct t_box4stsz
     424 {
     425     int sample_size;
     426     int sample_count;
     427     
     428     T_BOX4STSZ_ENTRY entrys[MAX_STSZ_ENTRY_NUM];
     429 } T_BOX4STSZ;
     430 
     431 /************************************************************************************************************
     432 **                                        stco: Chunk Offset Box
     433 **
     434 -------------------------------------------------------------------------------------------------------------
     435 **        字段名称               |    长度(bytes)    |        有关描述
     436 -------------------------------------------------------------------------------------------------------------
     437 **        boxsize                |    4             |        box的长度
     438 **        boxtype                |    4             |        box的类型
     439 **        version                |    1             |        box版本,0或1,一般为0(以下字节数均按version = 0)
     440 **        flags                  |    3             | 
     441 **        entry_count            |    4             |
     442 **        chunk_offset           |    4             |         
     443 
     444 **  "stco"定义了每个thunk在媒体流中的位置, sample的偏移可以根据其他box推算出来. 位置有两种可能, 32位的和64位的,
     445     后者对非常大的电影很有用. 在一个表中只会有一种可能, 这个位置是在整个文件中的, 而不是在任何box中的. 
     446     这样做就可以直接在文件中找到媒体数据, 而不用解释box. 需要注意的是一旦前面的box有了任何改变, 这张表都要重新建立, 因为位置信息已经改变了.
     447 ************************************************************************************************************/
     448 typedef struct t_box4stco_entry
     449 {
     450     int chunk_offset;
     451 } T_BOX4STCO_ENTRY;
     452 
     453 typedef struct t_box4stco
     454 {
     455     int entry_count;
     456     
     457     T_BOX4STCO_ENTRY entrys[MAX_STCO_ENTRY_NUM];
     458 } T_BOX4STCO;
     459 
     460 typedef struct t_box
     461 {
     462     T_BOX_HEADER boxHeader;
     463     
     464     unsigned char *boxData;
     465 } T_BOX;
     466 
     467 static void DealBox4ftyp(const T_BOX *box)
     468 {
     469     int i = 0;
     470     int j = 0;
     471     int brandsNum = 0;
     472 
     473     T_BOX4FTYP box4ftyp = {0};
     474     
     475     memset(&box4ftyp, 0x0, sizeof(T_BOX4FTYP));
     476 
     477     memcpy(box4ftyp.major_brand, box->boxData, 4);
     478     box4ftyp.major_brand[MAX_FTYP_BRABDS_LEN] = '';
     479     
     480     box4ftyp.minor_version =  box->boxData[4] << 24 | box->boxData[5] << 16 | box->boxData[6] << 8 | box->boxData[7];
     481 
     482     brandsNum = (box->boxHeader.boxSize - MAX_BOX_SIZE_LEN - MAX_BOX_TYPE_LEN - MAX_FTYP_BRABDS_LEN - 4) / 4;
     483 
     484     /* 1. if not have '', 每个brands的内存是连续的, 导致打印时后面的每4个数据都会加到前面;
     485        2. unsigned char brands[MAX_FTYP_BRABDS_LEN+1]; 可解决, 此时也不必加'', 但需初始化;
     486        3. 因此字符串最好定义+1并赋'';
     487        4. 复现: unsigned char brands[MAX_FTYP_BRABDS_LEN]
     488     */
     489     for (i=0; i<brandsNum; i++)
     490     {
     491         memcpy(box4ftyp.compatible_brands[i].brands, box->boxData+MAX_FTYP_BRABDS_LEN+4+4*i, 4);
     492         
     493         box4ftyp.compatible_brands[i].brands[MAX_FTYP_BRABDS_LEN] = '';
     494     }
     495 
     496 #ifdef PRINTF_DEBUG
     497     printf("	major_brand: %s, minor_version: %d, compatible_brands: ", box4ftyp.major_brand, box4ftyp.minor_version);
     498     
     499     for (i=0; i<brandsNum; i++)
     500     {
     501         if (i==brandsNum-1)
     502         {
     503             printf("%s", box4ftyp.compatible_brands[i].brands);
     504         }
     505         else
     506         {
     507             printf("%s,", box4ftyp.compatible_brands[i].brands);
     508         }
     509     }
     510     
     511     printf("
    ");
     512 #endif
     513 }
     514 
     515 static void DealBox4mvhd(const unsigned char *mvhdData)
     516 {
     517     unsigned char *data = NULL;
     518     
     519     T_BOX4MVHD box4mvhd = {0};
     520     
     521     memset(&box4mvhd, 0x0, sizeof(T_BOX4MVHD));
     522     
     523     data = (unsigned char *)mvhdData;
     524     
     525     data += 4;
     526     box4mvhd.creation_time = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     527     
     528     data += 4;
     529     box4mvhd.modification_time = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     530     
     531     data += 4;
     532     box4mvhd.timescale = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     533     
     534     data += 4;
     535     box4mvhd.duration = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     536     
     537     data += 4;
     538     //box4mvhd.rate = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     539     box4mvhd.rate = (data[0] << 8 | data[1]) + (data[2] << 8 | data[3]);
     540     
     541     data += 4;
     542     //box4mvhd.volume = data[0] << 8 | data[1];
     543     box4mvhd.volume = data[0] + data[1];
     544     
     545     data += 2;
     546     data += (MAX_MVHD_RESERVED_LEN + MAX_PRE_DEFINE_LEN + MAX_MATRIX_LEN);
     547     box4mvhd.next_track_id = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     548     
     549 #ifdef PRINTF_DEBUG
     550     printf("		creation_time: %d, modification_time: %d, timescale: %d, duration: %d, rate: %f, volume: %f, next_track_id: %d
    ",
     551             box4mvhd.creation_time, box4mvhd.modification_time, box4mvhd.timescale, box4mvhd.duration, box4mvhd.rate, box4mvhd.volume, box4mvhd.next_track_id);
     552 #endif    
     553 }
     554 
     555 static void DealBox4tkhd(const unsigned char *tkhdData)
     556 {
     557     unsigned char *data = NULL;
     558     
     559     T_BOX4TKHD box4tkhd = {0};
     560     
     561     memset(&box4tkhd, 0x0, sizeof(box4tkhd));
     562     
     563     data = (unsigned char *)tkhdData;
     564     
     565     box4tkhd.flags = data[1] << 16 | data[2] << 8 | data[3];
     566     
     567     data += 4;
     568     box4tkhd.creation_time = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     569     
     570     data += 4;
     571     box4tkhd.modification_time = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     572     
     573     data += 4;
     574     box4tkhd.track_id = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     575     
     576     data += 4;
     577     
     578     data += 4; /* 4 reserved */
     579     box4tkhd.duration = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     580     
     581     data += 4;
     582     
     583     data += 8; /* 8 reserved */
     584     box4tkhd.layer = data[0] << 8 | data[1];
     585     
     586     data += 2;
     587     box4tkhd.alternate_group = data[0] << 8 | data[1];
     588     
     589     data += 2;
     590     box4tkhd.volume = data[0] + data[1];
     591     
     592     data += 2;
     593     
     594     data += 2;
     595     
     596     data += 36;
     597     box4tkhd.width = (data[0] << 8 | data[1]) + (data[2] << 8 | data[3]);
     598     
     599     data += 4;
     600     box4tkhd.height = (data[0] << 8 | data[1]) + (data[2] << 8 | data[3]);
     601 
     602 #ifdef PRINTF_DEBUG
     603     printf("			flags: %d, creation_time: %d, modification_time: %d, track_id: %d, duration: %d, layer: %d, alternate_group: %d, volume: %f,  %f, height: %f
    ",
     604             box4tkhd.flags, box4tkhd.creation_time, box4tkhd.modification_time, box4tkhd.track_id, box4tkhd.duration, box4tkhd.layer, box4tkhd.alternate_group, box4tkhd.volume, box4tkhd.width, box4tkhd.height);
     605 #endif
     606 }
     607 
     608 static void DealBox4dref(const T_BOX *box)
     609 {
     610     // TODO
     611 }
     612 
     613 static void DealBox4dinf(const T_BOX *box)
     614 {    int boxSize = 0;
     615     int dinfDataSize = 0;
     616     
     617     unsigned char *dinfData = NULL;
     618     unsigned char *data = NULL;
     619     
     620     char boxType[MAX_BOX_TYPE_LEN+1] = {0};
     621     
     622     T_BOX drefBox = {0};
     623     
     624     dinfData = box->boxData;
     625     dinfDataSize = box->boxHeader.boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN;
     626     
     627     while (dinfDataSize > 0)
     628     {
     629         boxSize = dinfData[0] << 24 | dinfData[1] << 16 | dinfData[2] << 8 | dinfData[3];
     630         
     631         memcpy(boxType, dinfData+MAX_BOX_SIZE_LEN, 4);
     632 
     633 #ifdef PRINTF_DEBUG
     634     printf("					****BOX: Layer6****
    ");
     635     printf("						size: %d
    ", boxSize);
     636     printf("						type: %s
    ", boxType);
     637 #endif
     638         if (0 == strcmp(boxType, BOX_TYPE_DREF))
     639         {
     640             memset(&drefBox, 0x0, sizeof(T_BOX));
     641 
     642             drefBox.boxHeader.boxSize = boxSize;
     643 
     644             memcpy(drefBox.boxHeader.boxType, boxType, strlen(boxType));
     645 
     646             drefBox.boxData = (unsigned char*)malloc(boxSize);
     647             if (drefBox.boxData)
     648             {
     649                 memcpy(drefBox.boxData, dinfData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
     650 
     651                 DealBox4dref((const T_BOX*)&drefBox);
     652 
     653                 free(drefBox.boxData);
     654                 drefBox.boxData = NULL;
     655             }
     656         }
     657         
     658         dinfData += boxSize;
     659         dinfDataSize -= boxSize;
     660     }
     661 }
     662 
     663 static void DealBox4stts(const unsigned char *sttsData)
     664 {
     665     int i = 0;
     666     
     667     unsigned char *data = NULL;
     668     
     669     T_BOX4STTS box4stts = {0};
     670     
     671     memset(&box4stts, 0x0, sizeof(box4stts));
     672     
     673     data = (unsigned char *)sttsData;
     674     
     675     data += 4;
     676     
     677     box4stts.entry_count = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     678     
     679     data += 4;
     680 
     681     for (i=0; i<box4stts.entry_count; i++)
     682     {
     683         if (i == MAX_STTS_ENTRY_NUM)
     684         {
     685             break;
     686         }
     687         
     688         box4stts.entrys[i].sample_count = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     689         
     690         data += 4;
     691         
     692         box4stts.entrys[i].sample_delta = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     693         
     694         data += 4;
     695     }
     696     
     697 #ifdef PRINTF_DEBUG
     698     printf("			entry_count: %d, [sample_count, sample_delta]: ", box4stts.entry_count);
     699     
     700     if (box4stts.entry_count>MAX_STTS_ENTRY_NUM)
     701     {
     702         box4stts.entry_count = MAX_STTS_ENTRY_NUM;
     703     }
     704     
     705     for (i=0; i<box4stts.entry_count; i++)
     706     {
     707         if (i>0)
     708         {
     709             printf(", ");
     710         }
     711         
     712         printf("[%d, %d]", box4stts.entrys[i].sample_count, box4stts.entrys[i].sample_delta);
     713     }
     714     
     715     if (box4stts.entry_count==MAX_STTS_ENTRY_NUM)
     716     {
     717         printf("...(just show %d now)", MAX_STTS_ENTRY_NUM);
     718     }
     719     
     720     printf("
    ");
     721 #endif
     722 }
     723 
     724 static void DealBox4stss(const unsigned char *stssData)
     725 {
     726     int i = 0;
     727     
     728     unsigned char *data = NULL;
     729     
     730     T_BOX4STSS box4stss = {0};
     731     
     732     memset(&box4stss, 0x0, sizeof(box4stss));
     733     
     734     data = (unsigned char *)stssData;
     735     
     736     data += 4;
     737     
     738     box4stss.entry_count = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     739     
     740     data += 4;
     741 
     742     for (i=0; i<box4stss.entry_count; i++)
     743     {
     744         if (i == MAX_STSS_ENTRY_NUM)
     745         {
     746             break;
     747         }
     748         
     749         box4stss.entrys[i].sample_num = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     750         
     751         data += 4;
     752     }
     753     
     754 #ifdef PRINTF_DEBUG
     755     printf("			entry_count: %d, sample_num: ", box4stss.entry_count);
     756     
     757     if (box4stss.entry_count>MAX_STSS_ENTRY_NUM)
     758     {
     759         box4stss.entry_count = MAX_STSS_ENTRY_NUM;
     760     }
     761     
     762     for (i=0; i<box4stss.entry_count; i++)
     763     {
     764         if (i>0)
     765         {
     766             printf(", ");
     767         }
     768         
     769         printf("%d", box4stss.entrys[i].sample_num);
     770     }
     771     
     772     if (box4stss.entry_count==MAX_STSS_ENTRY_NUM)
     773     {
     774         printf("...(just show %d now)", MAX_STSS_ENTRY_NUM);
     775     }
     776     
     777     printf("
    ");
     778 #endif
     779 }
     780 
     781 static void DealBox4stsc(const unsigned char *stscData)
     782 {
     783     int i = 0;
     784     
     785     unsigned char *data = NULL;
     786     
     787     T_BOX4STSC box4stsc = {0};
     788     
     789     memset(&box4stsc, 0x0, sizeof(box4stsc));
     790     
     791     data = (unsigned char *)stscData;
     792     
     793     data += 4;
     794     
     795     box4stsc.entry_count = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     796     
     797     data += 4;
     798 
     799     for (i=0; i<box4stsc.entry_count; i++)
     800     {
     801         if (i == MAX_STSC_ENTRY_NUM)
     802         {
     803             break;
     804         }
     805         
     806         box4stsc.entrys[i].first_chunk = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     807         
     808         data += 4;
     809         
     810         box4stsc.entrys[i].samples_per_chunk = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     811 
     812         data += 4;
     813 
     814         box4stsc.entrys[i].sample_description_index = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     815 
     816         data += 4;
     817     }
     818     
     819 #ifdef PRINTF_DEBUG
     820     printf("			entry_count: %d, [first_chunk, samples_per_chunk, sample_description_index]: ", box4stsc.entry_count);
     821     
     822     if (box4stsc.entry_count>MAX_STSC_ENTRY_NUM)
     823     {
     824         box4stsc.entry_count = MAX_STSC_ENTRY_NUM;
     825     }
     826     
     827     for (i=0; i<box4stsc.entry_count; i++)
     828     {
     829         if (i>0)
     830         {
     831             printf(", ");
     832         }
     833         
     834         printf("[%d, %d, %d]", box4stsc.entrys[i].first_chunk, box4stsc.entrys[i].samples_per_chunk, box4stsc.entrys[i].sample_description_index);
     835     }
     836     
     837     if (box4stsc.entry_count==MAX_STSC_ENTRY_NUM)
     838     {
     839         printf("...(just show %d now)", MAX_STSC_ENTRY_NUM);
     840     }
     841     
     842     printf("
    ");
     843 #endif
     844 }
     845 
     846 static void DealBox4stsz(const unsigned char *stszData)
     847 {
     848     int i = 0;
     849     
     850     unsigned char *data = NULL;
     851     
     852     T_BOX4STSZ box4stsz = {0};
     853     
     854     memset(&box4stsz, 0x0, sizeof(box4stsz));
     855     
     856     data = (unsigned char *)stszData;
     857     
     858     data += 4;
     859     
     860     box4stsz.sample_size = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     861     
     862     data += 4;
     863     
     864     box4stsz.sample_count = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     865     
     866     data += 4;
     867 
     868     for (i=0; i<box4stsz.sample_count; i++)
     869     {
     870         if (i == MAX_STSZ_ENTRY_NUM)
     871         {
     872             break;
     873         }
     874         
     875         box4stsz.entrys[i].entry_size = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     876         
     877         data += 4;
     878     }
     879     
     880 #ifdef PRINTF_DEBUG
     881     printf("			sample_size: %d, sample_count: %d, [entry_size]: ", box4stsz.sample_size, box4stsz.sample_count);
     882     
     883     if (box4stsz.sample_count>MAX_STSZ_ENTRY_NUM)
     884     {
     885         box4stsz.sample_count = MAX_STSZ_ENTRY_NUM;
     886     }
     887     
     888     for (i=0; i<box4stsz.sample_count; i++)
     889     {
     890         if (i>0)
     891         {
     892             printf(", ");
     893         }
     894         
     895         printf("[%d]", box4stsz.entrys[i].entry_size);
     896     }
     897         
     898     if (box4stsz.sample_count==MAX_STSZ_ENTRY_NUM)
     899     {
     900         printf("...(just show %d now)", MAX_STSZ_ENTRY_NUM);
     901     }
     902     
     903     printf("
    ");
     904 #endif
     905 }
     906 
     907 static void DealBox4stco(const unsigned char *stcoData)
     908 {
     909     int i = 0;
     910     
     911     unsigned char *data = NULL;
     912     
     913     T_BOX4STCO box4stco = {0};
     914     
     915     memset(&box4stco, 0x0, sizeof(box4stco));
     916     
     917     data = (unsigned char *)stcoData;
     918     
     919     data += 4;
     920     
     921     box4stco.entry_count = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     922 
     923     data += 4;
     924 
     925     for (i=0; i<box4stco.entry_count; i++)
     926     {
     927         if (i == MAX_STCO_ENTRY_NUM)
     928         {
     929             break;
     930         }
     931         
     932         box4stco.entrys[i].chunk_offset = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
     933         
     934         data += 4;
     935     }
     936     
     937 #ifdef PRINTF_DEBUG
     938     printf("		entry_count: %d, [chunk_offset]: ", box4stco.entry_count);
     939     
     940     if (box4stco.entry_count>MAX_STCO_ENTRY_NUM)
     941     {
     942         box4stco.entry_count = MAX_STCO_ENTRY_NUM;
     943     }
     944     
     945     for (i=0; i<box4stco.entry_count; i++)
     946     {
     947         if (i>0)
     948         {
     949             printf(", ");
     950         }
     951         
     952         printf("[%d]", box4stco.entrys[i].chunk_offset);
     953     }
     954     
     955     if (box4stco.entry_count==MAX_STCO_ENTRY_NUM)
     956     {
     957         printf("...(just show %d now)", MAX_STCO_ENTRY_NUM);
     958     }
     959 
     960     printf("
    ");
     961 #endif
     962 }
     963 
     964 static void DealBox4stbl(const T_BOX *box)
     965 {
     966     int boxSize = 0;
     967     int stblDataSize = 0;
     968     
     969     unsigned char *stblData = NULL;
     970     unsigned char *data = NULL;
     971     
     972     char boxType[MAX_BOX_TYPE_LEN+1] = {0};
     973 
     974     stblData = box->boxData;
     975     stblDataSize = box->boxHeader.boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN;
     976     
     977     while (stblDataSize > 0)
     978     {
     979         boxSize = stblData[0] << 24 | stblData[1] << 16 | stblData[2] << 8 | stblData[3];
     980         
     981         memcpy(boxType, stblData+MAX_BOX_SIZE_LEN, 4);
     982 
     983 #ifdef PRINTF_DEBUG
     984     printf("					****BOX: Layer6****
    ");
     985     printf("						size: %d
    ", boxSize);
     986     printf("						type: %s
    ", boxType);
     987 #endif
     988 
     989         if (0 == strcmp(boxType, BOX_TYPE_STTS))
     990         {
     991             data = (unsigned char*)malloc(boxSize);
     992             if (data)
     993             {
     994                 memcpy(data, stblData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
     995 
     996                 DealBox4stts(data);
     997 
     998                 free(data);
     999                 data = NULL;
    1000             }
    1001         }
    1002         else if (0 == strcmp(boxType, BOX_TYPE_STSS))
    1003         {
    1004             data = (unsigned char*)malloc(boxSize);
    1005             if (data)
    1006             {
    1007                 memcpy(data, stblData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1008 
    1009                 DealBox4stss(data);
    1010 
    1011                 free(data);
    1012                 data = NULL;
    1013             }
    1014         }
    1015         else if (0 == strcmp(boxType, BOX_TYPE_STSC))
    1016         {
    1017             data = (unsigned char*)malloc(boxSize);
    1018             if (data)
    1019             {
    1020                 memcpy(data, stblData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1021 
    1022                 DealBox4stsc(data);
    1023 
    1024                 free(data);
    1025                 data = NULL;
    1026             }
    1027         }
    1028         else if (0 == strcmp(boxType, BOX_TYPE_STSZ))
    1029         {
    1030             data = (unsigned char*)malloc(boxSize);
    1031             if (data)
    1032             {
    1033                 memcpy(data, stblData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1034 
    1035                 DealBox4stsz(data);
    1036 
    1037                 free(data);
    1038                 data = NULL;
    1039             }
    1040         }
    1041         else if (0 == strcmp(boxType, BOX_TYPE_STCO))
    1042         {
    1043             data = (unsigned char*)malloc(boxSize);
    1044             if (data)
    1045             {
    1046                 memcpy(data, stblData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1047 
    1048                 DealBox4stco(data);
    1049 
    1050                 free(data);
    1051                 data = NULL;
    1052             }
    1053         }
    1054 
    1055         stblData += boxSize;
    1056         stblDataSize -= boxSize;
    1057     }
    1058 }
    1059 
    1060 static void DealBox4mdhd(const unsigned char *mdhdData)
    1061 {
    1062     unsigned char *data = NULL;
    1063     
    1064     T_BOX4MDHD box4mdhd = {0};
    1065     
    1066     memset(&box4mdhd, 0x0, sizeof(box4mdhd));
    1067     
    1068     data = (unsigned char *)mdhdData;
    1069     
    1070     data += 4;
    1071     box4mdhd.creation_time = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
    1072     
    1073     data += 4;
    1074     box4mdhd.modification_time = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
    1075     
    1076     data += 4;
    1077     box4mdhd.timescale = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
    1078 
    1079     data += 4;
    1080     box4mdhd.duration = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
    1081     
    1082     data += 4;
    1083     box4mdhd.language = data[0] << 8 | data[1];
    1084 
    1085 #ifdef PRINTF_DEBUG
    1086     //printf("			creation_time: %d, modification_time: %d, timescale: %d, duration: %d, language: %c%c%c
    ",
    1087             //box4mdhd.creation_time, box4mdhd.modification_time, box4mdhd.timescale, box4mdhd.duration, (box4mdhd.language>>10&0x1f), (box4mdhd.language>>5&0x1f), (box4mdhd.language&0x1f));
    1088 
    1089     printf("				creation_time: %d, modification_time: %d, timescale: %d, duration: %d, language:%d
    ",
    1090             box4mdhd.creation_time, box4mdhd.modification_time, box4mdhd.timescale, box4mdhd.duration, box4mdhd.language);
    1091 #endif
    1092 }
    1093 
    1094 static void DealBox4hdlr(const unsigned char *hdlrData)
    1095 {
    1096     int i = 0;
    1097     
    1098     unsigned char *data = NULL;
    1099     
    1100     T_BOX4HDLR box4hdlr = {0};
    1101     
    1102     memset(&box4hdlr, 0x0, sizeof(box4hdlr));
    1103     
    1104     data = (unsigned char *)hdlrData;
    1105     
    1106     data += 4;
    1107     data += 4;
    1108     
    1109     memcpy(box4hdlr.handler_type, data, 4);
    1110     
    1111     box4hdlr.handler_type[MAX_HANDLER_TYPE_LEN] = '';
    1112     
    1113     data += 4;
    1114     
    1115     data += 12;
    1116     
    1117     while ('' != data[i])
    1118     {
    1119         i++;
    1120     }
    1121     
    1122     memcpy(box4hdlr.name, data, i);
    1123     
    1124     box4hdlr.name[MAX_HDLR_NAME_LEN] = '';
    1125     
    1126 #ifdef PRINTF_DEBUG
    1127     printf("				handler_type: %s, name: %s
    ", box4hdlr.handler_type, box4hdlr.name);
    1128 #endif
    1129 }
    1130 
    1131 static void DealBox4vmdhd(const unsigned char *vmdhdData)
    1132 {
    1133     // TODO
    1134 }
    1135 
    1136 static void DealBox4minf(const T_BOX *box)
    1137 {    int boxSize = 0;
    1138     int minfDataSize = 0;
    1139     
    1140     unsigned char *minfData = NULL;
    1141     unsigned char *data = NULL;
    1142     
    1143     char boxType[MAX_BOX_TYPE_LEN+1] = {0};
    1144     
    1145     T_BOX dinfBox = {0};
    1146     T_BOX stblBox = {0};
    1147     
    1148     minfData = box->boxData;
    1149     minfDataSize = box->boxHeader.boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN;
    1150     
    1151     while (minfDataSize > 0)
    1152     {
    1153         boxSize = minfData[0] << 24 | minfData[1] << 16 | minfData[2] << 8 | minfData[3];
    1154         
    1155         memcpy(boxType, minfData+MAX_BOX_SIZE_LEN, 4);
    1156 
    1157 #ifdef PRINTF_DEBUG
    1158     printf("				********BOX: Layer5********
    ");
    1159     printf("					size: %d
    ", boxSize);
    1160     printf("					type: %s
    ", boxType);
    1161 #endif
    1162         if (0 == strcmp(boxType, BOX_TYPE_VMHD))
    1163         {
    1164             data = (unsigned char*)malloc(boxSize);
    1165             if (data)
    1166             {
    1167                 memcpy(data, minfData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1168 
    1169                 DealBox4vmdhd(data);
    1170 
    1171                 free(data);
    1172                 data = NULL;
    1173             }
    1174         }
    1175         else if (0 == strcmp(boxType, BOX_TYPE_DINF))
    1176         {
    1177             memset(&dinfBox, 0x0, sizeof(T_BOX));
    1178 
    1179             dinfBox.boxHeader.boxSize = boxSize;
    1180 
    1181             memcpy(dinfBox.boxHeader.boxType, boxType, strlen(boxType));
    1182 
    1183             dinfBox.boxData = (unsigned char*)malloc(boxSize);
    1184             if (dinfBox.boxData)
    1185             {
    1186                 memcpy(dinfBox.boxData, minfData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1187 
    1188                 DealBox4dinf((const T_BOX*)&dinfBox);
    1189 
    1190                 free(dinfBox.boxData);
    1191                 dinfBox.boxData = NULL;
    1192             }
    1193         }
    1194         else if (0 == strcmp(boxType, BOX_TYPE_STBL))
    1195         {
    1196             memset(&stblBox, 0x0, sizeof(T_BOX));
    1197 
    1198             stblBox.boxHeader.boxSize = boxSize;
    1199 
    1200             memcpy(stblBox.boxHeader.boxType, boxType, strlen(boxType));
    1201 
    1202             stblBox.boxData = (unsigned char*)malloc(boxSize);
    1203             if (stblBox.boxData)
    1204             {
    1205                 memcpy(stblBox.boxData, minfData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1206 
    1207                 DealBox4stbl((const T_BOX*)&stblBox);
    1208 
    1209                 free(stblBox.boxData);
    1210                 stblBox.boxData = NULL;
    1211             }
    1212         }
    1213         
    1214         minfData += boxSize;
    1215         minfDataSize -= boxSize;
    1216     }
    1217 }
    1218 
    1219 static void DealBox4mdia(const T_BOX *box)
    1220 {    int boxSize = 0;
    1221     int mdiaDataSize = 0;
    1222     
    1223     unsigned char *mdiaData = NULL;
    1224     unsigned char *data = NULL;
    1225     
    1226     char boxType[MAX_BOX_TYPE_LEN+1] = {0};
    1227     
    1228     T_BOX minfBox = {0};
    1229     
    1230     mdiaData = box->boxData;
    1231     mdiaDataSize = box->boxHeader.boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN;
    1232     
    1233     while (mdiaDataSize > 0)
    1234     {
    1235         boxSize = mdiaData[0] << 24 | mdiaData[1] << 16 | mdiaData[2] << 8 | mdiaData[3];
    1236         
    1237         memcpy(boxType, mdiaData+MAX_BOX_SIZE_LEN, 4);
    1238 
    1239 #ifdef PRINTF_DEBUG
    1240     printf("			************BOX: Layer4************
    ");
    1241     printf("				size: %d
    ", boxSize);
    1242     printf("				type: %s
    ", boxType);
    1243 #endif
    1244         if (0 == strcmp(boxType, BOX_TYPE_MDHD))
    1245         {
    1246             data = (unsigned char*)malloc(boxSize);
    1247             if (data)
    1248             {
    1249                 memcpy(data, mdiaData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1250 
    1251                 DealBox4mdhd(data);
    1252 
    1253                 free(data);
    1254                 data = NULL;
    1255             }
    1256         }
    1257         else if (0 == strcmp(boxType, BOX_TYPE_HDLR))
    1258         {            
    1259             data = (unsigned char*)malloc(boxSize);
    1260             if (data)
    1261             {
    1262                 memcpy(data, mdiaData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1263 
    1264                 DealBox4hdlr(data);
    1265 
    1266                 free(data);
    1267                 data = NULL;
    1268             }
    1269         }
    1270         else if (0 == strcmp(boxType, BOX_TYPE_MINF))
    1271         {
    1272             memset(&minfBox, 0x0, sizeof(T_BOX));
    1273 
    1274             minfBox.boxHeader.boxSize = boxSize;
    1275 
    1276             memcpy(minfBox.boxHeader.boxType, boxType, strlen(boxType));
    1277 
    1278             minfBox.boxData = (unsigned char*)malloc(boxSize);
    1279             if (minfBox.boxData)
    1280             {
    1281                 memcpy(minfBox.boxData, mdiaData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1282 
    1283                 DealBox4minf((const T_BOX*)&minfBox);
    1284 
    1285                 free(minfBox.boxData);
    1286                 minfBox.boxData = NULL;
    1287             }
    1288         }
    1289         
    1290         mdiaData += boxSize;
    1291         mdiaDataSize -= boxSize;
    1292     }
    1293 }
    1294 
    1295 static void DealBox4trak(const T_BOX *box)
    1296 {
    1297     int boxSize = 0;
    1298     int trakDataSize = 0;
    1299     
    1300     unsigned char *trakData = NULL;
    1301     unsigned char *data = NULL;
    1302     
    1303     char boxType[MAX_BOX_TYPE_LEN+1] = {0};
    1304     
    1305     T_BOX mdiaBox = {0};
    1306     
    1307     trakData = box->boxData;
    1308     trakDataSize = box->boxHeader.boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN;
    1309     
    1310     while (trakDataSize > 0)
    1311     {
    1312         boxSize = trakData[0] << 24 | trakData[1] << 16 | trakData[2] << 8 | trakData[3];
    1313         
    1314         memcpy(boxType, trakData+MAX_BOX_SIZE_LEN, 4);
    1315 
    1316 #ifdef PRINTF_DEBUG
    1317     printf("		****************BOX: Layer3****************
    ");
    1318     printf("			size: %d
    ", boxSize);
    1319     printf("			type: %s
    ", boxType);
    1320 #endif
    1321 
    1322         if (0 == strcmp(boxType, BOX_TYPE_TKHD))
    1323         {
    1324             data = (unsigned char*)malloc(boxSize);
    1325             if (data)
    1326             {
    1327                 memcpy(data, trakData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1328                 
    1329                 DealBox4tkhd(data);
    1330                 
    1331                 free(data);
    1332                 data = NULL;
    1333             }
    1334         }
    1335         else if (0 == strcmp(boxType, BOX_TYPE_MDIA))
    1336         {
    1337             memset(&mdiaBox, 0x0, sizeof(T_BOX));
    1338 
    1339             mdiaBox.boxHeader.boxSize = boxSize;
    1340 
    1341             memcpy(mdiaBox.boxHeader.boxType, boxType, strlen(boxType));
    1342 
    1343             mdiaBox.boxData = (unsigned char*)malloc(boxSize);
    1344             if (mdiaBox.boxData)
    1345             {
    1346                 memcpy(mdiaBox.boxData, trakData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1347 
    1348                 DealBox4mdia((const T_BOX*)&mdiaBox);
    1349 
    1350                 free(mdiaBox.boxData);
    1351                 mdiaBox.boxData = NULL;
    1352             }
    1353         }
    1354         
    1355         trakData += boxSize;
    1356         trakDataSize -= boxSize;
    1357     }
    1358 }
    1359 
    1360 static void DealBox4moov(const T_BOX *box)
    1361 {
    1362     int boxSize = 0;
    1363     int moovDataSize = 0;
    1364     
    1365     unsigned char *moovData = NULL;
    1366     unsigned char *data = NULL;
    1367     
    1368     char boxType[MAX_BOX_TYPE_LEN+1] = {0};
    1369     
    1370     T_BOX trakBox = {0};
    1371     
    1372     moovData = box->boxData;
    1373     moovDataSize = box->boxHeader.boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN;
    1374     
    1375     while (moovDataSize > 0)
    1376     {
    1377         boxSize = moovData[0] << 24 | moovData[1] << 16 | moovData[2] << 8 | moovData[3];
    1378         
    1379         memcpy(boxType, moovData+MAX_BOX_SIZE_LEN, 4);
    1380         
    1381         boxType[MAX_BOX_TYPE_LEN] = '';
    1382     
    1383 #ifdef PRINTF_DEBUG
    1384     printf("	********************BOX: Layer2********************
    ");
    1385     printf("		size: %d
    ", boxSize);
    1386     printf("		type: %s
    ", boxType);
    1387 #endif
    1388 
    1389         if (0 == strcmp(boxType, BOX_TYPE_MVHD))
    1390         {
    1391             data = (unsigned char*)malloc(boxSize);
    1392             if (data)
    1393             {
    1394                 memcpy(data, moovData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1395                 
    1396                 DealBox4mvhd(data);
    1397                 
    1398                 free(data);
    1399                 data = NULL;
    1400             }
    1401         }
    1402         else if (0 == strcmp(boxType, BOX_TYPE_TRAK))
    1403         {
    1404             memset(&trakBox, 0x0, sizeof(T_BOX));
    1405             
    1406             trakBox.boxHeader.boxSize = boxSize;
    1407 
    1408             memcpy(trakBox.boxHeader.boxType, boxType, strlen(boxType));
    1409             
    1410             trakBox.boxData = (unsigned char*)malloc(boxSize);
    1411             if (trakBox.boxData)
    1412             {
    1413                 memcpy(trakBox.boxData, moovData+MAX_BOX_SIZE_LEN+MAX_BOX_TYPE_LEN, boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1414 
    1415                 DealBox4trak((const T_BOX*)&trakBox);
    1416 
    1417                 free(trakBox.boxData);
    1418                 trakBox.boxData = NULL;
    1419             }
    1420         }
    1421         
    1422         moovData += boxSize;
    1423         moovDataSize -= boxSize;
    1424     }
    1425 }
    1426 
    1427 static void DealBox(const T_BOX *box)
    1428 {
    1429 #ifdef PRINTF_DEBUG
    1430     printf("****************************BOX: Layer1****************************
    ");
    1431     printf("	size: %d
    ", box->boxHeader.boxSize);
    1432     printf("	type: %s
    ", box->boxHeader.boxType);
    1433 #endif
    1434     
    1435     if (0 == strcmp(box->boxHeader.boxType, BOX_TYPE_FTYPE))
    1436     {
    1437         DealBox4ftyp(box);
    1438     }
    1439     else if (0 == strcmp(box->boxHeader.boxType, BOX_TYPE_MOOV))
    1440     {
    1441         DealBox4moov(box);
    1442     }
    1443 }
    1444 
    1445 int main(int argc, char *argv[])
    1446 {
    1447     unsigned char boxSize[MAX_BOX_SIZE_LEN] = {0};
    1448     
    1449     FILE *fp = NULL;
    1450 
    1451     T_BOX box = {0};
    1452     
    1453     if (2 != argc)
    1454     {
    1455         printf("Usage: mp4parse **.mp4
    ");
    1456         
    1457         return -1;
    1458     }
    1459     
    1460     fp = fopen(argv[1], "rb");
    1461     if (!fp)
    1462     {
    1463         printf("open file[%s] error!
    ", argv[1]);
    1464         
    1465         return -1;
    1466     }
    1467     
    1468     
    1469     while (1)
    1470     {
    1471         memset(&box, 0x0, sizeof(T_BOX));
    1472         
    1473         if (fread(boxSize, 1, 4, fp) <= 0)
    1474         {
    1475             break;
    1476         }
    1477         
    1478         box.boxHeader.boxSize = boxSize[0] << 24 | boxSize[1] << 16 | boxSize[2] << 8 | boxSize[3];
    1479         
    1480         fread(box.boxHeader.boxType, 1, 4, fp);
    1481         
    1482         box.boxHeader.boxType[MAX_BOX_TYPE_LEN] = '';
    1483         
    1484         box.boxData = (unsigned char*)malloc(box.boxHeader.boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN);
    1485         if (!box.boxData)
    1486         {
    1487             printf("malloc data error!
    ");
    1488             
    1489             break;
    1490         }
    1491         
    1492         fread(box.boxData, 1, box.boxHeader.boxSize-MAX_BOX_SIZE_LEN-MAX_BOX_TYPE_LEN, fp);
    1493         
    1494         /* deal box data */
    1495         DealBox(&box);
    1496         
    1497         /* free box */
    1498         free(box.boxData);
    1499         
    1500         box.boxData = NULL;
    1501     }
    1502     
    1503     fclose(fp);
    1504     
    1505     return 0;
    1506 }
    View Code

       最后如果您觉得本篇对您有帮助,可以打赏下,谢谢!!!

     

     
  • 相关阅读:
    Flutter之CupertinoSwitch和Switch开关组件的简单使用
    docker的/var/run/docker.sock参数
    Elasticsearch _reindex Alias使用
    json_decode的结果是null
    1.1-1.4 hadoop调度框架和oozie概述
    1.8-1.10 大数据仓库的数据收集架构及监控日志目录日志数据,实时抽取之hdfs系统上
    1.6-1.7 定义agent 读取日志存入hdfs
    zabbix监控华为交换机
    1.1-1.5 flume架构概述及安装使用
    1.16 sqoop options-file参数进行运行任务
  • 原文地址:https://www.cnblogs.com/leaffei/p/10463202.html
Copyright © 2011-2022 走看看