fix: normalize desktop capture dimensions
This commit is contained in:
parent
0f096a588d
commit
0a0d04f3a7
@ -20,6 +20,32 @@ func normalizeRTPPort(port int) int {
|
||||
return port
|
||||
}
|
||||
|
||||
func normalizeVideoDimension(value, fallback int) int {
|
||||
if value <= 0 {
|
||||
value = fallback
|
||||
}
|
||||
if value%2 != 0 {
|
||||
value--
|
||||
}
|
||||
if value < 2 {
|
||||
return fallback
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func normalizePipelineConfig(cfg PipelineConfig) PipelineConfig {
|
||||
cfg.Port = normalizeRTPPort(cfg.Port)
|
||||
cfg.Width = normalizeVideoDimension(cfg.Width, 1280)
|
||||
cfg.Height = normalizeVideoDimension(cfg.Height, 720)
|
||||
if cfg.FPS <= 0 {
|
||||
cfg.FPS = 30
|
||||
}
|
||||
if cfg.Bitrate <= 0 {
|
||||
cfg.Bitrate = 2000
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
// PipelineManager manages the screen capture process lifecycle
|
||||
type PipelineManager struct {
|
||||
cmd *exec.Cmd
|
||||
@ -58,19 +84,7 @@ func (pm *PipelineManager) Start(cfg PipelineConfig) error {
|
||||
cfg.Display = ":0.0"
|
||||
}
|
||||
}
|
||||
cfg.Port = normalizeRTPPort(cfg.Port)
|
||||
if cfg.Width <= 0 {
|
||||
cfg.Width = 1280
|
||||
}
|
||||
if cfg.Height <= 0 {
|
||||
cfg.Height = 720
|
||||
}
|
||||
if cfg.FPS <= 0 {
|
||||
cfg.FPS = 30
|
||||
}
|
||||
if cfg.Bitrate <= 0 {
|
||||
cfg.Bitrate = 2000
|
||||
}
|
||||
cfg = normalizePipelineConfig(cfg)
|
||||
|
||||
tool, args, err := pm.resolvePipeline(cfg)
|
||||
if err != nil {
|
||||
@ -172,13 +186,18 @@ func (pm *PipelineManager) hasExecutable(name string) bool {
|
||||
}
|
||||
|
||||
func (pm *PipelineManager) buildGStreamer(cfg PipelineConfig) (string, []string, error) {
|
||||
cfg = normalizePipelineConfig(cfg)
|
||||
var pipelineParts []string
|
||||
|
||||
// 1. Capture Source (X11)
|
||||
pipelineParts = append(pipelineParts, fmt.Sprintf("ximagesrc display-name=%s", cfg.Display))
|
||||
pipelineParts = append(pipelineParts, "video/x-raw,framerate=30/1")
|
||||
pipelineParts = append(pipelineParts, fmt.Sprintf("video/x-raw,framerate=%d/1", cfg.FPS))
|
||||
pipelineParts = append(pipelineParts, "videoconvert")
|
||||
pipelineParts = append(pipelineParts, "video/x-raw,format=I420")
|
||||
pipelineParts = append(pipelineParts, "videoscale")
|
||||
pipelineParts = append(
|
||||
pipelineParts,
|
||||
fmt.Sprintf("video/x-raw,format=I420,width=%d,height=%d,framerate=%d/1", cfg.Width, cfg.Height, cfg.FPS),
|
||||
)
|
||||
|
||||
// 2. Encoder
|
||||
encoderStr := "x264enc speed-preset=ultrafast tune=zerolatency bitrate=" + fmt.Sprintf("%d", cfg.Bitrate) + " byte-stream=true key-int-max=30"
|
||||
@ -211,6 +230,7 @@ func (pm *PipelineManager) buildGStreamer(cfg PipelineConfig) (string, []string,
|
||||
}
|
||||
|
||||
func (pm *PipelineManager) buildFFmpeg(cfg PipelineConfig) (string, []string, error) {
|
||||
cfg = normalizePipelineConfig(cfg)
|
||||
args := []string{
|
||||
"-f", "x11grab",
|
||||
"-draw_mouse", "1",
|
||||
|
||||
@ -23,6 +23,8 @@ func TestBuildGStreamerUsesBrowserFriendlyH264(t *testing.T) {
|
||||
joined := strings.Join(args, " ")
|
||||
for _, expected := range []string{
|
||||
"video/x-raw,format=I420",
|
||||
"width=1280",
|
||||
"height=720",
|
||||
"x264enc",
|
||||
"tune=zerolatency",
|
||||
"key-int-max=30",
|
||||
@ -37,6 +39,18 @@ func TestBuildGStreamerUsesBrowserFriendlyH264(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeVideoDimensionUsesEvenValues(t *testing.T) {
|
||||
if got := normalizeVideoDimension(1353, 1280); got != 1352 {
|
||||
t.Fatalf("expected odd dimension to be rounded down to 1352, got %d", got)
|
||||
}
|
||||
if got := normalizeVideoDimension(0, 720); got != 720 {
|
||||
t.Fatalf("expected fallback for zero dimension, got %d", got)
|
||||
}
|
||||
if got := normalizeVideoDimension(1, 720); got != 720 {
|
||||
t.Fatalf("expected fallback for too-small dimension, got %d", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildFFmpegUsesBrowserFriendlyH264(t *testing.T) {
|
||||
pm := NewPipelineManager()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user