From patchwork Mon Jun 7 23:04:11 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: 28130 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:b214:0:0:0:0:0 with SMTP id b20csp3887494iof; Mon, 7 Jun 2021 16:07:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz+5WntB3oqOhct58xa2LpboSBAPTC6dTwdw+g7aclukpQqKH7sIHqEE9kxabi6JJwd0Hct X-Received: by 2002:a17:906:4111:: with SMTP id j17mr19836775ejk.488.1623107235176; Mon, 07 Jun 2021 16:07:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623107235; cv=none; d=google.com; s=arc-20160816; b=qGZT1TTofyRJLUd0kFavjKf62vWuVDsoROjc4a5vRo8OZLhkBH0ZNeD5DSy486HTsu nz29YP1bbe3vSzV19x0sMSz+twDJKstFeiw0XUrVWhRNZ9vUbiA0AIbon3bL+PsuaOoG BrpksfDZalP8PxVqoKUNetmW8qUurP9ictRaPE2YgBS8LWEYzBBceBO6qPxkouYch0h2 hf5vZEoaR5N/Vd0sZt20isahIH6c1Dx1mgZ925CVFNeb+DVj6lMC+JzYwWQFXAhp3xav Q7K8LGEYT02Zj1IxyP8iQxKBiGjp0HQmazMBKiCTck2DArZ1eOO6IyyiMCkWatPzVfRB XVCQ== 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=x89Go4lf0EsXpvlwS24RYOya//t8OGx5capR0YoJVEg=; b=bDU3AKLcrtEH3u8KNfseaRa/PZhOBG02AAA6/xSU4XFMf5+vLnD506aI/M0E2rQ5t+ fVRBJidkeCj1O0uGQgUgwJGEFE00hBMu2fX1C4+XQtMDbGoQpTvRPUHm5ERp9xTPRPyE ylUC0sJdX1xlWycEF/jsFZO5vqkfzKCxESnDEQfardjjTBV0mci96gM7XxZhgVAT/Twe i5CwtOrAYEobeWYn3spBUf3ikJS/nnqkpFmg23hHYyo7sYZIQkuhT8wc+HwsM71H/nmm gOK98DzzonIVd9yCyMO32ULyHJhW6+Z5IpIcIrLa0/0BY/oiSbDDpDoDohX1mSqpyhUa VolA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=DVbLeirc; 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 b11si13279016ejl.253.2021.06.07.16.07.14; Mon, 07 Jun 2021 16:07:15 -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=DVbLeirc; 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 C754968806D; Tue, 8 Jun 2021 02:05:01 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D3D42687FB2 for ; Tue, 8 Jun 2021 02:04:57 +0300 (EEST) Received: by mail-lf1-f54.google.com with SMTP id p17so28210221lfc.6 for ; Mon, 07 Jun 2021 16:04:57 -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=zdBo2j68x0AXRtlcLkP3QlNN4PLChZM62tX1gLgkF84=; b=DVbLeircXaT8fQhFSiZYHgFtEZw2q80cz1Sq1bG7bzNbVvlz/vhCsKfu6pR6GGODN7 edO6g6iEp24Pb4pR3b4R74UkIme3WMb3xuQB6bT9D2MIwBXWGMiuhosbejy8LcF9I+ub ZxzafIiQNgNgNJhDqAGO79Y4qsyKkFufkhGb7Q4rzwCg7O9qMEjEbFm+sxpzBSRcvCea CCeRw1YH17hw9nf7QdKP+cIcBR1Q+798D5RzN63UcX+TVdouqUJFxh7uojdHTc42Fb5M +cFG8nNRUMkJxKwUBoZ+ocvsC5ONj+qKZk0cv7UAfeIgG1qpdENKoOw4gXEymh6Wm9NL zNuw== 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=zdBo2j68x0AXRtlcLkP3QlNN4PLChZM62tX1gLgkF84=; b=TewhU02C1D8C1dwY4q4KtVeitGXkCItUWK+uvI/QXoReFQQNju4xHUWEekDHksEiJd M5SUn26oNvMrMFVPGYvsec7ExmDPJQVb38rs7QG6YlrAHK7sdHojmZ6O6Ka01nryrRMq WoQnkUugaqpT+y2/9Jevcu48x6pIc3SNL2a1NImEUQcmoj0hsjiJ1Ye50TR5j0Brs6VV ikh1keRTbKf/ondQlw6CJdTqfyAfg+DQZcDgtEk60U3a3BkmE9Bu+oym9TXWFBfcEh31 24UCv0WEcRwDKpIeNQw3Bw4VQU7alf5ngpqkb/l1X63QEXtPuXyEkRB5HAeUxamjytL/ A9xQ== X-Gm-Message-State: AOAM530NeQOWieb11wtPRNuSiDAvCbiQ0WR4Aqf7YuY0U90XzbmlXB8G wikwzj7EaFHBYpo3gFVwdPZAECgFSKqT3Q== X-Received: by 2002:a05:6512:ac9:: with SMTP id n9mr13235641lfu.235.1623107096613; Mon, 07 Jun 2021 16:04:56 -0700 (PDT) Received: from localhost.localdomain (84-217-56-54.customers.ownit.se. [84.217.56.54]) by smtp.gmail.com with ESMTPSA id v9sm1999563ljv.131.2021.06.07.16.04.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Jun 2021 16:04:55 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Tue, 8 Jun 2021 01:04:11 +0200 Message-Id: <20210607230414.612-33-dcnieho@gmail.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20210607230414.612-1-dcnieho@gmail.com> References: <20210607230414.612-1-dcnieho@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 32/35] 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: jzxy10m8Pwqd Signed-off-by: Diederick Niehorster --- configure | 2 + doc/examples/.gitignore | 1 + doc/examples/Makefile | 1 + doc/examples/Makefile.example | 1 + doc/examples/device_get_capabilities.c | 192 +++++++++++++++++++++++++ 5 files changed, 197 insertions(+) create mode 100644 doc/examples/device_get_capabilities.c diff --git a/configure b/configure index 6bfd98b384..31b1790c8d 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..de707bb3ca 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -3,6 +3,7 @@ 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 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..f5909aaa0b --- /dev/null +++ b/doc/examples/device_get_capabilities.c @@ -0,0 +1,192 @@ +/* + * 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 + +void print_option_ranges(enum AVOptionType type, AVOptionRanges* ranges) +{ + 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: ", range->str); + if (!range->is_set) + { + printf(""); + } + else { + uint8_t* buf; + if (av_opt_to_string(range->value_min, type, &buf) < 0) + // fallback to just printing value + printf("%.2f", range->value_min); + else { + printf("%s", (const char*)buf); + av_freep(&buf); + } + if (range->is_range) { + if (av_opt_to_string(range->value_max, type, &buf) < 0) + // fallback to just printing value + printf(" -- %.2f", range->value_max); + else { + printf(" -- %s", (const char*)buf); + av_freep(&buf); + } + } + } + } + printf("\n"); + } +} + + + +int main (int argc, char **argv) +{ + int ret = 0; + const char* device_name = NULL; + const char* 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; + void* caps = NULL; + AVOptionRanges* ranges = NULL; + AVDictionary* options = NULL; + const AVOption* opt = NULL; + + if (argc != 6) { + fprintf(stderr, "usage: %s device_name 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 dshow video=\"Integrated Webcam\" frame_size pixel_format yuyv422", + argv[0], argv[0]); + exit(1); + } + device_name = argv[1]; + input_name = argv[2]; + query_cap = argv[3]; + set_cap_name = argv[4]; + set_cap_value = argv[5]; + + // make sure avdevices can be found among input and output formats + avdevice_register_all(); + // find specified device + fmt = av_find_input_format(device_name); + if (!fmt) { + fprintf(stderr, "Could not find the device '%s'\n",device_name); + ret = AVERROR(EINVAL); + goto end; + } + + // prepare device format context, and set device to query, + ret = avformat_alloc_input_context(&fmt_ctx, fmt, NULL); + if (ret < 0) { + fprintf(stderr, "Cannot allocate input format context\n"); + goto end; + } + fmt_ctx->url = av_strdup("video=Integrated Webcam:audio=OBS-Audio"); + + // prepare query object, setting device options (if any) + ret = avdevice_capabilities_create(&caps, fmt_ctx, &options); + if (ret < 0) { + fprintf(stderr, "avdevice_capabilities_create() failed\n"); + goto end; + } + + // check capability to query, and get info about the return type + opt = av_opt_find(caps, query_cap, NULL, 0, 0); + if (!opt) { + fprintf(stderr, "Capability '%s' you wish to query is not available\n", query_cap); + ret = AVERROR_OPTION_NOT_FOUND; + goto end; + } + + // query the capability without any filter set + ret = av_opt_query_ranges(&ranges, caps, opt->name, AV_OPT_MULTI_COMPONENT_RANGE); + if (ret < 0) { + fprintf(stderr, "av_opt_query_ranges() failed\n"); + goto end; + } + + // print results + print_option_ranges(opt->type, ranges); + 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) { + fprintf(stderr, "av_opt_set() failed\n"); + goto end; + } + + // query again + ret = av_opt_query_ranges(&ranges, caps, opt->name, AV_OPT_MULTI_COMPONENT_RANGE); + if (ret < 0) { + fprintf(stderr, "av_opt_query_ranges() failed\n"); + goto end; + } + + // print results + print_option_ranges(opt->type, ranges); + + +end: + if (ranges) + av_opt_freep_ranges(&ranges); + if (caps) + avdevice_capabilities_free(&caps, fmt_ctx); + + if (fmt_ctx) + avformat_free_context(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; +}