fftools/ffmpeg: move opening decoders to a new file
All decoding code will be moved to this file in the future.
This commit is contained in:
parent
ff92ecad2f
commit
9ce1a041d8
@ -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 \
|
||||
|
111
fftools/ffmpeg.c
111
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;
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
|
135
fftools/ffmpeg_dec.c
Normal file
135
fftools/ffmpeg_dec.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user