From patchwork Fri Mar 25 14:10:41 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: 34982 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:ab0:5fda:0:0:0:0:0 with SMTP id g26csp1377270uaj; Fri, 25 Mar 2022 07:15:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxT7BnN/x3+vRUZNTZuS7ocieuw7trnJx5SRfgMryMpQ2H+fq0jnJI12BWIVGhGhpI2QCkX X-Received: by 2002:aa7:c157:0:b0:418:f8e3:4c87 with SMTP id r23-20020aa7c157000000b00418f8e34c87mr13272768edp.271.1648217736372; Fri, 25 Mar 2022 07:15:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648217736; cv=none; d=google.com; s=arc-20160816; b=fowTjUEX8YdwojhVA79sQtNvhTh8Xlf10a49pma+RO9VBjI/89mioP4AiyGoFQw0gz OXEs0juTu6uun3XwLLSTlguZWGTQFUk4cXo9hfICMVRbcvhPmmCqfvcyOrGrG7c2OmF6 xBG8vkGkR2HHkGLiY6Lli8MmfUNLImgna6qT9CqXdEeAz4y5sbzZG0zkPoFiFnzNe/qm sZOH0Og52h8yFVo+0AFIz9+frI0BYqsfLiRI0RgpaXZDwuFKk/Dfzsphjh+EQ9GnpAkt oXfaloSo741OAGdnNNe6kZDSQXAIVKhUFSAav9DNuLMOxqOwjFTUMN72g6M1UtoaInxM NxtQ== 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=UHsKqZKvvXc+DDJ9zh3sAvU8KVDphNXE1XA7sWfle6E=; b=xhIjaUlCH9YDkIJPSY+gZh3+50Tgvv+0dSDAoWN3U6+27u8rr7ojSoElf5WYGisltW P1RGvAUIPj3WV2NYl4WDJrBvHRhJ2SGoxxQaBz5BS9O0o7MZLyOBujYnVF3HfbE1W0Q8 uc3KKGQanR7ujsDQqWMJHiKjQP9n0OxnxG72uuXnDwh8RXg760eAaUEUyexwIDiuwjDN UVXh7uNyXHpMuI+USQtVwxX1wgp5Msg5s/3OtYFSnCnL56LCT84WA8BTari2j/QuKWF+ 1/0sPsPYWyhctS6ZYaWbQhI2b7CXSJnw5gYv3MJTey4SZCzekr383owu2MVNdhgiduvd 3Xow== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=bwq8w2hu; 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 b13-20020aa7d48d000000b00418c2b5bd80si2862355edr.98.2022.03.25.07.15.36; Fri, 25 Mar 2022 07:15:36 -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=bwq8w2hu; 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 EED3568B2CE; Fri, 25 Mar 2022 16:13:35 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 984F368B2C6 for ; Fri, 25 Mar 2022 16:13:34 +0200 (EET) Received: by mail-lj1-f175.google.com with SMTP id g24so10474697lja.7 for ; Fri, 25 Mar 2022 07:13:34 -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=MoX3WE6sSUEUEPxyFw4Zpli4hgB9ZCym87zfR3vTSy0=; b=bwq8w2hu3rlS8AqCUhdQ45E7Vndw1fnDbKmfYXcPZp0PCxOTdC0WK78dQ+1Dwb+eBU yGskiGf8mGUlAjnOdc/rhltnz9AyfKaYwG7l521B0XgKmHM4pF1NJRyMapM3WZdaRpgu kZIr89c+Go1O0Wqkk2BXYmbXb3JBu3TfbfBxBzDfTG6/YXa8cvGdAuStpI7e4idWsEtf 5QuBzO4bXGJuC0JS4GHJFVd8rJDyUIUyh8p3UopBu4mKZXqSUxSW8EA2nWMP/q6c6hhX NWH7RtUnL8xY9732kAyAP6b1KQBj4H7YMnOzSfaLi2BFwlhdMzo7NWiJM49iU9031COx yosg== 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=MoX3WE6sSUEUEPxyFw4Zpli4hgB9ZCym87zfR3vTSy0=; b=2AWcZ8ckQMoe8Wivdqvngi34fMBU16FDEVNmYlGY6HvhaI5nzOARryh7qfraGcrX3C RXEI7x55BPRb5ewdDh+QmRhSZEvljnp6Yi431CoHWvme+oTVGoIma54eTfTGjfBXCY3U qNzEG5xF6mwY+PugqScx4X7uqbBZ4/TPKckP8sqolelnLNxsl0CGcLV/98/wnKAFmkzX SxAQE8vZNhdwpqCPgNzXxc70fMdBahenlaTBZcIrXsAqxrXC4KKx5rfahdJxz5BJ1eDm fnMkHTfRkchIGJBGn2T5Tten4xItudfGdW/bGJU8dRCn4u5/kYwKNTM0JRSipBh7T4hQ qv5w== X-Gm-Message-State: AOAM532dXylOcrlOquKCWiJPRAK1EtdCx8lLMmW16c7LDyr8SPqpzNde qsCjzBt8qXCtjOWcB+bJ9x6qjY3my5A= X-Received: by 2002:a2e:9847:0:b0:238:eca:62fd with SMTP id e7-20020a2e9847000000b002380eca62fdmr8310519ljj.65.1648217613284; Fri, 25 Mar 2022 07:13:33 -0700 (PDT) Received: from localhost.localdomain (deedock.humlab.lu.se. [130.235.135.183]) by smtp.gmail.com with ESMTPSA id x40-20020a056512132800b004489691436esm720853lfu.146.2022.03.25.07.13.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Mar 2022 07:13:32 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Fri, 25 Mar 2022 15:10:41 +0100 Message-Id: <20220325141041.1748-23-dcnieho@gmail.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20220325141041.1748-1-dcnieho@gmail.com> References: <20220325141041.1748-1-dcnieho@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v4 22/22] 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: CROaS9ZhS22F 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 c426cef905..216c888bed 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; }; /*****************************************************************************