Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions vidnumerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ const (
(0 << IOCNrShift) |
(unsafe.Sizeof(cap{}) << IOCSizeShift)

V4L2CapVideoCapture uint32 = 0x00000001
V4L2CapStreaming uint32 = 0x04000000
V4L2CapDeviceCaps uint32 = 0x80000000
V4L2CapVideoCapture uint32 = 0x00000001
V4L2CapVideoCaptureMPlane uint32 = 0x00001000
V4L2CapStreaming uint32 = 0x04000000
V4L2CapDeviceCaps uint32 = 0x80000000
)

type cap struct {
Expand Down Expand Up @@ -70,7 +71,8 @@ func (r cap) videoCaptureCaps() uint32 {

func (r cap) isVideoCapture() bool {
caps := r.videoCaptureCaps()
return caps&V4L2CapVideoCapture != 0 && caps&V4L2CapStreaming != 0
isCapture := caps&(V4L2CapVideoCapture|V4L2CapVideoCaptureMPlane) != 0
return isCapture && caps&V4L2CapStreaming != 0
}

// IsVideoCapture checks the ioctl for VIDIOC_QUERYCAP to see if the device is a video capture device.
Expand Down
56 changes: 30 additions & 26 deletions vidnumerator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,44 +92,48 @@ func TestCapVideoCaptureCapsFallsBackToCapabilities(t *testing.T) {
}
}

func TestCapIsVideoCaptureAcceptsAdditionalFlags(t *testing.T) {
ic := cap{
capabilities: V4L2CapDeviceCaps,
deviceCaps: V4L2CapVideoCapture |
V4L2CapStreaming |
0x00000002,
}

if !ic.isVideoCapture() {
t.Fatal("expected device with capture and streaming flags to be detected")
}
}

func TestCapIsVideoCaptureRequiresCaptureAndStreaming(t *testing.T) {
func TestCapIsVideoCapture(t *testing.T) {
tests := []struct {
name string
ic cap
caps uint32
want bool
}{
{
name: "missing capture",
ic: cap{
capabilities: V4L2CapDeviceCaps,
deviceCaps: V4L2CapStreaming,
},
name: "single-planar capture with streaming",
caps: V4L2CapVideoCapture | V4L2CapStreaming,
want: true,
},
{
name: "multi-planar capture with streaming",
caps: V4L2CapVideoCaptureMPlane | V4L2CapStreaming,
want: true,
},
{
name: "capture with additional flags",
caps: V4L2CapVideoCapture | V4L2CapStreaming | 0x00000002,
want: true,
},
{
name: "missing streaming",
ic: cap{
capabilities: V4L2CapDeviceCaps,
deviceCaps: V4L2CapVideoCapture,
},
caps: V4L2CapVideoCapture,
want: false,
},
{
name: "missing capture",
caps: V4L2CapStreaming,
want: false,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.ic.isVideoCapture() {
t.Fatal("expected non-capture device")
ic := cap{
capabilities: V4L2CapDeviceCaps,
deviceCaps: test.caps,
}

if got := ic.isVideoCapture(); got != test.want {
t.Fatalf("isVideoCapture() = %v, want %v", got, test.want)
}
})
}
Expand Down
Loading