summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/decode/lavc.h1
-rw-r--r--video/decode/lavc_dr1.c10
-rw-r--r--video/decode/vd_lavc.c13
3 files changed, 23 insertions, 1 deletions
diff --git a/video/decode/lavc.h b/video/decode/lavc.h
index 71d568aa8a..45d2d9b5cd 100644
--- a/video/decode/lavc.h
+++ b/video/decode/lavc.h
@@ -98,5 +98,6 @@ 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
index 03e2b5b873..f730a6c231 100644
--- a/video/decode/lavc_dr1.c
+++ b/video/decode/lavc_dr1.c
@@ -204,6 +204,16 @@ void mp_buffer_ref(struct FrameBuffer *buf)
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;
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index eed79e81b1..454251f4ad 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -688,7 +688,16 @@ static struct mp_image *image_from_decoder(struct dec_video *vd)
mp_image_copy_attributes(mpi, &new);
} else if (ctx->do_dr1 && pic->opaque) {
struct FrameBuffer *fb = pic->opaque;
- mp_buffer_ref(fb); // initial reference for mpi
+ // 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 {
@@ -734,6 +743,8 @@ static int decode(struct dec_video *vd, struct demux_packet *packet,
// Note: potentially resets ctx->pic as it is transferred to mpi
struct mp_image *mpi = image_from_decoder(vd);
+ if (!mpi)
+ return 0;
assert(mpi->planes[0]);
mp_image_set_params(mpi, &params);