shithub: dav1d

Download patch

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);