Skip to content

Commit

Permalink
Merge branch 'pion:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
jerry-tao committed Sep 7, 2023
2 parents 76317a5 + 67d2b3e commit 14d69f4
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 91 deletions.
2 changes: 1 addition & 1 deletion .reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Pion
Source: https://github.com/pion/

Files: README.md DESIGN.md **/README.md AUTHORS.txt renovate.json go.mod go.sum .eslintrc.json package.json examples/examples.json
Files: README.md DESIGN.md **/README.md AUTHORS.txt renovate.json go.mod go.sum **/go.mod **/go.sum .eslintrc.json package.json examples/examples.json
Copyright: 2023 The Pion community <https://pion.ly>
License: MIT

Expand Down
47 changes: 47 additions & 0 deletions codecs/av1/frame/av1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

// Package frame provides code to construct complete media frames from packetized media.
package frame

import "github.com/pion/rtp/codecs"

// AV1 represents a collection of OBUs given a stream of AV1 Packets.
// Each AV1 RTP Packet is a collection of OBU Elements. Each OBU Element may be a full OBU, or just a fragment of one.
// AV1 provides the tools to construct a collection of OBUs from a collection of OBU Elements. This structure
// contains an internal cache and should be used for the entire RTP Stream.
type AV1 struct {
// Buffer for fragmented OBU. If ReadFrames is called on a RTP Packet
// that doesn't contain a fully formed OBU
obuBuffer []byte
}

func (f *AV1) pushOBUElement(isFirstOBUFragment *bool, obuElement []byte, obuList [][]byte) [][]byte {
if *isFirstOBUFragment {
*isFirstOBUFragment = false
// Discard pushed because we don't have a fragment to combine it with
if f.obuBuffer == nil {
return obuList
}
obuElement = append(f.obuBuffer, obuElement...)
f.obuBuffer = nil
}
return append(obuList, obuElement)
}

// ReadFrames processes the codecs.AV1Packet and returns fully constructed frames
func (f *AV1) ReadFrames(pkt *codecs.AV1Packet) ([][]byte, error) {
OBUs := [][]byte{}
isFirstOBUFragment := pkt.Z

for i := range pkt.OBUElements {
OBUs = f.pushOBUElement(&isFirstOBUFragment, pkt.OBUElements[i], OBUs)
}

if pkt.Y && len(OBUs) > 0 {
// Take copy of OBUElement that is being cached
f.obuBuffer = append(f.obuBuffer, append([]byte{}, OBUs[len(OBUs)-1]...)...)
OBUs = OBUs[:len(OBUs)-1]
}
return OBUs, nil
}
File renamed without changes.
69 changes: 69 additions & 0 deletions codecs/av1/obu/leb128.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

// Package obu implements tools for working with the Open Bitstream Unit.
package obu

import "errors"

const (
sevenLsbBitmask = uint(0b01111111)
msbBitmask = uint(0b10000000)
)

// ErrFailedToReadLEB128 indicates that a buffer ended before a LEB128 value could be successfully read
var ErrFailedToReadLEB128 = errors.New("payload ended before LEB128 was finished")

// EncodeLEB128 encodes a uint as LEB128
func EncodeLEB128(in uint) (out uint) {
for {
// Copy seven bits from in and discard
// what we have copied from in
out |= (in & sevenLsbBitmask)
in >>= 7

// If we have more bits to encode set MSB
// otherwise we are done
if in != 0 {
out |= msbBitmask
out <<= 8
} else {
return out
}
}
}

func decodeLEB128(in uint) (out uint) {
for {
// Take 7 LSB from in
out |= (in & sevenLsbBitmask)

// Discard the MSB
in >>= 8
if in == 0 {
return out
}

out <<= 7
}
}

// ReadLeb128 scans an buffer and decodes a Leb128 value.
// If the end of the buffer is reached and all MSB are set
// an error is returned
func ReadLeb128(in []byte) (uint, uint, error) {
var encodedLength uint

for i := range in {
encodedLength |= uint(in[i])

if in[i]&byte(msbBitmask) == 0 {
return decodeLEB128(encodedLength), uint(i + 1), nil
}

// Make more room for next read
encodedLength <<= 8
}

return 0, 0, ErrFailedToReadLEB128
}
File renamed without changes.
2 changes: 1 addition & 1 deletion codecs/av1_packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
package codecs

