mpv/video/decode/vd_lavc.c

1257 lines
38 KiB
C
Raw Normal View History

/*
* This file is part of mpv.
*
* 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
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include <stdbool.h>
#include <libavcodec/avcodec.h>
#include <libavutil/common.h>
#include <libavutil/hwcontext.h>
#include <libavutil/opt.h>
#include <libavutil/intreadwrite.h>
#include <libavutil/pixdesc.h>
#include "config.h"
#include "mpv_talloc.h"
#include "common/global.h"
#include "common/msg.h"
#include "options/m_config.h"
#include "options/options.h"
#include "misc/bstr.h"
#include "common/av_common.h"
#include "common/codecs.h"
#include "video/fmt-conversion.h"
#include "filters/f_decoder_wrapper.h"
#include "filters/filter_internal.h"
#include "video/hwdec.h"
#include "video/img_format.h"
#include "video/mp_image.h"
#include "video/mp_image_pool.h"
#include "demux/demux.h"
#include "demux/stheader.h"
#include "demux/packet.h"
#include "video/csputils.h"
#include "video/sws_utils.h"
#include "video/out/vo.h"
#include "options/m_option.h"
static void init_avctx(struct mp_filter *vd);
static void uninit_avctx(struct mp_filter *vd);
static int get_buffer2_direct(AVCodecContext *avctx, AVFrame *pic, int flags);
static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
const enum AVPixelFormat *pix_fmt);
static int hwdec_validate_opt(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param);
#define HWDEC_DELAY_QUEUE_COUNT 2
#define OPT_BASE_STRUCT struct vd_lavc_params
struct vd_lavc_params {
int fast;
int show_all;
int skip_loop_filter;
int skip_idct;
int skip_frame;
int framedrop;
int threads;
int bitexact;
int old_x264;
int check_hw_profile;
int software_fallback;
char **avopts;
int dr;
char *hwdec_api;
char *hwdec_codecs;
int hwdec_image_format;
int hwdec_extra_frames;
};
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)
const struct m_sub_options vd_lavc_conf = {
.opts = (const m_option_t[]){
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),
OPT_INTRANGE("hwdec-extra-frames", hwdec_extra_frames, 0, 0, 256),
{0}
},
.size = sizeof(struct vd_lavc_params),
.defaults = &(const struct vd_lavc_params){
.show_all = 0,
.check_hw_profile = 1,
.software_fallback = 3,
.skip_loop_filter = AVDISCARD_DEFAULT,
.skip_idct = AVDISCARD_DEFAULT,
.skip_frame = AVDISCARD_DEFAULT,
.framedrop = AVDISCARD_NONREF,
.dr = 1,
.hwdec_api = HAVE_RPI ? "mmal" : "no",
.hwdec_codecs = "h264,vc1,hevc,vp9",
// 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,
},
};
struct hwdec_info {
char name[64];
char method_name[24]; // non-unique name describing the hwdec method
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;
struct m_config_cache *opts_cache;
struct vd_lavc_params *opts;
struct mp_codec_params *codec;
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;
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
struct lavc_state state;
const char *decoder;
2017-12-01 22:08:59 +01:00
bool hwdec_requested;
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
struct vo *vo;
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;
struct mp_decoder public;
} vd_ffmpeg_ctx;
// 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",
"vdpau",
"vdpau-copy",
0
};
static int hwdec_compare(const void *p1, const void *p2)
{
struct hwdec_info *h1 = (void *)p1;
struct hwdec_info *h2 = (void *)p2;
if (h1 == h2)
return 0;
// 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;
}
// (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;
info.auto_pos = INT_MAX;
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);
}
static void add_all_hwdec_methods(struct hwdec_info **infos, int *num_infos)
{
const AVCodec *codec = NULL;
void *iter = NULL;
while (1) {
codec = av_codec_iterate(&iter);
if (!codec)
break;
if (codec->type != AVMEDIA_TYPE_VIDEO || !av_codec_is_decoder(codec))
continue;
struct hwdec_info info_template = {
.pix_fmt = AV_PIX_FMT_NONE,
.codec = codec,
};
const char *wrapper = NULL;
if (codec->capabilities & (AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_HYBRID))
wrapper = codec->wrapper_name;
// 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;
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;
}
// Direct variant.
add_hwdec_item(infos, num_infos, info);
// 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;
}
add_hwdec_item(infos, num_infos, info);
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.
add_hwdec_item(infos, num_infos, info);
// Copy variant.
info.copying = true;
info.pix_fmt = AV_PIX_FMT_NONE; // trust it can do sw output
add_hwdec_item(infos, num_infos, info);
found_any = true;
}
}
if (!found_any && wrapper) {
// We _know_ there's something supported here, usually outputting
// sw surfaces. E.g. mediacodec (before hw_device_ctx support).
struct hwdec_info info = info_template;
info.copying = true; // probably
snprintf(info.method_name, sizeof(info.method_name), "%s", wrapper);
add_hwdec_item(infos, num_infos, info);
}
}
qsort(*infos, *num_infos, sizeof(struct hwdec_info), hwdec_compare);
}
static bool hwdec_codec_allowed(struct mp_filter *vd, const char *codec)
{
vd_ffmpeg_ctx *ctx = vd->priv;
bstr s = bstr0(ctx->opts->hwdec_codecs);
while (s.len) {
bstr item;
bstr_split_tok(s, ",", &item, &s);
if (bstr_equals0(item, "all") || bstr_equals0(item, codec))
return true;
}
return false;
}
static AVBufferRef *hwdec_create_dev(struct mp_filter *vd,
struct hwdec_info *hwdec,
bool autoprobe)
{
vd_ffmpeg_ctx *ctx = vd->priv;
assert(hwdec->lavc_device);
if (hwdec->copying) {
const struct hwcontext_fns *fns =
hwdec_get_hwcontext_fns(hwdec->lavc_device);
if (fns && fns->create_dev) {
struct hwcontext_create_dev_params params = {
.probing = autoprobe,
};
return fns->create_dev(vd->global, vd->log, &params);
} else {
AVBufferRef* ref = NULL;
av_hwdevice_ctx_create(&ref, hwdec->lavc_device, NULL, NULL, 0);
return ref;
}
} else if (ctx->hwdec_devs) {
hwdec_devices_request_all(ctx->hwdec_devs);
return hwdec_devices_get_lavc(ctx->hwdec_devs, hwdec->lavc_device);
}
return NULL;
}
// Select if and which hwdec to use. Also makes sure to get the decode device.
static void select_and_set_hwdec(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
const char *codec = ctx->codec->codec;
m_config_cache_update(ctx->opts_cache);
bstr opt = bstr0(ctx->opts->hwdec_api);
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;
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 {
struct hwdec_info *hwdecs = NULL;
int num_hwdecs = 0;
add_all_hwdec_methods(&hwdecs, &num_hwdecs);
2017-12-01 22:08:59 +01:00
ctx->hwdec_requested = true;
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;
if (!hwdec_auto && !(bstr_equals0(opt, hwdec->method_name) ||
bstr_equals0(opt, hwdec->name)))
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;
}
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");
}
} else if (!hwdec->copying) {
// Most likely METHOD_INTERNAL, which often use delay-loaded
// VO support as well.
if (ctx->hwdec_devs)
hwdec_devices_request_all(ctx->hwdec_devs);
}
ctx->use_hwdec = true;
ctx->hwdec = *hwdec;
break;
}
talloc_free(hwdecs);
if (!ctx->use_hwdec)
MP_VERBOSE(vd, "No hardware decoding available for this codec.\n");
}
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");
}
}
static int hwdec_validate_opt(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param)
{
if (bstr_equals0(param, "help")) {
struct hwdec_info *hwdecs = NULL;
int num_hwdecs = 0;
add_all_hwdec_methods(&hwdecs, &num_hwdecs);
mp_info(log, "Valid values (with alternative full names):\n");
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;
}
return 0;
}
static void force_fallback(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
uninit_avctx(vd);
int lev = ctx->hwdec_notified ? MSGL_WARN : MSGL_V;
mp_msg(vd->log, lev, "Falling back to software decoding.\n");
init_avctx(vd);
}
static void reinit(struct mp_filter *vd)
2011-10-22 02:51:37 +02:00
{
vd_ffmpeg_ctx *ctx = vd->priv;
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-28 01:49:45 +02:00
select_and_set_hwdec(vd);
bool use_hwdec = ctx->use_hwdec;
init_avctx(vd);
if (!ctx->avctx && use_hwdec)
force_fallback(vd);
}
static void init_avctx(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
struct vd_lavc_params *lavc_param = ctx->opts;
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 15:15:19 +01:00
m_config_cache_update(ctx->opts_cache);
assert(!ctx->avctx);
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 15:15:19 +01:00
if (!lavc_codec)
return;
video, audio: use lavc decoders without codecs.conf entries Add support for using libavcodec decoders that do not have entries in codecs.conf. This is currently only used with demux_lavf, and the codec selection is based on codec_id returned by libavformat. Also modify codec-related terminal output somewhat to make it use information from libavcodec and avoid excessively long default output. The new any-lavc-codec support is implemented with codecs.conf entries that invoke vd_ffmpeg/ad_ffmpeg without directly specifying any libavcodec codec name. In this mode, the decoders now instead select the libavcodec codec based on codec_id previously set by demux_lavf (if any). These new "generic" codecs.conf entries specify "status buggy", so that they're tried after any specific entries with higher-priority status. Add new directive "anyinput" to codecs.conf syntax. This means the entry will always match regardless of fourcc. This is used for the above new codecs.conf entries (so the driver always gets to decide whether to accept the input, and will fail init() if it can't find a suitable codec in libavcodec). Remove parsing support for the obsolete codecs.conf directive "cpuflags". This directive has not had any effect and has not been used in default codecs.conf since many years ago. Shorten codec-related terminal output. When using libavcodec decoders, show the libavcodec long_name field rather than codecs.conf "info" field as the name of the codec. Stop showing the codecs.conf entry name and "vfm/afm" name by default, as these are rarely needed; they're now in verbose output only. Show "VIDEO:" line at VO initialization rather than at demuxer open. This didn't really belong in demuxer code; the new location may show more accurate values (known after decoder has been opened) and works right if video track is changed after initial demuxer open. The vd.c changes (primarily done for terminal output changes) remove round-to-even behavior from code setting dimensions based on aspect ratio. I hope nothing depended on this; at least the even values were not consistently guaranteed anyway, as the rounding code did not run if the video file did not specify a nonzero aspect value.
2012-07-24 08:01:47 +02:00
const AVCodecDescriptor *desc = avcodec_descriptor_get(lavc_codec->id);
ctx->intra_only = desc && (desc->props & AV_CODEC_PROP_INTRA_ONLY);
ctx->codec_timebase = mp_get_codec_timebase(ctx->codec);
// This decoder does not read pkt_timebase correctly yet.
if (strstr(lavc_codec->name, "_mmal"))
ctx->codec_timebase = (AVRational){1, 1000000};
ctx->hwdec_failed = false;
ctx->hwdec_request_reinit = false;
ctx->avctx = avcodec_alloc_context3(lavc_codec);
AVCodecContext *avctx = ctx->avctx;
2014-12-12 17:28:22 +01:00
if (!ctx->avctx)
goto error;
avctx->codec_type = AVMEDIA_TYPE_VIDEO;
avctx->codec_id = lavc_codec->id;
#if LIBAVCODEC_VERSION_MICRO >= 100
avctx->pkt_timebase = ctx->codec_timebase;
#endif
ctx->pic = av_frame_alloc();
2014-12-12 17:28:22 +01:00
if (!ctx->pic)
goto error;
if (ctx->use_hwdec) {
avctx->opaque = vd;
avctx->thread_count = 1;
avctx->hwaccel_flags |= AV_HWACCEL_FLAG_IGNORE_LEVEL;
if (!lavc_param->check_hw_profile)
avctx->hwaccel_flags |= AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH;
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) {
if (!ctx->hwdec_dev)
goto error;
}
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;
ctx->hw_probing = true;
} else {
mp_set_avcodec_threads(vd->log, avctx, lavc_param->threads);
}
if (!ctx->use_hwdec && ctx->vo && lavc_param->dr) {
avctx->opaque = vd;
avctx->get_buffer2 = get_buffer2_direct;
avctx->thread_safe_callbacks = 1;
}
avctx->flags |= lavc_param->bitexact ? AV_CODEC_FLAG_BITEXACT : 0;
avctx->flags2 |= lavc_param->fast ? AV_CODEC_FLAG2_FAST : 0;
if (lavc_param->show_all)
avctx->flags |= AV_CODEC_FLAG_OUTPUT_CORRUPT;
avctx->skip_loop_filter = lavc_param->skip_loop_filter;
avctx->skip_idct = lavc_param->skip_idct;
avctx->skip_frame = lavc_param->skip_frame;
if (lavc_codec->id == AV_CODEC_ID_H264 && lavc_param->old_x264)
av_opt_set(avctx, "x264_build", "150", AV_OPT_SEARCH_CHILDREN);
mp_set_avopts(vd->log, avctx, lavc_param->avopts);
// Do this after the above avopt handling in case it changes values
ctx->skip_frame = avctx->skip_frame;
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 15:15:19 +01:00
}
/* open it */
if (avcodec_open2(avctx, lavc_codec, NULL) < 0)
goto error;
// 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);
}
return;
error:
MP_ERR(vd, "Could not open codec.\n");
uninit_avctx(vd);
}
static void reset_avctx(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
if (ctx->avctx && avcodec_is_open(ctx->avctx))
avcodec_flush_buffers(ctx->avctx);
ctx->flushing = false;
ctx->hwdec_request_reinit = false;
}
static void flush_all(struct mp_filter *vd)
{
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;
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;
reset_avctx(vd);
}
static void uninit_avctx(struct mp_filter *vd)
2011-10-22 02:51:37 +02:00
{
vd_ffmpeg_ctx *ctx = vd->priv;
flush_all(vd);
av_frame_free(&ctx->pic);
av_buffer_unref(&ctx->cached_hw_frames_ctx);
avcodec_free_context(&ctx->avctx);
av_buffer_unref(&ctx->hwdec_dev);
2015-05-28 21:52:04 +02:00
ctx->hwdec_failed = false;
ctx->hwdec_fail_count = 0;
ctx->max_delay_queue = 0;
ctx->hw_probing = false;
ctx->hwdec = (struct hwdec_info){0};
ctx->use_hwdec = false;
}
static int init_generic_hwaccel(struct mp_filter *vd, enum AVPixelFormat hw_fmt)
{
struct lavc_ctx *ctx = vd->priv;
AVBufferRef *new_frames_ctx = NULL;
if (!ctx->hwdec.use_hw_frames)
return 0;
if (!ctx->hwdec_dev) {
MP_ERR(ctx, "Missing device context.\n");
goto error;
}
if (avcodec_get_hw_frames_parameters(ctx->avctx,
ctx->hwdec_dev, hw_fmt, &new_frames_ctx) < 0)
{
MP_VERBOSE(ctx, "Hardware decoding of this stream is unsupported?\n");
goto error;
}
AVHWFramesContext *new_fctx = (void *)new_frames_ctx->data;
if (ctx->opts->hwdec_image_format)
new_fctx->sw_format = imgfmt2pixfmt(ctx->opts->hwdec_image_format);
// 1 surface is already included by libavcodec. The field is 0 if the
// hwaccel supports dynamic surface allocation.
if (new_fctx->initial_pool_size)
new_fctx->initial_pool_size += ctx->opts->hwdec_extra_frames - 1;
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);
// 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;
}
static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
const enum AVPixelFormat *fmt)
{
struct mp_filter *vd = avctx->opaque;
vd_ffmpeg_ctx *ctx = vd->priv;
MP_VERBOSE(vd, "Pixel formats supported by decoder:");
for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++)
MP_VERBOSE(vd, " %s", av_get_pix_fmt_name(fmt[i]));
MP_VERBOSE(vd, "\n");
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);
assert(ctx->use_hwdec);
ctx->hwdec_request_reinit |= ctx->hwdec_failed;
ctx->hwdec_failed = false;
enum AVPixelFormat select = AV_PIX_FMT_NONE;
for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++) {
if (ctx->hwdec.pix_fmt == fmt[i]) {
if (init_generic_hwaccel(vd, fmt[i]) < 0)
break;
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-28 01:49:45 +02:00
}
}
if (select == AV_PIX_FMT_NONE) {
ctx->hwdec_failed = true;
select = avcodec_default_get_format(avctx, fmt);
}
const char *name = av_get_pix_fmt_name(select);
MP_VERBOSE(vd, "Requesting pixfmt '%s' from decoder.\n", name ? name : "-");
return select;
}
static int get_buffer2_direct(AVCodecContext *avctx, AVFrame *pic, int flags)
{
struct mp_filter *vd = avctx->opaque;
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 03:06:47 +02:00
int stride_align = MP_IMAGE_BYTE_ALIGN;
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;
MP_DBG(p, "DR parameter change to %dx%d %s align=%d\n", w, h,
mp_imgfmt_to_name(imgfmt), stride_align);
}
struct mp_image *img = mp_image_pool_get_no_alloc(p->dr_pool, imgfmt, w, h);
if (!img) {
MP_DBG(p, "Allocating new DR image...\n");
img = vo_get_image(p->vo, imgfmt, w, h, stride_align);
if (!img) {
MP_DBG(p, "...failed..\n");
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);
}
static bool prepare_decoding(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
AVCodecContext *avctx = ctx->avctx;
struct vd_lavc_params *opts = ctx->opts;
if (!avctx || ctx->hwdec_failed)
return false;
int drop = ctx->framedrop_flags;
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;
} else {
avctx->skip_frame = ctx->skip_frame; // normal playback
}
if (ctx->hwdec_request_reinit)
reset_avctx(vd);
return true;
}
static void handle_err(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
struct vd_lavc_params *opts = ctx->opts;
MP_WARN(vd, "Error while decoding frame!\n");
if (ctx->use_hwdec) {
ctx->hwdec_fail_count += 1;
if (ctx->hwdec_fail_count >= opts->software_fallback)
ctx->hwdec_failed = true;
}
}
static bool do_send_packet(struct mp_filter *vd, struct demux_packet *pkt)
{
vd_ffmpeg_ctx *ctx = vd->priv;
AVCodecContext *avctx = ctx->avctx;
if (!prepare_decoding(vd))
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return AVERROR_UNKNOWN;
if (avctx->skip_frame == AVDISCARD_ALL)
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return AVERROR(EAGAIN);
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)
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
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);
}
if (ret < 0)
handle_err(vd);
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
}
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
static int send_queued(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
while (ctx->num_requeue_packets) {
int ret = do_send_packet(vd, ctx->requeue_packets[0]);
if (ret < 0)
return ret;
talloc_free(ctx->requeue_packets[0]);
MP_TARRAY_REMOVE_AT(ctx->requeue_packets, ctx->num_requeue_packets, 0);
}
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return 0;
}
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
static int send_packet(struct mp_filter *vd, struct demux_packet *pkt)
{
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
int ret = send_queued(vd);
if (ret < 0)
return false;
return do_send_packet(vd, pkt);
}
// Returns whether decoder is still active (!EOF state).
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
static int decode_frame(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
AVCodecContext *avctx = ctx->avctx;
if (!prepare_decoding(vd))
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return AVERROR(EAGAIN);
int ret = avcodec_receive_frame(avctx, ctx->pic);
if (ret == AVERROR_EOF) {
// If flushing was initialized earlier and has ended now, make it start
// 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);
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
} else if (ret < 0 && ret != AVERROR(EAGAIN)) {
handle_err(vd);
}
if (!ctx->pic->buf[0])
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
ctx->hwdec_fail_count = 0;
struct mp_image *mpi = mp_image_from_av_frame(ctx->pic);
if (!mpi) {
av_frame_unref(ctx->pic);
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
}
assert(mpi->planes[0] || mpi->planes[3]);
mpi->pts = mp_pts_from_av(ctx->pic->pts, &ctx->codec_timebase);
mpi->dts = mp_pts_from_av(ctx->pic->pkt_dts, &ctx->codec_timebase);
#if LIBAVCODEC_VERSION_MICRO >= 100
mpi->pkt_duration =
mp_pts_from_av(ctx->pic->pkt_duration, &ctx->codec_timebase);
#endif
av_frame_unref(ctx->pic);
MP_TARRAY_APPEND(ctx, ctx->delay_queue, ctx->num_delay_queue, mpi);
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
}
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
static int receive_frame(struct mp_filter *vd, struct mp_frame *out_frame)
{
vd_ffmpeg_ctx *ctx = vd->priv;
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
int ret = decode_frame(vd);
if (ctx->hwdec_failed) {
// Failed hardware decoding? Try again in software.
struct demux_packet **pkts = ctx->sent_packets;
int num_pkts = ctx->num_sent_packets;
ctx->sent_packets = NULL;
ctx->num_sent_packets = 0;
force_fallback(vd);
ctx->requeue_packets = pkts;
ctx->num_requeue_packets = num_pkts;
send_queued(vd);
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
ret = decode_frame(vd);
}
if (!ctx->num_delay_queue)
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
if (ctx->num_delay_queue <= ctx->max_delay_queue && ret >= 0)
return AVERROR(EAGAIN);
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)
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
if (ctx->use_hwdec && ctx->hwdec.copying && res->hwctx) {
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");
ctx->hwdec_fail_count = INT_MAX - 1; // force fallback
handle_err(vd);
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
}
}
2017-12-01 22:08:59 +01:00
if (!ctx->hwdec_notified && ctx->hwdec_requested) {
if (ctx->use_hwdec) {
MP_INFO(vd, "Using hardware decoding (%s).\n",
ctx->hwdec.method_name);
} else {
MP_VERBOSE(vd, "Using software decoding.\n");
}
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;
}
*out_frame = MAKE_FRAME(MP_FRAME_VIDEO, res);
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
return ret;
}
static int control(struct mp_filter *vd, enum dec_ctrl cmd, void *arg)
{
vd_ffmpeg_ctx *ctx = vd->priv;
switch (cmd) {
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 16:01:11 +01:00
case VDCTRL_GET_BFRAMES: {
AVCodecContext *avctx = ctx->avctx;
if (!avctx)
break;
2018-03-01 23:56:56 +01:00
if (ctx->use_hwdec && strcmp(ctx->hwdec.method_name, "mmal") == 0)
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 16:01:11 +01:00
*(int *)arg = avctx->has_b_frames;
return CONTROL_TRUE;
}
case VDCTRL_GET_HWDEC: {
*(char **)arg = ctx->use_hwdec ? ctx->hwdec.method_name : NULL;
return CONTROL_TRUE;
}
case VDCTRL_FORCE_HWDEC_FALLBACK:
if (ctx->use_hwdec) {
force_fallback(vd);
return ctx->avctx ? CONTROL_OK : CONTROL_ERROR;
}
return CONTROL_FALSE;
case VDCTRL_REINIT:
reinit(vd);
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
}
static void process(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
lavc_process(vd, &ctx->state, send_packet, receive_frame);
}
static void reset(struct mp_filter *vd)
{
vd_ffmpeg_ctx *ctx = vd->priv;
flush_all(vd);
ad_lavc, vd_lavc: return full error codes to shared decoder loop ad_lavc and vd_lavc use the lavc_process() helper to translate the FFmpeg push/pull API to the internal filter API (which completely mismatch, even though I'm responsible for both, just fucking kill me). This interface was "slightly" too tight. It returned only a bool indicating "progress", which was not enough to handle some cases (see following commit). While we're at it, move all state into a struct. This is only a single bool, but we get the chance to add more if needed. This fixes mpv falling asleep if decoding returns an error during draining. If decoding fails when we already sent EOF, the state machine stopped making progress. This left mpv just sitting around and doing nothing. A test case can be created with: echo $RANDOM >> image.png This makes libavformat read a proper packet plus a packet of garbage. libavcodec will decode a frame, and then return an error code. The lavc_process() wrapper could not deal with this, because there was no way to differentiate between "retry" and "send new packet". Normally, it would send a new packet, so decoding would make progress anyway. If there was "progress", we couldn't just retry, because it'd retry forever. This is made worse by the fact that it tries to decode at least two frames before starting display, meaning it will "sit around and do nothing" before the picture is displayed. Change it so that on error return, "receiving" a frame is retried. This will make it return the EOF, so everything works properly. This is a high-risk change, because all these funny bullshit exceptions for hardware decoding are in the way, and I didn't retest them. For example, if hardware decoding is enabled, it keeps a list of packets, that are fed into the decoder again if hardware decoding fails, and a software fallback is performed. Another case of horrifying accidental complexity. Fixes: #6618
2019-10-24 18:40:46 +02:00
ctx->state = (struct lavc_state){0};
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;
ctx->opts_cache = m_config_cache_alloc(ctx, vd->global, &vd_lavc_conf);
ctx->opts = ctx->opts_cache->opts;
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 15:15:19 +01:00
static void add_decoders(struct mp_decoder_list *list)
{
mp_add_lavc_decoders(list, AVMEDIA_TYPE_VIDEO);
}
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 15:15:19 +01:00
.add_decoders = add_decoders,
};