欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mp4文件解析(纯c解析代码)

程序员文章站 2023-10-28 17:29:04
1 #include 2 #include 3 #include 4 5 #define PRINTF_DEBUG 6 7 #define BOX_TYPE_FTYPE "ftyp" 8 #define BOX_TYPE_MOOV "m ......
mp4文件解析(纯c解析代码)
   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,以‘\0’结尾的字符串
 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] = '\0';
 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 '\0', 每个brands的内存是连续的, 导致打印时后面的每4个数据都会加到前面;
 485        2. unsigned char brands[max_ftyp_brabds_len+1]; 可解决, 此时也不必加'\0', 但需初始化;
 486        3. 因此字符串最好定义+1并赋'\0';
 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] = '\0';
 494     }
 495 
 496 #ifdef printf_debug
 497     printf("\tmajor_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("\n");
 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("\t\tcreation_time: %d, modification_time: %d, timescale: %d, duration: %d, rate: %f, volume: %f, next_track_id: %d\n",
 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("\t\t\tflags: %d, creation_time: %d, modification_time: %d, track_id: %d, duration: %d, layer: %d, alternate_group: %d, volume: %f, width: %f, height: %f\n",
 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("\t\t\t\t\t****box: layer6****\n");
 635     printf("\t\t\t\t\t\tsize: %d\n", boxsize);
 636     printf("\t\t\t\t\t\ttype: %s\n", 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("\t\t\tentry_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("\n");
 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("\t\t\tentry_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("\n");
 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("\t\t\tentry_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("\n");
 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("\t\t\tsample_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("\n");
 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("\t\t\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("\n");
 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("\t\t\t\t\t****box: layer6****\n");
 985     printf("\t\t\t\t\t\tsize: %d\n", boxsize);
 986     printf("\t\t\t\t\t\ttype: %s\n", 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("\t\t\tcreation_time: %d, modification_time: %d, timescale: %d, duration: %d, language: %c%c%c\n",
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("\t\t\t\tcreation_time: %d, modification_time: %d, timescale: %d, duration: %d, language:%d\n",
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] = '\0';
1112     
1113     data += 4;
1114     
1115     data += 12;
1116     
1117     while ('\0' != data[i])
1118     {
1119         i++;
1120     }
1121     
1122     memcpy(box4hdlr.name, data, i);
1123     
1124     box4hdlr.name[max_hdlr_name_len] = '\0';
1125     
1126 #ifdef printf_debug
1127     printf("\t\t\t\thandler_type: %s, name: %s\n", 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("\t\t\t\t********box: layer5********\n");
1159     printf("\t\t\t\t\tsize: %d\n", boxsize);
1160     printf("\t\t\t\t\ttype: %s\n", 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("\t\t\t************box: layer4************\n");
1241     printf("\t\t\t\tsize: %d\n", boxsize);
1242     printf("\t\t\t\ttype: %s\n", 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("\t\t****************box: layer3****************\n");
1318     printf("\t\t\tsize: %d\n", boxsize);
1319     printf("\t\t\ttype: %s\n", 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] = '\0';
1382     
1383 #ifdef printf_debug
1384     printf("\t********************box: layer2********************\n");
1385     printf("\t\tsize: %d\n", boxsize);
1386     printf("\t\ttype: %s\n", 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****************************\n");
1431     printf("\tsize: %d\n", box->boxheader.boxsize);
1432     printf("\ttype: %s\n", 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\n");
1456         
1457         return -1;
1458     }
1459     
1460     fp = fopen(argv[1], "rb");
1461     if (!fp)
1462     {
1463         printf("open file[%s] error!\n", 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] = '\0';
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!\n");
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