diff mbox series

[FFmpeg-devel,v2,2/5] libdc1394: Verify the camera supports the selected mode and framerate

Message ID 20201015213039.1019624-3-cyrozap@gmail.com
State New
Headers show
Series libdc1394 enhancements
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished

Commit Message

Forest Crossman Oct. 15, 2020, 9:30 p.m. UTC
Without this, if a mode or framerate is selected that the camera doesn't
support, the camera can enter a state where it won't respond until it's
power-cycled.

Tested with an Apple iSight.

Signed-off-by: Forest Crossman <cyrozap@gmail.com>
---
 libavdevice/libdc1394.c | 56 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
diff mbox series

Patch

diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c
index ec74cea87a..7be1d7b8dd 100644
--- a/libavdevice/libdc1394.c
+++ b/libavdevice/libdc1394.c
@@ -173,6 +173,13 @@  static int dc1394_read_header(AVFormatContext *c)
     int res, i;
     const struct dc1394_frame_format *fmt = NULL;
     const struct dc1394_frame_rate *fps = NULL;
+    const struct dc1394_frame_format *tmp_fmt;
+    const struct dc1394_frame_rate *tmp_fps;
+    dc1394video_modes_t supported_modes;
+    dc1394framerates_t supported_framerates;
+    int requested_mode_supported = 0;
+    int requested_framerate_supported = 0;
+    int mode_found;
 
     if (dc1394_read_common(c, &fmt, &fps) != 0)
        return -1;
@@ -223,11 +230,60 @@  static int dc1394_read_header(AVFormatContext *c)
         goto out_camera;
     }
 
+    if (dc1394_video_get_supported_modes(dc1394->camera, &supported_modes) != DC1394_SUCCESS) {
+        av_log(c, AV_LOG_ERROR, "Couldn't get supported video formats\n");
+        goto out_camera;
+    }
+
+    for (i = 0; i < supported_modes.num; i++) {
+        mode_found = 0;
+        if (fmt->frame_size_id == supported_modes.modes[i])
+            requested_mode_supported = 1;
+        for (tmp_fmt = dc1394_frame_formats; tmp_fmt->width; tmp_fmt++)
+            if (tmp_fmt->frame_size_id == supported_modes.modes[i]) {
+                av_log(c, AV_LOG_VERBOSE, "Supported format: %dx%d, %s\n",
+                       tmp_fmt->width, tmp_fmt->height, av_get_pix_fmt_name(tmp_fmt->pix_fmt));
+                mode_found = 1;
+                break;
+            }
+        if (!mode_found)
+            av_log(c, AV_LOG_VERBOSE, "Supported format (unsupported by libavdevice): %d\n",
+                   supported_modes.modes[i]);
+    }
+
+    if (!requested_mode_supported) {
+        av_log(c, AV_LOG_ERROR, "Camera doesn't support video format: %dx%d, %s\n",
+               fmt->width, fmt->height, av_get_pix_fmt_name(fmt->pix_fmt));
+        goto out_camera;
+    }
+
     if (dc1394_video_set_mode(dc1394->camera, fmt->frame_size_id) != DC1394_SUCCESS) {
         av_log(c, AV_LOG_ERROR, "Couldn't set video format\n");
         goto out_camera;
     }
 
+    if (dc1394_video_get_supported_framerates(dc1394->camera, fmt->frame_size_id, &supported_framerates) != DC1394_SUCCESS) {
+        av_log(c, AV_LOG_ERROR, "Couldn't get supported framerates\n");
+        goto out_camera;
+    }
+
+    for (i = 0; i < supported_framerates.num; i++) {
+        if (fps->frame_rate_id == supported_framerates.framerates[i])
+            requested_framerate_supported = 1;
+        for (tmp_fps = dc1394_frame_rates; tmp_fps->frame_rate; tmp_fps++)
+            if (tmp_fps->frame_rate_id == supported_framerates.framerates[i]) {
+                av_log(c, AV_LOG_VERBOSE, "Supported framerate for mode %dx%d, %s: %d:1000\n",
+                       fmt->width, fmt->height, av_get_pix_fmt_name(fmt->pix_fmt), tmp_fps->frame_rate);
+                break;
+            }
+    }
+
+    if (!requested_framerate_supported) {
+        av_log(c, AV_LOG_ERROR, "Camera doesn't support framerate for mode %dx%d, %s: %d:1000\n",
+               fmt->width, fmt->height, av_get_pix_fmt_name(fmt->pix_fmt), fps->frame_rate);
+        goto out_camera;
+    }
+
     if (dc1394_video_set_framerate(dc1394->camera,fps->frame_rate_id) != DC1394_SUCCESS) {
         av_log(c, AV_LOG_ERROR, "Couldn't set framerate %d \n",fps->frame_rate);
         goto out_camera;