- 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 }