shithub: dav1d

Download patch

ref: 3e95d8ed717082430db632d290309f4f7326e7fe
parent: 9c4bf181e0871d73cceb6e166447cfc3c6c7ca42
author: Ronald S. Bultje <rsbultje@gmail.com>
date: Fri Nov 23 15:57:07 EST 2018

Move Dav1dPictureParameters-related entries to top of Dav1dSeqHdr

Also remove redundant entries from Dav1dPictureParameters, and move
documentation of these fields into Dav1dFrame/SequenceHeader instead.

--- a/include/dav1d/headers.h
+++ b/include/dav1d/headers.h
@@ -161,7 +161,43 @@
 };
 
 typedef struct Dav1dSequenceHeader {
+    /**
+     * Stream profile, 0 for 8-10 bits/component 4:2:0 or monochrome;
+     * 1 for 8-10 bits/component 4:4:4; 2 for 4:2:2 at any bits/component,
+     * or 12 bits/component at any chroma subsampling.
+     */
     int profile;
+    /**
+     * Maximum dimensions for this stream. In non-scalable streams, these
+     * are often the actual dimensions of the stream, although that is not
+     * 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)
+    enum Dav1dChromaSamplePosition chr; ///< chroma sample position (av1)
+    /**
+     * Pixel data uses JPEG pixel range ([0,255] for 8bits) instead of
+     * MPEG pixel range ([16,235] for 8bits luma, [16,240] for 8bits chroma).
+     */
+    int color_range;
+
+    int num_operating_points;
+    struct Dav1dSequenceHeaderOperatingPoint {
+        int major_level, minor_level;
+        int initial_display_delay;
+        int idc;
+        int tier;
+        int decoder_model_param_present;
+        int decoder_buffer_delay;
+        int encoder_buffer_delay;
+        int low_delay_mode;
+        int display_model_param_present;
+    } operating_points[DAV1D_MAX_OPERATING_POINTS];
+
     int still_picture;
     int reduced_still_picture_header;
     int timing_info_present;
@@ -175,19 +211,7 @@
     int buffer_removal_delay_length;
     int frame_presentation_delay_length;
     int display_model_info_present;
-    int num_operating_points;
-    struct Dav1dSequenceHeaderOperatingPoint {
-        int idc;
-        int major_level, minor_level;
-        int tier;
-        int decoder_model_param_present;
-        int decoder_buffer_delay;
-        int encoder_buffer_delay;
-        int low_delay_mode;
-        int display_model_param_present;
-        int initial_display_delay;
-    } operating_points[DAV1D_MAX_OPERATING_POINTS];
-    int max_width, max_height, width_n_bits, height_n_bits;
+    int width_n_bits, height_n_bits;
     int frame_id_numbers_present;
     int delta_frame_id_n_bits;
     int frame_id_n_bits;
@@ -207,15 +231,8 @@
     int super_res;
     int cdef;
     int restoration;
-    int bpc;
     int hbd;
     int color_description_present;
-    enum Dav1dPixelLayout layout;
-    enum Dav1dColorPrimaries pri;
-    enum Dav1dTransferCharacteristics trc;
-    enum Dav1dMatrixCoefficients mtrx;
-    enum Dav1dChromaSamplePosition chr;
-    int color_range;
     int separate_uv_delta_q;
     int film_grain_present;
 } Dav1dSequenceHeader;
