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

Lukasz Marek lukasz.m.luki2 at gmail.com
Sun Mar 30 21:54:47 CEST 2014


On 30.03.2014 21:17, Thilo Borgmann wrote:
>>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);
> +    }

I'm not sure it is required. It can possibly lead to scan a random 
number that is a part of device name.

> +    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)) {

Many devices uses string "default" for this reason, not empty string. Be 
free to ignore this, but this would make it more consistent with other 
devices.

> +        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 },
>   };

You may also consider implementing .get_device_list callback to obtain 
device list programmatically (as another patch).



More information about the ffmpeg-devel mailing list