Commit 03d4ede0 authored by Ronald S. Bultje's avatar Ronald S. Bultje

Make frame_hdr a referenced object

parent c371907f
...@@ -2948,6 +2948,7 @@ error: ...@@ -2948,6 +2948,7 @@ error:
dav1d_ref_dec(&f->prev_segmap_ref); dav1d_ref_dec(&f->prev_segmap_ref);
dav1d_ref_dec(&f->mvs_ref); dav1d_ref_dec(&f->mvs_ref);
dav1d_ref_dec(&f->seq_hdr_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++) for (int i = 0; i < f->n_tile_data; i++)
dav1d_data_unref(&f->tile[i].data); dav1d_data_unref(&f->tile[i].data);
...@@ -2990,7 +2991,10 @@ int dav1d_submit_frame(Dav1dContext *const c) { ...@@ -2990,7 +2991,10 @@ int dav1d_submit_frame(Dav1dContext *const c) {
f->seq_hdr = c->seq_hdr; f->seq_hdr = c->seq_hdr;
f->seq_hdr_ref = c->seq_hdr_ref; f->seq_hdr_ref = c->seq_hdr_ref;
dav1d_ref_inc(f->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; const int bd_idx = (f->seq_hdr->bpc - 8) >> 1;
f->dsp = &c->dsp[bd_idx]; f->dsp = &c->dsp[bd_idx];
...@@ -3309,6 +3313,7 @@ error: ...@@ -3309,6 +3313,7 @@ error:
dav1d_thread_picture_unref(&f->sr_cur); dav1d_thread_picture_unref(&f->sr_cur);
dav1d_ref_dec(&f->mvs_ref); dav1d_ref_dec(&f->mvs_ref);
dav1d_ref_dec(&f->seq_hdr_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++) for (int i = 0; i < f->n_tile_data; i++)
dav1d_data_unref(&f->tile[i].data); dav1d_data_unref(&f->tile[i].data);
......
...@@ -75,11 +75,12 @@ struct Dav1dContext { ...@@ -75,11 +75,12 @@ struct Dav1dContext {
Dav1dData data; Dav1dData data;
int start, end; int start, end;
} tile[256]; } tile[256];
int n_tile_data, have_frame_hdr; int n_tile_data;
int n_tiles; int n_tiles;
Dav1dRef *seq_hdr_ref; Dav1dRef *seq_hdr_ref;
Av1SequenceHeader *seq_hdr; Av1SequenceHeader *seq_hdr;
Av1FrameHeader *frame_hdr, frame_hdr_mem; // FIXME make ref? Dav1dRef *frame_hdr_ref;
Av1FrameHeader *frame_hdr;
// decoded output picture queue // decoded output picture queue
Dav1dData in; Dav1dData in;
...@@ -125,7 +126,8 @@ struct Dav1dContext { ...@@ -125,7 +126,8 @@ struct Dav1dContext {
struct Dav1dFrameContext { struct Dav1dFrameContext {
Dav1dRef *seq_hdr_ref; Dav1dRef *seq_hdr_ref;
Av1SequenceHeader *seq_hdr; Av1SequenceHeader *seq_hdr;
Av1FrameHeader *frame_hdr, frame_hdr_mem; Dav1dRef *frame_hdr_ref;
Av1FrameHeader *frame_hdr;
Dav1dThreadPicture refp[7]; Dav1dThreadPicture refp[7];
Dav1dPicture cur; // during block coding / reconstruction Dav1dPicture cur; // during block coding / reconstruction
Dav1dThreadPicture sr_cur; // after super-resolution upscaling Dav1dThreadPicture sr_cur; // after super-resolution upscaling
......
...@@ -89,7 +89,6 @@ int dav1d_open(Dav1dContext **const c_out, ...@@ -89,7 +89,6 @@ int dav1d_open(Dav1dContext **const c_out,
if (!c) goto error; if (!c) goto error;
memset(c, 0, sizeof(*c)); memset(c, 0, sizeof(*c));
c->frame_hdr = &c->frame_hdr_mem;
c->allocator = s->allocator; c->allocator = s->allocator;
c->apply_grain = s->apply_grain; c->apply_grain = s->apply_grain;
c->operating_point = s->operating_point; c->operating_point = s->operating_point;
...@@ -108,7 +107,6 @@ int dav1d_open(Dav1dContext **const c_out, ...@@ -108,7 +107,6 @@ int dav1d_open(Dav1dContext **const c_out,
for (int n = 0; n < s->n_frame_threads; n++) { for (int n = 0; n < s->n_frame_threads; n++) {
Dav1dFrameContext *const f = &c->fc[n]; Dav1dFrameContext *const f = &c->fc[n];
f->c = c; f->c = c;
f->frame_hdr = &f->frame_hdr_mem;
f->lf.last_sharpness = -1; f->lf.last_sharpness = -1;
f->n_tc = s->n_tile_threads; f->n_tc = s->n_tile_threads;
f->tc = dav1d_alloc_aligned(sizeof(*f->tc) * s->n_tile_threads, 32); f->tc = dav1d_alloc_aligned(sizeof(*f->tc) * s->n_tile_threads, 32);
......
...@@ -1207,7 +1207,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) { ...@@ -1207,7 +1207,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
if (!ref) return -ENOMEM; if (!ref) return -ENOMEM;
Av1SequenceHeader *seq_hdr = ref->data; Av1SequenceHeader *seq_hdr = ref->data;
memset(seq_hdr, 0, sizeof(*seq_hdr)); 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) { if ((res = parse_seq_hdr(c, &gb, seq_hdr)) < 0) {
dav1d_ref_dec(&ref); dav1d_ref_dec(&ref);
return res; return res;
...@@ -1235,16 +1235,22 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) { ...@@ -1235,16 +1235,22 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
break; break;
} }
case OBU_REDUNDANT_FRAME_HDR: case OBU_REDUNDANT_FRAME_HDR:
if (c->have_frame_hdr) break; if (c->frame_hdr) break;
// fall-through // fall-through
case OBU_FRAME: case OBU_FRAME:
case OBU_FRAME_HDR: case OBU_FRAME_HDR:
c->have_frame_hdr = 0;
if (!c->seq_hdr) goto error; 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->temporal_id = temporal_id;
c->frame_hdr->spatial_id = spatial_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; return res;
}
for (int n = 0; n < c->n_tile_data; n++) for (int n = 0; n < c->n_tile_data; n++)
dav1d_data_unref(&c->tile[n].data); dav1d_data_unref(&c->tile[n].data);
c->n_tile_data = 0; c->n_tile_data = 0;
...@@ -1253,16 +1259,18 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) { ...@@ -1253,16 +1259,18 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
// This is actually a frame header OBU so read the // This is actually a frame header OBU so read the
// trailing bit and check for overrun. // trailing bit and check for overrun.
dav1d_get_bits(&gb, 1); 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; return -EINVAL;
}
c->have_frame_hdr = 1;
break; break;
} }
// OBU_FRAMEs shouldn't be signalled with show_existing_frame // 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;
c->have_frame_hdr = 1; goto error;
}
// This is the frame header at the start of a frame OBU. // 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 // There's no trailing bit at the end to skip, but we do need
...@@ -1270,7 +1278,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) { ...@@ -1270,7 +1278,7 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
dav1d_bytealign_get_bits(&gb); dav1d_bytealign_get_bits(&gb);
// fall-through // fall-through
case OBU_TILE_GRP: { 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; if (c->n_tile_data >= 256) goto error;
parse_tile_hdr(c, &gb); parse_tile_hdr(c, &gb);
// Align to the next byte boundary and check for overrun. // Align to the next byte boundary and check for overrun.
...@@ -1313,75 +1321,73 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) { ...@@ -1313,75 +1321,73 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
return -EINVAL; return -EINVAL;
} }
if (c->seq_hdr && c->have_frame_hdr && if (c->seq_hdr && c->frame_hdr) {
c->n_tiles == c->frame_hdr->tiling.cols * c->frame_hdr->tiling.rows) if (c->frame_hdr->show_existing_frame) {
{ if (c->n_fc == 1) {
if (!c->n_tile_data) dav1d_picture_ref(&c->out,
return -EINVAL; &c->refs[c->frame_hdr->existing_frame_idx].p.p);
if ((res = dav1d_submit_frame(c)) < 0) c->out.m = in->m;
return res; } else {
assert(!c->n_tile_data); // need to append this to the frame output queue
c->have_frame_hdr = 0; const unsigned next = c->frame_thread.next++;
c->n_tiles = 0; if (c->frame_thread.next == c->n_fc)
} else if (c->seq_hdr && c->have_frame_hdr && c->frame_thread.next = 0;
c->frame_hdr->show_existing_frame)
{ Dav1dFrameContext *const f = &c->fc[next];
if (c->n_fc == 1) { pthread_mutex_lock(&f->frame_thread.td.lock);
dav1d_picture_ref(&c->out, while (f->n_tile_data > 0)
&c->refs[c->frame_hdr->existing_frame_idx].p.p); pthread_cond_wait(&f->frame_thread.td.cond,
c->out.m = in->m; &f->frame_thread.td.lock);
} else { Dav1dThreadPicture *const out_delayed =
// need to append this to the frame output queue &c->frame_thread.out_delayed[next];
const unsigned next = c->frame_thread.next++; if (out_delayed->p.data[0]) {
if (c->frame_thread.next == c->n_fc) const unsigned progress = atomic_load_explicit(&out_delayed->progress[1],
c->frame_thread.next = 0; memory_order_relaxed);
if (out_delayed->visible && progress != FRAME_ERROR)
Dav1dFrameContext *const f = &c->fc[next]; dav1d_picture_ref(&c->out, &out_delayed->p);
pthread_mutex_lock(&f->frame_thread.td.lock); dav1d_thread_picture_unref(out_delayed);
while (f->n_tile_data > 0) }
pthread_cond_wait(&f->frame_thread.td.cond, dav1d_thread_picture_ref(out_delayed,
&f->frame_thread.td.lock); &c->refs[c->frame_hdr->existing_frame_idx].p);
Dav1dThreadPicture *const out_delayed = out_delayed->visible = 1;
&c->frame_thread.out_delayed[next]; out_delayed->p.m = in->m;
if (out_delayed->p.data[0]) { pthread_mutex_unlock(&f->frame_thread.td.lock);
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, if (c->refs[c->frame_hdr->existing_frame_idx].p.p.p.type == DAV1D_FRAME_TYPE_KEY) {
&c->refs[c->frame_hdr->existing_frame_idx].p); const int r = c->frame_hdr->existing_frame_idx;
out_delayed->visible = 1; for (int i = 0; i < 8; i++) {
out_delayed->p.m = in->m; if (i == c->frame_hdr->existing_frame_idx) continue;
pthread_mutex_unlock(&f->frame_thread.td.lock);
} if (c->refs[i].p.p.data[0])
c->have_frame_hdr = 0; dav1d_thread_picture_unref(&c->refs[i].p);
if (c->refs[c->frame_hdr->existing_frame_idx].p.p.p.type == DAV1D_FRAME_TYPE_KEY) { dav1d_thread_picture_ref(&c->refs[i].p, &c->refs[r].p);
const int r = c->frame_hdr->existing_frame_idx;
for (int i = 0; i < 8; i++) { if (c->cdf[i].cdf) dav1d_cdf_thread_unref(&c->cdf[i]);
if (i == c->frame_hdr->existing_frame_idx) continue; dav1d_init_states(&c->cdf[i], c->refs[r].qidx);
if (c->refs[i].p.p.data[0]) c->refs[i].lf_mode_ref_deltas = c->refs[r].lf_mode_ref_deltas;
dav1d_thread_picture_unref(&c->refs[i].p); c->refs[i].seg_data = c->refs[r].seg_data;
dav1d_thread_picture_ref(&c->refs[i].p, &c->refs[r].p); for (int j = 0; j < 7; j++)
c->refs[i].gmv[j] = dav1d_default_wm_params;
if (c->cdf[i].cdf) dav1d_cdf_thread_unref(&c->cdf[i]); c->refs[i].film_grain = c->refs[r].film_grain;
dav1d_init_states(&c->cdf[i], c->refs[r].qidx);
dav1d_ref_dec(&c->refs[i].segmap);
c->refs[i].lf_mode_ref_deltas = c->refs[r].lf_mode_ref_deltas; c->refs[i].segmap = c->refs[r].segmap;
c->refs[i].seg_data = c->refs[r].seg_data; if (c->refs[r].segmap)
for (int j = 0; j < 7; j++) dav1d_ref_inc(c->refs[r].segmap);
c->refs[i].gmv[j] = dav1d_default_wm_params; dav1d_ref_dec(&c->refs[i].refmvs);
c->refs[i].film_grain = c->refs[r].film_grain; 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;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment