[FFmpeg-devel] [PATCH] lavd/qtkit: Support choosing the input device by index or by name.

Thilo Borgmann thilo.borgmann at mail.de
Sun Mar 30 21:17:51 CEST 2014


Hi,

as in $subject. Borrowed ideas from the dshow device. Not sure if the sscanf's
and strncmp is safe, though.

-Thilo
-------------- next part --------------
>From a44489698c7237988817a63e55058e0d49b120dc Mon Sep 17 00:00:00 2001
From: Thilo Borgmann <thilo.borgmann at mail.de>
Date: Sun, 30 Mar 2014 21:13:04 +0200
Subject: [PATCH 1/2] lavd/qtkit: Support choosing the input device by index or
 by name.

---
 doc/indevs.texi     |  8 +++++++-
 libavdevice/qtkit.m | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/doc/indevs.texi b/doc/indevs.texi
index e1ff231..b54df72 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -535,12 +535,18 @@ ffmpeg -f pulse -i default /tmp/pulse.wav
 
 QTKit input device.
 
-The filename passed as input is unused. The default device will be chosen.
+The filename passed as input is parsed to contain either a device name or index.
+The default device will be chosen if an empty string is given.
+The available devices can be enumerated by using -list_devices.
 
 @example
 ffmpeg -f isight -i "" out.mpg
 @end example
 
+ at example
+ffmpeg -f qtkit -list_devices true -i ""
+ at end example
+
 @section sndio
 
 sndio input device.
diff --git a/libavdevice/qtkit.m b/libavdevice/qtkit.m
index 038ce02..edcc518 100644
--- a/libavdevice/qtkit.m
+++ b/libavdevice/qtkit.m
@@ -53,6 +53,9 @@ typedef struct
     pthread_cond_t  frame_wait_cond;
     id              qt_delegate;
 
+    int             list_devices;
+    int             video_device_index;
+
     QTCaptureSession*                 capture_session;
     QTCaptureDecompressedVideoOutput* video_output;
     CVImageBufferRef                  current_frame;
@@ -145,8 +148,51 @@ static int qtkit_read_header(AVFormatContext *s)
     pthread_mutex_init(&ctx->frame_lock, NULL);
     pthread_cond_init(&ctx->frame_wait_cond, NULL);
 
-    // Find default capture device
-    QTCaptureDevice *video_device = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed];
+    // List devices if requested
+    if (ctx->list_devices) {
+        av_log(ctx, AV_LOG_INFO, "QTKit video devices:\n");
+        NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
+        for (QTCaptureDevice *device in devices) {
+            char *name = [[device localizedDisplayName] UTF8String];
+            int index  = [devices indexOfObject:device];
+            av_log(ctx, AV_LOG_INFO, "[%d] %s\n", index, name);
+        }
+        goto fail;
+    }
+
+    // Find capture device
+    QTCaptureDevice *video_device = nil;
+
+    // check for device index given in filename
+    if (ctx->video_device_index == -1) {
+        sscanf(s->filename, "%d", &ctx->video_device_index);
+    }
+
+    if (ctx->video_device_index != -1) {
+        NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
+
+        if (ctx->video_device_index >= [devices count]) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid device index\n");
+            goto fail;
+        }
+
+        video_device = [devices objectAtIndex:ctx->video_device_index];
+    } else if (strncmp(s->filename, "", 1)) {
+        NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
+
+        for (QTCaptureDevice *device in devices) {
+            if (!strncmp(s->filename, [[device localizedDisplayName] UTF8String], strlen(s->filename))) {
+                video_device = device;
+                break;
+            }
+        }
+        if (!video_device) {
+            av_log(ctx, AV_LOG_ERROR, "Video device not found\n");
+            goto fail;
+        }
+    } else {
+        video_device = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed];
+    }
 
     BOOL success = [video_device open:nil];
 
@@ -284,6 +330,10 @@ static int qtkit_close(AVFormatContext *s)
 
 static const AVOption options[] = {
     { "frame_rate", "set frame rate", offsetof(CaptureContext, frame_rate), AV_OPT_TYPE_FLOAT, { .dbl = 30.0 }, 0.1, 30.0, AV_OPT_TYPE_VIDEO_RATE, NULL },
+    { "list_devices", "list available devices", offsetof(CaptureContext, list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
+    { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
+    { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
+    { "video_device_index", "select video device by index for devices with same name (starts at 0)", offsetof(CaptureContext, video_device_index), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
     { NULL },
 };
 
-- 
1.8.3.2



More information about the ffmpeg-devel mailing list