|
@@ -1,7 +1,6 @@
|
|
package v4l2
|
|
package v4l2
|
|
|
|
|
|
import (
|
|
import (
|
|
- "errors"
|
|
|
|
"fmt"
|
|
"fmt"
|
|
"unsafe"
|
|
"unsafe"
|
|
)
|
|
)
|
|
@@ -35,6 +34,18 @@ func fourcc(a, b, c, d uint32) FourCCEncoding {
|
|
return (a | b<<8) | c<<16 | d<<24
|
|
return (a | b<<8) | c<<16 | d<<24
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// PixelFormats provides a map of FourCC encoding description
|
|
|
|
+var PixelFormats = map[FourCCEncoding]string{
|
|
|
|
+ PixFmtRGB24: "24-bit RGB 8-8-8",
|
|
|
|
+ PixFmtGrey: "8-bit Greyscale",
|
|
|
|
+ PixelFmtYUYV: "YUYV 4:2:2",
|
|
|
|
+ PixelFmtMJPEG: "Motion-JPEG",
|
|
|
|
+ PixelFmtJPEG: "JFIF JPEG",
|
|
|
|
+ PixelFmtMPEG: "MPEG-1/2/4",
|
|
|
|
+ PixelFmtH264: "H.264",
|
|
|
|
+ PixelFmtMPEG4: "MPEG-4 Part 2 ES",
|
|
|
|
+}
|
|
|
|
+
|
|
// YcbcrEncoding (v4l2_ycbcr_encoding)
|
|
// YcbcrEncoding (v4l2_ycbcr_encoding)
|
|
// https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-defs.html?highlight=v4l2_ycbcr_encoding
|
|
// https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-defs.html?highlight=v4l2_ycbcr_encoding
|
|
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L300
|
|
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L300
|
|
@@ -59,40 +70,98 @@ const (
|
|
QuantizationLimRange // V4L2_QUANTIZATION_LIM_RANGE
|
|
QuantizationLimRange // V4L2_QUANTIZATION_LIM_RANGE
|
|
)
|
|
)
|
|
|
|
|
|
-// XferFunction (v4l2_xfer_func)
|
|
|
|
|
|
+// XferFunctionType (v4l2_xfer_func)
|
|
// https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-defs.html?highlight=v4l2_xfer_func#c.V4L.v4l2_xfer_func
|
|
// https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-defs.html?highlight=v4l2_xfer_func#c.V4L.v4l2_xfer_func
|
|
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L259
|
|
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L259
|
|
-type XferFunction = uint32
|
|
|
|
|
|
+type XferFunctionType = uint32
|
|
|
|
|
|
const (
|
|
const (
|
|
- XferFuncDefault XferFunction = iota // V4L2_XFER_FUNC_DEFAULT = 0
|
|
|
|
- XferFunc709 // V4L2_XFER_FUNC_709 = 1,
|
|
|
|
- ferFuncSRGB // V4L2_XFER_FUNC_SRGB = 2,
|
|
|
|
- XferFuncOpRGB // V4L2_XFER_FUNC_OPRGB = 3,
|
|
|
|
- XferFuncSmpte240M // V4L2_XFER_FUNC_SMPTE240M = 4,
|
|
|
|
- XferFuncNone // V4L2_XFER_FUNC_NONE = 5,
|
|
|
|
- XferFuncDciP3 // V4L2_XFER_FUNC_DCI_P3 = 6,
|
|
|
|
- XferFuncSmpte2084 // V4L2_XFER_FUNC_SMPTE2084 = 7,
|
|
|
|
|
|
+ XferFuncDefault XferFunctionType = iota // V4L2_XFER_FUNC_DEFAULT = 0
|
|
|
|
+ XferFunc709 // V4L2_XFER_FUNC_709 = 1,
|
|
|
|
+ XferFuncSRGB // V4L2_XFER_FUNC_SRGB = 2,
|
|
|
|
+ XferFuncOpRGB // V4L2_XFER_FUNC_OPRGB = 3,
|
|
|
|
+ XferFuncSMPTE240M // V4L2_XFER_FUNC_SMPTE240M = 4,
|
|
|
|
+ XferFuncNone // V4L2_XFER_FUNC_NONE = 5,
|
|
|
|
+ XferFuncDCIP3 // V4L2_XFER_FUNC_DCI_P3 = 6,
|
|
|
|
+ XferFuncSMPTE2084 // V4L2_XFER_FUNC_SMPTE2084 = 7,
|
|
)
|
|
)
|
|
|
|
|
|
-// Field (v4l2_field)
|
|
|
|
|
|
+var XferFunctions = map[XferFunctionType]string{
|
|
|
|
+ XferFuncDefault: "Default",
|
|
|
|
+ XferFunc709: "Rec. 709",
|
|
|
|
+ XferFuncSRGB: "sRGB",
|
|
|
|
+ XferFuncOpRGB: "opRGB",
|
|
|
|
+ XferFuncSMPTE240M: "SMPTE 240M",
|
|
|
|
+ XferFuncNone: "None",
|
|
|
|
+ XferFuncDCIP3: "DCI-P3",
|
|
|
|
+ XferFuncSMPTE2084: "SMPTE 2084",
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// FieldType (v4l2_field)
|
|
// https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/field-order.html?highlight=v4l2_field#c.v4l2_field
|
|
// https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/field-order.html?highlight=v4l2_field#c.v4l2_field
|
|
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L88
|
|
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L88
|
|
-type Field = uint32
|
|
|
|
|
|
+type FieldType = uint32
|
|
|
|
+
|
|
|
|
+const (
|
|
|
|
+ FieldAny FieldType = iota // V4L2_FIELD_ANY
|
|
|
|
+ FieldNone // V4L2_FIELD_NONE
|
|
|
|
+ FieldTop // V4L2_FIELD_TOP
|
|
|
|
+ FieldBottom // V4L2_FIELD_BOTTOM
|
|
|
|
+ FieldInterlaced // V4L2_FIELD_INTERLACED
|
|
|
|
+ FieldSequentialTopBottom // V4L2_FIELD_SEQ_TB
|
|
|
|
+ FieldSequentialBottomTop // V4L2_FIELD_SEQ_BT
|
|
|
|
+ FieldAlternate // V4L2_FIELD_ALTERNATE
|
|
|
|
+ FieldInterlacedTopBottom // V4L2_FIELD_INTERLACED_TB
|
|
|
|
+ FieldInterlacedBottomTop // V4L2_FIELD_INTERLACED_BT
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+// Fields is a map of FieldType description
|
|
|
|
+var Fields = map[FieldType]string{
|
|
|
|
+ FieldAny: "any",
|
|
|
|
+ FieldNone: "none",
|
|
|
|
+ FieldTop: "top",
|
|
|
|
+ FieldBottom: "bottom",
|
|
|
|
+ FieldInterlaced: "interlaced",
|
|
|
|
+ FieldSequentialTopBottom: "sequential top-bottom",
|
|
|
|
+ FieldSequentialBottomTop: "Sequential botton-top",
|
|
|
|
+ FieldAlternate: "alternating",
|
|
|
|
+ FieldInterlacedTopBottom: "interlaced top-bottom",
|
|
|
|
+ FieldInterlacedBottomTop: "interlaced bottom-top",
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// ColorspaceType
|
|
|
|
+// See https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L195
|
|
|
|
+type ColorspaceType = uint32
|
|
|
|
|
|
const (
|
|
const (
|
|
- FieldAny Field = iota // V4L2_FIELD_ANY
|
|
|
|
- FieldNone // V4L2_FIELD_NONE
|
|
|
|
- FieldTop // V4L2_FIELD_TOP
|
|
|
|
- FieldBottom // V4L2_FIELD_BOTTOM
|
|
|
|
- FieldInterlaced // V4L2_FIELD_INTERLACED
|
|
|
|
- FieldSeqTb // V4L2_FIELD_SEQ_TB
|
|
|
|
- FieldSeqBt // V4L2_FIELD_SEQ_BT
|
|
|
|
- FieldAlternate // V4L2_FIELD_ALTERNATE
|
|
|
|
- FieldInterlacedTb // V4L2_FIELD_INTERLACED_TB
|
|
|
|
- FieldInterlacedBt // V4L2_FIELD_INTERLACED_BT
|
|
|
|
|
|
+ ColorspaceTypeDefault ColorspaceType = iota //V4L2_COLORSPACE_DEFAULT
|
|
|
|
+ ColorspaceSMPTE170M //V4L2_COLORSPACE_SMPTE170M
|
|
|
|
+ ColorspaceSMPTE240M // V4L2_COLORSPACE_SMPTE240M
|
|
|
|
+ ColorspaceREC709 // V4L2_COLORSPACE_REC709
|
|
|
|
+ ColorspaceBT878 // V4L2_COLORSPACE_BT878 (absolete)
|
|
|
|
+ Colorspace470SystemM // V4L2_COLORSPACE_470_SYSTEM_M (absolete)
|
|
|
|
+ Colorspace470SystemBG // V4L2_COLORSPACE_470_SYSTEM_BG
|
|
|
|
+ ColorspaceJPEG // V4L2_COLORSPACE_JPEG
|
|
|
|
+ ColorspaceSRGB // V4L2_COLORSPACE_SRGB
|
|
|
|
+ ColorspaceOPRGB // V4L2_COLORSPACE_OPRGB
|
|
|
|
+ ColorspaceBT2020 // V4L2_COLORSPACE_BT2020
|
|
|
|
+ ColorspaceRaw // V4L2_COLORSPACE_RAW
|
|
|
|
+ ColorspaceDCIP3 // V4L2_COLORSPACE_DCI_P3
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+// Colorspaces is a map of colorspace to its respective description
|
|
|
|
+var Colorspaces = map[ColorspaceType]string{
|
|
|
|
+ ColorspaceTypeDefault: "Default",
|
|
|
|
+ ColorspaceREC709: "Rec. 709",
|
|
|
|
+ Colorspace470SystemBG: "470 System BG",
|
|
|
|
+ ColorspaceJPEG: "JPEG",
|
|
|
|
+ ColorspaceSRGB: "sRGB",
|
|
|
|
+ ColorspaceOPRGB: "opRGB",
|
|
|
|
+ ColorspaceBT2020: "BT.2020",
|
|
|
|
+ ColorspaceRaw: "Raw",
|
|
|
|
+ ColorspaceDCIP3: "DCI-P3",
|
|
|
|
+}
|
|
|
|
+
|
|
// PixFormat (v4l2_pix_format)
|
|
// PixFormat (v4l2_pix_format)
|
|
// https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/pixfmt-002.html?highlight=v4l2_pix_format
|
|
// https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/pixfmt-002.html?highlight=v4l2_pix_format
|
|
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L496
|
|
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L496
|
|
@@ -100,15 +169,15 @@ type PixFormat struct {
|
|
Width uint32
|
|
Width uint32
|
|
Height uint32
|
|
Height uint32
|
|
PixelFormat FourCCEncoding
|
|
PixelFormat FourCCEncoding
|
|
- Field Field
|
|
|
|
|
|
+ Field FieldType
|
|
BytesPerLine uint32
|
|
BytesPerLine uint32
|
|
SizeImage uint32
|
|
SizeImage uint32
|
|
- Colorspace uint32
|
|
|
|
|
|
+ Colorspace ColorspaceType
|
|
Priv uint32
|
|
Priv uint32
|
|
Flags uint32
|
|
Flags uint32
|
|
YcbcrEnc YcbcrEncoding
|
|
YcbcrEnc YcbcrEncoding
|
|
Quantization Quantization
|
|
Quantization Quantization
|
|
- XferFunc XferFunction
|
|
|
|
|
|
+ XferFunc XferFunctionType
|
|
}
|
|
}
|
|
|
|
|
|
// v4l2Format (v4l2_format)
|
|
// v4l2Format (v4l2_format)
|
|
@@ -151,12 +220,7 @@ func (f v4l2Format) setPixFormat(newPix PixFormat) {
|
|
func GetPixFormat(fd uintptr) (PixFormat, error) {
|
|
func GetPixFormat(fd uintptr) (PixFormat, error) {
|
|
format := v4l2Format{StreamType: BufTypeVideoCapture}
|
|
format := v4l2Format{StreamType: BufTypeVideoCapture}
|
|
if err := Send(fd, VidiocGetFormat, uintptr(unsafe.Pointer(&format))); err != nil {
|
|
if err := Send(fd, VidiocGetFormat, uintptr(unsafe.Pointer(&format))); err != nil {
|
|
- switch {
|
|
|
|
- case errors.Is(err, ErrorUnsupported):
|
|
|
|
- return PixFormat{}, fmt.Errorf("pix format: unsupported: %w", err)
|
|
|
|
- default:
|
|
|
|
- return PixFormat{}, fmt.Errorf("pix format failed: %w", err)
|
|
|
|
- }
|
|
|
|
|
|
+ return PixFormat{}, fmt.Errorf("pix format failed: %w", err)
|
|
}
|
|
}
|
|
|
|
|
|
return format.getPixFormat(), nil
|
|
return format.getPixFormat(), nil
|
|
@@ -169,12 +233,7 @@ func SetPixFormat(fd uintptr, pixFmt PixFormat) error {
|
|
format.setPixFormat(pixFmt)
|
|
format.setPixFormat(pixFmt)
|
|
|
|
|
|
if err := Send(fd, VidiocSetFormat, uintptr(unsafe.Pointer(&format))); err != nil {
|
|
if err := Send(fd, VidiocSetFormat, uintptr(unsafe.Pointer(&format))); err != nil {
|
|
- switch {
|
|
|
|
- case errors.Is(err, ErrorUnsupported):
|
|
|
|
- return fmt.Errorf("pix format: unsupported operation: %w", err)
|
|
|
|
- default:
|
|
|
|
- return fmt.Errorf("pix format failed: %w", err)
|
|
|
|
- }
|
|
|
|
|
|
+ return fmt.Errorf("pix format failed: %w", err)
|
|
}
|
|
}
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|