GOP追帧

This commit is contained in:
dexter
2021-08-19 14:38:05 +08:00
parent 8b2f91b4de
commit 3a16fe7883
4 changed files with 84 additions and 90 deletions

104
ring.go
View File

@@ -12,7 +12,7 @@ import (
type DataItem struct { type DataItem struct {
Timestamp time.Time Timestamp time.Time
Sequence int Sequence int
Value interface{} Value interface{}
} }
// TODO: 池化,泛型 // TODO: 池化,泛型
@@ -28,123 +28,123 @@ type RingBuffer struct {
context.Context context.Context
} }
func (r *RingBuffer) Init(ctx context.Context, n int) *RingBuffer { func (rb *RingBuffer) Init(ctx context.Context, n int) *RingBuffer {
var flag int32 var flag int32
if r == nil { if rb == nil {
r = &RingBuffer{Context: ctx, Ring: ring.New(n), Flag: &flag} rb = &RingBuffer{Context: ctx, Ring: ring.New(n), Flag: &flag}
} else { } else {
r.Ring = ring.New(n) rb.Ring = ring.New(n)
r.Context = ctx rb.Context = ctx
r.Flag = &flag rb.Flag = &flag
} }
for x := r.Ring; x.Value == nil; x = x.Next() { for x := rb.Ring; x.Value == nil; x = x.Next() {
x.Value = new(LockItem) x.Value = new(LockItem)
} }
r.Current().Lock() rb.Current().Lock()
return r return rb
} }
func (rb RingBuffer) Clone() *RingBuffer { func (rb RingBuffer) Clone() *RingBuffer {
return &rb return &rb
} }
func (r RingBuffer) SubRing(rr *ring.Ring) *RingBuffer { func (rb RingBuffer) SubRing(rr *ring.Ring) *RingBuffer {
r.Ring = rr rb.Ring = rr
return &r return &rb
} }
func (r *RingBuffer) CurrentValue() interface{} { func (rb *RingBuffer) CurrentValue() interface{} {
return r.Current().Value return rb.Current().Value
} }
func (r *RingBuffer) NextValue() interface{} { func (rb *RingBuffer) NextValue() interface{} {
return r.Next().Value.(*LockItem).Value return rb.Next().Value.(*LockItem).Value
} }
func (r *RingBuffer) Current() *LockItem { func (rb *RingBuffer) Current() *LockItem {
return r.Ring.Value.(*LockItem) return rb.Ring.Value.(*LockItem)
} }
func (r *RingBuffer) MoveNext() { func (rb *RingBuffer) MoveNext() {
r.Ring = r.Next() rb.Ring = rb.Next()
} }
func (r *RingBuffer) GetNext() *LockItem { func (rb *RingBuffer) GetNext() *LockItem {
r.MoveNext() rb.MoveNext()
return r.Current() return rb.Current()
} }
func (r *RingBuffer) Read() interface{} { func (rb *RingBuffer) Read() interface{} {
current := r.Current() current := rb.Current()
current.RLock() current.RLock()
defer current.RUnlock() defer current.RUnlock()
return current.Value return current.Value
} }
func (r *RingBuffer) Step() { func (rb *RingBuffer) Step() {
last := r.Current() last := rb.Current()
if atomic.CompareAndSwapInt32(r.Flag, 0, 1) { if atomic.CompareAndSwapInt32(rb.Flag, 0, 1) {
current := r.GetNext() current := rb.GetNext()
current.Lock() current.Lock()
last.Unlock() last.Unlock()
//Flag不为1代表被Dispose了但尚未处理Done //Flag不为1代表被Dispose了但尚未处理Done
if !atomic.CompareAndSwapInt32(r.Flag, 1, 0) { if !atomic.CompareAndSwapInt32(rb.Flag, 1, 0) {
current.Unlock() current.Unlock()
} }
} }
} }
func (r *RingBuffer) Write(value interface{}) { func (rb *RingBuffer) Write(value interface{}) {
last := r.Current() last := rb.Current()
last.Value = value last.Value = value
if atomic.CompareAndSwapInt32(r.Flag, 0, 1) { if atomic.CompareAndSwapInt32(rb.Flag, 0, 1) {
current := r.GetNext() current := rb.GetNext()
current.Lock() current.Lock()
last.Unlock() last.Unlock()
//Flag不为1代表被Dispose了但尚未处理Done //Flag不为1代表被Dispose了但尚未处理Done
if !atomic.CompareAndSwapInt32(r.Flag, 1, 0) { if !atomic.CompareAndSwapInt32(rb.Flag, 1, 0) {
current.Unlock() current.Unlock()
} }
} }
} }
func (r *RingBuffer) Dispose() { func (rb *RingBuffer) Dispose() {
current := r.Current() current := rb.Current()
if atomic.CompareAndSwapInt32(r.Flag, 0, 2) { if atomic.CompareAndSwapInt32(rb.Flag, 0, 2) {
current.Unlock() current.Unlock()
} else if atomic.CompareAndSwapInt32(r.Flag, 1, 2) { } else if atomic.CompareAndSwapInt32(rb.Flag, 1, 2) {
//当前是1代表正在写入此时变成2但是Done的任务得交给NextW来处理 //当前是1代表正在写入此时变成2但是Done的任务得交给NextW来处理
} else if atomic.CompareAndSwapInt32(r.Flag, 0, 2) { } else if atomic.CompareAndSwapInt32(rb.Flag, 0, 2) {
current.Unlock() current.Unlock()
} }
} }
func (r *RingBuffer) read() reflect.Value { func (rb *RingBuffer) read() reflect.Value {
return reflect.ValueOf(r.Read()) return reflect.ValueOf(rb.Read())
} }
func (r *RingBuffer) nextRead() reflect.Value { func (rb *RingBuffer) nextRead() reflect.Value {
r.MoveNext() rb.MoveNext()
return r.read() return rb.read()
} }
// ReadLoop 循环读取,采用了反射机制,不适用高性能场景 // ReadLoop 循环读取,采用了反射机制,不适用高性能场景
// handler入参可以传入回调函数或者channel // handler入参可以传入回调函数或者channel
func (r *RingBuffer) ReadLoop(handler interface{}) { func (rb *RingBuffer) ReadLoop(handler interface{}) {
r.ReadLoopConditional(handler, func() bool { rb.ReadLoopConditional(handler, func() bool {
return r.Err() == nil && *r.Flag != 2 return rb.Err() == nil && *rb.Flag != 2
}) })
} }
// goon判断函数用来判断是否继续读取,返回false将终止循环 // goon判断函数用来判断是否继续读取,返回false将终止循环
func (r *RingBuffer) ReadLoopConditional(handler interface{}, goon func() bool) { func (rb *RingBuffer) ReadLoopConditional(handler interface{}, goon func() bool) {
switch t := reflect.ValueOf(handler); t.Kind() { switch t := reflect.ValueOf(handler); t.Kind() {
case reflect.Chan: case reflect.Chan:
for v := r.read(); goon(); v = r.nextRead() { for v := rb.read(); goon(); v = rb.nextRead() {
t.Send(v) t.Send(v)
} }
case reflect.Func: case reflect.Func:
for args := []reflect.Value{r.read()}; goon(); args[0] = r.nextRead() { for args := []reflect.Value{rb.read()}; goon(); args[0] = rb.nextRead() {
t.Call(args) t.Call(args)
} }
} }

View File

@@ -3,7 +3,6 @@ package engine
import ( import (
"container/ring" "container/ring"
"context" "context"
"reflect"
"runtime" "runtime"
"time" "time"
) )
@@ -11,8 +10,8 @@ import (
type AVItem struct { type AVItem struct {
Timestamp uint32 Timestamp uint32
Sequence int Sequence int
Value interface{} Value interface{}
canRead bool canRead bool
} }
func (p *AVItem) Since(ts uint32) uint32 { func (p *AVItem) Since(ts uint32) uint32 {
@@ -36,8 +35,8 @@ func (r *AVRing) Init(ctx context.Context, n int) *AVRing {
} }
return r return r
} }
func (rb AVRing) Clone() *AVRing { func (r AVRing) Clone() *AVRing {
return &rb return &r
} }
func (r AVRing) SubRing(rr *ring.Ring) *AVRing { func (r AVRing) SubRing(rr *ring.Ring) *AVRing {
@@ -65,19 +64,6 @@ func (r *AVRing) wait() {
} }
} }
func (r *AVRing) read() reflect.Value {
current := r.Current()
for r.Err() == nil && !current.canRead {
r.wait()
}
return reflect.ValueOf(current.Value)
}
func (r *AVRing) nextRead() reflect.Value {
r.MoveNext()
return r.read()
}
func (r *AVRing) CurrentValue() interface{} { func (r *AVRing) CurrentValue() interface{} {
return r.Current().Value return r.Current().Value
} }
@@ -93,6 +79,9 @@ func (r *AVRing) NextRead() (item *AVItem, value interface{}) {
func (r *AVRing) NextValue() interface{} { func (r *AVRing) NextValue() interface{} {
return r.Next().Value.(*AVItem).Value return r.Next().Value.(*AVItem).Value
} }
func (r *AVRing) PreItem() *AVItem {
return r.Prev().Value.(*AVItem)
}
func (r *AVRing) GetNext() *AVItem { func (r *AVRing) GetNext() *AVItem {
r.MoveNext() r.MoveNext()
return r.Current() return r.Current()
@@ -104,18 +93,3 @@ func (r *AVRing) Read() (item *AVItem, value interface{}) {
} }
return current, current.Value return current, current.Value
} }
// ReadLoop 循环读取,采用了反射机制,不适用高性能场景
// handler入参可以传入回调函数或者channel
func (r *AVRing) ReadLoop(handler interface{}) {
switch t := reflect.ValueOf(handler); t.Kind() {
case reflect.Chan:
for v := r.read(); r.Err() == nil; v = r.nextRead() {
t.Send(v)
}
case reflect.Func:
for args := []reflect.Value{r.read()}; r.Err() == nil; args[0] = r.nextRead() {
t.Call(args)
}
}
}

View File

@@ -82,11 +82,13 @@ func (s *Subscriber) Play(at *AudioTrack, vt *VideoTrack) {
case <-extraExit: //可能等不到关键帧就退出了 case <-extraExit: //可能等不到关键帧就退出了
return return
} }
vr := vt.SubRing(vt.IDRing) //从关键帧开始读取,首屏秒开 vr := vt.SubRing(vt.IDRing) //从关键帧开始读取,首屏秒开
realSt := vt.PreItem().Timestamp // 当前时间戳
ar := at.Clone() ar := at.Clone()
iv, vp := vr.Read() iv, vp := vr.Read()
ia, ap := ar.Read() ia, ap := ar.Read()
vst, ast := iv.Timestamp, ia.Timestamp vst := iv.Timestamp
chase := true
for { for {
select { select {
case <-extraExit: case <-extraExit:
@@ -96,10 +98,18 @@ func (s *Subscriber) Play(at *AudioTrack, vt *VideoTrack) {
default: default:
if ia.Timestamp > iv.Timestamp || ia.Timestamp == 0 { if ia.Timestamp > iv.Timestamp || ia.Timestamp == 0 {
s.OnVideo(iv.Timestamp-vst, vp.(*VideoPack)) s.OnVideo(iv.Timestamp-vst, vp.(*VideoPack))
if chase {
if vst < realSt-10 {
vst += 10
} else {
vst = realSt
chase = false
}
}
vr.MoveNext() vr.MoveNext()
iv, vp = vr.Read() iv, vp = vr.Read()
} else { } else {
s.OnAudio(ia.Timestamp-ast, ap.(*AudioPack)) s.OnAudio(ia.Timestamp-vst, ap.(*AudioPack))
ar.MoveNext() ar.MoveNext()
ia, ap = ar.Read() ia, ap = ar.Read()
} }

View File

@@ -384,9 +384,11 @@ func (vt *VideoTrack) Play(onVideo func(uint32, *VideoPack), exit1, exit2 <-chan
case <-exit2: //可能等不到关键帧就退出了 case <-exit2: //可能等不到关键帧就退出了
return return
} }
vr := vt.SubRing(vt.IDRing) //从关键帧开始读取,首屏秒开 vr := vt.SubRing(vt.IDRing) //从关键帧开始读取,首屏秒开
realSt := vt.PreItem().Timestamp // 当前时间戳
item, vp := vr.Read() item, vp := vr.Read()
for startTimestamp := item.Timestamp; ; item, vp = vr.Read() { startTimestamp := item.Timestamp
for chase := true; ; item, vp = vr.Read() {
select { select {
case <-exit1: case <-exit1:
return return
@@ -394,6 +396,14 @@ func (vt *VideoTrack) Play(onVideo func(uint32, *VideoPack), exit1, exit2 <-chan
return return
default: default:
onVideo(item.Timestamp-startTimestamp, vp.(*VideoPack)) onVideo(item.Timestamp-startTimestamp, vp.(*VideoPack))
if chase {
if startTimestamp < realSt-10 {
startTimestamp += 10
} else {
startTimestamp = realSt
chase = false
}
}
vr.MoveNext() vr.MoveNext()
} }
} }