Preliminary analysis rtp video and audio formats (golang parsing)

rtp video, audio format parsing

A, rtp h264 analytical carrier

Analytical rtp h264 current carrying achieved in two ways: StapA and FUA

NALUs head composed of one byte, which has the following syntax:

Write pictures described here
* F.:.. 1 bit

. forbidden_zero_bit specified in the H.264 specification which must be a of 0. the

* the NRI:. 2 bits

. nal_ref_idc take 00 to 11, seems to indicate the importance of this NALU, such as the decoder 00 of the NALU
can be discarded without affecting its playback image.

* the Type:.. 5 bits

. nal_unit_type this the type of unit NALU summarized as follows:

0 not defined

1-23 NAL unit is a single NAL unit packet

24 STAP-a combination of a single packet time

25 STAP-B packet a single time in combination

a plurality of times MTAP16 26 Bundles

27 MTAP24 plurality time combination package

28 FU-a slicing unit

29 FU-B slice units

30-31 is not defined

to distinguish golang sample code is:

IF naluType {// == 0x18 STAP-a

self.packetMutex.Lock ( )



packetArray = self.demuxStapA (packet.data to)



self.packetMap.Remove (int (packet.sn))

self.packetMutex.Unlock()

} else if naluType == 0x1c { //FUs

//log.Infof(“getPacket start demuxFUa…”)

retAvPacket := self.demuxFUa()

if retAvPacket != nil {

packetArray = append(packetArray, retAvPacket)

}

}

1. Stapana

A brief description, is a packet contains more than h264 messages.

When the length of the particular hours of the NALU can combine several NALU unit enclosed in a RTP packet.

Write pictures described here
Golang sample code parsing stapa of:

for {

naluPacket: = & AVPacket {}

naluData: = Packet [startIndex:]



naluSize: = int (PIO. U16BE (naluData))



endpos: = startIndex + + naluSize NALU_SIZE

IF endpos> = (len (Packet) -. 1) {

BREAK

}



naluhdr: Packet = [startIndex + NALU_SIZE]



IF naluhdr NALU_ACCESS == {

startIndex = startIndex + + naluSize NALU_SIZE

Continue

}



naluPacket.data = the append (naluPacket.data, Packet [startIndex + NALU_SIZE: endpos] ...)

naluPacket.isVideo to true =

    packetArray = append(packetArray, naluPacket) <br/>
    startIndex = startIndex + NALU_SIZE + naluSize <br/>



if startIndex >= (len(packet) - 1) {

break

}

}

2. FUA

H264 FuA when relatively large packets, later split into a plurality of packages in a plurality of rtp.

Do not be scared format is the name of the above-mentioned RTP h264 load type, Type A is-FU

Write pictures described here
S 'bit is represented by a slice NAL started, when it is 1, E is not 1

E 1' bit indicates the end, when it is 1, S is not. 1

R & lt reserved bit 'bit

Type is Type NALU header, taking the value of 1-23

is therefore a need to fu indicator fu header and splicing: naluHeader: = (fuIndicator & 0xe0 ) | ( & 0x1F fuHeader)

golang examples code:

for index, Key: Range = {seqArray

SEQ: Key = (int).



IF lastSeq == 0 {

lastSeq = SEQ

} the else {

IF (SEQ - lastSeq). 1 = {!

discardFlag to true =

}

lastSeq = SEQ

}



var Packet * RtpPacket

IF discardFlag {!

value, _: = self.packetMap.Get (SEQ)

Packet = value (* RtpPacket).



avpacket.payloadtype = int(packet.pt)

avpacket.timestamp = packet.timestamp * 1000 / 90000



fuIndicator := packet.data[0]

fuHeader := packet.data[1]



naluHeader := (fuIndicator & 0xe0) | (fuHeader & 0x1f)



if index == 0 {

avpacket.data = append(avpacket.data, naluHeader)

}



avpacket.data = append(avpacket.data, packet.data[2:]…)

}



self.packetMap.Remove(seq)

if packet.m != 0 && index != 0 {

break

}

}


Second, the audio aac

aac rtp bearer format consists of two parts:
* 2-byte headers-length AU
* n th AU-header, 2 bytes each
* n th AU, is removed adts load aac

1. AU-headers-length

The first two bytes represent the au-header length, the unit is bit.

golang Code Example:

auHeaderLen: = pio.U16BE (packet.data to [0:])

auHeaderLen = auHeaderLen / 8

auHeaderCount: = int (auHeaderLen / 2)

Because the unit is bit, byte length is divided by 8 to auHeader; and because auheader single byte length of 2 bytes, the number is divided by 2 auheader.

2. AU-header

High 13 bits is a byte length au au-header of:

golang example:

for iIndex = 0; iIndex <int (auHeaderCount); iIndex ++ {

auHeaderInfo: = pio.U16BE (packet.data to [2 + 2 * iIndex: ])

Aulen: >> = auHeaderInfo. 3

auLenArray = the append (auLenArray, int (Aulen))

}

this will give the length of a plurality au

3. IN

startOffset := 2 + 2*auHeaderCount<br/> 
for _, auLen := range auLenArray {<br/> 
    retPacket := &AVPacket{}<br/> 



adtsPacket := self.GetADTS(self.sampleRate, self.channel, self.aacProfile, auLen)

retPacket.data = append(retPacket.data, adtsPacket[0:7]…)



endOffset := startOffset + auLen

retPacket.data = append(retPacket.data, packet.data[startOffset:endOffset]…)

retPacket.isVideo = false

retPacket.timestamp = packet.timestamp * 1000 / 90000

retPacket.payloadtype = int(packet.pt)



startOffset = startOffset + auLen



retPacketArray = append(retPacketArray, retPacket)

}

Published 21 original articles · won praise 18 · views 50000 +

Guess you like

Origin blog.csdn.net/sweibd/article/details/78072965