From patchwork Tue Jul 6 09:20:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Diederick C. Niehorster" X-Patchwork-Id: 28814 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a5d:965a:0:0:0:0:0 with SMTP id d26csp4923388ios; Tue, 6 Jul 2021 02:27:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwG505wQIAemXFJyVACZQ5ddbjGX+fSsYiVTS+93ludLudVFhQ96AzsJeX983jGa2n5rvOX X-Received: by 2002:a50:f0ce:: with SMTP id a14mr20994434edm.176.1625563670194; Tue, 06 Jul 2021 02:27:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625563670; cv=none; d=google.com; s=arc-20160816; b=hdLEn7yWiHuP/GMu62FhzZ81sdRkDV/J7ZkdPhum/ZLvBIDNxM/pSbzvnguuW8gu7Q FytbQvBmNf2t//nF7pamFOjxMPtGF67ryKhsWVuLdsvY9Grh2EQvX7mToFKFMBiwcDoJ xVhXM3QBUANuGRrZ+UoNjPYjhCkogmZL2DxbINYBEriaxHDBvNmjDU8uECWgLi91vON3 DcudLKfbnfYV6LGP31zzRLmWKQ1kSyFlSH1/UQpuC0Jb8akulVBgLqWJkoE/gd8oe6BM Nk9rmhEc3RoZNrjYKzPo+ueOpsIZf5GPGdBO68oKTjVeuJGKWWZm5xCiL1JJtRl98naD TMrA== 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=AD9mQxdQqw6CVmhPh7yqpRhLHifktUWmNoukHNexnfk=; b=afI0J0Rvht8YlKTElcDejg8xB3ezmnpct8K+KexzWdeq+hwQf8XkddwwdtrE+1yhlA s1d/HE0YpzRPu7ZsqgitnZkx1FV5C9AwHyzQP1ROeQu/GRXN5eQwWmsjmBU8Hy1QkP5k 9ulPYCUiNQqWV4JSbAAQUJF9LLpJL8t7MZfhGVr5ByUYUtAcSFKBD4OUqASeuxYLtWCf Vv3QwMNNCwzA0ArZN7d1TbDsbJP+uvUbbpNWQy3byd7m/7T4qOfOaFzeLuABxKESfDS5 n1v8Xv3AiCIHtKlrrZDX8GhIFS3IGWQFSlqsy5GvQ4K6qDinOQgNrkqMnzdFfh7Ug1W2 88og== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=L67DNb91; 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 hv20si3685488ejc.521.2021.07.06.02.27.49; Tue, 06 Jul 2021 02:27:50 -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=20161025 header.b=L67DNb91; 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 F423168A982; Tue, 6 Jul 2021 12:27:33 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id ED66968A970 for ; Tue, 6 Jul 2021 12:27:26 +0300 (EEST) Received: by mail-lf1-f54.google.com with SMTP id p1so1471242lfr.12 for ; Tue, 06 Jul 2021 02:27:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9hRuUIPhfn6sRc55ga+51OmjmgcHGu9+EplVS94wSGo=; b=L67DNb91cxuJsLCvjnRLGRDk5D33PAhtmeMPf2ljrLtDjIljbDWf5r2HMMj5zE8Njn qpVPUx8qWSHpYxs+X8RH8qP7ZSN5rbIysW+sEJXwOJW5zQO5UUxAUowbKLzWqtUv2Ria PnunMGon1VE6+xe1rufqzXe8mJHLKC1wpCpoW4ktjJfri+LzH5xy1X28HViaS5GmHwZR o2feK8QVjMCkGCnYHJrL14/wGDm/YCHGCkVBkoAGmfLjFaD3ZvzRUjHZUaPpyzh1nI4+ UY+PU2jxMTaRRPQx84tCmYckSXT5tDUQ9JQjfb16aCokE8F74yoQtVq6gHTKfxOlqr4W IX+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9hRuUIPhfn6sRc55ga+51OmjmgcHGu9+EplVS94wSGo=; b=aza57ENhuswC8amXaRhTA0kgA7dV/kofXxy93XjN1y8Ou3pwiElwnjQspbFeEsdCIP IPkXesemhQFEkTLJGbXobfzsn2DkQZZH4SkApXsI7hsJidgqaQS0a6f+Lv4Lu6k7mrTC hb3l472QEo9wuS0sA+xpehM4tPfMvAUYRYAkJ/LHrW3NXCClACV7ChaRjb8p8ut/xau2 tATakS/Dy2OJylrUo2dqcDltbUWjf6qjqXveY0strJsYLAasDvDTI65/kMb0r0/k09Of WaJBabshIJZ5ZWlW7sCyUXRAvNOniUNfpcJCapfej6+60G9tM9UKWWlT5iKjBScAR/D6 IvXA== X-Gm-Message-State: AOAM533gnaVlKSjBpH8X0oZ81N3XrSEyjlNv5T7CPok6w5w6kOPvYgro /9JADI/8M2BUz74H25azlh2cCH5Yals= X-Received: by 2002:a05:6512:3618:: with SMTP id f24mr6732704lfs.517.1625563646119; Tue, 06 Jul 2021 02:27:26 -0700 (PDT) Received: from localhost.localdomain (deedock.humlab.lu.se. [130.235.135.183]) by smtp.gmail.com with ESMTPSA id 14sm1349081lfz.84.2021.07.06.02.27.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 02:27:25 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Tue, 6 Jul 2021 11:20:20 +0200 Message-Id: <20210706092020.1057-35-dcnieho@gmail.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20210706092020.1057-1-dcnieho@gmail.com> References: <20210706092020.1057-1-dcnieho@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3 34/34] 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: bOVI7tX6C1h2 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 a66f7b81fd..5c1fadc23d 100644 --- a/libavdevice/dshow.c +++ b/libavdevice/dshow.c @@ -858,7 +858,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 @@ -884,6 +884,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: @@ -1191,7 +1194,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. @@ -1516,12 +1519,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; } @@ -2344,7 +2354,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, @@ -2362,49 +2373,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; + } } } @@ -2420,9 +2433,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 127695a86b..06ac4a6fd6 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; }; /*****************************************************************************