12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- package common
- import "m7s.live/engine/v4/util"
- // DTSEstimator is a DTS estimator.
- type DTSEstimator struct {
- hasB bool
- prevPTS uint32
- prevDTS uint32
- cache []uint32
- interval uint32
- }
- // NewDTSEstimator allocates a DTSEstimator.
- func NewDTSEstimator() *DTSEstimator {
- result := &DTSEstimator{}
- return result
- }
- func (d *DTSEstimator) Clone() *DTSEstimator {
- return &DTSEstimator{
- d.hasB,
- d.prevPTS,
- d.prevDTS,
- append([]uint32(nil), d.cache...),
- d.interval,
- }
- }
- func (d *DTSEstimator) add(pts uint32) {
- i := 0
- l := len(d.cache)
- if l >= 4 {
- l--
- // i = l - 3
- d.cache = append(d.cache[:0], d.cache[1:]...)[:l]
- }
- for ; i < l; i = i + 1 {
- if d.cache[i] > pts {
- break
- }
- }
- d.cache = append(d.cache, pts)
- d.cache = append(d.cache[:i+1], d.cache[i:l]...)
- d.cache[i] = pts
- }
- // Feed provides PTS to the estimator, and returns the estimated DTS.
- func (d *DTSEstimator) Feed(pts uint32) uint32 {
- interval := util.Conditoinal(pts > d.prevPTS, pts-d.prevPTS, d.prevPTS-pts)
- if interval > 10*d.interval {
- *d = *NewDTSEstimator()
- }
- d.interval = interval
- d.add(pts)
- dts := pts
- if !d.hasB {
- if pts < d.prevPTS {
- d.hasB = true
- dts = d.cache[0]
- }
- } else {
- dts = d.cache[0]
- }
- if d.prevDTS > dts {
- dts = d.prevDTS
- }
- // if d.prevDTS >= dts {
- // dts = d.prevDTS + 90
- // }
- d.prevPTS = pts
- d.prevDTS = dts
- return dts
- }
|