summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-08-11 23:23:12 +0200
committerwm4 <wm4@nowhere>2013-08-11 23:59:18 +0200
commit8fe4790ec8945cae52ea7600312f54e1dbdf8162 (patch)
treeda448807fd64dc944387f548b5c23ec7005c59c2
parentcdf4b7d2ee666a2b4635bd9eacce7e1a414dd7c2 (diff)
downloadmpv-8fe4790ec8945cae52ea7600312f54e1dbdf8162.tar.bz2
mpv-8fe4790ec8945cae52ea7600312f54e1dbdf8162.tar.xz
video: redo hw decoding initialization, add --hwdec=auto
Change how the HW decoding stuff is organized, the way it's initialized in particular. Instead of duplicating the list of supported codecs for hwaccel decoders, add a probe function which allows each decoder to report whether it supports a given codec. Add an "auto" choice to the --hwdec option, which automatically enables hardware decoding if libavcodec and/or the VO supports it. What mpv prints on the terminal changes a bit. Now it will just print a single line whether hw decoding is used or not (and nothing at all if no hw decoding at all was requested). The pretty violent fallback from hw decoding to software decoding is still quite verbose and evil-looking though.
-rw-r--r--etc/example.conf9
-rw-r--r--mpvcore/options.c1
-rw-r--r--video/decode/lavc.h32
-rw-r--r--video/decode/vd_lavc.c194
-rw-r--r--video/decode/vdpau.c44
-rw-r--r--video/decode/vdpau_old.c24
6 files changed, 204 insertions, 100 deletions
diff --git a/etc/example.conf b/etc/example.conf
index e610b81b4f..96c7afaca0 100644
--- a/etc/example.conf
+++ b/etc/example.conf
@@ -81,6 +81,9 @@
# Use this for a widescreen monitor, non-square pixels.
#monitoraspect=16:9
+# Enable hardware decoding if available. Often, this requires using an certain
+# video output, otherwise no hardware decoding will be used.
+#hwdec = auto
############
# Profiles #
@@ -89,7 +92,11 @@
# The options declared as part of profiles override global default settings,
# but only take effect when the profile is active.
-#[vo.vdpau]
+# The following profile can be enabled on the command line with: --profile=vdpau
+
+#[vdpau]
+# The profile forces the vdpau VO.
+#vo=vdpau
# Use hardware decoding (this might break playback of some h264 files)
#hwdec=vdpau
# Most video filters do not work with vdpau.
diff --git a/mpvcore/options.c b/mpvcore/options.c
index b66556d8bd..ff278cc7a2 100644
--- a/mpvcore/options.c
+++ b/mpvcore/options.c
@@ -466,6 +466,7 @@ const m_option_t mp_opts[] = {
OPT_CHOICE("hwdec", hwdec_api, 0,
({"no", 0},
+ {"auto", -1},
{"vdpau", 1},
{"vda", 2},
{"crystalhd", 3})),
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index 3611530400..94973cb2d8 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -10,10 +10,19 @@
#include "demux/stheader.h"
#include "video/mp_image.h"
+// keep in sync with --hwdec option
+enum hwdec_type {
+ HWDEC_AUTO = -1,
+ HWDEC_NONE = 0,
+ HWDEC_VDPAU = 1,
+ HWDEC_VDA = 2,
+ HWDEC_CRYSTALHD = 3,
+};
+
typedef struct lavc_ctx {
AVCodecContext *avctx;
AVFrame *pic;
- struct hwdec *hwdec;
+ struct vd_lavc_hwdec *hwdec;
enum PixelFormat pix_fmt;
int do_hw_dr1;
int vo_initialized;
@@ -35,16 +44,31 @@ typedef struct lavc_ctx {
struct mp_image_pool *non_dr1_pool;
} vd_ffmpeg_ctx;
-struct vd_lavc_hwdec_functions {
- // If not-NULL, a 0 terminated list of IMGFMT_ formats. Only one of these
- // formats is accepted when handling the libavcodec get_format callback.
+struct vd_lavc_hwdec {
+ enum hwdec_type type;
+ // If non-NULL: lists pairs software and hardware decoders. If the current
+ // codec is not one of the listed software decoders, probing fails.
+ // Otherwise, the AVCodecContext is initialized with the associated
+ // hardware decoder.
+ // Useful only if hw decoding requires a special codec, instead of using
+ // the libavcodec hwaccel infrastructure.
+ const char **codec_pairs;
+ // If not-NULL: a 0 terminated list of IMGFMT_ formats, and only one of
+ // these formats is accepted in the libavcodec get_format callback.
const int *image_formats;
+ int (*probe)(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
+ const char *decoder);
int (*init)(struct lavc_ctx *ctx);
void (*uninit)(struct lavc_ctx *ctx);
struct mp_image *(*allocate_image)(struct lavc_ctx *ctx, AVFrame *frame);
void (*fix_image)(struct lavc_ctx *ctx, struct mp_image *img);
};
+enum {
+ HWDEC_ERR_NO_CTX = -2,
+ HWDEC_ERR_NO_CODEC = -3,
+};
+
// lavc_dr1.c
int mp_codec_get_buffer(AVCodecContext *s, AVFrame *frame);
void mp_codec_release_buffer(AVCodecContext *s, AVFrame *frame);
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 0367c2afed..2fc7a1ea4c 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -59,7 +59,8 @@
#include "mpvcore/m_option.h"
-static void init_avctx(sh_video_t *sh, const char *decoder, struct hwdec *hwdec);
+static void init_avctx(sh_video_t *sh, const char *decoder,
+ struct vd_lavc_hwdec *hwdec);
static void uninit_avctx(sh_video_t *sh);
static void setup_refcounting_hw(struct AVCodecContext *s);
@@ -81,72 +82,56 @@ const m_option_t lavc_decode_opts_conf[] = {
{NULL, NULL, 0, 0, 0, 0, NULL}
};
-// keep in sync with --hwdec option
-enum hwdec_type {
- HWDEC_NONE = 0,
- HWDEC_VDPAU = 1,
- HWDEC_VDA = 2,
- HWDEC_CRYSTALHD = 3,
+const struct vd_lavc_hwdec mp_vd_lavc_vdpau;
+const struct vd_lavc_hwdec mp_vd_lavc_vdpau_old;
+
+static const struct vd_lavc_hwdec mp_vd_lavc_crystalhd = {
+ .type = HWDEC_CRYSTALHD,
+ .codec_pairs = (const char *[]) {
+ "mpeg2", "mpeg2_crystalhd",
+ "msmpeg4", "msmpeg4_crystalhd",
+ "wmv3", "wmv3_crystalhd",
+ "vc1", "vc1_crystalhd",
+ "h264", "h264_crystalhd",
+ "mpeg4", "mpeg4_crystalhd",
+ NULL
+ },
};
-struct hwdec {
- enum hwdec_type api;
- const char *codec, *hw_codec;
- const struct vd_lavc_hwdec_functions *fns;
+static const struct vd_lavc_hwdec mp_vd_lavc_vda = {
+ .type = HWDEC_VDA,
+ .codec_pairs = (const char *[]) {"h264", "h264_vda", NULL},
};
-const struct vd_lavc_hwdec_functions mp_vd_lavc_vdpau;
-const struct vd_lavc_hwdec_functions mp_vd_lavc_vdpau_old;
-
-static const struct hwdec hwdec_list[] = {
+static const struct vd_lavc_hwdec *hwdec_list[] = {
#if CONFIG_VDPAU
#if HAVE_AV_CODEC_NEW_VDPAU_API
- {HWDEC_VDPAU, "h264", NULL, &mp_vd_lavc_vdpau},
- {HWDEC_VDPAU, "wmv3", NULL, &mp_vd_lavc_vdpau},
- {HWDEC_VDPAU, "vc1", NULL, &mp_vd_lavc_vdpau},
- {HWDEC_VDPAU, "mpeg1video", NULL, &mp_vd_lavc_vdpau},
- {HWDEC_VDPAU, "mpeg2video", NULL, &mp_vd_lavc_vdpau},
- {HWDEC_VDPAU, "mpeg4", NULL, &mp_vd_lavc_vdpau},
+ &mp_vd_lavc_vdpau,
#else
- {HWDEC_VDPAU, "h264", "h264_vdpau", &mp_vd_lavc_vdpau_old},
- {HWDEC_VDPAU, "wmv3", "wmv3_vdpau", &mp_vd_lavc_vdpau_old},
- {HWDEC_VDPAU, "vc1", "vc1_vdpau", &mp_vd_lavc_vdpau_old},
- {HWDEC_VDPAU, "mpegvideo", "mpegvideo_vdpau", &mp_vd_lavc_vdpau_old},
- {HWDEC_VDPAU, "mpeg1video", "mpeg1video_vdpau", &mp_vd_lavc_vdpau_old},
- {HWDEC_VDPAU, "mpeg2video", "mpegvideo_vdpau", &mp_vd_lavc_vdpau_old},
- {HWDEC_VDPAU, "mpeg2", "mpeg2_vdpau", &mp_vd_lavc_vdpau_old},
- {HWDEC_VDPAU, "mpeg4", "mpeg4_vdpau", &mp_vd_lavc_vdpau_old},
+ &mp_vd_lavc_vdpau_old,
#endif
#endif // CONFIG_VDPAU
-
- {HWDEC_VDA, "h264", "h264_vda"},
-
- {HWDEC_CRYSTALHD, "mpeg2", "mpeg2_crystalhd"},
- {HWDEC_CRYSTALHD, "msmpeg4", "msmpeg4_crystalhd"},
- {HWDEC_CRYSTALHD, "wmv3", "wmv3_crystalhd"},
- {HWDEC_CRYSTALHD, "vc1", "vc1_crystalhd"},
- {HWDEC_CRYSTALHD, "h264", "h264_crystalhd"},
- {HWDEC_CRYSTALHD, "mpeg4", "mpeg4_crystalhd"},
-
- {0}
+ &mp_vd_lavc_vda,
+ &mp_vd_lavc_crystalhd,
+ NULL
};
-static struct hwdec *find_hwcodec(enum hwdec_type api, const char *codec)
+static struct vd_lavc_hwdec *find_hwcodec(enum hwdec_type api)
{
- for (int n = 0; hwdec_list[n].api; n++) {
- if (hwdec_list[n].api == api && strcmp(hwdec_list[n].codec, codec) == 0)
- return (struct hwdec *)&hwdec_list[n];
+ for (int n = 0; hwdec_list[n]; n++) {
+ if (hwdec_list[n]->type == api)
+ return (struct vd_lavc_hwdec *)hwdec_list[n];
}
return NULL;
}
-static bool hwdec_codec_allowed(sh_video_t *sh, struct hwdec *hwdec)
+static bool hwdec_codec_allowed(sh_video_t *sh, const char *codec)
{
bstr s = bstr0(sh->opts->hwdec_codecs);
while (s.len) {
bstr item;
bstr_split_tok(s, ",", &item, &s);
- if (bstr_equals0(item, "all") || bstr_equals0(item, hwdec->codec))
+ if (bstr_equals0(item, "all") || bstr_equals0(item, codec))
return true;
}
return false;
@@ -165,6 +150,56 @@ static enum AVDiscard str2AVDiscard(char *str)
return AVDISCARD_DEFAULT;
}
+static int hwdec_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
+ const char *decoder, const char **hw_decoder)
+{
+ if (hwdec->codec_pairs) {
+ for (int n = 0; hwdec->codec_pairs[n + 0]; n += 2) {
+ const char *sw = hwdec->codec_pairs[n + 0];
+ const char *hw = hwdec->codec_pairs[n + 1];
+ if (decoder && strcmp(decoder, sw) == 0) {
+ AVCodec *codec = avcodec_find_decoder_by_name(hw);
+ *hw_decoder = hw;
+ if (codec)
+ goto found;
+ }
+ }
+ return HWDEC_ERR_NO_CODEC;
+ found: ;
+ }
+ int r = 0;
+ if (hwdec->probe)
+ r = hwdec->probe(hwdec, info, decoder);
+ return r;
+}
+
+static bool probe_hwdec(sh_video_t *sh, bool autoprobe, enum hwdec_type api,
+ const char *decoder, struct vd_lavc_hwdec **use_hwdec,
+ const char **use_decoder)
+{
+ struct vd_lavc_hwdec *hwdec = find_hwcodec(api);
+ if (!hwdec) {
+ mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Requested hardware decoder not "
+ "compiled.\n");
+ return false;
+ }
+ const char *hw_decoder = NULL;
+ int r = hwdec_probe(hwdec, sh->hwdec_info, decoder, &hw_decoder);
+ if (r >= 0) {
+ *use_hwdec = hwdec;
+ *use_decoder = hw_decoder;
+ return true;
+ } else if (r == HWDEC_ERR_NO_CODEC) {
+ mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Hardware decoder '%s' not found in "
+ "libavcodec.\n", hw_decoder ? hw_decoder : decoder);
+ } else if (r == HWDEC_ERR_NO_CTX && !autoprobe) {
+ mp_tmsg(MSGT_DECVIDEO, MSGL_WARN, "VO does not support requested "
+ "hardware decoder.\n");
+ }
+ return false;
+}
+
+
static int init(sh_video_t *sh, const char *decoder)
{
vd_ffmpeg_ctx *ctx;
@@ -182,29 +217,35 @@ static int init(sh_video_t *sh, const char *decoder)
return 0;
}
- struct hwdec *hwdec = find_hwcodec(sh->opts->hwdec_api, decoder);
- struct hwdec *use_hwdec = NULL;
- if (hwdec && hwdec_codec_allowed(sh, hwdec)) {
- if (hwdec->hw_codec) {
- AVCodec *lavc_hwcodec = avcodec_find_decoder_by_name(hwdec->hw_codec);
- if (lavc_hwcodec) {
- ctx->software_fallback_decoder = talloc_strdup(ctx, decoder);
- decoder = lavc_hwcodec->name;
- use_hwdec = hwdec;
- } else {
- mp_tmsg(MSGT_DECVIDEO, MSGL_WARN, "Decoder '%s' not found in "
- "libavcodec, using software decoding.\n", hwdec->hw_codec);
+ struct vd_lavc_hwdec *hwdec = NULL;
+ const char *hw_decoder = NULL;
+
+ if (hwdec_codec_allowed(sh, decoder)) {
+ if (sh->opts->hwdec_api == HWDEC_AUTO) {
+ for (int n = 0; hwdec_list[n]; n++) {
+ if (probe_hwdec(sh, true, hwdec_list[n]->type, decoder,
+ &hwdec, &hw_decoder))
+ break;
}
- } else {
- ctx->software_fallback_decoder = talloc_strdup(ctx, decoder);
- use_hwdec = hwdec;
+ } else if (sh->opts->hwdec_api != HWDEC_NONE) {
+ probe_hwdec(sh, false, sh->opts->hwdec_api, decoder,
+ &hwdec, &hw_decoder);
}
- } else if (!hwdec && sh->opts->hwdec_api) {
- mp_tmsg(MSGT_DECVIDEO, MSGL_WARN, "Selected hardware decoding API not "
- "available, using software decoding.\n");
+ } else {
+ mp_tmsg(MSGT_DECVIDEO, MSGL_V, "Not trying to use hardware decoding: "
+ "codec %s is blacklisted by user.\n", decoder);
+ }
+
+ if (hwdec) {
+ ctx->software_fallback_decoder = talloc_strdup(ctx, decoder);
+ if (hw_decoder)
+ decoder = hw_decoder;
+ mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Trying to use hardware decoding.\n");
+ } else if (sh->opts->hwdec_api != HWDEC_NONE) {
+ mp_tmsg(MSGT_DECVIDEO, MSGL_INFO, "Using software decoding.\n");
}
- init_avctx(sh, decoder, use_hwdec);
+ init_avctx(sh, decoder, hwdec);
if (!ctx->avctx) {
if (ctx->software_fallback_decoder) {
mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Error initializing hardware "
@@ -279,7 +320,8 @@ static void set_from_bih(AVCodecContext *avctx, uint32_t format,
avctx->coded_height = bih->biHeight;
}
-static void init_avctx(sh_video_t *sh, const char *decoder, struct hwdec *hwdec)
+static void init_avctx(sh_video_t *sh, const char *decoder,
+ struct vd_lavc_hwdec *hwdec)
{
vd_ffmpeg_ctx *ctx = sh->context;
struct lavc_param *lavc_param = &sh->opts->lavc_param;
@@ -311,13 +353,13 @@ static void init_avctx(sh_video_t *sh, const char *decoder, struct hwdec *hwdec)
avctx->thread_count = lavc_param->threads;
- if (ctx->hwdec && ctx->hwdec->fns) {
+ if (ctx->hwdec && ctx->hwdec->allocate_image) {
ctx->do_hw_dr1 = true;
avctx->thread_count = 1;
- if (ctx->hwdec->fns->image_formats)
+ if (ctx->hwdec->image_formats)
avctx->get_format = get_format_hwdec;
setup_refcounting_hw(avctx);
- if (ctx->hwdec->fns->init(ctx) < 0) {
+ if (ctx->hwdec->init && ctx->hwdec->init(ctx) < 0) {
uninit_avctx(sh);
return;
}
@@ -404,8 +446,8 @@ static void uninit_avctx(sh_video_t *sh)
av_freep(&ctx->avctx);
avcodec_free_frame(&ctx->pic);
- if (ctx->hwdec && ctx->hwdec->fns)
- ctx->hwdec->fns->uninit(ctx);
+ if (ctx->hwdec && ctx->hwdec->uninit)
+ ctx->hwdec->uninit(ctx);
#if !HAVE_AVUTIL_REFCOUNTING
mp_buffer_pool_free(&ctx->dr1_buffer_pool);
@@ -487,10 +529,10 @@ static enum PixelFormat get_format_hwdec(struct AVCodecContext *avctx,
mp_msg(MSGT_DECVIDEO, MSGL_V, " %s", av_get_pix_fmt_name(fmt[i]));
mp_msg(MSGT_DECVIDEO, MSGL_V, "\n");
- assert(ctx->hwdec && ctx->hwdec->fns);
+ assert(ctx->hwdec);
for (int i = 0; fmt[i] != PIX_FMT_NONE; i++) {
- const int *okfmt = ctx->hwdec->fns->image_formats;
+ const int *okfmt = ctx->hwdec->image_formats;
for (int n = 0; okfmt && okfmt[n]; n++) {
if (imgfmt2pixfmt(okfmt[n]) == fmt[i])
return fmt[i];
@@ -519,7 +561,7 @@ static struct mp_image *get_surface_hwdec(struct sh_video *sh, AVFrame *pic)
if (!IMGFMT_IS_HWACCEL(imgfmt))
return NULL;
- struct mp_image *mpi = ctx->hwdec->fns->allocate_image(ctx, pic);
+ struct mp_image *mpi = ctx->hwdec->allocate_image(ctx, pic);
if (mpi) {
for (int i = 0; i < 4; i++)
@@ -694,8 +736,8 @@ static int decode(struct sh_video *sh, struct demux_packet *packet,
struct mp_image *mpi = image_from_decoder(sh);
assert(mpi->planes[0]);
- if (ctx->hwdec && ctx->hwdec->fns && ctx->hwdec->fns->fix_image)
- ctx->hwdec->fns->fix_image(ctx, mpi);
+ if (ctx->hwdec && ctx->hwdec->fix_image)
+ ctx->hwdec->fix_image(ctx, mpi);
mpi->colorspace = ctx->image_params.colorspace;
mpi->levels = ctx->image_params.colorlevels;
diff --git a/video/decode/vdpau.c b/video/decode/vdpau.c
index b259ae303a..e20abdafca 100644
--- a/video/decode/vdpau.c
+++ b/video/decode/vdpau.c
@@ -23,6 +23,7 @@
#include "lavc.h"
#include "mpvcore/mp_common.h"
+#include "mpvcore/av_common.h"
#include "video/fmt-conversion.h"
#include "video/vdpau.h"
#include "video/decode/dec_video.h"
@@ -109,6 +110,19 @@ static int handle_preemption(struct lavc_ctx *ctx)
return 0;
}
+static const struct profile_entry *find_codec(enum AVCodecID id, int ff_profile)
+{
+ for (int n = 0; n < MP_ARRAY_SIZE(profiles); n++) {
+ if (profiles[n].av_codec == id &&
+ (profiles[n].ff_profile == ff_profile ||
+ profiles[n].ff_profile == FF_PROFILE_UNKNOWN))
+ {
+ return &profiles[n];
+ }
+ }
+ return NULL;
+}
+
static bool create_vdp_decoder(struct lavc_ctx *ctx)
{
struct priv *p = ctx->hwdec_priv;
@@ -121,17 +135,8 @@ static bool create_vdp_decoder(struct lavc_ctx *ctx)
if (p->context.decoder != VDP_INVALID_HANDLE)
vdp->decoder_destroy(p->context.decoder);
- const struct profile_entry *pe = NULL;
- for (int n = 0; n < MP_ARRAY_SIZE(profiles); n++) {
- if (profiles[n].av_codec == ctx->avctx->codec_id &&
- (profiles[n].ff_profile == ctx->avctx->profile ||
- profiles[n].ff_profile == FF_PROFILE_UNKNOWN))
- {
- pe = &profiles[n];
- break;
- }
- }
-
+ const struct profile_entry *pe = find_codec(ctx->avctx->codec_id,
+ ctx->avctx->profile);
if (!pe) {
mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Unknown codec!\n");
goto fail;
@@ -200,9 +205,6 @@ static void uninit(struct lavc_ctx *ctx)
static int init(struct lavc_ctx *ctx)
{
- if (!ctx->hwdec_info || !ctx->hwdec_info->vdpau_ctx)
- return -1;
-
struct priv *p = talloc_ptrtype(NULL, p);
*p = (struct priv) {
.mpvdp = ctx->hwdec_info->vdpau_ctx,
@@ -220,8 +222,20 @@ static int init(struct lavc_ctx *ctx)
return 0;
}
-const struct vd_lavc_hwdec_functions mp_vd_lavc_vdpau = {
+static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
+ const char *decoder)
+{
+ if (!info || !info->vdpau_ctx)
+ return HWDEC_ERR_NO_CTX;
+ if (!find_codec(mp_codec_to_av_codec_id(decoder), FF_PROFILE_UNKNOWN))
+ return HWDEC_ERR_NO_CODEC;
+ return 0;
+}
+
+const struct vd_lavc_hwdec mp_vd_lavc_vdpau = {
+ .type = HWDEC_VDPAU,
.image_formats = (const int[]) {IMGFMT_VDPAU, 0},
+ .probe = probe,
.init = init,
.uninit = uninit,
.allocate_image = allocate_image,
diff --git a/video/decode/vdpau_old.c b/video/decode/vdpau_old.c
index e9c88b69ea..4abdafa9c0 100644
--- a/video/decode/vdpau_old.c
+++ b/video/decode/vdpau_old.c
@@ -223,9 +223,6 @@ static void uninit(struct lavc_ctx *ctx)
static int init(struct lavc_ctx *ctx)
{
- if (!ctx->hwdec_info || !ctx->hwdec_info->vdpau_ctx)
- return -1;
-
struct priv *p = talloc_ptrtype(NULL, p);
*p = (struct priv) {
.mpvdp = ctx->hwdec_info->vdpau_ctx,
@@ -246,6 +243,14 @@ static int init(struct lavc_ctx *ctx)
return 0;
}
+static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
+ const char *decoder)
+{
+ if (!info || !info->vdpau_ctx)
+ return HWDEC_ERR_NO_CTX;
+ return 0;
+}
+
static void fix_image(struct lavc_ctx *ctx, struct mp_image *img)
{
// Make it follow the convention of the "new" vdpau decoder
@@ -254,12 +259,23 @@ static void fix_image(struct lavc_ctx *ctx, struct mp_image *img)
img->planes[3] = (void *)(intptr_t)rndr->surface;
}
-const struct vd_lavc_hwdec_functions mp_vd_lavc_vdpau_old = {
+const struct vd_lavc_hwdec mp_vd_lavc_vdpau_old = {
.image_formats = (const int[]) {
IMGFMT_VDPAU_MPEG1, IMGFMT_VDPAU_MPEG2, IMGFMT_VDPAU_H264,
IMGFMT_VDPAU_WMV3, IMGFMT_VDPAU_VC1, IMGFMT_VDPAU_MPEG4,
0
},
+ .codec_pairs = (const char *[]) {
+ "h264", "h264_vdpau",
+ "wmv3", "wmv3_vdpau",
+ "vc1", "vc1_vdpau",
+ "mpegvideo", "mpegvideo_vdpau",
+ "mpeg1video", "mpeg1video_vdpau",
+ "mpeg2video", "mpegvideo_vdpau",
+ "mpeg2", "mpeg2_vdpau",
+ "mpeg4", "mpeg4_vdpau",
+ NULL
+ },
.init = init,
.uninit = uninit,
.allocate_image = allocate_image,