FLV文件中VideoPacket的详解

众所周知,FLV文件体主要有三种Tag组成:AUDIODATA、VIDEODATA和SCRIPTDATA,其中SCRIPTDATA中包含了MetaData,通过解析这些元数据,可以得到解码器的初始化信息,如音频解码元数据audiocodecid、audiodatarate、audiodelay、audiosamplerate、audiosamplesize、stereo,视频解码元数据videocodecid、framerate、height、width、videodatarate等信息。这些信息里面有的对于初始化解码器非常有用,例如解码器必须知道codecid,才能进行初始化从操作,视频解码器初始化时有的需要知道图像宽高信息,才能对解码重建Buffer进行初始化。

某些FLV文件,在SCRIPTDATA的MetaData中并未给出相应信息,这样就需要对AUDIODATA、VIDEODATA进行解析。Adobe Flash Video File Format Specification中只是简单交代了AVCVIDEOPACKET的格式。对其他的codecID对应的VideoPacket并未详细介绍。本文专门针对视频解码初始化过程中需要的width和height信息的深入解析为例,详细介绍一些VideoPacket。因为FLV的VideoPacket的格式和SWF文件离得VideoPacket格式基本一致,也可以参考SWF File Format Specification。详见http://www.adobe.com/go/swf_file_format。

1、VideoTagBody

IF FrameType == 5

UI8

ELSE (

IF CodecID == 2

H263VIDEOPACKET                            //Sorensen H263

IF CodecID == 3

SCREENVIDEOPACKET              //Screen

IF CodecID == 4

VP6FLVVIDEOPACKET               //On2 Vp6

IF CodecID == 5

VP6FLVALPHAVIDEOPACKET  //On2 VP6 alpha

IF CodecID == 6

SCREENV2VIDEOPACKET                  //Screen V2

IF CodecID == 7

AVCVIDEOPACKET                     //AVC

)

2、H263VIDEOPACKET

这里的H263是Sorenson H263,对ITU-T的H.263进行了订制,所以在picture层和MB层的header的格式发生了改动,且GOB层被删除。其具体格式为:

表格 1 H263VIDEOPACKET

Field

Type

Comment

PictureStartCode

UB[17]

Similar to H.263 5.1.1
0000 0000 0000 0000 1

Version

UB[5]

Video format version
Flash Player 6 supports 0 and 1

TemporalReference

UB[8]

See H.263 5.1.2

PictureSize

UB[3]

000: custom, 1 byte
001: custom, 2 bytes
010: CIF (352x288)
011: QCIF (176x144)
100: SQCIF (128x96)
101: 320x240
110: 160x120
111: reserved

CustomWidth

If PictureSize = 000, UB[8]
If PictureSize = 001, UB[16]
Otherwise absent
Note: UB[16] is not the same
as UI16; there is no byte
swapping.

Width in pixels

CustomHeight

If PictureSize = 000, UB[8]
If PictureSize = 001, UB[16]
Otherwise absent
Note: UB[16] is not the same
as UI16; there is no byte
swapping.

Height in pixels

PictureType

UB[2]

00: intra frame
01: inter frame
10: disposable inter frame
11: reserved

DeblockingFlag

UB[1]

Requests use of deblocking
filter (advisory only, Flash
Player may ignore)

Quantizer

UB[5]

See H.263 5.1.4

ExtraInformationFlag

UB[1]

See H.263 5.1.9

ExtraInformation

If ExtraInformationFlag = 1,
UB[8]
Otherwise absent

See H.263 5.1.10

...

The ExtraInformationFlag-
ExtraInformation sequence
repeats until an
ExtraInformationFlag of 0 is
encountered

Macroblock

MACROBLOCK

See following

PictureStuffing

varies

See H.263 5.1.13

从上表可以得出,不用深入到macroblock层,只需解析头部,就可很简单的得到width和height信息。

2、SCREENVIDEOPACKET和SCREENV2VIDEOPACKET

Screen Video是一个简单的无损压缩视频格式,它利用帧间编码传递位图,其pixel_froamt是BGR24,专用于电脑截屏视频传输。像素数据使用了Zlib开放标准进行了压缩。其具体格式为:

表格 2 SCREENVIDEOPACKET

Field

Type

Comment

BlockWidth

UB[4]

Pixel width of each block in the grid. This value is stored as (actualWidth / 16) - 1, so possible block sizes are a multiple of 16 and not more than 256.

ImageWidth

UB[12]

Pixel width of the full image.

BlockHeight

UB[4]

Pixel height of each block in the grid. This value is stored
as (actualHeight / 16) - 1, so possible block sizes are a
multiple of 16 and not more than 256.

ImageHeight

UB[12]

Pixel height of the full image.

ImageBlocks

IMAGEBLOCK[n]

Blocks of image data. See preceding for details of how
to calculate n. Blocks are ordered from bottom left to
top right, in rows.

表格 3 SCREENV2VIDEOPACKET

Field

