ref: b6bb8536ad299d52a5ff49a4f0317b923ce6b8bb
parent: 3e95d8ed717082430db632d290309f4f7326e7fe
author: Ronald S. Bultje <rsbultje@gmail.com>
date: Sat Nov 24 06:23:01 EST 2018
Store literal bitstream values in Dav1dSequence/FrameHeader This means storing monochrome, ss_hor/ver and hbd. The derived values bpc and layout are then stored in Dav1dPictureParameters.
--- a/include/dav1d/headers.h
+++ b/include/dav1d/headers.h
@@ -173,8 +173,6 @@
* a normative requirement.
*/
int max_width, max_height;
- int bpc; ///< bits per pixel component (8 or 10)
- enum Dav1dPixelLayout layout; ///< format of the picture
enum Dav1dColorPrimaries pri; ///< color primaries (av1)
enum Dav1dTransferCharacteristics trc; ///< transfer characteristics (av1)
enum Dav1dMatrixCoefficients mtrx; ///< matrix coefficients (av1)
@@ -231,7 +229,15 @@
int super_res;
int cdef;
int restoration;
+ /**
+ * 0, 1 and 2 mean 8, 10 or 12 bits/component, respectively. This is not
+ * exactly the same as 'hbd' from the spec; the spec's hbd distinguishes
+ * between 8 (0) and 10-12 (1) bits/component, and another element
+ * (twelve_bit) to distinguish between 10 and 12 bits/component. To get
+ * the spec's hbd, use !!our_hbd, and to get twelve_bit, use hbd == 2.
+ */
int hbd;
+ int ss_hor, ss_ver, monochrome;
int color_description_present;
int separate_uv_delta_q;
int film_grain_present;
--- a/include/dav1d/picture.h
+++ b/include/dav1d/picture.h
@@ -42,7 +42,6 @@
} Dav1dPictureParameters;
typedef struct Dav1dPicture {
- struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref;
Dav1dSequenceHeader *seq_hdr;
Dav1dFrameHeader *frame_hdr;
@@ -54,7 +53,6 @@
* zero'ed out.
*/
void *data[3];
- struct Dav1dRef *ref; ///< allocation origin
/**
* Number of bytes between 2 lines in data[] for luma [0] or chroma [1].
@@ -63,6 +61,7 @@
Dav1dPictureParameters p;
Dav1dDataProps m;
+ struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref, *ref; ///< allocation origins
void *allocator_data; ///< pointer managed by the allocator
} Dav1dPicture;
--- a/src/decode.c
+++ b/src/decode.c
@@ -62,12 +62,12 @@
const int vac = iclip_u8(yac + frame_hdr->quant.vac_delta);
const int vdc = iclip_u8(yac + frame_hdr->quant.vdc_delta);
- dq[i][0][0] = dav1d_dq_tbl[seq_hdr->bpc > 8][ydc][0];
- dq[i][0][1] = dav1d_dq_tbl[seq_hdr->bpc > 8][yac][1];
- dq[i][1][0] = dav1d_dq_tbl[seq_hdr->bpc > 8][udc][0];
- dq[i][1][1] = dav1d_dq_tbl[seq_hdr->bpc > 8][uac][1];
- dq[i][2][0] = dav1d_dq_tbl[seq_hdr->bpc > 8][vdc][0];
- dq[i][2][1] = dav1d_dq_tbl[seq_hdr->bpc > 8][vac][1];
+ dq[i][0][0] = dav1d_dq_tbl[seq_hdr->hbd][ydc][0];
+ dq[i][0][1] = dav1d_dq_tbl[seq_hdr->hbd][yac][1];
+ dq[i][1][0] = dav1d_dq_tbl[seq_hdr->hbd][udc][0];
+ dq[i][1][1] = dav1d_dq_tbl[seq_hdr->hbd][uac][1];
+ dq[i][2][0] = dav1d_dq_tbl[seq_hdr->hbd][vdc][0];
+ dq[i][2][1] = dav1d_dq_tbl[seq_hdr->hbd][vac][1];
}
}
@@ -702,7 +702,7 @@
const int cbw4 = (bw4 + ss_hor) >> ss_hor, cbh4 = (bh4 + ss_ver) >> ss_ver;
const int have_left = t->bx > ts->tiling.col_start;
const int have_top = t->by > ts->tiling.row_start;
- const int has_chroma = f->seq_hdr->layout != DAV1D_PIXEL_LAYOUT_I400 &&
+ const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 &&
(bw4 > ss_hor || t->bx & 1) &&
(bh4 > ss_ver || t->by & 1);
@@ -937,7 +937,7 @@
if (f->frame_hdr->delta.lf.present) {
const int n_lfs = f->frame_hdr->delta.lf.multi ?
- f->seq_hdr->layout != DAV1D_PIXEL_LAYOUT_I400 ? 4 : 2 : 1;
+ f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 ? 4 : 2 : 1;
for (int i = 0; i < n_lfs; i++) {
int delta_lf =
@@ -3000,13 +3000,18 @@
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];
+ f->dsp = &c->dsp[f->seq_hdr->hbd];
+ const int bpc = 8 + 2 * f->seq_hdr->hbd;
+ const enum Dav1dPixelLayout layout =
+ f->seq_hdr->monochrome ? DAV1D_PIXEL_LAYOUT_I400 :
+ !f->seq_hdr->ss_hor ? DAV1D_PIXEL_LAYOUT_I444 :
+ f->seq_hdr->ss_ver ? DAV1D_PIXEL_LAYOUT_I420 : DAV1D_PIXEL_LAYOUT_I422;
+
if (!f->dsp->ipred.intra_pred[DC_PRED]) {
- Dav1dDSPContext *const dsp = &c->dsp[bd_idx];
+ Dav1dDSPContext *const dsp = &c->dsp[f->seq_hdr->hbd];
- switch (f->seq_hdr->bpc) {
+ switch (bpc) {
#define assign_bitdepth_case(bd) \
case bd: \
dav1d_cdef_dsp_init_##bd##bpc(&dsp->cdef); \
@@ -3025,7 +3030,7 @@
#undef assign_bitdepth_case
default:
fprintf(stderr, "Compiled without support for %d-bit decoding\n",
- f->seq_hdr->bpc);
+ 8 + 2 * f->seq_hdr->hbd);
res = -ENOPROTOOPT;
goto error;
}
@@ -3037,7 +3042,7 @@
f->bd_fn.filter_sbrow = dav1d_filter_sbrow_##bd##bpc; \
f->bd_fn.backup_ipred_edge = dav1d_backup_ipred_edge_##bd##bpc; \
f->bd_fn.read_coef_blocks = dav1d_read_coef_blocks_##bd##bpc
- if (f->seq_hdr->bpc <= 8) {
+ if (!f->seq_hdr->hbd) {
#if CONFIG_8BPC
assign_bitdepth_case(8);
#endif
@@ -3064,8 +3069,8 @@
f->frame_hdr->height * 2 < c->refs[refidx].p.p.p.h ||
f->frame_hdr->width[0] > c->refs[refidx].p.p.p.w * 16 ||
f->frame_hdr->height > c->refs[refidx].p.p.p.h * 16 ||
- f->seq_hdr->layout != c->refs[refidx].p.p.p.layout ||
- f->seq_hdr->bpc != c->refs[refidx].p.p.p.bpc)
+ layout != c->refs[refidx].p.p.p.layout ||
+ bpc != c->refs[refidx].p.p.p.bpc)
{
for (int j = 0; j < i; j++)
dav1d_thread_picture_unref(&f->refp[j]);
@@ -3113,8 +3118,7 @@
// allocate frame
res = dav1d_thread_picture_alloc(&f->sr_cur, f->frame_hdr->width[1],
- f->frame_hdr->height,
- f->seq_hdr->layout, f->seq_hdr->bpc,
+ f->frame_hdr->height, layout, bpc,
c->n_fc > 1 ? &f->frame_thread.td : NULL,
f->frame_hdr->show_frame, &c->allocator);
if (res < 0) goto error;
--- a/src/obu.c
+++ b/src/obu.c
@@ -201,10 +201,9 @@
dav1d_get_bits_pos(gb) - init_bit_pos);
#endif
- const int hbd = dav1d_get_bits(gb, 1);
- hdr->bpc = hdr->profile == 2 && hbd ? 10U + 2 * dav1d_get_bits(gb, 1) : 8U + 2 * hbd;
- hdr->hbd = hdr->bpc > 8;
- const int monochrome = hdr->profile != 1 ? dav1d_get_bits(gb, 1) : 0;
+ hdr->hbd = dav1d_get_bits(gb, 1);
+ if (hdr->profile == 2 && hdr->hbd) hdr->hbd += dav1d_get_bits(gb, 1);
+ hdr->monochrome = hdr->profile != 1 ? dav1d_get_bits(gb, 1) : 0;
hdr->color_description_present = dav1d_get_bits(gb, 1);
if (hdr->color_description_present) {
hdr->pri = dav1d_get_bits(gb, 8);
@@ -215,9 +214,9 @@
hdr->trc = DAV1D_TRC_UNKNOWN;
hdr->mtrx = DAV1D_MC_UNKNOWN;
}
- if (monochrome) {
+ if (hdr->monochrome) {
hdr->color_range = dav1d_get_bits(gb, 1);
- hdr->layout = DAV1D_PIXEL_LAYOUT_I400;
+ hdr->ss_hor = hdr->ss_ver = 0;
hdr->chr = DAV1D_CHR_UNKNOWN;
hdr->separate_uv_delta_q = 0;
} else if (hdr->pri == DAV1D_COLOR_PRI_BT709 &&
@@ -224,27 +223,27 @@
hdr->trc == DAV1D_TRC_SRGB &&
hdr->mtrx == DAV1D_MC_IDENTITY)
{
- hdr->layout = DAV1D_PIXEL_LAYOUT_I444;
+ hdr->ss_hor = hdr->ss_ver = 1;
hdr->color_range = 1;
- if (hdr->profile != 1 && !(hdr->profile == 2 && hdr->bpc == 12))
+ if (hdr->profile != 1 && !(hdr->profile == 2 && hdr->hbd == 2))
goto error;
} else {
hdr->color_range = dav1d_get_bits(gb, 1);
switch (hdr->profile) {
- case 0: hdr->layout = DAV1D_PIXEL_LAYOUT_I420; break;
- case 1: hdr->layout = DAV1D_PIXEL_LAYOUT_I444; break;
+ case 0: hdr->ss_hor = hdr->ss_ver = 1; break;
+ case 1: hdr->ss_hor = hdr->ss_ver = 0; break;
case 2:
- if (hdr->bpc == 12) {
- hdr->layout = dav1d_get_bits(gb, 1) ?
- dav1d_get_bits(gb, 1) ? DAV1D_PIXEL_LAYOUT_I420 :
- DAV1D_PIXEL_LAYOUT_I422 :
- DAV1D_PIXEL_LAYOUT_I444;
- } else
- hdr->layout = DAV1D_PIXEL_LAYOUT_I422;
+ if (hdr->hbd == 2) {
+ hdr->ss_hor = dav1d_get_bits(gb, 1);
+ hdr->ss_ver = hdr->ss_hor && dav1d_get_bits(gb, 1);
+ } else {
+ hdr->ss_hor = 1;
+ hdr->ss_ver = 0;
+ }
break;
}
- if (hdr->layout == DAV1D_PIXEL_LAYOUT_I420)
- hdr->chr = dav1d_get_bits(gb, 2);
+ hdr->chr = hdr->ss_hor == 1 && hdr->ss_ver == 1 ?
+ dav1d_get_bits(gb, 2) : DAV1D_CHR_UNKNOWN;
hdr->separate_uv_delta_q = dav1d_get_bits(gb, 1);
}
#if DEBUG_SEQ_HDR
@@ -635,7 +634,7 @@
// quant data
hdr->quant.yac = dav1d_get_bits(gb, 8);
hdr->quant.ydc_delta = dav1d_get_bits(gb, 1) ? dav1d_get_sbits(gb, 6) : 0;
- if (seqhdr->layout != DAV1D_PIXEL_LAYOUT_I400) {
+ if (!seqhdr->monochrome) {
// If the sequence header says that delta_q might be different
// for U, V, we must check whether it actually is for this
// frame.
@@ -788,7 +787,7 @@
} else {
hdr->loopfilter.level_y[0] = dav1d_get_bits(gb, 6);
hdr->loopfilter.level_y[1] = dav1d_get_bits(gb, 6);
- if (seqhdr->layout != DAV1D_PIXEL_LAYOUT_I400 &&
+ if (!seqhdr->monochrome &&
(hdr->loopfilter.level_y[0] || hdr->loopfilter.level_y[1]))
{
hdr->loopfilter.level_u = dav1d_get_bits(gb, 6);
@@ -830,7 +829,7 @@
hdr->cdef.n_bits = dav1d_get_bits(gb, 2);
for (int i = 0; i < (1 << hdr->cdef.n_bits); i++) {
hdr->cdef.y_strength[i] = dav1d_get_bits(gb, 6);
- if (seqhdr->layout != DAV1D_PIXEL_LAYOUT_I400)
+ if (!seqhdr->monochrome)
hdr->cdef.uv_strength[i] = dav1d_get_bits(gb, 6);
}
} else {
@@ -848,7 +847,7 @@
seqhdr->restoration && !hdr->allow_intrabc)
{
hdr->restoration.type[0] = dav1d_get_bits(gb, 2);
- if (seqhdr->layout != DAV1D_PIXEL_LAYOUT_I400) {
+ if (!seqhdr->monochrome) {
hdr->restoration.type[1] = dav1d_get_bits(gb, 2);
hdr->restoration.type[2] = dav1d_get_bits(gb, 2);
} else {
@@ -868,7 +867,7 @@
}
hdr->restoration.unit_size[1] = hdr->restoration.unit_size[0];
if ((hdr->restoration.type[1] || hdr->restoration.type[2]) &&
- seqhdr->layout == DAV1D_PIXEL_LAYOUT_I420)
+ seqhdr->ss_hor == 1 && seqhdr->ss_ver == 1)
{
hdr->restoration.unit_size[1] -= dav1d_get_bits(gb, 1);
}
@@ -1046,10 +1045,9 @@
}
fgd->chroma_scaling_from_luma =
- seqhdr->layout != DAV1D_PIXEL_LAYOUT_I400 && dav1d_get_bits(gb, 1);
- if (seqhdr->layout == DAV1D_PIXEL_LAYOUT_I400 ||
- fgd->chroma_scaling_from_luma ||
- (seqhdr->layout == DAV1D_PIXEL_LAYOUT_I420 && !fgd->num_y_points))
+ !seqhdr->monochrome && dav1d_get_bits(gb, 1);
+ if (seqhdr->monochrome || fgd->chroma_scaling_from_luma ||
+ (seqhdr->ss_ver == 1 && seqhdr->ss_hor == 1 && !fgd->num_y_points))
{
fgd->num_uv_points[0] = fgd->num_uv_points[1] = 0;
} else for (int pl = 0; pl < 2; pl++) {
@@ -1063,7 +1061,7 @@
}
}
- if (seqhdr->layout == DAV1D_PIXEL_LAYOUT_I420 &&
+ if (seqhdr->ss_hor == 1 && seqhdr->ss_ver == 1 &&
!!fgd->num_uv_points[0] != !!fgd->num_uv_points[1])
{
goto error;
--- a/src/recon_tmpl.c
+++ b/src/recon_tmpl.c
@@ -368,7 +368,7 @@
const uint8_t *const b_dim = dav1d_block_dimensions[bs];
const int bw4 = b_dim[0], bh4 = b_dim[1];
const int cbw4 = (bw4 + ss_hor) >> ss_hor, cbh4 = (bh4 + ss_ver) >> ss_ver;
- const int has_chroma = f->seq_hdr->layout != DAV1D_PIXEL_LAYOUT_I400 &&
+ const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 &&
(bw4 > ss_hor || t->bx & 1) &&
(bh4 > ss_ver || t->by & 1);
@@ -748,7 +748,7 @@
const int bw4 = b_dim[0], bh4 = b_dim[1];
const int w4 = imin(bw4, f->bw - t->bx), h4 = imin(bh4, f->bh - t->by);
const int cw4 = (w4 + ss_hor) >> ss_hor, ch4 = (h4 + ss_ver) >> ss_ver;
- const int has_chroma = f->seq_hdr->layout != DAV1D_PIXEL_LAYOUT_I400 &&
+ const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 &&
(bw4 > ss_hor || t->bx & 1) &&
(bh4 > ss_ver || t->by & 1);
const TxfmInfo *const t_dim = &dav1d_txfm_dimensions[b->tx];
@@ -1139,7 +1139,7 @@
const uint8_t *const b_dim = dav1d_block_dimensions[bs];
const int bw4 = b_dim[0], bh4 = b_dim[1];
const int w4 = imin(bw4, f->bw - t->bx), h4 = imin(bh4, f->bh - t->by);
- const int has_chroma = f->seq_hdr->layout != DAV1D_PIXEL_LAYOUT_I400 &&
+ const int has_chroma = f->cur.p.layout != DAV1D_PIXEL_LAYOUT_I400 &&
(bw4 > ss_hor || t->bx & 1) &&
(bh4 > ss_ver || t->by & 1);
const int chr_layout_idx = f->cur.p.layout == DAV1D_PIXEL_LAYOUT_I400 ? 0 :
--- a/tools/output/y4m2.c
+++ b/tools/output/y4m2.c
@@ -73,9 +73,9 @@
};
const char *const ss_name =
- p->seq_hdr->layout == DAV1D_PIXEL_LAYOUT_I420 && p->seq_hdr->bpc == 8 ?
+ p->p.layout == DAV1D_PIXEL_LAYOUT_I420 && p->p.bpc == 8 ?
chr_names_8bpc_i420[p->seq_hdr->chr > 2 ? DAV1D_CHR_UNKNOWN : p->seq_hdr->chr] :
- ss_names[p->seq_hdr->layout][p->seq_hdr->bpc > 8];
+ ss_names[p->p.layout][p->p.bpc > 8];
fprintf(c->f, "YUV4MPEG2 W%d H%d F%d:%d Ip C%s\n",
p->p.w, p->p.h, c->fps[0], c->fps[1], ss_name);