mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-05 08:36:56 +08:00
ring 功能修复
This commit is contained in:
@@ -129,6 +129,7 @@ func (at *AudioTrack) push(pack *AudioPack) {
|
|||||||
at.bytes = 0
|
at.bytes = 0
|
||||||
at.ts = pack.Timestamp
|
at.ts = pack.Timestamp
|
||||||
}
|
}
|
||||||
|
at.lastTs = pack.Timestamp
|
||||||
at.Step()
|
at.Step()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,7 +16,6 @@ type Track interface {
|
|||||||
|
|
||||||
type AVPack interface {
|
type AVPack interface {
|
||||||
Since(uint32) uint32
|
Since(uint32) uint32
|
||||||
Distance(int) int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type BasePack struct {
|
type BasePack struct {
|
||||||
@@ -30,10 +29,6 @@ func (p *BasePack) Since(ts uint32) uint32 {
|
|||||||
return p.Timestamp - ts
|
return p.Timestamp - ts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *BasePack) Distance(sq int) int {
|
|
||||||
return p.Sequence - sq
|
|
||||||
}
|
|
||||||
|
|
||||||
type Track_Base struct {
|
type Track_Base struct {
|
||||||
RingDisposable `json:"-"`
|
RingDisposable `json:"-"`
|
||||||
Stream *Stream `json:"-"`
|
Stream *Stream `json:"-"`
|
||||||
@@ -42,6 +37,7 @@ type Track_Base struct {
|
|||||||
BPS int
|
BPS int
|
||||||
bytes int // GOP内的数据大小
|
bytes int // GOP内的数据大小
|
||||||
ts uint32 // GOP起始时间戳
|
ts uint32 // GOP起始时间戳
|
||||||
|
lastTs uint32 //最新的时间戳
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Track_Base) GetBPS() {
|
func (t *Track_Base) GetBPS() {
|
||||||
|
@@ -85,7 +85,7 @@ func (s *Subscriber) Play(at *AudioTrack, vt *VideoTrack) {
|
|||||||
}
|
}
|
||||||
vr := vt.SubRing(vt.IDRing) //从关键帧开始读取,首屏秒开
|
vr := vt.SubRing(vt.IDRing) //从关键帧开始读取,首屏秒开
|
||||||
ar := at.Clone()
|
ar := at.Clone()
|
||||||
dropping := false //是否处于丢帧中
|
// dropping := false //是否处于丢帧中
|
||||||
vp := vr.Read().(*VideoPack)
|
vp := vr.Read().(*VideoPack)
|
||||||
ap := ar.Read().(*AudioPack)
|
ap := ar.Read().(*AudioPack)
|
||||||
startTimestamp := vp.Timestamp
|
startTimestamp := vp.Timestamp
|
||||||
@@ -97,23 +97,25 @@ func (s *Subscriber) Play(at *AudioTrack, vt *VideoTrack) {
|
|||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
if ap.Timestamp > vp.Timestamp || ap.Timestamp == 0 {
|
if ap.Timestamp > vp.Timestamp || ap.Timestamp == 0 {
|
||||||
if !dropping {
|
|
||||||
s.OnVideo(vp.Copy(startTimestamp))
|
s.OnVideo(vp.Copy(startTimestamp))
|
||||||
if vt.CurrentValue().(AVPack).Since(vp.Timestamp) > 1000 {
|
// if !dropping {
|
||||||
dropping = true
|
// s.OnVideo(vp.Copy(startTimestamp))
|
||||||
}
|
// if vt.lastTs - vp.Timestamp > 1000 {
|
||||||
} else if vp.IDR {
|
// dropping = true
|
||||||
dropping = false
|
// }
|
||||||
}
|
// } else if vp.IDR {
|
||||||
|
// dropping = false
|
||||||
|
// }
|
||||||
vr.MoveNext()
|
vr.MoveNext()
|
||||||
vp = vr.Read().(*VideoPack)
|
vp = vr.Read().(*VideoPack)
|
||||||
} else {
|
} else {
|
||||||
if !dropping {
|
|
||||||
s.OnAudio(ap.Copy(startTimestamp))
|
s.OnAudio(ap.Copy(startTimestamp))
|
||||||
if at.CurrentValue().(AVPack).Since(ap.Timestamp) > 1000 {
|
// if !dropping {
|
||||||
dropping = true
|
// s.OnAudio(ap.Copy(startTimestamp))
|
||||||
}
|
// if at.CurrentValue().(AVPack).Since(ap.Timestamp) > 1000 {
|
||||||
}
|
// dropping = true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
ar.MoveNext()
|
ar.MoveNext()
|
||||||
ap = ar.Read().(*AudioPack)
|
ap = ar.Read().(*AudioPack)
|
||||||
}
|
}
|
||||||
@@ -128,14 +130,14 @@ func (s *Subscriber) PlayAudio(at *AudioTrack) {
|
|||||||
droped := 0
|
droped := 0
|
||||||
var action, send func()
|
var action, send func()
|
||||||
drop := func() {
|
drop := func() {
|
||||||
if at.CurrentValue().(AVPack).Distance(ap.Sequence) < 4 {
|
if at.current().Sequence-ap.Sequence < 4 {
|
||||||
action = send
|
action = send
|
||||||
} else {
|
} else {
|
||||||
droped++
|
droped++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
send = func() {
|
send = func() {
|
||||||
if s.OnAudio(ap.Copy(startTimestamp)); at.CurrentValue().(AVPack).Since(ap.Timestamp) > 1000 {
|
if s.OnAudio(ap.Copy(startTimestamp)); at.lastTs -ap.Timestamp > 1000 {
|
||||||
action = drop
|
action = drop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +181,7 @@ func (s *Subscriber) PlayVideo(vt *VideoTrack) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
send = func() {
|
send = func() {
|
||||||
if s.OnVideo(vp.Copy(startTimestamp)); vt.CurrentValue().(AVPack).Since(vp.Timestamp) > 1000 {
|
if s.OnVideo(vp.Copy(startTimestamp)); vt.lastTs - vp.Timestamp > 1000 {
|
||||||
action = drop
|
action = drop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,7 +34,6 @@ func (vp VideoPack) Copy(ts uint32) VideoPack {
|
|||||||
|
|
||||||
type VideoTrack struct {
|
type VideoTrack struct {
|
||||||
IDRing *ring.Ring //最近的关键帧位置,首屏渲染
|
IDRing *ring.Ring //最近的关键帧位置,首屏渲染
|
||||||
lastIDR *VideoPack
|
|
||||||
Track_Base
|
Track_Base
|
||||||
SPSInfo codec.SPSInfo
|
SPSInfo codec.SPSInfo
|
||||||
GOP int //关键帧间隔
|
GOP int //关键帧间隔
|
||||||
@@ -59,21 +58,25 @@ func (s *Stream) NewVideoTrack(codec byte) (vt *VideoTrack) {
|
|||||||
vt = &VideoTrack{
|
vt = &VideoTrack{
|
||||||
revIDR: func() {
|
revIDR: func() {
|
||||||
vt.IDRing = vt.Ring
|
vt.IDRing = vt.Ring
|
||||||
vt.lastIDR = vt.CurrentValue().(*VideoPack)
|
|
||||||
cancel()
|
cancel()
|
||||||
|
idrSequence := vt.current().Sequence
|
||||||
|
l := vt.Ring.Len()
|
||||||
vt.revIDR = func() {
|
vt.revIDR = func() {
|
||||||
current := vt.CurrentValue().(*VideoPack)
|
current := vt.current()
|
||||||
vt.GOP = current.Distance(vt.lastIDR.Sequence)
|
if vt.GOP = current.Sequence - idrSequence; vt.GOP > l-1 {
|
||||||
if l := vt.Ring.Len(); vt.IDRing.Value != vt.lastIDR {
|
|
||||||
//缓冲环不够大,导致IDR被覆盖
|
//缓冲环不够大,导致IDR被覆盖
|
||||||
exRing := NewRingBuffer(vt.GOP - l + 5).Ring
|
exRing := NewRingBuffer(vt.GOP - l + 5).Ring
|
||||||
exRing.Do(vt.initVideoRing)
|
exRing.Do(vt.initVideoRing)
|
||||||
vt.Link(exRing) // 扩大缓冲环
|
vt.Link(exRing) // 扩大缓冲环
|
||||||
|
l = vt.Ring.Len()
|
||||||
|
utils.Printf("%s ring grow to %d", s.StreamPath, l)
|
||||||
} else if vt.GOP < l-5 {
|
} else if vt.GOP < l-5 {
|
||||||
vt.Unlink(l - vt.GOP - 5) //缩小缓冲环节省内存
|
vt.Unlink(l - vt.GOP - 5) //缩小缓冲环节省内存
|
||||||
|
l = vt.Ring.Len()
|
||||||
|
utils.Printf("%s ring atrophy to %d", s.StreamPath, l)
|
||||||
}
|
}
|
||||||
vt.IDRing = vt.Ring
|
vt.IDRing = vt.Ring
|
||||||
vt.lastIDR = current
|
idrSequence = current.Sequence
|
||||||
vt.ts = current.Timestamp
|
vt.ts = current.Timestamp
|
||||||
vt.bytes = 0
|
vt.bytes = 0
|
||||||
}
|
}
|
||||||
@@ -492,15 +495,17 @@ func (vt *VideoTrack) pushByteStream(ts uint32, payload []byte) {
|
|||||||
}
|
}
|
||||||
// 已完成序列帧组装,重置Push函数,从Payload中提取Nalu供非bytestream格式使用
|
// 已完成序列帧组装,重置Push函数,从Payload中提取Nalu供非bytestream格式使用
|
||||||
vt.PushByteStream = func(ts uint32, payload []byte) {
|
vt.PushByteStream = func(ts uint32, payload []byte) {
|
||||||
pack := vt.CurrentValue().(*VideoPack)
|
pack := vt.current()
|
||||||
if len(payload) < 4 {
|
if len(payload) < 4 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
vt.bytes += len(payload)
|
vt.bytes += len(payload)
|
||||||
|
pack.IDR = payload[0]>>4 == 1
|
||||||
pack.Timestamp = ts
|
pack.Timestamp = ts
|
||||||
pack.Sequence = vt.PacketCount
|
pack.Sequence = vt.PacketCount
|
||||||
pack.Payload = payload
|
pack.Payload = payload
|
||||||
pack.CompositionTime = utils.BigEndian.Uint24(payload[2:])
|
pack.CompositionTime = utils.BigEndian.Uint24(payload[2:])
|
||||||
|
pack.NALUs = nil
|
||||||
for nalus := payload[5:]; len(nalus) > nalulenSize; {
|
for nalus := payload[5:]; len(nalus) > nalulenSize; {
|
||||||
nalulen := 0
|
nalulen := 0
|
||||||
for i := 0; i < nalulenSize; i++ {
|
for i := 0; i < nalulenSize; i++ {
|
||||||
@@ -522,9 +527,9 @@ func (vt *VideoTrack) push(pack *VideoPack) {
|
|||||||
vt.writeByteStream(pack)
|
vt.writeByteStream(pack)
|
||||||
}
|
}
|
||||||
vt.GetBPS()
|
vt.GetBPS()
|
||||||
pack.Sequence = vt.PacketCount
|
if pack.Sequence = vt.PacketCount; pack.IDR {
|
||||||
if pack.IDR {
|
vt.revIDR()
|
||||||
defer vt.revIDR()
|
|
||||||
}
|
}
|
||||||
|
vt.lastTs = pack.Timestamp
|
||||||
vt.Step()
|
vt.Step()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user