mirror of https://github.com/mpv-player/mpv
vd_lavc: add more ifdeffery and ffmpeg cargo culting for correctness
We mixed the "old" AVFrame management functions (avcodec_alloc_frame, avcodec_free_frame) with reference counting. This doesn't work correctly; you must use av_frame_alloc and av_frame_free. Of course ffmpeg doesn't warn us about the bad usage, but will just mess up things silently. (Thanks a lot...) While the alloc function seems to be 100% compatible, the free function will do bad things, such as freeing memory that might still be referenced by another frame. I didn't experience any actual bugs, but maybe that was pure luck.
This commit is contained in:
parent
d64b165b2a
commit
3ac568714c
|
@ -349,7 +349,6 @@ static void init_avctx(sh_video_t *sh, const char *decoder,
|
||||||
ctx->image_params = (struct mp_image_params){0};
|
ctx->image_params = (struct mp_image_params){0};
|
||||||
ctx->vo_image_params = (struct mp_image_params){0};
|
ctx->vo_image_params = (struct mp_image_params){0};
|
||||||
ctx->hwdec = hwdec;
|
ctx->hwdec = hwdec;
|
||||||
ctx->pic = avcodec_alloc_frame();
|
|
||||||
ctx->avctx = avcodec_alloc_context3(lavc_codec);
|
ctx->avctx = avcodec_alloc_context3(lavc_codec);
|
||||||
AVCodecContext *avctx = ctx->avctx;
|
AVCodecContext *avctx = ctx->avctx;
|
||||||
avctx->opaque = sh;
|
avctx->opaque = sh;
|
||||||
|
@ -358,6 +357,14 @@ static void init_avctx(sh_video_t *sh, const char *decoder,
|
||||||
|
|
||||||
avctx->thread_count = lavc_param->threads;
|
avctx->thread_count = lavc_param->threads;
|
||||||
|
|
||||||
|
|
||||||
|
#if HAVE_AVUTIL_REFCOUNTING
|
||||||
|
avctx->refcounted_frames = 1;
|
||||||
|
ctx->pic = av_frame_alloc();
|
||||||
|
#else
|
||||||
|
ctx->pic = avcodec_alloc_frame();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ctx->hwdec && ctx->hwdec->allocate_image) {
|
if (ctx->hwdec && ctx->hwdec->allocate_image) {
|
||||||
ctx->do_hw_dr1 = true;
|
ctx->do_hw_dr1 = true;
|
||||||
avctx->thread_count = 1;
|
avctx->thread_count = 1;
|
||||||
|
@ -369,9 +376,7 @@ static void init_avctx(sh_video_t *sh, const char *decoder,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if HAVE_AVUTIL_REFCOUNTING
|
#if !HAVE_AVUTIL_REFCOUNTING
|
||||||
avctx->refcounted_frames = 1;
|
|
||||||
#else
|
|
||||||
if (lavc_codec->capabilities & CODEC_CAP_DR1) {
|
if (lavc_codec->capabilities & CODEC_CAP_DR1) {
|
||||||
ctx->do_dr1 = true;
|
ctx->do_dr1 = true;
|
||||||
avctx->get_buffer = mp_codec_get_buffer;
|
avctx->get_buffer = mp_codec_get_buffer;
|
||||||
|
@ -449,12 +454,14 @@ static void uninit_avctx(sh_video_t *sh)
|
||||||
}
|
}
|
||||||
|
|
||||||
av_freep(&ctx->avctx);
|
av_freep(&ctx->avctx);
|
||||||
avcodec_free_frame(&ctx->pic);
|
|
||||||
|
|
||||||
if (ctx->hwdec && ctx->hwdec->uninit)
|
if (ctx->hwdec && ctx->hwdec->uninit)
|
||||||
ctx->hwdec->uninit(ctx);
|
ctx->hwdec->uninit(ctx);
|
||||||
|
|
||||||
#if !HAVE_AVUTIL_REFCOUNTING
|
#if HAVE_AVUTIL_REFCOUNTING
|
||||||
|
av_frame_free(&ctx->pic);
|
||||||
|
#else
|
||||||
|
avcodec_free_frame(&ctx->pic);
|
||||||
mp_buffer_pool_free(&ctx->dr1_buffer_pool);
|
mp_buffer_pool_free(&ctx->dr1_buffer_pool);
|
||||||
#endif
|
#endif
|
||||||
ctx->last_sample_aspect_ratio = (AVRational){0, 0};
|
ctx->last_sample_aspect_ratio = (AVRational){0, 0};
|
||||||
|
@ -603,7 +610,6 @@ static int get_buffer2_hwdec(AVCodecContext *avctx, AVFrame *pic, int flags)
|
||||||
static void setup_refcounting_hw(AVCodecContext *avctx)
|
static void setup_refcounting_hw(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
avctx->get_buffer2 = get_buffer2_hwdec;
|
avctx->get_buffer2 = get_buffer2_hwdec;
|
||||||
avctx->refcounted_frames = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_AVUTIL_REFCOUNTING */
|
#else /* HAVE_AVUTIL_REFCOUNTING */
|
||||||
|
|
Loading…
Reference in New Issue