Skip to content

Commit

Permalink
Finish AV1 Implementation
Browse files Browse the repository at this point in the history
1. Rewrite the AV1 Payloader according to the spec.
2. AV1 bitstream reader.
3. Tries to optimize the use of the W field as much as possible to
    reduce the size of the packet.
4. Added tests around edge cases.
  • Loading branch information
JoeTurki committed Mar 1, 2025
1 parent 061df8a commit 2146e1f
Show file tree
Hide file tree
Showing 4 changed files with 2,012 additions and 130 deletions.
13 changes: 5 additions & 8 deletions codecs/av1_depacketizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ func (d *AV1Depacketizer) Unmarshal(payload []byte) (buff []byte, err error) {
}

// |Z|Y| W |N|-|-|-|
obuZ := (0b10000000 & payload[0]) != 0 // Z
obuY := (0b01000000 & payload[0]) != 0 // Y
obuCount := (0b00110000 & payload[0]) >> 4 // W
obuN := (0b00001000 & payload[0]) != 0 // N
obuZ := (av1ZMask & payload[0]) != 0 // Z
obuY := (av1YMask & payload[0]) != 0 // Y
obuCount := (av1WMask & payload[0]) >> 4 // W
obuN := (av1NMask & payload[0]) != 0 // N
d.Z = obuZ
d.Y = obuY
d.N = obuN
Expand Down Expand Up @@ -120,10 +120,7 @@ func (d *AV1Depacketizer) Unmarshal(payload []byte) (buff []byte, err error) {
}

if len(obuBuffer) == 0 {
return nil, fmt.Errorf(
"%w: OBU size %d is 0",
errShortPacket, lengthField,
)
continue
}

obuHeader, err := obu.ParseOBUHeader(obuBuffer)
Expand Down
31 changes: 24 additions & 7 deletions codecs/av1_depacketizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ func TestAV1Depacketizerr_invalidPackets(t *testing.T) {
if !errors.Is(err, errShortPacket) {
t.Fatalf("Unexpected error: %v", err)
}

_, err = depacketizer.Unmarshal([]byte{0x00})
if !errors.Is(err, errShortPacket) {
t.Fatalf("Unexpected error: %v", err)
}

_, err = depacketizer.Unmarshal([]byte{0b11000000, 0xFF})
if !errors.Is(err, obu.ErrFailedToReadLEB128) {
t.Fatalf("Unexpected error: %v", err)
Expand All @@ -55,7 +49,7 @@ func TestAV1Depacketizerr_invalidPackets(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}

_, err = depacketizer.Unmarshal(append([]byte{0b00000000}, obu.WriteToLeb128(0)...))
_, err = depacketizer.Unmarshal(append([]byte{0b00000000}, obu.WriteToLeb128(0x01)...))
if !errors.Is(err, errShortPacket) {
t.Fatalf("Unexpected error: %v", err)
}
Expand Down Expand Up @@ -95,6 +89,29 @@ func TestAV1Depacketizerr_singleOBU(t *testing.T) {
}
}

func TestAV1Depacketizerr_singleOBUWithPadding(t *testing.T) {
payload := []byte{0x01, 0x02, 0x03}
obuData, expectedOBU := createAV1OBU(4, payload)

packet := make([]byte, 0)

packet = append(packet, []byte{0b00000000}...)
packet = append(packet, obu.WriteToLeb128(uint(len(obuData)))...)
packet = append(packet, obuData...)
// padding
packet = append(packet, []byte{0x00, 0x00, 0x00}...)

d := AV1Depacketizer{}
obu, err := d.Unmarshal(packet)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}

if !bytes.Equal(obu, expectedOBU) {
t.Fatalf("OBU data mismatch, expected %v, got %v", expectedOBU, obu)
}
}

// AV1 OBUs shouldn't include the obu_size_field when packetized in RTP,
// but we still support it since it's encountered in the wild (Including pion old clients).
func TestAV1Depacketizerr_withOBUSize(t *testing.T) {
Expand Down
Loading

0 comments on commit 2146e1f

Please sign in to comment.