Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions codecs/av1_depacketizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ type AV1Depacketizer struct {
videoDepacketizer
}

func (d *AV1Depacketizer) appendOBUWithCalculatedSize(
buff []byte,
obuHeader *obu.Header,
obuBuffer []byte,
payloadOffset int,
) []byte {
obuPayloadSize := len(obuBuffer) - payloadOffset
buff = append(buff, obuHeader.Marshal()...)
buff = append(buff, obu.WriteToLeb128(uint(obuPayloadSize))...) // nolint: gosec // G104
buff = append(buff, obuBuffer[payloadOffset:]...)

return buff
}

// Unmarshal parses an AV1 RTP payload into its constituent OBUs stream with obu_size_field,
// It assumes that the payload is in order (e.g. the caller is responsible for reordering RTP packets).
// If the last OBU in the payload is fragmented, it will be stored in the buffer until the
Expand Down Expand Up @@ -144,22 +158,17 @@ func (d *AV1Depacketizer) Unmarshal(payload []byte) (buff []byte, err error) {
return nil, err
}

// We validate the obu_size_field if it is present.
// Ignore obu_size_field if it is present and doesn't match the calculated size.
sizeFromOBUSize := obuHeader.Size() + int(obuSize) + int(n) //nolint:gosec
if lengthField != sizeFromOBUSize {
return nil, fmt.Errorf(
"%w: OBU size %d does not match calculated size %d",
errShortPacket, obuSize, sizeFromOBUSize,
)
payloadOffset := obuHeader.Size() + int(n) //nolint:gosec // n is small, LEB128.
buff = d.appendOBUWithCalculatedSize(buff, obuHeader, obuBuffer, payloadOffset)
} else {
buff = append(buff, obuBuffer...)
}

buff = append(buff, obuBuffer...)
} else {
obuHeader.HasSizeField = true
buff = append(buff, obuHeader.Marshal()...)
size := len(obuBuffer) - obuHeader.Size()
buff = append(buff, obu.WriteToLeb128(uint(size))...) // nolint: gosec // G104
buff = append(buff, obuBuffer[obuHeader.Size():]...)
buff = d.appendOBUWithCalculatedSize(buff, obuHeader, obuBuffer, obuHeader.Size())
}

if isLast {
Expand Down
24 changes: 20 additions & 4 deletions codecs/av1_depacketizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ func TestAV1Depacketizer_validateOBUSize(t *testing.T) {
tests := []struct {
name string
payload []byte
expect []byte
err error
}{
{
Expand All @@ -135,7 +136,11 @@ func TestAV1Depacketizer_validateOBUSize(t *testing.T) {
0x04, // LEB128 size
0x03, 0x01, 0x02, // OBU data
},
err: errShortPacket,
expect: []byte{
0x22, // OBU header
0x03, // Corrected size
0x03, 0x01, 0x02, // OBU data
},
},
{
name: "OBU size smaller than length field",
Expand All @@ -146,15 +151,26 @@ func TestAV1Depacketizer_validateOBUSize(t *testing.T) {
0x02, // LEB128 size
0x03, 0x01, 0x02, // OBU data
},
err: errShortPacket,
expect: []byte{
0x22, // OBU header
0x03, // Corrected size
0x03, 0x01, 0x02, // OBU data
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d := AV1Depacketizer{}
_, err := d.Unmarshal(tt.payload)
assert.ErrorIs(t, err, tt.err)
obu, err := d.Unmarshal(tt.payload)
if tt.err != nil {
assert.ErrorIs(t, err, tt.err)

return
}

assert.NoError(t, err)
assert.Equal(t, tt.expect, obu)
})
}
}
Expand Down
Loading