当前位置: 移动技术网 > IT编程>开发语言>C/C++ > mp4文件解析(纯c解析代码)

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

2019年03月03日  | 移动技术网IT编程  | 我要评论

月经期间同房有什么危害,史莱姆大战萝莉,牛郎小情人

   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

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网