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:
* 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.
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
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)
}