diff options
Diffstat (limited to 'video/decode')
-rw-r--r-- | video/decode/lavc.h | 3 | ||||
-rw-r--r-- | video/decode/vaapi.c | 21 | ||||
-rw-r--r-- | video/decode/vd_lavc.c | 13 |
3 files changed, 37 insertions, 0 deletions
diff --git a/video/decode/lavc.h b/video/decode/lavc.h index 14dc6dda4e..f6b3c700d9 100644 --- a/video/decode/lavc.h +++ b/video/decode/lavc.h @@ -60,6 +60,9 @@ struct vd_lavc_hwdec { int w, int h); // Process the image returned by the libavcodec decoder. struct mp_image *(*process_image)(struct lavc_ctx *ctx, struct mp_image *img); + // For horrible Intel shit-drivers only + void (*lock)(struct lavc_ctx *ctx); + void (*unlock)(struct lavc_ctx *ctx); }; enum { diff --git a/video/decode/vaapi.c b/video/decode/vaapi.c index 5f9002762f..de26ac2955 100644 --- a/video/decode/vaapi.c +++ b/video/decode/vaapi.c @@ -187,6 +187,8 @@ static void destroy_decoder(struct lavc_ctx *ctx) { struct priv *p = ctx->hwdec_priv; + va_lock(p->ctx); + if (p->va_context->context_id != VA_INVALID_ID) { vaDestroyContext(p->display, p->va_context->context_id); p->va_context->context_id = VA_INVALID_ID; @@ -197,6 +199,8 @@ static void destroy_decoder(struct lavc_ctx *ctx) p->va_context->config_id = VA_INVALID_ID; } + va_unlock(p->ctx); + mp_image_pool_clear(p->pool); } @@ -219,6 +223,8 @@ static int init_decoder(struct lavc_ctx *ctx, int fmt, int w, int h) destroy_decoder(ctx); + va_lock(p->ctx); + const struct hwdec_profile_entry *pe = hwdec_find_profile(ctx, profiles); if (!pe) { MP_ERR(p, "Unsupported codec or profile.\n"); @@ -300,6 +306,7 @@ static int init_decoder(struct lavc_ctx *ctx, int fmt, int w, int h) res = 0; error: + va_unlock(p->ctx); talloc_free(tmp); return res; } @@ -455,6 +462,18 @@ static struct mp_image *copy_image(struct lavc_ctx *ctx, struct mp_image *img) return img; } +static void intel_shit_lock(struct lavc_ctx *ctx) +{ + struct priv *p = ctx->hwdec_priv; + va_lock(p->ctx); +} + +static void intel_crap_unlock(struct lavc_ctx *ctx) +{ + struct priv *p = ctx->hwdec_priv; + va_unlock(p->ctx); +} + const struct vd_lavc_hwdec mp_vd_lavc_vaapi = { .type = HWDEC_VAAPI, .image_format = IMGFMT_VAAPI, @@ -463,6 +482,8 @@ const struct vd_lavc_hwdec mp_vd_lavc_vaapi = { .uninit = uninit, .init_decoder = init_decoder, .allocate_image = allocate_image, + .lock = intel_shit_lock, + .unlock = intel_crap_unlock, }; const struct vd_lavc_hwdec mp_vd_lavc_vaapi_copy = { diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c index 1cd4503968..350f5f16b2 100644 --- a/video/decode/vd_lavc.c +++ b/video/decode/vd_lavc.c @@ -160,6 +160,17 @@ static bool hwdec_codec_allowed(struct dec_video *vd, const char *codec) return false; } +static void hwdec_lock(struct lavc_ctx *ctx) +{ + if (ctx->hwdec && ctx->hwdec->lock) + ctx->hwdec->lock(ctx); +} +static void hwdec_unlock(struct lavc_ctx *ctx) +{ + if (ctx->hwdec && ctx->hwdec->unlock) + ctx->hwdec->unlock(ctx); +} + // Find the correct profile entry for the current codec and profile. // Assumes the table has higher profiles first (for each codec). const struct hwdec_profile_entry *hwdec_find_profile( @@ -608,7 +619,9 @@ static int decode(struct dec_video *vd, struct demux_packet *packet, mp_set_av_packet(&pkt, packet, NULL); + hwdec_lock(ctx); ret = avcodec_decode_video2(avctx, ctx->pic, &got_picture, &pkt); + hwdec_unlock(ctx); if (ret < 0) { MP_WARN(vd, "Error while decoding frame!\n"); return -1; |