rtp分包逻辑更新

This commit is contained in:
dexter
2020-07-31 17:51:50 +08:00
parent 1db1a7eab9
commit 2b73fbeee7
+82 -67
View File
@@ -2,6 +2,8 @@ package avformat
import (
"io"
"github.com/Monibuca/engine/v2/util"
)
// Start Code + NAL Unit -> NALU Header + NALU Body
@@ -68,6 +70,8 @@ var NALU_SEI_BYTE []byte
// raw byte sequence payload (RBSP) 原始字节序列载荷
type H264 struct {
SPS []byte
PPS []byte
}
func min(a, b int) int {
@@ -78,80 +82,91 @@ func min(a, b int) int {
}
//Payload 分包,用于RTP传输
func (*H264) Payload(mtu int, nalu []byte) (payloads [][]byte) {
if nalu == nil {
func (h264 *H264) Payload(mtu int, payload []byte) (payloads [][]byte) {
if payload == nil {
return payloads
}
naluType := nalu[0] & 0x1F //00011111
naluRefIdc := nalu[0] & 0x60 //1110000
if naluType == 9 || naluType == 12 {
return
videoFrameType := payload[0] >> 4
if videoFrameType == 1 || videoFrameType == 4 {
payloads = append(payloads, h264.SPS, h264.PPS)
}
var nalu []byte
var naluLen int
for payload := payload[5:]; len(payload) > 4; payload = nalu[naluLen:] {
naluLen = int(util.BigEndian.Uint32(payload))
nalu = payload[4:]
naluType := nalu[0] & 0x1F //00011111
naluRefIdc := nalu[0] & 0x60 //1110000
// Single NALU
if len(nalu) <= mtu {
out := make([]byte, len(nalu))
copy(out, nalu)
payloads = append(payloads, out)
return
}
// FU-A
maxFragmentSize := mtu - 2
// The FU payload consists of fragments of the payload of the fragmented
// NAL unit so that if the fragmentation unit payloads of consecutive
// FUs are sequentially concatenated, the payload of the fragmented NAL
// unit can be reconstructed. The NAL unit type octet of the fragmented
// NAL unit is not included as such in the fragmentation unit payload,
// but rather the information of the NAL unit type octet of the
// fragmented NAL unit is conveyed in the F and NRI fields of the FU
// indicator octet of the fragmentation unit and in the type field of
// the FU header. An FU payload MAY have any number of octets and MAY
// be empty.
naluData := nalu
// According to the RFC, the first octet is skipped due to redundant information
naluDataIndex := 1
naluDataLength := len(nalu) - naluDataIndex
naluDataRemaining := naluDataLength
if min(maxFragmentSize, naluDataRemaining) <= 0 {
return
}
for naluDataRemaining > 0 {
currentFragmentSize := min(maxFragmentSize, naluDataRemaining)
out := make([]byte, 2+currentFragmentSize)
// +---------------+
// |0|1|2|3|4|5|6|7|
// +-+-+-+-+-+-+-+-+
// |F|NRI| Type |
// +---------------+
out[0] = NALU_FUA | naluRefIdc
// +---------------+
//|0|1|2|3|4|5|6|7|
//+-+-+-+-+-+-+-+-+
//|S|E|R| Type |
//+---------------+
out[1] = naluType
if naluDataRemaining == naluDataLength {
// Set start bit
out[1] |= 1 << 7
} else if naluDataRemaining-currentFragmentSize == 0 {
// Set end bit
out[1] |= 1 << 6
if naluType == 9 || naluType == 12 {
continue
}
copy(out[2:], naluData[naluDataIndex:naluDataIndex+currentFragmentSize])
payloads = append(payloads, out)
// Single NALU
if len(nalu) <= mtu {
out := make([]byte, len(nalu))
copy(out, nalu)
payloads = append(payloads, out)
continue
}
// FU-A
maxFragmentSize := mtu - 2
// The FU payload consists of fragments of the payload of the fragmented
// NAL unit so that if the fragmentation unit payloads of consecutive
// FUs are sequentially concatenated, the payload of the fragmented NAL
// unit can be reconstructed. The NAL unit type octet of the fragmented
// NAL unit is not included as such in the fragmentation unit payload,
// but rather the information of the NAL unit type octet of the
// fragmented NAL unit is conveyed in the F and NRI fields of the FU
// indicator octet of the fragmentation unit and in the type field of
// the FU header. An FU payload MAY have any number of octets and MAY
// be empty.
naluData := nalu
// According to the RFC, the first octet is skipped due to redundant information
naluDataIndex := 1
naluDataLength := len(nalu) - naluDataIndex
naluDataRemaining := naluDataLength
if min(maxFragmentSize, naluDataRemaining) <= 0 {
continue
}
for naluDataRemaining > 0 {
currentFragmentSize := min(maxFragmentSize, naluDataRemaining)
out := make([]byte, 2+currentFragmentSize)
// +---------------+
// |0|1|2|3|4|5|6|7|
// +-+-+-+-+-+-+-+-+
// |F|NRI| Type |
// +---------------+
out[0] = NALU_FUA | naluRefIdc
// +---------------+
//|0|1|2|3|4|5|6|7|
//+-+-+-+-+-+-+-+-+
//|S|E|R| Type |
//+---------------+
out[1] = naluType
if naluDataRemaining == naluDataLength {
// Set start bit
out[1] |= 1 << 7
} else if naluDataRemaining-currentFragmentSize == 0 {
// Set end bit
out[1] |= 1 << 6
}
copy(out[2:], naluData[naluDataIndex:naluDataIndex+currentFragmentSize])
payloads = append(payloads, out)
naluDataRemaining -= currentFragmentSize
naluDataIndex += currentFragmentSize
}
naluDataRemaining -= currentFragmentSize
naluDataIndex += currentFragmentSize
}
return
}