-
Notifications
You must be signed in to change notification settings - Fork 9
/
doc.go
135 lines (101 loc) · 3.27 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
Package v4l2 exposes the V4L2 (Video4Linux version 2) API to Golang.
Example:
device, err := v4l2.Open(v4l2.Video0)
if nil != err {
//@TODO
return err
}
defer device.Close()
fmt.Printf("Driver: %q\n", device.MustDriver())
fmt.Printf("Card: %q\n", device.MustCard())
fmt.Printf("BusInfo: %q\n", device.MustBusInfo())
fmt.Printf("Version: %q\n", device.MustVersion())
fmt.Println()
fmt.Printf("Has Video Capture: %v\n", device.MustHasCapability(v4l2.CapabilityVideoCapture))
fmt.Printf("Has Streaming I/O: %v\n", device.MustHasCapability(v4l2.CapabilityStreaming))
That example opens up the V4L2 device at "/dev/video0" on the file system, and displays some basic information about the device.
(Of course, we could have opened one of the other V4L2 devices. Such as: v4l2.Video1, v4l2.Video2, ..., or v4l2.Video63.)
Continuing this same example:
formatFamilies, err := device.FormatFamilies()
if nil != err {
return err
}
defer formatFamilies.Close()
var formatFamily v4l2.FormatFamily
for formatFamilies.Next() {
if err := formatFamilies.Decode(&formatFamily); nil != err {
return err
}
fmt.Printf("[format] %q (%q) {compressed=%t} {emulated=%t} \n",
formatFamily.Description(),
formatFamily.PixelFormat(),
formatFamily.HasFlags(v4l2.FormatFamilyFlagCompressed),
formatFamily.HasFlags(v4l2.FormatFamilyFlagEmulated),
)
//@TODO
}
if err := formatFamilies.Err(); nil != err {
return err
}
Here we have iterating through the formats that are supported for this device.
Extending that last code block, to fill in that "//@TODO", we can iterate through the frame sizes, for each format, we the following:
frameSizes, err := formatFamily.FrameSizes()
if nil != err {
return return
}
defer frameSizes.Close()
var frameSize v4l2.FrameSize
for frameSizes.Next() {
if err := frameSizes.Decode(&frameSize); nil != err {
return err
}
casted, err := frameSize.Cast()
if nil != err {
return err
}
switch t := casted.(type) {
case v4l2.FrameSizeDiscrete:
fmt.Printf("\t [frame size discrete] pixel_format=%q, width=%d, height=%d \n",
t.PixelFormat,
t.Width,
t.Height,
)
case v4l2.FrameSizeContinuous:
fmt.Printf("\t [frame size continuous] pixel_format=%q, min_width=%d, max_width=%d, min_height=%d, max_height=% \n",
t.PixelFormat,
t.MinWidth,
t.MaxWidth,
t.MinHeight,
t.MaxHeight,
)
case v4l2.FrameSizeStepwise:
fmt.Printf("\t [frame size stepwise] pixel_format=%q, min_width=%d, max_width=%d, min_height=%d, max_height=% \n",
t.PixelFormat,
t.MinWidth,
t.MaxWidth,
t.MinHeight,
t.MaxHeight,
)
default:
return err
}
}
if err := frameSizes.Err(); nil != err {
return err
}
Device Paths
One thing to be cognisant of, is that on Linux systems, V4L2 (Video4Linux version 2) will create a (special) file in the
/dev/ directory for every V4L2 device.
These devices will name path names such as:
• /dev/video0
• /dev/video1
• /dev/video2
…
• /dev/video63
You would call Open using these names directly. For example:
device, err := v4l2.Open("/dev/video3")
However, this package also provides constants that can be used. For example:
device, err := v4l2.Open(v4l2.Video3)
*/
package v4l2