playback: fix jerky video (#4555)

this happened when recording has B-frames, playback format is fmp4 and starting position doesn't correspond to a IDR frame.
This commit is contained in:
Alessandro Ros
2025-05-25 21:09:23 +02:00
committed by GitHub
parent 9a3bbda8f8
commit 01e6fedc36
2 changed files with 24 additions and 16 deletions
+15 -10
View File
@@ -71,6 +71,7 @@ func (w *muxerFMP4) writeSample(
}
if dts >= 0 {
// this is the first visible sample of this track
if w.curTrack.firstDTS < 0 {
w.curTrack.firstDTS = dts
@@ -79,11 +80,11 @@ func (w *muxerFMP4) writeSample(
w.curTrack.samples = w.curTrack.samples[:0]
}
} else {
diff := dts - w.curTrack.lastDTS
if diff < 0 {
diff = 0
duration := dts - w.curTrack.lastDTS
if duration < 0 {
duration = 0
}
w.curTrack.samples[len(w.curTrack.samples)-1].Duration = uint32(diff)
w.curTrack.samples[len(w.curTrack.samples)-1].Duration = uint32(duration)
}
w.curTrack.samples = append(w.curTrack.samples, &fmp4.Sample{
@@ -103,17 +104,21 @@ func (w *muxerFMP4) writeSample(
}
} else {
if !isNonSyncSample { // sample is IDR
// reset GOP
// create a new GOP that starts from this sample.
// set sample duration to zero
w.curTrack.samples = w.curTrack.samples[:0]
w.curTrack.samples = append(w.curTrack.samples, &fmp4.Sample{
IsNonSyncSample: isNonSyncSample,
Payload: pl,
PTSOffset: ptsOffset,
})
} else { // sample is not IDR
// append sample to current GOP, with PTSOffset = 0 and Duration = 0
// append sample to current GOP
// set sample duration to zero
w.curTrack.samples = append(w.curTrack.samples, &fmp4.Sample{
IsNonSyncSample: isNonSyncSample,
Payload: pl,
PTSOffset: ptsOffset,
})
}
}
@@ -123,11 +128,11 @@ func (w *muxerFMP4) writeSample(
func (w *muxerFMP4) writeFinalDTS(dts int64) {
if len(w.curTrack.samples) != 0 && w.curTrack.firstDTS >= 0 {
diff := dts - w.curTrack.lastDTS
if diff < 0 {
diff = 0
duration := dts - w.curTrack.lastDTS
if duration < 0 {
duration = 0
}
w.curTrack.samples[len(w.curTrack.samples)-1].Duration = uint32(diff)
w.curTrack.samples[len(w.curTrack.samples)-1].Duration = uint32(duration)
}
}
+9 -6
View File
@@ -295,8 +295,9 @@ func TestOnGet(t *testing.T) {
ID: 1,
Samples: []*fmp4.Sample{
{
Duration: 0,
Payload: []byte{3, 4},
Duration: 0,
PTSOffset: 90000,
Payload: []byte{3, 4},
},
{
Duration: 90000,
@@ -516,8 +517,9 @@ func TestOnGetDifferentInit(t *testing.T) {
ID: 1,
Samples: []*fmp4.Sample{
{
Duration: 0,
Payload: []byte{3, 4},
Duration: 0,
PTSOffset: 90000,
Payload: []byte{3, 4},
},
{
Duration: 90000,
@@ -593,8 +595,9 @@ func TestOnGetNTPCompensation(t *testing.T) {
ID: 1,
Samples: []*fmp4.Sample{
{
Duration: 0,
Payload: []byte{3, 4},
Duration: 0,
PTSOffset: 90000,
Payload: []byte{3, 4},
},
{
Duration: 90000 - 45000,