Improve GStreamer frame stepping reliability

This commit is contained in:
Stu Leak 2026-01-10 03:08:18 -05:00
parent 48fc94acb8
commit 407269b6c7
2 changed files with 28 additions and 4 deletions

View File

@ -134,10 +134,18 @@ func (p *GStreamerPlayer) Load(path string, offset time.Duration) error {
}
C.free(unsafe.Pointer(syncName))
maxBuffers := C.CString("max-buffers")
C.vt_gst_set_int(appsink, maxBuffers, C.gint(2))
if p.preview {
C.vt_gst_set_int(appsink, maxBuffers, C.gint(2))
} else {
C.vt_gst_set_int(appsink, maxBuffers, C.gint(1))
}
C.free(unsafe.Pointer(maxBuffers))
dropName := C.CString("drop")
C.vt_gst_set_bool(appsink, dropName, C.gboolean(1))
if p.preview {
C.vt_gst_set_bool(appsink, dropName, C.gboolean(1))
} else {
C.vt_gst_set_bool(appsink, dropName, C.gboolean(0))
}
C.free(unsafe.Pointer(dropName))
var audioSink *C.GstElement
@ -366,6 +374,7 @@ func (p *GStreamerPlayer) primeAfterSeekLocked() {
if p.appsink == nil {
return
}
p.drainPendingLocked()
frame, err := p.readFrameLocked(C.GstClockTime(200 * 1000 * 1000))
if err != nil || frame == nil {
return
@ -373,6 +382,19 @@ func (p *GStreamerPlayer) primeAfterSeekLocked() {
p.queued = frame
}
func (p *GStreamerPlayer) drainPendingLocked() {
if p.appsink == nil {
return
}
for i := 0; i < 5; i++ {
sample := C.gst_app_sink_try_pull_sample((*C.GstAppSink)(unsafe.Pointer(p.appsink)), C.GstClockTime(0))
if sample == nil {
return
}
C.gst_sample_unref(sample)
}
}
func (p *GStreamerPlayer) SetVolume(level float64) error {
p.mu.Lock()
defer p.mu.Unlock()

View File

@ -11437,9 +11437,12 @@ func (p *playSession) frameDisplayLoop() {
// Get current time from GStreamer
currentTime := p.gstPlayer.GetCurrentTime()
p.mu.Lock()
isPaused := p.paused
p.mu.Unlock()
// Skip if this is the same frame as last time (optimization)
if currentTime == lastFrameTime && frameCount > 0 {
if currentTime == lastFrameTime && frameCount > 0 && !isPaused {
continue
}
lastFrameTime = currentTime
@ -11452,7 +11455,6 @@ func (p *playSession) frameDisplayLoop() {
p.mu.Lock()
p.frameN = actualFrameNumber
p.current = currentTime.Seconds()
isPaused := p.paused
p.mu.Unlock()
// Update UI on main thread