leaffei

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

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

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

   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 #include <string.h>
   4 
   5 #define PRINTF_DEBUG
   6 
   7 #define BOX_TYPE_FTYPE "ftyp"
   8 #define BOX_TYPE_MOOV "moov"
   9 #define BOX_TYPE_MVHD "mvhd"
  10 #define BOX_TYPE_TRAK "trak"
  11 #define BOX_TYPE_TKHD "tkhd"
  12 #define BOX_TYPE_EDTS "edts"
  13 #define BOX_TYPE_MDIA "mdia"
  14 #define BOX_TYPE_MDHD "mdhd"
  15 #define BOX_TYPE_HDLR "hdlr"
  16 #define BOX_TYPE_MINF "minf"
  17 #define BOX_TYPE_VMHD "vmhd"
  18 #define BOX_TYPE_DINF "dinf"
  19 #define BOX_TYPE_DREF "dref"
  20 #define BOX_TYPE_STBL "stbl"
  21 #define BOX_TYPE_STSD "stsd"
  22 #define BOX_TYPE_STTS "stts"
  23 #define BOX_TYPE_STSS "stss"
  24 #define BOX_TYPE_STSC "stsc"
  25 #define BOX_TYPE_STSZ "stsz"
  26 #define BOX_TYPE_STCO "stco"
  27 #define BOX_TYPE_UDTA "udta"
  28 
  29 #define MAX_BOX_SIZE_LEN 4
  30 #define MAX_BOX_TYPE_LEN 4
  31 #define MAX_HANDLER_TYPE_LEN 4
  32 #define MAX_FTYP_BRABDS_LEN 4
  33 #define MAX_FTYP_BRABDS_NUM 4
  34 #define MAX_STTS_ENTRY_NUM 8
  35 #define MAX_STSS_ENTRY_NUM 8
  36 #define MAX_STSC_ENTRY_NUM 100
  37 #define MAX_STSZ_ENTRY_NUM 100 /* now parse 100 frame */
  38 #define MAX_STCO_ENTRY_NUM 100 
  39 #define MAX_MVHD_RESERVED_LEN 10
  40 #define MAX_PRE_DEFINE_LEN 24
  41 #define MAX_MATRIX_LEN 36
  42 #define MAX_HDLR_NAME_LEN 100
  43 
  44 
  45 typedef struct t_box_header
  46 {
  47     int boxSize;
  48     
  49     unsigned char boxType[MAX_BOX_TYPE_LEN+1];
  50     
  51     long largeBoxSize; /* if boxSize=1 use, if boxSize=0, end of file */
  52 } T_BOX_HEADER;
  53 
  54 /********************************************************************************************
  55 **                            File Type Box (ftyp): file type, 表明文件类型
  56 **
  57 --------------------------------------------------------------------------------------------
  58 **        字段名称              |    长度(bytes)   |        有关描述
  59 --------------------------------------------------------------------------------------------
  60 **        boxsize               |    4            |        box的长度
  61 **        boxtype               |    4            |        box的类型
  62 **        major_brand           |    4            |
  63 **        minor_version         |    4            |        版本号
  64 **        compatible_brands     |    4 * N        |        本文件遵从的多种协议(ismo, iso2, mp41)
  65 ********************************************************************************************/
  66 typedef struct t_box4ftyp_brand
  67 {
  68     unsigned char brands[MAX_FTYP_BRABDS_LEN+1];
  69 } T_BOX4FTYP_BRAN;
  70 
  71 typedef struct t_box4ftyp
  72 {
  73     unsigned char major_brand[MAX_FTYP_BRABDS_LEN+1];
  74     
  75     int minor_version;
  76     
  77     T_BOX4FTYP_BRAN compatible_brands[MAX_FTYP_BRABDS_NUM];
  78 } T_BOX4FTYP;
  79 
  80 /************************************************************************************************************
  81 **                                            mvhd: movie header, 文件的总体信息: 时长, 创建时间等
  82 **
  83 --------------------------------------------------------------------------------------------
  84 **        字段名称              |    长度(bytes)   |        有关描述
  85 --------------------------------------------------------------------------------------------
  86 **        boxsize               |    4            |        box的长度
  87 **        boxtype               |    4            |        box的类型
  88 **        version               |    1            |        box版本,0或1,一般为0(以下字节数均按version = 0)
  89 **        flags                 |    3            |        
  90 **        creation time         |    4            |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
  91 **        modification time     |    4            |        修改时间
  92 **        time scale            |    4            |        文件媒体在1秒时间内的刻度值,可以理解为1秒长度的时间单元数
  93 **        duration              |    4            |        该track的时间长度,用duration和time scale值可以计算track时长
  94 **        rate                  |    4            |        推荐播放速率,高16位和低16位分别为小数点整数部分和小数部分,即[16.16] 格式.该值为1.0 (0x00010000)
  95 **        volume                |    2            |        与rate类似,[8.8] 格式,1.0(0x0100)表示最大音量
  96 **        reserved              |    10           |        保留位
  97 **        matrix                |    36           |        视频变换矩阵
  98 **        pre-defined           |    24           |        
  99 **        next track id         |    4            |        下一个track使用的id号
 100 ** 
 101 if (version==1) 
 102 {
 103     unsigned int(64) creation_time;
 104     unsigned int(64) modification_time;
 105     unsigned int(32) timescale;
 106     unsigned int(64) duration;
 107 } 
 108 else 
 109 {
 110     unsigned int(32) creation_time;
 111     unsigned int(32) modification_time;
 112     unsigned int(32) timescale;
 113     unsigned int(32) duration;
 114 }
 115 ************************************************************************************************************/
 116 typedef struct t_box4mvhd
 117 {
 118     int creation_time;
 119     int modification_time;
 120     int timescale;
 121     int duration;
 122     float rate;
 123     float volume;
 124     int next_track_id;
 125 } T_BOX4MVHD;
 126 
 127 /************************************************************************************************************
 128 **                                        tkhd: track header, track的总体信息, 如时长, 宽高等
 129 **
 130 -------------------------------------------------------------------------------------------------------------
 131 **        字段名称               |    长度(bytes)   |        有关描述
 132 -------------------------------------------------------------------------------------------------------------
 133 **        boxsize                |    4            |        box的长度
 134 **        boxtype                |    4            |        box的类型
 135 **        version                |    1            |        box版本,0或1,一般为0。(以下字节数均按version = 0)
 136 **        flags                  |    3            |        按位或操作结果值,预定义如下;
 137                                                          0x000001 track_enabled,否则该track不被播放;
 138                                                          0x000002 track_in_movie,表示该track在播放中被引用;
 139                                                          0x000004 track_in_preview,表示该track在预览时被引用。
 140                                                          一般该值为7,如果一个媒体所有track均未设置track_in_movie和track_in_preview,将被理解为所有track均设置了这两项;
 141                                                          对于hint track,该值为0;
 142 **        creation_time          |    4            |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
 143 **        modification_time      |    4            |        修改时间
 144 **        track_id               |    4            |        id号 不能重复且不能为0
 145 **        reserved               |    4            |        保留位
 146 **        duration               |    4            |        track的时间长度
 147 **        reserved               |    8            |        保留位
 148 **        layer                  |    2            |        视频层,默认为0,值小的在上层
 149 **        alternate_group        |    2            |        track分组信息,默认为0表示该track未与其他track有群组关系
 150 **        volume                 |    2            |        [8.8] 格式,如果为音频track,1.0(0x0100)表示最大音量;否则为0
 151 **        reserved               |    2            |        保留位
 152 **        matrix                 |    36           |        视频变换矩阵
 153 **        width                  |    4            |        宽
 154 **        height                 |    4            |        高,均为[16.16] 格式值 与sample描述中的实际画面大小比值,用于播放时的展示宽高
 155 if (version==1) 
 156 {
 157     unsigned int(64) creation_time;
 158     unsigned int(64) modification_time;
 159     unsigned int(32) track_ID;
 160     const unsigned int(32) reserved = 0;
 161     unsigned int(64) duration;
 162 } 
 163 else 
 164 {
 165     unsigned int(32) creation_time;
 166     unsigned int(32) modification_time;
 167     unsigned int(32) track_ID;
 168     const unsigned int(32) reserved = 0;
 169     unsigned int(32) duration;
 170 }
 171 ************************************************************************************************************/
 172 typedef struct t_box4tkhd
 173 {
 174     int flags;
 175     int creation_time;
 176     int modification_time;
 177     int track_id;
 178     int duration;
 179     int layer;
 180     int alternate_group;
 181     float volume;
 182     float width;
 183     float height;
 184 } T_BOX4TKHD;
 185 
 186 /************************************************************************************************************
 187 **                                        mdhd: 包含了了该track的总体信息, mdhd和tkhd 内容大致都是一样的.
 188 **
 189 -------------------------------------------------------------------------------------------------------------
 190 **        字段名称              |      长度(bytes)   |        有关描述
 191 -------------------------------------------------------------------------------------------------------------
 192 **        boxsize               |    4                |        box的长度
 193 **        boxtype               |    4                |        box的类型
 194 **        version               |    1         |        box版本0或1 一般为0 (以下字节数均按version=0)
 195 **        flags                 |    3                |        
 196 **        creation_time         |    4                |        创建时间(相对于UTC时间1904 - 01 - 01零点的秒数)
 197 **        modification_time     |    4                |        修改时间
 198 **        time_scale            |    4                |        
 199 **        duration              |    4               |        track的时间长度
 200 **        language              |    2               |        媒体语言码,最高位为0 后面15位为3个字符[见ISO 639-2/T标准中定义]
 201 **        pre-defined           |    2                |        保留位
 202 
 203 ** tkhd通常是对指定的track设定相关属性和内容, 而mdhd是针对于独立的media来设置的, 一般情况下二者相同.
 204 ************************************************************************************************************/
 205 typedef struct t_box4mdhd
 206 {
 207     int creation_time;
 208     int modification_time;
 209     int timescale;
 210     int duration;
 211     short language;
 212 } T_BOX4MDHD;
 213 
 214 /************************************************************************************************************
 215 **                                        hdlr: Handler Reference Box, 媒体的播放过程信息, 该box也可以被包含在meta box(meta)中
 216 **
 217 -------------------------------------------------------------------------------------------------------------
 218 **        字段名称               |    长度(bytes)    |        有关描述
 219 -------------------------------------------------------------------------------------------------------------
 220 **        boxsize                |    4             |        box的长度
 221 **        boxtype                |    4             |        box的类型
 222 **        version                |    1             |        box版本0或1 一般为0 (以下字节数均按version=0)
 223 **        flags                  |    3             |
 224 **        pre-defined            |    4             |
 225 **        handler type           |    4             |        在media box中,该值为4个字符
 226                                                           "vide"— video track
 227                                                           "soun"— audio track
 228                                                           "hint"— hint track
 229 **        reserved               |    12            |
 230 **        name                   |    不定           |        track type name,以‘\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

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

 

 

 

posted on 2019-03-02 21:58  leaffei  阅读(8029)  评论(0编辑  收藏  举报

导航