From patchwork Tue Dec 21 12:12:34 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: 32784 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:cd86:0:0:0:0:0 with SMTP id d128csp5361177iog; Tue, 21 Dec 2021 04:14:25 -0800 (PST) X-Google-Smtp-Source: ABdhPJypFxk3bYAZK4sap0nlxgFrJ9hhuJ3JQ9GPeSWN4dNW/FE6AD4OWaX1H+cp+bbgZUv3+XB9 X-Received: by 2002:a05:6402:1e8a:: with SMTP id f10mr3043793edf.52.1640088865088; Tue, 21 Dec 2021 04:14:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1640088865; cv=none; d=google.com; s=arc-20160816; b=p6Z6JZvJ7xnwFhEOgW9z9rJGgzw+uxpw8tzElIfJ40/lLjHVnT6x5UwnlagxYKJw3j 8jXiExQI6Hhx39hIXGa7oFsYFbKzo8GyKziJLMoz8vW+pkUslEluVkR95I3PzzozL/wj PDFY5r1rbqwIHthpdAJNMmueTNplQ9xwBWc26jxPmakjcCuSgfqzRpvCFDgIffj6ZHQu 8bgWgGO5I8/MrefahbQf/+fp9oUr84O+/dMpFGrRUfzgPiPTwlI0lheV+ur32WAAKSSw tQiqWggMGARVdZcGNn7aE9Z82GlOJkTqkbxJBvGlHroOnniMMAEJJBYWmaVu0xwU1RlF w6dA== 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=ckchGMdpEiP1zFYFdME8cEHxrtpNiMzR+wSs5u6/avo=; b=lInIlEmBwq6Rw7IuEcFpxtL954BhcxcLZV+nJtO9sIUNTK6EfjYLj86WgYJ2HLWj2w LnNt64kJDPnF844zuf06jyip5I6onmgxZJ6tkEq8yWQfLcn3zPBLMXOOaI2ESDjyZf/k FzeDFlHjuWLeqoxMKQE00NNVOfxA0nQVDde5HmZDDTBJDpygaNcHveNDZ6zenPJM3E3x 2C5AQfC2/7ly9ylzZyOYq31FM7M2JzxwbkiGPyHajcCCAiLG7DRpM5RSLfVtYkmjYfdz bMQ0jOEDLOA5/wNEOWLtpu0AamMF7NjwiavK7KxOcK/apC+1p9W9e7xE7dlAk1e9gZRk b4Rg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b="X7Oi3/1S"; 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 y9si155447edv.384.2021.12.21.04.14.24; Tue, 21 Dec 2021 04:14:25 -0800 (PST) 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="X7Oi3/1S"; 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 E44C268AFD2; Tue, 21 Dec 2021 14:13:46 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f41.google.com (mail-lf1-f41.google.com [209.85.167.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 9864168AFB3 for ; Tue, 21 Dec 2021 14:13:40 +0200 (EET) Received: by mail-lf1-f41.google.com with SMTP id o12so9630024lfk.1 for ; Tue, 21 Dec 2021 04:13:40 -0800 (PST) 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=LtqzHYGVuzjBr2UxmIJX18AIY5hVdJD9RAAMd5KqA0c=; b=X7Oi3/1SmRbMyz+RuHX3JvIJW/hhFKq99VVD1DnenSCboKc6c4ZUsucAEV3lQl7cUW 64CbeReeh/3ix/miPRBSuYl904wE9/LL80UEj+dfVM4GHZuna7Sxi3Wvff+wO5++OCLf KlrpACKdAFPoKk6Iuk6dgTwohi/93FXUYIylglOPf6UWpfyMYUzMxruZ/nvupOPjvQG/ 2R8wL6IGBDShqbfcXTB0AqLaJmPjl9pIDHaRhK40oszS20oWxPwsDILyDbR44LQBCxZZ gqdqWWD0RyRponlqLEaFmAie3ZYC9Y9JgNk9lDFvDSRBbicOfX3+msMX+g6Xo+ECltx4 vZjA== 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=LtqzHYGVuzjBr2UxmIJX18AIY5hVdJD9RAAMd5KqA0c=; b=WMgcOatVXOsfdWsPXOUZwCI+DEygMMvH+6Ai9G3kdeD73ZMhlnHYtmaLs7xbTDBwNx Okc6GAYdNy1a/fhzX3PFAEPFfJh9qHCZ0Aj7UWr4dFegtJfWiTZ5uqdLZtF2D30H0tUT cuN28cgCLoeBW/mUZzCohBpRsQpQphMeFxV70waMedmRudmJrjtbuDBrRr4zTVlrPLD5 RZ/pl6Y7nclTQq3o9RUtrbGu4maNQrgOoCO6DDVPO2KrOojrUwknQZTP7z7HZiVfj5F4 ASrzERT7bIfW4zPu/MCGjNXOiVYzg/RH0S/p0ozftz3yltdraPF+MuGyTq6Gl22obyK6 HQwA== X-Gm-Message-State: AOAM532LXh9+9SlTegxIABE7Kmf8k/cD6WrKPL0EmqNWlOnHUd/Z2bNr 4fr3jnbTea5wgl9NatVWCXjzs/LKuis+0w== X-Received: by 2002:a05:6512:3e13:: with SMTP id i19mr2867567lfv.508.1640088819683; Tue, 21 Dec 2021 04:13:39 -0800 (PST) Received: from localhost.localdomain ([196.244.192.13]) by smtp.gmail.com with ESMTPSA id m13sm2692142lfl.131.2021.12.21.04.13.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Dec 2021 04:13:39 -0800 (PST) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Tue, 21 Dec 2021 13:12:34 +0100 Message-Id: <20211221121239.1201-8-dcnieho@gmail.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20211221121239.1201-1-dcnieho@gmail.com> References: <20211221121239.1201-1-dcnieho@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v6 07/12] avdevice/dshow: list_devices: show media type(s) per 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: SHbYHvjAQq89 the list_devices option of dshow didn't indicate whether a specific device provides audio or video output. This patch iterates through all media formats of all pins exposed by the device to see what types it provides for capture, and prints this to the console for each device. Importantly, this now allows to find devices that provide both audio and video, and devices that provide neither. Signed-off-by: Diederick Niehorster --- libavdevice/dshow.c | 103 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c index e1702c8519..8dba04a787 100644 --- a/libavdevice/dshow.c +++ b/libavdevice/dshow.c @@ -197,6 +197,80 @@ fail: return; } +static void +dshow_get_device_media_types(AVFormatContext *avctx, enum dshowDeviceType devtype, + enum dshowSourceFilterType sourcetype, IBaseFilter *device_filter, + enum AVMediaType **media_types, int *nb_media_types) +{ + struct dshow_ctx *ctx = avctx->priv_data; + IEnumPins *pins = 0; + IPin *pin; + int has_audio = 0, has_video = 0; + + if (IBaseFilter_EnumPins(device_filter, &pins) != S_OK) + return; + + while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) { + IKsPropertySet *p = NULL; + PIN_INFO info = { 0 }; + GUID category; + DWORD r2; + IEnumMediaTypes *types = NULL; + AM_MEDIA_TYPE *type; + + if (IPin_QueryPinInfo(pin, &info) != S_OK) + goto next; + IBaseFilter_Release(info.pFilter); + + if (info.dir != PINDIR_OUTPUT) + goto next; + if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK) + goto next; + if (IKsPropertySet_Get(p, &ROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, + NULL, 0, &category, sizeof(GUID), &r2) != S_OK) + goto next; + if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE)) + goto next; + + if (IPin_EnumMediaTypes(pin, &types) != S_OK) + goto next; + + // enumerate media types exposed by pin + // NB: don't know if a pin can expose both audio and video, check 'm all to be safe + IEnumMediaTypes_Reset(types); + while (IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) { + if (IsEqualGUID(&type->majortype, &MEDIATYPE_Video)) { + has_video = 1; + } else if (IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) { + has_audio = 1; + } + CoTaskMemFree(type); + } + + next: + if (types) + IEnumMediaTypes_Release(types); + if (p) + IKsPropertySet_Release(p); + if (pin) + IPin_Release(pin); + } + + IEnumPins_Release(pins); + + if (has_audio || has_video) { + int nb_types = has_audio + has_video; + *media_types = av_malloc_array(nb_types, sizeof(enum AVMediaType)); + if (*media_types) { + if (has_audio) + (*media_types)[0] = AVMEDIA_TYPE_AUDIO; + if (has_video) + (*media_types)[0 + has_audio] = AVMEDIA_TYPE_VIDEO; + *nb_media_types = nb_types; + } + } +} + /** * Cycle through available devices using the device enumerator devenum, * retrieve the device with type specified by devtype and return the @@ -242,6 +316,8 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, LPOLESTR olestr = NULL; LPMALLOC co_malloc = NULL; AVDeviceInfo *device = NULL; + enum AVMediaType *media_types = NULL; + int nb_media_types = 0; int i; r = CoGetMalloc(1, &co_malloc); @@ -286,6 +362,12 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, // success, loop will end now } } else { + // get media types exposed by pins of device + if (IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void* ) &device_filter) == S_OK) { + dshow_get_device_media_types(avctx, devtype, sourcetype, device_filter, &media_types, &nb_media_types); + IBaseFilter_Release(device_filter); + device_filter = NULL; + } if (device_list) { device = av_mallocz(sizeof(AVDeviceInfo)); if (!device) @@ -308,12 +390,25 @@ dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, device = NULL; // copied into array, make sure not freed below } else { - av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name); - av_log(avctx, AV_LOG_INFO, " Alternative name \"%s\"\n", unique_name); + av_log(avctx, AV_LOG_INFO, "\"%s\"", friendly_name); + if (nb_media_types > 0) { + const char* media_type = av_get_media_type_string(media_types[0]); + av_log(avctx, AV_LOG_INFO, " (%s", media_type ? media_type : "unknown"); + for (int i = 1; i < nb_media_types; ++i) { + media_type = av_get_media_type_string(media_types[i]); + av_log(avctx, AV_LOG_INFO, ", %s", media_type ? media_type : "unknown"); + } + av_log(avctx, AV_LOG_INFO, ")"); + } else { + av_log(avctx, AV_LOG_INFO, " (none)"); + } + av_log(avctx, AV_LOG_INFO, "\n"); + av_log(avctx, AV_LOG_INFO, " Alternative name \"%s\"\n", unique_name); } } -fail: + fail: + av_freep(&media_types); if (device) { av_freep(&device->device_name); av_freep(&device->device_description); @@ -1186,9 +1281,7 @@ static int dshow_read_header(AVFormatContext *avctx) } if (ctx->list_devices) { - av_log(avctx, AV_LOG_INFO, "DirectShow video devices (some may be both video and audio devices)\n"); dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, NULL, NULL, NULL); - av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n"); dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, NULL, NULL, NULL); ret = AVERROR_EXIT; goto error;