v0.15.0 9006957

codec.go RawHistoryFolder

1package environment
2
3import (
4	"fmt"
5	"os"
6	"strconv"
7	"strings"
8
9	"github.com/bnema/dumber/internal/config"
10	"github.com/bnema/dumber/internal/logging"
11)
12
13// ApplyCodecConfiguration applies codec preferences to environment variables and GStreamer settings
14func ApplyCodecConfiguration(codecPrefs config.CodecConfig) {
15	logging.Info(fmt.Sprintf("[codec] Applying codec preferences: preferred=%s, force_av1=%t, block_vp9=%t",
16		codecPrefs.PreferredCodecs, codecPrefs.ForceAV1, codecPrefs.BlockVP9))
17
18	// Build comprehensive GStreamer plugin rankings
19	var rankSettings []string
20
21	// Get existing GST_PLUGIN_FEATURE_RANK or start fresh
22	existingRank := os.Getenv("GST_PLUGIN_FEATURE_RANK")
23	if existingRank != "" {
24		rankSettings = strings.Split(existingRank, ",")
25	}
26
27	// AV1 decoder promotions (high priority)
28	if codecPrefs.ForceAV1 || strings.Contains(codecPrefs.PreferredCodecs, "av1") {
29		av1Ranks := []string{
30			"vaav1dec:768",  // VA-API AV1 decoder (highest priority)
31			"nvav1dec:512",  // NVDEC AV1 decoder
32			"av1dec:384",    // Software AV1 decoder (fallback)
33			"avdec_av1:256", // libav AV1 decoder
34		}
35		rankSettings = append(rankSettings, av1Ranks...)
36		logging.Info(fmt.Sprintf("[codec] Promoted AV1 decoders for maximum priority"))
37	}
38
39	// H.264 decoder management
40	if strings.Contains(codecPrefs.PreferredCodecs, "h264") {
41		h264Ranks := []string{
42			"vah264dec:512",  // VA-API H.264 decoder
43			"nvh264dec:384",  // NVDEC H.264 decoder
44			"avdec_h264:256", // Software H.264 decoder
45		}
46		rankSettings = append(rankSettings, h264Ranks...)
47	}
48
49	// VP9 decoder demotion/blocking
50	if codecPrefs.DisableVP9Hardware || codecPrefs.BlockVP9 {
51		vp9Demotions := []string{
52			"vaapivp9dec:0", // Block VA-API VP9
53			"nvvp9dec:0",    // Block NVDEC VP9
54		}
55		if codecPrefs.BlockVP9 {
56			vp9Demotions = append(vp9Demotions, "vp9dec:0", "avdec_vp9:0") // Block all VP9
57		} else {
58			// Allow software VP9 with low priority
59			vp9Demotions = append(vp9Demotions, "vp9dec:64", "avdec_vp9:64")
60		}
61		rankSettings = append(rankSettings, vp9Demotions...)
62		logging.Info(fmt.Sprintf("[codec] Demoted/blocked VP9 decoders"))
63	}
64
65	// VP8 decoder blocking
66	if codecPrefs.BlockVP8 {
67		vp8Demotions := []string{
68			"vaapivp8dec:0",
69			"vp8dec:0",
70			"avdec_vp8:0",
71		}
72		rankSettings = append(rankSettings, vp8Demotions...)
73		logging.Info(fmt.Sprintf("[codec] Blocked VP8 decoders"))
74	}
75
76	// Apply the complete ranking system
77	if len(rankSettings) > 0 {
78		finalRank := strings.Join(rankSettings, ",")
79		if err := os.Setenv("GST_PLUGIN_FEATURE_RANK", finalRank); err != nil {
80			logging.Warn(fmt.Sprintf("[codec] Warning: failed to set GST_PLUGIN_FEATURE_RANK: %v", err))
81		} else {
82			logging.Info(fmt.Sprintf("[codec] Set comprehensive GST_PLUGIN_FEATURE_RANK: %s", finalRank))
83		}
84	}
85
86	// Set video buffer sizes if specified
87	if codecPrefs.VideoBufferSizeMB > 0 {
88		bufferSize := strconv.Itoa(codecPrefs.VideoBufferSizeMB * 1024 * 1024)
89
90		if err := os.Setenv("GST_BUFFER_SIZE", bufferSize); err != nil {
91			logging.Warn(fmt.Sprintf("[codec] Warning: failed to set GST_BUFFER_SIZE: %v", err))
92		}
93
94		if err := os.Setenv("GST_QUEUE2_MAX_SIZE_BYTES", bufferSize); err != nil {
95			logging.Warn(fmt.Sprintf("[codec] Warning: failed to set GST_QUEUE2_MAX_SIZE_BYTES: %v", err))
96		}
97
98		logging.Info(fmt.Sprintf("[codec] Set video buffer size to %dMB", codecPrefs.VideoBufferSizeMB))
99	}
100
101	// Set queue buffer time if specified
102	if codecPrefs.QueueBufferTimeSec > 0 {
103		// Convert seconds to nanoseconds for GStreamer
104		bufferTime := strconv.Itoa(codecPrefs.QueueBufferTimeSec * 1000000000)
105
106		if err := os.Setenv("GST_QUEUE2_MAX_SIZE_TIME", bufferTime); err != nil {
107			logging.Warn(fmt.Sprintf("[codec] Warning: failed to set GST_QUEUE2_MAX_SIZE_TIME: %v", err))
108		} else {
109			logging.Info(fmt.Sprintf("[codec] Set queue buffer time to %ds", codecPrefs.QueueBufferTimeSec))
110		}
111	}
112
113	// Set additional codec-specific environment variables
114	if codecPrefs.ForceAV1 {
115		// Enable AV1 hardware decoding if available
116		if err := os.Setenv("GST_AV1_DECODER_ENABLE_HW", "1"); err != nil {
117			logging.Warn(fmt.Sprintf("[codec] Warning: failed to set GST_AV1_DECODER_ENABLE_HW: %v", err))
118		}
119	}
120
121	// Disable video post-processing to avoid VA-API issues
122	if err := os.Setenv("GST_VAAPI_DISABLE_VPP", "1"); err != nil {
123		logging.Warn(fmt.Sprintf("[codec] Warning: failed to set GST_VAAPI_DISABLE_VPP: %v", err))
124	}
125
126	logging.Info(fmt.Sprintf("[codec] Codec configuration applied successfully"))
127}
128
129// BuildBlockedCodecsList converts config codec blocking preferences to a string slice
130func BuildBlockedCodecsList(codecPrefs config.CodecConfig) []string {
131	var blocked []string
132
133	if codecPrefs.BlockVP9 {
134		blocked = append(blocked, "vp9")
135	}
136	if codecPrefs.BlockVP8 {
137		blocked = append(blocked, "vp8")
138	}
139
140	return blocked
141}

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