Files
core/ffmpeg/skills/framebuffer.go
Jan Stabenow 9c0b535199 Add v16.7.2
2022-05-13 19:26:45 +02:00

136 lines
2.7 KiB
Go

package skills
import (
"bufio"
"bytes"
"fmt"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
)
type fbformat struct {
bpp int
roffset int
goffset int
boffset int
aoffset int
format string
}
var fbformats []fbformat = []fbformat{
{32, 0, 8, 16, 24, "rgba"},
{32, 16, 8, 0, 24, "bgra"},
{32, 8, 16, 24, 0, "argb"},
{32, 3, 2, 8, 0, "abgr"},
{24, 0, 8, 16, 0, "rgb24"},
{24, 16, 8, 0, 0, "bgr24"},
{16, 11, 5, 0, 0, "rgb565le"},
{16, 0, 5, 11, 0, "rgb565be"},
}
// DevicesFramebuffer returns a list of framebuffer devices found on the system
func DevicesFramebuffer() ([]HWDevice, error) {
devices := []HWDevice{}
for i := 0; i < 32; i++ {
path := fmt.Sprintf("/dev/fb%d", i)
_, err := os.Stat(path)
if err != nil {
break
}
buf := bytes.NewBuffer(nil)
cmd := exec.Command("fbset", "-s", "-fb", path)
cmd.Env = []string{}
cmd.Stdout = buf
cmd.Run()
device := HWDevice{
Id: path,
Name: path,
Extra: parseFramebufferDevice(buf),
Media: "video",
}
devices = append(devices, device)
}
return devices, nil
}
func parseFramebufferDevice(data *bytes.Buffer) string {
reGeometry := regexp.MustCompile(`geometry ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)`)
reRGBA := regexp.MustCompile(`rgba ([0-9]+/[0-9]+),([0-9]+/[0-9]+),([0-9]+/[0-9]+),([0-9]+/[0-9]+)`)
geometry := ""
format := fbformat{}
scanner := bufio.NewScanner(data)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
line := scanner.Text()
matches := reGeometry.FindStringSubmatch(line)
if matches != nil {
geometry = fmt.Sprintf("%sx%s", matches[1], matches[2])
if matches[1] != matches[3] || matches[2] != matches[4] {
geometry += fmt.Sprintf(" (%sx%s)", matches[3], matches[4])
}
if x, err := strconv.Atoi(matches[5]); err == nil {
format.bpp = x
}
}
matches = reRGBA.FindStringSubmatch(line)
if matches != nil {
format.roffset = parseFramebufferDeviceOffset(matches[1])
format.goffset = parseFramebufferDeviceOffset(matches[2])
format.boffset = parseFramebufferDeviceOffset(matches[3])
format.aoffset = parseFramebufferDeviceOffset(matches[4])
}
}
if len(geometry) == 0 || format.bpp == 0 {
return ""
}
for _, f := range fbformats {
if f.bpp == format.bpp && f.roffset == format.roffset && f.goffset == format.goffset && f.boffset == format.boffset {
return geometry + " " + f.format
}
}
return ""
}
func parseFramebufferDeviceOffset(format string) int {
c := strings.Split(format, "/")
bits := 0
offset := 0
if x, err := strconv.Atoi(c[0]); err == nil {
bits = x
} else {
return 0
}
if x, err := strconv.Atoi(c[1]); err == nil {
offset = x
} else {
return 0
}
if bits == 0 {
return 0
}
return offset
}