Type

Comment

BlockWidth

UB[4]

Pixel width of each block in the grid. This value is stored as (actualWidth / 16) - 1, so possible block sizes are a multiple of 16 and not more than 256.

ImageWidth

UB[12]

Pixel width of the full image.

BlockHeight

UB[4]

Pixel height of each block in the grid. This value is stored as (actualHeight / 16) - 1, so possible block sizes are a multiple of 16 and not more than 256.

ImageHeight

UB[12]

Pixel height of the full image.

Reserved

UB[6]

Must be 0

HasIFrameImage

UB[1]

If 1, has IFrameImage

HasPaletteInfo

UB[1]

If 1, has PaletteInfo

PaletteInfo

If HasPaletteInfo,
IMAGEBLOCK

One block of data to describe the palette.

ImageBlocks

IMAGEBLOCKV2[n]

Blocks of image data. See Block format for details of how to calculate n. Blocks are ordered from bottom left to top right in rows and can be a combination of keyblocks and interblocks.

IFrameImage

If HasIFrameImage,
IMAGEBLOCKV2[n]

Blocks of image data representing interblocks that must be combined with the previous keyblocks to produce the image. See Block format for details of how to calculate n. Blocks are ordered from bottom left to top right in rows.

从上表可以得出,不用深入到macroblock层,只需解析头部,就可很简单的得到width和height信息。

3、VP6FLVVIDEOPACKET和VP6FLVALPHAVIDEOPACKET

VP6FLVVIDEOPACKET和VP6FLVALPHAVIDEOPACKET比较简单,只是简单的将VP6或VP6A的一个视频帧封装到VideoPacket即可。

表格 4 VP6FLVVIDEOPACKET

Field

Type

Comment

HorizontalAdjustment

UB[4]

Number of pixels to subtract from the total width. The resulting width is used on the stage, and the rightmost pixels of the video is cropped.

VerticalAdjustment

UB[4]

Number of pixels to subtract from the total height. The resulting height is used on the stage, and the rightmost pixels of the video is cropped.

Data

UI8[n]

Raw VP6 video stream data

表格 5 VP6FLVALPHAVIDEOPACKET

Field

Type

Comment

HorizontalAdjustment

UB[4]

Number of pixels to subtract from the total width. The resulting width is used on the stage, and the rightmost pixels of the video is cropped.

VerticalAdjustment

UB[4]

Number of pixels to subtract from the total height. The resulting height is used on the stage, and the rightmost pixels of the video is cropped.

OffsetToAlpha

UI[24]

Offset in bytes to the alpha channel video data.

Data

UI8[n]

Raw VP6 video stream data.

AlphaData

UI8[n]

Raw VP6 video stream data representing the alpha channel

这样如果MetaData中没有宽高信息的话,就需要深入到Data层进行header parse,解析得到宽高信息,过程比较麻烦,不过可以参考FFmpeg的avcodec中的vp6_parse_header()函数,亦或是参考VP6或VP6Alpha的codec文档吧,本文暂不做详解。

4、AVCVIDEOPACKET

FLV将AVC的SPS(序列参数集)和PPS(图像参数集)和其他的配置信息封装到AVCDecoderConfigurationRecord,其具体格式为:

AVCDecoderConfigurationRecord {
         unsigned int(8) ConfigurationVersion = 1;
         unsigned int(8) AVCProfileIndication;
         unsigned int(8) ProfileCompatibility;
         unsigned int(8) AVCLevelIndication; 
         bit(6) reserved = ‘111111’b;
         unsigned int(2) LengthSizeMinusOne; 
         bit(3) reserved = ‘111’b;
         unsigned int(5) numOfSequenceParameterSets;
         for (i=0; i< numOfSequenceParameterSets;  i++) {
                   unsigned int(16) sequenceParameterSetLength ;
                   bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;   //SPS
         }
         unsigned int(8) numOfPictureParameterSets;
         for (i=0; i< numOfPictureParameterSets;  i++) {
                   unsigned int(16) pictureParameterSetLength;
                   bit(8*pictureParameterSetLength) pictureParameterSetNALUnit;              //PPS
         }
}

图像的宽高信息在SPS中,所以需要得到宽高信息,需要解析H.264的SPS,详见H.264的文档,当然也可以参考FFmpeg的avcodec中的ff_h264_decode_seq_parameter_set()函数。

5、一点点个人想法

流媒体播放中,多媒体音视频包经过网络到达终端,脱去一层层网络打包外衣,而后容器的外衣、再次是codec的header,经过艰辛的历程到达解码器。最终的目的就是节省网络带宽。随着互联网免费服务潮的到来,那些效果不错,但是收费高昂的标准或技术,遇到了很大的挑战。Google主推的VP8,较之ITU-T的H264,虽在编码效果上稍微逊色,但是其最大的杀手锏——免费,抓住了H264专利费高昂的七寸。Google强大的号召力或许真的会使VPx系列的codec最后胜出。一般公司玩技术、牛公司玩标准、超牛公司玩潮流,不得不佩服美帝的技术帝国。何种这些风潮才能Made in China?
--------------------- 
作者:xietao_live_cn 
来源:CSDN 
原文:https://blog.csdn.net/xietao_live_cn/article/details/6539625 
版权声明:本文为博主原创文章,转载请附上博文链接!

