From patchwork Fri Jun 11 20:31:01 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: 28234 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a5e:c91a:0:0:0:0:0 with SMTP id z26csp767118iol; Fri, 11 Jun 2021 13:40:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxhNaTcrYDEAQJ65disYZEqWgpzrdt2VWGpeyQgUIfUXXXcDH2oyzBj05w9urDhFTARmlcl X-Received: by 2002:a17:906:a281:: with SMTP id i1mr5206476ejz.307.1623444012212; Fri, 11 Jun 2021 13:40:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1623444012; cv=none; d=google.com; s=arc-20160816; b=be8Q50y6QoUrM6IJ4E1wjRhKH4hswQvDjpZ96v+ljvkdtaANluRfQx9XVZ4dnbD33C l5fWA0lCCwaztcMTPqXvmQcVhNDjEyaz2FUWMESgJlvCBMHd/xEW/g3JgiF+hBf5ZIu6 d6R1Ezz0huPxIYeWZ2XLdSkmOBtI83npT5ZuwWlHo2ywwIYUI10Be6VNmbZXh5olEDm9 ngSBiNRbeX4E0M6ek/ag0PjPx+nyHzk0C3Fq5c7OKRcrSOVitrw+vLRanTPMMgmtor+u 9WPSlBjErzIYe8yMZHySAAjoJqfigEdh20cqEZB23uS2VSb5tXUzIiM6xXEi9l2a4Sb4 TsDg== 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=ZtELuqM1JV/P9TOpGQgeFKUdz3vzyzR/F2+pHeKPPO0=; b=m1zll49dZH6unYMkc8AkgIEHVRdEEigKYES4yBXeMIa8xvpqYp/bVW5nZGz518+tju 68e/bOtc5E5CgWcO0HJAPYQJ3NdZfHR3g1YLrSC4UEwD3ZvSkGXhZIGGNuRrxsF67O1m yE0gssAPkSQBL+057+OpG5Gcv2CsKqg6kbJPUaturfAd+RS+zk/BpmzVhapSN1eQ/65K +zLTCc1+0YclNCJ/QL7jQLIYWLKXeO2oP/HRe/ZqZscU1d97319wait1b0nummry5qa+ jVExd3aM1bGJEqGFYR2chdlEpjFkOvwR6vJ/j8X7cIMLSFZzgV9WXvehhP66MMJx5axe 7QnQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=aQCUoICb; 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 m29si5840992ejn.735.2021.06.11.13.40.11; Fri, 11 Jun 2021 13:40:12 -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=aQCUoICb; 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 6F86B689965; Fri, 11 Jun 2021 23:40:09 +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 8CABC689965 for ; Fri, 11 Jun 2021 23:40:07 +0300 (EEST) Received: by mail-lf1-f48.google.com with SMTP id m21so10351865lfg.13 for ; Fri, 11 Jun 2021 13:40:07 -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=PLRtbBXXbyB2eKYVrABu+l9I4Mlyat1Ix0fjXHhbjQQ=; b=aQCUoICb8TztxKi3c3eZ2FRF/si/sqSP7cPIHKLVmimrzgWWEtmy18+1ws19Z+y+ri LGvgCW7eLeqP3x/APBuIbsrNYTOMc7p4zjsRunIK/96z9ZQuUoByzBfBCovtIaXZgkVS 7Ldp+3xmjHzGsSgD+aKfNWtOLQY83ueVygqwHWYyiNtOXDd70z6/UpiiIWUhF/HbJYN2 WTMnlUh4UoOCv7EHlmgx+XxsZXOJlGiejjKTND+cky+R0AOAAm6OPloe5XgErvpZ5N6a vs7gN8YgGp8ktKnIgR8/QB6JeGFAwWE2YC0bmk1EIthmnqRyI4MaFdvoI8qkhdHiFxGJ Mpbw== 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=PLRtbBXXbyB2eKYVrABu+l9I4Mlyat1Ix0fjXHhbjQQ=; b=WgNL1BQbbLnYZdZ7/P2FE4WeaGRWUyxcgvEAwE2c+xTAxcg09FHR43aOeI/1pDLROu 71oWhDIzWQSI+IYN/UE8e02l8m305uePGSXi4eBuhP3j/23q1H3JAQWl3h/A9+CkYbR4 JZudtcoSmwUwjouqx1Dhgt1RHDKTB+20ciyYwwtyPxoh9kbWJCxQgVdHGA7N76D6KO// SIS6PK0E+hWv/WhqOM7TbHbDzg4AuDlgPXwngLwUI6rmHo9tNVSKGgausVRMsibvMPay dYK/fJNsalKcySOlRYtUr0CLhGvMjYYmVGXt6TEYLcMIiy+sDkuBSbYVsSc1IAW8cD16 z1mg== X-Gm-Message-State: AOAM530Nm4840Jsc/Zwcms886uNpYcg5AwLDckZVbWZGXxAG5KP4l0z8 48EXo8LkIT6PqRYB7lDCI53hJL1KXwz5Eg== X-Received: by 2002:a05:6512:24a:: with SMTP id b10mr3690637lfo.136.1623444006489; Fri, 11 Jun 2021 13:40:06 -0700 (PDT) Received: from localhost.localdomain ([196.196.203.214]) by smtp.gmail.com with ESMTPSA id a13sm847342ljb.47.2021.06.11.13.40.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Jun 2021 13:40:06 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Fri, 11 Jun 2021 22:31:01 +0200 Message-Id: <20210611203104.1692-31-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 30/33] doc/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: USg0YxvXdtUP 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 | 190 +++++++++++++++++++++++++ 5 files changed, 195 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..46a7d1a86f --- /dev/null +++ b/doc/examples/device_get_capabilities.c @@ -0,0 +1,190 @@ +/* + * 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->value_min > range->value_max) { + printf(""); + } else { + uint8_t* buf; + if (av_opt_print_num(type, range->value_min, &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_print_num(type, range->value_max, &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; + AVDeviceCapabilitiesQuery* 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; +}