summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/decode/vda.c158
-rw-r--r--video/fmt-conversion.c10
-rw-r--r--wscript18
3 files changed, 19 insertions, 167 deletions
diff --git a/video/decode/vda.c b/video/decode/vda.c
index acfadc7be2..6e54479c98 100644
--- a/video/decode/vda.c
+++ b/video/decode/vda.c
@@ -37,55 +37,22 @@ static int probe(struct vd_lavc_hwdec *hwdec, struct mp_hwdec_info *info,
return 0;
}
-#if HAVE_VDA_AV_VDA_ALLOC_CONTEXT
-
static int init(struct lavc_ctx *ctx)
{
return 0;
}
-static int init_decoder(struct lavc_ctx *ctx, int fmt, int w, int h)
-{
- av_vda_default_free(ctx->avctx);
-
- if (av_vda_default_init(ctx->avctx) < 0)
- return -1;
- return 0;
-}
-
-static void uninit(struct lavc_ctx *ctx)
-{
- if (ctx->avctx)
- av_vda_default_free(ctx->avctx);
-}
-
-const struct vd_lavc_hwdec mp_vd_lavc_vda = {
- .type = HWDEC_VDA,
- .image_format = IMGFMT_VDA,
- .probe = probe,
- .init = init,
- .uninit = uninit,
- .init_decoder = init_decoder,
-};
-
-#else
-struct priv {
- struct vda_context vda_ctx;
-};
-
struct vda_error {
int code;
char *reason;
};
static const struct vda_error vda_errors[] = {
- { kVDADecoderHardwareNotSupportedErr,
- "Hardware doesn't support accelerated decoding" },
- { kVDADecoderFormatNotSupportedErr,
- "Hardware doesn't support requested output format" },
- { kVDADecoderConfigurationError,
+ { AVERROR(ENOSYS),
+ "Hardware doesn't support accelerated decoding for this stream" },
+ { AVERROR(EINVAL),
"Invalid configuration provided to VDADecoderCreate" },
- { kVDADecoderDecoderFailedErr,
+ { AVERROR_INVALIDDATA,
"Generic error returned by the decoder layer. The cause can range from"
" VDADecoder finding errors in the bitstream to another application"
" using VDA at the moment. Only one application can use VDA at a"
@@ -106,117 +73,21 @@ static void print_vda_error(struct mp_log *log, int lev, char *message,
mp_msg(log, lev, "%s: %d\n", message, error_code);
}
-static int init_vda_decoder(struct lavc_ctx *ctx)
+static int init_decoder(struct lavc_ctx *ctx, int fmt, int w, int h)
{
- struct priv *p = ctx->hwdec_priv;
-
- if (p->vda_ctx.decoder)
- ff_vda_destroy_decoder(&p->vda_ctx);
-
- p->vda_ctx = (struct vda_context) {
- .width = ctx->avctx->width,
- .height = ctx->avctx->height,
- .format = 'avc1',
- // equals to k2vuyPixelFormat (= YUY2/UYVY)
- .cv_pix_fmt_type = kCVPixelFormatType_422YpCbCr8,
-
-#if HAVE_VDA_LIBAVCODEC_REFCOUNTING
- .use_ref_buffer = 1,
-#endif
- // use_ref_buffer is 1 in ffmpeg (while libav doesn't support this
- // feature). This means that in the libav case, libavcodec returns us
- // a CVPixelBuffer with refcount=1 AND hands over ownership of that
- // reference.
-
- // This is slightly different from a typical refcounted situation
- // where the API would return something that we need to to retain
- // for it to stay around (ffmpeg behaves like expected when using
- // use_ref_buffer = 1).
-
- // If mpv doesn't properly free CVPixelBufferRefs that are no longer
- // used, the wrapped IOSurface ids increase monotonically hinting at
- // a leaking of both CVPixelBuffers and IOSurfaces.
- };
-
- int status = ff_vda_create_decoder(
- &p->vda_ctx, ctx->avctx->extradata, ctx->avctx->extradata_size);
-
- if (status) {
- print_vda_error(ctx->log, MSGL_ERR, "failed to init VDA decoder", status);
+ av_vda_default_free(ctx->avctx);
+ int err = av_vda_default_init(ctx->avctx);
+ if (err < 0) {
+ print_vda_error(ctx->log, MSGL_ERR, "failed to init VDA decoder", err);
return -1;
}
-
- return 0;
-}
-
-static int init(struct lavc_ctx *ctx)
-{
- struct priv *p = talloc_zero(NULL, struct priv);
- ctx->hwdec_priv = p;
- ctx->avctx->hwaccel_context = &p->vda_ctx;
return 0;
}
-static void uninit(struct lavc_ctx *ctx) {
- struct priv *p = ctx->hwdec_priv;
- if (p->vda_ctx.decoder)
- ff_vda_destroy_decoder(&p->vda_ctx);
-}
-
-// This actually returns dummy images, since vda_264 creates it's own AVFrames
-// to wrap CVPixelBuffers in planes[3].
-static struct mp_image *allocate_image(struct lavc_ctx *ctx, int fmt,
- int w, int h)
-{
- struct priv *p = ctx->hwdec_priv;
-
- if (fmt != IMGFMT_VDA)
- return NULL;
-
- if (w != p->vda_ctx.width || h != p->vda_ctx.height)
- init_vda_decoder(ctx);
-
- struct mp_image img = {0};
- mp_image_setfmt(&img, fmt);
- mp_image_set_size(&img, w, h);
-
- // There is an `assert(!dst->f.buf[0])` in libavcodec/h264.c
- // Setting the first plane to some dummy value allows to satisfy it
- img.planes[0] = (void*)"dummy";
-
- return mp_image_new_custom_ref(&img, NULL, NULL);
-}
-
-static void cv_retain(void *pbuf)
-{
- CVPixelBufferRetain((CVPixelBufferRef)pbuf);
-}
-
-static void cv_release(void *pbuf)
-{
- CVPixelBufferRelease((CVPixelBufferRef)pbuf);
-}
-
-static struct mp_image *mp_image_new_cv_ref(struct mp_image *mpi)
-{
- CVPixelBufferRef pbuf = (CVPixelBufferRef)mpi->planes[3];
- // mp_image_new_external_ref assumes the external reference count is
- // already 1 so the calls to cv_retain and cv_release are unbalanced (
- // in favor of cv_release). To balance out the retain count we need to
- // retain the CVPixelBufferRef if ffmpeg is set to automatically release
- // it when the AVFrame is unreffed.
-#if HAVE_VDA_LIBAVCODEC_REFCOUNTING
- cv_retain(pbuf);
-#endif
- return mp_image_new_external_ref(mpi,
- pbuf, cv_retain, cv_release, NULL, NULL);
-}
-
-static struct mp_image *process_image(struct lavc_ctx *ctx, struct mp_image *mpi)
+static void uninit(struct lavc_ctx *ctx)
{
- struct mp_image *cv_mpi = mp_image_new_cv_ref(mpi);
- mp_image_unrefp(&mpi);
- return cv_mpi;
+ if (ctx->avctx)
+ av_vda_default_free(ctx->avctx);
}
const struct vd_lavc_hwdec mp_vd_lavc_vda = {
@@ -225,8 +96,5 @@ const struct vd_lavc_hwdec mp_vd_lavc_vda = {
.probe = probe,
.init = init,
.uninit = uninit,
- .allocate_image = allocate_image,
- .process_image = process_image,
+ .init_decoder = init_decoder,
};
-
-#endif
diff --git a/video/fmt-conversion.c b/video/fmt-conversion.c
index 44fafa631f..a8ae905813 100644
--- a/video/fmt-conversion.c
+++ b/video/fmt-conversion.c
@@ -172,13 +172,11 @@ static const struct {
{IMGFMT_BGR0, AV_PIX_FMT_BGRA},
#endif
- {IMGFMT_VDPAU, AV_PIX_FMT_VDPAU},
-#if HAVE_VDA_AV_VDA_ALLOC_CONTEXT
- {IMGFMT_VDA, AV_PIX_FMT_VDA},
-#else
- {IMGFMT_VDA, AV_PIX_FMT_VDA_VLD},
+ {IMGFMT_VDPAU, AV_PIX_FMT_VDPAU},
+#if HAVE_VDA_HWACCEL
+ {IMGFMT_VDA, AV_PIX_FMT_VDA},
#endif
- {IMGFMT_VAAPI, AV_PIX_FMT_VAAPI_VLD},
+ {IMGFMT_VAAPI, AV_PIX_FMT_VAAPI_VLD},
{0, AV_PIX_FMT_NONE}
};
diff --git a/wscript b/wscript
index 148432dabd..2c82eac3e2 100644
--- a/wscript
+++ b/wscript
@@ -683,27 +683,13 @@ hwaccel_features = [
} , {
'name': '--vda-hwaccel',
'desc': 'libavcodec VDA hwaccel',
- 'deps': [ 'corevideo'],
+ 'deps': [ 'corevideo' ],
'func': compose_checks(
check_headers('VideoDecodeAcceleration/VDADecoder.h'),
check_statement('libavcodec/vda.h',
- 'ff_vda_create_decoder(NULL, NULL, NULL)',
+ 'av_vda_alloc_context()',
framework='IOSurface',
use='libav')),
- } , {
- 'name': 'vda-libavcodec-refcounting',
- 'desc': "libavcodec VDA ref-counted CVPixelBuffers",
- 'deps': [ 'vda-hwaccel' ],
- 'func': check_statement ('libavcodec/vda.h',
- """struct vda_context a = (struct vda_context) {
- .use_ref_buffer = 1 }""", use='libav')
- }, {
- 'name': 'vda-av-vda-alloc-context',
- 'desc': "libavcodec VDA hwaccel 1.2",
- 'deps': [ 'vda-hwaccel' ],
- 'func': check_statement('libavcodec/vda.h',
- 'av_vda_alloc_context()',
- use='libav')
}, {
'name': '--vda-gl',
'desc': 'VDA with OpenGL',