dtsestimator.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package util
  2. // DTSEstimator is a DTS estimator.
  3. type DTSEstimator struct {
  4. hasB bool
  5. prevPTS uint32
  6. prevDTS uint32
  7. cache []uint32
  8. interval uint32
  9. }
  10. // NewDTSEstimator allocates a DTSEstimator.
  11. func NewDTSEstimator() *DTSEstimator {
  12. result := &DTSEstimator{}
  13. return result
  14. }
  15. func (d *DTSEstimator) Clone() *DTSEstimator {
  16. return &DTSEstimator{
  17. d.hasB,
  18. d.prevPTS,
  19. d.prevDTS,
  20. append([]uint32(nil), d.cache...),
  21. d.interval,
  22. }
  23. }
  24. func (d *DTSEstimator) add(pts uint32) {
  25. i := 0
  26. l := len(d.cache)
  27. if l >= 4 {
  28. l--
  29. // i = l - 3
  30. d.cache = append(d.cache[:0], d.cache[1:]...)[:l]
  31. }
  32. for ; i < l; i = i + 1 {
  33. if d.cache[i] > pts {
  34. break
  35. }
  36. }
  37. d.cache = append(d.cache, pts)
  38. d.cache = append(d.cache[:i+1], d.cache[i:l]...)
  39. d.cache[i] = pts
  40. }
  41. // Feed provides PTS to the estimator, and returns the estimated DTS.
  42. func (d *DTSEstimator) Feed(pts uint32) uint32 {
  43. interval := Conditoinal(pts > d.prevPTS, pts-d.prevPTS, d.prevPTS-pts)
  44. if interval > 10*d.interval {
  45. *d = *NewDTSEstimator()
  46. }
  47. d.interval = interval
  48. d.add(pts)
  49. dts := pts
  50. if !d.hasB {
  51. if pts < d.prevPTS {
  52. d.hasB = true
  53. dts = d.cache[0]
  54. }
  55. } else {
  56. dts = d.cache[0]
  57. }
  58. if d.prevDTS > dts {
  59. dts = d.prevDTS
  60. }
  61. // if d.prevDTS >= dts {
  62. // dts = d.prevDTS + 90
  63. // }
  64. d.prevPTS = pts
  65. d.prevDTS = dts
  66. return dts
  67. }