Commit b6bb8536 authored by Ronald S. Bultje's avatar Ronald S. Bultje

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.
parent 3e95d8ed
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 :
......
......@@ -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);
......
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