Files
monibuca/pkg/avframe.go
2024-04-01 20:37:22 +08:00

159 lines
3.2 KiB
Go

package pkg
import (
"net"
"sync"
"sync/atomic"
"time"
"github.com/bluenviron/mediacommon/pkg/codecs/av1"
"m7s.live/m7s/v5/pkg/util"
)
type AVFrame struct {
DataFrame
Timestamp time.Duration // 绝对时间戳
Wrap IAVFrame `json:"-" yaml:"-"` // 封装格式
}
type DataFrame struct {
WriteTime time.Time // 写入时间,可用于比较两个帧的先后
Sequence uint32 // 在一个Track中的序号
BytesIn int // 输入字节数用于计算BPS
CanRead bool `json:"-" yaml:"-"` // 是否可读取
readerCount atomic.Int32 `json:"-" yaml:"-"` // 读取者数量
Raw any `json:"-" yaml:"-"` // 裸格式
sync.Cond `json:"-" yaml:"-"`
}
func (df *DataFrame) IsWriting() bool {
return !df.CanRead
}
func (df *DataFrame) IsDiscarded() bool {
return df.L == nil
}
func (df *DataFrame) Discard() int32 {
df.L = nil //标记为废弃
return df.readerCount.Load()
}
func (df *DataFrame) SetSequence(sequence uint32) {
df.Sequence = sequence
}
func (df *DataFrame) GetSequence() uint32 {
return df.Sequence
}
func (df *DataFrame) ReaderEnter() int32 {
return df.readerCount.Add(1)
}
func (df *DataFrame) ReaderCount() int32 {
return df.readerCount.Load()
}
func (df *DataFrame) ReaderLeave() int32 {
return df.readerCount.Add(-1)
}
func (df *DataFrame) StartWrite() bool {
if df.readerCount.Load() > 0 {
df.Discard() //标记为废弃
return false
} else {
df.Init()
df.CanRead = false //标记为正在写入
return true
}
}
func (df *DataFrame) Ready() {
df.WriteTime = time.Now()
df.CanRead = true //标记为可读取
df.Broadcast()
}
func (df *DataFrame) Init() {
df.L = EmptyLocker
}
func (df *DataFrame) Reset() {
df.BytesIn = 0
}
type ICodecCtx interface {
GetSequenceFrame() IAVFrame
}
type IDataFrame interface {
}
type IAVFrame interface {
DecodeConfig(*AVTrack) error
ToRaw(*AVTrack) (any, error)
FromRaw(*AVTrack, any) error
GetTimestamp() time.Duration
Recycle()
IsIDR() bool
Print() string
}
type Nalu [][]byte
type Nalus struct {
PTS time.Duration
DTS time.Duration
Nalus []Nalu
}
func (nalus *Nalus) Append(bytes ...[]byte) {
nalus.Nalus = append(nalus.Nalus, Nalu(bytes))
}
func (nalus *Nalus) ParseAVCC(reader *util.Buffers, naluSizeLen int) error {
for reader.Length > 0 {
l, err := reader.ReadBE(naluSizeLen)
if err != nil {
return err
}
nalu, err := reader.ReadBytes(int(l))
if err != nil {
return err
}
nalus.Append(nalu)
}
return nil
}
type OBUs struct {
PTS time.Duration
OBUs []net.Buffers
}
func (obus *OBUs) Append(bytes ...[]byte) {
obus.OBUs = append(obus.OBUs, bytes)
}
func (obus *OBUs) ParseAVCC(reader *util.Buffers) error {
var obuHeader av1.OBUHeader
for reader.Length > 0 {
offset := reader.Offset
b, _ := reader.ReadByte()
obuHeader.Unmarshal([]byte{b})
// if log.Trace {
// vt.Trace("obu", zap.Any("type", obuHeader.Type), zap.Bool("iframe", vt.Value.IFrame))
// }
obuSize, _, _ := reader.LEB128Unmarshal()
end := reader.Offset
size := end - offset + int(obuSize)
reader = &util.Buffers{Buffers: reader.Buffers}
reader.Skip(offset)
obu, err := reader.ReadBytes(size)
if err != nil {
return err
}
obus.Append(obu)
}
return nil
}