NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Go modules · #3085 by repository stars
Last release 6 months ago
06 Apr 2026
Ships unpredictably
gaps range from 8 days to 1.6 years
Nearly every release is documented
notes for 9 of 9 stable releases
Nothing withdrawn
no release was ever pulled
5 years old
60 releases · first in 2021
One column per quarter.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
This release primarily introduces a new fix to the Device API which was forcing an awkward call sequence (see #95 ). The release also introduces many
This release primarily introduces a new fix to the Device API which was forcing an awkward call sequence (see #95). The release also introduces many new features and enhancements.
Start()/GetOutput()/GetFrames() ordering issue (#95) — allow calling Start() before selecting aStart() now handles buffer queueing and StreamOn directly, without requiring a streaming mode to beGetOutput() / GetFrames() can be called after Start()Overhaul integration test infrastructure to support both real devices and v4l2loopback emulation cleanly. This allows tests to run on a device such as Raspberry Pi with a camera attached or in a CI/CD environment. End-to-end integration tests are important to catch issues that unit tests are not capable of revealing.
sudo modprobe v4l2loopback devices=2 video_nr=42,43 card_label="go4vl_test_1,go4vl_test_2" exclusive_caps=0
go test -v -tags=integration ./test/... -args -use-device-emulation=/dev/video42,/dev/video43
New test flags
-use-device=auto — auto-discover real V4L2 devices-use-device=/dev/video0 — use specific real device-use-device-emulation=auto — auto-discover or load v4l2loopback-use-device-emulation=/dev/video42,/dev/video43 — use specific loopback devicesNew Hardware Codecs
Implement new V4L2 codec support for hardware-accelerated video encoding/decoding:
VIDIOC_ENCODER_CMD and VIDIOC_DECODER_CMD ioctls including START, STOP, PAUSE, RESUME, and FLUSH operationsOUTPUT/CAPTURE queue managementFull Changelog: 0.4.0...v0.5.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Cleaned up legacy/deprecated packages
The vendored Linux kernel headers (include/linux/ directory) have been removed from the repository. go4vl now requires system V4L2 kernel headers to be installed.
Migration Required:
Users must install V4L2 kernel headers on their system:
# Ubuntu/Debian
sudo apt install linux-libc-dev
# Fedora/RHEL/CentOS
sudo dnf install kernel-headers
# Arch Linux
sudo pacman -S linux-headers
# Alpine Linux
apk add linux-headersWhy this change?
Using Custom Headers:
If you need specific kernel header versions or are cross-compiling, use the CGO_CFLAGS environment variable:
CGO_CFLAGS="-I/path/to/custom/headers" go build ./v4l2See docs/BUILD.md for comprehensive build instructions.
CGO_CFLAGS override mechanism for custom headersv4l2/cgo.go/usr/includemultipass directory and related codedocs/BUILD.md - Comprehensive build documentation (519 lines)README.md - Added Building section with quick start commandsexamples/README.md - Updated with header installation instructionsv4l2/cgo.go - Centralized CGo configuration with documentationv4l2/doc.go - Updated package documentationinclude/linux/videodev2.h - 2,770 lines (now uses system headers)include/linux/v4l2-controls.h - 2,486 lines (now uses system headers)include/linux/v4l2-common.h - 108 lines (now uses system headers)include/README.md - Removed vendored headers documentationmultipass/ - Removed unsupported packageMerged Pull Requests:
Commits: +620 additions, −5,586 deletions across 18 files
Compare: v0.2.0...v0.3.0
Nothing published for this version
Nothing published for this version
Fix race condition in Device.Stop() and deprecate Device.GetOutput() API The Device.Stop() method had a critical race condition causing segmentation f…
Introduction of the new Deivce.GetFrames that creates a pool of buffers to avoid continuous allocation. The method uses type Frame which not only returns the captured buffer from the driver, but also include metadata for each frame.
New pooling API for frame capture:
Fix race condition in Device.Stop() and deprecate Device.GetOutput() API
The Device.Stop() method had a critical race condition causing segmentation faults during streaming cleanup.
Stop() would un-map memory buffers while capture goroutines were still accessing them, leading to crashes in
benchmarks and tests.
Test infrastructure improvements:
Integration tests and benchmarks
See test/README.md for detail
Documentation updates:
Marked GetOutput() as deprecated with clear migration guidance:
// Deprecated: Use GetFrames() instead. GetFrames() provides the same functionality
// with significantly better performance through buffer pooling, using 540x less memory
// (1 KB vs 614 KB per frame) and reducing GC pressure. This method will be removed
// in a future version.
Full Changelog: v0.1.0...v0.2.0
This release is a reboot of the project to introduce work that has been done in the last couple years with a formal tag. Thank you to the many contrib
This release is a reboot of the project to introduce work that has been done in the last couple years with a formal tag. Thank you to the many contributors who have participated in the project so far.
Full Changelog: v0.0.5...v0.1.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
This release primarily focused on code changes to support updates to the webcam example, including:
This release primarily focused on code changes to support updates to the webcam example, including:
snapshot and simplecamThis release introduced crucial bug fixes and other features including:
This release introduced crucial bug fixes and other features including:
This release introduces support for V4L2 extended controls.
The following example shows how to retrieve all available extended controls from the driver.
func main() {
device, err := dev.Open("/dev/video0")
if err != nil {
log.Fatalf("failed to open device: %s", err)
}
defer device.Close()
ctrls, err := v4l2.QueryAllExtControls(device.Fd())
if err != nil {
log.Fatalf("failed to get ext controls: %s", err)
}
if len(ctrls) == 0 {
log.Println("Device does not have extended controls")
os.Exit(0)
}
for _, ctrl := range ctrls {
printControl(ctrl)
}
func printControl(ctrl v4l2.Contro) { ... }
}See full example here
Since the inception of the project, it was known there were some bugs that needed to be revisited. We found out that some of the examples were failing when running on a Raspberry PI and capturing from a Raspberry Pi HD camera module. The code's use of the Go's standard library os.OpenFile was causing the device to report busy (when compared to similar programs in C).
So this called for an overhaul of the entire capture sequence which delivered the followings
User @oyarzun reported a memory leak when running the webcam example (see issue #22). After a few hours of Go program profiling, it was found that the internal stream loop was leaking Go channel resources (by reinitialize the channel in the loop). After a simple fix (moving the channel initialization outside of the loop), the leak went away. After running the webcam program for over 25 hours on a RPi 3, it was observed that the memory consumption did not go over 1%. That was an awesome find.
Nothing published for this version
The main theme for this release is the introduction of the Control API with initial support of the V4L2 user controls. This release adds the following
The main theme for this release is the introduction of the Control API with initial support of the V4L2 user controls. This release adds the followings:
Device type to add new methods to work with the control APIfunc main() {
device, err := dev.Open(devName)
if err != nil {
log.Fatalf("failed to open device: %s", err)
}
defer device.Close()
// set single device control value
val := 12
device.SetControlValue(v4l2.CtrlBrightness, v4l2.CtrlValue(val))
// retrieve Control
ctrl, _ := device.GetControl(ctrlID)
fmt.Printf("Control id (%d) name: %s\t[min: %d; max: %d; step: %d; default: %d current_val: %d]\n",
ctrl.ID, ctrl.Name, ctrl.Minimum, ctrl.Maximum, ctrl.Step, ctrl.Default, ctrl.Value)
}For more detail, see the example
Another improvement contributed by the community (thanks @ajcasagrande) is the inclusion of V4L2 header files as part of the project. This will provide consistent builds without relying on user's local header files (which can sometimes be outdated).
See the include directory for detail.
To ease local development for non-Linux environment, this release comes with a script that can launch a Canonical Ubuntu VM managed by Multipass. This provides a VM along with a fake V4L2 driver (V4L2Loopback) to help run and test the project without the need of an environment with a real video camera attached.
See the multipass directory for detail.
This release introduces major refactor that simplifies the way the API works. Unfortunately, these changes are not backward compatible with the previo
This release introduces major refactor that simplifies the way the API works. Unfortunately, these changes are not backward compatible with the previous version. Meaning, if you adopt this release, you will have to modify your existing code a bit.
device packageThis release introduces a new device package to create and access device functionalities.
device packageThe device API creates a device without having to use the v4l2 directly.
import "github.com/vladimirvivien/go4vl/device"
func main() {
device, err := device.Open("/dev/video0")
...
}function device.Open supports variable length arguments that can be used to specify the configuration of the device as it is being created:
func main() {
device, err := device.Open("/dev/video0",
device.WithIOType(v4l2.IOTypeMMAP),
device.WithPixFormat(v4l2.PixFormat{PixelFormat: getFormatType(format), Width: uint32(width), Height: uint32(height)}),
device.WithFPS(uint32(frameRate)),
)
}Once a device is created, it can be started with a context as shown below
func main() {
device, err := device.Open("/dev/video0")
ctx, stop := context.WithCancel(context.TODO())
if err := device.Start(ctx); err != nil {
log.Fatalf("failed to start stream: %s", err)
}
}After a device has started, it's stream can be accessed as shown
func main() {
device, err := device.Open("/dev/video0")
ctx, stop := context.WithCancel(context.TODO())
if err := device.Start(ctx); err != nil {
log.Fatalf("failed to start stream: %s", err)
}
for frame := range device.GetOutput() {
....
}
}This release introduces access to more device information via additional types.
See the device info example for detail.
Nothing published for this version
Nothing published for this version
This release comes after an internal rewrite to use cgo-generated types and values (instead of hand-crafted types) to deal with type alignment issues.
This release comes after an internal rewrite to use cgo-generated types and values (instead of hand-crafted types) to deal with type alignment issues. Since the project targets the Linux OS, there is no need to be concerned with portability or cross-platform supportability.
The API is the same from the previous release. However, there are some changes that will cause code breakage (if you are using the previously tagged version) in how some types expose their values.
The ./examples directory contains additional examples including:
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →