✅ 操作成功!

流数据

发布时间:2023-06-13 作者:admin 来源:文学

流数据

流数据

-

2023年3月18日发(作者:北京东直门医院)

Rtmp数据流转h264的详细转码过程

一、目的:

这段时间,因为工作上的需要,在RTMP上做了flv流到标准h264、AAC的转换。

二、RTMP介绍:

RTMP(RealTimeMessagingProtocol)实时消息传送协议是AdobeSystems公司为

Flash播放器和服务器之间音频、视频和数据传输开发的私有协议。

RTMP协议就像一个用来装数据包的容器,这些数据可以是AMF格式的数据,也可以

是FLV中的视/音频数据.

它有三种变种:

1)工作在TCP之上的明文协议,使用端口1935;

2)RTMPT封装在HTTP请求之中,可穿越防火墙;

3)RTMPS类似RTMPT,但使用的是HTTPS连接;

Rtmp详细介绍请参照网上文档(一搜一大把)

三、Rtmp流转h264

基于rtmpclient端收取的数据包packet进行解码。

1、在rtmp传输数据流的时候,不论是在点播情况下或者直播

情况下,rtmpserver会在流开始的时候添加FileHeader和

MedadataTag。这些不需要分析。

2、数据头解析

2-1、Tagtype,一字节

每个packet的第一个字节代表了当前packet的类型。0x04表示Ping包,0x08

为audio,0x09为video。0x12为scriptdata。0x16比较特殊,这个是为了实现H.264

数据的直播而增加了一个数据类型。这个之后特别讨论。

2-2、Datasize,24bit

这三个字节表述了tag中数据段的大小。

2-3、Timestamp,24bit

记录了每一个tag相对于第一个tag(FileHeader)的相对时间。以毫秒

(milliseconds)为单位。而FileHeader的timestamp永远为0。

2-4、TimestampExtended,8bit

扩展时间字段,此字段与timestamp字段共同组成完整的时间戳字段,只不过

Timestamp是这个字段的低24位,TimestampExtended为这个字段的高8位。

2-5、StreamID,24bit

永远都是0。

2-6、Data,大小是Datasize

Tagbody。存储音视频信息等。

如果,

Tagtype==0x08,Data为audiodata。

Tagtype==0x09,Data为videodata。

Tagtype==0x12,Data为scriptdataobject。

Tagtype==0x16,Data为H264直播流数据包。

3、对rtmp音频数据的解析(audiotag)

不难看出rtmp中flv音频流就是一个接着一个的Audiotag。

每次传输流的第一个audiotag标示了音频使用的adtsheader信

息,即AACheader(audiodata),占据前3个字节。之后根据标

志位的不同,分AACsequenceheader和AACraw信息。具体解

析如下:

3-1、AACheader结构(2个字节)

3-1-1、SoundFormat,4bit

0=LinearPCM,platformendian

1=ADPCM

2=MP3

3=LinearPCM,littleendian

4=Nellymoser16kHzmono

5=Nellymoser8kHzmono

6=Nellymoser

7=G.711A-lawlogarithmicPCM

8=G.711mu-lawlogarithmicPCM

9=reserved

10=AAC

11=Speex

14=MP38kHz

15=Device-specificsound

3-1-2、SoundRate,2bit,抽样频率

0=5.5kHz

1=11kHz

2=22kHz

3=44kHz

对于aac音频来说,总是0x11,即44khz.

3-1-3、SoundSize,1bit,音频的位数。

0=8-bitsamples

1=16-bitsamples

AAC总是为0x01,16位。

3-1-4、SoundType,1bit,声道

0=Monosound

1=Stereosound

3-1-5、AACPacketType,8bit。

这个字段来表示AACAUDIODATA的类型:0=AACsequenceheader,1=AAC

raw。第一个音频包用0,后面的都用1

3-2、AACsequenceheader,2字节:

3-2-1、audioObjectType,5bit。结构编码类型

0=AACmain

1=AAClc

2=AACssr

3=AACLTP

一般AAC使用2,即AAClc

3-2-2、SamplingFrequencyIndex,4bit,音频采样率索引值

0:96000Hz

1:88200Hz

2:64000Hz

3:48000Hz

4:44100Hz

5:32000Hz

6:24000Hz

7:22050Hz

8:16000Hz

9:12000Hz

10:11025Hz

11:8000Hz

12:7350Hz

13:Reserved

14:Reserved

15:frequencyiswrittenexplicitly

通常aac固定选中44100,即应该对应为4,但是试验结果表明,当音频采样率

小于等于44100时,应该选择3,而当音频采样率为48000时,应该选择2.但是也

有例外。

3-2-3、ChannelConfiguration,4bit,音频输出声道。

对应的是音频的频道数目。单声道对应1,双声道对应2,依次类推。

0:DefinedinAOTSpecifcConfig

1:1channel:front-center

2:2channels:front-left,front-right

3:3channels:front-center,front-left,front-right

4:4channels:front-center,front-left,front-right,back-center

5:5channels:front-center,front-left,front-right,back-left,back-right

6:6channels:front-center,front-left,front-right,back-left,back-right,LFE-channel

7:8channels:front-center,front-left,front-right,side-left,side-right,back-left,

back-right,LFE-channel

8-15:Reserved

3-2-4、frameLengthConfig,1bit,标志位,用于表明IMDCT窗口长度

始终为0。

3-2-5、dependsOnCoreCoder,1bit,标志位,表明是否依赖于corecoder

始终为0。

3-2-7、extensionFlag,1bit

如果是AAC-LC,这里必须为0.

3-3、AACraw,大小不定

3-3-7、AACpayload

大小由packet的大小减去头的大小,再减去AACheader的2个字节的大小。一

般形式是,0xAF0x01+PAYLOAD.

4、对rtmp视频数据的解析(videotag)

如果packet头中的TagType==9时,就表示这个TAG是video。

那么StreamID之后的数据就表示是VideoTagHeader。

VideoTagHeader只有一个字节,也就是接跟着StreamID的1个

字节包含着视频帧类型及视频CodecID最基本信息

VideoTagHeader结构如下:

4-1、VideoTagHeader(8bit)结构:

4-1-1、FrameType,4bit,帧类型

1=keyframe(forAVC,aseekableframe)

2=interframe(forAVC,anon-seekableframe)

3=disposableinterframe(H.263only)

4=generatedkeyframe(reservedforserveruseonly)

5=videoinfo/commandframe

H264的一般为1或者2.

4-1-2、CodecID,4bit,编码类型

1=JPEG(currentlyunused)

2=SorensonH.263

3=Screenvideo

4=On2VP6

5=On2VP6withalphachannel

6=Screenvideoversion2

7=AVC

4-3、VideoData(根据CodecID判断之后videodata的类型)

IfCodecID=2,H263videopacket;

IfCodecID=3,SCREENvideopacket;

IfCodecID=4,VP6FLVvideopacket;

IfCodecID=5,VP6FLVALPHAvideopacket;

IfCodecID=6,SCREENV2videopacket;

IfCodecID=7,AVCvideopacket;

一般用AVCvideopacket。

VideoTagHeader之后跟着的就是VIDEODATA数据了,也就是videopayload.当然

就像音频AAC一样,这里也有特例就是如果视频的格式是AVC(H.264)的话,

VideoTagHeader会多出4个字节的信息。AVCPacketType和CompositionTime。

AVCPacketType表示接下来VIDEODATA(AVCVIDEOPACKET)的内容:

IFAVCPacketType==0AVCDecoderConfigurationRecord(AVCsequenceheader)

IFAVCPacketType==1OneormoreNALUs(Fullframesarerequired)

AVCDecoderConfigurationRecord.包含着是H.264解码相关比较重要的sps和pps信

息,再给AVC解码器送数据流之前一定要把sps和pps信息送出,否则的话解码器不

能正常解码。而且在解码器stop之后再次start之前,如seek、快进快退状态切换等,

都需要重新送一遍sps和pps的信息.AVCDecoderConfigurationRecord在FLV文件中一

般情况也是出现1次,也就是第一个videotag.

4-4、VIDEODATA(CodecID=7)

4-4-1、AVCPacketType,8bit

IFAVCPacketType==0AVCDecoderConfigurationRecord(AVCsequence

header)(此时FrameType必为1)

IFAVCPacketType==1OneormoreNALUs(Fullframesarerequired)

IFAVCPacketType==2AVCendofsequence(lowerlevelNALUsequence

enderisnotrequiredorsupported)

4-4-2、CompositionTime,24bit

IFAVCPacketType==1

Compositiontimeoffset,(没解析。)

ELSE

0

4-4-3、AVCDecoderConfigurationRecord(AVCPacketType==0,FrameType==1)

4-4-3-1、configurationVersion,8bit

4-4-3-2、AVCProfileIndication,8bit

4-4-3-3、profile_compatibility,8bit

4-4-3-4、AVCLevelIndication,8bit

4-4-3-5、lengthSizeMinusOne,8bit

H.264视频中NALU的长度,计算方法是1+(lengthSizeMinusOne&

3),实际测试时发现总为ff,计算结果为4.

4-4-3-6、numOfSequenceParameterSets,8bit

SPS的个数,计算方法是numOfSequenceParameterSets&0x1F,实际测

试时发现总为E1,计算结果为1

4-4-3-7、sequenceParameterSetLength,16bit

SPS的长度

4-4-3-8、sequenceParameterSetNALUnits,sps。

长度为sequenceParameterSetLength。

4-4-3-9、numOfPictureParameterSets,8bit

PPS的个数,计算方法是numOfPictureParameterSets&0x1F,实际测试

时发现总为E1,计算结果为1。

4-4-3-10、pictureParameterSetLength,16bit。

PPS的长度。

4-4-3-11、PPS

长度为pictureParameterSetLength。

4-4-4、NALUs(AVCPacketType==1,FrameType==1或者2)

一个packet里面可能包含多个NALUs,每个NALUs前的4个字节都是

标示这个NALU长度的4个字节,然后是这个NALU包。一个NALU包结束

之后,接着时下一个NALU包的长度4字节,然后是下一个NALU包。以此

类推,直到这个packet结束。

4-4-4-1、nal_length,32bit。每个nal包长度

每个NALU包前面都有(lengthSizeMinusOne&3)+1个字节的NAL

包长度描述(前文提到的,还记得吗),前面计算结果为4个字节。

4-4-4-2、nal包

这里插入一点NALU的小知识,每个NALU第一个字节的前5位标明

的是该NAL包的类型,即NALnal_unit_type

#defineNALU_TYPE_SLICE1

#defineNALU_TYPE_DPA2

#defineNALU_TYPE_DPB3

#defineNALU_TYPE_DPC4

#defineNALU_TYPE_IDR5//I帧

#defineNALU_TYPE_SEI6

#defineNALU_TYPE_SPS7

#defineNALU_TYPE_PPS8

#defineNALU_TYPE_AUD9//访问分隔符

#defineNALU_TYPE_EOSEQ10

#defineNALU_TYPE_EOSTREAM11

#defineNALU_TYPE_FILL12

四、参考文档:

1、/chef/archive/2012/07/18/

2、/liuzh501448/article/details/7245685

3、/blog/718123

4、/peijiangping1989/article/details/6934312

👁️ 阅读量:0