【音视频技术】H264流媒体封装FLV文件

    最近再封装H264文件,本来想想用ffmpeg,可惜设备端没有足够的空间放ffmpeg的库了,无奈只好开始撸协议自己封装了~

首先至少得了解以下知识点:

【音视频技术】AVC H264的一些基本概念和知识点

【音视频技术】FLV封装格式

【音视频技术】AMF实用协议解析说明

好了,开撸。

FLV的封装格式就不说了,这篇博客着重说一下 H264中的NALU如何封装成 FLV中的video tag ,关于FLVheader 及FLV其他结构有不清楚的可以上网查其他资料或者看我写的这篇【音视频技术】FLV封装格式博客。

-------------------------------------------------------------------------------------------------------------

H264 的NALU 封装成FLV有三种不同的形式: 

(H264 NALU 不清楚的【音视频技术】AVC H264的一些基本概念和知识点

(1)H264 NALU type SPS +PPS;

(2)H264 NALU type SEI;

(3)H264 NALU type Slice 也就是 type值为(1-5);

--------------------------------------------------------------------------------------------------------------

(1)H264 NALU type SPS +PPS 封装成 FLV video tag:

    在H264的码流中 SPS 和 PPS是成对出现的,先是SPS然后是PPS,SPS对于H264来说就是编码后的第一帧、PPS是编码后的第二帧这两针携带的数据主要是编码器的一些属性,比如宽高 profile level deblock滤波器等等。

    在封装FLV中这两帧数据被合并到一个video TAG中:


FLV tag header                Bytes                    value

1)Tag type                     // 0                        0x09

2)Data Size                    // 1-3                     0x00 0x00 0x24

3)TimeStamp                 // 4-6                     0x00 0x00 0x00     (First frame)

4)TimeStampExtend       // 7                        0x00

5)StreamID                    // 8-10                  0x00 0x00 0x00   (always zero)


AVC Video tag header         

1)FrameType | CodecID       //11                             0x17

2)AVCPacketType                //12                             0x00

3)Composition Time              //13-15                       0x00 0x00 0x00


                                 


AVCDecoderConfigurationRecord

1)Configuration VerSion                 //16                  0x01      

2)AVC Profile SPS[1]                     //17                   0x42       

3)profile_compatibility SPS[2]       //18                   0x00      

4)AVC Level SPS[3]                       //19                   0x2A      

5)lengthSizeMinusOne                    //20                   0xFF

6)numOfSequenceParameterSets //21                  0xE1      

SPS

1)SPS0 Length                                //22-23            0x0010

2)SPS0 Data

3)SPS(n) length /btyes 如果存在多个循环存放最多31个SPS

4)SPS(n) Data

                                     

PPS

PPS  count                                         //1byte             0x01

PPS0 Length                                     //2bytes           0x00 0x04

PPS0 Data

PPS(n) Length

PPS(n) Data

+PreviousTag Size


--------------------------------------------------------------------------------------------------------

(2)H264 NALU type Sei 封装成 FLV video tag:

    SEI NALU 是没有图像数据的,它的主要作用是对图像数据或者视频流的补充,有些内容可能对解码有帮助。在封装FLV文件中含义SEI的videoTAG其中包含色SEI数据还有SEI帧后紧跟着的一个IDR数据,其编码结构如下;


FLV tag header                Bytes                    value

1)Tag type                     // 0                          0x09

2)Data Size                    // 1-3                     0x00 0x00 0x24

3)TimeStamp                 // 4-6                     0x00 0x00 0x00     (First frame)

4)TimeStampExtend       // 7                       0x00

5)StreamID                    // 8-10                   0x00 0x00 0x00   (always zero)


AVC Video tag header         

1)FrameType | CodecID       //11                             0x27

2)AVCPacketType                //12                             0x01

3)Composition Time              //13-15                       0x00 0x00 0x00

SEI

1)SEI length                   //16-19                        0x00  0x00 0x00 0x05

2)SEI Data                       // 20-N                       0x06 E5 01 81 80

3)IDR NALU Length    //4Bytes               0x00 0x00 0x1F 0xF4

4)IDR NALU Data

+PreviousTag Size


----------------------------------------------------------------------------------------------------

(3)H264 NALU type Slice 封装成 FLV video tag:

    Slice Type NALU (1-5) 就是H264 中一片一片的数据了,在FLV video tag中封装 如下:


FLV tag header                Bytes                    value

1)Tag type                     // 0                          0x09

2)Data Size                    // 1-3                     0x00 0x95 0xF6

3)TimeStamp                 // 4-6                     0x00 0x00 0x00     (First frame)

4)TimeStampExtend       // 7                       0x00

5)StreamID                    // 8-10                   0x00 0x00 0x00   (always zero)


AVC Video tag header         

1)FrameType | CodecID       //11                             0x27 or 0x17

2)AVCPacketType                //12                             0x01

3)Composition Time              //13-15                       0x00 0x00 0x00


NALU

NALU Length                        //   4bytes                     0x00 0x00 0x95 0xED

NALU data

+PreviousTag Size

    OK,上述就是H264在封装成FLV文件时的3中video tag。再说点调试时的经验吧。封装FLV我总共花了3天,第一天了解FLV协议,AMF协议,结合着flv的媒体文件来对照协议,理解各个字段的意思。大家可以使用UEdit这个工具来看二进制文件,也可以使用这个flv解析工具来直接解析flv文件 (还算挺好用的吧)。封装过程中有些大端小端的一定要注意,还有扩展时间戳位(不知道搞协议的人怎么想的搞出这个东西来)。第二天,再网上搞了一套代码,看懂后改了改 ,可以封装H264了 但是 生产出来的flv文件播放有马赛克。后来用ffmpeg封装对比前后的文件慢慢找出的端倪。错在SEI type的nalu 我处理的不对又改了改,大功告成。源代码的话我就不放了,如果按照我这个按部就班的做应该没问题的,我就是这么搞出来的。

整个工作过程这篇博客给我的帮助是最大的,内容也是最正确的,其他看了好多感觉都有写的不对的地方(感谢感谢):

打包H264码流到FLV文件







猜你喜欢

转载自blog.csdn.net/u013008311/article/details/80249472