From e9ad39d87c837d0e7a8646b19f4971cc79ee15dc Mon Sep 17 00:00:00 2001 From: Eric Daniels Date: Sun, 5 Nov 2023 17:42:46 -0500 Subject: [PATCH] use poll instead of select in waitForFrame to allow for large fds Fixes #65 --- .gitignore | 1 + go.mod | 5 +++++ go.sum | 2 ++ v4l2.go | 14 ++------------ webcam.go | 4 +++- 5 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 .gitignore create mode 100644 go.mod create mode 100644 go.sum diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..72cb8e7 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/blackjack/webcam + +go 1.18 + +require golang.org/x/sys v0.14.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..5867dc0 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/v4l2.go b/v4l2.go index 7e538fe..79dc65d 100644 --- a/v4l2.go +++ b/v4l2.go @@ -557,19 +557,9 @@ func stopStreaming(fd uintptr) (err error) { } -func waitForFrame(fd uintptr, timeout uint32) (count int, err error) { - +func waitForFrame(pollFds []unix.PollFd, timeout uint32) (count int, err error) { for { - fds := &unix.FdSet{} - fds.Set(int(fd)) - - var oneSecInNsec int64 = 1e9 - timeoutNsec := int64(timeout) * oneSecInNsec - nativeTimeVal := unix.NsecToTimeval(timeoutNsec) - tv := &nativeTimeVal - - count, err = unix.Select(int(fd+1), fds, nil, nil, tv) - + count, err = unix.Poll(pollFds, int(timeout*1000)) if count < 0 && err == unix.EINTR { continue } diff --git a/webcam.go b/webcam.go index dcb5ca5..cc3adfa 100644 --- a/webcam.go +++ b/webcam.go @@ -17,6 +17,7 @@ type Webcam struct { bufcount uint32 buffers [][]byte streaming bool + pollFds []unix.PollFd } type ControlID uint32 @@ -58,6 +59,7 @@ func Open(path string) (*Webcam, error) { w := new(Webcam) w.fd = fd w.bufcount = 256 + w.pollFds = []unix.PollFd{{Fd: int32(fd), Events: unix.POLLIN}} return w, nil } @@ -294,7 +296,7 @@ func (w *Webcam) ReleaseFrame(index uint32) error { // Wait until frame could be read func (w *Webcam) WaitForFrame(timeout uint32) error { - count, err := waitForFrame(w.fd, timeout) + count, err := waitForFrame(w.pollFds, timeout) if count < 0 || err != nil { return err