v0.14.0 76d1892

codec.go RawHistoryFolder

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

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