|
@@ -16,9 +16,15 @@ import (
|
|
|
"github.com/vladimirvivien/go4vl/v4l2"
|
|
|
)
|
|
|
|
|
|
+// The capture resolution to open video device
|
|
|
+type CaptureResolution struct {
|
|
|
+ Width int
|
|
|
+ Height int
|
|
|
+ FPS int
|
|
|
+}
|
|
|
+
|
|
|
type Config struct {
|
|
|
DeviceName string
|
|
|
- Resolution *SizeInfo //The prefered resolution to start the video stream
|
|
|
}
|
|
|
|
|
|
type Instance struct {
|
|
@@ -26,6 +32,7 @@ type Instance struct {
|
|
|
SupportedResolutions []FormatInfo //The supported resolutions of the video device
|
|
|
Capturing bool
|
|
|
camera *device.Device
|
|
|
+ cameraStartContext context.CancelFunc
|
|
|
frames_buff <-chan []byte
|
|
|
pixfmt v4l2.FourCCType
|
|
|
width int
|
|
@@ -105,7 +112,7 @@ func (i *Instance) ServeVideoStream(w http.ResponseWriter, req *http.Request) {
|
|
|
}
|
|
|
|
|
|
// start video capture
|
|
|
-func (i *Instance) StartVideoCapture(selectedFPS int) error {
|
|
|
+func (i *Instance) StartVideoCapture(openWithResolution *CaptureResolution) error {
|
|
|
if i.Capturing {
|
|
|
return fmt.Errorf("video capture already started")
|
|
|
}
|
|
@@ -115,26 +122,10 @@ func (i *Instance) StartVideoCapture(selectedFPS int) error {
|
|
|
buffSize := 8
|
|
|
format := "mjpeg"
|
|
|
|
|
|
- if i.Config.Resolution == nil {
|
|
|
+ if openWithResolution == nil {
|
|
|
return fmt.Errorf("resolution not provided")
|
|
|
}
|
|
|
|
|
|
- //Check if the selected FPS is valid in the provided Resolutions
|
|
|
- if i.Config.Resolution != nil {
|
|
|
- for _, size := range i.Config.Resolution.FPS {
|
|
|
- if size == selectedFPS {
|
|
|
- frameRate = size
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if frameRate != selectedFPS {
|
|
|
- log.Printf("selected FPS %d is not supported, using default %d", selectedFPS, frameRate)
|
|
|
- }
|
|
|
- } else {
|
|
|
- log.Printf("no resolution provided, using default %d", frameRate)
|
|
|
- }
|
|
|
-
|
|
|
//Check if the video device is a capture device
|
|
|
isCaptureDev, err := checkVideoCaptureDevice(devName)
|
|
|
if err != nil {
|
|
@@ -144,13 +135,23 @@ func (i *Instance) StartVideoCapture(selectedFPS int) error {
|
|
|
return fmt.Errorf("device %s is not a video capture device", devName)
|
|
|
}
|
|
|
|
|
|
+ //Check if the selected FPS is valid in the provided Resolutions
|
|
|
+ resolutionIsSupported, err := deviceSupportResolution(i.Config.DeviceName, openWithResolution)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ if !resolutionIsSupported {
|
|
|
+ return errors.New("this device do not support the required resolution settings")
|
|
|
+ }
|
|
|
+
|
|
|
//Open the video device
|
|
|
camera, err := device.Open(devName,
|
|
|
device.WithIOType(v4l2.IOTypeMMAP),
|
|
|
device.WithPixFormat(v4l2.PixFormat{
|
|
|
PixelFormat: getFormatType(format),
|
|
|
- Width: uint32(i.Config.Resolution.Width),
|
|
|
- Height: uint32(i.Config.Resolution.Height),
|
|
|
+ Width: uint32(openWithResolution.Width),
|
|
|
+ Height: uint32(openWithResolution.Height),
|
|
|
Field: v4l2.FieldAny,
|
|
|
}),
|
|
|
device.WithFPS(uint32(frameRate)),
|
|
@@ -190,10 +191,7 @@ func (i *Instance) StartVideoCapture(selectedFPS int) error {
|
|
|
if err := camera.Start(ctx); err != nil {
|
|
|
log.Fatalf("stream capture: %s", err)
|
|
|
}
|
|
|
- defer func() {
|
|
|
- cancel()
|
|
|
- camera.Close()
|
|
|
- }()
|
|
|
+ i.cameraStartContext = cancel
|
|
|
|
|
|
// video stream
|
|
|
i.frames_buff = camera.GetOutput()
|
|
@@ -216,7 +214,7 @@ func (i *Instance) IsCapturing() bool {
|
|
|
// StopCapture stops the video capture and closes the camera device
|
|
|
func (i *Instance) StopCapture() error {
|
|
|
if i.camera != nil {
|
|
|
- i.camera.Stop()
|
|
|
+ i.cameraStartContext()
|
|
|
i.camera.Close()
|
|
|
i.camera = nil
|
|
|
}
|