123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- package v4l2
- /*
- #cgo linux CFLAGS: -I ${SRCDIR}/../include/
- #include <linux/videodev2.h>
- */
- import "C"
- import (
- "fmt"
- "unsafe"
- )
- // V4l2 video capability constants
- // see https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L451
- const (
- CapVideoCapture uint32 = C.V4L2_CAP_VIDEO_CAPTURE
- CapVideoOutput uint32 = C.V4L2_CAP_VIDEO_OUTPUT
- CapVideoOverlay uint32 = C.V4L2_CAP_VIDEO_OVERLAY
- CapVBICapture uint32 = C.V4L2_CAP_VBI_CAPTURE
- CapVBIOutput uint32 = C.V4L2_CAP_VBI_OUTPUT
- CapSlicedVBICapture uint32 = C.V4L2_CAP_SLICED_VBI_CAPTURE
- CapSlicedVBIOutput uint32 = C.V4L2_CAP_SLICED_VBI_OUTPUT
- CapRDSCapture uint32 = C.V4L2_CAP_RDS_CAPTURE
- CapVideoOutputOverlay uint32 = C.V4L2_CAP_VIDEO_OUTPUT_OVERLAY
- CapHWFrequencySeek uint32 = C.V4L2_CAP_HW_FREQ_SEEK
- CapRDSOutput uint32 = C.V4L2_CAP_RDS_OUTPUT
- CapVideoCaptureMPlane uint32 = C.V4L2_CAP_VIDEO_CAPTURE_MPLANE
- CapVideoOutputMPlane uint32 = C.V4L2_CAP_VIDEO_OUTPUT_MPLANE
- CapVideoMem2MemMPlane uint32 = C.V4L2_CAP_VIDEO_M2M_MPLANE
- CapVideoMem2Mem uint32 = C.V4L2_CAP_VIDEO_M2M
- CapTuner uint32 = C.V4L2_CAP_TUNER
- CapAudio uint32 = C.V4L2_CAP_AUDIO
- CapRadio uint32 = C.V4L2_CAP_RADIO
- CapModulator uint32 = C.V4L2_CAP_MODULATOR
- CapSDRCapture uint32 = C.V4L2_CAP_SDR_CAPTURE
- CapExtendedPixFormat uint32 = C.V4L2_CAP_EXT_PIX_FORMAT
- CapSDROutput uint32 = C.V4L2_CAP_SDR_OUTPUT
- CapMetadataCapture uint32 = C.V4L2_CAP_META_CAPTURE
- CapReadWrite uint32 = C.V4L2_CAP_READWRITE
- CapAsyncIO uint32 = C.V4L2_CAP_ASYNCIO
- CapStreaming uint32 = C.V4L2_CAP_STREAMING
- CapMetadataOutput uint32 = C.V4L2_CAP_META_OUTPUT
- CapTouch uint32 = C.V4L2_CAP_TOUCH
- CapIOMediaController uint32 = C.V4L2_CAP_IO_MC
- CapDeviceCapabilities uint32 = C.V4L2_CAP_DEVICE_CAPS
- )
- type CapabilityDesc struct {
- Cap uint32
- Desc string
- }
- var (
- Capabilities = []CapabilityDesc{
- {Cap: CapVideoCapture, Desc: "video capture (single-planar)"},
- {Cap: CapVideoOutput, Desc: "video output (single-planar)"},
- {Cap: CapVideoOverlay, Desc: "video overlay"},
- {Cap: CapVBICapture, Desc: "raw VBI capture"},
- {Cap: CapVBIOutput, Desc: "raw VBI output"},
- {Cap: CapSlicedVBICapture, Desc: "sliced VBI capture"},
- {Cap: CapSlicedVBIOutput, Desc: "sliced VBI output"},
- {Cap: CapRDSCapture, Desc: "RDS capture"},
- {Cap: CapVideoOutputOverlay, Desc: "video output overlay"},
- {Cap: CapHWFrequencySeek, Desc: "hardware frequency seeking"},
- {Cap: CapRDSOutput, Desc: "RDS output"},
- {Cap: CapVideoCaptureMPlane, Desc: "video capture (multi-planar)"},
- {Cap: CapVideoOutputMPlane, Desc: "video output (multi-planar)"},
- {Cap: CapVideoMem2MemMPlane, Desc: "memory-to-memory video (multi-planar)"},
- {Cap: CapVideoMem2Mem, Desc: "memory-to-memory video (single-planar)"},
- {Cap: CapTuner, Desc: "video tuner"},
- {Cap: CapAudio, Desc: "audio inputs or outputs"},
- {Cap: CapRadio, Desc: "radio receiver"},
- {Cap: CapModulator, Desc: "radio frequency modulator"},
- {Cap: CapSDRCapture, Desc: "SDR capture"},
- {Cap: CapExtendedPixFormat, Desc: "extended pixel format"},
- {Cap: CapSDROutput, Desc: "SDR output"},
- {Cap: CapMetadataCapture, Desc: "metadata capture"},
- {Cap: CapReadWrite, Desc: "read/write IO"},
- {Cap: CapAsyncIO, Desc: "asynchronous IO"},
- {Cap: CapStreaming, Desc: "streaming IO"},
- {Cap: CapMetadataOutput, Desc: "metadata output"},
- {Cap: CapTouch, Desc: "touch capability"},
- {Cap: CapIOMediaController, Desc: "IO media controller"},
- {Cap: CapDeviceCapabilities, Desc: "device capabilities"},
- }
- )
- // Capability represents capabilities retrieved for the device (see v4l2_capability).
- // Use attached methods on this type to access capabilities.
- // https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L440
- // https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/vidioc-querycap.html#c.V4L.v4l2_capability
- type Capability struct {
- // Driver name of the driver module
- Driver string
- // Card name of the device card
- Card string
- // BusInfo is the name of the device bus
- BusInfo string
- // Version is the kernel version
- Version uint32
- // Capabilities returns all exported capabilities for the physical device (opened or not)
- Capabilities uint32
- // DeviceCapabilities is the capability for this particular (opened) device or node
- DeviceCapabilities uint32
- }
- // GetCapability retrieves capability info for device
- func GetCapability(fd uintptr) (Capability, error) {
- var v4l2Cap C.struct_v4l2_capability
- if err := send(fd, C.VIDIOC_QUERYCAP, uintptr(unsafe.Pointer(&v4l2Cap))); err != nil {
- return Capability{}, fmt.Errorf("capability: %w", err)
- }
- return Capability{
- Driver: C.GoString((*C.char)(unsafe.Pointer(&v4l2Cap.driver[0]))),
- Card: C.GoString((*C.char)(unsafe.Pointer(&v4l2Cap.card[0]))),
- BusInfo: C.GoString((*C.char)(unsafe.Pointer(&v4l2Cap.bus_info[0]))),
- Version: uint32(v4l2Cap.version),
- Capabilities: uint32(v4l2Cap.capabilities),
- DeviceCapabilities: uint32(v4l2Cap.device_caps),
- }, nil
- }
- // GetCapabilities returns device capabilities if supported
- func (c Capability) GetCapabilities() uint32 {
- if c.IsDeviceCapabilitiesProvided() {
- return c.DeviceCapabilities
- }
- return c.Capabilities
- }
- // IsVideoCaptureSupported returns caps & CapVideoCapture
- func (c Capability) IsVideoCaptureSupported() bool {
- return c.Capabilities&CapVideoCapture != 0
- }
- // IsVideoOutputSupported returns caps & CapVideoOutput
- func (c Capability) IsVideoOutputSupported() bool {
- return c.Capabilities&CapVideoOutput != 0
- }
- // IsVideoOverlaySupported returns caps & CapVideoOverlay
- func (c Capability) IsVideoOverlaySupported() bool {
- return c.Capabilities&CapVideoOverlay != 0
- }
- // IsVideoOutputOverlaySupported returns caps & CapVideoOutputOverlay
- func (c Capability) IsVideoOutputOverlaySupported() bool {
- return c.Capabilities&CapVideoOutputOverlay != 0
- }
- // IsVideoCaptureMultiplanarSupported returns caps & CapVideoCaptureMPlane
- func (c Capability) IsVideoCaptureMultiplanarSupported() bool {
- return c.Capabilities&CapVideoCaptureMPlane != 0
- }
- // IsVideoOutputMultiplanerSupported returns caps & CapVideoOutputMPlane
- func (c Capability) IsVideoOutputMultiplanerSupported() bool {
- return c.Capabilities&CapVideoOutputMPlane != 0
- }
- // IsReadWriteSupported returns caps & CapReadWrite
- func (c Capability) IsReadWriteSupported() bool {
- return c.Capabilities&CapReadWrite != 0
- }
- // IsStreamingSupported returns caps & CapStreaming
- func (c Capability) IsStreamingSupported() bool {
- return c.Capabilities&CapStreaming != 0
- }
- // IsDeviceCapabilitiesProvided returns true if the device returns
- // device-specific capabilities (via CapDeviceCapabilities)
- // See notes on VL42_CAP_DEVICE_CAPS:
- // https://linuxtv.org/downloads/v4l-dvb-apis/userspace-api/v4l/vidioc-querycap.html?highlight=v4l2_cap_device_caps
- func (c Capability) IsDeviceCapabilitiesProvided() bool {
- return c.Capabilities&CapDeviceCapabilities != 0
- }
- // GetDriverCapDescriptions return textual descriptions of driver capabilities
- func (c Capability) GetDriverCapDescriptions() []CapabilityDesc {
- var result []CapabilityDesc
- for _, cap := range Capabilities {
- if c.Capabilities&cap.Cap == cap.Cap {
- result = append(result, cap)
- }
- }
- return result
- }
- // GetDeviceCapDescriptions return textual descriptions of device capabilities
- func (c Capability) GetDeviceCapDescriptions() []CapabilityDesc {
- var result []CapabilityDesc
- for _, cap := range Capabilities {
- if c.DeviceCapabilities&cap.Cap == cap.Cap {
- result = append(result, cap)
- }
- }
- return result
- }
- func (c Capability) GetVersionInfo() VersionInfo {
- return VersionInfo{value: c.Version}
- }
- // String returns a string value representing driver information
- func (c Capability) String() string {
- return fmt.Sprintf("driver: %s; card: %s; bus info: %s", c.Driver, c.Card, c.BusInfo)
- }
|