shithub: dav1d

Download patch

ref: 52b575c82641c0098404a874379c33e215afc563
parent: e72bec43b19f932bd1f95210fe4208e7d725abc9
author: Janne Grunau <janne-vlc@jannau.net>
date: Sat Dec 8 10:28:48 EST 2018

cdf: make CdfThreadContext allocation failure safe

--- a/src/cdf.c
+++ b/src/cdf.c
@@ -4055,14 +4055,15 @@
     [3] = { .cdf = NULL },
 };
 
-void dav1d_init_states(CdfThreadContext *const cdf, const int qidx) {
+int dav1d_init_states(CdfThreadContext *const cdf, const int qidx) {
     const int qcat = get_qcat_idx(qidx);
     if (cdf_init[qcat].cdf) {
         dav1d_cdf_thread_ref(cdf, &cdf_init[qcat]);
-        return;
+        return 0;
     }
 
-    dav1d_cdf_thread_alloc(&cdf_init[qcat], NULL);
+    int res = dav1d_cdf_thread_alloc(&cdf_init[qcat], NULL);
+    if (res < 0) return res;
     cdf_init[qcat].cdf->m = av1_default_cdf;
     memcpy(cdf_init[qcat].cdf->kfym, default_kf_y_mode_cdf,
            sizeof(default_kf_y_mode_cdf));
@@ -4070,6 +4071,7 @@
     cdf_init[qcat].cdf->mv = default_mv_cdf;
     cdf_init[qcat].cdf->dmv = default_mv_cdf;
     dav1d_cdf_thread_ref(cdf, &cdf_init[qcat]);
+    return 0;
 }
 
 void dav1d_update_tile_cdf(const Dav1dFrameHeader *const hdr,
@@ -4211,11 +4213,12 @@
 /*
  * CDF threading wrappers.
  */
-void dav1d_cdf_thread_alloc(CdfThreadContext *const cdf,
+int dav1d_cdf_thread_alloc(CdfThreadContext *const cdf,
                             struct thread_data *const t)
 {
     cdf->ref = dav1d_ref_create(sizeof(CdfContext) +
                                 (t != NULL) * sizeof(atomic_uint));
+    if (!cdf->ref) return -ENOMEM;
     cdf->cdf = cdf->ref->data;
     if (t) {
         cdf->progress = (atomic_uint *) &cdf->cdf[1];
@@ -4222,6 +4225,7 @@
         atomic_init(cdf->progress, 0);
         cdf->t = t;
     }
+    return 0;
 }
 
 void dav1d_cdf_thread_ref(CdfThreadContext *const dst,
--- a/src/cdf.h
+++ b/src/cdf.h
@@ -131,11 +131,11 @@
     atomic_uint *progress;
 } CdfThreadContext;
 
-void dav1d_init_states(CdfThreadContext *cdf, int qidx);
+int dav1d_init_states(CdfThreadContext *cdf, int qidx);
 void dav1d_update_tile_cdf(const Dav1dFrameHeader *hdr, CdfContext *dst,
                          const CdfContext *src);
 
-void dav1d_cdf_thread_alloc(CdfThreadContext *cdf, struct thread_data *t);
+int dav1d_cdf_thread_alloc(CdfThreadContext *cdf, struct thread_data *t);
 void dav1d_cdf_thread_ref(CdfThreadContext *dst, CdfThreadContext *src);
 void dav1d_cdf_thread_unref(CdfThreadContext *cdf);
 
--- a/src/decode.c
+++ b/src/decode.c
@@ -3103,13 +3103,15 @@
 
     // setup entropy
     if (f->frame_hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
-        dav1d_init_states(&f->in_cdf, f->frame_hdr->quant.yac);
+        res = dav1d_init_states(&f->in_cdf, f->frame_hdr->quant.yac);
+        if (res < 0) goto error;
     } else {
         const int pri_ref = f->frame_hdr->refidx[f->frame_hdr->primary_ref_frame];
         dav1d_cdf_thread_ref(&f->in_cdf, &c->cdf[pri_ref]);
     }
     if (f->frame_hdr->refresh_context) {
-        dav1d_cdf_thread_alloc(&f->out_cdf, c->n_fc > 1 ? &f->frame_thread.td : NULL);
+        res = dav1d_cdf_thread_alloc(&f->out_cdf, c->n_fc > 1 ? &f->frame_thread.td : NULL);
+        if (res < 0) goto error;
     }
 
     // FIXME qsort so tiles are in order (for frame threading)