From patchwork Thu Apr 13 14:12:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 41166 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:4645:b0:e3:3194:9d20 with SMTP id eb5csp1290460pzb; Thu, 13 Apr 2023 07:20:31 -0700 (PDT) X-Google-Smtp-Source: AKy350ZTOb8okYALkVXwak33HkcaWcQ+Kr56ViPm+M9ClXuydXJmHnfF3Zs9C5FMSI5f3d1dHVxB X-Received: by 2002:a17:906:4743:b0:932:fc34:88f with SMTP id j3-20020a170906474300b00932fc34088fmr3196726ejs.11.1681395631264; Thu, 13 Apr 2023 07:20:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681395631; cv=none; d=google.com; s=arc-20160816; b=fMWMzI1H5cf9u81tfS/bXuFhXiF24DKV/rZ5epihoLW9cXINzGdMBLmJ0yWyurHRJH bHkXeMgoZg1JbQS3ZOpNjeru3p467Z6dPy7QQbJVrH1eBqgIKcGm0sDBhu+8YQ9A2Fgi duaV38CTI9nCJ57SAZ6xuprmxZ2TZv41hlOxEqb0ZxiKzyeDJxPJkAJtDycRdFagKpOH sHG+SACakTY9GDsG7qRQgYoMo2Vt29XM0ppVMbY6iAs6+F3VfA44Y9aLu/W7uRs8RGpO +BWFbY7ofYwqw4Jps7Pf5R+u9jfzXWilmaqaXIx+B4FIFg/9fhN9Gmir+wBvNNJzLl9N 7/yA== 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:delivered-to; bh=9jg4Slni8zFH3OBybOtjutUWFwmfz3PXvtfZuHxD0tQ=; b=Seh9wB0o+lWyBs6Op0sqiHLDdZW4oXu/Ca6zXKnmUa9SPCwGqboD/4BmN0wC0+j1Pc zDG0MV9mI/DbuoEeW9YDhCycJ08xtEC8+bQAk644/3eBuPME8WjtMI/PfavWlFSHEKNU Ay05FRdnFil4oq/TGwQtvczsYhwONWifEuAccJK0HF5JpxGnCPwYcJ5O2Aph2idL8+8Z kK2NynRsQpddeKH2DMILyOJi6RMBSTwzqiedqHsGuVnFkFZgIAdf/9rjPaDmzq+AfpYG Vo2ZflOswmRv2LuipOVtTNHU1k4LTXXDIZtmD1Ff9GhvCn8bfK63Qs4BcT9hvSt7OA8J Ifqg== ARC-Authentication-Results: i=1; mx.google.com; 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 wl7-20020a170907310700b008d89608d4a2si1843566ejb.204.2023.04.13.07.20.30; Thu, 13 Apr 2023 07:20:31 -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; 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 0E3BA68BEF8; Thu, 13 Apr 2023 17:16:20 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E5C2168BE6B for ; Thu, 13 Apr 2023 17:16:00 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 28BBC2404EC for ; Thu, 13 Apr 2023 16:16:00 +0200 (CEST) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id EjKoSVcuWmQU for ; Thu, 13 Apr 2023 16:15:57 +0200 (CEST) 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 mail0.khirnov.net (Postfix) with ESMTPS id 5661F2406CC for ; Thu, 13 Apr 2023 16:15:53 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 467DB3A038E for ; Thu, 13 Apr 2023 16:15:53 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Thu, 13 Apr 2023 16:12:09 +0200 Message-Id: <20230413141223.17245-11-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230413141223.17245-1-anton@khirnov.net> References: <20230413141223.17245-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 11/25] fftools/ffmpeg: move opening decoders to a new file 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: opiQFagmo4AC All decoding code will be moved to this file in the future. --- fftools/Makefile | 1 + fftools/ffmpeg.c | 111 +---------------------------------- fftools/ffmpeg.h | 2 + fftools/ffmpeg_dec.c | 135 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 110 deletions(-) create mode 100644 fftools/ffmpeg_dec.c diff --git a/fftools/Makefile b/fftools/Makefile index 9939c7095c..56820e6bc8 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -10,6 +10,7 @@ ALLAVPROGS = $(AVBASENAMES:%=%$(PROGSSUF)$(EXESUF)) ALLAVPROGS_G = $(AVBASENAMES:%=%$(PROGSSUF)_g$(EXESUF)) OBJS-ffmpeg += \ + fftools/ffmpeg_dec.o \ fftools/ffmpeg_demux.o \ fftools/ffmpeg_enc.o \ fftools/ffmpeg_filter.o \ diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 57bdc12473..d8b06eb724 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -621,11 +621,6 @@ void assert_avoptions(AVDictionary *m) } } -static void abort_codec_experimental(const AVCodec *c, int encoder) -{ - exit_program(1); -} - void update_benchmark(const char *fmt, ...) { if (do_benchmark_all) { @@ -1858,110 +1853,6 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt, int no_eo return !eof_reached; } -static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts) -{ - InputStream *ist = s->opaque; - const enum AVPixelFormat *p; - int ret; - - for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p); - const AVCodecHWConfig *config = NULL; - int i; - - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) - break; - - if (ist->hwaccel_id == HWACCEL_GENERIC || - ist->hwaccel_id == HWACCEL_AUTO) { - for (i = 0;; i++) { - config = avcodec_get_hw_config(s->codec, i); - if (!config) - break; - if (!(config->methods & - AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) - continue; - if (config->pix_fmt == *p) - break; - } - } - if (config && config->device_type == ist->hwaccel_device_type) { - ret = hwaccel_decode_init(s); - if (ret < 0) { - if (ist->hwaccel_id == HWACCEL_GENERIC) { - av_log(NULL, AV_LOG_FATAL, - "%s hwaccel requested for input stream #%d:%d, " - "but cannot be initialized.\n", - av_hwdevice_get_type_name(config->device_type), - ist->file_index, ist->st->index); - return AV_PIX_FMT_NONE; - } - continue; - } - - ist->hwaccel_pix_fmt = *p; - break; - } - } - - return *p; -} - -static int init_input_stream(InputStream *ist) -{ - int ret; - - if (ist->decoding_needed) { - const AVCodec *codec = ist->dec; - if (!codec) { - av_log(ist, AV_LOG_ERROR, - "Decoding requested, but no decoder found for: %s\n", - avcodec_get_name(ist->dec_ctx->codec_id)); - return AVERROR(EINVAL); - } - - ist->dec_ctx->opaque = ist; - ist->dec_ctx->get_format = get_format; - - if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE && - (ist->decoding_needed & DECODING_FOR_OST)) { - av_dict_set(&ist->decoder_opts, "compute_edt", "1", AV_DICT_DONT_OVERWRITE); - if (ist->decoding_needed & DECODING_FOR_FILTER) - av_log(NULL, AV_LOG_WARNING, "Warning using DVB subtitles for filtering and output at the same time is not fully supported, also see -compute_edt [0|1]\n"); - } - - /* Useful for subtitles retiming by lavf (FIXME), skipping samples in - * audio, and video decoders such as cuvid or mediacodec */ - ist->dec_ctx->pkt_timebase = ist->st->time_base; - - if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0)) - av_dict_set(&ist->decoder_opts, "threads", "auto", 0); - /* Attached pics are sparse, therefore we would not want to delay their decoding till EOF. */ - if (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC) - av_dict_set(&ist->decoder_opts, "threads", "1", 0); - - ret = hw_device_setup_for_decode(ist); - if (ret < 0) { - av_log(ist, AV_LOG_ERROR, - "Hardware device setup failed for decoder: %s\n", - av_err2str(ret)); - return ret; - } - - if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) { - if (ret == AVERROR_EXPERIMENTAL) - abort_codec_experimental(codec, 0); - - av_log(ist, AV_LOG_ERROR, "Error while opening decoder: %s\n", - av_err2str(ret)); - return ret; - } - assert_avoptions(ist->decoder_opts); - } - - return 0; -} - static int init_output_stream_nofilter(OutputStream *ost) { int ret = 0; @@ -1993,7 +1884,7 @@ static int transcode_init(void) /* init input streams */ for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) - if ((ret = init_input_stream(ist)) < 0) + if (ist->decoding_needed && (ret = dec_open(ist)) < 0) goto dump_format; /* diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index c73fc8a459..5833c13812 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -829,6 +829,8 @@ AVBufferRef *hw_device_for_filter(void); int hwaccel_decode_init(AVCodecContext *avctx); +int dec_open(InputStream *ist); + int enc_alloc(Encoder **penc, const AVCodec *codec); void enc_free(Encoder **penc); diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c new file mode 100644 index 0000000000..ccf558649c --- /dev/null +++ b/fftools/ffmpeg_dec.c @@ -0,0 +1,135 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/dict.h" +#include "libavutil/error.h" +#include "libavutil/log.h" +#include "libavutil/pixdesc.h" +#include "libavutil/pixfmt.h" + +#include "libavcodec/avcodec.h" +#include "libavcodec/codec.h" + +#include "ffmpeg.h" + +static void abort_codec_experimental(const AVCodec *c, int encoder) +{ + exit_program(1); +} + +static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts) +{ + InputStream *ist = s->opaque; + const enum AVPixelFormat *p; + int ret; + + for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) { + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p); + const AVCodecHWConfig *config = NULL; + int i; + + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + break; + + if (ist->hwaccel_id == HWACCEL_GENERIC || + ist->hwaccel_id == HWACCEL_AUTO) { + for (i = 0;; i++) { + config = avcodec_get_hw_config(s->codec, i); + if (!config) + break; + if (!(config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) + continue; + if (config->pix_fmt == *p) + break; + } + } + if (config && config->device_type == ist->hwaccel_device_type) { + ret = hwaccel_decode_init(s); + if (ret < 0) { + if (ist->hwaccel_id == HWACCEL_GENERIC) { + av_log(NULL, AV_LOG_FATAL, + "%s hwaccel requested for input stream #%d:%d, " + "but cannot be initialized.\n", + av_hwdevice_get_type_name(config->device_type), + ist->file_index, ist->st->index); + return AV_PIX_FMT_NONE; + } + continue; + } + + ist->hwaccel_pix_fmt = *p; + break; + } + } + + return *p; +} + +int dec_open(InputStream *ist) +{ + const AVCodec *codec = ist->dec; + int ret; + + if (!codec) { + av_log(ist, AV_LOG_ERROR, + "Decoding requested, but no decoder found for: %s\n", + avcodec_get_name(ist->dec_ctx->codec_id)); + return AVERROR(EINVAL); + } + + ist->dec_ctx->opaque = ist; + ist->dec_ctx->get_format = get_format; + + if (ist->dec_ctx->codec_id == AV_CODEC_ID_DVB_SUBTITLE && + (ist->decoding_needed & DECODING_FOR_OST)) { + av_dict_set(&ist->decoder_opts, "compute_edt", "1", AV_DICT_DONT_OVERWRITE); + if (ist->decoding_needed & DECODING_FOR_FILTER) + av_log(NULL, AV_LOG_WARNING, "Warning using DVB subtitles for filtering and output at the same time is not fully supported, also see -compute_edt [0|1]\n"); + } + + /* Useful for subtitles retiming by lavf (FIXME), skipping samples in + * audio, and video decoders such as cuvid or mediacodec */ + ist->dec_ctx->pkt_timebase = ist->st->time_base; + + if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0)) + av_dict_set(&ist->decoder_opts, "threads", "auto", 0); + /* Attached pics are sparse, therefore we would not want to delay their decoding till EOF. */ + if (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC) + av_dict_set(&ist->decoder_opts, "threads", "1", 0); + + ret = hw_device_setup_for_decode(ist); + if (ret < 0) { + av_log(ist, AV_LOG_ERROR, + "Hardware device setup failed for decoder: %s\n", + av_err2str(ret)); + return ret; + } + + if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) { + if (ret == AVERROR_EXPERIMENTAL) + abort_codec_experimental(codec, 0); + + av_log(ist, AV_LOG_ERROR, "Error while opening decoder: %s\n", + av_err2str(ret)); + return ret; + } + assert_avoptions(ist->decoder_opts); + + return 0; +}