mp4文件解析(纯c解析代码)
程序员文章站
2022-06-01 08:52:05
1 #include 2 #include 3 #include 4 5 #define PRINTF_DEBUG 6 7 #define BOX_TYPE_FTYPE "ftyp" 8 #define BOX_TYPE_MOOV "m ......
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 }
上一篇: MySQL数据库级别的外键
下一篇: RMAN优缺点及RMAN备份及恢复步骤