mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-09-27 09:52:06 +08:00
159 lines
3.2 KiB
Go
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
|
|
}
|