obu.c 58.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
/*
 * Copyright © 2018, VideoLAN and dav1d authors
 * Copyright © 2018, Two Orioles, LLC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>

#include "dav1d/data.h"

#include "common/intops.h"

#include "src/decode.h"
#include "src/getbits.h"
#include "src/levels.h"
42
#include "src/log.h"
43 44
#include "src/obu.h"
#include "src/ref.h"
45
#include "src/thread_task.h"
46

47
static int parse_seq_hdr(Dav1dContext *const c, GetBits *const gb,
48
                         Dav1dSequenceHeader *const hdr)
49
{
50 51
#define DEBUG_SEQ_HDR 0

52 53 54 55
#if DEBUG_SEQ_HDR
    const unsigned init_bit_pos = dav1d_get_bits_pos(gb);
#endif

56
    hdr->profile = dav1d_get_bits(gb, 3);
57
    if (hdr->profile > 2) goto error;
58 59
#if DEBUG_SEQ_HDR
    printf("SEQHDR: post-profile: off=%ld\n",
60
           dav1d_get_bits_pos(gb) - init_bit_pos);
61 62
#endif

63 64
    hdr->still_picture = dav1d_get_bits(gb, 1);
    hdr->reduced_still_picture_header = dav1d_get_bits(gb, 1);
65 66 67
    if (hdr->reduced_still_picture_header && !hdr->still_picture) goto error;
#if DEBUG_SEQ_HDR
    printf("SEQHDR: post-stillpicture_flags: off=%ld\n",
68
           dav1d_get_bits_pos(gb) - init_bit_pos);
69 70 71 72 73 74 75 76
#endif

    if (hdr->reduced_still_picture_header) {
        hdr->timing_info_present = 0;
        hdr->decoder_model_info_present = 0;
        hdr->display_model_info_present = 0;
        hdr->num_operating_points = 1;
        hdr->operating_points[0].idc = 0;
77 78
        hdr->operating_points[0].major_level = dav1d_get_bits(gb, 3);
        hdr->operating_points[0].minor_level = dav1d_get_bits(gb, 2);
79 80 81 82
        hdr->operating_points[0].tier = 0;
        hdr->operating_points[0].decoder_model_param_present = 0;
        hdr->operating_points[0].display_model_param_present = 0;
    } else {
83
        hdr->timing_info_present = dav1d_get_bits(gb, 1);
84
        if (hdr->timing_info_present) {
85 86 87
            hdr->num_units_in_tick = dav1d_get_bits(gb, 32);
            hdr->time_scale = dav1d_get_bits(gb, 32);
            hdr->equal_picture_interval = dav1d_get_bits(gb, 1);
88 89 90 91 92 93
            if (hdr->equal_picture_interval) {
                unsigned num_ticks_per_picture = dav1d_get_vlc(gb);
                if (num_ticks_per_picture == 0xFFFFFFFFU)
                    goto error;
                hdr->num_ticks_per_picture = num_ticks_per_picture + 1;
            }
94

95
            hdr->decoder_model_info_present = dav1d_get_bits(gb, 1);
96
            if (hdr->decoder_model_info_present) {
97 98 99 100
                hdr->encoder_decoder_buffer_delay_length = dav1d_get_bits(gb, 5) + 1;
                hdr->num_units_in_decoding_tick = dav1d_get_bits(gb, 32);
                hdr->buffer_removal_delay_length = dav1d_get_bits(gb, 5) + 1;
                hdr->frame_presentation_delay_length = dav1d_get_bits(gb, 5) + 1;
101 102 103 104 105 106
            }
        } else {
            hdr->decoder_model_info_present = 0;
        }
#if DEBUG_SEQ_HDR
        printf("SEQHDR: post-timinginfo: off=%ld\n",
107
               dav1d_get_bits_pos(gb) - init_bit_pos);
108 109
#endif

110 111
        hdr->display_model_info_present = dav1d_get_bits(gb, 1);
        hdr->num_operating_points = dav1d_get_bits(gb, 5) + 1;
112
        for (int i = 0; i < hdr->num_operating_points; i++) {
113
            struct Dav1dSequenceHeaderOperatingPoint *const op =
114
                &hdr->operating_points[i];
115 116 117 118
            op->idc = dav1d_get_bits(gb, 12);
            op->major_level = 2 + dav1d_get_bits(gb, 3);
            op->minor_level = dav1d_get_bits(gb, 2);
            op->tier = op->major_level > 3 ? dav1d_get_bits(gb, 1) : 0;
119
            op->decoder_model_param_present =
120
                hdr->decoder_model_info_present && dav1d_get_bits(gb, 1);
121 122
            if (op->decoder_model_param_present) {
                op->decoder_buffer_delay =
123
                    dav1d_get_bits(gb, hdr->encoder_decoder_buffer_delay_length);
124
                op->encoder_buffer_delay =
125 126
                    dav1d_get_bits(gb, hdr->encoder_decoder_buffer_delay_length);
                op->low_delay_mode = dav1d_get_bits(gb, 1);
127 128
            }
            op->display_model_param_present =
129
                hdr->display_model_info_present && dav1d_get_bits(gb, 1);
130
            if (op->display_model_param_present) {
131
                op->initial_display_delay = dav1d_get_bits(gb, 4) + 1;
132 133
            }
        }
134 135 136 137
        if (c->operating_point < hdr->num_operating_points)
            c->operating_point_idc = hdr->operating_points[c->operating_point].idc;
        else
            c->operating_point_idc = hdr->operating_points[0].idc;
138 139
#if DEBUG_SEQ_HDR
        printf("SEQHDR: post-operating-points: off=%ld\n",
140
               dav1d_get_bits_pos(gb) - init_bit_pos);
141 142 143
#endif
    }

144 145 146 147
    hdr->width_n_bits = dav1d_get_bits(gb, 4) + 1;
    hdr->height_n_bits = dav1d_get_bits(gb, 4) + 1;
    hdr->max_width = dav1d_get_bits(gb, hdr->width_n_bits) + 1;
    hdr->max_height = dav1d_get_bits(gb, hdr->height_n_bits) + 1;
148 149
#if DEBUG_SEQ_HDR
    printf("SEQHDR: post-size: off=%ld\n",
150
           dav1d_get_bits_pos(gb) - init_bit_pos);
151 152
#endif
    hdr->frame_id_numbers_present =
153
        hdr->reduced_still_picture_header ? 0 : dav1d_get_bits(gb, 1);
154
    if (hdr->frame_id_numbers_present) {
155 156
        hdr->delta_frame_id_n_bits = dav1d_get_bits(gb, 4) + 2;
        hdr->frame_id_n_bits = dav1d_get_bits(gb, 3) + hdr->delta_frame_id_n_bits + 1;
157 158 159
    }
#if DEBUG_SEQ_HDR
    printf("SEQHDR: post-frame-id-numbers-present: off=%ld\n",
160
           dav1d_get_bits_pos(gb) - init_bit_pos);
161 162
#endif

163 164 165
    hdr->sb128 = dav1d_get_bits(gb, 1);
    hdr->filter_intra = dav1d_get_bits(gb, 1);
    hdr->intra_edge_filter = dav1d_get_bits(gb, 1);
166 167 168 169 170 171 172 173 174
    if (hdr->reduced_still_picture_header) {
        hdr->inter_intra = 0;
        hdr->masked_compound = 0;
        hdr->warped_motion = 0;
        hdr->dual_filter = 0;
        hdr->order_hint = 0;
        hdr->jnt_comp = 0;
        hdr->ref_frame_mvs = 0;
        hdr->order_hint_n_bits = 0;
175 176
        hdr->screen_content_tools = DAV1D_ADAPTIVE;
        hdr->force_integer_mv = DAV1D_ADAPTIVE;
177
    } else {
178 179 180 181 182
        hdr->inter_intra = dav1d_get_bits(gb, 1);
        hdr->masked_compound = dav1d_get_bits(gb, 1);
        hdr->warped_motion = dav1d_get_bits(gb, 1);
        hdr->dual_filter = dav1d_get_bits(gb, 1);
        hdr->order_hint = dav1d_get_bits(gb, 1);
183
        if (hdr->order_hint) {
184 185
            hdr->jnt_comp = dav1d_get_bits(gb, 1);
            hdr->ref_frame_mvs = dav1d_get_bits(gb, 1);
186 187 188 189 190
        } else {
            hdr->jnt_comp = 0;
            hdr->ref_frame_mvs = 0;
            hdr->order_hint_n_bits = 0;
        }
191
        hdr->screen_content_tools = dav1d_get_bits(gb, 1) ? DAV1D_ADAPTIVE : dav1d_get_bits(gb, 1);
192 193
    #if DEBUG_SEQ_HDR
        printf("SEQHDR: post-screentools: off=%ld\n",
194
               dav1d_get_bits_pos(gb) - init_bit_pos);
195 196
    #endif
        hdr->force_integer_mv = hdr->screen_content_tools ?
197
                                dav1d_get_bits(gb, 1) ? DAV1D_ADAPTIVE : dav1d_get_bits(gb, 1) : 2;
198
        if (hdr->order_hint)
199
            hdr->order_hint_n_bits = dav1d_get_bits(gb, 3) + 1;
200
    }
201 202 203
    hdr->super_res = dav1d_get_bits(gb, 1);
    hdr->cdef = dav1d_get_bits(gb, 1);
    hdr->restoration = dav1d_get_bits(gb, 1);
204 205
#if DEBUG_SEQ_HDR
    printf("SEQHDR: post-featurebits: off=%ld\n",
206
           dav1d_get_bits_pos(gb) - init_bit_pos);
207 208
#endif

209 210 211
    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;
212
    hdr->color_description_present = dav1d_get_bits(gb, 1);
213
    if (hdr->color_description_present) {
214 215 216
        hdr->pri = dav1d_get_bits(gb, 8);
        hdr->trc = dav1d_get_bits(gb, 8);
        hdr->mtrx = dav1d_get_bits(gb, 8);
217 218 219 220 221
    } else {
        hdr->pri = DAV1D_COLOR_PRI_UNKNOWN;
        hdr->trc = DAV1D_TRC_UNKNOWN;
        hdr->mtrx = DAV1D_MC_UNKNOWN;
    }
222
    if (hdr->monochrome) {
223
        hdr->color_range = dav1d_get_bits(gb, 1);
224
        hdr->layout = DAV1D_PIXEL_LAYOUT_I400;
225
        hdr->ss_hor = hdr->ss_ver = 1;
226 227 228 229 230 231
        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)
    {
232
        hdr->layout = DAV1D_PIXEL_LAYOUT_I444;
233
        hdr->ss_hor = hdr->ss_ver = 0;
234
        hdr->color_range = 1;
235
        if (hdr->profile != 1 && !(hdr->profile == 2 && hdr->hbd == 2))
236 237
            goto error;
    } else {
238
        hdr->color_range = dav1d_get_bits(gb, 1);
239
        switch (hdr->profile) {
240 241 242 243 244 245
        case 0: hdr->layout = DAV1D_PIXEL_LAYOUT_I420;
                hdr->ss_hor = hdr->ss_ver = 1;
                break;
        case 1: hdr->layout = DAV1D_PIXEL_LAYOUT_I444;
                hdr->ss_hor = hdr->ss_ver = 0;
                break;
246
        case 2:
247 248 249 250 251 252 253
            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;
            }
254 255 256 257
            hdr->layout = hdr->ss_hor ?
                          hdr->ss_ver ? DAV1D_PIXEL_LAYOUT_I420 :
                                        DAV1D_PIXEL_LAYOUT_I422 :
                                        DAV1D_PIXEL_LAYOUT_I444;
258 259
            break;
        }
260 261
        hdr->chr = hdr->ss_hor == 1 && hdr->ss_ver == 1 ?
                   dav1d_get_bits(gb, 2) : DAV1D_CHR_UNKNOWN;
262
    }
263
    hdr->separate_uv_delta_q = !hdr->monochrome && dav1d_get_bits(gb, 1);
264 265
#if DEBUG_SEQ_HDR
    printf("SEQHDR: post-colorinfo: off=%ld\n",
266
           dav1d_get_bits_pos(gb) - init_bit_pos);
267 268
#endif

269
    hdr->film_grain_present = dav1d_get_bits(gb, 1);
270 271
#if DEBUG_SEQ_HDR
    printf("SEQHDR: post-filmgrain: off=%ld\n",
272
           dav1d_get_bits_pos(gb) - init_bit_pos);
273 274
#endif

275
    dav1d_get_bits(gb, 1); // dummy bit
276

277 278 279 280 281
    // We needn't bother flushing the OBU here: we'll check we didn't
    // overrun in the caller and will then discard gb, so there's no
    // point in setting its position properly.

    return 0;
282 283

error:
284
    dav1d_log(c, "Error parsing sequence header\n");
285 286 287 288 289 290
    return -EINVAL;
}

static int read_frame_size(Dav1dContext *const c, GetBits *const gb,
                           const int use_ref)
{
291 292
    const Dav1dSequenceHeader *const seqhdr = c->seq_hdr;
    Dav1dFrameHeader *const hdr = c->frame_hdr;
293 294 295

    if (use_ref) {
        for (int i = 0; i < 7; i++) {
296
            if (dav1d_get_bits(gb, 1)) {
297
                Dav1dThreadPicture *const ref =
Ronald S. Bultje's avatar
Ronald S. Bultje committed
298
                    &c->refs[c->frame_hdr->refidx[i]].p;
299 300
                if (!ref->p.data[0]) return -1;
                // FIXME render_* may be wrong
Ronald S. Bultje's avatar
Ronald S. Bultje committed
301
                hdr->render_width = hdr->width[1] = ref->p.p.w;
302
                hdr->render_height = hdr->height = ref->p.p.h;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
303 304 305 306 307 308 309 310 311 312
                hdr->super_res.enabled = seqhdr->super_res && dav1d_get_bits(gb, 1);
                if (hdr->super_res.enabled) {
                    const int d = hdr->super_res.width_scale_denominator =
                        9 + dav1d_get_bits(gb, 3);
                    hdr->width[0] = imax((hdr->width[1] * 8 + (d >> 1)) / d,
                                         imin(16, hdr->width[1]));
                } else {
                    hdr->super_res.width_scale_denominator = 8;
                    hdr->width[0] = hdr->width[1];
                }
313 314 315 316 317 318
                return 0;
            }
        }
    }

    if (hdr->frame_size_override) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
319
        hdr->width[1] = dav1d_get_bits(gb, seqhdr->width_n_bits) + 1;
320
        hdr->height = dav1d_get_bits(gb, seqhdr->height_n_bits) + 1;
321
    } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
322
        hdr->width[1] = seqhdr->max_width;
323 324
        hdr->height = seqhdr->max_height;
    }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
325 326 327 328 329 330 331 332
    hdr->super_res.enabled = seqhdr->super_res && dav1d_get_bits(gb, 1);
    if (hdr->super_res.enabled) {
        const int d = hdr->super_res.width_scale_denominator = 9 + dav1d_get_bits(gb, 3);
        hdr->width[0] = imax((hdr->width[1] * 8 + (d >> 1)) / d, imin(16, hdr->width[1]));
    } else {
        hdr->super_res.width_scale_denominator = 8;
        hdr->width[0] = hdr->width[1];
    }
333
    hdr->have_render_size = dav1d_get_bits(gb, 1);
334
    if (hdr->have_render_size) {
335 336
        hdr->render_width = dav1d_get_bits(gb, 16) + 1;
        hdr->render_height = dav1d_get_bits(gb, 16) + 1;
337
    } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
338
        hdr->render_width = hdr->width[1];
339 340 341 342 343 344 345 346 347 348 349
        hdr->render_height = hdr->height;
    }
    return 0;
}

static inline int tile_log2(int sz, int tgt) {
    int k;
    for (k = 0; (sz << k) < tgt; k++) ;
    return k;
}

350
static const Dav1dLoopfilterModeRefDeltas default_mode_ref_deltas = {
351 352 353 354
    .mode_delta = { 0, 0 },
    .ref_delta = { 1, 0, 0, 0, -1, 0, -1, -1 },
};

355 356 357 358
static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) {
#define DEBUG_FRAME_HDR 0

#if DEBUG_FRAME_HDR
359
    const uint8_t *const init_ptr = gb->ptr;
360
#endif
361 362
    const Dav1dSequenceHeader *const seqhdr = c->seq_hdr;
    Dav1dFrameHeader *const hdr = c->frame_hdr;
363 364 365
    int res;

    hdr->show_existing_frame =
366
        !seqhdr->reduced_still_picture_header && dav1d_get_bits(gb, 1);
367 368 369 370 371
#if DEBUG_FRAME_HDR
    printf("HDR: post-show_existing_frame: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif
    if (hdr->show_existing_frame) {
372
        hdr->existing_frame_idx = dav1d_get_bits(gb, 3);
373 374
        if (seqhdr->decoder_model_info_present && !seqhdr->equal_picture_interval)
            hdr->frame_presentation_delay = dav1d_get_bits(gb, seqhdr->frame_presentation_delay_length);
375
        if (seqhdr->frame_id_numbers_present)
376
            hdr->frame_id = dav1d_get_bits(gb, seqhdr->frame_id_n_bits);
377
        return 0;
378 379
    }

380 381
    hdr->frame_type = seqhdr->reduced_still_picture_header ? DAV1D_FRAME_TYPE_KEY : dav1d_get_bits(gb, 2);
    hdr->show_frame = seqhdr->reduced_still_picture_header || dav1d_get_bits(gb, 1);
382 383 384 385
    if (hdr->show_frame) {
        if (seqhdr->decoder_model_info_present && !seqhdr->equal_picture_interval)
            hdr->frame_presentation_delay = dav1d_get_bits(gb, seqhdr->frame_presentation_delay_length);
    } else
386
        hdr->showable_frame = dav1d_get_bits(gb, 1);
387
    hdr->error_resilient_mode =
388 389
        (hdr->frame_type == DAV1D_FRAME_TYPE_KEY && hdr->show_frame) ||
        hdr->frame_type == DAV1D_FRAME_TYPE_SWITCH ||
390
        seqhdr->reduced_still_picture_header || dav1d_get_bits(gb, 1);
391 392 393 394
#if DEBUG_FRAME_HDR
    printf("HDR: post-frametype_bits: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif
395
    hdr->disable_cdf_update = dav1d_get_bits(gb, 1);
396
    hdr->allow_screen_content_tools = seqhdr->screen_content_tools == DAV1D_ADAPTIVE ?
397
                                 dav1d_get_bits(gb, 1) : seqhdr->screen_content_tools;
398
    if (hdr->allow_screen_content_tools)
399
        hdr->force_integer_mv = seqhdr->force_integer_mv == DAV1D_ADAPTIVE ?
400
                                dav1d_get_bits(gb, 1) : seqhdr->force_integer_mv;
401 402 403 404 405
    else
        hdr->force_integer_mv = 0;

    if (!(hdr->frame_type & 1))
        hdr->force_integer_mv = 1;
406 407

    if (seqhdr->frame_id_numbers_present)
408
        hdr->frame_id = dav1d_get_bits(gb, seqhdr->frame_id_n_bits);
409 410

    hdr->frame_size_override = seqhdr->reduced_still_picture_header ? 0 :
411
                               hdr->frame_type == DAV1D_FRAME_TYPE_SWITCH ? 1 : dav1d_get_bits(gb, 1);
412 413 414 415 416
#if DEBUG_FRAME_HDR
    printf("HDR: post-frame_size_override_flag: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif
    hdr->frame_offset = seqhdr->order_hint ?
417
                        dav1d_get_bits(gb, seqhdr->order_hint_n_bits) : 0;
418
    hdr->primary_ref_frame = !hdr->error_resilient_mode && hdr->frame_type & 1 ?
419
                             dav1d_get_bits(gb, 3) : DAV1D_PRIMARY_REF_NONE;
420

421 422 423
    if (seqhdr->decoder_model_info_present) {
        hdr->buffer_removal_time_present = dav1d_get_bits(gb, 1);
        if (hdr->buffer_removal_time_present) {
424
            for (int i = 0; i < c->seq_hdr->num_operating_points; i++) {
425 426
                const struct Dav1dSequenceHeaderOperatingPoint *const seqop = &seqhdr->operating_points[i];
                struct Dav1dFrameHeaderOperatingPoint *const op = &hdr->operating_points[i];
427
                if (seqop->decoder_model_param_present) {
428 429 430
                    int in_temporal_layer = (seqop->idc >> hdr->temporal_id) & 1;
                    int in_spatial_layer  = (seqop->idc >> (hdr->spatial_id + 8)) & 1;
                    if (!seqop->idc || (in_temporal_layer && in_spatial_layer))
431 432 433 434 435 436
                        op->buffer_removal_time = dav1d_get_bits(gb, seqhdr->buffer_removal_delay_length);
                }
            }
        }
    }

James Almer's avatar
James Almer committed
437 438 439 440 441
    if (hdr->frame_type == DAV1D_FRAME_TYPE_KEY ||
        hdr->frame_type == DAV1D_FRAME_TYPE_INTRA)
    {
        hdr->refresh_frame_flags = (hdr->frame_type == DAV1D_FRAME_TYPE_KEY &&
                                    hdr->show_frame) ? 0xff : dav1d_get_bits(gb, 8);
442 443 444
        if (hdr->refresh_frame_flags != 0xff && hdr->error_resilient_mode && seqhdr->order_hint)
            for (int i = 0; i < 8; i++)
                dav1d_get_bits(gb, seqhdr->order_hint_n_bits);
445 446
        if ((res = read_frame_size(c, gb, 0)) < 0) goto error;
        hdr->allow_intrabc = hdr->allow_screen_content_tools &&
Ronald S. Bultje's avatar
Ronald S. Bultje committed
447
                             !hdr->super_res.enabled && dav1d_get_bits(gb, 1);
448 449
        hdr->use_ref_frame_mvs = 0;
    } else {
James Almer's avatar
James Almer committed
450 451 452 453 454 455 456 457
        hdr->allow_intrabc = 0;
        hdr->refresh_frame_flags = hdr->frame_type == DAV1D_FRAME_TYPE_SWITCH ? 0xff :
                                   dav1d_get_bits(gb, 8);
        if (hdr->error_resilient_mode && seqhdr->order_hint)
            for (int i = 0; i < 8; i++)
                dav1d_get_bits(gb, seqhdr->order_hint_n_bits);
        hdr->frame_ref_short_signaling =
            seqhdr->order_hint && dav1d_get_bits(gb, 1);
458 459 460 461 462 463 464 465
        if (hdr->frame_ref_short_signaling) { // FIXME: Nearly verbatim copy from section 7.8
            hdr->refidx[0] = dav1d_get_bits(gb, 3);
            hdr->refidx[1] = hdr->refidx[2] = -1;
            hdr->refidx[3] = dav1d_get_bits(gb, 3);
            hdr->refidx[4] = hdr->refidx[5] = hdr->refidx[6] = -1;

            int shifted_frame_offset[8];
            const int current_frame_offset = 1 << (seqhdr->order_hint_n_bits - 1);
466 467
            for (int i = 0; i < 8; i++) {
                if (!c->refs[i].p.p.frame_hdr) goto error;
468 469 470 471
                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);
472
            }
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547

            int used_frame[8] = { 0 };
            used_frame[hdr->refidx[0]] = 1;
            used_frame[hdr->refidx[3]] = 1;

            int latest_frame_offset = -1;
            for (int i = 0; i < 8; i++) {
                int hint = shifted_frame_offset[i];
                if (!used_frame[i] && hint >= current_frame_offset &&
                    hint >= latest_frame_offset)
                {
                    hdr->refidx[6] = i;
                    latest_frame_offset = hint;
                }
            }
            if (latest_frame_offset != -1)
                used_frame[hdr->refidx[6]] = 1;

            int earliest_frame_offset = INT_MAX;
            for (int i = 0; i < 8; i++) {
                int hint = shifted_frame_offset[i];
                if (!used_frame[i] && hint >= current_frame_offset &&
                    hint < earliest_frame_offset)
                {
                    hdr->refidx[4] = i;
                    earliest_frame_offset = hint;
                }
            }
            if (earliest_frame_offset != INT_MAX)
                used_frame[hdr->refidx[4]] = 1;

            earliest_frame_offset = INT_MAX;
            for (int i = 0; i < 8; i++) {
                int hint = shifted_frame_offset[i];
                if (!used_frame[i] && hint >= current_frame_offset &&
                    (hint < earliest_frame_offset))
                {
                    hdr->refidx[5] = i;
                    earliest_frame_offset = hint;
                }
            }
            if (earliest_frame_offset != INT_MAX)
                used_frame[hdr->refidx[5]] = 1;

            for (int i = 1; i < 7; i++) {
                if (hdr->refidx[i] < 0) {
                    latest_frame_offset = -1;
                    for (int j = 0; j < 8; j++) {
                        int hint = shifted_frame_offset[j];
                        if (!used_frame[j] && hint < current_frame_offset &&
                            hint >= latest_frame_offset)
                        {
                            hdr->refidx[i] = j;
                            latest_frame_offset = hint;
                        }
                    }
                    if (latest_frame_offset != -1)
                        used_frame[hdr->refidx[i]] = 1;
                }
            }

            earliest_frame_offset = INT_MAX;
            int ref = -1;
            for (int i = 0; i < 8; i++) {
                int hint = shifted_frame_offset[i];
                if (hint < earliest_frame_offset) {
                    ref = i;
                    earliest_frame_offset = hint;
                }
            }
            for (int i = 0; i < 7; i++) {
                if (hdr->refidx[i] < 0)
                    hdr->refidx[i] = ref;
            }
        }
James Almer's avatar
James Almer committed
548
        for (int i = 0; i < 7; i++) {
549 550
            if (!hdr->frame_ref_short_signaling)
                hdr->refidx[i] = dav1d_get_bits(gb, 3);
James Almer's avatar
James Almer committed
551 552
            if (seqhdr->frame_id_numbers_present)
                dav1d_get_bits(gb, seqhdr->delta_frame_id_n_bits);
553
        }
James Almer's avatar
James Almer committed
554 555 556 557
        const int use_ref = !hdr->error_resilient_mode &&
                            hdr->frame_size_override;
        if ((res = read_frame_size(c, gb, use_ref)) < 0) goto error;
        hdr->hp = !hdr->force_integer_mv && dav1d_get_bits(gb, 1);
558
        hdr->subpel_filter_mode = dav1d_get_bits(gb, 1) ? DAV1D_FILTER_SWITCHABLE :
James Almer's avatar
James Almer committed
559 560 561 562 563
                                                          dav1d_get_bits(gb, 2);
        hdr->switchable_motion_mode = dav1d_get_bits(gb, 1);
        hdr->use_ref_frame_mvs = !hdr->error_resilient_mode &&
            seqhdr->ref_frame_mvs && seqhdr->order_hint &&
            hdr->frame_type & 1 && dav1d_get_bits(gb, 1);
564 565 566 567 568 569 570
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-frametype-specific-bits: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    hdr->refresh_context = !seqhdr->reduced_still_picture_header &&
571
                           !hdr->disable_cdf_update && !dav1d_get_bits(gb, 1);
572 573 574 575 576 577
#if DEBUG_FRAME_HDR
    printf("HDR: post-refresh_context: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    // tile data
578
    hdr->tiling.uniform = dav1d_get_bits(gb, 1);
579 580
    const int sbsz_min1 = (64 << seqhdr->sb128) - 1;
    int sbsz_log2 = 6 + seqhdr->sb128;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
581
    int sbw = (hdr->width[0] + sbsz_min1) >> sbsz_log2;
582
    int sbh = (hdr->height + sbsz_min1) >> sbsz_log2;
583
    int max_tile_width_sb = 4096 >> sbsz_log2;
584 585
    int max_tile_area_sb = 4096 * 2304 >> (2 * sbsz_log2);
    hdr->tiling.min_log2_cols = tile_log2(max_tile_width_sb, sbw);
586 587
    hdr->tiling.max_log2_cols = tile_log2(1, imin(sbw, DAV1D_MAX_TILE_COLS));
    hdr->tiling.max_log2_rows = tile_log2(1, imin(sbh, DAV1D_MAX_TILE_ROWS));
588 589 590 591
    int min_log2_tiles = imax(tile_log2(max_tile_area_sb, sbw * sbh),
                              hdr->tiling.min_log2_cols);
    if (hdr->tiling.uniform) {
        for (hdr->tiling.log2_cols = hdr->tiling.min_log2_cols;
592
             hdr->tiling.log2_cols < hdr->tiling.max_log2_cols && dav1d_get_bits(gb, 1);
593 594 595 596 597 598 599 600 601
             hdr->tiling.log2_cols++) ;
        const int tile_w = 1 + ((sbw - 1) >> hdr->tiling.log2_cols);
        hdr->tiling.cols = 0;
        for (int sbx = 0; sbx < sbw; sbx += tile_w, hdr->tiling.cols++)
            hdr->tiling.col_start_sb[hdr->tiling.cols] = sbx;
        hdr->tiling.min_log2_rows =
            imax(min_log2_tiles - hdr->tiling.log2_cols, 0);

        for (hdr->tiling.log2_rows = hdr->tiling.min_log2_rows;
602
             hdr->tiling.log2_rows < hdr->tiling.max_log2_rows && dav1d_get_bits(gb, 1);
603 604 605 606 607 608 609 610
             hdr->tiling.log2_rows++) ;
        const int tile_h = 1 + ((sbh - 1) >> hdr->tiling.log2_rows);
        hdr->tiling.rows = 0;
        for (int sby = 0; sby < sbh; sby += tile_h, hdr->tiling.rows++)
            hdr->tiling.row_start_sb[hdr->tiling.rows] = sby;
    } else {
        hdr->tiling.cols = 0;
        int widest_tile = 0, max_tile_area_sb = sbw * sbh;
611
        for (int sbx = 0; sbx < sbw && hdr->tiling.cols < DAV1D_MAX_TILE_COLS; hdr->tiling.cols++) {
612 613 614 615
            const int tile_width_sb = imin(sbw - sbx, max_tile_width_sb);
            const int tile_w = (tile_width_sb > 1) ?
                                   1 + dav1d_get_uniform(gb, tile_width_sb) :
                                   1;
616 617 618 619 620 621
            hdr->tiling.col_start_sb[hdr->tiling.cols] = sbx;
            sbx += tile_w;
            widest_tile = imax(widest_tile, tile_w);
        }
        hdr->tiling.log2_cols = tile_log2(1, hdr->tiling.cols);
        if (min_log2_tiles) max_tile_area_sb >>= min_log2_tiles + 1;
622
        int max_tile_height_sb = imax(max_tile_area_sb / widest_tile, 1);
623 624

        hdr->tiling.rows = 0;
625
        for (int sby = 0; sby < sbh && hdr->tiling.rows < DAV1D_MAX_TILE_ROWS; hdr->tiling.rows++) {
626 627 628 629
            const int tile_height_sb = imin(sbh - sby, max_tile_height_sb);
            const int tile_h = (tile_height_sb > 1) ?
                                   1 + dav1d_get_uniform(gb, tile_height_sb) :
                                   1;
630 631 632 633 634 635 636 637
            hdr->tiling.row_start_sb[hdr->tiling.rows] = sby;
            sby += tile_h;
        }
        hdr->tiling.log2_rows = tile_log2(1, hdr->tiling.rows);
    }
    hdr->tiling.col_start_sb[hdr->tiling.cols] = sbw;
    hdr->tiling.row_start_sb[hdr->tiling.rows] = sbh;
    if (hdr->tiling.log2_cols || hdr->tiling.log2_rows) {
638 639
        hdr->tiling.update = dav1d_get_bits(gb, hdr->tiling.log2_cols +
                                                hdr->tiling.log2_rows);
640 641
        if (hdr->tiling.update >= hdr->tiling.cols * hdr->tiling.rows)
            goto error;
642
        hdr->tiling.n_bytes = dav1d_get_bits(gb, 2) + 1;
643 644 645 646 647 648 649 650 651
    } else {
        hdr->tiling.n_bytes = hdr->tiling.update = 0;
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-tiling: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    // quant data
652 653
    hdr->quant.yac = dav1d_get_bits(gb, 8);
    hdr->quant.ydc_delta = dav1d_get_bits(gb, 1) ? dav1d_get_sbits(gb, 6) : 0;
654
    if (!seqhdr->monochrome) {
655 656 657 658
        // If the sequence header says that delta_q might be different
        // for U, V, we must check whether it actually is for this
        // frame.
        int diff_uv_delta = seqhdr->separate_uv_delta_q ? dav1d_get_bits(gb, 1) : 0;
659 660
        hdr->quant.udc_delta = dav1d_get_bits(gb, 1) ? dav1d_get_sbits(gb, 6) : 0;
        hdr->quant.uac_delta = dav1d_get_bits(gb, 1) ? dav1d_get_sbits(gb, 6) : 0;
661
        if (diff_uv_delta) {
662 663
            hdr->quant.vdc_delta = dav1d_get_bits(gb, 1) ? dav1d_get_sbits(gb, 6) : 0;
            hdr->quant.vac_delta = dav1d_get_bits(gb, 1) ? dav1d_get_sbits(gb, 6) : 0;
664 665 666 667 668 669 670 671 672
        } else {
            hdr->quant.vdc_delta = hdr->quant.udc_delta;
            hdr->quant.vac_delta = hdr->quant.uac_delta;
        }
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-quant: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif
673
    hdr->quant.qm = dav1d_get_bits(gb, 1);
674
    if (hdr->quant.qm) {
675 676
        hdr->quant.qm_y = dav1d_get_bits(gb, 4);
        hdr->quant.qm_u = dav1d_get_bits(gb, 4);
skal's avatar
skal committed
677 678 679
        hdr->quant.qm_v =
            seqhdr->separate_uv_delta_q ? (int)dav1d_get_bits(gb, 4) :
                                          hdr->quant.qm_u;
680 681 682 683 684 685 686
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-qm: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    // segmentation data
687
    hdr->segmentation.enabled = dav1d_get_bits(gb, 1);
688
    if (hdr->segmentation.enabled) {
689
        if (hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
690 691 692 693
            hdr->segmentation.update_map = 1;
            hdr->segmentation.temporal = 0;
            hdr->segmentation.update_data = 1;
        } else {
694
            hdr->segmentation.update_map = dav1d_get_bits(gb, 1);
695
            hdr->segmentation.temporal =
696 697
                hdr->segmentation.update_map ? dav1d_get_bits(gb, 1) : 0;
            hdr->segmentation.update_data = dav1d_get_bits(gb, 1);
698 699 700 701 702
        }

        if (hdr->segmentation.update_data) {
            hdr->segmentation.seg_data.preskip = 0;
            hdr->segmentation.seg_data.last_active_segid = -1;
703
            for (int i = 0; i < DAV1D_MAX_SEGMENTS; i++) {
704
                Dav1dSegmentationData *const seg =
705
                    &hdr->segmentation.seg_data.d[i];
706 707
                if (dav1d_get_bits(gb, 1)) {
                    seg->delta_q = dav1d_get_sbits(gb, 8);
708 709 710 711
                    hdr->segmentation.seg_data.last_active_segid = i;
                } else {
                    seg->delta_q = 0;
                }
712 713
                if (dav1d_get_bits(gb, 1)) {
                    seg->delta_lf_y_v = dav1d_get_sbits(gb, 6);
714 715 716 717
                    hdr->segmentation.seg_data.last_active_segid = i;
                } else {
                    seg->delta_lf_y_v = 0;
                }
718 719
                if (dav1d_get_bits(gb, 1)) {
                    seg->delta_lf_y_h = dav1d_get_sbits(gb, 6);
720 721 722 723
                    hdr->segmentation.seg_data.last_active_segid = i;
                } else {
                    seg->delta_lf_y_h = 0;
                }
724 725
                if (dav1d_get_bits(gb, 1)) {
                    seg->delta_lf_u = dav1d_get_sbits(gb, 6);
726 727 728 729
                    hdr->segmentation.seg_data.last_active_segid = i;
                } else {
                    seg->delta_lf_u = 0;
                }
730 731
                if (dav1d_get_bits(gb, 1)) {
                    seg->delta_lf_v = dav1d_get_sbits(gb, 6);
732 733 734 735
                    hdr->segmentation.seg_data.last_active_segid = i;
                } else {
                    seg->delta_lf_v = 0;
                }
736 737
                if (dav1d_get_bits(gb, 1)) {
                    seg->ref = dav1d_get_bits(gb, 3);
738 739 740 741 742
                    hdr->segmentation.seg_data.last_active_segid = i;
                    hdr->segmentation.seg_data.preskip = 1;
                } else {
                    seg->ref = -1;
                }
743
                if ((seg->skip = dav1d_get_bits(gb, 1))) {
744 745 746
                    hdr->segmentation.seg_data.last_active_segid = i;
                    hdr->segmentation.seg_data.preskip = 1;
                }
747
                if ((seg->globalmv = dav1d_get_bits(gb, 1))) {
748 749 750 751 752
                    hdr->segmentation.seg_data.last_active_segid = i;
                    hdr->segmentation.seg_data.preskip = 1;
                }
            }
        } else {
753 754
            // segmentation.update_data was false so we should copy
            // segmentation data from the reference frame.
755
            assert(hdr->primary_ref_frame != DAV1D_PRIMARY_REF_NONE);
756
            const int pri_ref = hdr->refidx[hdr->primary_ref_frame];
757
            if (!c->refs[pri_ref].p.p.frame_hdr) return -EINVAL;
758 759
            hdr->segmentation.seg_data =
                c->refs[pri_ref].p.p.frame_hdr->segmentation.seg_data;
760
        }
761
    } else {
762
        memset(&hdr->segmentation.seg_data, 0, sizeof(Dav1dSegmentationDataSet));
763
        for (int i = 0; i < DAV1D_MAX_SEGMENTS; i++)
764
            hdr->segmentation.seg_data.d[i].ref = -1;
765 766 767 768 769 770 771
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-segmentation: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    // delta q
772 773
    hdr->delta.q.present = hdr->quant.yac ? dav1d_get_bits(gb, 1) : 0;
    hdr->delta.q.res_log2 = hdr->delta.q.present ? dav1d_get_bits(gb, 2) : 0;
774
    hdr->delta.lf.present = hdr->delta.q.present && !hdr->allow_intrabc &&
775 776 777
                            dav1d_get_bits(gb, 1);
    hdr->delta.lf.res_log2 = hdr->delta.lf.present ? dav1d_get_bits(gb, 2) : 0;
    hdr->delta.lf.multi = hdr->delta.lf.present ? dav1d_get_bits(gb, 1) : 0;
778 779 780 781 782 783 784 785 786
#if DEBUG_FRAME_HDR
    printf("HDR: post-delta_q_lf_flags: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    // derive lossless flags
    const int delta_lossless = !hdr->quant.ydc_delta && !hdr->quant.udc_delta &&
        !hdr->quant.uac_delta && !hdr->quant.vdc_delta && !hdr->quant.vac_delta;
    hdr->all_lossless = 1;
787
    for (int i = 0; i < DAV1D_MAX_SEGMENTS; i++) {
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
        hdr->segmentation.qidx[i] = hdr->segmentation.enabled ?
            iclip_u8(hdr->quant.yac + hdr->segmentation.seg_data.d[i].delta_q) :
            hdr->quant.yac;
        hdr->segmentation.lossless[i] =
            !hdr->segmentation.qidx[i] && delta_lossless;
        hdr->all_lossless &= hdr->segmentation.lossless[i];
    }

    // loopfilter
    if (hdr->all_lossless || hdr->allow_intrabc) {
        hdr->loopfilter.level_y[0] = hdr->loopfilter.level_y[1] = 0;
        hdr->loopfilter.level_u = hdr->loopfilter.level_v = 0;
        hdr->loopfilter.sharpness = 0;
        hdr->loopfilter.mode_ref_delta_enabled = 1;
        hdr->loopfilter.mode_ref_delta_update = 1;
        hdr->loopfilter.mode_ref_deltas = default_mode_ref_deltas;
    } else {
805 806
        hdr->loopfilter.level_y[0] = dav1d_get_bits(gb, 6);
        hdr->loopfilter.level_y[1] = dav1d_get_bits(gb, 6);
807
        if (!seqhdr->monochrome &&
808 809
            (hdr->loopfilter.level_y[0] || hdr->loopfilter.level_y[1]))
        {
810 811
            hdr->loopfilter.level_u = dav1d_get_bits(gb, 6);
            hdr->loopfilter.level_v = dav1d_get_bits(gb, 6);
812
        }
813
        hdr->loopfilter.sharpness = dav1d_get_bits(gb, 3);
814

815
        if (hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
816 817 818
            hdr->loopfilter.mode_ref_deltas = default_mode_ref_deltas;
        } else {
            const int ref = hdr->refidx[hdr->primary_ref_frame];
819
            if (!c->refs[ref].p.p.frame_hdr) return -EINVAL;
820 821
            hdr->loopfilter.mode_ref_deltas =
                c->refs[ref].p.p.frame_hdr->loopfilter.mode_ref_deltas;
822
        }
823
        hdr->loopfilter.mode_ref_delta_enabled = dav1d_get_bits(gb, 1);
824
        if (hdr->loopfilter.mode_ref_delta_enabled) {
825
            hdr->loopfilter.mode_ref_delta_update = dav1d_get_bits(gb, 1);
826 827
            if (hdr->loopfilter.mode_ref_delta_update) {
                for (int i = 0; i < 8; i++)
828
                    if (dav1d_get_bits(gb, 1))
829
                        hdr->loopfilter.mode_ref_deltas.ref_delta[i] =
830
                            dav1d_get_sbits(gb, 6);
831
                for (int i = 0; i < 2; i++)
832
                    if (dav1d_get_bits(gb, 1))
833
                        hdr->loopfilter.mode_ref_deltas.mode_delta[i] =
834
                            dav1d_get_sbits(gb, 6);
835 836 837 838 839 840 841 842 843 844
            }
        }
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-lpf: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    // cdef
    if (!hdr->all_lossless && seqhdr->cdef && !hdr->allow_intrabc) {
845 846
        hdr->cdef.damping = dav1d_get_bits(gb, 2) + 3;
        hdr->cdef.n_bits = dav1d_get_bits(gb, 2);
847
        for (int i = 0; i < (1 << hdr->cdef.n_bits); i++) {
848
            hdr->cdef.y_strength[i] = dav1d_get_bits(gb, 6);
849
            if (!seqhdr->monochrome)
850
                hdr->cdef.uv_strength[i] = dav1d_get_bits(gb, 6);
851 852 853 854 855 856 857 858 859 860 861 862
        }
    } else {
        hdr->cdef.n_bits = 0;
        hdr->cdef.y_strength[0] = 0;
        hdr->cdef.uv_strength[0] = 0;
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-cdef: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    // restoration
Ronald S. Bultje's avatar
Ronald S. Bultje committed
863 864 865
    if ((!hdr->all_lossless || hdr->super_res.enabled) &&
        seqhdr->restoration && !hdr->allow_intrabc)
    {
866
        hdr->restoration.type[0] = dav1d_get_bits(gb, 2);
867
        if (!seqhdr->monochrome) {
868 869
            hdr->restoration.type[1] = dav1d_get_bits(gb, 2);
            hdr->restoration.type[2] = dav1d_get_bits(gb, 2);
870 871
        } else {
            hdr->restoration.type[1] =
872
            hdr->restoration.type[2] = DAV1D_RESTORATION_NONE;
873 874 875 876 877 878 879
        }

        if (hdr->restoration.type[0] || hdr->restoration.type[1] ||
            hdr->restoration.type[2])
        {
            // Log2 of the restoration unit size.
            hdr->restoration.unit_size[0] = 6 + seqhdr->sb128;
880
            if (dav1d_get_bits(gb, 1)) {
881 882
                hdr->restoration.unit_size[0]++;
                if (!seqhdr->sb128)
883
                    hdr->restoration.unit_size[0] += dav1d_get_bits(gb, 1);
884 885 886
            }
            hdr->restoration.unit_size[1] = hdr->restoration.unit_size[0];
            if ((hdr->restoration.type[1] || hdr->restoration.type[2]) &&
887
                seqhdr->ss_hor == 1 && seqhdr->ss_ver == 1)
888
            {
889
                hdr->restoration.unit_size[1] -= dav1d_get_bits(gb, 1);
890 891 892 893 894
            }
        } else {
            hdr->restoration.unit_size[0] = 8;
        }
    } else {
895 896 897
        hdr->restoration.type[0] = DAV1D_RESTORATION_NONE;
        hdr->restoration.type[1] = DAV1D_RESTORATION_NONE;
        hdr->restoration.type[2] = DAV1D_RESTORATION_NONE;
898 899 900 901 902 903
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-restoration: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

904 905
    hdr->txfm_mode = hdr->all_lossless ? DAV1D_TX_4X4_ONLY :
                     dav1d_get_bits(gb, 1) ? DAV1D_TX_SWITCHABLE : DAV1D_TX_LARGEST;
906 907 908 909
#if DEBUG_FRAME_HDR
    printf("HDR: post-txfmmode: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif
910
    hdr->switchable_comp_refs = hdr->frame_type & 1 ? dav1d_get_bits(gb, 1) : 0;
911 912 913 914 915
#if DEBUG_FRAME_HDR
    printf("HDR: post-refmode: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif
    hdr->skip_mode_allowed = 0;
916
    if (hdr->switchable_comp_refs && hdr->frame_type & 1 && seqhdr->order_hint) {
917 918 919 920
        const unsigned poc = hdr->frame_offset;
        unsigned off_before[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
        int off_after = -1;
        int off_before_idx[2], off_after_idx;
921
        off_before_idx[0] = 0;
922
        for (int i = 0; i < 7; i++) {
923
            if (!c->refs[hdr->refidx[i]].p.p.data[0]) return -EINVAL;
924
            const unsigned refpoc = c->refs[hdr->refidx[i]].p.p.frame_hdr->frame_offset;
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954

            const int diff = get_poc_diff(seqhdr->order_hint_n_bits, refpoc, poc);
            if (diff > 0) {
                if (off_after == -1 || get_poc_diff(seqhdr->order_hint_n_bits,
                                                    off_after, refpoc) > 0)
                {
                    off_after = refpoc;
                    off_after_idx = i;
                }
            } else if (diff < 0) {
                if (off_before[0] == 0xFFFFFFFFU ||
                    get_poc_diff(seqhdr->order_hint_n_bits,
                                 refpoc, off_before[0]) > 0)
                {
                    off_before[1] = off_before[0];
                    off_before[0] = refpoc;
                    off_before_idx[1] = off_before_idx[0];
                    off_before_idx[0] = i;
                } else if (refpoc != off_before[0] &&
                           (off_before[1] == 0xFFFFFFFFU ||
                            get_poc_diff(seqhdr->order_hint_n_bits,
                                         refpoc, off_before[1]) > 0))
                {
                    off_before[1] = refpoc;
                    off_before_idx[1] = i;
                }
            }
        }

        if (off_before[0] != 0xFFFFFFFFU && off_after != -1) {
955 956
            hdr->skip_mode_refs[0] = imin(off_before_idx[0], off_after_idx);
            hdr->skip_mode_refs[1] = imax(off_before_idx[0], off_after_idx);
957 958 959 960
            hdr->skip_mode_allowed = 1;
        } else if (off_before[0] != 0xFFFFFFFFU &&
                   off_before[1] != 0xFFFFFFFFU)
        {
961 962
            hdr->skip_mode_refs[0] = imin(off_before_idx[0], off_before_idx[1]);
            hdr->skip_mode_refs[1] = imax(off_before_idx[0], off_before_idx[1]);
963 964 965
            hdr->skip_mode_allowed = 1;
        }
    }
966
    hdr->skip_mode_enabled = hdr->skip_mode_allowed ? dav1d_get_bits(gb, 1) : 0;
967 968 969 970 971
#if DEBUG_FRAME_HDR
    printf("HDR: post-extskip: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif
    hdr->warp_motion = !hdr->error_resilient_mode && hdr->frame_type & 1 &&
972
        seqhdr->warped_motion && dav1d_get_bits(gb, 1);
973 974 975 976
#if DEBUG_FRAME_HDR
    printf("HDR: post-warpmotionbit: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif
977
    hdr->reduced_txtp_set = dav1d_get_bits(gb, 1);
978 979 980 981 982 983
#if DEBUG_FRAME_HDR
    printf("HDR: post-reducedtxtpset: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

    for (int i = 0; i < 7; i++)
984
        hdr->gmv[i] = dav1d_default_wm_params;
985 986 987

    if (hdr->frame_type & 1) {
        for (int i = 0; i < 7; i++) {
988 989 990 991
            hdr->gmv[i].type = !dav1d_get_bits(gb, 1) ? DAV1D_WM_TYPE_IDENTITY :
                                dav1d_get_bits(gb, 1) ? DAV1D_WM_TYPE_ROT_ZOOM :
                                dav1d_get_bits(gb, 1) ? DAV1D_WM_TYPE_TRANSLATION :
                                                  DAV1D_WM_TYPE_AFFINE;
992

993
            if (hdr->gmv[i].type == DAV1D_WM_TYPE_IDENTITY) continue;
994

995 996 997 998 999 1000 1001 1002
            const Dav1dWarpedMotionParams *ref_gmv;
            if (hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
                ref_gmv = &dav1d_default_wm_params;
            } else {
                const int pri_ref = hdr->refidx[hdr->primary_ref_frame];
                if (!c->refs[pri_ref].p.p.frame_hdr) return -EINVAL;
                ref_gmv = &c->refs[pri_ref].p.p.frame_hdr->gmv[i];
            }
1003 1004 1005 1006
            int32_t *const mat = hdr->gmv[i].matrix;
            const int32_t *const ref_mat = ref_gmv->matrix;
            int bits, shift;

1007
            if (hdr->gmv[i].type >= DAV1D_WM_TYPE_ROT_ZOOM) {
1008
                mat[2] = (1 << 16) + 2 *
1009 1010
                    dav1d_get_bits_subexp(gb, (ref_mat[2] - (1 << 16)) >> 1, 12);
                mat[3] = 2 * dav1d_get_bits_subexp(gb, ref_mat[3] >> 1, 12);
1011 1012 1013 1014 1015 1016 1017 1018

                bits = 12;
                shift = 10;
            } else {
                bits = 9 - !hdr->hp;
                shift = 13 + !hdr->hp;
            }

1019
            if (hdr->gmv[i].type == DAV1D_WM_TYPE_AFFINE) {
1020
                mat[4] = 2 * dav1d_get_bits_subexp(gb, ref_mat[4] >> 1, 12);
1021
                mat[5] = (1 << 16) + 2 *
1022
                    dav1d_get_bits_subexp(gb, (ref_mat[5] - (1 << 16)) >> 1, 12);
1023 1024 1025 1026 1027
            } else {
                mat[4] = -mat[3];
                mat[5] = mat[2];
            }

1028 1029
            mat[0] = dav1d_get_bits_subexp(gb, ref_mat[0] >> shift, bits) * (1 << shift);
            mat[1] = dav1d_get_bits_subexp(gb, ref_mat[1] >> shift, bits) * (1 << shift);
1030 1031 1032 1033 1034 1035 1036
        }
    }
#if DEBUG_FRAME_HDR
    printf("HDR: post-gmv: off=%ld\n",
           (gb->ptr - init_ptr) * 8 - gb->bits_left);
#endif

1037 1038
    hdr->film_grain.present = seqhdr->film_grain_present &&
                              (hdr->show_frame || hdr->showable_frame) &&
1039
                              dav1d_get_bits(gb, 1);
1040
    if (hdr->film_grain.present) {
1041
        const unsigned seed = dav1d_get_bits(gb, 16);
1042
        hdr->film_grain.update = hdr->frame_type != DAV1D_FRAME_TYPE_INTER || dav1d_get_bits(gb, 1);
1043
        if (!hdr->film_grain.update) {
1044
            const int refidx = dav1d_get_bits(gb, 3);
1045 1046 1047 1048
            int i;
            for (i = 0; i < 7; i++)
                if (hdr->refidx[i] == refidx)
                    break;
1049
            if (i == 7 || !c->refs[refidx].p.p.frame_hdr)  goto error;
1050
            hdr->film_grain.data = c->refs[refidx].p.p.frame_hdr->film_grain.data;
1051
            hdr->film_grain.data.seed = seed;
1052
        } else {
1053 1054
            Dav1dFilmGrainData *const fgd = &hdr->film_grain.data;
            fgd->seed = seed;
1055

1056
            fgd->num_y_points = dav1d_get_bits(gb, 4);
1057 1058
            if (fgd->num_y_points > 14) goto error;
            for (int i = 0; i < fgd->num_y_points; i++) {
1059
                fgd->y_points[i][0] = dav1d_get_bits(gb, 8);
1060 1061
                if (i && fgd->y_points[i - 1][0] >= fgd->y_points[i][0])
                    goto error;
1062
                fgd->y_points[i][1] = dav1d_get_bits(gb, 8);
1063 1064 1065
            }

            fgd->chroma_scaling_from_luma =
1066 1067 1068
                !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))
1069 1070 1071
            {
                fgd->num_uv_points[0] = fgd->num_uv_points[1] = 0;
            } else for (int pl = 0; pl < 2; pl++) {
1072
                fgd->num_uv_points[pl] = dav1d_get_bits(gb, 4);
1073 1074
                if (fgd->num_uv_points[pl] > 10) goto error;
                for (int i = 0; i < fgd->num_uv_points[pl]; i++) {
1075
                    fgd->uv_points[pl][