rtph264: set marker flag correctly

This commit is contained in:
aler9
2021-04-05 15:23:33 +02:00
parent 14ce8dbc45
commit db676cab85
3 changed files with 20 additions and 19 deletions

View File

@@ -67,7 +67,7 @@ func (e *Encoder) Encode(nts []*NALUAndTimestamp) ([][]byte, error) {
// split NALUs into batches // split NALUs into batches
for _, nt := range nts { for _, nt := range nts {
if len(batch) > 0 && batch[0].Timestamp != nt.Timestamp { if len(batch) > 0 && batch[0].Timestamp != nt.Timestamp {
return nil, fmt.Errorf("encoding NALUs with different timestamps is unimplemented") return nil, fmt.Errorf("encoding NALUs with different timestamps is not supported")
} }
if e.lenAggregated(batch, nt) <= rtpPayloadMaxSize { if e.lenAggregated(batch, nt) <= rtpPayloadMaxSize {
@@ -75,9 +75,9 @@ func (e *Encoder) Encode(nts []*NALUAndTimestamp) ([][]byte, error) {
batch = append(batch, nt) batch = append(batch, nt)
} else { } else {
// write last batch // write batch
if batch != nil { if batch != nil {
pkts, err := e.writeBatch(batch) pkts, err := e.writeBatch(batch, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -89,8 +89,9 @@ func (e *Encoder) Encode(nts []*NALUAndTimestamp) ([][]byte, error) {
} }
} }
// write last batch // write final batch
pkts, err := e.writeBatch(batch) // marker is used to indicate when all NALUs with same PTS have been sent
pkts, err := e.writeBatch(batch, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -99,21 +100,21 @@ func (e *Encoder) Encode(nts []*NALUAndTimestamp) ([][]byte, error) {
return rets, nil return rets, nil
} }
func (e *Encoder) writeBatch(nts []*NALUAndTimestamp) ([][]byte, error) { func (e *Encoder) writeBatch(nts []*NALUAndTimestamp, marker bool) ([][]byte, error) {
if len(nts) == 1 { if len(nts) == 1 {
// the NALU fits into a single RTP packet // the NALU fits into a single RTP packet
if len(nts[0].NALU) < rtpPayloadMaxSize { if len(nts[0].NALU) < rtpPayloadMaxSize {
return e.writeSingle(nts[0]) return e.writeSingle(nts[0], marker)
} }
// split the NALU into multiple fragmentation packet // split the NALU into multiple fragmentation packet
return e.writeFragmented(nts[0]) return e.writeFragmented(nts[0], marker)
} }
return e.writeAggregated(nts) return e.writeAggregated(nts, marker)
} }
func (e *Encoder) writeSingle(nt *NALUAndTimestamp) ([][]byte, error) { func (e *Encoder) writeSingle(nt *NALUAndTimestamp, marker bool) ([][]byte, error) {
rpkt := rtp.Packet{ rpkt := rtp.Packet{
Header: rtp.Header{ Header: rtp.Header{
Version: rtpVersion, Version: rtpVersion,
@@ -121,7 +122,7 @@ func (e *Encoder) writeSingle(nt *NALUAndTimestamp) ([][]byte, error) {
SequenceNumber: e.sequenceNumber, SequenceNumber: e.sequenceNumber,
Timestamp: e.encodeTimestamp(nt.Timestamp), Timestamp: e.encodeTimestamp(nt.Timestamp),
SSRC: e.ssrc, SSRC: e.ssrc,
Marker: true, Marker: marker,
}, },
Payload: nt.NALU, Payload: nt.NALU,
} }
@@ -135,7 +136,7 @@ func (e *Encoder) writeSingle(nt *NALUAndTimestamp) ([][]byte, error) {
return [][]byte{frame}, nil return [][]byte{frame}, nil
} }
func (e *Encoder) writeFragmented(nt *NALUAndTimestamp) ([][]byte, error) { func (e *Encoder) writeFragmented(nt *NALUAndTimestamp, marker bool) ([][]byte, error) {
nalu := nt.NALU nalu := nt.NALU
// use only FU-A, not FU-B, since we always use non-interleaved mode // use only FU-A, not FU-B, since we always use non-interleaved mode
@@ -181,7 +182,7 @@ func (e *Encoder) writeFragmented(nt *NALUAndTimestamp) ([][]byte, error) {
SequenceNumber: e.sequenceNumber, SequenceNumber: e.sequenceNumber,
Timestamp: ts, Timestamp: ts,
SSRC: e.ssrc, SSRC: e.ssrc,
Marker: (i == (packetCount - 1)), Marker: (i == (packetCount-1) && marker),
}, },
Payload: data, Payload: data,
} }
@@ -214,7 +215,7 @@ func (e *Encoder) lenAggregated(nts []*NALUAndTimestamp, additionalEl *NALUAndTi
return ret return ret
} }
func (e *Encoder) writeAggregated(nts []*NALUAndTimestamp) ([][]byte, error) { func (e *Encoder) writeAggregated(nts []*NALUAndTimestamp, marker bool) ([][]byte, error) {
payload := make([]byte, e.lenAggregated(nts, nil)) payload := make([]byte, e.lenAggregated(nts, nil))
// header // header
@@ -239,7 +240,7 @@ func (e *Encoder) writeAggregated(nts []*NALUAndTimestamp) ([][]byte, error) {
SequenceNumber: e.sequenceNumber, SequenceNumber: e.sequenceNumber,
Timestamp: e.encodeTimestamp(nts[0].Timestamp), Timestamp: e.encodeTimestamp(nts[0].Timestamp),
SSRC: e.ssrc, SSRC: e.ssrc,
Marker: true, Marker: marker,
}, },
Payload: payload, Payload: payload,
} }

View File

@@ -10,7 +10,7 @@ const (
NALUTypeDataPartitionB NALUType = 3 NALUTypeDataPartitionB NALUType = 3
NALUTypeDataPartitionC NALUType = 4 NALUTypeDataPartitionC NALUType = 4
NALUTypeIDR NALUType = 5 NALUTypeIDR NALUType = 5
NALUTypeSei NALUType = 6 NALUTypeSEI NALUType = 6
NALUTypeSPS NALUType = 7 NALUTypeSPS NALUType = 7
NALUTypePPS NALUType = 8 NALUTypePPS NALUType = 8
NALUTypeAccessUnitDelimiter NALUType = 9 NALUTypeAccessUnitDelimiter NALUType = 9
@@ -49,7 +49,7 @@ func (nt NALUType) String() string {
return "DataPartitionC" return "DataPartitionC"
case NALUTypeIDR: case NALUTypeIDR:
return "IDR" return "IDR"
case NALUTypeSei: case NALUTypeSEI:
return "Sei" return "Sei"
case NALUTypeSPS: case NALUTypeSPS:
return "SPS" return "SPS"

View File

@@ -172,7 +172,7 @@ var cases = []struct {
}, },
[][]byte{ [][]byte{
{ {
0x80, 0xe0, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55, 0x80, 0x60, 0x44, 0xed, 0x88, 0x77, 0x66, 0x55,
0x9d, 0xbb, 0x78, 0x12, 0x18, 0x00, 0x02, 0x09, 0x9d, 0xbb, 0x78, 0x12, 0x18, 0x00, 0x02, 0x09,
0xf0, 0x00, 0x44, 0x41, 0x9a, 0x24, 0x6c, 0x41, 0xf0, 0x00, 0x44, 0x41, 0x9a, 0x24, 0x6c, 0x41,
0x4f, 0xfe, 0xd6, 0x8c, 0xb0, 0x00, 0x00, 0x03, 0x4f, 0xfe, 0xd6, 0x8c, 0xb0, 0x00, 0x00, 0x03,
@@ -220,7 +220,7 @@ var cases = []struct {
), ),
mergeBytes( mergeBytes(
[]byte{ []byte{
0x80, 0xe0, 0x44, 0xee, 0x88, 0x77, 0x66, 0x55, 0x80, 0x60, 0x44, 0xee, 0x88, 0x77, 0x66, 0x55,
0x9d, 0xbb, 0x78, 0x12, 0x1c, 0x45, 0x9d, 0xbb, 0x78, 0x12, 0x1c, 0x45,
}, },
[]byte{0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, []byte{0x02, 0x03, 0x04, 0x05, 0x06, 0x07},