2010-01-30 16:57:40 +00:00
|
|
|
/*
|
2015-04-13 07:36:54 +00:00
|
|
|
* This file is part of mpv.
|
2010-01-30 16:57:40 +00:00
|
|
|
*
|
2017-09-21 11:50:18 +00:00
|
|
|
* mpv 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
|
2017-10-05 13:54:10 +00:00
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2010-01-30 16:57:40 +00:00
|
|
|
*
|
2015-04-13 07:36:54 +00:00
|
|
|
* mpv is distributed in the hope that it will be useful,
|
2010-01-30 16:57:40 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2017-09-21 11:50:18 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2010-01-30 16:57:40 +00:00
|
|
|
*
|
2017-09-21 11:50:18 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
|
2010-01-30 16:57:40 +00:00
|
|
|
*/
|
|
|
|
|
2002-03-06 20:54:43 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2017-12-01 21:01:54 +00:00
|
|
|
#include <pthread.h>
|
2002-03-06 20:54:43 +00:00
|
|
|
#include <assert.h>
|
2010-01-20 14:31:13 +00:00
|
|
|
#include <stdbool.h>
|
2002-03-06 20:54:43 +00:00
|
|
|
|
2017-12-01 21:01:54 +00:00
|
|
|
#include <libavcodec/avcodec.h>
|
2012-01-28 11:41:36 +00:00
|
|
|
#include <libavutil/common.h>
|
2017-12-01 21:01:54 +00:00
|
|
|
#include <libavutil/hwcontext.h>
|
2012-01-28 11:41:36 +00:00
|
|
|
#include <libavutil/opt.h>
|
2012-02-01 18:01:16 +00:00
|
|
|
#include <libavutil/intreadwrite.h>
|
2012-12-11 17:16:42 +00:00
|
|
|
#include <libavutil/pixdesc.h>
|
2012-01-28 11:41:36 +00:00
|
|
|
|
2018-05-21 14:05:03 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2016-01-11 18:03:40 +00:00
|
|
|
#include "mpv_talloc.h"
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
#include "common/global.h"
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/msg.h"
|
2018-05-21 14:05:03 +00:00
|
|
|
#include "options/m_config.h"
|
2013-12-17 01:02:25 +00:00
|
|
|
#include "options/options.h"
|
2014-08-29 10:09:04 +00:00
|
|
|
#include "misc/bstr.h"
|
2013-12-17 01:39:45 +00:00
|
|
|
#include "common/av_common.h"
|
|
|
|
#include "common/codecs.h"
|
2002-03-06 20:54:43 +00:00
|
|
|
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "video/fmt-conversion.h"
|
2002-03-06 20:54:43 +00:00
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
#include "filters/f_decoder_wrapper.h"
|
|
|
|
#include "filters/filter_internal.h"
|
2017-12-01 21:01:54 +00:00
|
|
|
#include "video/hwdec.h"
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "video/img_format.h"
|
2017-12-01 21:01:54 +00:00
|
|
|
#include "video/mp_image.h"
|
|
|
|
#include "video/mp_image_pool.h"
|
2015-12-22 01:35:15 +00:00
|
|
|
#include "demux/demux.h"
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "demux/stheader.h"
|
2013-11-18 17:46:44 +00:00
|
|
|
#include "demux/packet.h"
|
2012-11-09 00:06:43 +00:00
|
|
|
#include "video/csputils.h"
|
2015-02-06 22:20:41 +00:00
|
|
|
#include "video/sws_utils.h"
|
2017-07-23 07:41:51 +00:00
|
|
|
#include "video/out/vo.h"
|
2002-03-06 20:54:43 +00:00
|
|
|
|
2013-12-17 01:02:25 +00:00
|
|
|
#include "options/m_option.h"
|
2002-06-02 12:48:55 +00:00
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void init_avctx(struct mp_filter *vd);
|
|
|
|
static void uninit_avctx(struct mp_filter *vd);
|
2002-07-16 00:56:12 +00:00
|
|
|
|
2017-07-23 07:41:51 +00:00
|
|
|
static int get_buffer2_direct(AVCodecContext *avctx, AVFrame *pic, int flags);
|
2013-11-29 16:39:57 +00:00
|
|
|
static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
|
|
|
|
const enum AVPixelFormat *pix_fmt);
|
2018-05-21 14:05:03 +00:00
|
|
|
static int hwdec_validate_opt(struct mp_log *log, const m_option_t *opt,
|
|
|
|
struct bstr name, struct bstr param);
|
2012-11-06 14:27:44 +00:00
|
|
|
|
2017-12-01 21:01:54 +00:00
|
|
|
#define HWDEC_DELAY_QUEUE_COUNT 2
|
|
|
|
|
2014-06-10 23:35:39 +00:00
|
|
|
#define OPT_BASE_STRUCT struct vd_lavc_params
|
|
|
|
|
|
|
|
struct vd_lavc_params {
|
|
|
|
int fast;
|
|
|
|
int show_all;
|
2014-06-13 00:03:45 +00:00
|
|
|
int skip_loop_filter;
|
|
|
|
int skip_idct;
|
|
|
|
int skip_frame;
|
2014-08-08 22:35:25 +00:00
|
|
|
int framedrop;
|
2014-06-10 23:35:39 +00:00
|
|
|
int threads;
|
|
|
|
int bitexact;
|
2017-12-26 04:53:44 +00:00
|
|
|
int old_x264;
|
2014-06-10 23:35:39 +00:00
|
|
|
int check_hw_profile;
|
2015-10-25 09:45:44 +00:00
|
|
|
int software_fallback;
|
2014-08-02 01:12:09 +00:00
|
|
|
char **avopts;
|
2017-07-23 07:41:51 +00:00
|
|
|
int dr;
|
2018-05-21 14:05:03 +00:00
|
|
|
char *hwdec_api;
|
|
|
|
char *hwdec_codecs;
|
|
|
|
int hwdec_image_format;
|
2019-05-31 18:11:32 +00:00
|
|
|
int hwdec_extra_frames;
|
2014-06-10 23:35:39 +00:00
|
|
|
};
|
|
|
|
|
2014-06-13 00:03:45 +00:00
|
|
|
static const struct m_opt_choice_alternatives discard_names[] = {
|
|
|
|
{"none", AVDISCARD_NONE},
|
|
|
|
{"default", AVDISCARD_DEFAULT},
|
|
|
|
{"nonref", AVDISCARD_NONREF},
|
|
|
|
{"bidir", AVDISCARD_BIDIR},
|
|
|
|
{"nonkey", AVDISCARD_NONKEY},
|
|
|
|
{"all", AVDISCARD_ALL},
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
#define OPT_DISCARD(name, field, flags) \
|
|
|
|
OPT_GENERAL(int, name, field, flags, .type = CONF_TYPE_CHOICE, \
|
|
|
|
.priv = (void *)discard_names)
|
|
|
|
|
2014-06-10 23:35:39 +00:00
|
|
|
const struct m_sub_options vd_lavc_conf = {
|
|
|
|
.opts = (const m_option_t[]){
|
2018-05-21 14:05:03 +00:00
|
|
|
OPT_FLAG("vd-lavc-fast", fast, 0),
|
|
|
|
OPT_FLAG("vd-lavc-show-all", show_all, 0),
|
|
|
|
OPT_DISCARD("vd-lavc-skiploopfilter", skip_loop_filter, 0),
|
|
|
|
OPT_DISCARD("vd-lavc-skipidct", skip_idct, 0),
|
|
|
|
OPT_DISCARD("vd-lavc-skipframe", skip_frame, 0),
|
|
|
|
OPT_DISCARD("vd-lavc-framedrop", framedrop, 0),
|
|
|
|
OPT_INT("vd-lavc-threads", threads, M_OPT_MIN, .min = 0),
|
|
|
|
OPT_FLAG("vd-lavc-bitexact", bitexact, 0),
|
|
|
|
OPT_FLAG("vd-lavc-assume-old-x264", old_x264, 0),
|
|
|
|
OPT_FLAG("vd-lavc-check-hw-profile", check_hw_profile, 0),
|
|
|
|
OPT_CHOICE_OR_INT("vd-lavc-software-fallback", software_fallback,
|
|
|
|
0, 1, INT_MAX, ({"no", INT_MAX}, {"yes", 1})),
|
|
|
|
OPT_KEYVALUELIST("vd-lavc-o", avopts, 0),
|
|
|
|
OPT_FLAG("vd-lavc-dr", dr, 0),
|
|
|
|
OPT_STRING_VALIDATE("hwdec", hwdec_api, M_OPT_OPTIONAL_PARAM,
|
|
|
|
hwdec_validate_opt),
|
|
|
|
OPT_STRING("hwdec-codecs", hwdec_codecs, 0),
|
|
|
|
OPT_IMAGEFORMAT("hwdec-image-format", hwdec_image_format, 0, .min = -1),
|
2019-05-31 18:11:32 +00:00
|
|
|
OPT_INTRANGE("hwdec-extra-frames", hwdec_extra_frames, 0, 0, 256),
|
2014-06-10 23:35:39 +00:00
|
|
|
{0}
|
|
|
|
},
|
|
|
|
.size = sizeof(struct vd_lavc_params),
|
|
|
|
.defaults = &(const struct vd_lavc_params){
|
|
|
|
.show_all = 0,
|
|
|
|
.check_hw_profile = 1,
|
2015-11-03 13:03:02 +00:00
|
|
|
.software_fallback = 3,
|
2014-06-13 00:03:45 +00:00
|
|
|
.skip_loop_filter = AVDISCARD_DEFAULT,
|
|
|
|
.skip_idct = AVDISCARD_DEFAULT,
|
|
|
|
.skip_frame = AVDISCARD_DEFAULT,
|
2014-08-08 22:35:25 +00:00
|
|
|
.framedrop = AVDISCARD_NONREF,
|
2018-04-28 13:41:39 +00:00
|
|
|
.dr = 1,
|
2018-05-21 14:05:03 +00:00
|
|
|
.hwdec_api = HAVE_RPI ? "mmal" : "no",
|
2019-03-10 23:00:27 +00:00
|
|
|
.hwdec_codecs = "h264,vc1,hevc,vp9",
|
2019-05-31 18:11:32 +00:00
|
|
|
// Maximum number of surfaces the player wants to buffer. This number
|
|
|
|
// might require adjustment depending on whatever the player does;
|
|
|
|
// for example, if vo_gpu increases the number of reference surfaces for
|
|
|
|
// interpolation, this value has to be increased too.
|
|
|
|
.hwdec_extra_frames = 6,
|
2014-06-10 23:35:39 +00:00
|
|
|
},
|
2002-06-02 12:48:55 +00:00
|
|
|
};
|
|
|
|
|
2017-12-01 21:01:54 +00:00
|
|
|
struct hwdec_info {
|
|
|
|
char name[64];
|
2018-12-16 12:07:11 +00:00
|
|
|
char method_name[24]; // non-unique name describing the hwdec method
|
2017-12-01 21:01:54 +00:00
|
|
|
const AVCodec *codec; // implemented by this codec
|
|
|
|
enum AVHWDeviceType lavc_device; // if not NONE, get a hwdevice
|
|
|
|
bool copying; // if true, outputs sw frames, or copy to sw ourselves
|
|
|
|
enum AVPixelFormat pix_fmt; // if not NONE, select in get_format
|
|
|
|
bool use_hw_frames; // set AVCodecContext.hw_frames_ctx
|
|
|
|
bool use_hw_device; // set AVCodecContext.hw_device_ctx
|
|
|
|
|
|
|
|
// for internal sorting
|
|
|
|
int auto_pos;
|
|
|
|
int rank;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct lavc_ctx {
|
|
|
|
struct mp_log *log;
|
2018-05-21 14:05:03 +00:00
|
|
|
struct m_config_cache *opts_cache;
|
|
|
|
struct vd_lavc_params *opts;
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
struct mp_codec_params *codec;
|
2017-12-01 21:01:54 +00:00
|
|
|
AVCodecContext *avctx;
|
|
|
|
AVFrame *pic;
|
|
|
|
bool use_hwdec;
|
|
|
|
struct hwdec_info hwdec; // valid only if use_hwdec==true
|
|
|
|
AVRational codec_timebase;
|
|
|
|
enum AVDiscard skip_frame;
|
|
|
|
bool flushing;
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
bool eof_returned;
|
2017-12-01 21:01:54 +00:00
|
|
|
const char *decoder;
|
2017-12-01 21:08:59 +00:00
|
|
|
bool hwdec_requested;
|
2017-12-01 21:01:54 +00:00
|
|
|
bool hwdec_failed;
|
|
|
|
bool hwdec_notified;
|
|
|
|
|
|
|
|
bool intra_only;
|
|
|
|
int framedrop_flags;
|
|
|
|
|
|
|
|
bool hw_probing;
|
|
|
|
struct demux_packet **sent_packets;
|
|
|
|
int num_sent_packets;
|
|
|
|
|
|
|
|
struct demux_packet **requeue_packets;
|
|
|
|
int num_requeue_packets;
|
|
|
|
|
|
|
|
struct mp_image **delay_queue;
|
|
|
|
int num_delay_queue;
|
|
|
|
int max_delay_queue;
|
|
|
|
|
|
|
|
// From VO
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
struct vo *vo;
|
2017-12-01 21:01:54 +00:00
|
|
|
struct mp_hwdec_devices *hwdec_devs;
|
|
|
|
|
|
|
|
// Wrapped AVHWDeviceContext* used for decoding.
|
|
|
|
AVBufferRef *hwdec_dev;
|
|
|
|
|
|
|
|
bool hwdec_request_reinit;
|
|
|
|
int hwdec_fail_count;
|
|
|
|
|
|
|
|
struct mp_image_pool *hwdec_swpool;
|
|
|
|
|
|
|
|
AVBufferRef *cached_hw_frames_ctx;
|
|
|
|
|
|
|
|
// --- The following fields are protected by dr_lock.
|
|
|
|
pthread_mutex_t dr_lock;
|
|
|
|
bool dr_failed;
|
|
|
|
struct mp_image_pool *dr_pool;
|
|
|
|
int dr_imgfmt, dr_w, dr_h, dr_stride_align;
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
|
|
|
|
struct mp_decoder public;
|
2017-12-01 21:01:54 +00:00
|
|
|
} vd_ffmpeg_ctx;
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
// Things not included in this list will be tried last, in random order.
|
|
|
|
static const char *const hwdec_autoprobe_order[] = {
|
|
|
|
"d3d11va",
|
|
|
|
"dxva2",
|
|
|
|
"dxva2-copy",
|
|
|
|
"d3d11va-copy",
|
|
|
|
"nvdec",
|
|
|
|
"nvdec-copy",
|
|
|
|
"vaapi",
|
|
|
|
"vaapi-copy",
|
2019-07-06 02:18:02 +00:00
|
|
|
"vdpau",
|
|
|
|
"vdpau-copy",
|
2017-12-01 20:05:54 +00:00
|
|
|
0
|
2016-04-25 10:09:09 +00:00
|
|
|
};
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
static int hwdec_compare(const void *p1, const void *p2)
|
|
|
|
{
|
|
|
|
struct hwdec_info *h1 = (void *)p1;
|
|
|
|
struct hwdec_info *h2 = (void *)p2;
|
2016-09-11 03:12:27 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
if (h1 == h2)
|
|
|
|
return 0;
|
2016-10-09 16:18:14 +00:00
|
|
|
|
2017-12-02 01:32:41 +00:00
|
|
|
// Strictly put non-preferred hwdecs to the end of the list.
|
|
|
|
if ((h1->auto_pos == INT_MAX) != (h2->auto_pos == INT_MAX))
|
|
|
|
return h1->auto_pos == INT_MAX ? 1 : -1;
|
|
|
|
// List non-copying entries first, so --hwdec=auto takes them.
|
|
|
|
if (h1->copying != h2->copying)
|
|
|
|
return h1->copying ? 1 : -1;
|
|
|
|
// Order by autoprobe preferrence order.
|
|
|
|
if (h1->auto_pos != h2->auto_pos)
|
|
|
|
return h1->auto_pos > h2->auto_pos ? 1 : -1;
|
|
|
|
// Fallback sort order to make sorting stable.
|
|
|
|
return h1->rank > h2->rank ? 1 :-1;
|
2017-12-01 20:05:54 +00:00
|
|
|
}
|
2017-02-20 07:39:55 +00:00
|
|
|
|
2017-12-01 23:54:42 +00:00
|
|
|
// (This takes care of some bookkeeping too, like setting info.name)
|
|
|
|
static void add_hwdec_item(struct hwdec_info **infos, int *num_infos,
|
|
|
|
struct hwdec_info info)
|
|
|
|
{
|
|
|
|
if (info.copying)
|
|
|
|
mp_snprintf_cat(info.method_name, sizeof(info.method_name), "-copy");
|
|
|
|
|
|
|
|
// (Including the codec name in case this is a wrapper looks pretty dumb,
|
|
|
|
// but better not have them clash with hwaccels and others.)
|
|
|
|
snprintf(info.name, sizeof(info.name), "%s-%s",
|
|
|
|
info.codec->name, info.method_name);
|
|
|
|
|
|
|
|
info.rank = *num_infos;
|
2017-12-02 01:32:41 +00:00
|
|
|
info.auto_pos = INT_MAX;
|
2017-12-01 23:54:42 +00:00
|
|
|
for (int x = 0; hwdec_autoprobe_order[x]; x++) {
|
|
|
|
if (strcmp(hwdec_autoprobe_order[x], info.method_name) == 0)
|
|
|
|
info.auto_pos = x;
|
|
|
|
}
|
|
|
|
|
|
|
|
MP_TARRAY_APPEND(NULL, *infos, *num_infos, info);
|
|
|
|
}
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
static void add_all_hwdec_methods(struct hwdec_info **infos, int *num_infos)
|
|
|
|
{
|
2018-02-12 18:28:30 +00:00
|
|
|
const AVCodec *codec = NULL;
|
|
|
|
void *iter = NULL;
|
2017-12-01 20:05:54 +00:00
|
|
|
while (1) {
|
2018-02-12 18:28:30 +00:00
|
|
|
codec = av_codec_iterate(&iter);
|
2017-12-01 20:05:54 +00:00
|
|
|
if (!codec)
|
|
|
|
break;
|
2017-12-14 18:28:07 +00:00
|
|
|
if (codec->type != AVMEDIA_TYPE_VIDEO || !av_codec_is_decoder(codec))
|
|
|
|
continue;
|
2017-02-20 07:39:55 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
struct hwdec_info info_template = {
|
|
|
|
.pix_fmt = AV_PIX_FMT_NONE,
|
|
|
|
.codec = codec,
|
|
|
|
};
|
2017-03-23 10:06:28 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
const char *wrapper = NULL;
|
2017-12-14 18:28:07 +00:00
|
|
|
if (codec->capabilities & (AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_HYBRID))
|
|
|
|
wrapper = codec->wrapper_name;
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
// A decoder can provide multiple methods. In particular, hwaccels
|
|
|
|
// provide various methods (e.g. native h264 with vaapi & d3d11), but
|
|
|
|
// even wrapper decoders could provide multiple methods.
|
|
|
|
bool found_any = false;
|
|
|
|
for (int n = 0; ; n++) {
|
|
|
|
const AVCodecHWConfig *cfg = avcodec_get_hw_config(codec, n);
|
|
|
|
if (!cfg)
|
|
|
|
break;
|
2017-03-23 10:06:28 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
if ((cfg->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) ||
|
|
|
|
(cfg->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
|
|
|
|
{
|
|
|
|
struct hwdec_info info = info_template;
|
|
|
|
info.lavc_device = cfg->device_type;
|
|
|
|
info.pix_fmt = cfg->pix_fmt;
|
|
|
|
|
|
|
|
const char *name = av_hwdevice_get_type_name(cfg->device_type);
|
|
|
|
assert(name); // API violation by libavcodec
|
|
|
|
|
|
|
|
// nvdec hwaccels and the cuvid full decoder clash with their
|
|
|
|
// naming, so fix it here; we also prefer nvdec for the hwaccel.
|
|
|
|
if (strcmp(name, "cuda") == 0 && !wrapper)
|
|
|
|
name = "nvdec";
|
|
|
|
|
|
|
|
snprintf(info.method_name, sizeof(info.method_name), "%s", name);
|
|
|
|
|
|
|
|
// Usually we want to prefer using hw_frames_ctx for true
|
|
|
|
// hwaccels only, but we actually don't have any way to detect
|
|
|
|
// those, so always use hw_frames_ctx if offered.
|
|
|
|
if (cfg->methods & AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX) {
|
|
|
|
info.use_hw_frames = true;
|
|
|
|
} else {
|
|
|
|
info.use_hw_device = true;
|
|
|
|
}
|
2017-12-01 07:13:24 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
// Direct variant.
|
2017-12-01 23:54:42 +00:00
|
|
|
add_hwdec_item(infos, num_infos, info);
|
2017-12-01 07:13:24 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
// Copy variant.
|
|
|
|
info.copying = true;
|
|
|
|
if (cfg->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) {
|
|
|
|
info.use_hw_frames = false;
|
|
|
|
info.use_hw_device = true;
|
|
|
|
}
|
2017-12-01 23:54:42 +00:00
|
|
|
add_hwdec_item(infos, num_infos, info);
|
2017-12-01 20:05:54 +00:00
|
|
|
|
|
|
|
found_any = true;
|
|
|
|
} else if (cfg->methods & AV_CODEC_HW_CONFIG_METHOD_INTERNAL) {
|
|
|
|
struct hwdec_info info = info_template;
|
|
|
|
info.pix_fmt = cfg->pix_fmt;
|
|
|
|
|
|
|
|
const char *name = wrapper;
|
|
|
|
if (!name)
|
|
|
|
name = av_get_pix_fmt_name(info.pix_fmt);
|
|
|
|
assert(name); // API violation by libavcodec
|
|
|
|
|
|
|
|
snprintf(info.method_name, sizeof(info.method_name), "%s", name);
|
|
|
|
|
|
|
|
// Direct variant.
|
2017-12-01 23:54:42 +00:00
|
|
|
add_hwdec_item(infos, num_infos, info);
|
2017-12-01 20:05:54 +00:00
|
|
|
|
|
|
|
// Copy variant.
|
2017-12-01 23:54:42 +00:00
|
|
|
info.copying = true;
|
2017-12-02 20:08:38 +00:00
|
|
|
info.pix_fmt = AV_PIX_FMT_NONE; // trust it can do sw output
|
2017-12-01 23:54:42 +00:00
|
|
|
add_hwdec_item(infos, num_infos, info);
|
2017-12-01 20:05:54 +00:00
|
|
|
|
|
|
|
found_any = true;
|
|
|
|
}
|
|
|
|
}
|
2017-10-31 14:18:57 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
if (!found_any && wrapper) {
|
|
|
|
// We _know_ there's something supported here, usually outputting
|
|
|
|
// sw surfaces. E.g. mediacodec (before hw_device_ctx support).
|
2017-12-01 17:01:15 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
struct hwdec_info info = info_template;
|
|
|
|
info.copying = true; // probably
|
2017-11-30 20:54:13 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
snprintf(info.method_name, sizeof(info.method_name), "%s", wrapper);
|
2017-12-01 23:54:42 +00:00
|
|
|
add_hwdec_item(infos, num_infos, info);
|
2017-12-01 20:05:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
qsort(*infos, *num_infos, sizeof(struct hwdec_info), hwdec_compare);
|
2012-12-11 17:16:42 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static bool hwdec_codec_allowed(struct mp_filter *vd, const char *codec)
|
2013-05-03 19:00:05 +00:00
|
|
|
{
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
bstr s = bstr0(ctx->opts->hwdec_codecs);
|
2013-05-03 19:00:05 +00:00
|
|
|
while (s.len) {
|
|
|
|
bstr item;
|
|
|
|
bstr_split_tok(s, ",", &item, &s);
|
2013-08-11 21:23:12 +00:00
|
|
|
if (bstr_equals0(item, "all") || bstr_equals0(item, codec))
|
2013-05-03 19:00:05 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static AVBufferRef *hwdec_create_dev(struct mp_filter *vd,
|
2017-12-01 20:05:54 +00:00
|
|
|
struct hwdec_info *hwdec,
|
|
|
|
bool autoprobe)
|
2016-04-25 09:28:25 +00:00
|
|
|
{
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2017-12-01 20:05:54 +00:00
|
|
|
assert(hwdec->lavc_device);
|
2016-04-25 09:28:25 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
if (hwdec->copying) {
|
2017-12-01 07:01:08 +00:00
|
|
|
const struct hwcontext_fns *fns =
|
2017-12-01 20:05:54 +00:00
|
|
|
hwdec_get_hwcontext_fns(hwdec->lavc_device);
|
2017-12-01 07:01:08 +00:00
|
|
|
if (fns && fns->create_dev) {
|
|
|
|
struct hwcontext_create_dev_params params = {
|
|
|
|
.probing = autoprobe,
|
|
|
|
};
|
2017-12-01 20:05:54 +00:00
|
|
|
return fns->create_dev(vd->global, vd->log, ¶ms);
|
2017-12-01 07:01:08 +00:00
|
|
|
} else {
|
2017-12-01 20:05:54 +00:00
|
|
|
AVBufferRef* ref = NULL;
|
|
|
|
av_hwdevice_ctx_create(&ref, hwdec->lavc_device, NULL, NULL, 0);
|
|
|
|
return ref;
|
2017-10-30 17:33:18 +00:00
|
|
|
}
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
} else if (ctx->hwdec_devs) {
|
|
|
|
hwdec_devices_request_all(ctx->hwdec_devs);
|
|
|
|
return hwdec_devices_get_lavc(ctx->hwdec_devs, hwdec->lavc_device);
|
2017-02-20 07:39:55 +00:00
|
|
|
}
|
2017-12-01 20:05:54 +00:00
|
|
|
|
2017-02-20 07:39:55 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
// Select if and which hwdec to use. Also makes sure to get the decode device.
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void select_and_set_hwdec(struct mp_filter *vd)
|
2013-08-11 21:23:12 +00:00
|
|
|
{
|
2016-05-09 17:42:03 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
const char *codec = ctx->codec->codec;
|
2017-12-01 20:05:54 +00:00
|
|
|
|
2018-05-21 14:05:03 +00:00
|
|
|
m_config_cache_update(ctx->opts_cache);
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
bstr opt = bstr0(ctx->opts->hwdec_api);
|
2017-12-01 20:05:54 +00:00
|
|
|
|
|
|
|
bool hwdec_requested = !bstr_equals0(opt, "no");
|
|
|
|
bool hwdec_auto_all = bstr_equals0(opt, "auto") ||
|
|
|
|
bstr_equals0(opt, "yes") ||
|
|
|
|
bstr_equals0(opt, "");
|
|
|
|
bool hwdec_auto_copy = bstr_equals0(opt, "auto-copy");
|
|
|
|
bool hwdec_auto = hwdec_auto_all || hwdec_auto_copy;
|
|
|
|
|
2018-03-07 21:39:51 +00:00
|
|
|
if (!hwdec_requested) {
|
|
|
|
MP_VERBOSE(vd, "No hardware decoding requested.\n");
|
|
|
|
} else if (!hwdec_codec_allowed(vd, codec)) {
|
|
|
|
MP_VERBOSE(vd, "Not trying to use hardware decoding: codec %s is not "
|
|
|
|
"on whitelist.\n", codec);
|
|
|
|
} else {
|
2017-12-01 20:05:54 +00:00
|
|
|
struct hwdec_info *hwdecs = NULL;
|
|
|
|
int num_hwdecs = 0;
|
|
|
|
add_all_hwdec_methods(&hwdecs, &num_hwdecs);
|
|
|
|
|
2017-12-01 21:08:59 +00:00
|
|
|
ctx->hwdec_requested = true;
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
for (int n = 0; n < num_hwdecs; n++) {
|
|
|
|
struct hwdec_info *hwdec = &hwdecs[n];
|
|
|
|
|
|
|
|
const char *hw_codec = mp_codec_from_av_codec_id(hwdec->codec->id);
|
|
|
|
if (!hw_codec || strcmp(hw_codec, codec) != 0)
|
|
|
|
continue;
|
|
|
|
|
2017-12-01 23:57:25 +00:00
|
|
|
if (!hwdec_auto && !(bstr_equals0(opt, hwdec->method_name) ||
|
|
|
|
bstr_equals0(opt, hwdec->name)))
|
2017-12-01 20:05:54 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
MP_VERBOSE(vd, "Looking at hwdec %s...\n", hwdec->name);
|
|
|
|
|
|
|
|
if (hwdec_auto_copy && !hwdec->copying) {
|
|
|
|
MP_VERBOSE(vd, "Not using this for auto-copy.\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hwdec->lavc_device) {
|
|
|
|
ctx->hwdec_dev = hwdec_create_dev(vd, hwdec, hwdec_auto);
|
|
|
|
if (!ctx->hwdec_dev) {
|
|
|
|
MP_VERBOSE(vd, "Could not create device.\n");
|
|
|
|
continue;
|
|
|
|
}
|
2017-12-02 03:27:02 +00:00
|
|
|
|
|
|
|
const struct hwcontext_fns *fns =
|
|
|
|
hwdec_get_hwcontext_fns(hwdec->lavc_device);
|
|
|
|
if (fns && fns->is_emulated && fns->is_emulated(ctx->hwdec_dev)) {
|
|
|
|
if (hwdec_auto) {
|
|
|
|
MP_VERBOSE(vd, "Not using emulated API.\n");
|
|
|
|
av_buffer_unref(&ctx->hwdec_dev);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
MP_WARN(vd, "Using emulated hardware decoding API.\n");
|
|
|
|
}
|
2017-12-10 21:51:22 +00:00
|
|
|
} else if (!hwdec->copying) {
|
|
|
|
// Most likely METHOD_INTERNAL, which often use delay-loaded
|
|
|
|
// VO support as well.
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
if (ctx->hwdec_devs)
|
|
|
|
hwdec_devices_request_all(ctx->hwdec_devs);
|
2017-12-01 20:05:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ctx->use_hwdec = true;
|
|
|
|
ctx->hwdec = *hwdec;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
talloc_free(hwdecs);
|
2018-03-07 21:39:51 +00:00
|
|
|
|
|
|
|
if (!ctx->use_hwdec)
|
|
|
|
MP_VERBOSE(vd, "No hardware decoding available for this codec.\n");
|
2017-02-20 07:39:55 +00:00
|
|
|
}
|
2017-12-01 20:05:54 +00:00
|
|
|
|
|
|
|
if (ctx->use_hwdec) {
|
|
|
|
MP_VERBOSE(vd, "Trying hardware decoding via %s.\n", ctx->hwdec.name);
|
|
|
|
if (strcmp(ctx->decoder, ctx->hwdec.codec->name) != 0)
|
|
|
|
MP_VERBOSE(vd, "Using underlying hw-decoder '%s'\n",
|
|
|
|
ctx->hwdec.codec->name);
|
|
|
|
} else {
|
|
|
|
MP_VERBOSE(vd, "Using software decoding.\n");
|
2016-04-25 09:28:25 +00:00
|
|
|
}
|
2013-08-11 21:23:12 +00:00
|
|
|
}
|
|
|
|
|
2018-05-21 14:05:03 +00:00
|
|
|
static int hwdec_validate_opt(struct mp_log *log, const m_option_t *opt,
|
|
|
|
struct bstr name, struct bstr param)
|
2013-08-11 21:23:12 +00:00
|
|
|
{
|
2017-12-01 20:05:54 +00:00
|
|
|
if (bstr_equals0(param, "help")) {
|
|
|
|
struct hwdec_info *hwdecs = NULL;
|
|
|
|
int num_hwdecs = 0;
|
|
|
|
add_all_hwdec_methods(&hwdecs, &num_hwdecs);
|
|
|
|
|
2017-12-01 23:57:25 +00:00
|
|
|
mp_info(log, "Valid values (with alternative full names):\n");
|
2017-12-01 20:05:54 +00:00
|
|
|
|
|
|
|
for (int n = 0; n < num_hwdecs; n++) {
|
|
|
|
struct hwdec_info *hwdec = &hwdecs[n];
|
|
|
|
|
|
|
|
mp_info(log, " %s (%s)\n", hwdec->method_name, hwdec->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
talloc_free(hwdecs);
|
|
|
|
|
|
|
|
return M_OPT_EXIT;
|
2013-08-11 21:23:12 +00:00
|
|
|
}
|
2017-12-01 20:05:54 +00:00
|
|
|
return 0;
|
2013-08-11 21:23:12 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void force_fallback(struct mp_filter *vd)
|
2015-09-02 21:10:39 +00:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
|
|
|
uninit_avctx(vd);
|
2015-09-02 21:31:01 +00:00
|
|
|
int lev = ctx->hwdec_notified ? MSGL_WARN : MSGL_V;
|
|
|
|
mp_msg(vd->log, lev, "Falling back to software decoding.\n");
|
2017-12-01 20:05:54 +00:00
|
|
|
init_avctx(vd);
|
2015-09-02 21:10:39 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void reinit(struct mp_filter *vd)
|
2011-10-22 00:51:37 +00:00
|
|
|
{
|
2016-01-29 21:47:27 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2009-02-12 15:41:59 +00:00
|
|
|
|
2016-01-29 21:47:27 +00:00
|
|
|
uninit_avctx(vd);
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-27 23:49:45 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
select_and_set_hwdec(vd);
|
2012-12-11 17:16:42 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
bool use_hwdec = ctx->use_hwdec;
|
|
|
|
init_avctx(vd);
|
|
|
|
if (!ctx->avctx && use_hwdec)
|
2015-09-02 21:10:39 +00:00
|
|
|
force_fallback(vd);
|
2016-01-29 21:47:27 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void init_avctx(struct mp_filter *vd)
|
2012-12-11 17:16:42 +00:00
|
|
|
{
|
2013-11-23 20:36:20 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2018-05-21 14:05:03 +00:00
|
|
|
struct vd_lavc_params *lavc_param = ctx->opts;
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
struct mp_codec_params *c = ctx->codec;
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
|
2018-05-21 14:05:03 +00:00
|
|
|
m_config_cache_update(ctx->opts_cache);
|
|
|
|
|
2013-04-27 11:36:09 +00:00
|
|
|
assert(!ctx->avctx);
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
const AVCodec *lavc_codec = NULL;
|
|
|
|
|
|
|
|
if (ctx->use_hwdec) {
|
|
|
|
lavc_codec = ctx->hwdec.codec;
|
|
|
|
} else {
|
|
|
|
lavc_codec = avcodec_find_decoder_by_name(ctx->decoder);
|
|
|
|
}
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
if (!lavc_codec)
|
2013-04-27 11:36:09 +00:00
|
|
|
return;
|
2012-07-24 06:01:47 +00:00
|
|
|
|
2017-10-26 17:44:26 +00:00
|
|
|
const AVCodecDescriptor *desc = avcodec_descriptor_get(lavc_codec->id);
|
|
|
|
ctx->intra_only = desc && (desc->props & AV_CODEC_PROP_INTRA_ONLY);
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
ctx->codec_timebase = mp_get_codec_timebase(ctx->codec);
|
2016-08-29 10:49:18 +00:00
|
|
|
|
|
|
|
// This decoder does not read pkt_timebase correctly yet.
|
2017-12-01 20:05:54 +00:00
|
|
|
if (strstr(lavc_codec->name, "_mmal"))
|
2016-08-29 10:49:18 +00:00
|
|
|
ctx->codec_timebase = (AVRational){1, 1000000};
|
|
|
|
|
2017-08-23 12:00:24 +00:00
|
|
|
ctx->hwdec_failed = false;
|
|
|
|
ctx->hwdec_request_reinit = false;
|
2012-01-28 11:41:36 +00:00
|
|
|
ctx->avctx = avcodec_alloc_context3(lavc_codec);
|
2012-12-11 17:16:42 +00:00
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
2014-12-12 16:28:22 +00:00
|
|
|
if (!ctx->avctx)
|
2014-12-13 21:00:42 +00:00
|
|
|
goto error;
|
2011-04-19 23:59:45 +00:00
|
|
|
avctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
2009-09-23 19:21:38 +00:00
|
|
|
avctx->codec_id = lavc_codec->id;
|
2016-08-29 10:46:12 +00:00
|
|
|
|
|
|
|
#if LIBAVCODEC_VERSION_MICRO >= 100
|
|
|
|
avctx->pkt_timebase = ctx->codec_timebase;
|
|
|
|
#endif
|
2016-04-25 09:47:35 +00:00
|
|
|
|
2013-10-31 17:12:39 +00:00
|
|
|
ctx->pic = av_frame_alloc();
|
2014-12-12 16:28:22 +00:00
|
|
|
if (!ctx->pic)
|
2014-12-13 21:00:42 +00:00
|
|
|
goto error;
|
2013-10-31 17:12:39 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
if (ctx->use_hwdec) {
|
vd, vd_lavc: change license to LGPL (almost)
iive agreed only to LGPL 3.0+ only. All of his relevant changes are for
XvMC, for which mpv completely dropped support back in mplayer2 times.
But you could claim that the get_format code represents some residual
copyright (everything else added by iive was removed, only get_format
still is around in some form). While I doubt that this is relly
copyright-relevant, consider it is for now.
michael is the original author of vd_lavc.c, so this file can become
LGPL only after the core becomes LGPL.
cehoyos did not agree with the LGPL relicensing, but all of his code is
gone.
Some others could not be reached, but their code is gone as well. In
particular, vdpau support, which was originally done by Nvidia, had
larger impact on vd_lavc.c, but vdpau support was first refactored a few
times (for the purpose of modularization) and moved to different files,
and then decoding was completely moved to libavcodec.
Lastly, assigning the "opaque" field was moved by Gwenole Beauchesne in
commit 8e5edec13eab. Agreement is pending (due to copyright apparently
owned by the author's employer). So just undo the change, so we don't
have to think about whether the change is copyrightable.
2017-06-15 13:52:18 +00:00
|
|
|
avctx->opaque = vd;
|
2016-04-25 10:12:40 +00:00
|
|
|
avctx->thread_count = 1;
|
2017-03-23 10:06:28 +00:00
|
|
|
avctx->hwaccel_flags |= AV_HWACCEL_FLAG_IGNORE_LEVEL;
|
2017-07-04 12:58:34 +00:00
|
|
|
if (!lavc_param->check_hw_profile)
|
|
|
|
avctx->hwaccel_flags |= AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH;
|
2017-12-01 20:05:54 +00:00
|
|
|
|
|
|
|
if (ctx->hwdec.use_hw_device) {
|
|
|
|
if (ctx->hwdec_dev)
|
|
|
|
avctx->hw_device_ctx = av_buffer_ref(ctx->hwdec_dev);
|
|
|
|
if (!avctx->hw_device_ctx)
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (ctx->hwdec.use_hw_frames) {
|
2017-02-20 07:39:55 +00:00
|
|
|
if (!ctx->hwdec_dev)
|
|
|
|
goto error;
|
|
|
|
}
|
2017-12-01 20:05:54 +00:00
|
|
|
|
|
|
|
if (ctx->hwdec.pix_fmt != AV_PIX_FMT_NONE)
|
|
|
|
avctx->get_format = get_format_hwdec;
|
|
|
|
|
|
|
|
// Some APIs benefit from this, for others it's additional bloat.
|
|
|
|
if (ctx->hwdec.copying)
|
|
|
|
ctx->max_delay_queue = HWDEC_DELAY_QUEUE_COUNT;
|
2017-01-10 15:49:06 +00:00
|
|
|
ctx->hw_probing = true;
|
2013-03-09 19:21:12 +00:00
|
|
|
} else {
|
2015-01-05 11:17:55 +00:00
|
|
|
mp_set_avcodec_threads(vd->log, avctx, lavc_param->threads);
|
2010-12-20 03:53:28 +00:00
|
|
|
}
|
2002-09-06 22:53:26 +00:00
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
if (!ctx->use_hwdec && ctx->vo && lavc_param->dr) {
|
2017-07-23 07:41:51 +00:00
|
|
|
avctx->opaque = vd;
|
|
|
|
avctx->get_buffer2 = get_buffer2_direct;
|
|
|
|
avctx->thread_safe_callbacks = 1;
|
|
|
|
}
|
|
|
|
|
2016-12-29 06:37:31 +00:00
|
|
|
avctx->flags |= lavc_param->bitexact ? AV_CODEC_FLAG_BITEXACT : 0;
|
|
|
|
avctx->flags2 |= lavc_param->fast ? AV_CODEC_FLAG2_FAST : 0;
|
2009-02-12 15:41:59 +00:00
|
|
|
|
2016-04-25 17:11:16 +00:00
|
|
|
if (lavc_param->show_all)
|
2016-12-29 06:37:31 +00:00
|
|
|
avctx->flags |= AV_CODEC_FLAG_OUTPUT_CORRUPT;
|
2013-12-29 13:07:08 +00:00
|
|
|
|
2014-06-13 00:03:45 +00:00
|
|
|
avctx->skip_loop_filter = lavc_param->skip_loop_filter;
|
|
|
|
avctx->skip_idct = lavc_param->skip_idct;
|
|
|
|
avctx->skip_frame = lavc_param->skip_frame;
|
2017-12-26 04:53:44 +00:00
|
|
|
|
|
|
|
if (lavc_codec->id == AV_CODEC_ID_H264 && lavc_param->old_x264)
|
|
|
|
av_opt_set(avctx, "x264_build", "150", AV_OPT_SEARCH_CHILDREN);
|
2008-05-10 18:55:31 +00:00
|
|
|
|
2014-08-02 01:12:09 +00:00
|
|
|
mp_set_avopts(vd->log, avctx, lavc_param->avopts);
|
2008-05-10 18:55:31 +00:00
|
|
|
|
2011-07-09 10:50:16 +00:00
|
|
|
// Do this after the above avopt handling in case it changes values
|
|
|
|
ctx->skip_frame = avctx->skip_frame;
|
|
|
|
|
2017-01-25 07:24:19 +00:00
|
|
|
if (mp_set_avctx_codec_headers(avctx, c) < 0) {
|
|
|
|
MP_ERR(vd, "Could not set codec parameters.\n");
|
|
|
|
goto error;
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
}
|
|
|
|
|
2002-03-06 20:54:43 +00:00
|
|
|
/* open it */
|
2014-12-13 21:00:42 +00:00
|
|
|
if (avcodec_open2(avctx, lavc_codec, NULL) < 0)
|
|
|
|
goto error;
|
|
|
|
|
2017-12-26 05:09:26 +00:00
|
|
|
// Sometimes, the first packet contains information required for correct
|
|
|
|
// decoding of the rest of the stream. The only currently known case is the
|
|
|
|
// x264 build number (encoded in a SEI element), needed to enable a
|
|
|
|
// workaround for broken 4:4:4 streams produced by older x264 versions.
|
|
|
|
if (lavc_codec->id == AV_CODEC_ID_H264 && c->first_packet) {
|
|
|
|
AVPacket avpkt;
|
|
|
|
mp_set_av_packet(&avpkt, c->first_packet, &ctx->codec_timebase);
|
|
|
|
avcodec_send_packet(avctx, &avpkt);
|
|
|
|
avcodec_receive_frame(avctx, ctx->pic);
|
|
|
|
av_frame_unref(ctx->pic);
|
|
|
|
avcodec_flush_buffers(ctx->avctx);
|
|
|
|
}
|
|
|
|
|
2014-12-13 21:00:42 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
|
|
|
MP_ERR(vd, "Could not open codec.\n");
|
|
|
|
uninit_avctx(vd);
|
2002-03-06 20:54:43 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void reset_avctx(struct mp_filter *vd)
|
2015-11-10 15:06:42 +00:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
2016-02-06 09:09:13 +00:00
|
|
|
if (ctx->avctx && avcodec_is_open(ctx->avctx))
|
2015-11-10 15:06:42 +00:00
|
|
|
avcodec_flush_buffers(ctx->avctx);
|
|
|
|
ctx->flushing = false;
|
2017-08-23 12:00:24 +00:00
|
|
|
ctx->hwdec_request_reinit = false;
|
2015-11-10 15:06:42 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void flush_all(struct mp_filter *vd)
|
2016-01-25 20:00:53 +00:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
|
|
|
for (int n = 0; n < ctx->num_delay_queue; n++)
|
|
|
|
talloc_free(ctx->delay_queue[n]);
|
|
|
|
ctx->num_delay_queue = 0;
|
|
|
|
|
2017-01-10 15:49:06 +00:00
|
|
|
for (int n = 0; n < ctx->num_sent_packets; n++)
|
|
|
|
talloc_free(ctx->sent_packets[n]);
|
|
|
|
ctx->num_sent_packets = 0;
|
|
|
|
|
|
|
|
for (int n = 0; n < ctx->num_requeue_packets; n++)
|
|
|
|
talloc_free(ctx->requeue_packets[n]);
|
|
|
|
ctx->num_requeue_packets = 0;
|
2017-01-10 15:19:57 +00:00
|
|
|
|
2016-01-25 20:00:53 +00:00
|
|
|
reset_avctx(vd);
|
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void uninit_avctx(struct mp_filter *vd)
|
2011-10-22 00:51:37 +00:00
|
|
|
{
|
2013-11-23 20:36:20 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2009-02-12 15:41:59 +00:00
|
|
|
|
2016-01-30 19:59:25 +00:00
|
|
|
flush_all(vd);
|
|
|
|
av_frame_free(&ctx->pic);
|
2017-01-17 09:56:16 +00:00
|
|
|
av_buffer_unref(&ctx->cached_hw_frames_ctx);
|
2016-01-30 19:59:25 +00:00
|
|
|
|
2017-07-06 14:12:50 +00:00
|
|
|
avcodec_free_context(&ctx->avctx);
|
2005-01-08 19:16:21 +00:00
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
av_buffer_unref(&ctx->hwdec_dev);
|
2017-02-20 07:39:55 +00:00
|
|
|
|
vd_lavc: make hardware decoding fallback less violent
Most of hardware decoding is initialized lazily. When the first packet
is parsed, libavcodec will call get_format() to check whether hw or sw
decoding is wanted. Until now, we've returned AV_PIX_FMT_NONE from
get_format() if hw decoder initialization failed. This caused the
avcodec_decode_video2() call to fail, which in turn let us trigger the
fallback. We didn't return a sw format from get_format(), because we
didn't want to continue decoding at all. (The reason being that full
reinitialization is more robust when continuing sw decoding.)
This has some disadvantages. libavcodec vomited some unwanted error
messages. Sometimes the failures are more severe, like it happened with
HEVC. In this case, the error code path simply acted up in a way that
was extremely inconvenient (and had to be fixed by myself). In general,
libavcodec is not designed to fallback this way.
Make it a bit less violent from the API usage point of view. Return a sw
format if hw decoder initialization fails. In this case, we let
get_buffer2() call avcodec_default_get_buffer2() as well. libavcodec is
allowed to perform its own sw fallback. But once the decode function
returns, we do the full reinitialization we wanted to do.
The result is that the fallback is more robust, and doesn't trigger any
decoder error codepaths or messages either. Change our own fallback
message to a warning, since there are no other messages with error
severity anymore.
2015-05-28 19:52:04 +00:00
|
|
|
ctx->hwdec_failed = false;
|
2015-11-03 13:03:02 +00:00
|
|
|
ctx->hwdec_fail_count = 0;
|
2016-01-25 20:00:53 +00:00
|
|
|
ctx->max_delay_queue = 0;
|
2017-01-10 15:49:06 +00:00
|
|
|
ctx->hw_probing = false;
|
2017-12-01 20:05:54 +00:00
|
|
|
ctx->hwdec = (struct hwdec_info){0};
|
|
|
|
ctx->use_hwdec = false;
|
2002-03-06 20:54:43 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static int init_generic_hwaccel(struct mp_filter *vd, enum AVPixelFormat hw_fmt)
|
2017-10-27 15:22:32 +00:00
|
|
|
{
|
|
|
|
struct lavc_ctx *ctx = vd->priv;
|
|
|
|
AVBufferRef *new_frames_ctx = NULL;
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
if (!ctx->hwdec.use_hw_frames)
|
2017-10-27 15:22:32 +00:00
|
|
|
return 0;
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
if (!ctx->hwdec_dev) {
|
2017-10-27 15:22:32 +00:00
|
|
|
MP_ERR(ctx, "Missing device context.\n");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (avcodec_get_hw_frames_parameters(ctx->avctx,
|
2017-12-01 20:05:54 +00:00
|
|
|
ctx->hwdec_dev, hw_fmt, &new_frames_ctx) < 0)
|
2017-10-27 15:22:32 +00:00
|
|
|
{
|
|
|
|
MP_VERBOSE(ctx, "Hardware decoding of this stream is unsupported?\n");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
AVHWFramesContext *new_fctx = (void *)new_frames_ctx->data;
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
if (ctx->opts->hwdec_image_format)
|
|
|
|
new_fctx->sw_format = imgfmt2pixfmt(ctx->opts->hwdec_image_format);
|
2017-10-27 15:22:32 +00:00
|
|
|
|
|
|
|
// 1 surface is already included by libavcodec. The field is 0 if the
|
|
|
|
// hwaccel supports dynamic surface allocation.
|
|
|
|
if (new_fctx->initial_pool_size)
|
2019-05-31 18:11:32 +00:00
|
|
|
new_fctx->initial_pool_size += ctx->opts->hwdec_extra_frames - 1;
|
2017-10-27 15:22:32 +00:00
|
|
|
|
2017-12-01 05:47:37 +00:00
|
|
|
const struct hwcontext_fns *fns =
|
|
|
|
hwdec_get_hwcontext_fns(new_fctx->device_ctx->type);
|
|
|
|
|
|
|
|
if (fns && fns->refine_hwframes)
|
|
|
|
fns->refine_hwframes(new_frames_ctx);
|
2017-10-27 15:22:32 +00:00
|
|
|
|
|
|
|
// We might be able to reuse a previously allocated frame pool.
|
|
|
|
if (ctx->cached_hw_frames_ctx) {
|
|
|
|
AVHWFramesContext *old_fctx = (void *)ctx->cached_hw_frames_ctx->data;
|
|
|
|
|
|
|
|
if (new_fctx->format != old_fctx->format ||
|
|
|
|
new_fctx->sw_format != old_fctx->sw_format ||
|
|
|
|
new_fctx->width != old_fctx->width ||
|
|
|
|
new_fctx->height != old_fctx->height ||
|
|
|
|
new_fctx->initial_pool_size != old_fctx->initial_pool_size)
|
|
|
|
av_buffer_unref(&ctx->cached_hw_frames_ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ctx->cached_hw_frames_ctx) {
|
|
|
|
if (av_hwframe_ctx_init(new_frames_ctx) < 0) {
|
|
|
|
MP_ERR(ctx, "Failed to allocate hw frames.\n");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->cached_hw_frames_ctx = new_frames_ctx;
|
|
|
|
new_frames_ctx = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->avctx->hw_frames_ctx = av_buffer_ref(ctx->cached_hw_frames_ctx);
|
|
|
|
if (!ctx->avctx->hw_frames_ctx)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
av_buffer_unref(&new_frames_ctx);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
av_buffer_unref(&new_frames_ctx);
|
|
|
|
av_buffer_unref(&ctx->cached_hw_frames_ctx);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-11-29 16:39:57 +00:00
|
|
|
static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
|
|
|
|
const enum AVPixelFormat *fmt)
|
2012-11-06 14:27:44 +00:00
|
|
|
{
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
struct mp_filter *vd = avctx->opaque;
|
2013-11-23 20:36:20 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2012-11-06 14:27:44 +00:00
|
|
|
|
2013-12-21 16:47:38 +00:00
|
|
|
MP_VERBOSE(vd, "Pixel formats supported by decoder:");
|
2013-11-29 16:39:57 +00:00
|
|
|
for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++)
|
2013-12-21 16:47:38 +00:00
|
|
|
MP_VERBOSE(vd, " %s", av_get_pix_fmt_name(fmt[i]));
|
|
|
|
MP_VERBOSE(vd, "\n");
|
2012-12-11 17:16:42 +00:00
|
|
|
|
2016-01-08 08:13:56 +00:00
|
|
|
const char *profile = avcodec_profile_name(avctx->codec_id, avctx->profile);
|
|
|
|
MP_VERBOSE(vd, "Codec profile: %s (0x%x)\n", profile ? profile : "unknown",
|
|
|
|
avctx->profile);
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
assert(ctx->use_hwdec);
|
2012-12-11 17:16:42 +00:00
|
|
|
|
2015-10-12 19:24:25 +00:00
|
|
|
ctx->hwdec_request_reinit |= ctx->hwdec_failed;
|
|
|
|
ctx->hwdec_failed = false;
|
|
|
|
|
2017-03-01 15:02:08 +00:00
|
|
|
enum AVPixelFormat select = AV_PIX_FMT_NONE;
|
2016-04-25 10:12:40 +00:00
|
|
|
for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++) {
|
2017-12-01 20:05:54 +00:00
|
|
|
if (ctx->hwdec.pix_fmt == fmt[i]) {
|
|
|
|
if (init_generic_hwaccel(vd, fmt[i]) < 0)
|
|
|
|
break;
|
2017-03-01 15:02:08 +00:00
|
|
|
select = fmt[i];
|
|
|
|
break;
|
vdpau: split off decoder parts, use "new" libavcodec vdpau hwaccel API
Move the decoder parts from vo_vdpau.c to a new file vdpau_old.c. This
file is named so because because it's written against the "old"
libavcodec vdpau pseudo-decoder (e.g. "h264_vdpau").
Add support for the "new" libavcodec vdpau support. This was recently
added and replaces the "old" vdpau parts. (In fact, Libav is about to
deprecate and remove the "old" API without deprecation grace period,
so we have to support it now. Moreover, there will probably be no Libav
release which supports both, so the transition is even less smooth than
we could hope, and we have to support both the old and new API.)
Whether the old or new API is used is checked by a configure test: if
the new API is found, it is used, otherwise the old API is assumed.
Some details might be handled differently. Especially display preemption
is a bit problematic with the "new" libavcodec vdpau support: it wants
to keep a pointer to a specific vdpau API function (which can be driver
specific, because preemption might switch drivers). Also, surface IDs
are now directly stored in AVFrames (and mp_images), so they can't be
forced to VDP_INVALID_HANDLE on preemption. (This changes even with
older libavcodec versions, because mp_image always uses the newer
representation to make vo_vdpau.c simpler.)
Decoder initialization in the new code tries to deal with codec
profiles, while the old code always uses the highest profile per codec.
Surface allocation changes. Since the decoder won't call config() in
vo_vdpau.c on video size change anymore, we allow allocating surfaces
of arbitrary size instead of locking it to what the VO was configured.
The non-hwdec code also has slightly different allocation behavior now.
Enabling the old vdpau special decoders via e.g. --vd=lavc:h264_vdpau
doesn't work anymore (a warning suggesting the --hwdec option is
printed instead).
2013-07-27 23:49:45 +00:00
|
|
|
}
|
2012-11-06 14:27:44 +00:00
|
|
|
}
|
2012-12-11 17:16:42 +00:00
|
|
|
|
2017-03-01 15:02:08 +00:00
|
|
|
if (select == AV_PIX_FMT_NONE) {
|
|
|
|
ctx->hwdec_failed = true;
|
2018-05-16 18:54:46 +00:00
|
|
|
select = avcodec_default_get_format(avctx, fmt);
|
2015-05-29 12:17:51 +00:00
|
|
|
}
|
2017-03-01 15:02:08 +00:00
|
|
|
|
|
|
|
const char *name = av_get_pix_fmt_name(select);
|
|
|
|
MP_VERBOSE(vd, "Requesting pixfmt '%s' from decoder.\n", name ? name : "-");
|
|
|
|
return select;
|
2012-11-06 14:27:44 +00:00
|
|
|
}
|
|
|
|
|
2017-07-23 07:41:51 +00:00
|
|
|
static int get_buffer2_direct(AVCodecContext *avctx, AVFrame *pic, int flags)
|
|
|
|
{
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
struct mp_filter *vd = avctx->opaque;
|
2017-07-23 07:41:51 +00:00
|
|
|
vd_ffmpeg_ctx *p = vd->priv;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&p->dr_lock);
|
|
|
|
|
|
|
|
int w = pic->width;
|
|
|
|
int h = pic->height;
|
|
|
|
int linesize_align[AV_NUM_DATA_POINTERS] = {0};
|
|
|
|
avcodec_align_dimensions2(avctx, &w, &h, linesize_align);
|
|
|
|
|
|
|
|
// We assume that different alignments are just different power-of-2s.
|
|
|
|
// Thus, a higher alignment always satisfies a lower alignment.
|
video: generally try to align image data on 64 bytes
Generally, using x86 SIMD efficiently (or crash-free) requires aligning
all data on boundaries of 16, 32, or 64 (depending on instruction set
used). 64 bytes is needed or AVX-512, 32 for old AVX, 16 for SSE. Both
FFmpeg and zimg usually require aligned data for this reason.
FFmpeg is very unclear about alignment. Yes, it requires you to align
data pointers and strides. No, it doesn't tell you how much, except
sometimes (libavcodec has a legacy-looking avcodec_align_dimensions2()
API function, that requires a heavy-weight AVCodecContext as argument).
Sometimes, FFmpeg will take a shit on YOUR and ITS OWN alignment. For
example, vf_crop will randomly reduce alignment of data pointers,
depending on the crop parameters. On the other hand, some libavfilter
filters or libavcodec encoders may randomly crash if they get the wrong
alignment. I have no idea how this thing works at all.
FFmpeg usually doesn't seem to signal alignment internal anywhere, and
usually leaves it to av_malloc() etc. to allocate with proper alignment.
libavutil/mem.c currently has a ALIGN define, which is set to 64 if
FFmpeg is built with AVX-512 support, or as low as 16 if built without
any AVX support. The really funny thing is that a normal FFmpeg build
will e.g. align tiny string allocations to 64 bytes, even if the machine
does not support AVX at all.
For zimg use (in a later commit), we also want guaranteed alignment.
Modern x86 should actually not be much slower at unaligned accesses, but
that doesn't help. zimg's dumb intrinsic code apparently randomly
chooses between aligned or unaligned accesses (depending on compiler, I
guess), and on some CPUs these can even cause crashes. So just treat the
requirement to align as a fact of life.
All this means that we should probably make sure our own allocations are
64 bit aligned. This still doesn't guarantee alignment in all cases, but
it's slightly better than before.
This also makes me wonder whether we should always override libavcodec's
buffer pool, just so we have a guaranteed alignment. Currently, we only
do that if --vd-lavc-dr is used (and if that actually works). On the
other hand, it always uses DR on my machine, so who cares.
2019-07-15 01:06:47 +00:00
|
|
|
int stride_align = MP_IMAGE_BYTE_ALIGN;
|
2017-07-23 07:41:51 +00:00
|
|
|
for (int n = 0; n < AV_NUM_DATA_POINTERS; n++)
|
|
|
|
stride_align = MPMAX(stride_align, linesize_align[n]);
|
|
|
|
|
|
|
|
int imgfmt = pixfmt2imgfmt(pic->format);
|
|
|
|
if (!imgfmt)
|
|
|
|
goto fallback;
|
|
|
|
|
|
|
|
if (p->dr_failed)
|
|
|
|
goto fallback;
|
|
|
|
|
|
|
|
// (For simplicity, we realloc on any parameter change, instead of trying
|
|
|
|
// to be clever.)
|
|
|
|
if (stride_align != p->dr_stride_align || w != p->dr_w || h != p->dr_h ||
|
|
|
|
imgfmt != p->dr_imgfmt)
|
|
|
|
{
|
|
|
|
mp_image_pool_clear(p->dr_pool);
|
|
|
|
p->dr_imgfmt = imgfmt;
|
|
|
|
p->dr_w = w;
|
|
|
|
p->dr_h = h;
|
|
|
|
p->dr_stride_align = stride_align;
|
2017-09-28 09:53:57 +00:00
|
|
|
MP_DBG(p, "DR parameter change to %dx%d %s align=%d\n", w, h,
|
|
|
|
mp_imgfmt_to_name(imgfmt), stride_align);
|
2017-07-23 07:41:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct mp_image *img = mp_image_pool_get_no_alloc(p->dr_pool, imgfmt, w, h);
|
|
|
|
if (!img) {
|
2017-09-28 09:53:57 +00:00
|
|
|
MP_DBG(p, "Allocating new DR image...\n");
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
img = vo_get_image(p->vo, imgfmt, w, h, stride_align);
|
2017-07-23 07:41:51 +00:00
|
|
|
if (!img) {
|
2017-09-28 09:53:57 +00:00
|
|
|
MP_DBG(p, "...failed..\n");
|
2017-07-23 07:41:51 +00:00
|
|
|
goto fallback;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now make the mp_image part of the pool. This requires doing magic to
|
|
|
|
// the image, so just add it to the pool and get it back to avoid
|
|
|
|
// dealing with magic ourselves. (Normally this never fails.)
|
|
|
|
mp_image_pool_add(p->dr_pool, img);
|
|
|
|
img = mp_image_pool_get_no_alloc(p->dr_pool, imgfmt, w, h);
|
|
|
|
if (!img)
|
|
|
|
goto fallback;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get_buffer2 callers seem very unappreciative of overwriting pic with a
|
|
|
|
// new reference. The AVCodecContext.get_buffer2 comments tell us exactly
|
|
|
|
// what we should do, so follow that.
|
|
|
|
for (int n = 0; n < 4; n++) {
|
|
|
|
pic->data[n] = img->planes[n];
|
|
|
|
pic->linesize[n] = img->stride[n];
|
|
|
|
pic->buf[n] = img->bufs[n];
|
|
|
|
img->bufs[n] = NULL;
|
|
|
|
}
|
|
|
|
talloc_free(img);
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&p->dr_lock);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fallback:
|
|
|
|
if (!p->dr_failed)
|
|
|
|
MP_VERBOSE(p, "DR failed - disabling.\n");
|
|
|
|
p->dr_failed = true;
|
|
|
|
pthread_mutex_unlock(&p->dr_lock);
|
|
|
|
|
|
|
|
return avcodec_default_get_buffer2(avctx, pic, flags);
|
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static bool prepare_decoding(struct mp_filter *vd)
|
2009-11-21 18:53:10 +00:00
|
|
|
{
|
2013-11-23 20:36:20 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2002-07-14 19:44:40 +00:00
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
2018-05-21 14:05:03 +00:00
|
|
|
struct vd_lavc_params *opts = ctx->opts;
|
2002-07-14 19:44:40 +00:00
|
|
|
|
2017-01-10 15:19:57 +00:00
|
|
|
if (!avctx || ctx->hwdec_failed)
|
|
|
|
return false;
|
2015-12-05 22:53:55 +00:00
|
|
|
|
2017-01-10 15:19:57 +00:00
|
|
|
int drop = ctx->framedrop_flags;
|
2017-10-26 17:44:26 +00:00
|
|
|
if (drop == 1) {
|
|
|
|
avctx->skip_frame = opts->framedrop; // normal framedrop
|
|
|
|
} else if (drop == 2) {
|
|
|
|
avctx->skip_frame = AVDISCARD_NONREF; // hr-seek framedrop
|
|
|
|
// Can be much more aggressive for true intra codecs.
|
|
|
|
if (ctx->intra_only)
|
|
|
|
avctx->skip_frame = AVDISCARD_ALL;
|
2014-08-08 22:35:25 +00:00
|
|
|
} else {
|
2017-10-26 17:44:26 +00:00
|
|
|
avctx->skip_frame = ctx->skip_frame; // normal playback
|
2014-08-08 22:35:25 +00:00
|
|
|
}
|
2002-07-14 19:44:40 +00:00
|
|
|
|
2017-01-10 15:19:57 +00:00
|
|
|
if (ctx->hwdec_request_reinit)
|
2015-11-10 15:06:42 +00:00
|
|
|
reset_avctx(vd);
|
2013-06-02 23:55:48 +00:00
|
|
|
|
2017-01-10 15:19:57 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void handle_err(struct mp_filter *vd)
|
2017-01-10 15:19:57 +00:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2018-05-21 14:05:03 +00:00
|
|
|
struct vd_lavc_params *opts = ctx->opts;
|
2017-01-10 15:19:57 +00:00
|
|
|
|
|
|
|
MP_WARN(vd, "Error while decoding frame!\n");
|
|
|
|
|
2017-12-01 20:05:54 +00:00
|
|
|
if (ctx->use_hwdec) {
|
2017-01-10 15:19:57 +00:00
|
|
|
ctx->hwdec_fail_count += 1;
|
2017-09-26 17:13:26 +00:00
|
|
|
if (ctx->hwdec_fail_count >= opts->software_fallback)
|
2017-01-10 15:19:57 +00:00
|
|
|
ctx->hwdec_failed = true;
|
2016-03-24 16:53:30 +00:00
|
|
|
}
|
2017-01-10 15:19:57 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static bool do_send_packet(struct mp_filter *vd, struct demux_packet *pkt)
|
2017-01-10 15:19:57 +00:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
|
|
|
|
|
|
|
if (!prepare_decoding(vd))
|
|
|
|
return false;
|
|
|
|
|
2017-10-26 17:44:26 +00:00
|
|
|
if (avctx->skip_frame == AVDISCARD_ALL)
|
|
|
|
return true;
|
|
|
|
|
2017-01-10 15:19:57 +00:00
|
|
|
AVPacket avpkt;
|
|
|
|
mp_set_av_packet(&avpkt, pkt, &ctx->codec_timebase);
|
|
|
|
|
|
|
|
int ret = avcodec_send_packet(avctx, pkt ? &avpkt : NULL);
|
|
|
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
|
|
|
return false;
|
2015-11-10 15:06:42 +00:00
|
|
|
|
2017-01-10 15:49:06 +00:00
|
|
|
if (ctx->hw_probing && ctx->num_sent_packets < 32) {
|
|
|
|
pkt = pkt ? demux_copy_packet(pkt) : NULL;
|
|
|
|
MP_TARRAY_APPEND(ctx, ctx->sent_packets, ctx->num_sent_packets, pkt);
|
|
|
|
}
|
2003-04-06 23:37:56 +00:00
|
|
|
|
2017-01-10 15:19:57 +00:00
|
|
|
if (ret < 0)
|
|
|
|
handle_err(vd);
|
|
|
|
return true;
|
|
|
|
}
|
2015-10-19 15:49:30 +00:00
|
|
|
|
2018-02-04 18:00:28 +00:00
|
|
|
static bool send_queued(struct mp_filter *vd)
|
2017-01-10 15:49:06 +00:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
2018-02-04 18:00:28 +00:00
|
|
|
while (ctx->num_requeue_packets && do_send_packet(vd, ctx->requeue_packets[0]))
|
|
|
|
{
|
|
|
|
talloc_free(ctx->requeue_packets[0]);
|
|
|
|
MP_TARRAY_REMOVE_AT(ctx->requeue_packets, ctx->num_requeue_packets, 0);
|
2017-01-10 15:49:06 +00:00
|
|
|
}
|
|
|
|
|
2018-02-04 18:00:28 +00:00
|
|
|
return ctx->num_requeue_packets == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool send_packet(struct mp_filter *vd, struct demux_packet *pkt)
|
|
|
|
{
|
|
|
|
if (!send_queued(vd))
|
|
|
|
return false;
|
|
|
|
|
2017-01-10 15:49:06 +00:00
|
|
|
return do_send_packet(vd, pkt);
|
|
|
|
}
|
|
|
|
|
2017-01-11 09:56:25 +00:00
|
|
|
// Returns whether decoder is still active (!EOF state).
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static bool decode_frame(struct mp_filter *vd)
|
2017-01-10 15:19:57 +00:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
2016-02-19 17:35:11 +00:00
|
|
|
|
2017-01-10 15:19:57 +00:00
|
|
|
if (!prepare_decoding(vd))
|
2017-01-11 09:56:25 +00:00
|
|
|
return true;
|
2017-01-10 15:19:57 +00:00
|
|
|
|
|
|
|
int ret = avcodec_receive_frame(avctx, ctx->pic);
|
|
|
|
if (ret == AVERROR_EOF) {
|
|
|
|
// If flushing was initialized earlier and has ended now, make it start
|
2018-02-05 20:09:30 +00:00
|
|
|
// over in case we get new packets at some point in the future. This
|
|
|
|
// must take the delay queue into account, so avctx returns EOF until
|
|
|
|
// the delay queue has been drained.
|
|
|
|
if (!ctx->num_delay_queue)
|
|
|
|
reset_avctx(vd);
|
2017-01-11 09:56:25 +00:00
|
|
|
return false;
|
2017-01-10 15:19:57 +00:00
|
|
|
} else if (ret < 0 && ret != AVERROR(EAGAIN)) {
|
|
|
|
handle_err(vd);
|
2016-01-25 20:00:53 +00:00
|
|
|
}
|
2015-10-19 16:19:57 +00:00
|
|
|
|
2017-01-10 15:19:57 +00:00
|
|
|
if (!ctx->pic->buf[0])
|
2017-01-11 09:56:25 +00:00
|
|
|
return true;
|
2017-01-10 15:19:57 +00:00
|
|
|
|
2015-11-03 13:03:02 +00:00
|
|
|
ctx->hwdec_fail_count = 0;
|
|
|
|
|
2014-03-16 08:21:21 +00:00
|
|
|
struct mp_image *mpi = mp_image_from_av_frame(ctx->pic);
|
2016-01-25 19:47:13 +00:00
|
|
|
if (!mpi) {
|
|
|
|
av_frame_unref(ctx->pic);
|
2017-01-11 09:56:25 +00:00
|
|
|
return true;
|
2016-01-25 19:47:13 +00:00
|
|
|
}
|
2014-03-23 18:20:43 +00:00
|
|
|
assert(mpi->planes[0] || mpi->planes[3]);
|
2016-12-07 18:44:29 +00:00
|
|
|
mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase);
|
2016-03-24 15:38:14 +00:00
|
|
|
mpi->dts = mp_pts_from_av(ctx->pic->pkt_dts, &ctx->codec_timebase);
|
2016-01-25 19:47:13 +00:00
|
|
|
|
2016-12-21 17:18:24 +00:00
|
|
|
#if LIBAVCODEC_VERSION_MICRO >= 100
|
|
|
|
mpi->pkt_duration =
|
2017-10-30 12:36:44 +00:00
|
|
|
mp_pts_from_av(ctx->pic->pkt_duration, &ctx->codec_timebase);
|
2016-12-21 17:18:24 +00:00
|
|
|
#endif
|
|
|
|
|
2016-01-25 19:47:13 +00:00
|
|
|
av_frame_unref(ctx->pic);
|
|
|
|
|
2016-01-25 20:00:53 +00:00
|
|
|
MP_TARRAY_APPEND(ctx, ctx->delay_queue, ctx->num_delay_queue, mpi);
|
2017-01-11 09:56:25 +00:00
|
|
|
return true;
|
2012-12-11 17:16:42 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static bool receive_frame(struct mp_filter *vd, struct mp_frame *out_frame)
|
2013-12-10 18:07:29 +00:00
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
2017-01-11 09:56:25 +00:00
|
|
|
bool progress = decode_frame(vd);
|
2017-01-10 15:19:57 +00:00
|
|
|
|
2015-09-23 18:37:47 +00:00
|
|
|
if (ctx->hwdec_failed) {
|
2013-12-10 18:07:29 +00:00
|
|
|
// Failed hardware decoding? Try again in software.
|
2017-01-10 15:49:06 +00:00
|
|
|
struct demux_packet **pkts = ctx->sent_packets;
|
|
|
|
int num_pkts = ctx->num_sent_packets;
|
|
|
|
ctx->sent_packets = NULL;
|
|
|
|
ctx->num_sent_packets = 0;
|
2017-01-10 15:19:57 +00:00
|
|
|
|
2016-04-22 13:45:23 +00:00
|
|
|
force_fallback(vd);
|
2012-12-11 17:16:42 +00:00
|
|
|
|
2017-01-10 15:49:06 +00:00
|
|
|
ctx->requeue_packets = pkts;
|
|
|
|
ctx->num_requeue_packets = num_pkts;
|
2018-02-04 18:00:28 +00:00
|
|
|
|
|
|
|
send_queued(vd);
|
|
|
|
progress = decode_frame(vd);
|
2015-09-02 21:31:01 +00:00
|
|
|
}
|
|
|
|
|
2017-01-11 09:58:30 +00:00
|
|
|
if (!ctx->num_delay_queue)
|
|
|
|
return progress;
|
|
|
|
|
|
|
|
if (ctx->num_delay_queue <= ctx->max_delay_queue && progress)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
struct mp_image *res = ctx->delay_queue[0];
|
|
|
|
MP_TARRAY_REMOVE_AT(ctx->delay_queue, ctx->num_delay_queue, 0);
|
|
|
|
|
|
|
|
res = res ? mp_img_swap_to_native(res) : NULL;
|
|
|
|
if (!res)
|
|
|
|
return progress;
|
|
|
|
|
2017-12-02 01:45:49 +00:00
|
|
|
if (ctx->use_hwdec && ctx->hwdec.copying && res->hwctx) {
|
2017-01-12 12:15:45 +00:00
|
|
|
struct mp_image *sw = mp_image_hw_download(res, ctx->hwdec_swpool);
|
|
|
|
mp_image_unrefp(&res);
|
|
|
|
res = sw;
|
|
|
|
if (!res) {
|
|
|
|
MP_ERR(vd, "Could not copy back hardware decoded frame.\n");
|
2017-01-17 10:03:42 +00:00
|
|
|
ctx->hwdec_fail_count = INT_MAX - 1; // force fallback
|
2017-01-12 12:15:45 +00:00
|
|
|
handle_err(vd);
|
2018-02-05 20:09:30 +00:00
|
|
|
return true;
|
2017-01-12 12:15:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-01 21:08:59 +00:00
|
|
|
if (!ctx->hwdec_notified && ctx->hwdec_requested) {
|
2017-12-01 20:05:54 +00:00
|
|
|
if (ctx->use_hwdec) {
|
2017-01-11 09:58:30 +00:00
|
|
|
MP_INFO(vd, "Using hardware decoding (%s).\n",
|
2017-12-01 20:05:54 +00:00
|
|
|
ctx->hwdec.method_name);
|
2017-01-11 09:58:30 +00:00
|
|
|
} else {
|
2017-01-13 17:52:07 +00:00
|
|
|
MP_VERBOSE(vd, "Using software decoding.\n");
|
2017-01-11 09:58:30 +00:00
|
|
|
}
|
|
|
|
ctx->hwdec_notified = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ctx->hw_probing) {
|
|
|
|
for (int n = 0; n < ctx->num_sent_packets; n++)
|
|
|
|
talloc_free(ctx->sent_packets[n]);
|
|
|
|
ctx->num_sent_packets = 0;
|
|
|
|
ctx->hw_probing = false;
|
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
*out_frame = MAKE_FRAME(MP_FRAME_VIDEO, res);
|
2017-01-11 09:58:30 +00:00
|
|
|
return true;
|
2002-03-06 20:54:43 +00:00
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static int control(struct mp_filter *vd, enum dec_ctrl cmd, void *arg)
|
2011-11-14 18:12:20 +00:00
|
|
|
{
|
2013-11-23 20:36:20 +00:00
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
2011-11-14 18:12:20 +00:00
|
|
|
switch (cmd) {
|
2017-01-10 15:19:57 +00:00
|
|
|
case VDCTRL_SET_FRAMEDROP:
|
|
|
|
ctx->framedrop_flags = *(int *)arg;
|
|
|
|
return CONTROL_TRUE;
|
video: approximate AVI timestamps via DTS handling
Until now (and in mplayer traditionally), avi timestamps were handled
with a timestamp FIFO. AVI timestamps are essentially just strictly
increasing frame numbers and are not reordered like normal timestamps.
Limiting the FIFO is required because frames can be dropped. To make
it worse, frame dropping can't be distinguished from the decoder not
returning output due to increasing the buffering required for B-frames.
("Measuring" the buffering at playback start seems like an interesting
idea, but won't work as the buffering could be increased mid-playback.)
Another problem are skipped frames (packets with data, but which do
not contain a video frame).
Besides dropped and skipped frames, there is the problem that we can't
always know the delay. External decoders like MMAL are not going to
tell us. (And later perhaps others, like direct VideoToolbox usage.)
In general, this works not-well enough that I prefer the solution of
passing through AVI timestamps as DTS. This is slightly incorrect,
because most decoders treat DTS as mpeg-style timestamps, which
already include a b-frame delay, and thus will be shifted by a few
frames. This means there will be a problem with A/V sync in some
situations.
Note that the FFmpeg AVI demuxer shifts timestamps by an additional
amount (which increases after the first seek!?!?), which makes the
situation worse. It works well with VfW-muxed Matroska files, though.
On RPI, the first X timestamps are broken until the MMAL decoder "locks
on".
2016-02-11 15:01:11 +00:00
|
|
|
case VDCTRL_GET_BFRAMES: {
|
video: readd codec delay estimation
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.
To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
2015-12-02 13:38:47 +00:00
|
|
|
AVCodecContext *avctx = ctx->avctx;
|
2015-12-05 22:53:55 +00:00
|
|
|
if (!avctx)
|
video: readd codec delay estimation
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.
To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
2015-12-02 13:38:47 +00:00
|
|
|
break;
|
2018-03-01 22:56:56 +00:00
|
|
|
if (ctx->use_hwdec && strcmp(ctx->hwdec.method_name, "mmal") == 0)
|
video: readd codec delay estimation
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.
To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
2015-12-02 13:38:47 +00:00
|
|
|
break; // MMAL has arbitrary buffering, thus unknown
|
video: approximate AVI timestamps via DTS handling
Until now (and in mplayer traditionally), avi timestamps were handled
with a timestamp FIFO. AVI timestamps are essentially just strictly
increasing frame numbers and are not reordered like normal timestamps.
Limiting the FIFO is required because frames can be dropped. To make
it worse, frame dropping can't be distinguished from the decoder not
returning output due to increasing the buffering required for B-frames.
("Measuring" the buffering at playback start seems like an interesting
idea, but won't work as the buffering could be increased mid-playback.)
Another problem are skipped frames (packets with data, but which do
not contain a video frame).
Besides dropped and skipped frames, there is the problem that we can't
always know the delay. External decoders like MMAL are not going to
tell us. (And later perhaps others, like direct VideoToolbox usage.)
In general, this works not-well enough that I prefer the solution of
passing through AVI timestamps as DTS. This is slightly incorrect,
because most decoders treat DTS as mpeg-style timestamps, which
already include a b-frame delay, and thus will be shifted by a few
frames. This means there will be a problem with A/V sync in some
situations.
Note that the FFmpeg AVI demuxer shifts timestamps by an additional
amount (which increases after the first seek!?!?), which makes the
situation worse. It works well with VfW-muxed Matroska files, though.
On RPI, the first X timestamps are broken until the MMAL decoder "locks
on".
2016-02-11 15:01:11 +00:00
|
|
|
*(int *)arg = avctx->has_b_frames;
|
video: readd codec delay estimation
Approximately reverts commit 3ccac74d. This failed with some avi files,
which do pseudo-VFR by sending packets with empty frames (or repeat
frames, depending on point of view). Specifically, these packets are not
0 bytes, so they don't get skipped by libavformat, as with the usual VFR
avi hack. Instead, the packet contains a VOP with vop_coded=0, so
libavcodec will just return no frame. We could probably distinguish such
skipped frames and delayed frames by explicitly measuring the codec
delay by counting how long it takes to get the very first frame (and
then treat skips as explicit drops), but we may as well simply reinstate
the old code.
To appease to at least one semi-broken case, do not enable this logic on
the RPI, as the FFmpeg MMAL wrapper has arbitrary buffering (and MMAL
itself is asynchronous).
2015-12-02 13:38:47 +00:00
|
|
|
return CONTROL_TRUE;
|
|
|
|
}
|
2014-04-22 23:17:28 +00:00
|
|
|
case VDCTRL_GET_HWDEC: {
|
2017-12-01 20:05:54 +00:00
|
|
|
*(char **)arg = ctx->use_hwdec ? ctx->hwdec.method_name : NULL;
|
2014-04-22 23:17:28 +00:00
|
|
|
return CONTROL_TRUE;
|
|
|
|
}
|
2013-12-10 18:07:29 +00:00
|
|
|
case VDCTRL_FORCE_HWDEC_FALLBACK:
|
2017-12-01 20:05:54 +00:00
|
|
|
if (ctx->use_hwdec) {
|
2016-04-22 13:45:23 +00:00
|
|
|
force_fallback(vd);
|
2015-09-02 21:10:39 +00:00
|
|
|
return ctx->avctx ? CONTROL_OK : CONTROL_ERROR;
|
2016-04-22 13:45:23 +00:00
|
|
|
}
|
2015-09-02 21:10:39 +00:00
|
|
|
return CONTROL_FALSE;
|
2016-01-29 21:47:27 +00:00
|
|
|
case VDCTRL_REINIT:
|
|
|
|
reinit(vd);
|
|
|
|
return CONTROL_TRUE;
|
2011-11-14 18:12:20 +00:00
|
|
|
}
|
|
|
|
return CONTROL_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
static void process(struct mp_filter *vd)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
|
|
|
lavc_process(vd, &ctx->eof_returned, send_packet, receive_frame);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void reset(struct mp_filter *vd)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
|
|
|
flush_all(vd);
|
|
|
|
|
|
|
|
ctx->eof_returned = false;
|
|
|
|
ctx->framedrop_flags = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void destroy(struct mp_filter *vd)
|
|
|
|
{
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
|
|
|
|
uninit_avctx(vd);
|
|
|
|
|
|
|
|
pthread_mutex_destroy(&ctx->dr_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct mp_filter_info vd_lavc_filter = {
|
|
|
|
.name = "vd_lavc",
|
|
|
|
.priv_size = sizeof(vd_ffmpeg_ctx),
|
|
|
|
.process = process,
|
|
|
|
.reset = reset,
|
|
|
|
.destroy = destroy,
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct mp_decoder *create(struct mp_filter *parent,
|
|
|
|
struct mp_codec_params *codec,
|
|
|
|
const char *decoder)
|
|
|
|
{
|
|
|
|
struct mp_filter *vd = mp_filter_create(parent, &vd_lavc_filter);
|
|
|
|
if (!vd)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
mp_filter_add_pin(vd, MP_PIN_IN, "in");
|
|
|
|
mp_filter_add_pin(vd, MP_PIN_OUT, "out");
|
|
|
|
|
|
|
|
vd->log = mp_log_new(vd, parent->log, NULL);
|
|
|
|
|
|
|
|
vd_ffmpeg_ctx *ctx = vd->priv;
|
|
|
|
ctx->log = vd->log;
|
2018-05-21 14:05:03 +00:00
|
|
|
ctx->opts_cache = m_config_cache_alloc(ctx, vd->global, &vd_lavc_conf);
|
|
|
|
ctx->opts = ctx->opts_cache->opts;
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
ctx->codec = codec;
|
|
|
|
ctx->decoder = talloc_strdup(ctx, decoder);
|
|
|
|
ctx->hwdec_swpool = mp_image_pool_new(ctx);
|
|
|
|
ctx->dr_pool = mp_image_pool_new(ctx);
|
|
|
|
|
|
|
|
ctx->public.f = vd;
|
|
|
|
ctx->public.control = control;
|
|
|
|
|
|
|
|
pthread_mutex_init(&ctx->dr_lock, NULL);
|
|
|
|
|
|
|
|
// hwdec/DR
|
|
|
|
struct mp_stream_info *info = mp_filter_find_stream_info(vd);
|
|
|
|
if (info) {
|
|
|
|
ctx->hwdec_devs = info->hwdec_devs;
|
|
|
|
ctx->vo = info->dr_vo;
|
|
|
|
}
|
|
|
|
|
|
|
|
reinit(vd);
|
|
|
|
|
|
|
|
if (!ctx->avctx) {
|
|
|
|
talloc_free(vd);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return &ctx->public;
|
|
|
|
}
|
|
|
|
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
static void add_decoders(struct mp_decoder_list *list)
|
|
|
|
{
|
|
|
|
mp_add_lavc_decoders(list, AVMEDIA_TYPE_VIDEO);
|
|
|
|
}
|
|
|
|
|
video: make decoder wrapper a filter
Move dec_video.c to filters/f_decoder_wrapper.c. It essentially becomes
a source filter. vd.h mostly disappears, because mp_filter takes care of
the dataflow, but its remains are in struct mp_decoder_fns.
One goal is to simplify dataflow by letting the filter framework handle
it (or more accurately, using its conventions). One result is that the
decode calls disappear from video.c, because we simply connect the
decoder wrapper and the filter chain with mp_pin_connect().
Another goal is to eventually remove the code duplication between the
audio and video paths for this. This commit prepares for this by trying
to make f_decoder_wrapper.c extensible, so it can be used for audio as
well later.
Decoder framedropping changes a bit. It doesn't seem to be worse than
before, and it's an obscure feature, so I'm content with its new state.
Some special code that was apparently meant to avoid dropping too many
frames in a row is removed, though.
I'm not sure how the source code tree should be organized. For one,
video/decode/vd_lavc.c is the only file in its directory, which is a bit
annoying.
2018-01-28 09:08:45 +00:00
|
|
|
const struct mp_decoder_fns vd_lavc = {
|
|
|
|
.create = create,
|
core: redo how codecs are mapped, remove codecs.conf
Use codec names instead of FourCCs to identify codecs. Rewrite how
codecs are selected and initialized. Now each decoder exports a list
of decoders (and the codec it supports) via add_decoders(). The order
matters, and the first decoder for a given decoder is preferred over
the other decoders. E.g. all ad_mpg123 decoders are preferred over
ad_lavc, because it comes first in the mpcodecs_ad_drivers array.
Likewise, decoders within ad_lavc that are enumerated first by
libavcodec (using av_codec_next()) are preferred. (This is actually
critical to select h264 software decoding by default instead of vdpau.
libavcodec and ffmpeg/avconv use the same method to select decoders by
default, so we hope this is sane.)
The codec names follow libavcodec's codec names as defined by
AVCodecDescriptor.name (see libavcodec/codec_desc.c). Some decoders
have names different from the canonical codec name. The AVCodecDescriptor
API is relatively new, so we need a compatibility layer for older
libavcodec versions for codec names that are referenced internally,
and which are different from the decoder name. (Add a configure check
for that, because checking versions is getting way too messy.)
demux/codec_tags.c is generated from the former codecs.conf (minus
"special" decoders like vdpau, and excluding the mappings that are the
same as the mappings libavformat's exported RIFF tables). It contains
all the mappings from FourCCs to codec name. This is needed for
demux_mkv, demux_mpg, demux_avi and demux_asf. demux_lavf will set the
codec as determined by libavformat, while the other demuxers have to do
this on their own, using the mp_set_audio/video_codec_from_tag()
functions. Note that the sh_audio/video->format members don't uniquely
identify the codec anymore, and sh->codec takes over this role.
Replace the --ac/--vc/--afm/--vfm with new --vd/--ad options, which
provide cover the functionality of the removed switched.
Note: there's no CODECS_FLAG_FLIP flag anymore. This means some obscure
container/video combinations (e.g. the sample Film_200_zygo_pro.mov)
are played flipped. ffplay/avplay doesn't handle this properly either,
so we don't care and blame ffmeg/libav instead.
2013-02-09 14:15:19 +00:00
|
|
|
.add_decoders = add_decoders,
|
2009-11-21 18:53:10 +00:00
|
|
|
};
|