summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-03-16 09:21:21 +0100
committerwm4 <wm4@nowhere>2014-03-16 13:19:19 +0100
commit3ec7f528c4af6efa9f5b5951a25ea4c6311741b5 (patch)
treea4b080461b702d5309924a981e8cf9294e494a5e /video
parent75b185dfc50757402bbaf2c8b8fa8aa9602e92e8 (diff)
downloadmpv-3ec7f528c4af6efa9f5b5951a25ea4c6311741b5.tar.bz2
mpv-3ec7f528c4af6efa9f5b5951a25ea4c6311741b5.tar.xz
vd_lavc: remove compatibility crap
All this code was needed for compatibility with very old libavcodec versions only (such as Libav 9). Includes some now-possible simplifications too.
Diffstat (limited to 'video')
-rw-r--r--video/decode/lavc.h28
-rw-r--r--video/decode/lavc_dr1.c297
-rw-r--r--video/decode/vaapi.c4
-rw-r--r--video/decode/vd_lavc.c206
-rw-r--r--video/decode/vda.c2
-rw-r--r--video/decode/vdpau.c2
-rw-r--r--video/decode/vdpau_old.c287
-rw-r--r--video/fmt-conversion.c22
-rw-r--r--video/mp_image.c4
9 files changed, 29 insertions, 823 deletions
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index 45d2d9b5cd..954b2c852f 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -41,25 +41,13 @@ typedef struct lavc_ctx {
int hwdec_fmt;
int hwdec_w;
int hwdec_h;
-
- // Legacy
- bool do_dr1;
- struct FramePool *dr1_buffer_pool;
- struct mp_image_pool *non_dr1_pool;
} vd_ffmpeg_ctx;
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;
+ // If not-0: the IMGFMT_ format that should be accepted in the libavcodec
+ // get_format callback.
+ int image_format;
int (*probe)(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
const char *decoder);
int (*init)(struct lavc_ctx *ctx);
@@ -90,14 +78,4 @@ bool hwdec_check_codec_support(const char *decoder,
const struct hwdec_profile_entry *table);
int hwdec_get_max_refs(struct lavc_ctx *ctx);
-// lavc_dr1.c
-int mp_codec_get_buffer(AVCodecContext *s, AVFrame *frame);
-void mp_codec_release_buffer(AVCodecContext *s, AVFrame *frame);
-struct FrameBuffer;
-void mp_buffer_ref(struct FrameBuffer *buffer);
-void mp_buffer_unref(struct FrameBuffer *buffer);
-bool mp_buffer_is_unique(struct FrameBuffer *buffer);
-void mp_buffer_pool_free(struct FramePool **pool);
-bool mp_buffer_check(struct FrameBuffer *buffer);
-
#endif
diff --git a/video/decode/lavc_dr1.c b/video/decode/lavc_dr1.c
deleted file mode 100644
index f730a6c231..0000000000
--- a/video/decode/lavc_dr1.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Various utilities for command line tools
- * Copyright (c) 2000-2003 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-/*
- * NOTE: this file is for compatibility with older versions of
- * libavcodec, before AVFrame reference counting was introduced.
- * It is not compiled if libavcodec is new enough.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <math.h>
-#include <pthread.h>
-
-#include <libavcodec/avcodec.h>
-#include <libavutil/avassert.h>
-#include <libavutil/mathematics.h>
-#include <libavutil/imgutils.h>
-#include <libavutil/pixdesc.h>
-#include <libavutil/common.h>
-
-#include "config.h"
-
-#include "lavc.h"
-#include "video/decode/dec_video.h"
-
-static pthread_mutex_t pool_mutex = PTHREAD_MUTEX_INITIALIZER;
-#define pool_lock() pthread_mutex_lock(&pool_mutex)
-#define pool_unlock() pthread_mutex_unlock(&pool_mutex)
-
-typedef struct FramePool {
- struct FrameBuffer *list;
- // used to deal with frames that live past the time the pool should live
- int dead;
- int refcount; // number of allocated buffers (not in list)
-} FramePool;
-
-typedef struct FrameBuffer {
- uint8_t *base[4];
- uint8_t *data[4];
- int linesize[4];
-
- int h, w;
- int pix_fmt;
-
- int used_by_decoder, needed_by_decoder;
- int refcount;
- struct FramePool *pool;
- struct FrameBuffer *next;
-} FrameBuffer;
-
-
-static int alloc_buffer(FramePool *pool, AVCodecContext *s)
-{
- const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[s->pix_fmt];
- FrameBuffer *buf;
- int i, ret;
- int pixel_size;
- int h_chroma_shift, v_chroma_shift;
- int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
- int w = s->width, h = s->height;
-
- if (!desc)
- return AVERROR(EINVAL);
- pixel_size = desc->comp[0].step_minus1 + 1;
-
- buf = av_mallocz(sizeof(*buf));
- if (!buf)
- return AVERROR(ENOMEM);
-
- avcodec_align_dimensions(s, &w, &h);
-
- if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
- w += 2*edge;
- h += 2*edge;
- }
-
- if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
- s->pix_fmt, 32)) < 0) {
- av_freep(&buf);
- av_log(s, AV_LOG_ERROR, "alloc_buffer: av_image_alloc() failed\n");
- return ret;
- }
- /* XXX this shouldn't be needed, but some tests break without this line
- * those decoders are buggy and need to be fixed.
- * the following tests fail:
- * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
- */
- memset(buf->base[0], 128, ret);
-
- avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
- for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
- const int h_shift = i==0 ? 0 : h_chroma_shift;
- const int v_shift = i==0 ? 0 : v_chroma_shift;
- if ((s->flags & CODEC_FLAG_EMU_EDGE) || !buf->linesize[i] || !buf->base[i])
- buf->data[i] = buf->base[i];
- else
- buf->data[i] = buf->base[i] +
- FFALIGN((buf->linesize[i]*edge >> v_shift) +
- (pixel_size*edge >> h_shift), 32);
- }
- buf->w = s->width;
- buf->h = s->height;
- buf->pix_fmt = s->pix_fmt;
- buf->pool = pool;
-
- buf->next = pool->list;
- pool->list = buf;
- return 0;
-}
-
-int mp_codec_get_buffer(AVCodecContext *s, AVFrame *frame)
-{
- struct dec_video *vd = s->opaque;
- struct lavc_ctx *ctx = vd->priv;
-
- if (!ctx->dr1_buffer_pool) {
- ctx->dr1_buffer_pool = av_mallocz(sizeof(*ctx->dr1_buffer_pool));
- if (!ctx->dr1_buffer_pool)
- return AVERROR(ENOMEM);
- }
-
- FramePool *pool = ctx->dr1_buffer_pool;
- FrameBuffer *buf;
- int ret, i;
-
- if(av_image_check_size(s->width, s->height, 0, s) || s->pix_fmt<0) {
- av_log(s, AV_LOG_ERROR, "codec_get_buffer: image parameters invalid\n");
- return -1;
- }
-
- pool_lock();
-
- if (!pool->list && (ret = alloc_buffer(pool, s)) < 0) {
- pool_unlock();
- return ret;
- }
-
- buf = pool->list;
- if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
- pool->list = buf->next;
- av_freep(&buf->base[0]);
- av_free(buf);
- if ((ret = alloc_buffer(pool, s)) < 0) {
- pool_unlock();
- return ret;
- }
- buf = pool->list;
- }
- av_assert0(!buf->refcount);
- buf->refcount++;
-
- pool->list = buf->next;
- pool->refcount++;
-
- pool_unlock();
-
- frame->opaque = buf;
- frame->type = FF_BUFFER_TYPE_USER;
- frame->extended_data = frame->data;
-
- buf->used_by_decoder = buf->needed_by_decoder = 1;
- if (frame->buffer_hints & FF_BUFFER_HINTS_VALID) {
- buf->needed_by_decoder =
- (frame->buffer_hints & FF_BUFFER_HINTS_PRESERVE) ||
- (frame->buffer_hints & FF_BUFFER_HINTS_REUSABLE);
- } else {
- buf->needed_by_decoder = !!frame->reference;
- }
-
- for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
- frame->base[i] = buf->base[i]; // XXX h264.c uses base though it shouldn't
- frame->data[i] = buf->data[i];
- frame->linesize[i] = buf->linesize[i];
- }
-
- return 0;
-}
-
-void mp_buffer_ref(struct FrameBuffer *buf)
-{
- pool_lock();
- buf->refcount++;
- pool_unlock();
-}
-
-bool mp_buffer_check(struct FrameBuffer *buf)
-{
- pool_lock();
- bool ok = buf->refcount > 0;
- if (ok)
- buf->refcount++;
- pool_unlock();
- return ok;
-}
-
-void mp_buffer_unref(struct FrameBuffer *buf)
-{
- FramePool *pool = buf->pool;
- bool pool_dead;
-
- pool_lock();
-
- av_assert0(pool->refcount > 0);
- av_assert0(buf->refcount > 0);
- buf->refcount--;
- if (!buf->refcount) {
- FrameBuffer *tmp;
- for(tmp= pool->list; tmp; tmp= tmp->next)
- av_assert1(tmp != buf);
-
- buf->next = pool->list;
- pool->list = buf;
- pool->refcount--;
- }
-
- pool_dead = pool->dead && pool->refcount == 0;
- pool_unlock();
-
- if (pool_dead)
- mp_buffer_pool_free(&pool);
-}
-
-bool mp_buffer_is_unique(struct FrameBuffer *buf)
-{
- int refcount;
- pool_lock();
- refcount = buf->refcount;
- // Decoder has a reference, but doesn't want to use it. (ffmpeg has no good
- // way of transferring frame ownership to the user.)
- if (buf->used_by_decoder && !buf->needed_by_decoder)
- refcount--;
- pool_unlock();
- return refcount == 1;
-}
-
-void mp_codec_release_buffer(AVCodecContext *s, AVFrame *frame)
-{
- FrameBuffer *buf = frame->opaque;
- int i;
-
- if(frame->type!=FF_BUFFER_TYPE_USER) {
- avcodec_default_release_buffer(s, frame);
- return;
- }
-
- buf->used_by_decoder = buf->needed_by_decoder = 0;
-
- for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
- frame->data[i] = NULL;
-
- mp_buffer_unref(buf);
-}
-
-void mp_buffer_pool_free(struct FramePool **p_pool)
-{
- struct FramePool *pool = *p_pool;
- if (!pool)
- return;
-
- pool_lock();
-
- while (pool->list) {
- FrameBuffer *buf = pool->list;
- pool->list = buf->next;
- av_assert0(buf->refcount == 0);
- av_freep(&buf->base[0]);
- av_free(buf);
- }
- pool->dead = 1;
- if (pool->refcount == 0)
- av_free(pool);
-
- pool_unlock();
-
- *p_pool = NULL;
-}
diff --git a/video/decode/vaapi.c b/video/decode/vaapi.c
index bdddfcc7ef..63c180c5a0 100644
--- a/video/decode/vaapi.c
+++ b/video/decode/vaapi.c
@@ -451,7 +451,7 @@ static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img)
const struct vd_lavc_hwdec mp_vd_lavc_vaapi = {
.type = HWDEC_VAAPI,
- .image_formats = (const int[]) {IMGFMT_VAAPI, 0},
+ .image_format = IMGFMT_VAAPI,
.probe = probe,
.init = init,
.uninit = uninit,
@@ -461,7 +461,7 @@ const struct vd_lavc_hwdec mp_vd_lavc_vaapi = {
const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy = {
.type = HWDEC_VAAPI_COPY,
- .image_formats = (const int[]) {IMGFMT_VAAPI, 0},
+ .image_format = IMGFMT_VAAPI,
.probe = probe_copy,
.init = init_copy,
.uninit = uninit,
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 454251f4ad..b49f3c6c44 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -44,7 +44,6 @@
#include "vd.h"
#include "video/img_format.h"
-#include "video/mp_image_pool.h"
#include "video/filter/vf.h"
#include "video/decode/dec_video.h"
#include "demux/stheader.h"
@@ -62,8 +61,8 @@
static void init_avctx(struct dec_video *vd, const char *decoder,
struct vd_lavc_hwdec *hwdec);
static void uninit_avctx(struct dec_video *vd);
-static void setup_refcounting_hw(struct AVCodecContext *s);
+static int get_buffer2_hwdec(AVCodecContext *avctx, AVFrame *pic, int flags);
static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
const enum AVPixelFormat *pix_fmt);
@@ -85,7 +84,6 @@ const m_option_t lavc_decode_opts_conf[] = {
};
const struct vd_lavc_hwdec mp_vd_lavc_vdpau;
-const struct vd_lavc_hwdec mp_vd_lavc_vdpau_old;
const struct vd_lavc_hwdec mp_vd_lavc_vda;
const struct vd_lavc_hwdec mp_vd_lavc_vaapi;
const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy;
@@ -94,9 +92,6 @@ static const struct vd_lavc_hwdec *hwdec_list[] = {
#if HAVE_VDPAU_HWACCEL
&mp_vd_lavc_vdpau,
#endif
-#if HAVE_VDPAU_DECODER
- &mp_vd_lavc_vdpau_old,
-#endif
#if HAVE_VDA_HWACCEL
&mp_vd_lavc_vda,
#endif
@@ -191,52 +186,35 @@ void hwdec_request_api(struct mp_hwdec_info *info, const char *api_name)
}
static int hwdec_probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
- const char *decoder, const char **hw_decoder)
+ const char *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(struct dec_video *vd, bool autoprobe, enum hwdec_type api,
- const char *decoder, struct vd_lavc_hwdec **use_hwdec,
- const char **use_decoder)
+static struct vd_lavc_hwdec *probe_hwdec(struct dec_video *vd, bool autoprobe,
+ enum hwdec_type api,
+ const char *decoder)
{
struct vd_lavc_hwdec *hwdec = find_hwcodec(api);
if (!hwdec) {
MP_VERBOSE(vd, "Requested hardware decoder not "
"compiled.\n");
- return false;
+ return NULL;
}
- const char *hw_decoder = NULL;
- int r = hwdec_probe(hwdec, &vd->hwdec_info, decoder, &hw_decoder);
+ int r = hwdec_probe(hwdec, &vd->hwdec_info, decoder);
if (r >= 0) {
- *use_hwdec = hwdec;
- *use_decoder = hw_decoder;
- return true;
+ return hwdec;
} else if (r == HWDEC_ERR_NO_CODEC) {
MP_VERBOSE(vd, "Hardware decoder '%s' not found in "
- "libavcodec.\n", hw_decoder ? hw_decoder : decoder);
+ "libavcodec.\n", decoder);
} else if (r == HWDEC_ERR_NO_CTX && !autoprobe) {
MP_WARN(vd, "VO does not support requested "
"hardware decoder.\n");
}
- return false;
+ return NULL;
}
@@ -246,7 +224,6 @@ static int init(struct dec_video *vd, const char *decoder)
ctx = vd->priv = talloc_zero(NULL, vd_ffmpeg_ctx);
ctx->log = vd->log;
ctx->opts = vd->opts;
- ctx->non_dr1_pool = talloc_steal(ctx, mp_image_pool_new(16));
if (bstr_endswith0(bstr0(decoder), "_vdpau")) {
MP_WARN(vd, "VDPAU decoder '%s' was requested. "
@@ -260,18 +237,16 @@ static int init(struct dec_video *vd, const char *decoder)
}
struct vd_lavc_hwdec *hwdec = NULL;
- const char *hw_decoder = NULL;
if (hwdec_codec_allowed(vd, decoder)) {
if (vd->opts->hwdec_api == HWDEC_AUTO) {
for (int n = 0; hwdec_list[n]; n++) {
- if (probe_hwdec(vd, true, hwdec_list[n]->type, decoder,
- &hwdec, &hw_decoder))
+ hwdec = probe_hwdec(vd, true, hwdec_list[n]->type, decoder);
+ if (hwdec)
break;
}
} else if (vd->opts->hwdec_api != HWDEC_NONE) {
- probe_hwdec(vd, false, vd->opts->hwdec_api, decoder,
- &hwdec, &hw_decoder);
+ hwdec = probe_hwdec(vd, false, vd->opts->hwdec_api, decoder);
}
} else {
MP_VERBOSE(vd, "Not trying to use hardware decoding: "
@@ -280,8 +255,6 @@ static int init(struct dec_video *vd, const char *decoder)
if (hwdec) {
ctx->software_fallback_decoder = talloc_strdup(ctx, decoder);
- if (hw_decoder)
- decoder = hw_decoder;
MP_INFO(vd, "Trying to use hardware decoding.\n");
} else if (vd->opts->hwdec_api != HWDEC_NONE) {
MP_INFO(vd, "Using software decoding.\n");
@@ -336,7 +309,7 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
ctx->hwdec_info = &vd->hwdec_info;
- ctx->do_dr1 = ctx->do_hw_dr1 = 0;
+ ctx->do_hw_dr1 = 0;
ctx->pix_fmt = AV_PIX_FMT_NONE;
ctx->hwdec = hwdec;
ctx->hwdec_fmt = 0;
@@ -346,30 +319,19 @@ static void init_avctx(struct dec_video *vd, const char *decoder,
avctx->codec_type = AVMEDIA_TYPE_VIDEO;
avctx->codec_id = lavc_codec->id;
-#if HAVE_AVUTIL_REFCOUNTING
avctx->refcounted_frames = 1;
ctx->pic = av_frame_alloc();
-#else
- ctx->pic = avcodec_alloc_frame();
-#endif
if (ctx->hwdec) {
ctx->do_hw_dr1 = true;
avctx->thread_count = 1;
avctx->get_format = get_format_hwdec;
- setup_refcounting_hw(avctx);
+ avctx->get_buffer2 = get_buffer2_hwdec;
if (ctx->hwdec->init(ctx) < 0) {
uninit_avctx(vd);
return;
}
} else {
-#if !HAVE_AVUTIL_REFCOUNTING
- if (lavc_codec->capabilities & CODEC_CAP_DR1) {
- ctx->do_dr1 = true;
- avctx->get_buffer = mp_codec_get_buffer;
- avctx->release_buffer = mp_codec_release_buffer;
- }
-#endif
mp_set_avcodec_threads(avctx, lavc_param->threads);
}
@@ -446,12 +408,7 @@ static void uninit_avctx(struct dec_video *vd)
if (ctx->hwdec && ctx->hwdec->uninit)
ctx->hwdec->uninit(ctx);
-#if HAVE_AVUTIL_REFCOUNTING
av_frame_free(&ctx->pic);
-#else
- avcodec_free_frame(&ctx->pic);
- mp_buffer_pool_free(&ctx->dr1_buffer_pool);
-#endif
}
static void uninit(struct dec_video *vd)
@@ -468,10 +425,6 @@ static void update_image_params(struct dec_video *vd, AVFrame *frame,
float aspect = av_q2d(frame->sample_aspect_ratio) * width / height;
int pix_fmt = frame->format;
-#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 40, 0)
- pix_fmt = ctx->avctx->pix_fmt;
-#endif
-
if (pix_fmt != ctx->pix_fmt) {
ctx->pix_fmt = pix_fmt;
ctx->best_csp = pixfmt2imgfmt(pix_fmt);
@@ -509,13 +462,12 @@ static enum AVPixelFormat get_format_hwdec(struct AVCodecContext *avctx,
assert(ctx->hwdec);
- for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++) {
- const int *okfmt = ctx->hwdec->image_formats;
- for (int n = 0; okfmt && okfmt[n]; n++) {
- if (imgfmt2pixfmt(okfmt[n]) == fmt[i]) {
+ if (ctx->hwdec->image_format) {
+ for (int i = 0; fmt[i] != AV_PIX_FMT_NONE; i++) {
+ if (ctx->hwdec->image_format == pixfmt2imgfmt(fmt[i])) {
ctx->hwdec_w = avctx->width;
ctx->hwdec_h = avctx->height;
- ctx->hwdec_fmt = okfmt[n];
+ ctx->hwdec_fmt = ctx->hwdec->image_format;
if (ctx->hwdec->init_decoder) {
if (ctx->hwdec->init_decoder(ctx, ctx->hwdec_fmt,
ctx->hwdec_w, ctx->hwdec_h) < 0)
@@ -573,8 +525,6 @@ static struct mp_image *get_surface_hwdec(struct dec_video *vd, AVFrame *pic)
return mpi;
}
-#if HAVE_AVUTIL_REFCOUNTING
-
static void free_mpi(void *opaque, uint8_t *data)
{
struct mp_image *mpi = opaque;
@@ -594,120 +544,6 @@ static int get_buffer2_hwdec(AVCodecContext *avctx, AVFrame *pic, int flags)
return 0;
}
-static void setup_refcounting_hw(AVCodecContext *avctx)
-{
- avctx->get_buffer2 = get_buffer2_hwdec;
-}
-
-#else /* HAVE_AVUTIL_REFCOUNTING */
-
-static int get_buffer_hwdec(AVCodecContext *avctx, AVFrame *pic)
-{
- struct dec_video *vd = avctx->opaque;
-
- struct mp_image *mpi = get_surface_hwdec(vd, pic);
- if (!mpi)
- return -1;
-
- pic->opaque = mpi;
- pic->type = FF_BUFFER_TYPE_USER;
-
- /* The libavcodec reordered_opaque functionality is implemented by
- * a similar copy in avcodec_default_get_buffer() and without a
- * workaround like this it'd stop working when a custom buffer
- * callback is used.
- */
- pic->reordered_opaque = avctx->reordered_opaque;
- return 0;
-}
-
-static void release_buffer_hwdec(AVCodecContext *avctx, AVFrame *pic)
-{
- mp_image_t *mpi = pic->opaque;
-
- assert(pic->type == FF_BUFFER_TYPE_USER);
- assert(mpi);
-
- talloc_free(mpi);
-
- for (int i = 0; i < 4; i++)
- pic->data[i] = NULL;
-}
-
-static void setup_refcounting_hw(AVCodecContext *avctx)
-{
- avctx->get_buffer = get_buffer_hwdec;
- avctx->release_buffer = release_buffer_hwdec;
-}
-
-#endif /* HAVE_AVUTIL_REFCOUNTING */
-
-#if HAVE_AVUTIL_REFCOUNTING
-
-static struct mp_image *image_from_decoder(struct dec_video *vd)
-{
- vd_ffmpeg_ctx *ctx = vd->priv;
- AVFrame *pic = ctx->pic;
-
- struct mp_image *img = mp_image_from_av_frame(pic);
- av_frame_unref(pic);
-
- return img;
-}
-
-#else /* HAVE_AVUTIL_REFCOUNTING */
-
-static void fb_ref(void *b)
-{
- mp_buffer_ref(b);
-}
-
-static void fb_unref(void *b)
-{
- mp_buffer_unref(b);
-}
-
-static bool fb_is_unique(void *b)
-{
- return mp_buffer_is_unique(b);
-}
-
-static struct mp_image *image_from_decoder(struct dec_video *vd)
-{
- vd_ffmpeg_ctx *ctx = vd->priv;
- AVFrame *pic = ctx->pic;
-
- struct mp_image new = {0};
- mp_image_copy_fields_from_av_frame(&new, pic);
-
- struct mp_image *mpi;
- if (ctx->do_hw_dr1 && pic->opaque) {
- mpi = pic->opaque; // reordered frame
- assert(mpi);
- mpi = mp_image_new_ref(mpi);
- mp_image_copy_attributes(mpi, &new);
- } else if (ctx->do_dr1 && pic->opaque) {
- struct FrameBuffer *fb = pic->opaque;
- // initial reference for mpi
- if (!new.planes[0] || !mp_buffer_check(fb)) {
- // Decoder returned an unreferenced buffer! Taking this would just
- // lead to an eventual double-free. Nothing we can do about this.
- // So just say "fuck you" in a nice way.
- MP_FATAL(vd,
- "Impossible condition detected! This version of Libav/FFmpeg is not\n"
- "supported anymore. Please update.\n");
- return NULL;
- }
- mpi = mp_image_new_external_ref(&new, fb, fb_ref, fb_unref,
- fb_is_unique, NULL);
- } else {
- mpi = mp_image_pool_new_copy(ctx->non_dr1_pool, &new);
- }
- return mpi;
-}
-
-#endif /* HAVE_AVUTIL_REFCOUNTING */
-
static int decode(struct dec_video *vd, struct demux_packet *packet,
int flags, struct mp_image **out_image)
{
@@ -741,8 +577,8 @@ static int decode(struct dec_video *vd, struct demux_packet *packet,
vd->codec_pts = mp_pts_from_av(ctx->pic->pkt_pts, NULL);
vd->codec_dts = mp_pts_from_av(ctx->pic->pkt_dts, NULL);
- // Note: potentially resets ctx->pic as it is transferred to mpi
- struct mp_image *mpi = image_from_decoder(vd);
+ struct mp_image *mpi = mp_image_from_av_frame(ctx->pic);
+ av_frame_unref(ctx->pic);
if (!mpi)
return 0;
assert(mpi->planes[0]);
diff --git a/video/decode/vda.c b/video/decode/vda.c
index 91d96f191c..6ac34aed89 100644
--- a/video/decode/vda.c
+++ b/video/decode/vda.c
@@ -214,7 +214,7 @@ static struct mp_image *allocate_image(struct lavc_ctx *ctx, int fmt,
const struct vd_lavc_hwdec mp_vd_lavc_vda = {
.type = HWDEC_VDA,
- .image_formats = (const int[]) { IMGFMT_VDA, 0 },
+ .image_format = IMGFMT_VDA,
.probe = probe,
.init = init,
.uninit = uninit,
diff --git a/video/decode/vdpau.c b/video/decode/vdpau.c
index 995b5460e8..34435360c3 100644
--- a/video/decode/vdpau.c
+++ b/video/decode/vdpau.c
@@ -206,7 +206,7 @@ static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
const struct vd_lavc_hwdec mp_vd_lavc_vdpau = {
.type = HWDEC_VDPAU,
- .image_formats = (const int[]) {IMGFMT_VDPAU, 0},
+ .image_format = IMGFMT_VDPAU,
.probe = probe,
.init = init,
.uninit = uninit,
diff --git a/video/decode/vdpau_old.c b/video/decode/vdpau_old.c
deleted file mode 100644
index 9e03026221..0000000000
--- a/video/decode/vdpau_old.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * VDPAU video output driver
- *
- * Copyright (C) 2008 NVIDIA
- * Copyright (C) 2009 Uoti Urpala
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stddef.h>
-#include <assert.h>
-
-#include <libavcodec/vdpau.h>
-#include <libavutil/common.h>
-
-#include "lavc.h"
-#include "video/fmt-conversion.h"
-#include "video/vdpau.h"
-#include "video/hwdec.h"
-#include "video/decode/dec_video.h"
-
-struct priv {
- struct mp_log *log;
- struct mp_vdpau_ctx *mpvdp;
- struct vdp_functions *vdp;
- VdpDevice vdp_device;
- uint64_t preemption_counter;
-
- int image_format;
- int vid_width;
- int vid_height;
-
- VdpDecoder decoder;
- int decoder_max_refs;
-};
-
-static void mark_uninitialized(struct lavc_ctx *ctx)
-{
- struct priv *p = ctx->hwdec_priv;
-
- p->vdp_device = VDP_INVALID_HANDLE;
- p->decoder = VDP_INVALID_HANDLE;
-}
-
-static int handle_preemption(struct lavc_ctx *ctx)
-{
- struct priv *p = ctx->hwdec_priv;
-
- if (!mp_vdpau_status_ok(p->mpvdp))
- return -1;
-
- // Mark objects as destroyed if preemption+reinit occured
- if (p->preemption_counter < p->mpvdp->preemption_counter) {
- p->preemption_counter = p->mpvdp->preemption_counter;
- mark_uninitialized(ctx);
- }
-
- p->vdp_device = p->mpvdp->vdp_device;
- p->vdp = p->mpvdp->vdp;
-
- return 0;
-}
-
-static bool create_vdp_decoder(struct lavc_ctx *ctx, int max_refs)
-{
- struct priv *p = ctx->hwdec_priv;
- struct vdp_functions *vdp = p->mpvdp->vdp;
- VdpStatus vdp_st;
- VdpDecoderProfile vdp_decoder_profile;
-
- if (handle_preemption(ctx) < 0)
- return false;
-
- if (p->decoder != VDP_INVALID_HANDLE)
- vdp->decoder_destroy(p->decoder);
-
- switch (p->image_format) {
- case IMGFMT_VDPAU_MPEG1:
- vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG1;
- break;
- case IMGFMT_VDPAU_MPEG2:
- vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
- break;
- case IMGFMT_VDPAU_H264:
- vdp_decoder_profile = VDP_DECODER_PROFILE_H264_HIGH;
- MP_VERBOSE(p, "Creating H264 hardware decoder "
- "for %d reference frames.\n", max_refs);
- break;
- case IMGFMT_VDPAU_WMV3:
- vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_MAIN;
- break;
- case IMGFMT_VDPAU_VC1:
- vdp_decoder_profile = VDP_DECODER_PROFILE_VC1_ADVANCED;
- break;
- case IMGFMT_VDPAU_MPEG4:
- vdp_decoder_profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP;
- break;
- default:
- MP_ERR(p, "Unknown image format!\n");
- goto fail;
- }
- vdp_st = vdp->decoder_create(p->vdp_device, vdp_decoder_profile,
- p->vid_width, p->vid_height, max_refs,
- &p->decoder);
- CHECK_VDP_WARNING(p, "Failed creating VDPAU decoder");
- if (vdp_st != VDP_STATUS_OK)
- goto fail;
- p->decoder_max_refs = max_refs;
- return true;
-
-fail:
- p->decoder = VDP_INVALID_HANDLE;
- p->decoder_max_refs = 0;
- return false;
-}
-
-static void draw_slice_hwdec(struct AVCodecContext *s,
- const AVFrame *src, int offset[4],
- int y, int type, int height)
-{
- struct dec_video *vd = s->opaque;
- struct lavc_ctx *ctx = vd->priv;
- struct priv *p = ctx->hwdec_priv;
- struct vdp_functions *vdp = p->vdp;
- VdpStatus vdp_st;
-
- if (handle_preemption(ctx) < 0)
- return;
-
- struct vdpau_render_state *rndr = (void *)src->data[0];
-
- int max_refs = p->image_format == IMGFMT_VDPAU_H264 ?
- rndr->info.h264.num_ref_frames : 2;
- if ((p->decoder == VDP_INVALID_HANDLE || p->decoder_max_refs < max_refs)
- && !create_vdp_decoder(ctx, max_refs))
- return;
-
- vdp_st = vdp->decoder_render(p->decoder, rndr->surface,
- (void *)&rndr->info,
- rndr->bitstream_buffers_used,
- rndr->bitstream_buffers);
- CHECK_VDP_WARNING(p, "Failed VDPAU decoder rendering");
-}
-
-static void release_surface(void *ptr)
-{
- struct vdpau_render_state *state = ptr;
- // Free bitstream buffers allocated by libavcodec
- av_freep(&state->bitstream_buffers);
- talloc_free(state);
-}
-
-static struct mp_image *allocate_image(struct lavc_ctx *ctx, int imgfmt,
- int w, int h)
-{
- struct priv *p = ctx->hwdec_priv;
-
- if (!IMGFMT_IS_VDPAU(imgfmt))
- return NULL;
-
- if (w != p->vid_width || h != p->vid_height || imgfmt != p->image_format) {
- p->vid_width = w;
- p->vid_height = h;
- p->image_format = imgfmt;
- if (!create_vdp_decoder(ctx, 2))
- return NULL;
- }
-
- VdpChromaType chroma;
- mp_vdpau_get_format(p->image_format, &chroma, NULL);
-
- struct mp_image *img =
- mp_vdpau_get_video_surface(p->mpvdp, imgfmt, chroma, w, h);