// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>// SPDX-License-Identifier: MITpackage codecsimport ()// AV1Depacketizer is a AV1 RTP Packet depacketizer.// Reads AV1 packets from a RTP stream and outputs AV1 low overhead bitstream.typeAV1Depacketizerstruct {// holds the fragmented OBU from the previous packet. buffer []byte// Z, Y, N are flags from the AV1 Aggregation Header. Z, Y, N boolvideoDepacketizer}// 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// it is completed.////nolint:gocognit,cyclopfunc ( *AV1Depacketizer) ( []byte) ( []byte, error) { = make([]byte, 0)iflen() <= 1 {returnnil, errShortPacket }// |Z|Y| W |N|-|-|-| := (av1ZMask & [0]) != 0// Z := (av1YMask & [0]) != 0// Y := (av1WMask & [0]) >> 4// W := (av1NMask & [0]) != 0// N .Z = .Y = .N = if { .buffer = nil }// Make sure we clear the buffer if Z is not 0.if ! && len(.buffer) > 0 { .buffer = nil } := 0for := 1; < len(); ++ { := == 0 := != 0 && == int()-1// https://aomediacodec.github.io/av1-rtp-spec/#44-av1-aggregation-header // W: two bit field that describes the number of OBU elements in the packet. // This field MUST be set equal to 0 or equal to the number of OBU elements contained in the packet. // If set to 0, each OBU element MUST be preceded by a length field. If not set to 0 // (i.e., W = 1, 2 or 3) the last OBU element MUST NOT be preceded by a length field.var , intif == 0 || ! { , , := obu.ReadLeb128([:]) = int() //nolint:gosec // G115 false positive = int() //nolint:gosec // G115 false positiveif != nil {returnnil, } += if == 0 && + == len() { = true } } else {// https://aomediacodec.github.io/av1-rtp-spec/#44-av1-aggregation-header // Length of the last OBU element = // length of the RTP payload // - length of aggregation header // - length of previous OBU elements including length fields = len() - }if + > len() {returnnil, fmt.Errorf("%w: OBU size %d + %d offset exceeds payload length %d",errShortPacket, , , len(), ) }var []byteif && {// We lost the first fragment of the OBU // We drop the buffer and continueiflen(.buffer) == 0 {if {break } += continue } = make([]byte, len(.buffer)+)copy(, .buffer)copy([len(.buffer):], [:+]) .buffer = nil } else { = [ : +] } += if && { .buffer = break }iflen() == 0 {continue } , := obu.ParseOBUHeader()if != nil {returnnil, }// The temporal delimiter OBU, if present, SHOULD be removed when transmitting, // and MUST be ignored by receivers. Tile list OBUs are not supported. // They SHOULD be removed when transmitted, and MUST be ignored by receivers. // https://aomediacodec.github.io/av1-rtp-spec/#5-packetization-rulesif .Type == obu.OBUTemporalDelimiter || .Type == obu.OBUTileList {continue }// obu_has_size_field should be set to 0 for AV1 RTP packets. // But we still check it to be sure, if we get obu size we just use it, instead of calculating it.if .HasSizeField { , , := obu.ReadLeb128([.Size():])if != nil {returnnil, }// We validate the obu_size_field if it is present. := .Size() + int() + int() //nolint:gosecif != {returnnil, fmt.Errorf("%w: OBU size %d does not match calculated size %d",errShortPacket, , , ) } = append(, ...) } else { .HasSizeField = true = append(, .Marshal()...) := len() - .Size() = append(, obu.WriteToLeb128(uint())...) // nolint: gosec // G104 = append(, [.Size():]...) }if {break } }if != 0 && != int(-1) {returnnil, fmt.Errorf("%w: OBU count %d does not match number of OBUs %d",errShortPacket, , , ) }return , nil}// IsPartitionHead returns true if Z in the AV1 Aggregation Header// is set to 0.func ( *AV1Depacketizer) ( []byte) bool {iflen() == 0 {returnfalse }return ([0] & av1ZMask) == 0}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.