import (
"github.com/pion/rtp/pkg/obu"
"github.com/pion/rtp/codecs/av1/obu"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion codecs/av1_packet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"reflect"
"testing"

"github.com/pion/rtp/pkg/obu"
"github.com/pion/rtp/codecs/av1/obu"
)

func TestAV1_Marshal(t *testing.T) {
Expand Down
44 changes: 7 additions & 37 deletions pkg/frame/av1.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,17 @@
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

// Package frame provides code to construct complete media frames from packetized media
// Package frame is deprecated.
package frame

import "github.com/pion/rtp/codecs"
import (
"github.com/pion/rtp/codecs/av1/frame"
)

// AV1 represents a collection of OBUs given a stream of AV1 Packets.
// Each AV1 RTP Packet is a collection of OBU Elements. Each OBU Element may be a full OBU, or just a fragment of one.
// AV1 provides the tools to construct a collection of OBUs from a collection of OBU Elements. This structure
// contains an internal cache and should be used for the entire RTP Stream.
type AV1 struct {
// Buffer for fragmented OBU. If ReadFrames is called on a RTP Packet
// that doesn't contain a fully formed OBU
obuBuffer []byte
}

func (f *AV1) pushOBUElement(isFirstOBUFragment *bool, obuElement []byte, obuList [][]byte) [][]byte {
if *isFirstOBUFragment {
*isFirstOBUFragment = false
// Discard pushed because we don't have a fragment to combine it with
if f.obuBuffer == nil {
return obuList
}
obuElement = append(f.obuBuffer, obuElement...)
f.obuBuffer = nil
}
return append(obuList, obuElement)
}

// ReadFrames processes the codecs.AV1Packet and returns fully constructed frames
func (f *AV1) ReadFrames(pkt *codecs.AV1Packet) ([][]byte, error) {
OBUs := [][]byte{}
isFirstOBUFragment := pkt.Z

for i := range pkt.OBUElements {
OBUs = f.pushOBUElement(&isFirstOBUFragment, pkt.OBUElements[i], OBUs)
}

if pkt.Y && len(OBUs) > 0 {
// Take copy of OBUElement that is being cached
f.obuBuffer = append(f.obuBuffer, append([]byte{}, OBUs[len(OBUs)-1]...)...)
OBUs = OBUs[:len(OBUs)-1]
}
return OBUs, nil
}
//
// Deprecated: moved into codecs/av1/frame.
type AV1 = frame.AV1
63 changes: 12 additions & 51 deletions pkg/obu/leb128.go
Original file line number Diff line number Diff line change
@@ -1,69 +1,30 @@
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

// Package obu implements tools for working with the "Open Bitstream Unit"
// Package obu is deprecated.
package obu

import "errors"

const (
sevenLsbBitmask = uint(0b01111111)
msbBitmask = uint(0b10000000)
import (
"github.com/pion/rtp/codecs/av1/obu"
)

// ErrFailedToReadLEB128 indicates that a buffer ended before a LEB128 value could be successfully read
var ErrFailedToReadLEB128 = errors.New("payload ended before LEB128 was finished")
//
// Deprecated: moved into codecs/av1/obu.
var ErrFailedToReadLEB128 = obu.ErrFailedToReadLEB128

// EncodeLEB128 encodes a uint as LEB128
//
// Deprecated: moved into codecs/av1/obu.
func EncodeLEB128(in uint) (out uint) {
for {
// Copy seven bits from in and discard
// what we have copied from in
out |= (in & sevenLsbBitmask)
in >>= 7

// If we have more bits to encode set MSB
// otherwise we are done
if in != 0 {
out |= msbBitmask
out <<= 8
} else {
return out
}
}
}

func decodeLEB128(in uint) (out uint) {
for {
// Take 7 LSB from in
out |= (in & sevenLsbBitmask)

// Discard the MSB
in >>= 8
if in == 0 {
return out
}

out <<= 7
}
return obu.EncodeLEB128(in)
}

// ReadLeb128 scans an buffer and decodes a Leb128 value.
// If the end of the buffer is reached and all MSB are set
// an error is returned
//
// Deprecated: moved into codecs/av1/obu.
func ReadLeb128(in []byte) (uint, uint, error) {
var encodedLength uint

for i := range in {
encodedLength |= uint(in[i])

if in[i]&byte(msbBitmask) == 0 {
return decodeLEB128(encodedLength), uint(i + 1), nil
}

// Make more room for next read
encodedLength <<= 8
}

return 0, 0, ErrFailedToReadLEB128
return obu.ReadLeb128(in)
}

0 comments on commit 14d69f4

Please sign in to comment.