From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id F271140533 for ; Tue, 21 Dec 2021 12:14:21 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id AF35C68AFD1; Tue, 21 Dec 2021 14:13:46 +0200 (EET) 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-Google-Smtp-Source: ABdhPJyfMdwVvmvYSFkZAG9aNnqEWXx59mBSEDw2a7jZUHWrGdHdxkmP/C6ZM93oQazzO5379nx4Lg== 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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: 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; -- 2.28.0.windows.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".