diff --git a/pkg/rtph264/encoder.go b/pkg/rtph264/encoder.go index 40c3aaef..01ac3aff 100644 --- a/pkg/rtph264/encoder.go +++ b/pkg/rtph264/encoder.go @@ -67,7 +67,7 @@ func (e *Encoder) Encode(nts []*NALUAndTimestamp) ([][]byte, error) { // split NALUs into batches for _, nt := range nts { 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 { @@ -75,9 +75,9 @@ func (e *Encoder) Encode(nts []*NALUAndTimestamp) ([][]byte, error) { batch = append(batch, nt) } else { - // write last batch + // write batch if batch != nil { - pkts, err := e.writeBatch(batch) + pkts, err := e.writeBatch(batch, false) if err != nil { return nil, err } @@ -89,8 +89,9 @@ func (e *Encoder) Encode(nts []*NALUAndTimestamp) ([][]byte, error) { } } - // write last batch - pkts, err := e.writeBatch(batch) + // write final batch + // marker is used to indicate when all NALUs with same PTS have been sent + pkts, err := e.writeBatch(batch, true) if err != nil { return nil, err } @@ -99,21 +100,21 @@ func (e *Encoder) Encode(nts []*NALUAndTimestamp) ([][]byte, error) { 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 { // the NALU fits into a single RTP packet if len(nts[0].NALU) < rtpPayloadMaxSize { - return e.writeSingle(nts[0]) + return e.writeSingle(nts[0], marker) } // 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{ Header: rtp.Header{ Version: rtpVersion, @@ -121,7 +122,7 @@ func (e *Encoder) writeSingle(nt *NALUAndTimestamp) ([][]byte, error) { SequenceNumber: e.sequenceNumber, Timestamp: e.encodeTimestamp(nt.Timestamp), SSRC: e.ssrc, - Marker: true, + Marker: marker, }, Payload: nt.NALU, } @@ -135,7 +136,7 @@ func (e *Encoder) writeSingle(nt *NALUAndTimestamp) ([][]byte, error) { 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 // 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, Timestamp: ts, SSRC: e.ssrc, - Marker: (i == (packetCount - 1)), + Marker: (i == (packetCount-1) && marker), }, Payload: data, } @@ -214,7 +215,7 @@ func (e *Encoder) lenAggregated(nts []*NALUAndTimestamp, additionalEl *NALUAndTi 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)) // header @@ -239,7 +240,7 @@ func (e *Encoder) writeAggregated(nts []*NALUAndTimestamp) ([][]byte, error) { SequenceNumber: e.sequenceNumber, Timestamp: e.encodeTimestamp(nts[0].Timestamp), SSRC: e.ssrc, - Marker: true, + Marker: marker, }, Payload: payload, } diff --git a/pkg/rtph264/nalutype.go b/pkg/rtph264/nalutype.go index 097ec3cd..0a1ee69c 100644 --- a/pkg/rtph264/nalutype.go +++ b/pkg/rtph264/nalutype.go @@ -10,7 +10,7 @@ const ( NALUTypeDataPartitionB NALUType = 3 NALUTypeDataPartitionC NALUType = 4 NALUTypeIDR NALUType = 5 - NALUTypeSei NALUType = 6 + NALUTypeSEI NALUType = 6 NALUTypeSPS NALUType = 7 NALUTypePPS NALUType = 8 NALUTypeAccessUnitDelimiter NALUType = 9 @@ -49,7 +49,7 @@ func (nt NALUType) String() string { return "DataPartitionC" case NALUTypeIDR: return "IDR" - case NALUTypeSei: + case NALUTypeSEI: return "Sei" case NALUTypeSPS: return "SPS" diff --git a/pkg/rtph264/rtph264_test.go b/pkg/rtph264/rtph264_test.go index d3d6a274..bc96113e 100644 --- a/pkg/rtph264/rtph264_test.go +++ b/pkg/rtph264/rtph264_test.go @@ -172,7 +172,7 @@ var cases = []struct { }, [][]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, 0xf0, 0x00, 0x44, 0x41, 0x9a, 0x24, 0x6c, 0x41, 0x4f, 0xfe, 0xd6, 0x8c, 0xb0, 0x00, 0x00, 0x03, @@ -220,7 +220,7 @@ var cases = []struct { ), mergeBytes( []byte{ - 0x80, 0xe0, 0x44, 0xee, 0x88, 0x77, 0x66, 0x55, + 0x80, 0x60, 0x44, 0xee, 0x88, 0x77, 0x66, 0x55, 0x9d, 0xbb, 0x78, 0x12, 0x1c, 0x45, }, []byte{0x02, 0x03, 0x04, 0x05, 0x06, 0x07},