Files
engine/track/base.go
dexter 5b51e8c494 1.修复读取ts中aac格式数据多次flush问题
2.修复subscribe结束时判断IsClosed调用对象错误
3.增加DefaultYaml功能
2023-01-03 18:55:32 +08:00

188 lines
5.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package track
import (
"context"
"time"
"unsafe"
. "m7s.live/engine/v4/common"
"m7s.live/engine/v4/config"
"m7s.live/engine/v4/util"
)
type 流速控制 struct {
起始时间戳 uint32
起始时间 time.Time
等待上限 time.Duration
}
func (p *流速控制) 重置(绝对时间戳 uint32) {
p.起始时间 = time.Now()
p.起始时间戳 = 绝对时间戳
// println("重置", p.起始时间.Format("2006-01-02 15:04:05"), p.起始时间戳)
}
func (p *流速控制) 时间戳差(绝对时间戳 uint32) time.Duration {
return time.Duration(绝对时间戳-p.起始时间戳) * time.Millisecond
}
func (p *流速控制) 控制流速(绝对时间戳 uint32) {
数据时间差, 实际时间差 := p.时间戳差(绝对时间戳), time.Since(p.起始时间)
// println("数据时间差", 数据时间差, "实际时间差", 实际时间差, "绝对时间戳", 绝对时间戳, "起始时间戳", p.起始时间戳, "起始时间", p.起始时间.Format("2006-01-02 15:04:05"))
// if 实际时间差 > 数据时间差 {
// p.重置(绝对时间戳)
// return
// }
// 如果收到的帧的时间戳超过实际消耗的时间100ms就休息一下100ms作为一个弹性区间防止频繁调用sleep
if 过快毫秒 := (数据时间差 - 实际时间差) / time.Millisecond; 过快毫秒 > 300 {
if 过快毫秒 > p.等待上限 {
time.Sleep(time.Millisecond * p.等待上限)
} else {
time.Sleep(过快毫秒 * time.Millisecond)
}
}
}
// Media 基础媒体Track类
type Media[T RawSlice] struct {
Base
AVRing[T]
SampleRate uint32
SSRC uint32
DecoderConfiguration DecoderConfiguration[T] `json:"-"` //H264(SPS、PPS) H265(VPS、SPS、PPS) AAC(config)
// util.BytesPool //无锁内存池,用于发布者(在同一个协程中)复用小块的内存,通常是解包时需要临时使用
RTPMuxer
RTPDemuxer
流速控制
}
func (av *Media[T]) SetSpeedLimit(value int) {
av.等待上限 = time.Duration(value)
}
func (av *Media[T]) SetStuff(stuff ...any) {
for _, s := range stuff {
switch v := s.(type) {
case time.Duration:
av.Poll = v
case string:
av.Name = v
case int:
av.AVRing.Init(v)
av.SSRC = uint32(uintptr(unsafe.Pointer(av)))
av.等待上限 = time.Duration(config.Global.SpeedLimit)
case uint32:
av.SampleRate = v
case byte:
av.DecoderConfiguration.PayloadType = v
case IStream:
av.Stream = v
case RTPWriter:
av.RTPWriter = v
}
}
}
func (av *Media[T]) LastWriteTime() time.Time {
return av.AVRing.RingBuffer.LastValue.Timestamp
}
func (av *Media[T]) Play(ctx context.Context, onMedia func(*AVFrame[T]) error) error {
for ar := av.ReadRing(); ctx.Err() == nil; ar.MoveNext() {
ap := ar.Read(ctx)
if err := onMedia(ap); err != nil {
// TODO: log err
return err
}
}
return ctx.Err()
}
func (av *Media[T]) ReadRing() *AVRing[T] {
return util.Clone(av.AVRing)
}
func (av *Media[T]) GetDecoderConfiguration() DecoderConfiguration[T] {
return av.DecoderConfiguration
}
func (av *Media[T]) CurrentFrame() *AVFrame[T] {
return &av.AVRing.RingBuffer.Value
}
func (av *Media[T]) PreFrame() *AVFrame[T] {
return av.AVRing.RingBuffer.LastValue
}
func (av *Media[T]) generateTimestamp() {
ts := av.AVRing.RingBuffer.Value.RTP[0].Timestamp
av.AVRing.RingBuffer.Value.PTS = ts
av.AVRing.RingBuffer.Value.DTS = ts
}
func (av *Media[T]) WriteSlice(slice T) {
av.Value.AppendRaw(slice)
}
func (av *Media[T]) WriteAVCC(ts uint32, frame AVCCFrame) {
curValue := &av.Value
cts := frame.CTS()
curValue.BytesIn += len(frame)
curValue.AppendAVCC(frame)
curValue.DTS = ts * 90
curValue.PTS = (ts + cts) * 90
// av.Stream.Tracef("WriteAVCC:ts %d,cts %d,len %d", ts, cts, len(frame))
}
func (av *Media[T]) Flush() {
curValue, preValue := &av.Value, av.LastValue
if av.起始时间.IsZero() {
av.重置(curValue.AbsTime)
} else {
curValue.DeltaTime = (curValue.DTS - preValue.DTS) / 90
println(curValue.DeltaTime ,curValue.DTS , preValue.DTS)
curValue.AbsTime = preValue.AbsTime + curValue.DeltaTime
}
av.Base.Flush(&curValue.BaseFrame)
if av.等待上限 > 0 {
av.控制流速(curValue.AbsTime)
}
av.Step()
}
func (av *Media[T]) ComplementAVCC() bool {
return config.Global.EnableAVCC && len(av.Value.AVCC) == 0
}
// 是否需要补完RTP格式
func (av *Media[T]) ComplementRTP() bool {
return config.Global.EnableRTP && len(av.Value.RTP) == 0
}
// https://www.cnblogs.com/moonwalk/p/15903760.html
// Packetize packetizes the payload of an RTP packet and returns one or more RTP packets
func (av *Media[T]) PacketizeRTP(payloads ...[][]byte) {
packetCount := len(payloads)
if cap(av.Value.RTP) < packetCount {
av.Value.RTP = make([]*RTPFrame, packetCount)
} else {
av.Value.RTP = av.Value.RTP[:packetCount]
}
for i, pp := range payloads {
av.rtpSequence++
packet := av.Value.RTP[i]
if packet == nil {
packet = &RTPFrame{}
av.Value.RTP[i] = packet
packet.Version = 2
packet.PayloadType = av.DecoderConfiguration.PayloadType
packet.Payload = make([]byte, 0, 1200)
packet.SSRC = av.SSRC
}
packet.Payload = packet.Payload[:0]
packet.SequenceNumber = av.rtpSequence
packet.Timestamp = av.Value.PTS
packet.Marker = i == packetCount-1
for _, p := range pp {
packet.Payload = append(packet.Payload, p...)
}
}
}