capture1

command
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2024 License: MIT Imports: 10 Imported by: 0

README

Capture example

In this capture example, the source code uses a more advanced approach (compared to capture0/capture0.go) where it leverages the go4vl device description API to ensure that the device supports the selected preferred format and size.

First, the source code opens the device with device.Open function call. Unlike in the previous example, the call to Open omits the pixel format option.

func main() {
	devName := "/dev/video0"
	device, err := device.Open(devName)
	if err != nil {
		log.Fatalf("failed to open device: %s", err)
	}
	defer device.Close()
}

Next, the source code defines a function that is used to search formats supported by the device.

func main() {
...
	findPreferredFmt := func(fmts []v4l2.FormatDescription, pixEncoding v4l2.FourCCType) *v4l2.FormatDescription {
		for _, desc := range fmts {
			if desc.PixelFormat == pixEncoding{
				return &desc
			}
		}
		return nil
	}
}

Next, the code enumerates the formats supported by the device, device.GetFormatDescriptions, and used the search function to test whether the device support one of several preferred formats.

func main() {
...
	fmtDescs, err := device.GetFormatDescriptions()
	if err != nil{
		log.Fatal("failed to get format desc:", err)
	}

	// search for preferred formats
	preferredFmts := []v4l2.FourCCType{v4l2.PixelFmtMPEG, v4l2.PixelFmtMJPEG, v4l2.PixelFmtJPEG, v4l2.PixelFmtYUYV}
	var fmtDesc *v4l2.FormatDescription
	for _, preferredFmt := range preferredFmts{
		fmtDesc = findPreferredFmt(fmtDescs, preferredFmt)
		if fmtDesc != nil {
			break
		}
	}
}

Next, if one of the preferred formats is found, then it is assigned to fmtDesc. The next step is to search the device for an appropriate supported dimension (640x480) for the selected format which is stored in frmSize.

func main() {
...
    frameSizes, err := v4l2.GetFormatFrameSizes(device.Fd(), fmtDesc.PixelFormat)

	// select size 640x480 for format
	var frmSize v4l2.FrameSizeEnum
	for _, size := range frameSizes {
		if size.Size.MinWidth == 640 && size.Size.MinHeight == 480 {
			frmSize = size
			break
		}
	}
}

At this point, the device can be assigned the selected pixel format and its associated size.

func main() {
...
	if err := device.SetPixFormat(v4l2.PixFormat{
		Width:       frmSize.Size.MinWidth,
		Height:      frmSize.Size.MinHeight,
		PixelFormat: fmtDesc.PixelFormat,
		Field:       v4l2.FieldNone,
	}); err != nil {
		log.Fatalf("failed to set format: %s", err)
	}
}

Finally, the device can be started and the streaming buffers can be captured:

fun main() {
...
	if err := device.Start(ctx); err != nil {
		log.Fatalf("failed to stream: %s", err)
	}

	for frame := range device.GetOutput() {
		fileName := fmt.Sprintf("capture_%d.jpg", count)
		file, err := os.Create(fileName)
		if err != nil {
			log.Printf("failed to create file %s: %s", fileName, err)
			continue
		}
		if _, err := file.Write(frame); err != nil {
			log.Printf("failed to write file %s: %s", fileName, err)
			continue
		}
        ...
	}
}

See source code here.

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL