From patchwork Thu Jun 3 22:45:52 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: 28070 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:b214:0:0:0:0:0 with SMTP id b20csp538176iof; Thu, 3 Jun 2021 15:47:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyJUcJtjBcmTvgMJgutRsBUEqXKziQNxQSVM6pFOB8fKxGof84d6I+Ym4HK+lr3TiQu5TxZ X-Received: by 2002:a17:907:1112:: with SMTP id qu18mr1300313ejb.511.1622760429440; Thu, 03 Jun 2021 15:47:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622760429; cv=none; d=google.com; s=arc-20160816; b=CdGlGYxyfRRaITAn5su1XeIzSkoGBSii3UJ7t6a6d9zvlbfLxyErOETHWCb/l46QEy WeQWKGbcqzZz/R7gWgmXfVNqTngtWig/WsZHr2jksx+EN2OnMcrgWWh8rRFO6j4iFLgg vIZ5vFfNv3NQm3brOiw8p42xI/3svwoA31lNgncDk9UJ/7o3m9P3CmFYh9r4MVcELkO0 8SBVxcT6OVumxy9EuWAG9apOLVHaXgTlFIP3RQ10Gxh40WJT+9kxWoDWlOlwNMUB+1ez GwOPpsQhC/2hZRDPkp53qlZO/OGK9DXqfqN6xZ4TWz0M83Z1KwlOj6f6omCNXFLxSHA5 WIvQ== 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=NsuSZ7K5/KEBF9r2YQSCCbrXj9ngoT/VrJB7h+K2WPJNj2rWTeH+/f3Mk/H+/xpvBX WaEqnD8m3IDOaTLDXmWknr1Ktn9CpVKnHSBgS9CUvcZn6ZYuMTj2pfsPj7Fl9aHKXeMO CjAsfVvr0LL0W1qvCfa9ZZhZ3DHj9cVWdq5x3MSB3FywdFH1cYsSyZRtDvK1HkIljB8l CMNDRCy833lhYz7g/XoZJEBSjao8MBy1/vkKIhoL2TjTIjJQ1UIkbFamtbV/F3H/sQ8O k9xK0rRM+d5UQxq//NTZODfIel5Msf8NQcWjkXxI8/u5JbGJrrEjqsUkUynNic0yPBBh xdWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=ZvV4wIkN; 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 u10si3183515ejf.585.2021.06.03.15.47.09; Thu, 03 Jun 2021 15:47:09 -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=ZvV4wIkN; 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 9B62F689829; Fri, 4 Jun 2021 01:46:33 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f169.google.com (mail-lj1-f169.google.com [209.85.208.169]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5DBBA68A2C3 for ; Fri, 4 Jun 2021 01:46:26 +0300 (EEST) Received: by mail-lj1-f169.google.com with SMTP id p20so9103223ljj.8 for ; Thu, 03 Jun 2021 15:46:26 -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=ZvV4wIkNCeV51fw7vP2cpeJiCytEJEDSi1gRhIt1eRm8a4NqwaAq+eDl7tPe+ND3TT aHtGX3h7lqvYwn7qT3cu11H8yc6yqYOdo4TwJNTnMQTvRcpygvSJGbgSZLEQ8xwWretj IkxQKQJclPV8JEFPjaqS1Xl13B9F/GbWPFuRZc9GJ4HVvFAYmPMkLGHEzALyq4BGfVk4 P7Al7liFc6n09DPE7BtKh8uMbGXg5+qJFcGPeEadv/Ya2mFxXAP+NESnJa7neBmxPc+8 hbekUdoBlwKM3eng/1wkLTl4YF9173ft9A5nMIfqAkQlmpMEntS0vk/zVgTfzW3iOpF+ zPZQ== 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=XvlfEFBBmEnVTRCg5wDhVjn2IaW9dwoSlPo13FC1cTXamNz1QinYK8XBRxrdXGUf0h Pbb4MgC0WCTojvvlTVoN7ACXMEkISQ2kO8Dp1i4OaDEts3Qie0hj0JYzsakRuxnIwchf Xc9q8iviBfC/NECwEIIgy0iZyMzqtXh+lnHiuOM0ulDlXYy2giWkOm6f22lGxAwGIdfv QTn9C6PzyisMCW7Sse5btd/VB/31hc9b6B21MwnxeDqmfPAo1AlZzmTVmjK1LEaR9muA ZZzuVImxL9QZ7IcklPsFhw/n3h9oVI+emqtZCemEYRBaGsMwrjvJKuAdD6uPNztaO6Mo oSvg== X-Gm-Message-State: AOAM530jWatBUntr3aW7o6I8dEkFlJ4MQWUP2f6mO7sekHtvIs4C211O iAv4DUpGSfXpNiNQvOOM2P4pzUwefJQ= X-Received: by 2002:a05:651c:306:: with SMTP id a6mr1145847ljp.285.1622760385278; Thu, 03 Jun 2021 15:46:25 -0700 (PDT) Received: from localhost.localdomain (84-217-56-54.customers.ownit.se. [84.217.56.54]) by smtp.gmail.com with ESMTPSA id t15sm82373lfp.176.2021.06.03.15.46.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 15:46:24 -0700 (PDT) From: Diederick Niehorster To: ffmpeg-devel@ffmpeg.org Date: Fri, 4 Jun 2021 00:45:52 +0200 Message-Id: <20210603224552.1218-5-dcnieho@gmail.com> X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20210603224552.1218-1-dcnieho@gmail.com> References: <20210603224552.1218-1-dcnieho@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 4/4] 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: gDf0lWaHqAxx 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; +}