Files
go-mxl-pattern-generator/internal/video/generator.go
T
2026-09-18 10:25:35 +03:00

90 lines
2.2 KiB
Go

package video
import (
"errors"
"fmt"
"log"
"mxl-pattern-generator/internal/generator"
)
type generatorFactory func() (generator.FrameGenerator, error)
func newFrameGenerator(cfg Config, pattern pattern) (generator.FrameGenerator, Backend, error) {
newGPU := func() (generator.FrameGenerator, error) {
return generator.NewWGPUGenerator(cfg.Width(), cfg.Height(), pattern.kernelSource)
}
newCPU := func() (generator.FrameGenerator, error) {
return generator.NewCPUPatternGenerator(cfg.Width(), cfg.Height(), cfg.Pattern)
}
fill, backend, err := selectFrameGenerator(cfg.Backend, newGPU, newCPU)
if err != nil {
return nil, "", err
}
gen, err := wrapAlphaGenerator(cfg, fill, pattern.dynamic)
if err != nil {
return nil, "", err
}
return gen, backend, nil
}
func wrapAlphaGenerator(
cfg Config,
fill generator.FrameGenerator,
fillDynamic bool,
) (generator.FrameGenerator, error) {
if !cfg.HasAlpha() {
return fill, nil
}
gen, err := generator.NewV210AGenerator(fill, cfg.Width(), cfg.Height(), fillDynamic)
if err != nil {
closeErr := fill.Close()
return nil, errors.Join(
fmt.Errorf("initialize v210a generator: %w", err),
closeErr,
)
}
return gen, nil
}
func selectFrameGenerator(
backend Backend,
newGPU, newCPU generatorFactory,
) (generator.FrameGenerator, Backend, error) {
switch backend {
case BackendGPU:
gen, err := newGPU()
if err != nil {
return nil, "", fmt.Errorf("initialize GPU video generator: %w", err)
}
return gen, BackendGPU, nil
case BackendCPU:
gen, err := newCPU()
if err != nil {
return nil, "", fmt.Errorf("initialize CPU video generator: %w", err)
}
return gen, BackendCPU, nil
case "", BackendAuto:
gpuGen, gpuErr := newGPU()
if gpuErr == nil {
return gpuGen, BackendGPU, nil
}
log.Printf("GPU video generator unavailable, falling back to CPU: %v", gpuErr)
cpuGen, cpuErr := newCPU()
if cpuErr == nil {
return cpuGen, BackendCPU, nil
}
return nil, "", errors.Join(
fmt.Errorf("initialize GPU video generator: %w", gpuErr),
fmt.Errorf("initialize CPU video generator: %w", cpuErr),
)
default:
return nil, "", fmt.Errorf("unsupported video backend %q", backend)
}
}