diff options
-rw-r--r-- | include/dav1d/headers.h | 10 | ||||
-rw-r--r-- | include/dav1d/picture.h | 3 | ||||
-rw-r--r-- | src/decode.c | 40 | ||||
-rw-r--r-- | src/obu.c | 56 | ||||
-rw-r--r-- | src/recon_tmpl.c | 6 | ||||
-rw-r--r-- | tools/output/y4m2.c | 4 |
6 files changed, 63 insertions, 56 deletions
diff --git a/include/dav1d/headers.h b/include/dav1d/headers.h index cdde681..bf8c5ae 100644 --- a/include/dav1d/headers.h +++ b/include/dav1d/headers.h @@ -173,8 +173,6 @@ typedef struct Dav1dSequenceHeader { * 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 @@ typedef struct Dav1dSequenceHeader { 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; diff --git a/include/dav1d/picture.h b/include/dav1d/picture.h index bdb26d9..1c51074 100644 --- a/include/dav1d/picture.h +++ b/include/dav1d/picture.h @@ -42,7 +42,6 @@ typedef struct Dav1dPictureParameters { } Dav1dPictureParameters; typedef struct Dav1dPicture { - struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref; Dav1dSequenceHeader *seq_hdr; Dav1dFrameHeader *frame_hdr; @@ -54,7 +53,6 @@ typedef struct Dav1dPicture { * 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 @@ typedef struct Dav1dPicture { Dav1dPictureParameters p; Dav1dDataProps m; + struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref, *ref; ///< allocation origins void *allocator_data; ///< pointer managed by the allocator } Dav1dPicture; diff --git a/src/decode.c b/src/decode.c index 75090a9..4fc43b3 100644 --- a/src/decode.c +++ b/src/decode.c @@ -62,12 +62,12 @@ static void init_quant_tables(const Dav1dSequenceHeader *const seq_hdr, 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 @@ static int decode_b(Dav1dTileContext *const t, 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 @@ static int decode_b(Dav1dTileContext *const t, 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 @@ int dav1d_submit_frame(Dav1dContext *const c) { 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 @@ int dav1d_submit_frame(Dav1dContext *const c) { #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 @@ int dav1d_submit_frame(Dav1dContext *const c) { 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 @@ int dav1d_submit_frame(Dav1dContext *const c) { 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 @@ int dav1d_submit_frame(Dav1dContext *const c) { // 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; @@ -201,10 +201,9 @@ static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb, 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,36 +214,36 @@ static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb, 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 && 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 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) { // 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 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) { } 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 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) { 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 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) { 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 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) { } 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 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) { } 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 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) { } } - 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; diff --git a/src/recon_tmpl.c b/src/recon_tmpl.c index a31df3d..09e12cf 100644 --- a/src/recon_tmpl.c +++ b/src/recon_tmpl.c @@ -368,7 +368,7 @@ void bytefn(dav1d_read_coef_blocks)(Dav1dTileContext *const t, 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 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize 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 @@ int bytefn(dav1d_recon_b_inter)(Dav1dTileContext *const t, const enum BlockSize 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 : diff --git a/tools/output/y4m2.c b/tools/output/y4m2.c index 9a81022..cbe2b14 100644 --- a/tools/output/y4m2.c +++ b/tools/output/y4m2.c @@ -73,9 +73,9 @@ static int write_header(Y4m2OutputContext *const c, const Dav1dPicture *const p) }; 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); |