package common // DTSEstimator is a DTS estimator. type DTSEstimator struct { hasB bool prevPTS uint32 prevDTS uint32 cache []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...), } } 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 { if pts < d.prevPTS && d.prevPTS-pts > 0x80000000 { *d = *NewDTSEstimator() } 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 } d.prevPTS = pts d.prevDTS = dts return dts }