added controls
This commit is contained in:
parent
9ef7d28c46
commit
45063b7d97
3 changed files with 167 additions and 3 deletions
132
webcam.go
132
webcam.go
|
|
@ -151,6 +151,30 @@ type frmsizeenum struct {
|
|||
reserved [2]uint32
|
||||
}
|
||||
|
||||
type queryctrl struct {
|
||||
id uint32
|
||||
_type uint32
|
||||
name [32]uint8
|
||||
minimum int32
|
||||
maximum int32
|
||||
step int32
|
||||
default_value int32
|
||||
flags uint32
|
||||
reserved [2]uint32
|
||||
}
|
||||
|
||||
type querymenu struct {
|
||||
id uint32
|
||||
index uint32
|
||||
name [32]uint8
|
||||
reserved uint32
|
||||
}
|
||||
|
||||
type control struct {
|
||||
id uint32
|
||||
value int32
|
||||
}
|
||||
|
||||
const (
|
||||
_IOC_READ = 2
|
||||
_IOC_WRITE = 1
|
||||
|
|
@ -173,6 +197,55 @@ const (
|
|||
_V4L2_FRMSIZE_TYPE_DISCRETE = 1
|
||||
_V4L2_FRMSIZE_TYPE_CONTINUOUS = 2
|
||||
_V4L2_FRMSIZE_TYPE_STEPWISE = 3
|
||||
|
||||
_V4L2_CTRL_FLAG_NEXT_CTRL = 0x80000000
|
||||
_V4L2_CTRL_FLAG_DISABLED = 0x0001
|
||||
_V4L2_CTRL_TYPE_MENU = 3
|
||||
_V4L2_CTRL_CLASS_USER = 0x00980000
|
||||
_V4L2_CID_BASE = _V4L2_CTRL_CLASS_USER | 0x900
|
||||
_V4L2_CID_USER_BASE = _V4L2_CID_BASE
|
||||
_V4L2_CID_USER_CLASS = _V4L2_CTRL_CLASS_USER | 1
|
||||
|
||||
// Controls
|
||||
V4L2_CID_BRIGHTNESS = _V4L2_CID_BASE + 0
|
||||
V4L2_CID_CONTRAST = _V4L2_CID_BASE + 1
|
||||
V4L2_CID_SATURATION = _V4L2_CID_BASE + 2
|
||||
V4L2_CID_HUE = _V4L2_CID_BASE + 3
|
||||
V4L2_CID_AUDIO_VOLUME = _V4L2_CID_BASE + 5
|
||||
V4L2_CID_AUDIO_BALANCE = _V4L2_CID_BASE + 6
|
||||
V4L2_CID_AUDIO_BASS = _V4L2_CID_BASE + 7
|
||||
V4L2_CID_AUDIO_TREBLE = _V4L2_CID_BASE + 8
|
||||
V4L2_CID_AUDIO_MUTE = _V4L2_CID_BASE + 9
|
||||
V4L2_CID_AUDIO_LOUDNESS = _V4L2_CID_BASE + 10
|
||||
V4L2_CID_AUTO_WHITE_BALANCE = _V4L2_CID_BASE + 12
|
||||
V4L2_CID_DO_WHITE_BALANCE = _V4L2_CID_BASE + 13
|
||||
V4L2_CID_RED_BALANCE = _V4L2_CID_BASE + 14
|
||||
V4L2_CID_BLUE_BALANCE = _V4L2_CID_BASE + 15
|
||||
V4L2_CID_GAMMA = _V4L2_CID_BASE + 16
|
||||
V4L2_CID_EXPOSURE = _V4L2_CID_BASE + 17
|
||||
V4L2_CID_AUTOGAIN = _V4L2_CID_BASE + 18
|
||||
V4L2_CID_GAIN = _V4L2_CID_BASE + 19
|
||||
V4L2_CID_HFLIP = _V4L2_CID_BASE + 20
|
||||
V4L2_CID_VFLIP = _V4L2_CID_BASE + 21
|
||||
V4L2_CID_POWER_LINE_FREQUENCY = _V4L2_CID_BASE + 24
|
||||
V4L2_CID_HUE_AUTO = _V4L2_CID_BASE + 25
|
||||
V4L2_CID_WHITE_BALANCE_TEMPERATURE = _V4L2_CID_BASE + 26
|
||||
V4L2_CID_SHARPNESS = _V4L2_CID_BASE + 27
|
||||
V4L2_CID_BACKLIGHT_COMPENSATION = _V4L2_CID_BASE + 28
|
||||
V4L2_CID_CHROMA_AGC = _V4L2_CID_BASE + 29
|
||||
V4L2_CID_COLOR_KILLER = _V4L2_CID_BASE + 30
|
||||
V4L2_CID_COLORFX = _V4L2_CID_BASE + 31
|
||||
V4L2_CID_AUTOBRIGHTNESS = _V4L2_CID_BASE + 32
|
||||
V4L2_CID_BAND_STOP_FILTER = _V4L2_CID_BASE + 33
|
||||
V4L2_CID_ROTATE = _V4L2_CID_BASE + 34
|
||||
V4L2_CID_BG_COLOR = _V4L2_CID_BASE + 35
|
||||
V4L2_CID_CHROMA_GAIN = _V4L2_CID_BASE + 36
|
||||
V4L2_CID_ILLUMINATORS_1 = _V4L2_CID_BASE + 37
|
||||
V4L2_CID_ILLUMINATORS_2 = _V4L2_CID_BASE + 38
|
||||
V4L2_CID_MIN_BUFFERS_FOR_CAPTURE = _V4L2_CID_BASE + 39
|
||||
V4L2_CID_MIN_BUFFERS_FOR_OUTPUT = _V4L2_CID_BASE + 40
|
||||
V4L2_CID_ALPHA_COMPONENT = _V4L2_CID_BASE + 41
|
||||
V4L2_CID_COLORFX_CBCR = _V4L2_CID_BASE + 42
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -185,6 +258,10 @@ var (
|
|||
_VIDIOC_DQBUF = _IOWR('V', 17, unsafe.Sizeof(buffer{}))
|
||||
_VIDIOC_STREAMON = _IOW('V', 18, unsafe.Sizeof(int32(0)))
|
||||
_VIDIOC_ENUM_FRAMESIZES = _IOWR('V', 74, unsafe.Sizeof(frmsizeenum{}))
|
||||
_VIDIOC_QUERYCTRL = _IOWR('V', 36, unsafe.Sizeof(queryctrl{}))
|
||||
_VIDIOC_QUERYMENU = _IOWR('V', 37, unsafe.Sizeof(querymenu{}))
|
||||
_VIDIOC_G_CTRL = _IOWR('V', 27, unsafe.Sizeof(control{}))
|
||||
_VIDIOC_S_CTRL = _IOWR('V', 28, unsafe.Sizeof(control{}))
|
||||
)
|
||||
|
||||
func _IOC(dir, t, nr, size uintptr) uintptr {
|
||||
|
|
@ -214,6 +291,17 @@ func ioctl(fd, cmd, ptr uintptr) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func u2s(a [32]uint8) string {
|
||||
buf := make([]byte, 32)
|
||||
for i, u := range a {
|
||||
if u == 0 {
|
||||
break
|
||||
}
|
||||
buf[i] = byte(u)
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
func (w *Webcam) checkCapabilities() (video, stream bool, err error) {
|
||||
c := new(capability)
|
||||
err = ioctl(w.fd, _VIDIOC_QUERYCAP, uintptr(unsafe.Pointer(c)))
|
||||
|
|
@ -222,6 +310,50 @@ func (w *Webcam) checkCapabilities() (video, stream bool, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (w *Webcam) enumMenu(id uint32, min, max int32) (items []string) {
|
||||
var qm querymenu
|
||||
qm.id = id
|
||||
for qm.index = uint32(min); qm.index <= uint32(max); qm.index++ {
|
||||
if ioctl(w.fd, _VIDIOC_QUERYMENU, uintptr(unsafe.Pointer(&qm))) == nil {
|
||||
items = append(items, u2s(qm.name))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *Webcam) GetControls() (m map[string][]string) {
|
||||
m = make(map[string][]string)
|
||||
var qc queryctrl
|
||||
qc.id = _V4L2_CTRL_FLAG_NEXT_CTRL
|
||||
for ioctl(w.fd, _VIDIOC_QUERYCTRL, uintptr(unsafe.Pointer(&qc))) == nil {
|
||||
if (qc.flags & _V4L2_CTRL_FLAG_DISABLED) == 0 {
|
||||
items := []string{}
|
||||
if qc._type == _V4L2_CTRL_TYPE_MENU {
|
||||
items = w.enumMenu(qc.id, qc.minimum, qc.maximum)
|
||||
}
|
||||
m[u2s(qc.name)] = items
|
||||
}
|
||||
qc.id |= _V4L2_CTRL_FLAG_NEXT_CTRL
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *Webcam) SetControl(ctrl uint32, value int32) error {
|
||||
var qc queryctrl
|
||||
qc.id = ctrl
|
||||
err := ioctl(w.fd, _VIDIOC_QUERYCTRL, uintptr(unsafe.Pointer(&qc)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (qc.flags & _V4L2_CTRL_FLAG_DISABLED) != 0 {
|
||||
return errors.New("unsupported")
|
||||
}
|
||||
var c control
|
||||
c.id = ctrl
|
||||
c.value = value
|
||||
return ioctl(w.fd, _VIDIOC_S_CTRL, uintptr(unsafe.Pointer(&c)))
|
||||
|
||||
}
|
||||
func (w *Webcam) GetPixelFormats() (m map[uint32]string) {
|
||||
m = make(map[uint32]string)
|
||||
for i := uint32(0); ; i++ {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue