detached e49694e

refactor(cef): remove bootstrap/runtime transcoder startup plumbing

commit
e49694e3df8f7429f1c92e357700e7c9fcc18542
author
brice · · 2026-04-28 03:54 UTC
parent
669a894
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
5 files · +5 -146
M internal/bootstrap/engine.go +1 -16
@@ -15,7 +15,6 @@ import (
1515 "github.com/bnema/dumber/internal/infrastructure/env"
1616 "github.com/bnema/dumber/internal/infrastructure/handlers"
1717 "github.com/bnema/dumber/internal/infrastructure/runtimeprofile"
18- "github.com/bnema/dumber/internal/infrastructure/transcoder"
1918 "github.com/bnema/dumber/internal/infrastructure/webkit"
2019 "github.com/bnema/dumber/internal/ui/theme"
2120 "github.com/rs/zerolog"
@@ -84,12 +83,6 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
8483 EnableAudioHandler: cfg.Engine.CEF.EnableAudioHandler,
8584 TraceHandlers: cfg.Engine.CEF.TraceHandlers,
8685 }
87- transcodingCfg := cef.TranscodingRuntimeConfig{
88- Enabled: cfg.Transcoding.Enabled,
89- HWAccel: cfg.Transcoding.HWAccel,
90- MaxConcurrent: cfg.Transcoding.MaxConcurrent,
91- Quality: cfg.Transcoding.Quality,
92- }
9386 deps := cef.EngineDependencies{
9487 RegisterHandlers: handlers.RegisterAll,
9588 RegisterAccentHandlers: handlers.RegisterAccentHandlers,
@@ -99,20 +92,12 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
9992 ContextMenuExecutorFactory: contextMenuExecutorFactory,
10093 Clipboard: clipboardinfra.New(),
10194 ImageDataResolver: webkit.NewContextMenuResolver(),
102- MediaClassifier: cef.MediaClassifier{
103- IsProprietaryVideoMIME: transcoder.IsProprietaryVideoMIME,
104- IsOpenVideoMIME: transcoder.IsOpenVideoMIME,
105- IsStreamingManifestMIME: transcoder.IsStreamingManifestMIME,
106- IsStreamingManifestURL: transcoder.IsStreamingManifestURL,
107- IsEagerTranscodeURL: transcoder.IsEagerTranscodeURL,
108- ParseSyntheticTranscodeURL: transcoder.ParseSyntheticTranscodeURL,
109- },
11095 }
11196 audioFactory := audiofactory.NewAudioOutputFactory()
11297 return cef.NewEngine(input.Ctx, opts, cef.RuntimePaths{
11398 StateRoot: profile.CEFUserDataDir(),
11499 LogFile: profile.CEFLogFile(),
115- }, cefCfg, transcodingCfg, audioFactory, deps)
100+ }, cefCfg, audioFactory, deps)
116101 default:
117102 return nil, fmt.Errorf("unknown engine type: %q", engineType)
118103 }
@@ -15,7 +15,6 @@ import (
15 "github.com/bnema/dumber/internal/infrastructure/env"15 "github.com/bnema/dumber/internal/infrastructure/env"
16 "github.com/bnema/dumber/internal/infrastructure/handlers"16 "github.com/bnema/dumber/internal/infrastructure/handlers"
17 "github.com/bnema/dumber/internal/infrastructure/runtimeprofile"17 "github.com/bnema/dumber/internal/infrastructure/runtimeprofile"
18- "github.com/bnema/dumber/internal/infrastructure/transcoder"
19 "github.com/bnema/dumber/internal/infrastructure/webkit"18 "github.com/bnema/dumber/internal/infrastructure/webkit"
20 "github.com/bnema/dumber/internal/ui/theme"19 "github.com/bnema/dumber/internal/ui/theme"
21 "github.com/rs/zerolog"20 "github.com/rs/zerolog"
@@ -84,12 +83,6 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
84 EnableAudioHandler: cfg.Engine.CEF.EnableAudioHandler,83 EnableAudioHandler: cfg.Engine.CEF.EnableAudioHandler,
85 TraceHandlers: cfg.Engine.CEF.TraceHandlers,84 TraceHandlers: cfg.Engine.CEF.TraceHandlers,
86 }85 }
87- transcodingCfg := cef.TranscodingRuntimeConfig{
88- Enabled: cfg.Transcoding.Enabled,
89- HWAccel: cfg.Transcoding.HWAccel,
90- MaxConcurrent: cfg.Transcoding.MaxConcurrent,
91- Quality: cfg.Transcoding.Quality,
92- }
93 deps := cef.EngineDependencies{86 deps := cef.EngineDependencies{
94 RegisterHandlers: handlers.RegisterAll,87 RegisterHandlers: handlers.RegisterAll,
95 RegisterAccentHandlers: handlers.RegisterAccentHandlers,88 RegisterAccentHandlers: handlers.RegisterAccentHandlers,
@@ -99,20 +92,12 @@ func BuildEngine(input EngineInput) (port.Engine, error) {
99 ContextMenuExecutorFactory: contextMenuExecutorFactory,92 ContextMenuExecutorFactory: contextMenuExecutorFactory,
100 Clipboard: clipboardinfra.New(),93 Clipboard: clipboardinfra.New(),
101 ImageDataResolver: webkit.NewContextMenuResolver(),94 ImageDataResolver: webkit.NewContextMenuResolver(),
102- MediaClassifier: cef.MediaClassifier{
103- IsProprietaryVideoMIME: transcoder.IsProprietaryVideoMIME,
104- IsOpenVideoMIME: transcoder.IsOpenVideoMIME,
105- IsStreamingManifestMIME: transcoder.IsStreamingManifestMIME,
106- IsStreamingManifestURL: transcoder.IsStreamingManifestURL,
107- IsEagerTranscodeURL: transcoder.IsEagerTranscodeURL,
108- ParseSyntheticTranscodeURL: transcoder.ParseSyntheticTranscodeURL,
109- },
110 }95 }
111 audioFactory := audiofactory.NewAudioOutputFactory()96 audioFactory := audiofactory.NewAudioOutputFactory()
112 return cef.NewEngine(input.Ctx, opts, cef.RuntimePaths{97 return cef.NewEngine(input.Ctx, opts, cef.RuntimePaths{
113 StateRoot: profile.CEFUserDataDir(),98 StateRoot: profile.CEFUserDataDir(),
114 LogFile: profile.CEFLogFile(),99 LogFile: profile.CEFLogFile(),
115- }, cefCfg, transcodingCfg, audioFactory, deps)100+ }, cefCfg, audioFactory, deps)
116 default:101 default:
117 return nil, fmt.Errorf("unknown engine type: %q", engineType)102 return nil, fmt.Errorf("unknown engine type: %q", engineType)
118 }103 }
M internal/infrastructure/cef/engine.go +0 -44
@@ -42,7 +42,6 @@ type Engine struct {
4242 clipboardTextOrchestrator port.ClipboardTextOrchestrator
4343 onClipboardCopied func(textLen int)
4444 resolver port.ImageDataResolver
45- mediaClassifier MediaClassifier
4645 downloadMu sync.RWMutex
4746 downloadHandler *downloadHandler
4847 alreadyRunningAppRelaunchMu sync.RWMutex
@@ -71,20 +70,6 @@ type Engine struct {
7170 browserCreateLastHeight atomic.Int32
7271 browserCreateComplete atomic.Bool
7372
74- transcoderState transcoderStartupState
75- transcoderStateLogged atomic.Bool
76-}
77-
78-type transcoderStartupState struct {
79- ConfigEnabled bool
80- ProbeAttempted bool
81- HWAccel string
82- MaxConcurrent int
83- Quality string
84- Status string
85- API string
86- Encoders []string
87- Decoders []string
8873 }
8974
9075 func (e *Engine) Factory() port.WebViewFactory {
@@ -387,7 +372,6 @@ func (e *Engine) SetHandlerContext(ctx context.Context) {
387372 if e.messageRouter != nil {
388373 e.messageRouter.SetBaseContext(ctx)
389374 }
390- e.logTranscoderStartupState()
391375 }
392376
393377 func (e *Engine) recordContextInitialized() {
@@ -492,31 +476,3 @@ func (e *Engine) currentDownloadHandler() *downloadHandler {
492476 return e.downloadHandler
493477 }
494478
495-func (e *Engine) logTranscoderStartupState() {
496- if e == nil || !e.transcoderStateLogged.CompareAndSwap(false, true) {
497- return
498- }
499-
500- state := e.transcoderState
501- log := logging.FromContext(e.currentContext())
502- event := log.Info().
503- Str("component", "cef-transcoder").
504- Bool("config_enabled", state.ConfigEnabled).
505- Bool("probe_attempted", state.ProbeAttempted).
506- Str("hwaccel", state.HWAccel).
507- Int("max_concurrent", state.MaxConcurrent).
508- Str("quality", state.Quality).
509- Str("status", state.Status)
510-
511- if state.API != "" {
512- event = event.Str("api", state.API)
513- }
514- if len(state.Encoders) > 0 {
515- event = event.Strs("encoders", state.Encoders)
516- }
517- if len(state.Decoders) > 0 {
518- event = event.Strs("decoders", state.Decoders)
519- }
520-
521- event.Msg("cef: transcoder startup state")
522-}
@@ -42,7 +42,6 @@ type Engine struct {
42 clipboardTextOrchestrator port.ClipboardTextOrchestrator42 clipboardTextOrchestrator port.ClipboardTextOrchestrator
43 onClipboardCopied func(textLen int)43 onClipboardCopied func(textLen int)
44 resolver port.ImageDataResolver44 resolver port.ImageDataResolver
45- mediaClassifier MediaClassifier
46 downloadMu sync.RWMutex45 downloadMu sync.RWMutex
47 downloadHandler *downloadHandler46 downloadHandler *downloadHandler
48 alreadyRunningAppRelaunchMu sync.RWMutex47 alreadyRunningAppRelaunchMu sync.RWMutex
@@ -71,20 +70,6 @@ type Engine struct {
71 browserCreateLastHeight atomic.Int3270 browserCreateLastHeight atomic.Int32
72 browserCreateComplete atomic.Bool71 browserCreateComplete atomic.Bool
73 72
74- transcoderState transcoderStartupState
75- transcoderStateLogged atomic.Bool
76-}
77-
78-type transcoderStartupState struct {
79- ConfigEnabled bool
80- ProbeAttempted bool
81- HWAccel string
82- MaxConcurrent int
83- Quality string
84- Status string
85- API string
86- Encoders []string
87- Decoders []string
88 }73 }
89 74
90 func (e *Engine) Factory() port.WebViewFactory {75 func (e *Engine) Factory() port.WebViewFactory {
@@ -387,7 +372,6 @@ func (e *Engine) SetHandlerContext(ctx context.Context) {
387 if e.messageRouter != nil {372 if e.messageRouter != nil {
388 e.messageRouter.SetBaseContext(ctx)373 e.messageRouter.SetBaseContext(ctx)
389 }374 }
390- e.logTranscoderStartupState()
391 }375 }
392 376
393 func (e *Engine) recordContextInitialized() {377 func (e *Engine) recordContextInitialized() {
@@ -492,31 +476,3 @@ func (e *Engine) currentDownloadHandler() *downloadHandler {
492 return e.downloadHandler476 return e.downloadHandler
493 }477 }
494 478
495-func (e *Engine) logTranscoderStartupState() {
496- if e == nil || !e.transcoderStateLogged.CompareAndSwap(false, true) {
497- return
498- }
499-
500- state := e.transcoderState
501- log := logging.FromContext(e.currentContext())
502- event := log.Info().
503- Str("component", "cef-transcoder").
504- Bool("config_enabled", state.ConfigEnabled).
505- Bool("probe_attempted", state.ProbeAttempted).
506- Str("hwaccel", state.HWAccel).
507- Int("max_concurrent", state.MaxConcurrent).
508- Str("quality", state.Quality).
509- Str("status", state.Status)
510-
511- if state.API != "" {
512- event = event.Str("api", state.API)
513- }
514- if len(state.Encoders) > 0 {
515- event = event.Strs("encoders", state.Encoders)
516- }
517- if len(state.Decoders) > 0 {
518- event = event.Strs("decoders", state.Decoders)
519- }
520-
521- event.Msg("cef: transcoder startup state")
522-}
M internal/infrastructure/cef/engine_init.go +2 -73
@@ -18,7 +18,6 @@ import (
1818 "github.com/bnema/dumber/assets"
1919 "github.com/bnema/dumber/internal/application/port"
2020 "github.com/bnema/dumber/internal/infrastructure/config"
21- transcoderpkg "github.com/bnema/dumber/internal/infrastructure/transcoder"
2221 "github.com/bnema/dumber/internal/logging"
2322 )
2423
@@ -37,12 +36,10 @@ func NewEngine(
3736 opts port.EngineOptions,
3837 paths RuntimePaths,
3938 cfg RuntimeConfig,
40- transcodingCfg TranscodingRuntimeConfig,
4139 audioFactory port.AudioOutputFactory,
4240 deps EngineDependencies,
4341 ) (*Engine, error) {
4442 logger := logging.FromContext(ctx)
45- deps.MediaClassifier = deps.MediaClassifier.normalize()
4643 stateRoot := resolvedStateRoot(paths.StateRoot, opts)
4744 cleanStaleSingletonLocks(logger, stateRoot)
4845 windowlessFrameRate := config.CEFEngineConfig{WindowlessFrameRate: cfg.WindowlessFrameRate}.CEFWindowlessFrameRate()
@@ -67,7 +64,6 @@ func NewEngine(
6764 ctxMenuExecutorFactory: deps.ContextMenuExecutorFactory,
6865 clipboard: deps.Clipboard,
6966 resolver: deps.ImageDataResolver,
70- mediaClassifier: deps.MediaClassifier,
7167 }
7268
7369 logger.Info().
@@ -87,11 +83,9 @@ func NewEngine(
8783 ctx,
8884 eng,
8985 cfg,
90- transcodingCfg,
9186 windowlessFrameRate,
9287 audioFactory,
9388 logger,
94- deps.MediaClassifier,
9589 deps.CurrentConfigPayload,
9690 deps.DefaultConfigPayload,
9791 )
@@ -168,9 +162,8 @@ func initializeCEF(eng *Engine, settings purecef.Settings, logger *zerolog.Logge
168162
169163 // wireEngine creates GL loader, factory, pool, and scheme handler after CEF init.
170164 func wireEngine(
171- ctx context.Context, eng *Engine, _ RuntimeConfig, transcodingCfg TranscodingRuntimeConfig,
165+ ctx context.Context, eng *Engine, _ RuntimeConfig,
172166 windowlessFrameRate int32, audioFactory port.AudioOutputFactory, logger *zerolog.Logger,
173- mediaClassifier MediaClassifier,
174167 currentConfigPayload func() ([]byte, error), defaultConfigPayload func() ([]byte, error),
175168 ) (*Engine, error) {
176169 gl, err := newGLLoader()
@@ -179,18 +172,16 @@ func wireEngine(
179172 return nil, fmt.Errorf("GL loader: %w", err)
180173 }
181174
182- mediaTranscoder, transcoderState := initializeEngineTranscoder(transcodingCfg, logger)
175+ var mediaTranscoder port.MediaTranscoder
183176 eng.gl = gl
184177 eng.factory = newWebViewFactory(eng, gl, webViewFactoryOptions{
185178 scale: detectHiDPIScale(logger),
186179 windowlessFrameRate: windowlessFrameRate,
187180 transcoder: mediaTranscoder,
188- mediaClassifier: mediaClassifier,
189181 audioOutputFactory: audioFactory,
190182 })
191183 eng.pool = newWebViewPool(eng.factory)
192184 eng.contentInj = newContentInjector(eng, nil)
193- eng.transcoderState = transcoderState
194185
195186 messageRouter, schemeHandler, err := newEngineSchemeHandler(
196187 ctx,
@@ -211,39 +202,6 @@ func wireEngine(
211202 return eng, nil
212203 }
213204
214-func initializeEngineTranscoder(
215- transcodingCfg TranscodingRuntimeConfig,
216- logger *zerolog.Logger,
217-) (port.MediaTranscoder, transcoderStartupState) {
218- transcoderState := buildTranscoderStartupState(transcodingCfg)
219- if !transcodingCfg.Enabled {
220- return nil, transcoderState
221- }
222-
223- transcoderState.ProbeAttempted = true
224- tc := transcoderpkg.New(config.TranscodingConfig{
225- Enabled: transcodingCfg.Enabled,
226- HWAccel: transcodingCfg.HWAccel,
227- MaxConcurrent: transcodingCfg.MaxConcurrent,
228- Quality: transcodingCfg.Quality,
229- }, logger)
230- caps := tc.Capabilities()
231- transcoderState.API = caps.API
232- transcoderState.Encoders = append([]string(nil), caps.Encoders...)
233- transcoderState.Decoders = append([]string(nil), caps.Decoders...)
234- if !tc.Available() {
235- transcoderState.Status = "unavailable_no_compatible_gpu"
236- logger.Warn().Msg("cef: GPU transcoding enabled but no compatible GPU found — feature disabled")
237- return nil, transcoderState
238- }
239-
240- transcoderState.Status = "available"
241- logger.Info().
242- Str("api", caps.API).
243- Strs("encoders", caps.Encoders).
244- Msg("cef: GPU transcoding available")
245- return tc, transcoderState
246-}
247205
248206 func newEngineSchemeHandler(
249207 ctx context.Context,
@@ -328,35 +286,6 @@ func registerEngineSchemeFactory(
328286 Msg("cef: registered internal https handler factory")
329287 }
330288
331-func buildTranscoderStartupState(cfg TranscodingRuntimeConfig) transcoderStartupState {
332- hwaccel := cfg.HWAccel
333- if hwaccel == "" {
334- hwaccel = "auto"
335- }
336-
337- maxConcurrent := cfg.MaxConcurrent
338- if maxConcurrent <= 0 {
339- maxConcurrent = 2
340- }
341-
342- quality := cfg.Quality
343- if quality == "" {
344- quality = "medium"
345- }
346-
347- status := "disabled_in_config"
348- if cfg.Enabled {
349- status = "configured_enabled"
350- }
351-
352- return transcoderStartupState{
353- ConfigEnabled: cfg.Enabled,
354- HWAccel: hwaccel,
355- MaxConcurrent: maxConcurrent,
356- Quality: quality,
357- Status: status,
358- }
359-}
360289
361290 // getPrimaryMonitor returns the primary GDK monitor, or nil if unavailable.
362291 func getPrimaryMonitor() *gdk.Monitor {
@@ -18,7 +18,6 @@ import (
18 "github.com/bnema/dumber/assets"18 "github.com/bnema/dumber/assets"
19 "github.com/bnema/dumber/internal/application/port"19 "github.com/bnema/dumber/internal/application/port"
20 "github.com/bnema/dumber/internal/infrastructure/config"20 "github.com/bnema/dumber/internal/infrastructure/config"
21- transcoderpkg "github.com/bnema/dumber/internal/infrastructure/transcoder"
22 "github.com/bnema/dumber/internal/logging"21 "github.com/bnema/dumber/internal/logging"
23 )22 )
24 23
@@ -37,12 +36,10 @@ func NewEngine(
37 opts port.EngineOptions,36 opts port.EngineOptions,
38 paths RuntimePaths,37 paths RuntimePaths,
39 cfg RuntimeConfig,38 cfg RuntimeConfig,
40- transcodingCfg TranscodingRuntimeConfig,
41 audioFactory port.AudioOutputFactory,39 audioFactory port.AudioOutputFactory,
42 deps EngineDependencies,40 deps EngineDependencies,
43 ) (*Engine, error) {41 ) (*Engine, error) {
44 logger := logging.FromContext(ctx)42 logger := logging.FromContext(ctx)
45- deps.MediaClassifier = deps.MediaClassifier.normalize()
46 stateRoot := resolvedStateRoot(paths.StateRoot, opts)43 stateRoot := resolvedStateRoot(paths.StateRoot, opts)
47 cleanStaleSingletonLocks(logger, stateRoot)44 cleanStaleSingletonLocks(logger, stateRoot)
48 windowlessFrameRate := config.CEFEngineConfig{WindowlessFrameRate: cfg.WindowlessFrameRate}.CEFWindowlessFrameRate()45 windowlessFrameRate := config.CEFEngineConfig{WindowlessFrameRate: cfg.WindowlessFrameRate}.CEFWindowlessFrameRate()
@@ -67,7 +64,6 @@ func NewEngine(
67 ctxMenuExecutorFactory: deps.ContextMenuExecutorFactory,64 ctxMenuExecutorFactory: deps.ContextMenuExecutorFactory,
68 clipboard: deps.Clipboard,65 clipboard: deps.Clipboard,
69 resolver: deps.ImageDataResolver,66 resolver: deps.ImageDataResolver,
70- mediaClassifier: deps.MediaClassifier,
71 }67 }
72 68
73 logger.Info().69 logger.Info().
@@ -87,11 +83,9 @@ func NewEngine(
87 ctx,83 ctx,
88 eng,84 eng,
89 cfg,85 cfg,
90- transcodingCfg,
91 windowlessFrameRate,86 windowlessFrameRate,
92 audioFactory,87 audioFactory,
93 logger,88 logger,
94- deps.MediaClassifier,
95 deps.CurrentConfigPayload,89 deps.CurrentConfigPayload,
96 deps.DefaultConfigPayload,90 deps.DefaultConfigPayload,
97 )91 )
@@ -168,9 +162,8 @@ func initializeCEF(eng *Engine, settings purecef.Settings, logger *zerolog.Logge
168 162
169 // wireEngine creates GL loader, factory, pool, and scheme handler after CEF init.163 // wireEngine creates GL loader, factory, pool, and scheme handler after CEF init.
170 func wireEngine(164 func wireEngine(
171- ctx context.Context, eng *Engine, _ RuntimeConfig, transcodingCfg TranscodingRuntimeConfig,165+ ctx context.Context, eng *Engine, _ RuntimeConfig,
172 windowlessFrameRate int32, audioFactory port.AudioOutputFactory, logger *zerolog.Logger,166 windowlessFrameRate int32, audioFactory port.AudioOutputFactory, logger *zerolog.Logger,
173- mediaClassifier MediaClassifier,
174 currentConfigPayload func() ([]byte, error), defaultConfigPayload func() ([]byte, error),167 currentConfigPayload func() ([]byte, error), defaultConfigPayload func() ([]byte, error),
175 ) (*Engine, error) {168 ) (*Engine, error) {
176 gl, err := newGLLoader()169 gl, err := newGLLoader()
@@ -179,18 +172,16 @@ func wireEngine(
179 return nil, fmt.Errorf("GL loader: %w", err)172 return nil, fmt.Errorf("GL loader: %w", err)
180 }173 }
181 174
182- mediaTranscoder, transcoderState := initializeEngineTranscoder(transcodingCfg, logger)175+ var mediaTranscoder port.MediaTranscoder
183 eng.gl = gl176 eng.gl = gl
184 eng.factory = newWebViewFactory(eng, gl, webViewFactoryOptions{177 eng.factory = newWebViewFactory(eng, gl, webViewFactoryOptions{
185 scale: detectHiDPIScale(logger),178 scale: detectHiDPIScale(logger),
186 windowlessFrameRate: windowlessFrameRate,179 windowlessFrameRate: windowlessFrameRate,
187 transcoder: mediaTranscoder,180 transcoder: mediaTranscoder,
188- mediaClassifier: mediaClassifier,
189 audioOutputFactory: audioFactory,181 audioOutputFactory: audioFactory,
190 })182 })
191 eng.pool = newWebViewPool(eng.factory)183 eng.pool = newWebViewPool(eng.factory)
192 eng.contentInj = newContentInjector(eng, nil)184 eng.contentInj = newContentInjector(eng, nil)
193- eng.transcoderState = transcoderState
194 185
195 messageRouter, schemeHandler, err := newEngineSchemeHandler(186 messageRouter, schemeHandler, err := newEngineSchemeHandler(
196 ctx,187 ctx,
@@ -211,39 +202,6 @@ func wireEngine(
211 return eng, nil202 return eng, nil
212 }203 }
213 204
214-func initializeEngineTranscoder(
215- transcodingCfg TranscodingRuntimeConfig,
216- logger *zerolog.Logger,
217-) (port.MediaTranscoder, transcoderStartupState) {
218- transcoderState := buildTranscoderStartupState(transcodingCfg)
219- if !transcodingCfg.Enabled {
220- return nil, transcoderState
221- }
222-
223- transcoderState.ProbeAttempted = true
224- tc := transcoderpkg.New(config.TranscodingConfig{
225- Enabled: transcodingCfg.Enabled,
226- HWAccel: transcodingCfg.HWAccel,
227- MaxConcurrent: transcodingCfg.MaxConcurrent,
228- Quality: transcodingCfg.Quality,
229- }, logger)
230- caps := tc.Capabilities()
231- transcoderState.API = caps.API
232- transcoderState.Encoders = append([]string(nil), caps.Encoders...)
233- transcoderState.Decoders = append([]string(nil), caps.Decoders...)
234- if !tc.Available() {
235- transcoderState.Status = "unavailable_no_compatible_gpu"
236- logger.Warn().Msg("cef: GPU transcoding enabled but no compatible GPU found — feature disabled")
237- return nil, transcoderState
238- }
239-
240- transcoderState.Status = "available"
241- logger.Info().
242- Str("api", caps.API).
243- Strs("encoders", caps.Encoders).
244- Msg("cef: GPU transcoding available")
245- return tc, transcoderState
246-}
247 205
248 func newEngineSchemeHandler(206 func newEngineSchemeHandler(
249 ctx context.Context,207 ctx context.Context,
@@ -328,35 +286,6 @@ func registerEngineSchemeFactory(
328 Msg("cef: registered internal https handler factory")286 Msg("cef: registered internal https handler factory")
329 }287 }
330 288
331-func buildTranscoderStartupState(cfg TranscodingRuntimeConfig) transcoderStartupState {
332- hwaccel := cfg.HWAccel
333- if hwaccel == "" {
334- hwaccel = "auto"
335- }
336-
337- maxConcurrent := cfg.MaxConcurrent
338- if maxConcurrent <= 0 {
339- maxConcurrent = 2
340- }
341-
342- quality := cfg.Quality
343- if quality == "" {
344- quality = "medium"
345- }
346-
347- status := "disabled_in_config"
348- if cfg.Enabled {
349- status = "configured_enabled"
350- }
351-
352- return transcoderStartupState{
353- ConfigEnabled: cfg.Enabled,
354- HWAccel: hwaccel,
355- MaxConcurrent: maxConcurrent,
356- Quality: quality,
357- Status: status,
358- }
359-}
360 289
361 // getPrimaryMonitor returns the primary GDK monitor, or nil if unavailable.290 // getPrimaryMonitor returns the primary GDK monitor, or nil if unavailable.
362 func getPrimaryMonitor() *gdk.Monitor {291 func getPrimaryMonitor() *gdk.Monitor {
M internal/infrastructure/cef/factory.go +2 -5
@@ -26,7 +26,6 @@ type WebViewFactory struct {
2626 windowlessFrameRate int32
2727 bgColor atomic.Uint32 // packed ARGB for BrowserSettings.BackgroundColor
2828 transcoder port.MediaTranscoder
29- mediaClassifier MediaClassifier
3029 audioOutputFactory port.AudioOutputFactory
3130 }
3231
@@ -34,7 +33,6 @@ type webViewFactoryOptions struct {
3433 scale int32
3534 windowlessFrameRate int32
3635 transcoder port.MediaTranscoder
37- mediaClassifier MediaClassifier
3836 audioOutputFactory port.AudioOutputFactory
3937 }
4038
@@ -64,9 +62,8 @@ func newWebViewFactory(engine *Engine, gl *glLoader, opts webViewFactoryOptions)
6462 gl: gl,
6563 scale: opts.scale,
6664 windowlessFrameRate: opts.windowlessFrameRate,
67- transcoder: opts.transcoder,
68- mediaClassifier: opts.mediaClassifier,
69- audioOutputFactory: opts.audioOutputFactory,
65+ transcoder: opts.transcoder,
66+ audioOutputFactory: opts.audioOutputFactory,
7067 }
7168 }
7269
@@ -26,7 +26,6 @@ type WebViewFactory struct {
26 windowlessFrameRate int3226 windowlessFrameRate int32
27 bgColor atomic.Uint32 // packed ARGB for BrowserSettings.BackgroundColor27 bgColor atomic.Uint32 // packed ARGB for BrowserSettings.BackgroundColor
28 transcoder port.MediaTranscoder28 transcoder port.MediaTranscoder
29- mediaClassifier MediaClassifier
30 audioOutputFactory port.AudioOutputFactory29 audioOutputFactory port.AudioOutputFactory
31 }30 }
32 31
@@ -34,7 +33,6 @@ type webViewFactoryOptions struct {
34 scale int3233 scale int32
35 windowlessFrameRate int3234 windowlessFrameRate int32
36 transcoder port.MediaTranscoder35 transcoder port.MediaTranscoder
37- mediaClassifier MediaClassifier
38 audioOutputFactory port.AudioOutputFactory36 audioOutputFactory port.AudioOutputFactory
39 }37 }
40 38
@@ -64,9 +62,8 @@ func newWebViewFactory(engine *Engine, gl *glLoader, opts webViewFactoryOptions)
64 gl: gl,62 gl: gl,
65 scale: opts.scale,63 scale: opts.scale,
66 windowlessFrameRate: opts.windowlessFrameRate,64 windowlessFrameRate: opts.windowlessFrameRate,
67- transcoder: opts.transcoder,65+ transcoder: opts.transcoder,
68- mediaClassifier: opts.mediaClassifier,66+ audioOutputFactory: opts.audioOutputFactory,
69- audioOutputFactory: opts.audioOutputFactory,
70 }67 }
71 }68 }
72 69
M internal/infrastructure/cef/runtime_config.go +0 -8
@@ -23,13 +23,6 @@ type RuntimeConfig struct {
2323 TraceHandlers bool
2424 }
2525
26-type TranscodingRuntimeConfig struct {
27- Enabled bool
28- HWAccel string
29- MaxConcurrent int
30- Quality string
31-}
32-
3326 type HandlerRegistrar func(context.Context, port.WebUIHandlerRouter, port.HandlerDependencies) error
3427
3528 type AccentHandlerRegistrar func(context.Context, port.WebUIHandlerRouter, port.AccentKeyHandler) error
@@ -74,5 +67,4 @@ type EngineDependencies struct {
7467 ContextMenuExecutorFactory port.ContextMenuActionExecutorFactory
7568 Clipboard port.Clipboard
7669 ImageDataResolver port.ImageDataResolver
77- MediaClassifier MediaClassifier
7870 }
@@ -23,13 +23,6 @@ type RuntimeConfig struct {
23 TraceHandlers bool23 TraceHandlers bool
24 }24 }
25 25
26-type TranscodingRuntimeConfig struct {
27- Enabled bool
28- HWAccel string
29- MaxConcurrent int
30- Quality string
31-}
32-
33 type HandlerRegistrar func(context.Context, port.WebUIHandlerRouter, port.HandlerDependencies) error26 type HandlerRegistrar func(context.Context, port.WebUIHandlerRouter, port.HandlerDependencies) error
34 27
35 type AccentHandlerRegistrar func(context.Context, port.WebUIHandlerRouter, port.AccentKeyHandler) error28 type AccentHandlerRegistrar func(context.Context, port.WebUIHandlerRouter, port.AccentKeyHandler) error
@@ -74,5 +67,4 @@ type EngineDependencies struct {
74 ContextMenuExecutorFactory port.ContextMenuActionExecutorFactory67 ContextMenuExecutorFactory port.ContextMenuActionExecutorFactory
75 Clipboard port.Clipboard68 Clipboard port.Clipboard
76 ImageDataResolver port.ImageDataResolver69 ImageDataResolver port.ImageDataResolver
77- MediaClassifier MediaClassifier
78 }70 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close