@@ -260,11 +277,19 @@
 } Dav1dFilmGrainData;
 
 typedef struct Dav1dFrameHeader {
+    enum Dav1dFrameType frame_type; ///< type of the picture
+    int width[2 /* { coded_width, superresolution_upscaled_width } */], height;
+    int frame_offset; ///< frame number
+    struct {
+        int present, update;
+        Dav1dFilmGrainData data;
+    } film_grain; ///< film grain parameters
+    int temporal_id, spatial_id; ///< spatial and temporal id of the frame for SVC
+
     int show_existing_frame;
     int existing_frame_idx;
     int frame_id;
     int frame_presentation_delay;
-    enum Dav1dFrameType frame_type;
     int show_frame;
     int showable_frame;
     int error_resilient_mode;
@@ -277,9 +302,7 @@
     struct Dav1dFrameHeaderOperatingPoint {
         int buffer_removal_time;
     } operating_points[DAV1D_MAX_OPERATING_POINTS];
-    int frame_offset;
     int refresh_frame_flags;
-    int width[2 /* { coded_width, superresolution_upscaled_width } */], height;
     int render_width, render_height;
     struct {
         int width_scale_denominator;
@@ -350,11 +373,6 @@
     int warp_motion;
     int reduced_txtp_set;
     Dav1dWarpedMotionParams gmv[DAV1D_REFS_PER_FRAME];
-    struct {
-        int present, update;
-        Dav1dFilmGrainData data;
-    } film_grain;
-    int temporal_id, spatial_id;
 } Dav1dFrameHeader;
 
 #endif /* __DAV1D_HEADERS_H__ */
--- a/include/dav1d/picture.h
+++ b/include/dav1d/picture.h
@@ -38,25 +38,13 @@
     int w; ///< width (in pixels)
     int h; ///< height (in pixels)
     enum Dav1dPixelLayout layout; ///< format of the picture
-    enum Dav1dFrameType type; ///< type of the picture
     int bpc; ///< bits per pixel component (8 or 10)
-
-    enum Dav1dColorPrimaries pri; ///< color primaries (av1)
-    enum Dav1dTransferCharacteristics trc; ///< transfer characteristics (av1)
-    enum Dav1dMatrixCoefficients mtrx; ///< matrix coefficients (av1)
-    enum Dav1dChromaSamplePosition chr; ///< chroma sample position (av1)
-    /**
-     * Pixel data uses JPEG pixel range ([0,255] for 8bits) instead of
-     * MPEG pixel range ([16,235] for 8bits luma, [16,240] for 8bits chroma).
-     */
-    int fullrange;
-
-    Dav1dFilmGrainData film_grain; ///< film grain parameters
-    int spatial_id; ///< spatial id of the frame for scalable AV1
 } Dav1dPictureParameters;
 
 typedef struct Dav1dPicture {
-    int poc; ///< frame number
+    struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref;
+    Dav1dSequenceHeader *seq_hdr;
+    Dav1dFrameHeader *frame_hdr;
 
     /**
      * Pointers to planar image data (Y is [0], U is [1], V is [2]). The data
@@ -67,9 +55,6 @@
      */
     void *data[3];
     struct Dav1dRef *ref; ///< allocation origin
-    struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref;
-    Dav1dSequenceHeader *seq_hdr;
-    Dav1dFrameHeader *frame_hdr;
 
     /**
      * Number of bytes between 2 lines in data[] for luma [0] or chroma [1].
--- a/src/decode.c
+++ b/src/decode.c
@@ -1543,9 +1543,10 @@
                 if (f->seq_hdr->jnt_comp) {
                     const int jnt_ctx =
                         get_jnt_comp_ctx(f->seq_hdr->order_hint_n_bits,
-                                         f->cur.poc, f->refp[b->ref[0]].p.poc,
-                                         f->refp[b->ref[1]].p.poc, t->a, &t->l,
-                                         by4, bx4);
+                                         f->cur.frame_hdr->frame_offset,
+                                         f->refp[b->ref[0]].p.frame_hdr->frame_offset,
+                                         f->refp[b->ref[1]].p.frame_hdr->frame_offset,
+                                         t->a, &t->l, by4, bx4);
                     b->comp_type = COMP_INTER_WEIGHTED_AVG +
                         msac_decode_bool_adapt(&ts->msac,
                                                ts->cdf.m.jnt_comp[jnt_ctx]);
@@ -2683,7 +2684,9 @@
         const int order_hint_n_bits = f->seq_hdr->order_hint * f->seq_hdr->order_hint_n_bits;
         const int ret = av1_init_ref_mv_common(f->libaom_cm, f->bw >> 1, f->bh >> 1,
                                                f->b4_stride, f->seq_hdr->sb128,
-                                               f->mvs, f->ref_mvs, f->cur.poc, f->refpoc,
+                                               f->mvs, f->ref_mvs,
+                                               f->cur.frame_hdr->frame_offset,
+                                               f->refpoc,
                                                f->refrefpoc, f->frame_hdr->gmv,
                                                f->frame_hdr->hp, f->frame_hdr->force_integer_mv,
                                                f->frame_hdr->use_ref_frame_mvs,
@@ -2709,15 +2712,17 @@
     // setup jnt_comp weights
     if (f->frame_hdr->switchable_comp_refs) {
         for (int i = 0; i < 7; i++) {
-            const unsigned ref0poc = f->refp[i].p.poc;
+            const unsigned ref0poc = f->refp[i].p.frame_hdr->frame_offset;
 
             for (int j = i + 1; j < 7; j++) {
-                const unsigned ref1poc = f->refp[j].p.poc;
+                const unsigned ref1poc = f->refp[j].p.frame_hdr->frame_offset;
 
-                const unsigned d1 = imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits,
-                                                          ref0poc, f->cur.poc)), 31);
-                const unsigned d0 = imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits,
-                                                          ref1poc, f->cur.poc)), 31);
+                const unsigned d1 =
+                    imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits, ref0poc,
+                                          f->cur.frame_hdr->frame_offset)), 31);
+                const unsigned d0 =
+                    imin(abs(get_poc_diff(f->seq_hdr->order_hint_n_bits, ref1poc,
+                                          f->cur.frame_hdr->frame_offset)), 31);
                 const int order = d0 <= d1;
 
                 static const uint8_t quant_dist_weight[3][2] = {
@@ -3114,16 +3119,7 @@
                                      f->frame_hdr->show_frame, &c->allocator);
     if (res < 0) goto error;
 
-    f->sr_cur.p.poc = f->frame_hdr->frame_offset;
-    f->sr_cur.p.p.type = f->frame_hdr->frame_type;
-    f->sr_cur.p.p.film_grain = f->frame_hdr->film_grain.data;
-    f->sr_cur.p.p.pri = f->seq_hdr->pri;
-    f->sr_cur.p.p.trc = f->seq_hdr->trc;
-    f->sr_cur.p.p.mtrx = f->seq_hdr->mtrx;
-    f->sr_cur.p.p.chr = f->seq_hdr->chr;
-    f->sr_cur.p.p.fullrange = f->seq_hdr->color_range;
     f->sr_cur.p.m = f->tile[0].data.m;
-    f->sr_cur.p.p.spatial_id = f->frame_hdr->spatial_id;
     f->sr_cur.p.frame_hdr = f->frame_hdr;
     f->sr_cur.p.frame_hdr_ref = f->frame_hdr_ref;
     dav1d_ref_inc(f->frame_hdr_ref);
@@ -3175,7 +3171,7 @@
         f->mvs = f->mvs_ref->data;
         if (!f->frame_hdr->allow_intrabc) {
             for (int i = 0; i < 7; i++)
-                f->refpoc[i] = f->refp[i].p.poc;
+                f->refpoc[i] = f->refp[i].p.frame_hdr->frame_offset;
         } else {
             memset(f->refpoc, 0, sizeof(f->refpoc));
         }
--- a/src/film_grain_tmpl.c
+++ b/src/film_grain_tmpl.c
@@ -75,7 +75,7 @@
 static void generate_grain_y(const Dav1dPicture *const in,
                              entry buf[GRAIN_HEIGHT][GRAIN_WIDTH])
 {
-    const Dav1dFilmGrainData *data = &in->p.film_grain;
+    const Dav1dFilmGrainData *data = &in->frame_hdr->film_grain.data;
     unsigned seed = data->seed;
     const int shift = 12 - BITDEPTH + data->grain_scale_shift;
 
@@ -111,7 +111,7 @@
                               entry buf[GRAIN_HEIGHT][GRAIN_WIDTH],
                               entry buf_y[GRAIN_HEIGHT][GRAIN_WIDTH])
 {
-    const Dav1dFilmGrainData *data = &in->p.film_grain;
+    const Dav1dFilmGrainData *data = &in->frame_hdr->film_grain.data;
     unsigned seed = data->seed ^ (uv ? 0x49d8 : 0xb524);
     const int shift = 12 - BITDEPTH + data->grain_scale_shift;
 
@@ -211,7 +211,7 @@
                            entry grain_lut[GRAIN_HEIGHT][GRAIN_WIDTH],
                            uint8_t scaling[SCALING_SIZE], int row_num)
 {
-    const Dav1dFilmGrainData *const data = &out->p.film_grain;
+    const Dav1dFilmGrainData *const data = &out->frame_hdr->film_grain.data;
     const int rows = 1 + (data->overlap_flag && row_num > 0);
 
     int min_value, max_value;
@@ -330,13 +330,13 @@
                             entry grain_lut[GRAIN_HEIGHT][GRAIN_WIDTH],
                             uint8_t scaling[SCALING_SIZE], int uv, int row_num)
 {
-    const Dav1dFilmGrainData *const data = &out->p.film_grain;
+    const Dav1dFilmGrainData *const data = &out->frame_hdr->film_grain.data;
     const int rows = 1 + (data->overlap_flag && row_num > 0);
 
     int min_value, max_value;
     if (data->clip_to_restricted_range) {
         min_value = 16 << (BITDEPTH - 8);
-        if (out->p.mtrx == DAV1D_MC_IDENTITY) {
+        if (out->seq_hdr->mtrx == DAV1D_MC_IDENTITY) {
             max_value = 235 << (BITDEPTH - 8);
         } else {
             max_value = 240 << (BITDEPTH - 8);
@@ -477,7 +477,7 @@
 void bitfn(dav1d_apply_grain)(Dav1dPicture *const out,
                               const Dav1dPicture *const in)
 {
-    const Dav1dFilmGrainData *const data = &out->p.film_grain;
+    const Dav1dFilmGrainData *const data = &out->frame_hdr->film_grain.data;
 
     entry grain_lut[3][GRAIN_HEIGHT][GRAIN_WIDTH];
     uint8_t scaling[3][SCALING_SIZE];
--- a/src/lib.c
+++ b/src/lib.c
@@ -183,7 +183,7 @@
 static int output_image(Dav1dContext *const c, Dav1dPicture *const out,
                         Dav1dPicture *const in)
 {
-    const Dav1dFilmGrainData *fgdata = &in->p.film_grain;
+    const Dav1dFilmGrainData *fgdata = &in->frame_hdr->film_grain.data;
     int has_grain = fgdata->num_y_points || fgdata->num_uv_points[0] ||
                     fgdata->num_uv_points[1];
 
@@ -190,7 +190,7 @@
     // skip lower spatial layers
     if (c->operating_point_idc && !c->all_layers) {
         const int max_spatial_id = ulog2(c->operating_point_idc >> 8);
-        if (max_spatial_id > in->p.spatial_id) {
+        if (max_spatial_id > in->frame_hdr->spatial_id) {
             dav1d_picture_unref(in);
             return 0;
         }
--- a/src/obu.c
+++ b/src/obu.c
@@ -450,8 +450,10 @@
             int shifted_frame_offset[8];
             const int current_frame_offset = 1 << (seqhdr->order_hint_n_bits - 1);
             for (int i = 0; i < 8; i++)
-                shifted_frame_offset[i] =
-                    current_frame_offset + get_poc_diff(seqhdr->order_hint_n_bits, c->refs[i].p.p.poc, hdr->frame_offset);
+                shifted_frame_offset[i] = current_frame_offset +
+                    get_poc_diff(seqhdr->order_hint_n_bits,
+                                 c->refs[i].p.p.frame_hdr->frame_offset,
+                                 hdr->frame_offset);
 
             int used_frame[8] = { 0 };
             used_frame[hdr->refidx[0]] = 1;
@@ -902,7 +904,7 @@
         int off_before_idx[2], off_after_idx;
         for (int i = 0; i < 7; i++) {
             if (!c->refs[hdr->refidx[i]].p.p.data[0]) return -EINVAL;
-            const unsigned refpoc = c->refs[hdr->refidx[i]].p.p.poc;
+            const unsigned refpoc = c->refs[hdr->refidx[i]].p.p.frame_hdr->frame_offset;
 
             const int diff = get_poc_diff(seqhdr->order_hint_n_bits, refpoc, poc);
             if (diff > 0) {
@@ -1364,7 +1366,7 @@
                 out_delayed->p.m = in->m;
                 pthread_mutex_unlock(&f->frame_thread.td.lock);
             }
-            if (c->refs[c->frame_hdr->existing_frame_idx].p.p.p.type == DAV1D_FRAME_TYPE_KEY) {
+            if (c->refs[c->frame_hdr->existing_frame_idx].p.p.frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY) {
                 const int r = c->frame_hdr->existing_frame_idx;
                 for (int i = 0; i < 8; i++) {
                     if (i == c->frame_hdr->existing_frame_idx) continue;
--- a/src/picture.c
+++ b/src/picture.c
@@ -116,14 +116,9 @@
 
     p->p.w = w;
     p->p.h = h;
-    p->p.pri = DAV1D_COLOR_PRI_UNKNOWN;
-    p->p.trc = DAV1D_TRC_UNKNOWN;
-    p->p.mtrx = DAV1D_MC_UNKNOWN;
-    p->p.chr = DAV1D_CHR_UNKNOWN;
     p->m.timestamp = p->m.duration = p->m.offset = ~0ULL;
     p->p.layout = layout;
     p->p.bpc = bpc;
-    p->p.film_grain = (Dav1dFilmGrainData) { 0 };
     int res = p_allocator->alloc_picture_callback(p, p_allocator->cookie);
     if (res < 0) {
         free(pic_ctx);
@@ -176,7 +171,6 @@
                                              0, NULL);
 
     if (!res) {
-        dst->poc = src->poc;
         dst->p = src->p;
         dst->m = src->m;
         dst->p.w = w;
--- a/tools/output/y4m2.c
+++ b/tools/output/y4m2.c
@@ -37,6 +37,8 @@
 
 typedef struct MuxerPriv {
     FILE *f;
+    int first;
+    unsigned fps[2];
 } Y4m2OutputContext;
 
 static int y4m2_open(Y4m2OutputContext *const c, const char *const file,
@@ -49,6 +51,14 @@
         return -1;
     }
 
+    c->first = 1;
+    c->fps[0] = fps[0];
+    c->fps[1] = fps[1];
+
+    return 0;
+}
+
+static int write_header(Y4m2OutputContext *const c, const Dav1dPicture *const p) {
     static const char *const ss_names[][2] = {
         [DAV1D_PIXEL_LAYOUT_I400] = { "mono", "mono10" },
         [DAV1D_PIXEL_LAYOUT_I420] = { NULL, "420p10" },
@@ -62,17 +72,23 @@
         [DAV1D_CHR_COLOCATED] = "420"
     };
 
-    const char *const ss_name = p->layout == DAV1D_PIXEL_LAYOUT_I420 && p->bpc == 8 ?
-        chr_names_8bpc_i420[p->chr > 2 ? DAV1D_CHR_UNKNOWN : p->chr] :
-        ss_names[p->layout][p->bpc > 8];
+    const char *const ss_name =
+        p->seq_hdr->layout == DAV1D_PIXEL_LAYOUT_I420 && p->seq_hdr->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];
 
     fprintf(c->f, "YUV4MPEG2 W%d H%d F%d:%d Ip C%s\n",
-            p->w, p->h, fps[0], fps[1], ss_name);
+            p->p.w, p->p.h, c->fps[0], c->fps[1], ss_name);
 
     return 0;
 }
 
 static int y4m2_write(Y4m2OutputContext *const c, Dav1dPicture *const p) {
+    if (c->first) {
+        c->first = 0;
+        const int res = write_header(c, p);
+        if (res < 0) return res;
+    }
     fprintf(c->f, "FRAME\n");
 
     uint8_t *ptr;