ffmpeg源码分析--6.关于mpeg文件格式2之video的track

4750阅读 0评论2016-04-27 wangcong02345
分类:LINUX

1. video的track
主要描述在文件:ISO14496-12中
1.1 video的track如下图所示

1.2 vidoe的track
trak-->tkhd
  1. 6097020:                          0005 bf9d 7472           ....tr
  2. 6097030: 616b 0000 005c 746b 6864 0000 000f 7c25 ak...\tkhd....|%
  3. 6097040: b080 7c25 b080 0000 0001 0000 0000 0014 ..|%............
  4. 6097050: 6595 0000 0000 0000 0000 0000 0000 0000 e...............
  5. 6097060: 0000 0001 0000 0000 0000 0000 0000 0000 ................
  6. 6097070: 0000 0001 0000 0000 0000 0000 0000 0000 ................
  7. 6097080: 0000 4000 0000 01d6 0000 0160 0000 0000 ..@........`....

  8. 0005 bf9d 7472 616b         --> track的长度是0x5bf9d,type=trak
  9. 0000 005c 746b 6864        --> tkhd的长度是0x5c, type=tkhd
  10. 0000 000F                  -->tkhd的version与flag
  11. 7c25 b080 7c25 b080        -->create_time=modify_time=0x7c25b080
  12. 0000 0001                  --> trackID=1
  13. 0000 0000                  --> reserve
  14. 0014 6595                  --> duration=0x146595
  15. 0000 0000                  --> reserved
  16. 0000 0000                  --> reserved
  17. 0000 0000                  --> layer+group
  18. 0000 0000                  --> volum+resever
  19. 0001 0000 0000 0000 0000 0000  --> matrix
  20. 0000 0000 0001 0000 0000 0000
  21. 0000 0000 0000 0000 4000 0000
  22. 01d6 0000 0160 0000         --> width=0x1d6 height=0x160(这儿都需要向右移16位)
1.3 edts-->elst
  1. 6097080:                                    0000               ..
  2. 6097090: 0024 6564 7473 0000 001c 656c 7374 0000 .$edts....elst..
  3. 60970a0: 0000 0000 0001 0014 6595 0000 03e9 0001 ........e.......
  4. 60970b0: 0000
  5. 0000 0024 6564 7473     --> edts的长度为0x24,type=edts
  6. 0000 001c 656c 7374     --> elst的长度为0x1c,type=elst
  7. 0000                    -->version
  8. 0000 0000               -->flag
  9. 0000 0001               -->elst_count=1
  10. 0014 6595               -->segment duration=0x146595
  11. 0000 03e9               -->media time=0x3e9=1001        ;;video的开始时间
  12. 0001 0000               -->rate=0x1000,rate/65536=1.0
计算dts时需要elst中的media_time作为开始的时间,取负-1001,就是开始的时间
以后的时间再累加stts中的sample_duration,就是所有的dts
1.3 mdia-->mdhd
  1. 60970b0: 0005 bf15 6d64 6961 0000 0020 6d64 ....mdia... md
  2. 60970c0: 6864 0000 0000 7c25 b080 7c25 b080 0000 hd....|%..|%....
  3. 60970d0: 5dc2 01e9 9054 15c7 0000
  4. 0005 bf15 6d64 6961     -->mdia的长度=0x5bf15,type=mdia
  5. 0000 0020 6d64 6864     -->mdhd的长度=0x20,type=mdhd
  6. 0000                    -->version=0
  7. 0000                    -->flag=0
  8. 7c25 b080 7c25 b080     -->create_time与modify_time
  9. 0000 5dc2               -->timescale=0x5dc2
  10. 01e9 9054               -->duration=0x1e99054
  11. 15c7                    --->language
  12. 0000                    --> quality
1.4 mdia-->hdlr
  1. 60970d0:                          0000 002d 6864             .-hd
  2. 60970e0: 6c72 0000 0000 0000 0000 7669 6465 0000 lr........vide..
  3. 60970f0: 0000 0000 0000 0000 0000 5669 6465 6f48 ..........VideoH
  4. 6097100: 616e 646c 6572 00 andler.
  5. 0000 002d 6864 6c72         -->hdlr的长度=0x2d,type=hdlr
  6. 0000 0000                   -->version 与 flags
  7. 0000 0000                   -->pre_defined,即现在不用了
  8. 7669 6465         -->type="vide",说明这是一个video的track::ffmpeg中st->codec->codec_type=AVMEDIA_TYPE_VIDEO
  9. 0000 0000                   -->reserved
  10. 0000 0000                   -->reserved
  11. 0000 0000                   -->reserved
  12. 5669 6465 6f48 616e 646c 6572 00 -->name="VideoHandler"
1.4 mdia-->minf-->vmhd
      mdia-->minf-->dinf
  1. 6097100:                  00 05be c06d 696e 6600       .....minf.
  2. 6097110: 0000 1476 6d68 6400 0000 0100 0000 0000 ...vmhd.........
  3. 6097120: 0000 0000 0000 2464 696e 6600 0000 1c64 ......$dinf....d
  4. 6097130: 7265 6600 0000 0000 0000 0100 0000 0c75 ref............u
  5. 6097140: 726c 2000 0000 01                       rl ....
  6. 00 05be c06d 696e 66              -->minf的长度=0x5bec0,type=minf
  7. 00 0000 1476 6d68 64              -->vmhd的长度=0x14,type=vmhd
  8. 00 0000 01                        -->version与flag
  9. 00 00                             -->graphicsmode
  10. 00 0000 0000 00                   -->opcolor
  11. 00 0000 2464 696e 66              -->dinf的长度=0x24,type=dinf
  12. 00 0000 1c64 7265 66              -->dref的长度=0x1c,type=dref
  13. 00 0000 00                        -->version与flag
  14. 00 0000 01                        -->entriy=1
  15. 00 0000 0c                        -->size=0xc
  16. 75 726c 20                        -->type=url
  17. 00 0000 01                        -->url的version与flag
1.4mdia-->minf-->stbl-->stsd-->avcC                                   
                                   -->stts
  1. 6097140:                  00 05be 8073 7462 6c00        ....stbl.
  2. 6097150: 0000 9473 7473 6400 0000 0000 0000 0100 ...stsd.........
  3. 6097160: 0000 8461 7663 3100 0000 0000 0000 0100 ...avc1.........
  4. 6097170: 0000 0000 0000 0000 0000 0000 0000 0001 ................
  5. 6097180: d601 6000 4800 0000 4800 0000 0000 0000 ..`.H...H.......
  6. 6097190: 0100 0000 0000 0000 0000 0000 0000 0000 ................
  7. 60971a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
  8. 60971b0: 0000 18ff ff00 0000 2e61 7663 4301 4d40 .........avcC.M@
  9. 60971c0: 15ff e100 1767 4d40 159a 760f 05bc de02 .....gM@..v.....
  10. 60971d0: 2000 000b 6000 0221 81e2 c5a7 0100 0468 ...`..!.......h
  11. 60971e0: ea8c b200 020b a873 7474 7300 0000 0000 .......stts.....
  12. 60971f0: 0041 7300 0000 0100 0003 e900 0000 0100 .As.............
  13. 6097200: 000b bb                                 ......

  14. 00 05be 8073 7462 6c            -->stbl的长度=0x5be80,type=stbl
  15. 00 0000 9473 7473 64            -->stsd的长度=0x94,type=stsd
  16. 00 0000 00                      -->stsd的version与flag
  17. 00 0000 01                      -->stsd的entries
  18. 00 0000 84                      -->size=0x84
  19. 61 7663 31                      -->format=avc1 ::ffmpeg根据这个format寻找解码器::ffmpeg中st->codec->codec_tag及codec_id
  20. 00 0000 00                      -->reserved
  21. 00 00                           -->reserved
  22. 00 01                           -->dref_id=0x01
  23. 00 00                           -->version
  24. 00 00                           -->version_level
  25. 00 0000 00                      -->vendor
  26. 00 0000 00                      -->temporal
  27. 00 0000 00                      -->spatioal
  28. 01 d601 60                      -->width=0x1d6=470,height=0x160=352 ::ffmpeg中st->codec->width与height
  29. 00 4800 00                      -->72dpi
  30. 00 4800 00                      -->72dpi
  31. 00 0000 00                      -->reserved
  32. 00 01                           -->frame_count=1
  33. 32个00                          -->string
  34. 00 18                           -->depth=0x0018               ::ffmpeg中st->codec->bits_per_coded_sample=0x18=24
  35. ff ff                           -->pre_defined=-1
  36. avcC的读取是在函数mov_read_glbl中
    00 0000 2e61 7663 43     -->avcC的长度=0x2e,type=avcC   
    01 4d40 15               -->将剩余的字节放进extradata中,调用的是:ff_get_extradata


    00 020b a873 7474 73     -->stts的长度=0x20ba8,type=stts
    00 0000 00               -->stts的version与flag
    00 0041 73               -->entries=0x4173=16755    ::剩下的就是sample_count与sample_duration的entry
    00 0000 01               -->sample_count=0x01       ::sample_count=1, sample_duration=1001
    00 0003 e9               -->sample_duration=0x3e9   
    00 0000 01               -->sample_count=0x1        ::sample_count=1, sample_duration=3003
    00 000b bb               -->sample_duration=0xbbb
stts中的entries表存储着所有sample的duration
sample_count*sample_duration这样连加起来就是druation媒体文件的长度
mov_read_stts中有对duration的连加正好是32084052=0x1E99054,total_sam_c=20054
timescale=0x5dc2=24002
注意: audio trak中也有一个stts,但是audio中只有一个entry

mov_read_stsd
    -->ff_mov_read_stsd_entries
        a. 先读取format=0x31637661="avc1"
        b. mov_code_id中查表ff_codec_movvideo_tags发现avc1对应AV_CODEC_ID_H264
        c. 最后把AV_CODEC_ID_H264做为st->codec->codec_id

1.4mdia-->minf-->stbl-->stss
  1. 60b7d80:                            00 0002 0473 ...............s
  2. 60b7d90: 7473 7300 0000 0000 0000 7d00 0000 0100 tss.......}.....
  3. 60b7da0: 0000 2100 0000 4000 0001 3600 0002 3000 ..!...@...6...0.
  4. 00 0002 0473 7473              -->stss的长度=0x204,type=stss
  5. 00 0000 00                     -->stss的version与flag
  6. 00 0000 7d                     -->stss的entries=0x7d
  7. 00 0000 01                     -->keyframes[0]=1
  8. 00 0000 21                     -->keyframes[1]=0x21=33
"stss"确定媒体文件中的关键帧。关键帧是解压缩时不依赖其它的帧,而后续帧的解压缩将依赖于这个关键帧。
1.4mdia-->minf-->stbl-->ctts
  1. 60b7f80: 00 .
  2. 60b7f90: 013d 4863 7474 7300 0000 0000 0027 a700 .=Hctts......'..
  3. 60b7fa0: 0000 0100 0003 e900 0000 0100 001f 4800 ..............H.
  4. 60b7fb0: 0000 0300 0000 0000 0000 0100 0017 7600 ..............v.
  5. 00 013d 4863 7474 73           -->ctts的长度=0x204,type=ctts
  6. 00 0000 00                     -->ctts的version与flag
  7. 00 0027 a7                     -->ctts的entries=0x27a7=10151  ::一共10151个
  8. 00 0000 01                     -->count=0x01
  9. 00 0003 e9                     -->duration=0x3e9
  10. 00 0000 01                     -->count=0x1
  11. 00 001f 48                     -->duration=0x1f48
  12. ....
1.4mdia-->minf-->stbl-->stsc-->stsz
  1. 60cbcd0:                  00 0000 1c73 7473 6300        ....stsc.
  2. 60cbce0: 0000 0000 0000 0100 0000 0100 0000 0100 ................
  3. 60cbcf0: 0000 0100 0139 6c73 7473 7a00 0000 0000 .....9lstsz.....
  4. 60cbd00: 0000 0000 004e 5600 0013 3300 000f 6f00 .....NV...3...o.
  5. 60cbd10: 0009 9100 0009 ab00 0008 e400 0015 0200 ................
  6. 60cbd20: 0007 af00 000a a800 0008 8000 001d 2000 .............. .
  7. 00 0000 1c73 7473 63           -->stsc的长度=0x1c,type=stsc
  8. 00 0000 00                     -->stsc的version与flag
  9. 00 0000 01                     -->stsc的entries=0x01
  10. 00 0000 01                     -->first=0x01
  11. 00 0000 01                     -->count=0x01
  12. 00 0000 01                     -->id=0x01
  13. 00 0139 6c73 7473 7a           -->stsz的长度=0x1396c,type=stsz
  14. 00 0000 00                     -->stsz的version与flag
  15. 00 0000 00                     -->stsc的sample_size=0x0
  16. 00 004e 56                     -->stsc的sample_count=0x4e56=20054
  17. 00 0013 33                     -->sample_sizes[0]=0x1333
  18. 00 000f 6f                     -->sample_sizes[1]=0xf6f
  19. ...
"stsz"定义了每个sample的大小,包括sample的数目和一个内容是每个sample的大小的表。
例如:sample_sizes[0]=0x1333,即视频的第0个sample的长度=0x1333(byte)
1.4 mdia-->minf-->stbl-->stco
  1. 60df650:                                      00                .
  2. 60df660: 0139 6873 7463 6f00 0000 0000 004e 5600 .9hstco......NV.
  3. 60df670: 0000 3000 0013 7d00 0025 3c00 0031 4300 ..0...}..%<..1C.
  4. 00 0139 6873 7463 6f           -->stco的长度=0x13968,type=stco
  5. 00 0000 00                     -->stco的version与flag
  6. 00 004e 56                     -->stco的entries=0x4e56
  7. 00 0000 30                     -->chunk_offsets[0]=0x30
  8. 00 0013 7d                     -->chunk_offsets[1]=0x137d   
  9. ....
"stco"定义了每个thunk在媒体流中的位置,音频与视频流都有一个stco表
这儿是video的stco,里面的内容是chunk_offsets,即每个视频sample在文件中的偏移
例如:chunk_offsets[0]=0x30,长度通过stsz中的sample_sizes[0]=0x1333确定。
也就是说从san.mp4这个文件的0x30处读取0x1333个字节的数据,就是视频的第0个sample的数据

上一篇:ffmpeg源码分析--5.avio分析
下一篇:ffmpeg源码分析--7.关于mpeg文件格式3之audio的track