From patchwork Thu May 23 09:03:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 49171 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:542:0:b0:460:55fa:d5ed with SMTP id 63csp895419vqf; Thu, 23 May 2024 02:04:01 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWRApUYAyFnY66nioPVhGYNlqSAicfB9M3eiqVV0zFpMiYhOlo0Bhir7s0jIW1qXtq3iJ2Flh6D2TBvEQg0PDk5ZyPv/6Q0cfjA7w== X-Google-Smtp-Source: AGHT+IENofMUE628Y+yjacKF9KDFukaDxTbN1OQM2mwCoBIZv/bJ5j3CKbcSDMVFkw8zNipBgk66 X-Received: by 2002:a17:906:1608:b0:a59:b02a:90dc with SMTP id a640c23a62f3a-a6228198c19mr268434166b.54.1716455041107; Thu, 23 May 2024 02:04:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1716455041; cv=none; d=google.com; s=arc-20160816; b=cIFgMG/A1QLylsh7roEj2tNHJBv9fi5AAL54dM7Kw33xEaA1jlahlg5qUtDzyzpAs8 7cf4o0srA4R2e6ViI2CQZjeRX5g2WVyeCXpfpHumKpRgjiiga4z3cun62c3PATOoDnQZ 4h5U69oicpeT/d7bPF8fad8h3aCIqogM8oOZtHVpHhNyk4AVm7YutrJRZivTOMFeonfI 7vnxI9ehYEYRbpYnWWyhh9t/tLsDX1CeLMoa7RLKrTzE0dks1Gudp67VoQoOO6q9djaW OCFYLz/4OBlPGrSEz8CkEOwkAtjHYGPbrNG7LEf8Jg0ssn7DpPoeguHJqh5GVTovBE5z f9Yg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=jOkPWPOMTfIOvfsTNps9/EOrERaRFd4KezyF6BS/O94=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=lIlSVf13qkEO3kUJXFMn1prZ2GPZNsaIGHDuJPqNGkXPV643sqVgoRxbYDkOp6MWEB 5AKx2aoh0rZ5q+tgKcg30LZheh1q6WJkSURTJ242xN0+2Ix1Ca42kXqT2KVKHjgvBLRf jaTl4URn8qrXWQU2tCwvsZyb7snQx8Q+Br3SU8Q0XG/NxcFXheomudkWLa7j4uPqkOGo j4fAONpQprdIwZ/p3hSt9blLbjYbNA2OeRaQrYMgxp5zz404Op7P+VpYLGWrXKxvM2RT ea0y1CrktBFq4cpiYPiVDGgllr5+zx4hj4ujg1uj4AzZO/Ujax8gqZBfd71Stjlf8whk A1bw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=O69aKUSR; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id a640c23a62f3a-a5a179461a2si1612148866b.106.2024.05.23.02.04.00; Thu, 23 May 2024 02:04:01 -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=@khirnov.net header.s=mail header.b=O69aKUSR; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BD1BC68D428; Thu, 23 May 2024 12:03:56 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A478168D159 for ; Thu, 23 May 2024 12:03:49 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=O69aKUSR; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id B0A0A4DC0 for ; Thu, 23 May 2024 11:03:48 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id qJtudfc0qRgo for ; Thu, 23 May 2024 11:03:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1716455027; bh=DOIEvka74dcH5QghY6jZSAluepbNH6gnhlZBGHkU9CA=; h=From:To:Subject:Date:From; b=O69aKUSR5Jcu8/R8eHQuUKoTgElRrbC0LTYxhoUSeaAglhog2scCPF7/5lMtt6Oyr DI8XnZ8jUVjm3BcBRF3TNxVLbNT7KX8bpIzcqtssB412OWD3VgXjWdn/bsOYp+gplL HP6t5LX9VQ0wqYAqp43joV95YglVggIL7UgeASCvbUMyW0fg1OJmUV8yrER3ZvEJO1 ibXLLWMZrw8TqtyS3b1tvenCXx+v1jkfOUaHuhf62nn6TIssMK0e6JDKUSdyXh+Nun oKkjf6eIO2G+OW8xeNyV3by+ykjIpXF2MRoFpbhYuxKJPAMDRvcUbkb1LkqN+FPX3l ByoUbQ3xlKB0w== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 399764D58 for ; Thu, 23 May 2024 11:03:47 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id CC59D3A0231 for ; Thu, 23 May 2024 11:03:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 May 2024 11:03:36 +0200 Message-ID: <20240523090339.4228-1-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/4] lavc/qsvenc: rename the skip_frame private option to qsv_skip_frame 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: uWWmV0BKJW3+ It conflicts with the AVCodecContext option of the same name. --- libavcodec/qsvenc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index e3eb083746..d69dd19049 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -139,7 +139,7 @@ { "avbr_convergence", "Convergence of the AVBR ratecontrol (unit of 100 frames)", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE }, #define QSV_OPTION_SKIP_FRAME \ -{ "skip_frame", "Allow frame skipping", OFFSET(qsv.skip_frame), AV_OPT_TYPE_INT, { .i64 = MFX_SKIPFRAME_NO_SKIP }, \ +{ "qsv_skip_frame", "Allow frame skipping", OFFSET(qsv.skip_frame), AV_OPT_TYPE_INT, { .i64 = MFX_SKIPFRAME_NO_SKIP }, \ MFX_SKIPFRAME_NO_SKIP, MFX_SKIPFRAME_BRC_ONLY, VE, .unit = "skip_frame" }, \ { "no_skip", "Frame skipping is disabled", \ 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_NO_SKIP }, .flags = VE, .unit = "skip_frame" }, \ From patchwork Thu May 23 09:03:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 49174 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:542:0:b0:460:55fa:d5ed with SMTP id 63csp895761vqf; Thu, 23 May 2024 02:04:34 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX/242pP+qZcZPVJ5rPy0CZdCDsfsnMXTznK8UL2A+V60cnTgXWCzrlnUMTJMoKeHQqpgA35Dj3Uxm/+6LqamzMMIvMUYKowsVZUQ== X-Google-Smtp-Source: AGHT+IFBZrcfbhg+UgAy7f92a0PQEWAoKVAJGIrTztBuBAvlbPjppQmGSR1XOH7pVyNylWz8JqjX X-Received: by 2002:ac2:5930:0:b0:523:89b0:9b64 with SMTP id 2adb3069b0e04-526bebb45afmr2365618e87.7.1716455074357; Thu, 23 May 2024 02:04:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1716455074; cv=none; d=google.com; s=arc-20160816; b=sUHd3tgNW3RcNh8Apz3B83LK+HW6edGOa2nbJ2+AhHxedyH8MBUnRY7gp8/fm4trSL dv9Cutet5EAXXnH+wqR7mvCo/D3NMnpAcTsE7sI02LBRqHGaYu/73oDJh9w9TAELXX9v mPIdLRnqFKsYCHGNPqm3YJdNU64DIFbyxfbt5/YnY2N0s38kilTAx/OMs2+B07hVu/Xf d5unxIzwHqMC7DscvDKxIOSeAZHAlCS0H8D9hqyb1SVC/09xESVhrAC6UE4iX6Gm1pmg V7Did9WKZWag/Fe0fJlAcBearpAGaDzpSoFkZopX4j0Tq9C7vl4vCqFgW+glNoipFa/c hbEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding: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=a+nx8l3CAPN30CdzJeT1g4xsbmjz62YcK2OB87LXGaA=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=eqkZYwqdrSN04/4Wzh/TN5ekLayk5ZHVpWS2GK2P0bmfPHy94HsteRMXVv1PcZ6YOk m+XK0gnDmq/upAO77zuOgwmE5XHM3OyZY3K8cy5U6sZijUUtoP2j3bLQQBSFj98Isz6A mzH3KVr6UuF5dXqVOWVAID9KKR4VVgSRYkIGVuVnTO1H/RLgr55rFxk7iy5hA3QWQpKV /NhvNa0T3g2KOWOFlaVfVMdtw0hhaOIPNnxw65Ywxm0fv97ThNulLCQDPaDpu6SM8Ipm O6pnnCUBlhYN+INrBFdeDH6P6WWFKxLcgQY5UM7CW4v0XScxFT+ZG0TgbvRLP1VINz7J xATg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=juW2hPZF; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id a640c23a62f3a-a5a17ba5d70si1555202866b.659.2024.05.23.02.04.34; Thu, 23 May 2024 02:04:34 -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=@khirnov.net header.s=mail header.b=juW2hPZF; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BC3E668D485; Thu, 23 May 2024 12:03:59 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0154068D1C4 for ; Thu, 23 May 2024 12:03:49 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=juW2hPZF; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 9E7AD4D58 for ; Thu, 23 May 2024 11:03:49 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id PV4xChiQgbuZ for ; Thu, 23 May 2024 11:03:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1716455027; bh=e0o/Ez/HZ+zhaGSIk2DCo9ipdPA2h8ACo8dIbBuqs7o=; h=From:To:Subject:Date:In-Reply-To:References:From; b=juW2hPZFZ2Ab7xZASDXFZtogBlJWYcbOOJsRi2pCehrAAD7rO8ZwK0613yUp+RbGN NfZFqIYD6zhpybzcN55v8VzH0TaJlurJp0F/mpbSn0bSxi0p6Cvnc9zS1KRYdoDhzB a4M5Q5UwG0dM4zP8hhyLohB9jN+QflwIxg+Y22nGHmm2Vwo2RAQyo4QYdz+aHrctst kthRWK68GDSnL3nVulm9NQsUriyIVcf80zpDNZF8XkW+c1vm0o+XvlP6qo6Zmo49S3 5eql7nSKL4ICc5hOvaEsrD27ywz2JtN+cYsmPjZ4yuAkNE34P5CCfAewOENQRWdOyt FIJJs2/TAdXgA== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 3AE804D76 for ; Thu, 23 May 2024 11:03:47 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id DA5713A0423 for ; Thu, 23 May 2024 11:03:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 May 2024 11:03:37 +0200 Message-ID: <20240523090339.4228-2-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240523090339.4228-1-anton@khirnov.net> References: <20240523090339.4228-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/4] fftools/ffmpeg: rewrite checking whether codec AVOptions have been used 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 0vFTCP16aASq Share the code between encoding and decoding. Instead of checking every stream's options dictionary (which is also used for other purposes), track all used options in a dedicated dictionary. --- fftools/cmdutils.c | 17 ++++++++---- fftools/cmdutils.h | 4 ++- fftools/ffmpeg.c | 49 ++++++++++++++++++++++++++++++++++ fftools/ffmpeg.h | 3 ++- fftools/ffmpeg_demux.c | 50 ++++++++--------------------------- fftools/ffmpeg_mux.c | 1 + fftools/ffmpeg_mux.h | 3 +++ fftools/ffmpeg_mux_init.c | 55 +++++---------------------------------- fftools/ffmpeg_opt.c | 18 ------------- fftools/ffplay.c | 2 +- fftools/ffprobe.c | 2 +- 11 files changed, 89 insertions(+), 115 deletions(-) diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index a8f5c6d89b..265ce5c04c 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -986,7 +986,7 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec) int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, AVFormatContext *s, AVStream *st, const AVCodec *codec, - AVDictionary **dst) + AVDictionary **dst, AVDictionary **opts_used) { AVDictionary *ret = NULL; const AVDictionaryEntry *t = NULL; @@ -1013,6 +1013,7 @@ int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, while (t = av_dict_iterate(opts, t)) { const AVClass *priv_class; char *p = strchr(t->key, ':'); + int used = 0; /* check stream specification in opt name */ if (p) { @@ -1030,15 +1031,21 @@ int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, !codec || ((priv_class = codec->priv_class) && av_opt_find(&priv_class, t->key, NULL, flags, - AV_OPT_SEARCH_FAKE_OBJ))) + AV_OPT_SEARCH_FAKE_OBJ))) { av_dict_set(&ret, t->key, t->value, 0); - else if (t->key[0] == prefix && + used = 1; + } else if (t->key[0] == prefix && av_opt_find(&cc, t->key + 1, NULL, flags, - AV_OPT_SEARCH_FAKE_OBJ)) + AV_OPT_SEARCH_FAKE_OBJ)) { av_dict_set(&ret, t->key + 1, t->value, 0); + used = 1; + } if (p) *p = ':'; + + if (used && opts_used) + av_dict_set(opts_used, t->key, "", 0); } *dst = ret; @@ -1063,7 +1070,7 @@ int setup_find_stream_info_opts(AVFormatContext *s, for (int i = 0; i < s->nb_streams; i++) { ret = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id, - s, s->streams[i], NULL, &opts[i]); + s, s->streams[i], NULL, &opts[i], NULL); if (ret < 0) goto fail; } diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h index d0c773663b..5966501d84 100644 --- a/fftools/cmdutils.h +++ b/fftools/cmdutils.h @@ -371,11 +371,13 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec); * @param codec The particular codec for which the options should be filtered. * If null, the default one is looked up according to the codec id. * @param dst a pointer to the created dictionary + * @param opts_used if non-NULL, every option stored in dst is also stored here, + * with specifiers preserved * @return a non-negative number on success, a negative error code on failure */ int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, AVFormatContext *s, AVStream *st, const AVCodec *codec, - AVDictionary **dst); + AVDictionary **dst, AVDictionary **opts_used); /** * Setup AVCodecContext options for avformat_find_stream_info(). diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index c86fd5065e..5e27f073aa 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -493,6 +493,55 @@ int check_avoptions(AVDictionary *m) return 0; } +int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used, + void *logctx, int decode) +{ + const AVClass *class = avcodec_get_class(); + const AVClass *fclass = avformat_get_class(); + + const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM : + AV_OPT_FLAG_ENCODING_PARAM; + const AVDictionaryEntry *e = NULL; + + while ((e = av_dict_iterate(opts, e))) { + const AVOption *option, *foption; + char *optname, *p; + + optname = av_strdup(e->key); + if (!optname) + return AVERROR(ENOMEM); + + p = strchr(optname, ':'); + if (p) + *p = 0; + + option = av_opt_find(&class, optname, NULL, 0, + AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); + foption = av_opt_find(&fclass, optname, NULL, 0, + AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); + av_freep(&optname); + if (!option || foption) + continue; + + if (!(option->flags & flag)) { + av_log(logctx, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a %s " + "option.\n", option->name, option->help ? option->help : "", + decode ? "decoding" : "encoding"); + return AVERROR(EINVAL); + } + + if (!av_dict_get(opts_used, e->key, NULL, 0)) { + av_log(logctx, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used " + "for any stream. The most likely reason is either wrong type " + "(e.g. a video option with no video streams) or that it is a " + "private option of some decoder which was not actually used " + "for any stream.\n", option->name, option->help ? option->help : ""); + } + } + + return 0; +} + void update_benchmark(const char *fmt, ...) { if (do_benchmark_all) { diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 885a7c0c10..9cab8148ca 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -712,9 +712,10 @@ void show_usage(void); void remove_avoptions(AVDictionary **a, AVDictionary *b); int check_avoptions(AVDictionary *m); +int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used, + void *logctx, int decode); int assert_file_overwrite(const char *filename); -AVDictionary *strip_specifiers(const AVDictionary *dict); int find_codec(void *logctx, const char *name, enum AVMediaType type, int encoder, const AVCodec **codec); int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global); diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index cba63dab5f..52e427ea49 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -1207,7 +1207,7 @@ static DemuxStream *demux_stream_alloc(Demuxer *d, AVStream *st) return ds; } -static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st) +static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictionary **opts_used) { AVFormatContext *ic = d->f.ctx; AVCodecParameters *par = st->codecpar; @@ -1334,7 +1334,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st) if (ist->dec) { ret = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, - ic, st, ist->dec, &ds->decoder_opts); + ic, st, ist->dec, &ds->decoder_opts, opts_used); if (ret < 0) return ret; } @@ -1532,8 +1532,7 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch) const AVInputFormat *file_iformat = NULL; int err, i, ret = 0; int64_t timestamp; - AVDictionary *unused_opts = NULL; - const AVDictionaryEntry *e = NULL; + AVDictionary *opts_used = NULL; const char* video_codec_name = NULL; const char* audio_codec_name = NULL; const char* subtitle_codec_name = NULL; @@ -1805,48 +1804,21 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch) /* Add all the streams from the given input file to the demuxer */ for (int i = 0; i < ic->nb_streams; i++) { - ret = ist_add(o, d, ic->streams[i]); - if (ret < 0) + ret = ist_add(o, d, ic->streams[i], &opts_used); + if (ret < 0) { + av_dict_free(&opts_used); return ret; + } } /* dump the file content */ av_dump_format(ic, f->index, filename, 0); /* check if all codec options have been used */ - unused_opts = strip_specifiers(o->g->codec_opts); - for (i = 0; i < f->nb_streams; i++) { - DemuxStream *ds = ds_from_ist(f->streams[i]); - e = NULL; - while ((e = av_dict_iterate(ds->decoder_opts, e))) - av_dict_set(&unused_opts, e->key, NULL, 0); - } - - e = NULL; - while ((e = av_dict_iterate(unused_opts, e))) { - const AVClass *class = avcodec_get_class(); - const AVOption *option = av_opt_find(&class, e->key, NULL, 0, - AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); - const AVClass *fclass = avformat_get_class(); - const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0, - AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); - if (!option || foption) - continue; - - - if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) { - av_log(d, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a decoding " - "option.\n", e->key, option->help ? option->help : ""); - return AVERROR(EINVAL); - } - - av_log(d, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used " - "for any stream. The most likely reason is either wrong type " - "(e.g. a video option with no video streams) or that it is a " - "private option of some decoder which was not actually used " - "for any stream.\n", e->key, option->help ? option->help : ""); - } - av_dict_free(&unused_opts); + ret = check_avoptions_used(o->g->codec_opts, opts_used, d, 1); + av_dict_free(&opts_used); + if (ret < 0) + return ret; for (i = 0; i < o->dump_attachment.nb_opt; i++) { int j; diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index a1583edd61..055e2f3678 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -865,6 +865,7 @@ void of_free(OutputFile **pof) av_freep(&mux->sch_stream_idx); av_dict_free(&mux->opts); + av_dict_free(&mux->enc_opts_used); av_packet_free(&mux->sq_pkt); diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h index 1e9ea35412..1c1b407484 100644 --- a/fftools/ffmpeg_mux.h +++ b/fftools/ffmpeg_mux.h @@ -99,6 +99,9 @@ typedef struct Muxer { AVDictionary *opts; + // used to validate that all encoder avoptions have been actually used + AVDictionary *enc_opts_used; + /* filesize limit expressed in bytes */ int64_t limit_filesize; atomic_int_least64_t last_filesize; diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 8797265145..41afe8259d 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -1160,7 +1160,8 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, const char *enc_time_base = NULL; ret = filter_codec_opts(o->g->codec_opts, enc->codec_id, - oc, st, enc->codec, &ost->encoder_opts); + oc, st, enc->codec, &ost->encoder_opts, + &mux->enc_opts_used); if (ret < 0) return ret; @@ -1265,7 +1266,8 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, } } else { ret = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, - NULL, &ost->encoder_opts); + NULL, &ost->encoder_opts, + &mux->enc_opts_used); if (ret < 0) return ret; } @@ -3114,52 +3116,6 @@ static int process_forced_keyframes(Muxer *mux, const OptionsContext *o) return 0; } -static int validate_enc_avopt(Muxer *mux, const AVDictionary *codec_avopt) -{ - const AVClass *class = avcodec_get_class(); - const AVClass *fclass = avformat_get_class(); - const OutputFile *of = &mux->of; - - AVDictionary *unused_opts; - const AVDictionaryEntry *e; - - unused_opts = strip_specifiers(codec_avopt); - for (int i = 0; i < of->nb_streams; i++) { - e = NULL; - while ((e = av_dict_iterate(of->streams[i]->encoder_opts, e))) - av_dict_set(&unused_opts, e->key, NULL, 0); - } - - e = NULL; - while ((e = av_dict_iterate(unused_opts, e))) { - const AVOption *option = av_opt_find(&class, e->key, NULL, 0, - AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); - const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0, - AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ); - if (!option || foption) - continue; - - if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) { - av_log(mux, AV_LOG_ERROR, "Codec AVOption %s (%s) is not an " - "encoding option.\n", e->key, option->help ? option->help : ""); - return AVERROR(EINVAL); - } - - // gop_timecode is injected by generic code but not always used - if (!strcmp(e->key, "gop_timecode")) - continue; - - av_log(mux, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used " - "for any stream. The most likely reason is either wrong type " - "(e.g. a video option with no video streams) or that it is a " - "private option of some encoder which was not actually used for " - "any stream.\n", e->key, option->help ? option->help : ""); - } - av_dict_free(&unused_opts); - - return 0; -} - static const char *output_file_item_name(void *obj) { const Muxer *mux = obj; @@ -3267,7 +3223,8 @@ int of_open(const OptionsContext *o, const char *filename, Scheduler *sch) return err; /* check if all codec options have been used */ - err = validate_enc_avopt(mux, o->g->codec_opts); + err = check_avoptions_used(o->g->codec_opts, mux->enc_opts_used, mux, 0); + av_dict_free(&mux->enc_opts_used); if (err < 0) return err; diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 910e4a336b..b256fc9372 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -151,24 +151,6 @@ static int show_hwaccels(void *optctx, const char *opt, const char *arg) return 0; } -/* return a copy of the input with the stream specifiers removed from the keys */ -AVDictionary *strip_specifiers(const AVDictionary *dict) -{ - const AVDictionaryEntry *e = NULL; - AVDictionary *ret = NULL; - - while ((e = av_dict_iterate(dict, e))) { - char *p = strchr(e->key, ':'); - - if (p) - *p = 0; - av_dict_set(&ret, e->key, e->value, 0); - if (p) - *p = ':'; - } - return ret; -} - const char *opt_match_per_type_str(const SpecifierOptList *sol, char mediatype) { diff --git a/fftools/ffplay.c b/fftools/ffplay.c index 5a66bfa38d..14999349ac 100644 --- a/fftools/ffplay.c +++ b/fftools/ffplay.c @@ -2674,7 +2674,7 @@ static int stream_component_open(VideoState *is, int stream_index) avctx->flags2 |= AV_CODEC_FLAG2_FAST; ret = filter_codec_opts(codec_opts, avctx->codec_id, ic, - ic->streams[stream_index], codec, &opts); + ic->streams[stream_index], codec, &opts, NULL); if (ret < 0) goto fail; diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 2d38e5dfdc..ce1b0fb6ba 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -3922,7 +3922,7 @@ static int open_input_file(InputFile *ifile, const char *filename, AVDictionary *opts; err = filter_codec_opts(codec_opts, stream->codecpar->codec_id, - fmt_ctx, stream, codec, &opts); + fmt_ctx, stream, codec, &opts, NULL); if (err < 0) exit(1); From patchwork Thu May 23 09:03:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 49172 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:542:0:b0:460:55fa:d5ed with SMTP id 63csp895512vqf; Thu, 23 May 2024 02:04:12 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXxiyRbfKvYKWidQZW+EUqzC4dBqEGIFWJc9xJOT07q9cYKbauIkPb7WC9/giFsa4nrUE0y+4YbghnyrxSrPbERCmBkcy8UnWjQlg== X-Google-Smtp-Source: AGHT+IE+MxoYI2RuwESqOFFIo0Uz6+o7wWkDbPB3CdRdAXGECRA5+aC+cVFd2FCqFSBgU51C67ny X-Received: by 2002:a05:6402:3550:b0:572:d841:1179 with SMTP id 4fb4d7f45d1cf-57832cbc6bdmr2956700a12.3.1716455051887; Thu, 23 May 2024 02:04:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1716455051; cv=none; d=google.com; s=arc-20160816; b=c33anwxz+DuzQXbXXdgqxHg5usYVfCIcE47wwL1uAIBROkHtRAb794ifLL5Lwwbla+ ZEECDZTrPS5reNigzGifb6s0YgO7jDxLstPsmMkGeNdHSU5slj6T5fZnj0yXDyTWEqru f5/gF1BNXOnM1wIiRmzzOiJVhQKNuDg2mDMbG5TN/k5znHLpbZ1THbT/q45EpRMt1wol 3X62q5rTZ2dqWg9z0ol6ONN8gUlY0Hr5PVmPFq4gnI4YZAvQkwi4m0obKUiWX26V3/yO im/QvD/tqGS6/IvmGCRtKQ73avexASd4+6Tt5GRjqcQb/BlmCw0aqRBIUuMS/BTxzxRv aw7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding: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=MxIECiLy7iD/Ik1Ik4hlYVqC2NnIIQ6nlUOx+ZtGOfc=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=jRjfQKPdCUx9BfNgYOZaj63hsSlYLe2vO1NGQdsGlfp1HCtAV7WGJRU+pepz2Ypnsd voevfntl8nqOT4/gv4Op8rQ7sUPLN6zOWF25cCf3BOIo0KTe611wPIZDnRFZJtgjIUpd KHOwj2U7qDD10IaIK/oq8lEmASNT2+mJr8pfI0F+Jx1qf3sHyKaduknGPbJo0jcCIGQz APl+SKujSzZwAI2szLGrQ84s4uDq1g2emvy3bcmbrBIZRZqDVre69l9g3Ky9UWsv3IVw 3GoaDPMiFuFLFVafznm+f+1M9V0zMNuTY1bLxQpzqujNSW3qaaMY6YxzRx//+BYbZk82 nGsA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=r+ZSdD4P; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 4fb4d7f45d1cf-5733beac5a9si16349607a12.86.2024.05.23.02.04.11; Thu, 23 May 2024 02:04:11 -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=@khirnov.net header.s=mail header.b=r+ZSdD4P; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C999A68D438; Thu, 23 May 2024 12:03:57 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A7B7668D1C4 for ; Thu, 23 May 2024 12:03:49 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=r+ZSdD4P; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id B3EC44DC4 for ; Thu, 23 May 2024 11:03:48 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id rMoHPf9r2U5F for ; Thu, 23 May 2024 11:03:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1716455027; bh=FFabwziLzaO10vf4oUQbXD78iNzOmWYnIy9cnUXwvdg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=r+ZSdD4PHs/Lf8HB1Hn+VBuwJxhhtLzcW3QYUnnGy4yHM3UksLrjt7eorb107P34N 8vkpjFVsRpt+jn72UOxP9J4a5073jpHaLnXu0F4sKmaXiyIQ1TrOCRxkCKOBJzutXL 7nNdI/CIo+gIYO/4a5rDRYBieRtVLHO4pydL21otv2VKAADErUKQD/JsFhF2w9h2wC 0GWY2MUAiiMJDcVu/8cxcavRpbhFLuG3S4x66C4llxTGGJUxl94ouZAkqpznlZce+b 3/euYV7PkwTHQBeMNlAneKkifVn3be/bZrhK9G+cEMYFWWvee7vfdq5CTSQVzfPUjv 9CWKL0EfBd6tA== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 3D2F04D7E for ; Thu, 23 May 2024 11:03:47 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id E637D3A0451 for ; Thu, 23 May 2024 11:03:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 May 2024 11:03:38 +0200 Message-ID: <20240523090339.4228-3-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240523090339.4228-1-anton@khirnov.net> References: <20240523090339.4228-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/4] fftools/ffmpeg_mux_init: apply encoder options manually 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: HOn3DQu0pO1x Do not pass an options dictionary to the avcodec_open2() in enc_open(). This is cleaner and more robust, as previously various bits of code would try to interpret the contents of the options dictionary, with varying degrees of correctness. Now they can just access the encoder AVCodecContext directly. Cf. 372c78dd42f2b1ca743473b9c32fad71c65919e0 - analogous change for decoding. A non-progressive field order is now written on the container level in interlaced ProRes encoding tests. --- fftools/ffmpeg_enc.c | 18 ++---- fftools/ffmpeg_mux_init.c | 66 +++++++++++---------- tests/ref/vsynth/vsynth1-prores_444_int | 2 +- tests/ref/vsynth/vsynth1-prores_int | 2 +- tests/ref/vsynth/vsynth2-prores_444_int | 2 +- tests/ref/vsynth/vsynth2-prores_int | 2 +- tests/ref/vsynth/vsynth3-prores_444_int | 2 +- tests/ref/vsynth/vsynth3-prores_int | 2 +- tests/ref/vsynth/vsynth_lena-prores_444_int | 2 +- tests/ref/vsynth/vsynth_lena-prores_int | 2 +- 10 files changed, 47 insertions(+), 53 deletions(-) diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c index 618ba193ff..029980063d 100644 --- a/fftools/ffmpeg_enc.c +++ b/fftools/ffmpeg_enc.c @@ -307,16 +307,10 @@ int enc_open(void *opaque, const AVFrame *frame) if (ost->bitexact) enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT; - if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0)) - av_dict_set(&ost->encoder_opts, "threads", "auto", 0); + if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) + enc_ctx->flags |= AV_CODEC_FLAG_COPY_OPAQUE; - if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) { - ret = av_dict_set(&ost->encoder_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY); - if (ret < 0) - return ret; - } - - av_dict_set(&ost->encoder_opts, "flags", "+frame_duration", AV_DICT_MULTIKEY); + enc_ctx->flags |= AV_CODEC_FLAG_FRAME_DURATION; ret = hw_device_setup_for_encode(ost, frame ? frame->hw_frames_ctx : NULL); if (ret < 0) { @@ -325,7 +319,7 @@ int enc_open(void *opaque, const AVFrame *frame) return ret; } - if ((ret = avcodec_open2(ost->enc_ctx, enc, &ost->encoder_opts)) < 0) { + if ((ret = avcodec_open2(ost->enc_ctx, enc, NULL)) < 0) { if (ret != AVERROR_EXPERIMENTAL) av_log(ost, AV_LOG_ERROR, "Error while opening encoder - maybe " "incorrect parameters such as bit_rate, rate, width or height.\n"); @@ -337,10 +331,6 @@ int enc_open(void *opaque, const AVFrame *frame) if (ost->enc_ctx->frame_size) frame_samples = ost->enc_ctx->frame_size; - ret = check_avoptions(ost->encoder_opts); - if (ret < 0) - return ret; - if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 && ost->enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */) av_log(ost, AV_LOG_WARNING, "The bitrate parameter is set too low." diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 41afe8259d..61a0d8658f 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -711,14 +711,10 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, /* two pass mode */ MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st); if (do_pass) { - if (do_pass & 1) { + if (do_pass & 1) video_enc->flags |= AV_CODEC_FLAG_PASS1; - av_dict_set(&ost->encoder_opts, "flags", "+pass1", AV_DICT_APPEND); - } - if (do_pass & 2) { + if (do_pass & 2) video_enc->flags |= AV_CODEC_FLAG_PASS2; - av_dict_set(&ost->encoder_opts, "flags", "+pass2", AV_DICT_APPEND); - } } MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st); @@ -740,7 +736,10 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, DEFAULT_PASS_LOGFILENAME_PREFIX, ost_idx); if (!strcmp(ost->enc_ctx->codec->name, "libx264")) { - av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE); + if (av_opt_is_set_to_default_by_name(ost->enc_ctx, "stats", + AV_OPT_SEARCH_CHILDREN) > 0) + av_opt_set(ost->enc_ctx, "stats", logfilename, + AV_OPT_SEARCH_CHILDREN); } else { if (video_enc->flags & AV_CODEC_FLAG_PASS2) { char *logbuffer = file_read(logfilename); @@ -1041,6 +1040,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, const AVCodec *enc; AVStream *st; int ret = 0, keep_pix_fmt = 0, autoscale = 1; + int threads_manual = 0; AVRational enc_tb = { 0, 0 }; enum VideoSyncMethod vsync_method = VSYNC_AUTO; const char *bsfs = NULL, *time_base = NULL; @@ -1264,6 +1264,23 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, enc_tb = q; } + + threads_manual = !!av_dict_get(ost->encoder_opts, "threads", NULL, 0); + + ret = av_opt_set_dict2(ost->enc_ctx, &ost->encoder_opts, AV_OPT_SEARCH_CHILDREN); + if (ret < 0) { + av_log(ost, AV_LOG_ERROR, "Error applying encoder options: %s\n", + av_err2str(ret)); + return ret; + } + + ret = check_avoptions(ost->encoder_opts); + if (ret < 0) + return ret; + + // default to automatic thread count + if (!threads_manual) + ost->enc_ctx->thread_count = 0; } else { ret = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL, &ost->encoder_opts, @@ -1276,8 +1293,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, if (o->bitexact) { ost->bitexact = 1; } else if (ost->enc_ctx) { - ost->bitexact = check_opt_bitexact(ost->enc_ctx, ost->encoder_opts, "flags", - AV_CODEC_FLAG_BITEXACT); + ost->bitexact = !!(ost->enc_ctx->flags & AV_CODEC_FLAG_BITEXACT); } MATCH_PER_STREAM_OPT(time_bases, str, time_base, oc, st); @@ -1372,7 +1388,6 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, if (ost->enc && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { - const AVDictionaryEntry *e; char name[16]; OutputFilterOptions opts = { .enc = enc, @@ -1398,10 +1413,6 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, snprintf(name, sizeof(name), "#%d:%d", mux->of.index, ost->index); - e = av_dict_get(ost->encoder_opts, "threads", NULL, 0); - if (e) - opts.nb_threads = e->value; - // MJPEG encoder exports a full list of supported pixel formats, // but the full-range ones are experimental-only. // Restrict the auto-conversion list unless -strict experimental @@ -1413,33 +1424,26 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE }; - const AVDictionaryEntry *strict = av_dict_get(ost->encoder_opts, "strict", NULL, 0); - int strict_val = ost->enc_ctx->strict_std_compliance; - - if (strict) { - const AVOption *o = av_opt_find(ost->enc_ctx, strict->key, NULL, 0, 0); - av_assert0(o); - av_opt_eval_int(ost->enc_ctx, o, strict->value, &strict_val); - } - - if (strict_val > FF_COMPLIANCE_UNOFFICIAL) + if (ost->enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) opts.pix_fmts = mjpeg_formats; } + if (threads_manual) { + ret = av_opt_get(ost->enc_ctx, "threads", 0, (uint8_t**)&opts.nb_threads); + if (ret < 0) + return ret; + } + if (ofilter) { ost->filter = ofilter; ret = ofilter_bind_ost(ofilter, ost, ms->sch_idx_enc, &opts); - if (ret < 0) - return ret; } else { ret = init_simple_filtergraph(ost->ist, ost, filters, mux->sch, ms->sch_idx_enc, &opts); - if (ret < 0) { - av_log(ost, AV_LOG_ERROR, - "Error initializing a simple filtergraph\n"); - return ret; - } } + av_freep(&opts.nb_threads); + if (ret < 0) + return ret; ret = sch_connect(mux->sch, SCH_ENC(ms->sch_idx_enc), SCH_MSTREAM(mux->sch_idx, ms->sch_idx)); diff --git a/tests/ref/vsynth/vsynth1-prores_444_int b/tests/ref/vsynth/vsynth1-prores_444_int index 76db62d4e9..3d4c616c7a 100644 --- a/tests/ref/vsynth/vsynth1-prores_444_int +++ b/tests/ref/vsynth/vsynth1-prores_444_int @@ -1,4 +1,4 @@ -fd2a2f49c61817c2338f39d5736d5fd2 *tests/data/fate/vsynth1-prores_444_int.mov +bd1502671ce7144c106a6a460b2af404 *tests/data/fate/vsynth1-prores_444_int.mov 9940947 tests/data/fate/vsynth1-prores_444_int.mov 732ceeb6887524e0aee98762fe50578b *tests/data/fate/vsynth1-prores_444_int.out.rawvideo stddev: 2.83 PSNR: 39.08 MAXDIFF: 45 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-prores_int b/tests/ref/vsynth/vsynth1-prores_int index 3e2bbeff2a..c3b57631c8 100644 --- a/tests/ref/vsynth/vsynth1-prores_int +++ b/tests/ref/vsynth/vsynth1-prores_int @@ -1,4 +1,4 @@ -1f1b246dfabe028f04c78887e5da51ed *tests/data/fate/vsynth1-prores_int.mov +842f92426e56cf6208cc94360d29fc69 *tests/data/fate/vsynth1-prores_int.mov 6308688 tests/data/fate/vsynth1-prores_int.mov 164a4ca890695cf594293d1acec9463c *tests/data/fate/vsynth1-prores_int.out.rawvideo stddev: 2.66 PSNR: 39.62 MAXDIFF: 34 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-prores_444_int b/tests/ref/vsynth/vsynth2-prores_444_int index a2ee569c49..8d2a13b91b 100644 --- a/tests/ref/vsynth/vsynth2-prores_444_int +++ b/tests/ref/vsynth/vsynth2-prores_444_int @@ -1,4 +1,4 @@ -5ac517fc2380a6cf11b7d86d2fafee0a *tests/data/fate/vsynth2-prores_444_int.mov +6f5fa77609698fbed3a7eef1c91bb9ea *tests/data/fate/vsynth2-prores_444_int.mov 6420787 tests/data/fate/vsynth2-prores_444_int.mov 33a5db4f0423168d4ae4f1db3610928e *tests/data/fate/vsynth2-prores_444_int.out.rawvideo stddev: 0.93 PSNR: 48.73 MAXDIFF: 14 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-prores_int b/tests/ref/vsynth/vsynth2-prores_int index 72139ee6c3..f80ff34601 100644 --- a/tests/ref/vsynth/vsynth2-prores_int +++ b/tests/ref/vsynth/vsynth2-prores_int @@ -1,4 +1,4 @@ -4062c74196d95a64e642bd917377ed93 *tests/data/fate/vsynth2-prores_int.mov +a9a9812dd8944a58c2c2b3b0ce41247d *tests/data/fate/vsynth2-prores_int.mov 4070996 tests/data/fate/vsynth2-prores_int.mov bef9e38387a1fbb1ce2e4401b6d41674 *tests/data/fate/vsynth2-prores_int.out.rawvideo stddev: 1.54 PSNR: 44.37 MAXDIFF: 13 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth3-prores_444_int b/tests/ref/vsynth/vsynth3-prores_444_int index ac30691143..ca30db5383 100644 --- a/tests/ref/vsynth/vsynth3-prores_444_int +++ b/tests/ref/vsynth/vsynth3-prores_444_int @@ -1,4 +1,4 @@ -50db4bbc4674de3dfdd41f306af1cb17 *tests/data/fate/vsynth3-prores_444_int.mov +b61864cafb35ad8e592b4f899bdd84b6 *tests/data/fate/vsynth3-prores_444_int.mov 184397 tests/data/fate/vsynth3-prores_444_int.mov a8852aa2841c2ce5f2aa86176ceda4ef *tests/data/fate/vsynth3-prores_444_int.out.rawvideo stddev: 3.24 PSNR: 37.91 MAXDIFF: 41 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-prores_int b/tests/ref/vsynth/vsynth3-prores_int index 86fc2266b5..0feee26de1 100644 --- a/tests/ref/vsynth/vsynth3-prores_int +++ b/tests/ref/vsynth/vsynth3-prores_int @@ -1,4 +1,4 @@ -24b765064b4aec754fdd0cc3658bba19 *tests/data/fate/vsynth3-prores_int.mov +2e89dfb5e2b5146337c1d65ccc4fe196 *tests/data/fate/vsynth3-prores_int.mov 120484 tests/data/fate/vsynth3-prores_int.mov e5859ba47a99f9e53c1ddcaa68a8f8f8 *tests/data/fate/vsynth3-prores_int.out.rawvideo stddev: 2.92 PSNR: 38.81 MAXDIFF: 29 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth_lena-prores_444_int b/tests/ref/vsynth/vsynth_lena-prores_444_int index f05f1fe775..b13a7a126a 100644 --- a/tests/ref/vsynth/vsynth_lena-prores_444_int +++ b/tests/ref/vsynth/vsynth_lena-prores_444_int @@ -1,4 +1,4 @@ -09b5dffd1a484e2152a3b5a0bcceed32 *tests/data/fate/vsynth_lena-prores_444_int.mov +e76d98c772c65c7ac75f7d43484883d3 *tests/data/fate/vsynth_lena-prores_444_int.mov 5696258 tests/data/fate/vsynth_lena-prores_444_int.mov 466380156e4d2b811f4ffb9c5a8bca72 *tests/data/fate/vsynth_lena-prores_444_int.out.rawvideo stddev: 0.88 PSNR: 49.23 MAXDIFF: 9 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-prores_int b/tests/ref/vsynth/vsynth_lena-prores_int index ea08089745..cec45a59b9 100644 --- a/tests/ref/vsynth/vsynth_lena-prores_int +++ b/tests/ref/vsynth/vsynth_lena-prores_int @@ -1,4 +1,4 @@ -c7e9a61054f44fe372a3bce619b68ce9 *tests/data/fate/vsynth_lena-prores_int.mov +21d328216b194500a3c87c45afa5e927 *tests/data/fate/vsynth_lena-prores_int.mov 3532698 tests/data/fate/vsynth_lena-prores_int.mov eb5caa9824ca294f403cd13f33c40f23 *tests/data/fate/vsynth_lena-prores_int.out.rawvideo stddev: 1.47 PSNR: 44.78 MAXDIFF: 12 bytes: 7603200/ 7603200 From patchwork Thu May 23 09:03:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 49173 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:542:0:b0:460:55fa:d5ed with SMTP id 63csp895662vqf; Thu, 23 May 2024 02:04:24 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWIHp3M+XSSibP/XuAtSnAjUoiQMkjCHXVmXaVLz+IbhmSCH2Iwb8hRzWtv7/fqt2RffwhfaEJVBfup+TcrWhl7o9La5uVL2wc52A== X-Google-Smtp-Source: AGHT+IHf0nU1YKxbbU2uNhQP4g3QCRw6a3KbqmFONKl83G+Af+sA3BsKqi7sLdIlq96hloc8w+3y X-Received: by 2002:a05:6512:10d1:b0:51f:4d57:6812 with SMTP id 2adb3069b0e04-526bf07e4e8mr4227541e87.19.1716455063960; Thu, 23 May 2024 02:04:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1716455063; cv=none; d=google.com; s=arc-20160816; b=SdFB0bJrLgAWP5uZ9NkJB1FsrVBibChZe1bzRDbT7EC0GioZYGIWypXG9qo73olott mqnEfHHGO5u94a81cUlYEgn1MnKP4rPEh5ihmaRcIZoQvqiRoXd6E0MmlKAxAVFgUSl5 FYGAGfyU0XID8yINOmn2uzAEz9uQpkWOdwQguFUtOXulTzp3IPoILoGta3AfuNAqq4cT wOjOGbhcVAA2Fd+89TlHjICqgZvWWgO+A3jkUiWd9wrsihDkg/M1Tn8Q4IUVi2cGsnd8 q2LQkVgbDuF44poUEeu+hZGTHoctRK/OXMPfieqXRxFDjJGPLkBxU+yc9eKHeznzSULb DaWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding: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=SELDjH/9pGbR3Z2HxLFq9MDyLY9AXgucBsFrpRiAKGE=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=OjJRrv3+xVgaMPq2jNVNlZXjIlqVAJxveepo3JqIi7PUQJX8Thb28EbFSFThwkkNUT MHKzX6CvhCZPToKATx6jVr/2MyKjUxdyFnJr5weS9ujYEo8R8+Ort5y/YbezZTfMPT7w rAlSpxqg9lH43A7BGixwsQoi/N/z5317VBzePxRb7uXzclX0q6ZBdQMzvTZHad4vRQF7 xQ/PftBGaq5MgMQnYaVJrsrV5cB99cQ4jBsmD+Xdg4H0+T9aObJnp5YNdnfvFISSwtwB ckwxXegDujn45EilfGlvth05d23L934jZYOMa6SDVesoDgBnpfFG5KbPlGdtMtE6s9nO CMzQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=X56MTIfc; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 2adb3069b0e04-52818e39416si355667e87.257.2024.05.23.02.04.23; Thu, 23 May 2024 02:04:23 -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=@khirnov.net header.s=mail header.b=X56MTIfc; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CB91468D435; Thu, 23 May 2024 12:03:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CF8C768D23D for ; Thu, 23 May 2024 12:03:49 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=X56MTIfc; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 724E04DC2 for ; Thu, 23 May 2024 11:03:49 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id d3cWYybLy-Sc for ; Thu, 23 May 2024 11:03:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1716455028; bh=3bcZAR+irIqRBiJwNBU5oOOLqe7axPirEYLA3gYfLnY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=X56MTIfczZEaxWUy9lvUSKBD7CC/rG1qWM5fFBF+FDsGOVjyS/y8gHm41seYg4szD RZISztR4y9/P7ahKGk+Ulx5GUZF+T+NTygjTqHnfmDMaeXjGO1KEs2NODWH7mBz6rP +cMZuYuae8TwVY/GsXDH7fBguRT3bjHbrylO+qe7lhHhiPzh4wljF4AEj2+CaAZYbr 2/N5HVlRuPRlPnOV2lpYRfTwt8me39rRkJQOdfHFbAQVJ4fLkgmut5DHomGw9YwfPY bzC8tKTBgJ6MFFOlSGr26oDdBXFQljHAtxADBat7f1gvsZYapDsgedmbi8XYn1SME+ JzmdPtt90TOVA== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 4FF624DC6 for ; Thu, 23 May 2024 11:03:48 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id F1B673A04E0 for ; Thu, 23 May 2024 11:03:41 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Thu, 23 May 2024 11:03:39 +0200 Message-ID: <20240523090339.4228-4-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240523090339.4228-1-anton@khirnov.net> References: <20240523090339.4228-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 4/4] fftools/ffmpeg_mux_init: make encoder_opts local to ost_add() 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: hoXFA7YlNg3j It is no longer needed after this function returns. --- fftools/ffmpeg.h | 2 -- fftools/ffmpeg_mux.c | 1 - fftools/ffmpeg_mux_init.c | 71 ++++++++++++++++++++++----------------- 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 9cab8148ca..51aee0679a 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -586,8 +586,6 @@ typedef struct OutputStream { FilterGraph *fg_simple; OutputFilter *filter; - AVDictionary *encoder_opts; - char *attachment_filename; /* stats */ diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 055e2f3678..de3e052152 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -813,7 +813,6 @@ static void ost_free(OutputStream **post) av_packet_free(&ms->bsf_pkt); av_packet_free(&ms->pkt); - av_dict_free(&ost->encoder_opts); av_freep(&ost->kf.pts); av_expr_free(ost->kf.pexpr); diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 61a0d8658f..b8dc6017a9 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -905,7 +905,7 @@ static int new_stream_subtitle(Muxer *mux, const OptionsContext *o, return 0; } -static int streamcopy_init(const Muxer *mux, OutputStream *ost) +static int streamcopy_init(const Muxer *mux, OutputStream *ost, AVDictionary **encoder_opts) { MuxStream *ms = ms_from_ost(ost); @@ -928,7 +928,7 @@ static int streamcopy_init(const Muxer *mux, OutputStream *ost) ret = avcodec_parameters_to_context(codec_ctx, ist->par); if (ret >= 0) - ret = av_opt_set_dict(codec_ctx, &ost->encoder_opts); + ret = av_opt_set_dict(codec_ctx, encoder_opts); if (ret < 0) { av_log(ost, AV_LOG_FATAL, "Error setting up codec context options.\n"); @@ -1039,6 +1039,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, OutputStream *ost; const AVCodec *enc; AVStream *st; + AVDictionary *encoder_opts = NULL; int ret = 0, keep_pix_fmt = 0, autoscale = 1; int threads_manual = 0; AVRational enc_tb = { 0, 0 }; @@ -1160,10 +1161,10 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, const char *enc_time_base = NULL; ret = filter_codec_opts(o->g->codec_opts, enc->codec_id, - oc, st, enc->codec, &ost->encoder_opts, + oc, st, enc->codec, &encoder_opts, &mux->enc_opts_used); if (ret < 0) - return ret; + goto fail; MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); @@ -1187,7 +1188,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, break; } *arg++ = 0; - av_dict_set(&ost->encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE); + av_dict_set(&encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE); } while (!s->eof_reached); av_bprint_finalize(&bprint, NULL); avio_closep(&s); @@ -1195,7 +1196,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, if (ret) { av_log(ost, AV_LOG_FATAL, "Preset %s specified, but could not be opened.\n", preset); - return ret; + goto fail; } MATCH_PER_STREAM_OPT(enc_stats_pre, str, enc_stats_pre, oc, st); @@ -1207,7 +1208,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ret = enc_stats_init(ost, &ost->enc_stats_pre, 1, enc_stats_pre, format); if (ret < 0) - return ret; + goto fail; } MATCH_PER_STREAM_OPT(enc_stats_post, str, enc_stats_post, oc, st); @@ -1219,7 +1220,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ret = enc_stats_init(ost, &ost->enc_stats_post, 0, enc_stats_post, format); if (ret < 0) - return ret; + goto fail; } MATCH_PER_STREAM_OPT(mux_stats, str, mux_stats, oc, st); @@ -1231,7 +1232,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ret = enc_stats_init(ost, &ms->stats, 0, mux_stats, format); if (ret < 0) - return ret; + goto fail; } MATCH_PER_STREAM_OPT(enc_time_bases, str, enc_time_base, oc, st); @@ -1253,7 +1254,8 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, #endif ) { av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", enc_time_base); - return ret < 0 ? ret : AVERROR(EINVAL); + ret = ret < 0 ? ret : AVERROR(EINVAL); + goto fail; } #if FFMPEG_OPT_ENC_TIME_BASE_NUM if (q.num < 0) @@ -1265,28 +1267,28 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, enc_tb = q; } - threads_manual = !!av_dict_get(ost->encoder_opts, "threads", NULL, 0); + threads_manual = !!av_dict_get(encoder_opts, "threads", NULL, 0); - ret = av_opt_set_dict2(ost->enc_ctx, &ost->encoder_opts, AV_OPT_SEARCH_CHILDREN); + ret = av_opt_set_dict2(ost->enc_ctx, &encoder_opts, AV_OPT_SEARCH_CHILDREN); if (ret < 0) { av_log(ost, AV_LOG_ERROR, "Error applying encoder options: %s\n", av_err2str(ret)); - return ret; + goto fail; } - ret = check_avoptions(ost->encoder_opts); + ret = check_avoptions(encoder_opts); if (ret < 0) - return ret; + goto fail; // default to automatic thread count if (!threads_manual) ost->enc_ctx->thread_count = 0; } else { ret = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, - NULL, &ost->encoder_opts, + NULL, &encoder_opts, &mux->enc_opts_used); if (ret < 0) - return ret; + goto fail; } @@ -1302,7 +1304,8 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 || q.num <= 0 || q.den <= 0) { av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", time_base); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } st->time_base = q; } @@ -1325,7 +1328,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ret = av_bsf_list_parse_str(bsfs, &ms->bsf_ctx); if (ret < 0) { av_log(ost, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret)); - return ret; + goto fail; } } @@ -1378,12 +1381,12 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, case AVMEDIA_TYPE_SUBTITLE: ret = new_stream_subtitle (mux, o, ost); break; } if (ret < 0) - return ret; + goto fail; if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO) { ret = ost_get_filters(o, oc, ost, &filters); if (ret < 0) - return ret; + goto fail; } if (ost->enc && @@ -1431,7 +1434,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, if (threads_manual) { ret = av_opt_get(ost->enc_ctx, "threads", 0, (uint8_t**)&opts.nb_threads); if (ret < 0) - return ret; + goto fail; } if (ofilter) { @@ -1443,18 +1446,19 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, } av_freep(&opts.nb_threads); if (ret < 0) - return ret; + goto fail; ret = sch_connect(mux->sch, SCH_ENC(ms->sch_idx_enc), SCH_MSTREAM(mux->sch_idx, ms->sch_idx)); if (ret < 0) - return ret; + goto fail; } else if (ost->ist) { int sched_idx = ist_output_add(ost->ist, ost); if (sched_idx < 0) { av_log(ost, AV_LOG_ERROR, "Error binding an input stream\n"); - return sched_idx; + ret = sched_idx; + goto fail; } ms->sch_idx_src = sched_idx; @@ -1462,24 +1466,24 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ret = sch_connect(mux->sch, SCH_DEC(sched_idx), SCH_ENC(ms->sch_idx_enc)); if (ret < 0) - return ret; + goto fail; ret = sch_connect(mux->sch, SCH_ENC(ms->sch_idx_enc), SCH_MSTREAM(mux->sch_idx, ms->sch_idx)); if (ret < 0) - return ret; + goto fail; } else { ret = sch_connect(mux->sch, SCH_DSTREAM(ost->ist->file->index, sched_idx), SCH_MSTREAM(ost->file->index, ms->sch_idx)); if (ret < 0) - return ret; + goto fail; } } if (ost->ist && !ost->enc) { - ret = streamcopy_init(mux, ost); + ret = streamcopy_init(mux, ost, &encoder_opts); if (ret < 0) - return ret; + goto fail; } // copy estimated duration as a hint to the muxer @@ -1491,7 +1495,12 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, if (post) *post = ost; - return 0; + ret = 0; + +fail: + av_dict_free(&encoder_opts); + + return ret; } static int map_auto_video(Muxer *mux, const OptionsContext *o)