diff options
author | Janne Grunau <janne-vlc@jannau.net> | 2018-11-22 21:23:49 +0300 |
---|---|---|
committer | Janne Grunau <janne-vlc@jannau.net> | 2018-11-23 01:31:53 +0300 |
commit | f8e1a621f9b68ac60115773874b0ce646e79c02d (patch) | |
tree | 6a016dc04c540cb1190d92f329a764dd884afd4f | |
parent | 3fa2f04f23482dcb97207096c3206605aa53539e (diff) |
frame-mt: check delayed pics for decoding errors
Also mark all planes broken after tile error.
Fixes an use-of-uninitialized-value in apply_to_row_y() with
clusterfuzz-testcase-minimized-dav1d_fuzzer_mt-5652400153559040. Credits
to oss-fuzz.
-rw-r--r-- | src/decode.c | 2 | ||||
-rw-r--r-- | src/lib.c | 7 | ||||
-rw-r--r-- | src/obu.c | 8 |
3 files changed, 14 insertions, 3 deletions
diff --git a/src/decode.c b/src/decode.c index 2a4b200..92ce9e2 100644 --- a/src/decode.c +++ b/src/decode.c @@ -2873,7 +2873,7 @@ int dav1d_decode_frame(Dav1dFrameContext *const f) { } if (progress == TILE_ERROR) { dav1d_thread_picture_signal(&f->sr_cur, FRAME_ERROR, - progress_plane_type); + PLANE_TYPE_ALL); const uint64_t all_mask = ~0ULL >> (64 - f->n_tc); pthread_mutex_lock(&f->tile_thread.lock); while (f->tile_thread.available != all_mask) @@ -237,8 +237,13 @@ int dav1d_get_picture(Dav1dContext *const c, Dav1dPicture *const out) if (++c->frame_thread.next == c->n_fc) c->frame_thread.next = 0; if (out_delayed->p.data[0]) { - if (out_delayed->visible && !out_delayed->flushed) + const unsigned progress = atomic_load_explicit(&out_delayed->progress[1], + memory_order_relaxed); + if (out_delayed->visible && !out_delayed->flushed && + progress != FRAME_ERROR) + { dav1d_picture_ref(&c->out, &out_delayed->p); + } dav1d_thread_picture_unref(out_delayed); if (c->out.data[0]) return output_image(c, out, &c->out); @@ -41,6 +41,7 @@ #include "src/levels.h" #include "src/obu.h" #include "src/ref.h" +#include "src/thread_task.h" static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb, Av1SequenceHeader *const hdr) @@ -1316,8 +1317,13 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) { Dav1dThreadPicture *const out_delayed = &c->frame_thread.out_delayed[next]; if (out_delayed->p.data[0]) { - if (out_delayed->visible && !out_delayed->flushed) + const unsigned progress = atomic_load_explicit(&out_delayed->progress[1], + memory_order_relaxed); + if (out_delayed->visible && !out_delayed->flushed && + progress != FRAME_ERROR) + { dav1d_picture_ref(&c->out, &out_delayed->p); + } dav1d_thread_picture_unref(out_delayed); } dav1d_thread_picture_ref(out_delayed, |