diff options
author | Anton Khirnov <anton@khirnov.net> | 2023-04-11 13:21:56 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2023-04-17 12:01:40 +0200 |
commit | 9ce1a041d8879379cc2a4231d073738616b2c3e5 (patch) | |
tree | f04b6b146a5409c748bffc2bee3ebd0016933a31 | |
parent | ff92ecad2fca6143637538fb7ab3423205ebb4a7 (diff) | |
download | ffmpeg-9ce1a041d8879379cc2a4231d073738616b2c3e5.tar.gz |
fftools/ffmpeg: move opening decoders to a new file
All decoding code will be moved to this file in the future.
-rw-r--r-- | fftools/Makefile | 1 | ||||
-rw-r--r-- | fftools/ffmpeg.c | 111 | ||||
-rw-r--r-- | fftools/ffmpeg.h | 2 | ||||
-rw-r--r-- | fftools/ffmpeg_dec.c | 135 |
4 files changed, 139 insertions, 110 deletions
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 0ceb25fed0..ba92b2aa84 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; +} |