From patchwork Tue Jul 6 09:19:53 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: 28788 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a5d:965a:0:0:0:0:0 with SMTP id d26csp4920001ios; Tue, 6 Jul 2021 02:22:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyuE6xZSZhp8uCzpKYQ4NNmR1N8BbjdbscaYUFpFemm/3fBw7rXdbnSYs7GRcA9rUYO8oNo X-Received: by 2002:a17:906:c354:: with SMTP id ci20mr979457ejb.435.1625563346307; Tue, 06 Jul 2021 02:22:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625563346; cv=none; d=google.com; s=arc-20160816; b=KiWLKziHeogXOjAkyHIk8HZYF/d9P35x4sPqGcvbXnlZTRGWTIlAFasqRJNPenKlhM ExkaQqHzavonrcKE8o2eMuHNSVIDxcd5HkhYNip0YCJTsgyzQ1EjxfYByTNEtrpnSbHx Dctka7BksbLD1TtzB8GODg34RIls1IMoOVLsxbgzOXY0Z4qLg+uWVsFDdsyFeMdN6+16 HPmx4T8qp/halgyE52m+wnMsJa7ZlQK4v3+dWx/gqL3WmNJD4asvkUvfIlBYWZJbIU8U mUAJGtzWuWY+4AikDK2nsyCcZPD0awiHt0kNcVpL6XswWiS2XFOxZvaQhI4QRTWM652y ZU9A== 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=hi3p4JVC4YXx30h8HU54Rh1dYgcs13vustRqybcIk2s=; b=lPJpOliQGzCoKrpReAKrUUq3KRpiEwfkZRZwCc8MtFTXxBTPXAs0IScTTfKANYpSyF ExLjchB/+/erYfPWRqM0K1NMIuKsZCP8SUDMJo/fZ5DItPUilQl9HKZckYy0yph6OnKu edU+Vk0ptdIMWN1xriRVv7UBcxgd9DSVtB77EXPMPok5Jjp/9ixYch2WCDBMUbtGG7o2 IvMwbwObaFVMcgut0I5mSsBmm5fGxTwhbkZrZpDZ0EuBLfr7ootX80tRzmzr1B1huZ9e F8+2hqb1JdZ5Lxe5Haj4q7HTsAur2qnuGFVC4BRZwLxyiqktK7YCmySm6uemM66JxckG LMvw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b="vX/FQcyh"; 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 gt34si9641582ejc.285.2021.07.06.02.22.25; Tue, 06 Jul 2021 02:22:26 -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="vX/FQcyh"; 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 7E61468A74E; Tue, 6 Jul 2021 12:22:22 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f48.google.com (mail-lf1-f48.google.com [209.85.167.48]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E23A568A729 for ; Tue, 6 Jul 2021 12:22:15 +0300 (EEST) Received: by mail-lf1-f48.google.com with SMTP id p16so9699559lfc.5 for ; Tue, 06 Jul 2021 02:22:15 -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=tNu63/BMH/m9BRQPy4AqhA7Gv2OzNcdYzh97WMexFkM=; b=vX/FQcyht8K5PSjtU+EjkYhwto6JZ5WmSLll8x7LwicSJQStP8xk6lGyIWDBGjdW+F TgCA+RpTouYRmKpmLh61/T/Il/8Sbr36D42wnuthF/gtTfv5w11LdvJbPrkoiHqTi4bJ S8eHTWjBddriBJQak8w7waXwyh9D+VTVVQa/zRtDFdecrvm4mqfD3etuypkxwBWEPDjT q+nDdu8lQXIqPtKUpFlbUoj4jdODyhnSxOsh5BWj4PLmfusn6doifAsHXAaX+v/rEmW6 CEFdO78+d5n9jdb1loznzHgw9+yFy4idoCidmxjFRBp2h14Od9SsDKWZkomCtq3lokja 89UQ== 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=tNu63/BMH/m9BRQPy4AqhA7Gv2OzNcdYzh97WMexFkM=; b=kvuQkGPljmJCQ76nYqDl+SDHgxj7hKBOFCCO4nP/p31Mi2ltaJL2vtxVmJU3QaMAlS xZnK6IG/XRk4BTbquTmtlDYKk3deAQ295nhO7RhoMKIw57TA7knTG//Sa0Bgb6Y9Qxqo y7HyEXEwlaaYJ9LYO9Vv3oEwK3X+Vbj2JCFdZmhmL1ZQYx3f8+mZDjTnrdXBusE3OkEu 1+2jJn9QBHQCzYkXPac7hcjfiqP9ToRpcmHv3WXEvJxqrDp3xYDUZnt6ygwNfHU1Plcy K8B24UyEpx1CaD/KwfvYdRt9srTYzgJ/BcRw2hbgPNDqR6WWUJKNqvc+lEU1JO3w+Mag 2ZWA== X-Gm-Message-State: AOAM5331NDQCiOP0Sb8WGEPkG881VXyHQEmDXyriVMtzMlV/A60/tfy5 KshClEyHWilzTQUD0Wz4npqP8GokWwI= X-Received: by 2002:ac2:43b7:: with SMTP id t23mr10511800lfl.640.1625563334998; Tue, 06 Jul 2021 02:22:14 -0700 (PDT) Received: from localhost.localdomain (deedock.humlab.lu.se. [130.235.135.183]) by smtp.gmail.com with ESMTPSA id w3sm159671lfq.157.2021.07.06.02.22.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jul 2021 02:22:14 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Tue, 6 Jul 2021 11:19:53 +0200 Message-Id: <20210706092020.1057-8-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 07/34] 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: lRx6tTR9HT5j 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 25de6b1acd..8e693875c6 100644 --- a/libavdevice/dshow.c +++ b/libavdevice/dshow.c @@ -197,6 +197,79 @@ 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 +315,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 +361,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) @@ -306,12 +387,26 @@ 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 && media_types) { + const char* media_type = av_get_media_type_string(media_types[0]); + av_log(NULL, 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(NULL, AV_LOG_INFO, ", %s", media_type ? media_type : "unknown"); + } + av_log(NULL, AV_LOG_INFO, ")"); + } else { + av_log(NULL, AV_LOG_INFO, " (none)"); + } + av_log(avctx, AV_LOG_INFO, "\n"); + av_log(avctx, AV_LOG_INFO, " Alternative name \"%s\"\n", unique_name); } } -fail1: + fail1: + if (media_types) + av_freep(&media_types); if (device) { if (device->device_name) av_freep(&device->device_name); @@ -1194,9 +1289,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;