From patchwork Thu Jun 3 22:33:00 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: 28075 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:b214:0:0:0:0:0 with SMTP id b20csp545301iof; Thu, 3 Jun 2021 16:00:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzLKXI27kUywh5Y238UeidLaKcYUBZY/br+ZMbE3BBwE5NGtY9T/268aHZjxgN+LY64N/EQ X-Received: by 2002:a17:906:7302:: with SMTP id di2mr1331980ejc.409.1622761241454; Thu, 03 Jun 2021 16:00:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622761241; cv=none; d=google.com; s=arc-20160816; b=rtAgY84CVhf3kmdi0R0zSowmfWdLK2VDwShvrFFdHjJjEBOgn28JU4o5Dw1P6GiRjw 4B9z+RGKrYIAENe2Q+lT0ZyAF3KDL/45Ycv8e9edUFk0PvBAG3s4d+FFttoU+j5nKdlG YZiXDQybjFvJvAMqz6bLsqDJOsKhK15X3r95js3ZPCrYMbdhVhUFquLpi+DT5IfditsD XP+dgoPnDsdbNAR1TteLs+JQ2SYD6WzIq6TXsJTNMR+ZyGdgh2TW8Q1MueXem5v+rRJT 5hPlGxOy1uz85KUSE4M34JPlSGz4ZR/yUWBuqHtvcACjpBMnbAAmjYQtrYwU7ItVGNLt 55LQ== 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=xtm6vihorRTVqzNsAIcAKftlTJnsb9y7aMe1S58Xbp4=; b=f5kBJKYG0sfYuuEkKBpKchl96rXrOJZk1tN80CO13Mjz4Zjuu8dwH3/cugjN6VlSLM nFiiUJtN1DV8wqYv0DRdLdSQuFbry6YVoEgCxrSyD2edXiVDgxoDTj+so9spwA0e0lUt FbtaofLbSG0Nyr11cro1HDNUrJT70mLjF86jMhwLsASpFYBDQ58PfZY+cMslZBu10V+P JlRY6ZaLecq+zm93dk1JsVdCjADdtlw42INlzY8lMkN7WXMFJSxpPvFzVj0YwZki6V8m RhYUZhEopSAe33om6c+ywva/eMLCu4q4asu/VUTAdnDpVoiJOkKCbXpKuDYL3wc98jby qV9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=RGUdUZBR; 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 dn20si3867322ejc.125.2021.06.03.16.00.41; Thu, 03 Jun 2021 16:00:41 -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=RGUdUZBR; 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 B190F68A2B2; Fri, 4 Jun 2021 02:00:38 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BE670689E85 for ; Fri, 4 Jun 2021 02:00:32 +0300 (EEST) Received: by mail-ej1-f41.google.com with SMTP id g8so11662611ejx.1 for ; Thu, 03 Jun 2021 16:00:32 -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=pVuug6zOBrm12AB23nP8todnuFf6FXEqrhUsNaKTNXY=; b=RGUdUZBRMX1JFwt1TqU2Mv1s+2Vo484IZ8YINx9SVgN/RFvlkF9JyGklcpld1BzqNB I0arqN+GlgfKUmn11Ig9ldWVBpUIfa9EXOKvtOwjm4Cu1MU7pU0cDilvVJBjwzo1QFlM Th6YvJ+kpIuyEtBMAnttIRT19qFhkOMxIxzNoxf5LuZcSZ/UpIP/eF9fVY/tzwzZNGTo 3G7cYSugZzpuL7c8B2swoWtPoQnKMxdf3Xk3cmi3WsMtPuOwm2usaMLlYqOPC98QySC6 ZMP92C36007XWe3DKLtOIqVBKUtpPMadLARfSPZzUYcrBNPnMsokfPeWhLfQPR+f5aTJ RHrA== 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=pVuug6zOBrm12AB23nP8todnuFf6FXEqrhUsNaKTNXY=; b=lgfiRXENOdH+qGZ5v+qa7/E0N6E4R2shD13k8x9XDrkBNC79vIgk9o4zrxbWqiIfm0 sVT+vLs3xj1W+hOSqK2CNlGsFwTkybjDeYZ4FLUT+u/xtqEF00GTlMGJC/Pis95xc7bS 99tCAKcGnSjNsJ89A2gTBPdZk/8vQpwoZ5QJVh/BurDpbLsRGspDCW9wRIsVWTEaBIEC O34g74Pl5NYWAQajRtNiaW98kBdMHnuhrZmdxWSrnO38/mlnkukv8o97NJhJynZfuTpX PDdYP5CANE2lRRqISr6w4uM4bEHoaopF7f2PL3djRIeuR0NmJ6C+ZBvaSLAW7ygi8raM G8lg== X-Gm-Message-State: AOAM533dql2LDQbneASsf3hYQo5OPP6lSxSy/WQUtFB9/26dLEqigkf8 bIqIjqpFeIlcrSXpuF7BlAusJ/NcIbA= X-Received: by 2002:a19:ed1a:: with SMTP id y26mr725686lfy.120.1622759744257; Thu, 03 Jun 2021 15:35:44 -0700 (PDT) Received: from localhost.localdomain (84-217-56-54.customers.ownit.se. [84.217.56.54]) by smtp.gmail.com with ESMTPSA id b6sm236026lfa.296.2021.06.03.15.35.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 15:35:43 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Fri, 4 Jun 2021 00:33:00 +0200 Message-Id: <20210603223302.1047-5-dcnieho@gmail.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20210603223302.1047-1-dcnieho@gmail.com> References: <20210603223302.1047-1-dcnieho@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] examples: adding device_get_capabilities example 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: OdiaCIPbdeoJ Signed-off-by: Diederick Niehorster --- configure | 2 + doc/examples/.gitignore | 1 + doc/examples/Makefile | 47 ++++---- doc/examples/Makefile.example | 1 + doc/examples/device_get_capabilities.c | 151 +++++++++++++++++++++++++ 5 files changed, 179 insertions(+), 23 deletions(-) create mode 100644 doc/examples/device_get_capabilities.c diff --git a/configure b/configure index 82367fd30d..5e9666d017 100755 --- a/configure +++ b/configure @@ -1705,6 +1705,7 @@ EXAMPLE_LIST=" decode_audio_example decode_video_example demuxing_decoding_example + device_get_capabilities_example encode_audio_example encode_video_example extract_mvs_example @@ -3712,6 +3713,7 @@ avio_reading_deps="avformat avcodec avutil" decode_audio_example_deps="avcodec avutil" decode_video_example_deps="avcodec avutil" demuxing_decoding_example_deps="avcodec avformat avutil" +device_get_capabilities_example_deps="avdevice avformat avutil" encode_audio_example_deps="avcodec avutil" encode_video_example_deps="avcodec avutil" extract_mvs_example_deps="avcodec avformat avutil" diff --git a/doc/examples/.gitignore b/doc/examples/.gitignore index 44960e1de7..256f33a600 100644 --- a/doc/examples/.gitignore +++ b/doc/examples/.gitignore @@ -3,6 +3,7 @@ /decode_audio /decode_video /demuxing_decoding +/device_get_capabilities /encode_audio /encode_video /extract_mvs diff --git a/doc/examples/Makefile b/doc/examples/Makefile index 81bfd34d5d..7988ed4226 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -1,26 +1,27 @@ -EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir -EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading -EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio -EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video -EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding -EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio -EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video -EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs -EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio -EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio -EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video -EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient -EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode -EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata -EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing -EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec -EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing -EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio -EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video -EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac -EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding -EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode -EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode +EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir +EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading +EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio +EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video +EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding +EXAMPLES-$(CONFIG_DEVICE_GET_CAPABILITIES_EXAMPLE) += device_get_capabilities +EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio +EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video +EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs +EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio +EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE) += filtering_audio +EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE) += filtering_video +EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient +EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode +EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata +EXAMPLES-$(CONFIG_MUXING_EXAMPLE) += muxing +EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE) += qsvdec +EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing +EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio +EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video +EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac +EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE) += transcoding +EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode +EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF)) EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF)) diff --git a/doc/examples/Makefile.example b/doc/examples/Makefile.example index a232d97f98..b861b9cc74 100644 --- a/doc/examples/Makefile.example +++ b/doc/examples/Makefile.example @@ -16,6 +16,7 @@ EXAMPLES= avio_list_dir \ decode_audio \ decode_video \ demuxing_decoding \ + device_get_capabilities \ encode_audio \ encode_video \ extract_mvs \ diff --git a/doc/examples/device_get_capabilities.c b/doc/examples/device_get_capabilities.c new file mode 100644 index 0000000000..f3b9f31e0d --- /dev/null +++ b/doc/examples/device_get_capabilities.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2021 Diederick Niehorster + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @file + * avdevice getting capabilities example. + * + * Shows how to use the avdevice capabilities API to probe + * device capabilities (supported codecs, pixel formats, sample + * formats, resolutions, channel counts, etc) + * @example device_get_capabilities.c + */ + +#include +#include +#include +#include + + + +int main (int argc, char **argv) +{ + int ret = 0; + const char* dshow_input_name = NULL; + const char* query_cap = NULL; + const char* set_cap_name = NULL; + const char* set_cap_value = NULL; + + const AVInputFormat* fmt = NULL; + AVFormatContext* fmt_ctx = NULL; + AVDeviceCapabilitiesQuery* caps = NULL; + AVOptionRanges* ranges = NULL; + + if (argc != 5) { + fprintf(stderr, "usage: %s dshow_input_name query_cap set_cap_name set_cap_value\n" + "API example program to show how to use the avdevice\n" + "capabilities API to probe device capabilities \n" + "(supported codecs, pixel formats, sample formats,\n" + "resolutions, channel counts, etc).\n\n" + "example invocation: " + "%s video=\"Integrated Webcam\" frame_size pixel_format yuyv422", + argv[0], argv[0]); + exit(1); + } + dshow_input_name = argv[1]; + query_cap = argv[2]; + set_cap_name = argv[3]; + set_cap_value = argv[4]; + + // make sure avdevices can be found + avdevice_register_all(); + // find our device (capabilities API is currently + // only implemented for dshow device, so hardcode that) + fmt = av_find_input_format("dshow"); + + // since there is no equivalent of avformat_alloc_output_context2 for an input context, + // so we get this dirty code that users shouldn't have to write.... + fmt_ctx = avformat_alloc_context(); + fmt_ctx->url = av_strdup(dshow_input_name); + fmt_ctx->iformat = fmt; + if (fmt_ctx->iformat->priv_data_size > 0) { + if (!(fmt_ctx->priv_data = av_mallocz(fmt_ctx->iformat->priv_data_size))) { + ret = AVERROR(ENOMEM); + goto end; + } + if (fmt_ctx->iformat->priv_class) { + *(const AVClass**)fmt_ctx->priv_data = fmt_ctx->iformat->priv_class; + av_opt_set_defaults(fmt_ctx->priv_data); + } + } + // end dirty code + + // query the capability without any filter set + ret = avdevice_capabilities_create(&caps, fmt_ctx, NULL); + if (ret < 0) + goto end; + + ret = av_opt_query_ranges(&ranges, caps, query_cap, AV_OPT_MULTI_COMPONENT_RANGE); + if (ret < 0) + goto end; + + for (int range_index = 0; range_index < ranges->nb_ranges; range_index++) { + for (int component_index = 0; component_index < ranges->nb_components; component_index++) + { + AVOptionRange *range = ranges->range[ranges->nb_ranges * component_index + range_index]; + if (component_index > 0) + printf(", "); + printf("%s: %.2f -- %.2f", range->str, range->value_min, range->value_max); + } + printf("\n"); + } + av_opt_freep_ranges(&ranges); + + printf("=============\n"); + + // set one capability, which may filter out some returned capabilities + // (or all, if set to an invalid value) + ret = av_opt_set(caps, set_cap_name, set_cap_value, 0); + if (ret < 0) + goto end; + + ret = av_opt_query_ranges(&ranges, caps, query_cap, AV_OPT_MULTI_COMPONENT_RANGE); + if (ret < 0) + goto end; + + for (int range_index = 0; range_index < ranges->nb_ranges; range_index++) { + for (int component_index = 0; component_index < ranges->nb_components; component_index++) + { + AVOptionRange* range = ranges->range[ranges->nb_ranges * component_index + range_index]; + if (component_index > 0) + printf(", "); + printf("%s: %.2f -- %.2f", range->str, range->value_min, range->value_max); + } + printf("\n"); + } + + +end: + av_opt_freep_ranges(&ranges); + avdevice_capabilities_free(&caps, fmt_ctx); + + avformat_close_input(&fmt_ctx); + + if (ret < 0) { + char a[AV_ERROR_MAX_STRING_SIZE] = { 0 }; + av_make_error_string(a, AV_ERROR_MAX_STRING_SIZE, ret); + + printf("!!Error: %s\n", a); + } + + return ret < 0; +}