Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move pkg into codecs/av1 #237

Merged
merged 1 commit into from
Aug 15, 2023
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
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)
}
Loading