diff options
author | Stefano Pigozzi <stefano.pigozzi@gmail.com> | 2014-08-01 09:16:42 +0200 |
---|---|---|
committer | Stefano Pigozzi <stefano.pigozzi@gmail.com> | 2014-08-01 10:38:18 +0200 |
commit | 6aac17cebbcec645a9c07043b78d57a9b04f2578 (patch) | |
tree | 0f5d78f2e7e157e3a2320ce23b4df1e63fcce7ac /video/decode/vda.c | |
parent | 33137606e9fba8677f1cb1f5424aff2067075147 (diff) | |
download | mpv-6aac17cebbcec645a9c07043b78d57a9b04f2578.tar.bz2 mpv-6aac17cebbcec645a9c07043b78d57a9b04f2578.tar.xz |
vda: only support the new hwaccel 1.2 API (remove old code)
Since the new hwaccel API is now merged in ffmpeg's stable release, we can
finally remove support for the old API.
I pretty much kept lu_zero's new code unchanged and just added some error
printing (that we had with the old glue code) to make the life of our users
less miserable.
Diffstat (limited to 'video/decode/vda.c')
-rw-r--r-- | video/decode/vda.c | 158 |
1 files changed, 13 insertions, 145 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 |