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)