mirror of
https://github.com/Monibuca/engine.git
synced 2025-09-27 04:46:03 +08:00
75 lines
1.3 KiB
Go
75 lines
1.3 KiB
Go
package 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 := 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
|
|
}
|