FLV文件中VideoPacket的详解相关推荐

  1. NT的BOOT.INI文件中ARC命名详解(转)

    NT的BOOT.INI文件中ARC命名详解(转)[@more@] ARC命名是Windows NT系统用来定位其引导分区所在的路径,也就是利用它指明引导分区在哪一个磁盘控制器,哪一个硬盘,哪一个分区内 ...

  2. python调用php命令行,python调用php函数 python怎样调用php文件中的函数详解

    前言 python调用php代码实现思路:php文件可通过在terminal中使用php命令行进行调用,因此可使用python开启子进程执行命令行代码.函数所需的参数可通过命令行传递. 测试环境 1. ...

  3. python echo函数_python如何调用php文件中的函数详解

    前言 python调用php代码实现思路:php文件可通过在terminal中使用php命令行进行调用,因此可使用python开启子进程执行命令行代码.函数所需的参数可通过命令行传递. 测试环境 1. ...

  4. 数据库控制文件中的SCN详解

    在的启动和关闭数据库的时候控制文件起着重要的作用,从官方文档中我们可以知道控制 文件中保存着下列的信息: 数据库的名称及数据库创建时间等 所有的数据文件.重做日志文件的名称和位置信息. 表空间的信息. ...

  5. python调用php_python如何调用php文件中的函数详解

    前言 python调用php代码实现思路:php文件可通过在terminal中使用php命令行进行调用,因此可使用python开启子进程执行命令行代码.函数所需的参数可通过命令行传递. 测试环境 1. ...

  6. Android.mk文件中的内容详解

    一.简介 在官网对 Android.mk 的介绍中写道: Android.mk 文件位于项目 jni/ 目录的子目录中,用于向构建系统描述源文件和共享库. 二.基础知识 这里介绍一些Android.m ...

  7. 【C++】C++中的头文件(.h)—详解(2)

    接上... [fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 头文件中写些什么 在上篇博客中写到头文件本身不参与编译,但是它们被包含到源文件中 ...

  8. 【C++】C++中的头文件(.h)—详解(1)

    [fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 前言 之前写过一篇<C++中头文件的使用>,那篇文章主要讲述C++中头文件的使用 ...

  9. python中文件读写--open函数详解

    python中open函数详解 在python中文件的读取分为三步走: 读:打开文件 -> 读文件 -> 关闭文件 (有点像把大象放进冰箱需要几步?的问题) 1.open函数 open函数 ...

最新文章

  1. jmeter+mysql+set_Jmeter中如何进行对数据库压测(上)
  2. mysql 插入数据 自增长_MySQL ------ 插入数据(INSERT和insert select)(二十)
  3. Recyclerview删除数据后无法加载下一页数据(或者是漏了一条数据)
  4. Java开发高性能网站需要关注的事
  5. 计蒜客可以做计算机编程吗,如果你的编程能力不足以支撑你成为工程师的野心,不妨到计蒜客上学学看...
  6. C语言实现单链表操作
  7. node作为java中间间_node作为中间服务层如何发送请求(发送请求的实现方法详解)...
  8. Docker学习之守护进程
  9. android 倒计时 动画下载,倒计时器app下载-倒计时器安卓最新版-幻想游戏网
  10. 指针变量的所占字节数大小确定
  11. 使用Vue做评论+localStorage存储(js模块化)
  12. 用Matlab分享一个软件低通滤波算法
  13. 基于android studio真机连接本地服务器(Apache)详细流程
  14. 《剑指offter》
  15. 资源网365,资源之家! 天天好资源!力争打造一个更好的资源网下载站.希望大家指教!...
  16. 头腾大战再升级 字节跳动做游戏的胜算有多少?
  17. 域名过期会怎么样?域名可以永久持有吗?
  18. powerbi中的earlier函数
  19. 研究生发论文是先有idea再做实验,还是先做实验再有idea?
  20. Echarts柱状图设置渐变色

热门文章

  1. 浅谈MD5加密算法中的加盐值(SALT)
  2. 拦截Activity的后退键处理
  3. CodeForces - 1476E Pattern Matching(字典树+拓扑)
  4. CodeForces - 916D Jamie and To-do List(主席树+模拟)
  5. 牛客 - tokitsukaze and Inverse Number(树状数组+逆序对定理)
  6. POJ - 3680 Intervals(最大费用最大流+思维建边)
  7. PAT (Advanced Level) 1015 Reversible Primes(进制转换)
  8. 读取SSDT表和原函数地址
  9. 换种思路去理解设计模式
  10. 2_4 FacadeMode.cpp 外观模式