From patchwork Wed Mar 30 12:18:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Diederick C. Niehorster" X-Patchwork-Id: 35075 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c05:b0:7a:e998:b410 with SMTP id bw5csp775082pzb; Wed, 30 Mar 2022 05:22:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyBJwxC5+tUTUgb5DE0cq6nBQ+oZULU+LHKYP+a4wU39Hhrlfc3Szd3aXEhHkHTT3Z+JABB X-Received: by 2002:a17:906:58d2:b0:6da:b635:fbf3 with SMTP id e18-20020a17090658d200b006dab635fbf3mr38642187ejs.40.1648642925731; Wed, 30 Mar 2022 05:22:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648642925; cv=none; d=google.com; s=arc-20160816; b=vj6ZoNX789XmLMQkH+Mlz9hr+XQQSTS+P8sFST755kuX4CVWJnUnYBAt1/IGM7YuY8 yURpFu6ffHZ5oVFZ0yTru9wWgdwOBmxfVooYrRKMHShxL4b8CTa0sZZ5AHUgCFkd9DPR 2BEKgJ1Z6ny/z0b8di93qQmD4TvfiG7WjOnL/KHaeI0fpbt8JSYaFJaSE0CtbJp74TSf HYbPnoMz9smcsZkv1AyomIhWLF6PijpbM0Yum18Dpdw8H+kW21J/sqxMyIVPo00BNToE LfqpWM38YB1Dq3evAX6wVu5xxgjWKuPFeo/5KIhQqNozUC0iL7GVhPkzw7qMYiBbETy5 tmNw== 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:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=AaJnY39oP3AkeCTAKkoV1wcqehCaeIsYJMEPtnbpqDg=; b=ABE3wa6jdBnAzNcWU+ptzOmBZyBMYIlIYNbW308giLLvTdWSUnpvd40w678KihPy8d XzhxQgyDHH4/5Op/HLQhoFc5ePiSiHLJHlUDo0A1Q0qOAD1CJAUdIgv0JnTc+lITVKx7 yNa2CvFY2cyeMgJTsuEF9TBjRRUaAEa6yb/oHWO8dt0qYS8gAqHEJtoH7SGTlIao9XxL FLYCYzcmaCBqxcL38UTf8Sdncteiglta8nU+m81dCSKEMIBrvHDK+Geb/jlUqyTnipdz b1hHO0G7tC4VeReKf9Qh+/tVb7nlwEktH7P1zQqZfMRS02O2wu8h4THuYe0BiQq+b5Gp 12EA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=AMQSzhmi; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id e20-20020a17090658d400b006df91581f50si26420845ejs.983.2022.03.30.05.22.05; Wed, 30 Mar 2022 05:22:05 -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=@gmail.com header.s=20210112 header.b=AMQSzhmi; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A2CF468B2BD; Wed, 30 Mar 2022 15:20:44 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f44.google.com (mail-lf1-f44.google.com [209.85.167.44]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C83C368B24E for ; Wed, 30 Mar 2022 15:20:38 +0300 (EEST) Received: by mail-lf1-f44.google.com with SMTP id bq24so19525458lfb.5 for ; Wed, 30 Mar 2022 05:20:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=D07bVlKiIkA2SzzUiC6GaF15DcgQb3Fp+hz3VGzc3Z8=; b=AMQSzhmiuWyl8LE7aHiHQQkAVy40xgLNO8ZyJ0C1mAUqg7tZh5nGxIvuv0khbqrihA 4PPTGHHRB2XK3U2yk3E1+Ur93NtKfpeibprPzwNczh7vzEN5Mm37Pilti1v/m+2pTcON NM6Lr9yi0ExrII6cBLQkmp4mLH0j20afLNnnnl8GCDOY08kxpa07UgySf+EzY+xEr1OO 4kHnWq1QFDjKO8lDS4V97TpL7tKfiOGfybhiTVLHk+p8QmFrNohFbYN39a/22nOfZx+3 uFREXm3+0B1XvdVJOCrBv6Neth3QHx4fRXJnE95IMGRLQtRwhvH1kli11dB/1nm6htzE j9sA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=D07bVlKiIkA2SzzUiC6GaF15DcgQb3Fp+hz3VGzc3Z8=; b=WV11SdAeJ4yWUk0Ej1UwQ5GRZ27qECNHcNfjUQuoRK1adS+nbzXpGNUM3oRhTlLFtc WVJBBrnnGhwu0ROq2zeDLNQKuVB+6W003YqYv5GRgQ1jcpJdy6IJbc805quT1jTtk31x lBc+u6KW6S+A/anl+sxxfgj1Z/ZBOZIeY/MivwlGZn8nS5RhiBfOqkYXB3HJdT6f+4Bf IStNSJrNG5CVsnm1YUSGZtrLHI9EAJu6RxHFi8c6SNxNy3RblVChV5v3Q7CAyNW9aDtc ma3a4dsxce1FqPiq1LjH3dARXwh/W4ZlEU6KBuba6X4ZEkLFxq3KTH2bShgJ38XvgFu5 Efjw== X-Gm-Message-State: AOAM5313BzASiaTanTzNXie9G+4Gqe176Fn6gXfya06UxjyYYz973HOB kk3PfSWERSLcdjxfyOI0YPcGLDJuVys= X-Received: by 2002:a05:6512:400e:b0:447:5d84:c40 with SMTP id br14-20020a056512400e00b004475d840c40mr6221092lfb.591.1648642837904; Wed, 30 Mar 2022 05:20:37 -0700 (PDT) Received: from localhost.localdomain (deedock.humlab.lu.se. [130.235.135.183]) by smtp.gmail.com with ESMTPSA id a21-20020a2eb555000000b00247ea2fa530sm2324070ljn.20.2022.03.30.05.20.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 30 Mar 2022 05:20:37 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Wed, 30 Mar 2022 14:18:06 +0200 Message-Id: <20220330121806.822-22-dcnieho@gmail.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20220330121806.822-1-dcnieho@gmail.com> References: <20220330121806.822-1-dcnieho@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v5 21/21] avdevice/dshow: capabilities query also works on opened device X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Diederick Niehorster Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: YXD9dpMOPKdB While the capabilities API is in principle meant to be used with an allocated format context belonging to an unopened device, small changes make it work for an opened dshow device as well. So hereby done. Signed-off-by: Diederick Niehorster --- libavdevice/dshow.c | 110 +++++++++++++++++++++--------------- libavdevice/dshow_capture.h | 3 + 2 files changed, 66 insertions(+), 47 deletions(-) diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c index 3cae7d265e..1e4025983a 100644 --- a/libavdevice/dshow.c +++ b/libavdevice/dshow.c @@ -849,7 +849,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype, void *caps = NULL; int i, n, size, r; int wait_for_better = 0; - int use_default; + int use_default, already_opened; // format parameters requested by user // if none are requested by user, the values will below be set to @@ -875,6 +875,9 @@ dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype, if (!caps) goto end; + // get if device is already opened + already_opened = ctx->device_name[0] || ctx->device_name[1]; + /** * If we should open the device with the default format, * then: @@ -1153,7 +1156,7 @@ dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype, // in ranges, try to apply in all cases, and store // caps if successfully applied if (!wait_for_better || ranges) { - if (IAMStreamConfig_SetFormat(config, type) != S_OK) + if (!already_opened && IAMStreamConfig_SetFormat(config, type) != S_OK) // skip if device already opened goto next; else if (ranges) { // format matched and could be set successfully. @@ -1494,12 +1497,19 @@ dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum, char *device_unique_name = NULL; int r; - if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_unique_name, NULL)) < 0) - return r; - ctx->device_filter[devtype] = device_filter; - ctx->device_unique_name[devtype] = device_unique_name; + if (!ctx->device_filter[devtype]) { + if ((r = dshow_cycle_devices(avctx, devenum, devtype, sourcetype, &device_filter, &device_unique_name, NULL)) < 0) + return r; + + // put them in context so they'll be cleaned up again + ctx->device_filter[devtype] = device_filter; + ctx->device_unique_name[devtype] = device_unique_name; + } else + device_filter = ctx->device_filter[devtype]; + if ((r = dshow_cycle_pins(avctx, devtype, sourcetype, device_filter, ranges ? &device_pin : NULL, ranges, query_type)) < 0) return r; + return 0; } @@ -2319,7 +2329,8 @@ fail1: return ret; } -// fake class to point av_opt_query_ranges to our query_ranges function +// fake class to point av_opt functions to capabilities that can be queried, +// and av_opt_query_ranges to our query_ranges function static const AVClass dshow_dev_caps_class = { .class_name = "", .item_name = av_default_item_name, @@ -2337,49 +2348,51 @@ static int dshow_create_device_capabilities(struct AVFormatContext *avctx, AVDev // set class so queries work caps->av_class = &dshow_dev_caps_class; - if (ctx->device_name[0] || ctx->device_name[1]) { - av_log(avctx, AV_LOG_ERROR, "You cannot query device capabilities on an opened device\n"); - ret = AVERROR(EIO); - goto fail; - } + // check if device setup is needed or we will be querying capabilities of an already opened device + ctx->cap_query_already_opened = ctx->device_name[0] || ctx->device_name[1]; + if (ctx->cap_query_already_opened) + av_log(avctx, AV_LOG_WARNING, "Querying device capabilities on an opened device: may yield false positives\n"); - if (!parse_device_name(avctx)) { - av_log(avctx, AV_LOG_ERROR, "You must set a device name (AVFormatContext url) to specify which device to query capabilities from\n"); - ret = AVERROR(EINVAL); - goto fail; - } - - CoInitialize(0); - if (CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, - &IID_ICreateDevEnum, (void **) &devenum)) { - av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n"); - ret = AVERROR(EIO); - goto fail; - } + // if device not already opened, check that what user specified can be opened + if (!ctx->cap_query_already_opened) { + if (!parse_device_name(avctx)) { + av_log(avctx, AV_LOG_ERROR, "You must set a device name (AVFormatContext url) to specify which device to query capabilities from\n"); + ret = AVERROR(EINVAL); + goto fail; + } - // check devices can be found - if (ctx->device_name[VideoDevice]) { - IBaseFilter *device_filter = NULL; - char *device_unique_name = NULL; - if ((ret = dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, &device_filter, &device_unique_name, NULL)) < 0) - return ret; - - if (ret >= 0) { - ctx->device_filter[VideoDevice] = device_filter; - ctx->device_unique_name[VideoDevice] = device_unique_name; + CoInitialize(0); + if (CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, + &IID_ICreateDevEnum, (void **) &devenum)) { + av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n"); + ret = AVERROR(EIO); + goto fail; } - } - if (ctx->device_name[AudioDevice]) { - IBaseFilter *device_filter = NULL; - char *device_unique_name = NULL; - if (dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, &device_filter, &device_unique_name, NULL) < 0) { - /* try to access audio from combined video+audio sources as fallback */ - if ((ret = dshow_cycle_devices(avctx, devenum, AudioDevice, VideoSourceDevice, &device_filter, &device_unique_name, NULL)) < 0) - goto fail; + + // check devices can be found + if (ctx->device_name[VideoDevice]) { + IBaseFilter *device_filter = NULL; + char *device_unique_name = NULL; + if ((ret = dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, &device_filter, &device_unique_name, NULL)) < 0) + return ret; + + if (ret >= 0) { + ctx->device_filter[VideoDevice] = device_filter; + ctx->device_unique_name[VideoDevice] = device_unique_name; + } } - if (ret >= 0) { - ctx->device_filter[AudioDevice] = device_filter; - ctx->device_unique_name[AudioDevice] = device_unique_name; + if (ctx->device_name[AudioDevice]) { + IBaseFilter *device_filter = NULL; + char *device_unique_name = NULL; + if (dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, &device_filter, &device_unique_name, NULL) < 0) { + /* try to access audio from combined video+audio sources as fallback */ + if ((ret = dshow_cycle_devices(avctx, devenum, AudioDevice, VideoSourceDevice, &device_filter, &device_unique_name, NULL)) < 0) + goto fail; + } + if (ret >= 0) { + ctx->device_filter[AudioDevice] = device_filter; + ctx->device_unique_name[AudioDevice] = device_unique_name; + } } } @@ -2395,9 +2408,12 @@ fail: static int dshow_free_device_capabilities(struct AVFormatContext *avctx, AVDeviceCapabilitiesQuery *caps) { + struct dshow_ctx *ctx = avctx->priv_data; + // clear state variables that may have been set during the querying process // (e.g. frees device names, removes device_filters, etc) - dshow_read_close(avctx); + if (!ctx->cap_query_already_opened) + dshow_read_close(avctx); return 0; } diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h index 94ba9896b7..a2c107b19c 100644 --- a/libavdevice/dshow_capture.h +++ b/libavdevice/dshow_capture.h @@ -345,6 +345,9 @@ struct dshow_ctx { int sample_rate; int sample_size; int channels; + + // for capabilities query + int cap_query_already_opened; }; /*****************************************************************************