Show camera name and pixel format in startup banner

This commit is contained in:
Milan Nikolic
2026-06-30 15:28:53 +02:00
parent 1a24bd6337
commit 87461e519e
7 changed files with 96 additions and 1 deletions

View File

@@ -22,6 +22,45 @@ type DeviceInfo struct {
Name string
}
// Info describes the negotiated capture format.
type Info struct {
Format string
Width int
Height int
}
// fourccName returns a readable name for a V4L/VfW pixel format.
func fourccName(format uint32) string {
switch format {
case mjpgFourCC:
return "MJPEG"
case jpegFourCC:
return "JPEG"
case yuyvFourCC, yuy2FourCC:
return "YUYV"
case uyvyFourCC:
return "UYVY"
case yvyuFourCC:
return "YVYU"
case vyuyFourCC:
return "VYUY"
case nv12FourCC:
return "NV12"
case yu12FourCC:
return "YU12"
case yv12FourCC:
return "YV12"
case rgb24FourCC:
return "RGB24"
case bgr24FourCC:
return "BGR24"
case greyFourCC:
return "GREY"
}
return string([]byte{byte(format), byte(format >> 8), byte(format >> 16), byte(format >> 24)})
}
var (
yuy2FourCC = fourcc("YUY2")
yuyvFourCC = fourcc("YUYV")

View File

@@ -100,6 +100,11 @@ func New(opts Options) (c *Camera, err error) {
return c, nil
}
// Info returns the negotiated capture format.
func (c *Camera) Info() Info {
return Info{Format: "BGRA", Width: int(c.opts.Width), Height: int(c.opts.Height)}
}
// Devices returns the available capture devices.
func Devices() ([]DeviceInfo, error) {
if err := loadFrameworks(); err != nil {

View File

@@ -215,6 +215,11 @@ func (c *Camera) Close() (err error) {
return
}
// Info returns the negotiated capture format.
func (c *Camera) Info() Info {
return Info{Format: fourccName(c.config.Format), Width: c.config.Width, Height: c.config.Height}
}
// Devices returns the available capture devices.
func Devices() ([]DeviceInfo, error) {
infos := v4l.FindDevices()

View File

@@ -10,6 +10,10 @@ import (
)
func TestCamera(t *testing.T) {
if testing.Short() {
t.Skip("skipping camera test in short mode")
}
camera, err := New(Options{0, 0, "", 640, 480, false, ""})
if err != nil {
t.Skipf("no camera available: %v", err)

View File

@@ -449,6 +449,11 @@ func nv12ToYCbCr420(data []byte, stride, width, height int, dst *image.YCbCr) {
}
}
// Info returns the negotiated capture format.
func (c *Camera) Info() Info {
return Info{Format: "NV12", Width: c.width, Height: c.height}
}
// Devices returns the available capture devices.
func Devices() ([]DeviceInfo, error) {
runtime.LockOSThread()

View File

@@ -25,6 +25,8 @@ type Camera struct {
className string
format uint32
bpp int
width int
height int
}
// New returns new Camera for given camera index.
@@ -145,6 +147,9 @@ func (c *Camera) run(ready chan<- error) {
height = -height
}
c.width = width
c.height = height
rect := image.Rect(0, 0, width, height)
switch {
@@ -483,6 +488,16 @@ func capCreateCaptureWindow(lpszWindowName string, dwStyle, x, y, width, height
return syscall.Handle(ret), nil
}
// Info returns the negotiated capture format.
func (c *Camera) Info() Info {
format := fourccName(c.format)
if c.format == 0 {
format = fmt.Sprintf("RGB%d", c.bpp*8)
}
return Info{Format: format, Width: c.width, Height: c.height}
}
// Devices returns the available capture devices.
func Devices() ([]DeviceInfo, error) {
var devices []DeviceInfo

View File

@@ -139,7 +139,13 @@ func main() {
defer srv.Reader.Close()
stderr("%s %s listening on %s\n", name, version, srv.Bind)
info := cam.Info()
desc := fmt.Sprintf("%dx%d %s", info.Width, info.Height, info.Format)
if dn := deviceName(srv.Index); dn != "" {
desc = dn + ", " + desc
}
stderr("%s %s [%s] listening on %s\n", name, version, desc, srv.Bind)
err = srv.ListenAndServe()
if err != nil {
@@ -152,6 +158,22 @@ func stderr(format string, a ...any) {
_, _ = fmt.Fprintf(os.Stderr, format, a...)
}
// deviceName returns the name of the camera at the given index, or "" if unknown.
func deviceName(index int) string {
devices, err := camera.Devices()
if err != nil {
return ""
}
for _, d := range devices {
if d.Index == index {
return d.Name
}
}
return ""
}
// deviceIndex returns the index of the first camera whose name contains the query.
func deviceIndex(name string) (int, error) {
devices, err := camera.Devices()