From patchwork Mon Sep 4 13:46:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgQsWTc2No?= X-Patchwork-Id: 4978 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.15.201 with SMTP id 70csp3139758jao; Mon, 4 Sep 2017 06:46:35 -0700 (PDT) X-Google-Smtp-Source: ADKCNb6H06G19aXwL0fCVfX5tq935QDwf1xUBIIwX9dCAnxksXLKjWMzPIG5R+JexQOQfJRQuQ+k X-Received: by 10.28.238.140 with SMTP id j12mr708751wmi.103.1504532795218; Mon, 04 Sep 2017 06:46:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504532795; cv=none; d=google.com; s=arc-20160816; b=oxRBn/r4QHWqHns4SfsefBAwlmBL8izIPXZGAjdMnDDv+hd9TNpIDT8fKuZY4ukZrF KISh1vScmEDRBy9uSqn+c7+X06RCtALATu00i5qArROX3/3ot6OvYvZtFoxPE4OXc3hG ky1dHjJ6/HI192UZKlV9o+6YYemVcrPSgvZDAgNrepKFucuG2FB+7ofSlQA1WXZbHCh6 hl9yGI0B8b899wszWvuIFAfmUGuXRIfsQvG/BKz8vAFQy3uOye0p3yBSLFXgE5p9iSF5 pvzWbIO4ubFzqV1QVl86R+rWkyU+BPBEzAfOizWZwIkMxmeD7ihAXNyYHEZOmPCBYe5n qVvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :domainkey-signature:dkim-signature:delivered-to :arc-authentication-results; bh=qtWrcMm5EM1K3UVPByxYb5uidAiU9CZ5jNrjZ3rbJq0=; b=ff6bH3/2MBf4Zhky0+8wGMyy8xm+RbI1mSKXqTmPHOL28MspcZDXQST7JS4TjZkekw KWDx5Fgb3TaDo0F1KSDlGwNcAIOx6lGuw0v5WquRKpCtETgjFkCCI0lVKDulFATzbdZ4 JanhYc4AIctQ9oVWfgSvUorRG1cr0J35oNu7cf7U+s2JkNSAKQOeGTwQqN5hPWwapEZ1 h6aklGaUhVCkh62wKvFdb+2g1qh7WFBZy1IONzuvIBVOMCJsD3q4HTV6OXWesp27bn1/ jU897FvhLud0zpPpmfqkZc/Pk8/nGakGhHaqlJ7aSDV0w6+wgn3X0j80/8LC9N7OzdcK +mDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=d5tgzoWy; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id o90si1877541wmi.213.2017.09.04.06.46.33; Mon, 04 Sep 2017 06:46:35 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@pkh.me header.s=selector1 header.b=d5tgzoWy; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id EBBB268A103; Mon, 4 Sep 2017 16:46:27 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from golem.pkh.me (LStLambert-657-1-117-164.w92-154.abo.wanadoo.fr [92.154.28.164]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C9C0768A0A0 for ; Mon, 4 Sep 2017 16:46:21 +0300 (EEST) Received: from golem.pkh.me (localhost.localdomain [127.0.0.1]) by golem.pkh.me (OpenSMTPD) with ESMTP id 0ea19594; Mon, 4 Sep 2017 13:46:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pkh.me; h=from:to:cc :subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=selector1; bh=tv4LbK9q7suWlACRBeVR /8f+KAI=; b=d5tgzoWyfij8PXzs9bAs6rxHidLK1krq2Nn+gm0kqt3pIhQB91GZ UgG09wDKsunzOqJn6X1NtBKKlxWF+0BcAZvc7FN3wPDcSBfJm/pwwhpe1kjcY9qf j2Sxcuw3f5ScVuwC34cAQXcB1ywoi43zlbuOo28r8Y2uPx+/K0Pk5tkMqVSIUr/8 L5MumPBmTZoX/2Fw/NiXWaE16RjtZUYLhdK+ojcyiLColpRWkWWdJpzpN57kFHur SlViUDdMOhPhWB14zOPR/5S4Ua1OUgYK8+h30MKA8A7QIW3Jdz/Kh7VCaAblBRIg cqviz8p8OzvcwF2dEMTCUcFtdgIOU39gtQ== DomainKey-Signature: a=rsa-sha1; c=nofws; d=pkh.me; h=from:to:cc:subject :date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=selector1; b=V2+1hquv/djtyP v9sBrVtOJLlVNKb58hFQqxswz7Czh7pcnWe4Oayq/vIGeZtUQYg01f411jcokc7Q 5xb9PiGJPXC7PAYd4QSrJEeb78vATavK/Qaak8x6+np31dWWRdQPaE9mOHstIo6v mD3UZEKmg/hocdEuOvSwnSsOGVWrnej6InuwkXWRa/iOvXNkYKAfHlooHvZ84lfp f80KschatNRfDybhKwENUXpWS6GqFH5VAJGgtHCwKF4Q7kApjgXaspxio0rJ5RQu TtKfy6AcHMlffwQKshRRoGjy0nYdWWCUUIsfHoqNa2ArS4LMGwaoDzRmB7mhAvZZ QW2+8/iA== Received: from localhost (golem.pkh.me [local]) by golem.pkh.me (OpenSMTPD) with ESMTPA id c236462d; Mon, 4 Sep 2017 13:46:23 +0000 (UTC) From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= To: ffmpeg-devel@ffmpeg.org Date: Mon, 4 Sep 2017 15:46:22 +0200 Message-Id: <20170904134622.29934-1-u@pkh.me> X-Mailer: git-send-email 2.14.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] lavd: drop QTKit indev X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Thilo Borgmann , =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Clément Bœsch QTKit has been deprecated in favor of AVFoundation for years, and we have an avfoundation input device. See https://developer.apple.com/documentation/qtkit --- Changelog | 1 + MAINTAINERS | 1 - configure | 3 - doc/indevs.texi | 44 ------ libavdevice/Makefile | 1 - libavdevice/alldevices.c | 1 - libavdevice/qtkit.m | 362 ----------------------------------------------- 7 files changed, 1 insertion(+), 412 deletions(-) delete mode 100644 libavdevice/qtkit.m diff --git a/Changelog b/Changelog index ccbcdf6328..cbeb248655 100644 --- a/Changelog +++ b/Changelog @@ -41,6 +41,7 @@ version : - FITS demuxer and decoder - FITS muxer and encoder - add --disable-autodetect build switch +- drop deprecated qtkit input device (use avfoundation instead) version 3.3: - CrystalHD decoder moved to new decode API diff --git a/MAINTAINERS b/MAINTAINERS index ce5e1dae08..8a6ac9840f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -291,7 +291,6 @@ libavdevice libdc1394.c Roman Shaposhnik opengl_enc.c Lukasz Marek pulse_audio_enc.c Lukasz Marek - qtkit.m Thilo Borgmann sdl Stefano Sabatini sdl2.c Josh de Kock v4l2.c Giorgio Vazzana diff --git a/configure b/configure index d58270550c..f7558f6998 100755 --- a/configure +++ b/configure @@ -3043,8 +3043,6 @@ oss_indev_deps_any="soundcard_h sys_soundcard_h" oss_outdev_deps_any="soundcard_h sys_soundcard_h" pulse_indev_deps="libpulse" pulse_outdev_deps="libpulse" -qtkit_indev_extralibs="-framework QTKit -framework Foundation -framework QuartzCore" -qtkit_indev_select="qtkit" sdl2_outdev_deps="sdl2" sndio_indev_deps="sndio" sndio_outdev_deps="sndio" @@ -6010,7 +6008,6 @@ enabled openssl && { use_pkg_config openssl openssl/ssl.h OPENSSL_init check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; } -enabled qtkit_indev && { check_header_objcc QTKit/QTKit.h || disable qtkit_indev; } if enabled gcrypt; then GCRYPT_CONFIG="${cross_prefix}libgcrypt-config" diff --git a/doc/indevs.texi b/doc/indevs.texi index 5423bed32f..ad6418751b 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -68,7 +68,6 @@ Set the number of channels. Default is 2. AVFoundation input device. AVFoundation is the currently recommended framework by Apple for streamgrabbing on OSX >= 10.7 as well as on iOS. -The older QTKit framework has been marked deprecated since OSX version 10.7. The input filename has to be given in the following syntax: @example @@ -1141,49 +1140,6 @@ Record a stream from default device: ffmpeg -f pulse -i default /tmp/pulse.wav @end example -@section qtkit - -QTKit input device. - -The filename passed as input is parsed to contain either a device name or index. -The device index can also be given by using -video_device_index. -A given device index will override any given device name. -If the desired device consists of numbers only, use -video_device_index to identify it. -The default device will be chosen if an empty string or the device name "default" is given. -The available devices can be enumerated by using -list_devices. - -@example -ffmpeg -f qtkit -i "0" out.mpg -@end example - -@example -ffmpeg -f qtkit -video_device_index 0 -i "" out.mpg -@end example - -@example -ffmpeg -f qtkit -i "default" out.mpg -@end example - -@example -ffmpeg -f qtkit -list_devices true -i "" -@end example - -@subsection Options - -@table @option - -@item frame_rate -Set frame rate. Default is 30. - -@item list_devices -If set to @code{true}, print a list of devices and exit. Default is -@code{false}. - -@item video_device_index -Select the video device by index for devices with the same name (starts at 0). - -@end table - @section sndio sndio input device. diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 0efb3f905f..2a27d20388 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -41,7 +41,6 @@ OBJS-$(CONFIG_PULSE_INDEV) += pulse_audio_dec.o \ pulse_audio_common.o timefilter.o OBJS-$(CONFIG_PULSE_OUTDEV) += pulse_audio_enc.o \ pulse_audio_common.o -OBJS-$(CONFIG_QTKIT_INDEV) += qtkit.o OBJS-$(CONFIG_SDL2_OUTDEV) += sdl2.o OBJS-$(CONFIG_SNDIO_INDEV) += sndio_dec.o sndio.o OBJS-$(CONFIG_SNDIO_OUTDEV) += sndio_enc.o sndio.o diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c index 4bf08d798d..38010e288a 100644 --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c @@ -58,7 +58,6 @@ static void register_all(void) REGISTER_OUTDEV (OPENGL, opengl); REGISTER_INOUTDEV(OSS, oss); REGISTER_INOUTDEV(PULSE, pulse); - REGISTER_INDEV (QTKIT, qtkit); REGISTER_OUTDEV (SDL2, sdl2); REGISTER_INOUTDEV(SNDIO, sndio); REGISTER_INOUTDEV(V4L2, v4l2); diff --git a/libavdevice/qtkit.m b/libavdevice/qtkit.m deleted file mode 100644 index 22a94ca561..0000000000 --- a/libavdevice/qtkit.m +++ /dev/null @@ -1,362 +0,0 @@ -/* - * QTKit input device - * Copyright (c) 2013 Vadim Kalinsky - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * QTKit input device - * @author Vadim Kalinsky - */ - -#if defined(__clang__) -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - -#import -#include - -#include "libavutil/pixdesc.h" -#include "libavutil/opt.h" -#include "libavformat/internal.h" -#include "libavutil/internal.h" -#include "libavutil/time.h" -#include "avdevice.h" - -#define QTKIT_TIMEBASE 100 - -static const AVRational kQTKitTimeBase_q = { - .num = 1, - .den = QTKIT_TIMEBASE -}; - -typedef struct -{ - AVClass* class; - - float frame_rate; - int frames_captured; - int64_t first_pts; - pthread_mutex_t frame_lock; - 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; -} CaptureContext; - -static void lock_frames(CaptureContext* ctx) -{ - pthread_mutex_lock(&ctx->frame_lock); -} - -static void unlock_frames(CaptureContext* ctx) -{ - pthread_mutex_unlock(&ctx->frame_lock); -} - -/** FrameReciever class - delegate for QTCaptureSession - */ -@interface FFMPEG_FrameReceiver : NSObject -{ - CaptureContext* _context; -} - -- (id)initWithContext:(CaptureContext*)context; - -- (void)captureOutput:(QTCaptureOutput *)captureOutput - didOutputVideoFrame:(CVImageBufferRef)videoFrame - withSampleBuffer:(QTSampleBuffer *)sampleBuffer - fromConnection:(QTCaptureConnection *)connection; - -@end - -@implementation FFMPEG_FrameReceiver - -- (id)initWithContext:(CaptureContext*)context -{ - if (self = [super init]) { - _context = context; - } - return self; -} - -- (void)captureOutput:(QTCaptureOutput *)captureOutput - didOutputVideoFrame:(CVImageBufferRef)videoFrame - withSampleBuffer:(QTSampleBuffer *)sampleBuffer - fromConnection:(QTCaptureConnection *)connection -{ - lock_frames(_context); - if (_context->current_frame != nil) { - CVBufferRelease(_context->current_frame); - } - - _context->current_frame = CVBufferRetain(videoFrame); - - pthread_cond_signal(&_context->frame_wait_cond); - - unlock_frames(_context); - - ++_context->frames_captured; -} - -@end - -static void destroy_context(CaptureContext* ctx) -{ - [ctx->capture_session stopRunning]; - - [ctx->capture_session release]; - [ctx->video_output release]; - [ctx->qt_delegate release]; - - ctx->capture_session = NULL; - ctx->video_output = NULL; - ctx->qt_delegate = NULL; - - pthread_mutex_destroy(&ctx->frame_lock); - pthread_cond_destroy(&ctx->frame_wait_cond); - - if (ctx->current_frame) - CVBufferRelease(ctx->current_frame); -} - -static int qtkit_read_header(AVFormatContext *s) -{ - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - CaptureContext* ctx = (CaptureContext*)s->priv_data; - - ctx->first_pts = av_gettime(); - - pthread_mutex_init(&ctx->frame_lock, NULL); - pthread_cond_init(&ctx->frame_wait_cond, NULL); - - // 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) { - const 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 >= 0) { - 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) && - strncmp(s->filename, "default", 7)) { - 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]; - - // Video capture device not found, looking for QTMediaTypeVideo - if (!success) { - video_device = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo]; - success = [video_device open:nil]; - - if (!success) { - av_log(s, AV_LOG_ERROR, "No QT capture device found\n"); - goto fail; - } - } - - NSString* dev_display_name = [video_device localizedDisplayName]; - av_log (s, AV_LOG_DEBUG, "'%s' opened\n", [dev_display_name UTF8String]); - - // Initialize capture session - ctx->capture_session = [[QTCaptureSession alloc] init]; - - QTCaptureDeviceInput* capture_dev_input = [[[QTCaptureDeviceInput alloc] initWithDevice:video_device] autorelease]; - success = [ctx->capture_session addInput:capture_dev_input error:nil]; - - if (!success) { - av_log (s, AV_LOG_ERROR, "Failed to add QT capture device to session\n"); - goto fail; - } - - // Attaching output - // FIXME: Allow for a user defined pixel format - ctx->video_output = [[QTCaptureDecompressedVideoOutput alloc] init]; - - NSDictionary *captureDictionary = [NSDictionary dictionaryWithObject: - [NSNumber numberWithUnsignedInt:kCVPixelFormatType_24RGB] - forKey:(id)kCVPixelBufferPixelFormatTypeKey]; - - [ctx->video_output setPixelBufferAttributes:captureDictionary]; - - ctx->qt_delegate = [[FFMPEG_FrameReceiver alloc] initWithContext:ctx]; - - [ctx->video_output setDelegate:ctx->qt_delegate]; - [ctx->video_output setAutomaticallyDropsLateVideoFrames:YES]; - [ctx->video_output setMinimumVideoFrameInterval:1.0/ctx->frame_rate]; - - success = [ctx->capture_session addOutput:ctx->video_output error:nil]; - - if (!success) { - av_log (s, AV_LOG_ERROR, "can't add video output to capture session\n"); - goto fail; - } - - [ctx->capture_session startRunning]; - - // Take stream info from the first frame. - while (ctx->frames_captured < 1) { - CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES); - } - - lock_frames(ctx); - - AVStream* stream = avformat_new_stream(s, NULL); - - if (!stream) { - goto fail; - } - - avpriv_set_pts_info(stream, 64, 1, QTKIT_TIMEBASE); - - stream->codec->codec_id = AV_CODEC_ID_RAWVIDEO; - stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; - stream->codec->width = (int)CVPixelBufferGetWidth (ctx->current_frame); - stream->codec->height = (int)CVPixelBufferGetHeight(ctx->current_frame); - stream->codec->pix_fmt = AV_PIX_FMT_RGB24; - - CVBufferRelease(ctx->current_frame); - ctx->current_frame = nil; - - unlock_frames(ctx); - - [pool release]; - - return 0; - -fail: - [pool release]; - - destroy_context(ctx); - - return AVERROR(EIO); -} - -static int qtkit_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - CaptureContext* ctx = (CaptureContext*)s->priv_data; - - do { - lock_frames(ctx); - - if (ctx->current_frame != nil) { - if (av_new_packet(pkt, (int)CVPixelBufferGetDataSize(ctx->current_frame)) < 0) { - return AVERROR(EIO); - } - - pkt->pts = pkt->dts = av_rescale_q(av_gettime() - ctx->first_pts, AV_TIME_BASE_Q, kQTKitTimeBase_q); - pkt->stream_index = 0; - pkt->flags |= AV_PKT_FLAG_KEY; - - CVPixelBufferLockBaseAddress(ctx->current_frame, 0); - - void* data = CVPixelBufferGetBaseAddress(ctx->current_frame); - memcpy(pkt->data, data, pkt->size); - - CVPixelBufferUnlockBaseAddress(ctx->current_frame, 0); - CVBufferRelease(ctx->current_frame); - ctx->current_frame = nil; - } else { - pkt->data = NULL; - pthread_cond_wait(&ctx->frame_wait_cond, &ctx->frame_lock); - } - - unlock_frames(ctx); - } while (!pkt->data); - - return 0; -} - -static int qtkit_close(AVFormatContext *s) -{ - CaptureContext* ctx = (CaptureContext*)s->priv_data; - - destroy_context(ctx); - - return 0; -} - -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 }, -}; - -static const AVClass qtkit_class = { - .class_name = "QTKit input device", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, -}; - -AVInputFormat ff_qtkit_demuxer = { - .name = "qtkit", - .long_name = NULL_IF_CONFIG_SMALL("QTKit input device"), - .priv_data_size = sizeof(CaptureContext), - .read_header = qtkit_read_header, - .read_packet = qtkit_read_packet, - .read_close = qtkit_close, - .flags = AVFMT_NOFILE, - .priv_class = &qtkit_class, -};