mp4文件解析(纯c解析代码)
参考链接:1. mp4文件格式解析 https://www.cnblogs.com/ranson7zop/p/7889272.html
View Code
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 }
最后如果您觉得本篇对您有帮助,可以打赏下,谢谢!!!