[FFmpeg-devel] [PATCH v2 3/5] libdc1394: Enable specifying a camera by GUID[:unit]

Forest Crossman cyrozap at gmail.com
Fri Oct 16 00:30:37 EEST 2020


This enables a user to select a specific unit of a specific camera,
instead of always selecting the first unit of the first camera that's
found.

Signed-off-by: Forest Crossman <cyrozap at gmail.com>
---
 doc/indevs.texi         |  3 ++
 libavdevice/libdc1394.c | 70 ++++++++++++++++++++++++++++-------------
 2 files changed, 51 insertions(+), 22 deletions(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index 3d554bc8d8..46203833e9 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -1096,6 +1096,9 @@ IIDC1394 input device, based on libdc1394 and libraw1394.
 
 Requires the configure option @code{--enable-libdc1394}.
 
+Specify the FireWire device GUID to be used as the input file, or "auto"
+to choose the first device detected.
+
 @subsection Options
 @table @option
 
diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c
index 7be1d7b8dd..90252f7c4a 100644
--- a/libavdevice/libdc1394.c
+++ b/libavdevice/libdc1394.c
@@ -171,6 +171,8 @@ static int dc1394_read_header(AVFormatContext *c)
     dc1394_data* dc1394 = c->priv_data;
     dc1394camera_list_t *list;
     int res, i;
+    uint64_t guid;
+    uint16_t unit;
     const struct dc1394_frame_format *fmt = NULL;
     const struct dc1394_frame_rate *fps = NULL;
     const struct dc1394_frame_format *tmp_fmt;
@@ -186,33 +188,57 @@ static int dc1394_read_header(AVFormatContext *c)
 
     /* Now let us prep the hardware. */
     dc1394->d = dc1394_new();
-    if (dc1394_camera_enumerate(dc1394->d, &list) != DC1394_SUCCESS || !list) {
-        av_log(c, AV_LOG_ERROR, "Unable to look for an IIDC camera.\n");
-        goto out;
-    }
 
-    if (list->num == 0) {
-        av_log(c, AV_LOG_ERROR, "No cameras found.\n");
-        dc1394_camera_free_list(list);
-        goto out;
-    }
+    /* Parse URL */
+    if (sscanf(c->url, "0x%"SCNx64":%"SCNu16, &guid, &unit) == 2) {
+        /* If both the GUID and unit are set, open the device based on
+         * those values exactly. */
+        dc1394->camera = dc1394_camera_new_unit(dc1394->d, guid, unit);
+        if (!dc1394->camera) {
+             av_log(c, AV_LOG_ERROR, "Unable to open camera 0x%016"PRIx64":%"PRIu16"\n",
+                    guid, unit);
+             goto out;
+        }
+    } else if (sscanf(c->url, "0x%"SCNx64, &guid) == 1) {
+        /* If the GUID is set, but not the unit, grab the device using
+         * the first unit found. */
+        dc1394->camera = dc1394_camera_new(dc1394->d, guid);
+        if (!dc1394->camera) {
+             av_log(c, AV_LOG_ERROR, "Unable to open camera 0x%016"PRIx64"\n",
+                    guid);
+             goto out;
+        }
+    } else {
+        /* If no GUID is set, or is set to "auto", use the first camera
+         * found. */
+        if (dc1394_camera_enumerate(dc1394->d, &list) != DC1394_SUCCESS || !list) {
+            av_log(c, AV_LOG_ERROR, "Unable to look for an IIDC camera.\n");
+            goto out;
+        }
 
-    /* FIXME: To select a specific camera I need to search in list its guid */
-    dc1394->camera = dc1394_camera_new (dc1394->d, list->ids[0].guid);
+        if (list->num == 0) {
+            av_log(c, AV_LOG_ERROR, "No cameras found.\n");
+            dc1394_camera_free_list(list);
+            goto out;
+        }
 
-    if (!dc1394->camera) {
-         av_log(c, AV_LOG_ERROR, "Unable to open camera with guid 0x%"PRIx64"\n",
-                list->ids[0].guid);
-         dc1394_camera_free_list(list);
-         goto out;
-    }
+        if (list->num > 1) {
+            av_log(c, AV_LOG_INFO, "Multiple cameras detected, using the first camera found.\n");
+        }
 
-    if (list->num > 1) {
-        av_log(c, AV_LOG_INFO, "Working with the first camera found\n");
-    }
+        guid = list->ids[0].guid;
+        unit = list->ids[0].unit;
+        dc1394->camera = dc1394_camera_new_unit(dc1394->d, guid, unit);
 
-    /* Freeing list of cameras */
-    dc1394_camera_free_list (list);
+        /* Freeing list of cameras */
+        dc1394_camera_free_list (list);
+
+        if (!dc1394->camera) {
+             av_log(c, AV_LOG_ERROR, "Unable to open camera 0x%016"PRIx64":%"PRIu16"\n",
+                    guid, unit);
+             goto out;
+        }
+    }
 
     /* Select MAX Speed possible from the cam */
     if (dc1394->camera->bmode_capable>0) {
-- 
2.20.1



More information about the ffmpeg-devel mailing list