video_info.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package v4l2
  2. // #include <linux/videodev2.h>
  3. import "C"
  4. import (
  5. "fmt"
  6. "unsafe"
  7. sys "golang.org/x/sys/unix"
  8. )
  9. // InputStatus
  10. // See https://linuxtv.org/downloads/v4l-dvb-apis/userspace-api/v4l/vidioc-enuminput.html?highlight=v4l2_input#input-status
  11. type InputStatus = uint32
  12. var (
  13. InputStatusNoPower InputStatus = C.V4L2_IN_ST_NO_POWER
  14. InputStatusNoSignal InputStatus = C.V4L2_IN_ST_NO_SIGNAL
  15. InputStatusNoColor InputStatus = C.V4L2_IN_ST_NO_COLOR
  16. )
  17. var InputStatuses = map[InputStatus]string{
  18. 0: "ok",
  19. InputStatusNoPower: "no power",
  20. InputStatusNoSignal: "no signal",
  21. InputStatusNoColor: "no color",
  22. }
  23. type InputType = uint32
  24. const (
  25. InputTypeTuner InputType = iota + 1
  26. InputTypeCamera
  27. InputTypeTouch
  28. )
  29. type StandardId = uint64
  30. // InputInfo (v4l2_input)
  31. // https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/videodev2.h#L1649
  32. // https://linuxtv.org/downloads/v4l-dvb-apis/userspace-api/v4l/vidioc-enuminput.html
  33. type InputInfo struct {
  34. v4l2Input C.struct_v4l2_input
  35. }
  36. func (i InputInfo) GetIndex() uint32 {
  37. return uint32(i.v4l2Input.index)
  38. }
  39. func (i InputInfo) GetName() string {
  40. return C.GoString((*C.char)(unsafe.Pointer(&i.v4l2Input.name[0])))
  41. }
  42. func (i InputInfo) GetInputType() InputType {
  43. return InputType(i.v4l2Input._type)
  44. }
  45. func (i InputInfo) GetAudioset() uint32 {
  46. return uint32(i.v4l2Input.audioset)
  47. }
  48. func (i InputInfo) GetTuner() uint32 {
  49. return uint32(i.v4l2Input.tuner)
  50. }
  51. func (i InputInfo) GetStandardId() StandardId {
  52. return StandardId(i.v4l2Input.std)
  53. }
  54. func (i InputInfo) GetStatus() uint32 {
  55. return uint32(i.v4l2Input.status)
  56. }
  57. func (i InputInfo) GetCapabilities() uint32 {
  58. return uint32(i.v4l2Input.capabilities)
  59. }
  60. // GetCurrentVideoInputIndex returns the currently selected video input index
  61. // See https://linuxtv.org/downloads/v4l-dvb-apis/userspace-api/v4l/vidioc-g-input.html
  62. func GetCurrentVideoInputIndex(fd uintptr) (int32, error) {
  63. var index int32
  64. if err := send(fd, C.VIDIOC_G_INPUT, uintptr(unsafe.Pointer(&index))); err != nil {
  65. return -1, fmt.Errorf("video input get: %w", err)
  66. }
  67. return index, nil
  68. }
  69. // GetVideoInputInfo returns specified input information for video device
  70. // See https://linuxtv.org/downloads/v4l-dvb-apis/userspace-api/v4l/vidioc-enuminput.html
  71. func GetVideoInputInfo(fd uintptr, index uint32) (InputInfo, error) {
  72. var input C.struct_v4l2_input
  73. input.index = C.uint(index)
  74. if err := send(fd, C.VIDIOC_ENUMINPUT, uintptr(unsafe.Pointer(&input))); err != nil {
  75. return InputInfo{}, fmt.Errorf("video input info: index %d: %w", index, err)
  76. }
  77. return InputInfo{v4l2Input: input}, nil
  78. }
  79. // GetAllVideoInputInfo returns all input information for device by
  80. // iterating from input index = 0 until an error (EINVL) is returned.
  81. func GetAllVideoInputInfo(fd uintptr) (result []InputInfo, err error) {
  82. index := uint32(0)
  83. for {
  84. var input C.struct_v4l2_input
  85. input.index = C.uint(index)
  86. if err = send(fd, C.VIDIOC_ENUMINPUT, uintptr(unsafe.Pointer(&input))); err != nil {
  87. errno := err.(sys.Errno)
  88. if errno.Is(sys.EINVAL) && len(result) > 0 {
  89. break
  90. }
  91. return result, fmt.Errorf("all video info: %w", err)
  92. }
  93. result = append(result, InputInfo{v4l2Input: input})
  94. index++
  95. }
  96. return result, err
  97. }