ref: 03d4ede0656490a384e2a2ffe10b16c5aabdc8ec
parent: c371907ffea1cafa9ee5867df4127a53b836d68f
author: Ronald S. Bultje <rsbultje@gmail.com>
date: Sun Nov 18 11:47:46 EST 2018
Make frame_hdr a referenced object
--- a/src/decode.c
+++ b/src/decode.c
@@ -2948,6 +2948,7 @@
dav1d_ref_dec(&f->prev_segmap_ref);
dav1d_ref_dec(&f->mvs_ref);
dav1d_ref_dec(&f->seq_hdr_ref);
+ dav1d_ref_dec(&f->frame_hdr_ref);
for (int i = 0; i < f->n_tile_data; i++)
dav1d_data_unref(&f->tile[i].data);
@@ -2990,7 +2991,10 @@
f->seq_hdr = c->seq_hdr;
f->seq_hdr_ref = c->seq_hdr_ref;
dav1d_ref_inc(f->seq_hdr_ref);
- *f->frame_hdr = *c->frame_hdr;
+ f->frame_hdr = c->frame_hdr;
+ f->frame_hdr_ref = c->frame_hdr_ref;
+ c->frame_hdr = NULL;
+ c->frame_hdr_ref = NULL;
const int bd_idx = (f->seq_hdr->bpc - 8) >> 1;
f->dsp = &c->dsp[bd_idx];
@@ -3309,6 +3313,7 @@
dav1d_thread_picture_unref(&f->sr_cur);
dav1d_ref_dec(&f->mvs_ref);
dav1d_ref_dec(&f->seq_hdr_ref);
+ dav1d_ref_dec(&f->frame_hdr_ref);
for (int i = 0; i < f->n_tile_data; i++)
dav1d_data_unref(&f->tile[i].data);
--- a/src/internal.h
+++ b/src/internal.h
@@ -75,11 +75,12 @@
Dav1dData data;
int start, end;
} tile[256];
- int n_tile_data, have_frame_hdr;
+ int n_tile_data;
int n_tiles;
Dav1dRef *seq_hdr_ref;
Av1SequenceHeader *seq_hdr;
- Av1FrameHeader *frame_hdr, frame_hdr_mem; // FIXME make ref?
+ Dav1dRef *frame_hdr_ref;
+ Av1FrameHeader *frame_hdr;
// decoded output picture queue
Dav1dData in;
@@ -125,7 +126,8 @@
struct Dav1dFrameContext {
Dav1dRef *seq_hdr_ref;
Av1SequenceHeader *seq_hdr;
- Av1FrameHeader *frame_hdr, frame_hdr_mem;
+ Dav1dRef *frame_hdr_ref;
+ Av1FrameHeader *frame_hdr;
Dav1dThreadPicture refp[7];
Dav1dPicture cur; // during block coding / reconstruction
Dav1dThreadPicture sr_cur; // after super-resolution upscaling
--- a/src/lib.c
+++ b/src/lib.c
@@ -89,7 +89,6 @@
if (!c) goto error;
memset(c, 0, sizeof(*c));
- c->frame_hdr = &c->frame_hdr_mem;
c->allocator = s->allocator;
c->apply_grain = s->apply_grain;
c->operating_point = s->operating_point;
@@ -108,7 +107,6 @@
for (int n = 0; n < s->n_frame_threads; n++) {
Dav1dFrameContext *const f = &c->fc[n];
f->c = c;
- f->frame_hdr = &f->frame_hdr_mem;
f->lf.last_sharpness = -1;
f->n_tc = s->n_tile_threads;
f->tc = dav1d_alloc_aligned(sizeof(*f->tc) * s->n_tile_threads, 32);
--- a/src/obu.c
+++ b/src/obu.c
@@ -1207,7 +1207,7 @@
if (!ref) return -ENOMEM;
Av1SequenceHeader *seq_hdr = ref->data;
memset(seq_hdr, 0, sizeof(*seq_hdr));
- c->have_frame_hdr = 0;
+ c->frame_hdr = NULL;
if ((res = parse_seq_hdr(c, &gb, seq_hdr)) < 0) {
dav1d_ref_dec(&ref);
return res;
@@ -1235,16 +1235,22 @@
break;
}
case OBU_REDUNDANT_FRAME_HDR:
- if (c->have_frame_hdr) break;
+ if (c->frame_hdr) break;
// fall-through
case OBU_FRAME:
case OBU_FRAME_HDR:
- c->have_frame_hdr = 0;
if (!c->seq_hdr) goto error;
+ if (!c->frame_hdr_ref) {
+ c->frame_hdr_ref = dav1d_ref_create(sizeof(Av1FrameHeader));
+ if (!c->frame_hdr_ref) return -ENOMEM;
+ }
+ c->frame_hdr = c->frame_hdr_ref->data;
c->frame_hdr->temporal_id = temporal_id;
c->frame_hdr->spatial_id = spatial_id;
- if ((res = parse_frame_hdr(c, &gb)) < 0)
+ if ((res = parse_frame_hdr(c, &gb)) < 0) {
+ c->frame_hdr = NULL;
return res;
+ }
for (int n = 0; n < c->n_tile_data; n++)
dav1d_data_unref(&c->tile[n].data);
c->n_tile_data = 0;
@@ -1253,17 +1259,19 @@
// This is actually a frame header OBU so read the
// trailing bit and check for overrun.
dav1d_get_bits(&gb, 1);
- if (check_for_overrun(&gb, init_bit_pos, len))
+ if (check_for_overrun(&gb, init_bit_pos, len)) {
+ c->frame_hdr = NULL;
return -EINVAL;
+ }
- c->have_frame_hdr = 1;
break;
}
// OBU_FRAMEs shouldn't be signalled with show_existing_frame
- if (c->frame_hdr->show_existing_frame) goto error;
+ if (c->frame_hdr->show_existing_frame) {
+ c->frame_hdr = NULL;
+ goto error;
+ }
- c->have_frame_hdr = 1;
-
// This is the frame header at the start of a frame OBU.
// There's no trailing bit at the end to skip, but we do need
// to align to the next byte.
@@ -1270,7 +1278,7 @@
dav1d_bytealign_get_bits(&gb);
// fall-through
case OBU_TILE_GRP: {
- if (!c->have_frame_hdr) goto error;
+ if (!c->frame_hdr) goto error;
if (c->n_tile_data >= 256) goto error;
parse_tile_hdr(c, &gb);
// Align to the next byte boundary and check for overrun.
@@ -1313,75 +1321,73 @@
return -EINVAL;
}
- if (c->seq_hdr && c->have_frame_hdr &&
- c->n_tiles == c->frame_hdr->tiling.cols * c->frame_hdr->tiling.rows)
- {
- if (!c->n_tile_data)
- return -EINVAL;
- if ((res = dav1d_submit_frame(c)) < 0)
- return res;
- assert(!c->n_tile_data);
- c->have_frame_hdr = 0;
- c->n_tiles = 0;
- } else if (c->seq_hdr && c->have_frame_hdr &&
- c->frame_hdr->show_existing_frame)
- {
- if (c->n_fc == 1) {
- dav1d_picture_ref(&c->out,
- &c->refs[c->frame_hdr->existing_frame_idx].p.p);
- c->out.m = in->m;
- } else {
- // need to append this to the frame output queue
- const unsigned next = c->frame_thread.next++;
- if (c->frame_thread.next == c->n_fc)
- c->frame_thread.next = 0;
+ if (c->seq_hdr && c->frame_hdr) {
+ if (c->frame_hdr->show_existing_frame) {
+ if (c->n_fc == 1) {
+ dav1d_picture_ref(&c->out,
+ &c->refs[c->frame_hdr->existing_frame_idx].p.p);
+ c->out.m = in->m;
+ } else {
+ // need to append this to the frame output queue
+ const unsigned next = c->frame_thread.next++;
+ if (c->frame_thread.next == c->n_fc)
+ c->frame_thread.next = 0;
- Dav1dFrameContext *const f = &c->fc[next];
- pthread_mutex_lock(&f->frame_thread.td.lock);
- while (f->n_tile_data > 0)
- pthread_cond_wait(&f->frame_thread.td.cond,
- &f->frame_thread.td.lock);
- Dav1dThreadPicture *const out_delayed =
- &c->frame_thread.out_delayed[next];
- if (out_delayed->p.data[0]) {
- const unsigned progress = atomic_load_explicit(&out_delayed->progress[1],
- memory_order_relaxed);
- if (out_delayed->visible && progress != FRAME_ERROR)
- dav1d_picture_ref(&c->out, &out_delayed->p);
- dav1d_thread_picture_unref(out_delayed);
+ Dav1dFrameContext *const f = &c->fc[next];
+ pthread_mutex_lock(&f->frame_thread.td.lock);
+ while (f->n_tile_data > 0)
+ pthread_cond_wait(&f->frame_thread.td.cond,
+ &f->frame_thread.td.lock);
+ Dav1dThreadPicture *const out_delayed =
+ &c->frame_thread.out_delayed[next];
+ if (out_delayed->p.data[0]) {
+ const unsigned progress = atomic_load_explicit(&out_delayed->progress[1],
+ memory_order_relaxed);
+ if (out_delayed->visible && progress != FRAME_ERROR)
+ dav1d_picture_ref(&c->out, &out_delayed->p);
+ dav1d_thread_picture_unref(out_delayed);
+ }
+ dav1d_thread_picture_ref(out_delayed,
+ &c->refs[c->frame_hdr->existing_frame_idx].p);
+ out_delayed->visible = 1;
+ out_delayed->p.m = in->m;
+ pthread_mutex_unlock(&f->frame_thread.td.lock);
}
- dav1d_thread_picture_ref(out_delayed,
- &c->refs[c->frame_hdr->existing_frame_idx].p);
- out_delayed->visible = 1;
- out_delayed->p.m = in->m;
- pthread_mutex_unlock(&f->frame_thread.td.lock);
- }
- c->have_frame_hdr = 0;
- if (c->refs[c->frame_hdr->existing_frame_idx].p.p.p.type == DAV1D_FRAME_TYPE_KEY) {
- const int r = c->frame_hdr->existing_frame_idx;
- for (int i = 0; i < 8; i++) {
- if (i == c->frame_hdr->existing_frame_idx) continue;
+ if (c->refs[c->frame_hdr->existing_frame_idx].p.p.p.type == DAV1D_FRAME_TYPE_KEY) {
+ const int r = c->frame_hdr->existing_frame_idx;
+ for (int i = 0; i < 8; i++) {
+ if (i == c->frame_hdr->existing_frame_idx) continue;
- if (c->refs[i].p.p.data[0])
- dav1d_thread_picture_unref(&c->refs[i].p);
- dav1d_thread_picture_ref(&c->refs[i].p, &c->refs[r].p);
+ if (c->refs[i].p.p.data[0])
+ dav1d_thread_picture_unref(&c->refs[i].p);
+ dav1d_thread_picture_ref(&c->refs[i].p, &c->refs[r].p);
- if (c->cdf[i].cdf) dav1d_cdf_thread_unref(&c->cdf[i]);
- dav1d_init_states(&c->cdf[i], c->refs[r].qidx);
+ if (c->cdf[i].cdf) dav1d_cdf_thread_unref(&c->cdf[i]);
+ dav1d_init_states(&c->cdf[i], c->refs[r].qidx);
- c->refs[i].lf_mode_ref_deltas = c->refs[r].lf_mode_ref_deltas;
- c->refs[i].seg_data = c->refs[r].seg_data;
- for (int j = 0; j < 7; j++)
- c->refs[i].gmv[j] = dav1d_default_wm_params;
- c->refs[i].film_grain = c->refs[r].film_grain;
+ c->refs[i].lf_mode_ref_deltas = c->refs[r].lf_mode_ref_deltas;
+ c->refs[i].seg_data = c->refs[r].seg_data;
+ for (int j = 0; j < 7; j++)
+ c->refs[i].gmv[j] = dav1d_default_wm_params;
+ c->refs[i].film_grain = c->refs[r].film_grain;
- dav1d_ref_dec(&c->refs[i].segmap);
- c->refs[i].segmap = c->refs[r].segmap;
- if (c->refs[r].segmap)
- dav1d_ref_inc(c->refs[r].segmap);
- dav1d_ref_dec(&c->refs[i].refmvs);
- c->refs[i].qidx = c->refs[r].qidx;
+ dav1d_ref_dec(&c->refs[i].segmap);
+ c->refs[i].segmap = c->refs[r].segmap;
+ if (c->refs[r].segmap)
+ dav1d_ref_inc(c->refs[r].segmap);
+ dav1d_ref_dec(&c->refs[i].refmvs);
+ c->refs[i].qidx = c->refs[r].qidx;
+ }
}
+ c->frame_hdr = NULL;
+ } else if (c->n_tiles == c->frame_hdr->tiling.cols * c->frame_hdr->tiling.rows) {
+ if (!c->n_tile_data)
+ return -EINVAL;
+ if ((res = dav1d_submit_frame(c)) < 0)
+ return res;
+ assert(!c->n_tile_data);
+ c->frame_hdr = NULL;
+ c->n_tiles = 0;
}
}