C++音视频

代码改变世界

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

flv文件格式协议见上一篇文章:flv格式

flv分析工具

flvmeta:flvmeta.com,flvmeta是一个可以操作flv文件格式的命令行工具。

1. 分析文件准备

我去网上下载了一个MP4文件,这个文件有300MB,太大了,winhex打开不方便,我使用ffmpeg截取了前面的10s片段,截断命令

ffmpeg -i 1.mp4 -t 10 -c:v copy -c:a copy cut.mp4

然后转成flv格式

ffmpeg -i cut.mp4 -c:v copy -c:a copy demo.flv

为了方便分析视频数据,从MP4文件中提取了h264裸流,以方便对比,提取命令如下

ffmpeg -i cut.mp4 -an -vcodec copy -bsf:v h264_mp4toannexb -f h264 demo.h264

这样就方便分析了。这里使用winhex进行二进制方式查看。

2. flv 文件头

flv header

flv文件头是9个字节,介绍见 flv格式 第 1 小节。
前三个字节为 "FLV" 字符串;version为 1 ;0x05表示既有音频也有视频;后续 4 字节表示flv头的长度为 9 。

3. flv body

9字节的flv头之后的数据都是flv body。flv body 由一个一个的tag连续组成。介绍见 flv格式 第 2.1 小节。

3.1 script tag

  • tag的前 4 个字节表示前一个tag的长度,由于这是第一个tag,所以前一个tag的长度为 0
  • 0x12 = 18, 表示这是一个 script data
  • Datasize 00 01 99 表示数据长度为0x000199(409),从StreamID之后开始计算,
  • DataSize之后是 4 字节的时间戳和扩展时间戳,均为 0
  • 之后是标蓝色的 3 字节 StreamID,为 0
  • 最后是长达409字节的 script data,内容暂没关注

3.2 video tag

接着上一个tag,从地址编译00000433开始

  • 红色 4 字节, 前一个tag的长度,0x000001A4 (420), 前一个tag的长度 11 + 409
  • 蓝色 09, TagType,表示是video tag
  • 00 00 31 DataSize, 0x31(49)
  • 时间戳和扩展时间戳都是 0
  • StreamID 为 0
  • TagType = 9, 紧跟着5个字节的视频tag头,详细介绍见 flv格式 第 2.3.1 小节。0x17表示,Frame Type = 1 关键帧,CodecID = 7 编码格式 AVC(H264); AVCPacketType = 0 后续数据是序列头;3个字节的 CompositionTime 为 0
  • 后续从 453 - 496 长度 44 字节的数据是 AVC 的 AVCDecoderConfigurationRecord(介绍见flv格式 第 2.3.2 小节)。

AVCDecoderConfigurationRecord 数据说明:

  1. 01, 第一个字节, configurationVersion 始终为 1;
  2. 64 00 32 分别是 AVCProfileIndication,profile_compatibility,AVCLevelIndication,是H264 SPS 的前3个字节;
  3. FF, lengthSizeMinusOne = b11,(lengthSizeMinusOne + 1)表示NALU前缀的长度(单位字节),此处是 4 。即是 H264 编码的每一个NALU前面用4字节表示这个NALU的长度。h264只是定义了编码方式,但是没有定义编码出来的nalu怎么存储。存储编码出来的nalu有两种方法,一种是在每一个nalu前面加上000001或者00000001,这种方法叫annexB;另一种就是在每一个nalu前面加上长度值,可以是 1 ,2,3, 4个字节,这种方式叫 avcc (h265这种存储方式叫hvcc);
  4. E1,numOfSequenceParameterSets = 1, 表示后续有一个SPS参数集,紧跟两个字节的 SPS 参数集长度 (00 1B),后续就是 27 个字节的SPS,对照右图,67 64 00 32 AC 56 24 07 80 67 FA C0 44 00 00 03 00 04 00 00 03 00 C0 3C 60 C6 26 是SPS;
  5. 01, numOfPictureParameterSets = 1, 表示后续有一个PPS参数集,紧跟两个字节的 SPS 参数集长度 (00 06), 后面是 6 个字节的 PPS, 68 E8 8E CB 22 C0

继续分析video tag

  • 前一个tag长度 0x00000012
  • 09 video tag
  • DataSize 0x0052A4
  • 时间戳和扩展时间戳都是 0
  • 0x17 关键帧,编码为AVC
  • AVCPacketType = 1, 这是一个AVC NALU
  • CompositionTime 为 00 00 53
  • 黑色的 4 字节是nalu的长度,000002BF(703)
  • 紧跟着是nalu,nalu第一字节 06 表示这是一个 SEI 帧;

3.3 audio tag

  • 蓝色 08, 表示是audio tag
  • Datasize 是 7
  • 黑色两个字节 AF 00 是audio tag头,SoundFormat = 10 编码格式为 aac,SoundRate = 3 采样率是44KHz, SoundSize = 1 采样位数16bit,SoundType = 1 立体声;AACPacketType = 0, 表述数据是aac序列头;audio tag头介绍见flv格式 第 2.2.1 小节
  • 后面5个字节是aac序列头:
posted on 2022-02-23 14:23  shunxiang  阅读(462)  评论(0编辑  收藏  举报