From patchwork Fri Jun 11 20:30:38 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: 28206 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a5e:c91a:0:0:0:0:0 with SMTP id z26csp763255iol; Fri, 11 Jun 2021 13:33:42 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy/oQbIHB/5UdKyOa7+FpoA3uEkXmceaybyqGRkPIBRurOuRF5Tw/pSd5QcyH7FE59sOTHu X-Received: by 2002:a17:906:eb17:: with SMTP id mb23mr5320247ejb.239.1623443622573; Fri, 11 Jun 2021 13:33:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623443622; cv=none; d=google.com; s=arc-20160816; b=WWJ4XzUNQ3CJJ6edWUyHDZM3N9/4pSqQ/0XnOKIRlFWyHRoeKGoWo9cwZy17HTxw07 XFDSzPlpiqo2f5vgEMp57iTKslGeEUvqRzQGWqjx7vWRYjXME3CaDjO7lm6jZFeoLSKw Q+FeuyDyZkgw69elx/COShLX7L69LT6097Mjnb/gh5uk0TIRCKRcNyiXJyrGqtQP/Zin 9+8bfuNI8yRDSo62Oxtojsy4sIcau+Aoja3V5tO1HmJ6xSO8Zg+f7nBTfZkx/Vqb6G7g CAkHjUUMmTlxhF2IQAZj7DuRAVCmHfbIzwHDEDBcMSDo3YX5MSj2HFR8Vh/uvt21dJk4 bdCQ== 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=r4TCCbmYS4Gea8+w0+RQLm61JsyAJaXWteXbkW6kefI=; b=wDw1ME8nmghgA6YnzOdRe8rRtsl6TcKo3XY2T4yvgJJKQshBI/p0MTxRk1AFp7jff7 Ue17643el907mvKWdJp0lecthU05FnCyjfdX5ybheImOtIK4WZi1Chygqa0+ETiA3o6E Xoa7EEtfpEST7aMQdP9ZvF5bV1DKh0taw1jxN/m0CcSL39GzKEYc+YO9v1IuFKyV2oJu tFRpy2hI3ecapSbKIuOo2SMv2aM3M3w+9ipRtvZSmOGnH1AMomJ7cex2s6n/NwjZLtQb s9yXvbqlhXYl7WDrEQldKMlpFAnYmm5EqUyKoLG2XsKm0jSXl4zdrfYFTA4JeIttJ1u+ Wb/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=HOhI446O; 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 b6si6364423edu.115.2021.06.11.13.33.42; Fri, 11 Jun 2021 13:33:42 -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=HOhI446O; 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 6611C68814B; Fri, 11 Jun 2021 23:33:39 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f176.google.com (mail-lj1-f176.google.com [209.85.208.176]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 90335687F27 for ; Fri, 11 Jun 2021 23:33:37 +0300 (EEST) Received: by mail-lj1-f176.google.com with SMTP id r16so11389098ljc.0 for ; Fri, 11 Jun 2021 13:33:37 -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=3rUKQxo3ad42j1iPnnbOHplre1vZ9tYsRgcPCB5N31w=; b=HOhI446OpWuW5pfB5+4eXq5UWoin+QbceHhjgzxXtkU83xEipPiRlt2QOds2W8aNNJ nEFRU1FU2SAOhsHsyFGkGDA+TGwv437XrYtaWTyula/HXuBKWpnNie04Hyv1CQx7XwRy z9P0tjQ9sfRL9w2jQzdoyx2CcZvr0LL0fFzKtHOg732kRHn+W+bN2WmA4DDIySO3awRp ytncLFnvSmXKvxle1Jb+rksu9vMlUhz7gBOo1z3NMerbKF9SXCGP4S4/vIe+Tbqaq6nv QryhUPznQggqy1muYdwVUW4UCpBpWveJSh9hT4gD4s/3bhloXkspNhNIcsOVXlaxkqjb NoJg== 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=3rUKQxo3ad42j1iPnnbOHplre1vZ9tYsRgcPCB5N31w=; b=Ck7/VvJqjtDSI2hEuD5+8Cm9/2jix8cudSK2q07b+s/1YFkv989lWDQ1UzX6ukQe2/ 2tFhzf0b/4iQ9EEDAu96p6zJqdqBMDtJcZKUHfGKHZHB4wfwgEqgfnDTCu4SNFCCKFlu gQ2KHxy6vjuS1lXNXUH9iQNsXBurW12+/Yik1WqSWhtjSlxECP+WN7MVuCsPMJOhaLjJ tK/lJwXE6va2rFr7onRKkiy4SoFmbmq5IWJ8rVFkdqvDwpJNNHVo/iRckwQkCdZe+ePv wBgjrGUoT82BhB2eGsxopIzyaun1RernSBu5wx6cwyMLD0CShAt8HtkfWq++iSGYuVKw VO/Q== X-Gm-Message-State: AOAM533rtSDgp78W9xUOiGVtn0peNoajlf/Hk+oLqrvPqRd46sENkzvs IXD9Y5dkpbzM9CumObOzTiX9lZh/EuUe9w== X-Received: by 2002:a2e:8e2b:: with SMTP id r11mr4403653ljk.349.1623443616629; Fri, 11 Jun 2021 13:33:36 -0700 (PDT) Received: from localhost.localdomain ([196.196.203.214]) by smtp.gmail.com with ESMTPSA id t13sm845330lji.19.2021.06.11.13.33.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Jun 2021 13:33:36 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Fri, 11 Jun 2021 22:30:38 +0200 Message-Id: <20210611203104.1692-8-dcnieho@gmail.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20210611203104.1692-1-dcnieho@gmail.com> References: <20210611203104.1692-1-dcnieho@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 07/33] 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: 3V1tdNeVa+aZ 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..5d7f065a8c 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;