Skip to content

Commit

Permalink
do not change other classes
Browse files Browse the repository at this point in the history
  • Loading branch information
bazile-clyde committed Apr 21, 2023
1 parent f0f6be7 commit c3711a1
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 5 deletions.
10 changes: 10 additions & 0 deletions examples/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/blackjack/webcam v0.0.0-20220329180758-ba064708e165 h1:QsIbRyO2tn5eSJZ/skuDqSTo0GWI5H4G1AT7Mm2H0Nw=
github.com/blackjack/webcam v0.0.0-20220329180758-ba064708e165/go.mod h1:G0X+rEqYPWSq0dG8OMf8M446MtKytzpPjgS3HbdOJZ4=
github.com/blackjack/webcam v0.0.0-20230411204030-32744c21431f h1:qBxp6Oz8y0AfeqjrYcHaYdfWQf+vUXAwgZ+GWnTtd/E=
github.com/blackjack/webcam v0.0.0-20230411204030-32744c21431f/go.mod h1:G0X+rEqYPWSq0dG8OMf8M446MtKytzpPjgS3HbdOJZ4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -111,8 +113,11 @@ golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw=
golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand All @@ -130,6 +135,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -152,6 +158,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20191110171634-ad39bd3f0407/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand All @@ -165,10 +173,12 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
25 changes: 25 additions & 0 deletions pkg/driver/availability/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package availability

import (
"errors"
)

type Error interface {
Error() string
}

var ErrUnimplemented Error = errors.New("not implemented")
var ErrBusy Error = errors.New("device or resource busy")
var ErrNoDevice Error = errors.New("no such device")

type errorString struct {
s string
}

func NewError(text string) Error {
return &errorString{text}
}

func (e *errorString) Error() string {
return e.s
}
35 changes: 35 additions & 0 deletions pkg/driver/camera/camera_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import "C"
import (
"context"
"errors"
"github.com/pion/mediadevices/pkg/driver/availability"
"image"
"io"
"os"
"path/filepath"
"strconv"
"sync"
"syscall"
"time"

"github.com/blackjack/webcam"
Expand Down Expand Up @@ -350,3 +352,36 @@ func (c *camera) Properties() []prop.Media {
}
return properties
}

func (c *camera) IsAvailable() (bool, availability.Error) {
var err error

// close the opened file descriptor as quickly as possible and in all cases, including panics
func() {
var cam *webcam.Webcam
if cam, err = webcam.Open(c.path); err == nil {
defer cam.Close()
var index int32
// "Drivers must implement all the input ioctls when the device has one or more inputs..."
// Source: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/video.html?highlight=vidioc_enuminput
if index, err = cam.GetInput(); err == nil {
err = cam.SelectInput(uint32(index))
}
}
}()

var errno syscall.Errno
errors.As(err, &errno)

// See https://man7.org/linux/man-pages/man3/errno.3.html
switch {
case err == nil:
return true, nil
case errno == syscall.EBUSY:
return false, availability.ErrBusy
case errno == syscall.ENODEV || errno == syscall.ENOENT:
return false, availability.ErrNoDevice
default:
return false, availability.NewError(errno.Error())
}
}
12 changes: 12 additions & 0 deletions pkg/driver/driver.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package driver

import (
"github.com/pion/mediadevices/pkg/driver/availability"
"github.com/pion/mediadevices/pkg/io/audio"
"github.com/pion/mediadevices/pkg/io/video"
"github.com/pion/mediadevices/pkg/prop"
Expand Down Expand Up @@ -45,3 +46,14 @@ type Driver interface {
Info() Info
Status() State
}

type AvailabilityAdapter interface {
IsAvailable() (bool, availability.Error)
}

func IsAvailable(d Driver) (bool, availability.Error) {
if aa, ok := d.(AvailabilityAdapter); ok {
return aa.IsAvailable()
}
return false, availability.ErrUnimplemented
}
25 changes: 20 additions & 5 deletions pkg/driver/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package driver

import (
"github.com/google/uuid"
"github.com/pion/mediadevices/pkg/driver/availability"
"github.com/pion/mediadevices/pkg/io/audio"
"github.com/pion/mediadevices/pkg/io/video"
"github.com/pion/mediadevices/pkg/prop"
Expand All @@ -21,22 +22,28 @@ func wrapAdapter(a Adapter, info Info) Driver {
state: StateClosed,
}

if aa, ok := a.(AvailabilityAdapter); ok {
d.isAvailable = aa.IsAvailable
}

switch v := a.(type) {
case VideoRecorder:
// Only expose Driver and VideoRecorder interfaces
d.VideoRecorder = v
r := &struct {
Driver
VideoRecorder
}{d, d}
AvailabilityAdapter
}{d, d, d}
return r
case AudioRecorder:
// Only expose Driver and AudioRecorder interfaces
d.AudioRecorder = v
return &struct {
Driver
AudioRecorder
}{d, d}
AvailabilityAdapter
}{d, d, d}
default:
panic("adapter has to be either VideoRecorder/AudioRecorder")
}
Expand All @@ -46,9 +53,10 @@ type adapterWrapper struct {
Adapter
VideoRecorder
AudioRecorder
id string
info Info
state State
id string
info Info
state State
isAvailable func() (bool, availability.Error)
}

func (w *adapterWrapper) ID() string {
Expand Down Expand Up @@ -104,3 +112,10 @@ func (w *adapterWrapper) AudioRecord(p prop.Media) (r audio.Reader, err error) {
}
return
}

func (w *adapterWrapper) IsAvailable() (bool, availability.Error) {
if w.isAvailable == nil {
return false, availability.ErrUnimplemented
}
return w.isAvailable()
}
40 changes: 40 additions & 0 deletions pkg/driver/wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package driver

import (
"fmt"
"github.com/pion/mediadevices/pkg/driver/availability"
"testing"

"github.com/pion/mediadevices/pkg/io/audio"
Expand Down Expand Up @@ -39,6 +40,10 @@ func (a *audioAdapterBrokenMock) AudioRecord(p prop.Media) (r audio.Reader, err
return nil, recordErr
}

type availabilityAdapterMock struct{ videoAdapterMock }

func (a *availabilityAdapterMock) IsAvailable() (bool, availability.Error) { return true, nil }

func TestVideoWrapperState(t *testing.T) {
var a videoAdapterMock
d := wrapAdapter(&a, Info{})
Expand Down Expand Up @@ -136,3 +141,38 @@ func TestAudioWrapperWithBrokenRecorderState(t *testing.T) {
t.Errorf("expected the status to be %v, but got %v", StateClosed, d.Status())
}
}

func TestWrapperAvailabilityAdapter(t *testing.T) {
var aa availabilityAdapterMock
d := wrapAdapter(&aa, Info{})

ok, err := IsAvailable(d)
if err != nil {
t.Errorf("expected nil, but got %v", err)
}
if !ok {
t.Errorf("expected true, but got %v", ok)
}

var v videoAdapterMock
d = wrapAdapter(&v, Info{})

ok, err = IsAvailable(d)
if err == nil {
t.Errorf("expected err, but got %v", err)
}
if ok {
t.Errorf("expected false, but got %v", ok)
}

var a audioAdapterMock
d = wrapAdapter(&a, Info{})

ok, err = IsAvailable(d)
if err == nil {
t.Errorf("expected err, but got %v", err)
}
if ok {
t.Errorf("expected false, but got %v", ok)
}
}

0 comments on commit c3711a1

Please sign in to comment.