Improve GStreamer seek responsiveness and allow disable toggle

This commit is contained in:
VideoTools CI 2026-01-18 06:43:36 -05:00
parent d14ca93560
commit 016d2a4f8a
3 changed files with 49 additions and 24 deletions

View File

@ -9,8 +9,16 @@ import (
"git.leaktechnologies.dev/stu/VideoTools/internal/logging" "git.leaktechnologies.dev/stu/VideoTools/internal/logging"
) )
// DisableGStreamer forces fallback to the stub controller even when the gstreamer build tag is set.
var DisableGStreamer bool
// newController creates a GStreamer-based controller for embedded video playback // newController creates a GStreamer-based controller for embedded video playback
func newController() Controller { func newController() Controller {
if DisableGStreamer {
logging.Info(logging.CatPlayer, "GStreamer disabled by settings; using stub controller")
return &stubController{}
}
config := Config{ config := Config{
Backend: BackendAuto, Backend: BackendAuto,
WindowWidth: 640, WindowWidth: 640,

View File

@ -2,6 +2,11 @@
package player package player
import "fmt"
func newFramePlayer(config Config) (framePlayer, error) { func newFramePlayer(config Config) (framePlayer, error) {
if DisableGStreamer {
return nil, fmt.Errorf("gstreamer disabled by settings")
}
return NewGStreamerPlayer(config) return NewGStreamerPlayer(config)
} }

View File

@ -83,26 +83,37 @@ import (
var gstInitOnce sync.Once var gstInitOnce sync.Once
type GStreamerPlayer struct { type GStreamerPlayer struct {
mu sync.Mutex
seekMu sync.Mutex
pipeline *C.GstElement pipeline *C.GstElement
appsink *C.GstElement
bus *C.GstBus bus *C.GstBus
busQuit chan struct{} appsink *C.GstElement
busDone chan struct{}
events chan busEvent
paused bool
volume float64
preview bool
width int width int
height int height int
fps float64 fps float64
mode PlayerState
paused bool
volume float64
queued *image.RGBA queued *image.RGBA
lastErr string lastErr string
eos bool backend Backend
state C.GstState config Config
seekMu sync.Mutex
events chan busEvent
mu sync.Mutex
// Cached duration
duration time.Duration duration time.Duration
mode PlayerState
// Bus handling
busCh chan *C.GstMessage
// Bus loop controls
busStop chan struct{}
busDone chan struct{}
// Seek coalescing
lastSeekTarget time.Duration
} }
type busEvent struct { type busEvent struct {
@ -309,7 +320,8 @@ func (p *GStreamerPlayer) Pause() error {
func (p *GStreamerPlayer) SeekToTime(offset time.Duration) error { func (p *GStreamerPlayer) SeekToTime(offset time.Duration) error {
p.seekMu.Lock() p.seekMu.Lock()
defer p.seekMu.Unlock() p.lastSeekTarget = offset
p.seekMu.Unlock()
p.mu.Lock() p.mu.Lock()
prevMode := p.mode prevMode := p.mode
@ -471,7 +483,7 @@ func (p *GStreamerPlayer) primeAfterSeekLocked() {
return return
} }
p.drainPendingLocked() p.drainPendingLocked()
frame, err := p.readFrameLocked(C.GstClockTime(200 * 1000 * 1000)) frame, err := p.readFrameLocked(C.GstClockTime(120 * 1000 * 1000))
if err != nil || frame == nil { if err != nil || frame == nil {
return return
} }