tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

obu.c (72426B)


      1 /*
      2 * Copyright © 2018-2021, VideoLAN and dav1d authors
      3 * Copyright © 2018, Two Orioles, LLC
      4 * All rights reserved.
      5 *
      6 * Redistribution and use in source and binary forms, with or without
      7 * modification, are permitted provided that the following conditions are met:
      8 *
      9 * 1. Redistributions of source code must retain the above copyright notice, this
     10 *    list of conditions and the following disclaimer.
     11 *
     12 * 2. Redistributions in binary form must reproduce the above copyright notice,
     13 *    this list of conditions and the following disclaimer in the documentation
     14 *    and/or other materials provided with the distribution.
     15 *
     16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 */
     27 
     28 #include "config.h"
     29 
     30 #include <errno.h>
     31 #include <limits.h>
     32 #include <stdio.h>
     33 
     34 #include "dav1d/data.h"
     35 
     36 #include "common/frame.h"
     37 #include "common/intops.h"
     38 #include "common/validate.h"
     39 
     40 #include "src/decode.h"
     41 #include "src/getbits.h"
     42 #include "src/levels.h"
     43 #include "src/log.h"
     44 #include "src/obu.h"
     45 #include "src/ref.h"
     46 #include "src/thread_task.h"
     47 
     48 static int check_trailing_bits(GetBits *const gb,
     49                               const int strict_std_compliance)
     50 {
     51    const int trailing_one_bit = dav1d_get_bit(gb);
     52 
     53    if (gb->error)
     54        return DAV1D_ERR(EINVAL);
     55 
     56    if (!strict_std_compliance)
     57        return 0;
     58 
     59    if (!trailing_one_bit || gb->state)
     60        return DAV1D_ERR(EINVAL);
     61 
     62    ptrdiff_t size = gb->ptr_end - gb->ptr;
     63    while (size > 0 && gb->ptr[size - 1] == 0)
     64        size--;
     65 
     66    if (size)
     67        return DAV1D_ERR(EINVAL);
     68 
     69    return 0;
     70 }
     71 
     72 static NOINLINE int parse_seq_hdr(Dav1dSequenceHeader *const hdr,
     73                                  GetBits *const gb,
     74                                  const int strict_std_compliance)
     75 {
     76 #define DEBUG_SEQ_HDR 0
     77 
     78 #if DEBUG_SEQ_HDR
     79    const unsigned init_bit_pos = dav1d_get_bits_pos(gb);
     80 #endif
     81 
     82    memset(hdr, 0, sizeof(*hdr));
     83    hdr->profile = dav1d_get_bits(gb, 3);
     84    if (hdr->profile > 2) goto error;
     85 #if DEBUG_SEQ_HDR
     86    printf("SEQHDR: post-profile: off=%u\n",
     87           dav1d_get_bits_pos(gb) - init_bit_pos);
     88 #endif
     89 
     90    hdr->still_picture = dav1d_get_bit(gb);
     91    hdr->reduced_still_picture_header = dav1d_get_bit(gb);
     92    if (hdr->reduced_still_picture_header && !hdr->still_picture) goto error;
     93 #if DEBUG_SEQ_HDR
     94    printf("SEQHDR: post-stillpicture_flags: off=%u\n",
     95           dav1d_get_bits_pos(gb) - init_bit_pos);
     96 #endif
     97 
     98    if (hdr->reduced_still_picture_header) {
     99        hdr->num_operating_points = 1;
    100        hdr->operating_points[0].major_level = dav1d_get_bits(gb, 3);
    101        hdr->operating_points[0].minor_level = dav1d_get_bits(gb, 2);
    102        hdr->operating_points[0].initial_display_delay = 10;
    103    } else {
    104        hdr->timing_info_present = dav1d_get_bit(gb);
    105        if (hdr->timing_info_present) {
    106            hdr->num_units_in_tick = dav1d_get_bits(gb, 32);
    107            hdr->time_scale = dav1d_get_bits(gb, 32);
    108            if (strict_std_compliance && (!hdr->num_units_in_tick || !hdr->time_scale))
    109                goto error;
    110            hdr->equal_picture_interval = dav1d_get_bit(gb);
    111            if (hdr->equal_picture_interval) {
    112                const unsigned num_ticks_per_picture = dav1d_get_vlc(gb);
    113                if (num_ticks_per_picture == UINT32_MAX)
    114                    goto error;
    115                hdr->num_ticks_per_picture = num_ticks_per_picture + 1;
    116            }
    117 
    118            hdr->decoder_model_info_present = dav1d_get_bit(gb);
    119            if (hdr->decoder_model_info_present) {
    120                hdr->encoder_decoder_buffer_delay_length = dav1d_get_bits(gb, 5) + 1;
    121                hdr->num_units_in_decoding_tick = dav1d_get_bits(gb, 32);
    122                if (strict_std_compliance && !hdr->num_units_in_decoding_tick)
    123                    goto error;
    124                hdr->buffer_removal_delay_length = dav1d_get_bits(gb, 5) + 1;
    125                hdr->frame_presentation_delay_length = dav1d_get_bits(gb, 5) + 1;
    126            }
    127        }
    128 #if DEBUG_SEQ_HDR
    129        printf("SEQHDR: post-timinginfo: off=%u\n",
    130               dav1d_get_bits_pos(gb) - init_bit_pos);
    131 #endif
    132 
    133        hdr->display_model_info_present = dav1d_get_bit(gb);
    134        hdr->num_operating_points = dav1d_get_bits(gb, 5) + 1;
    135        for (int i = 0; i < hdr->num_operating_points; i++) {
    136            struct Dav1dSequenceHeaderOperatingPoint *const op =
    137                &hdr->operating_points[i];
    138            op->idc = dav1d_get_bits(gb, 12);
    139            if (op->idc && (!(op->idc & 0xff) || !(op->idc & 0xf00)))
    140                goto error;
    141            op->major_level = 2 + dav1d_get_bits(gb, 3);
    142            op->minor_level = dav1d_get_bits(gb, 2);
    143            if (op->major_level > 3)
    144                op->tier = dav1d_get_bit(gb);
    145            if (hdr->decoder_model_info_present) {
    146                op->decoder_model_param_present = dav1d_get_bit(gb);
    147                if (op->decoder_model_param_present) {
    148                    struct Dav1dSequenceHeaderOperatingParameterInfo *const opi =
    149                        &hdr->operating_parameter_info[i];
    150                    opi->decoder_buffer_delay =
    151                        dav1d_get_bits(gb, hdr->encoder_decoder_buffer_delay_length);
    152                    opi->encoder_buffer_delay =
    153                        dav1d_get_bits(gb, hdr->encoder_decoder_buffer_delay_length);
    154                    opi->low_delay_mode = dav1d_get_bit(gb);
    155                }
    156            }
    157            if (hdr->display_model_info_present)
    158                op->display_model_param_present = dav1d_get_bit(gb);
    159            op->initial_display_delay =
    160                op->display_model_param_present ? dav1d_get_bits(gb, 4) + 1 : 10;
    161        }
    162 #if DEBUG_SEQ_HDR
    163        printf("SEQHDR: post-operating-points: off=%u\n",
    164               dav1d_get_bits_pos(gb) - init_bit_pos);
    165 #endif
    166    }
    167 
    168    hdr->width_n_bits = dav1d_get_bits(gb, 4) + 1;
    169    hdr->height_n_bits = dav1d_get_bits(gb, 4) + 1;
    170    hdr->max_width = dav1d_get_bits(gb, hdr->width_n_bits) + 1;
    171    hdr->max_height = dav1d_get_bits(gb, hdr->height_n_bits) + 1;
    172 #if DEBUG_SEQ_HDR
    173    printf("SEQHDR: post-size: off=%u\n",
    174           dav1d_get_bits_pos(gb) - init_bit_pos);
    175 #endif
    176    if (!hdr->reduced_still_picture_header) {
    177        hdr->frame_id_numbers_present = dav1d_get_bit(gb);
    178        if (hdr->frame_id_numbers_present) {
    179            hdr->delta_frame_id_n_bits = dav1d_get_bits(gb, 4) + 2;
    180            hdr->frame_id_n_bits = dav1d_get_bits(gb, 3) + hdr->delta_frame_id_n_bits + 1;
    181        }
    182    }
    183 #if DEBUG_SEQ_HDR
    184    printf("SEQHDR: post-frame-id-numbers-present: off=%u\n",
    185           dav1d_get_bits_pos(gb) - init_bit_pos);
    186 #endif
    187 
    188    hdr->sb128 = dav1d_get_bit(gb);
    189    hdr->filter_intra = dav1d_get_bit(gb);
    190    hdr->intra_edge_filter = dav1d_get_bit(gb);
    191    if (hdr->reduced_still_picture_header) {
    192        hdr->screen_content_tools = DAV1D_ADAPTIVE;
    193        hdr->force_integer_mv = DAV1D_ADAPTIVE;
    194    } else {
    195        hdr->inter_intra = dav1d_get_bit(gb);
    196        hdr->masked_compound = dav1d_get_bit(gb);
    197        hdr->warped_motion = dav1d_get_bit(gb);
    198        hdr->dual_filter = dav1d_get_bit(gb);
    199        hdr->order_hint = dav1d_get_bit(gb);
    200        if (hdr->order_hint) {
    201            hdr->jnt_comp = dav1d_get_bit(gb);
    202            hdr->ref_frame_mvs = dav1d_get_bit(gb);
    203        }
    204        hdr->screen_content_tools = dav1d_get_bit(gb) ? DAV1D_ADAPTIVE : dav1d_get_bit(gb);
    205    #if DEBUG_SEQ_HDR
    206        printf("SEQHDR: post-screentools: off=%u\n",
    207               dav1d_get_bits_pos(gb) - init_bit_pos);
    208    #endif
    209        hdr->force_integer_mv = hdr->screen_content_tools ?
    210                                dav1d_get_bit(gb) ? DAV1D_ADAPTIVE : dav1d_get_bit(gb) : 2;
    211        if (hdr->order_hint)
    212            hdr->order_hint_n_bits = dav1d_get_bits(gb, 3) + 1;
    213    }
    214    hdr->super_res = dav1d_get_bit(gb);
    215    hdr->cdef = dav1d_get_bit(gb);
    216    hdr->restoration = dav1d_get_bit(gb);
    217 #if DEBUG_SEQ_HDR
    218    printf("SEQHDR: post-featurebits: off=%u\n",
    219           dav1d_get_bits_pos(gb) - init_bit_pos);
    220 #endif
    221 
    222    hdr->hbd = dav1d_get_bit(gb);
    223    if (hdr->profile == 2 && hdr->hbd)
    224        hdr->hbd += dav1d_get_bit(gb);
    225    if (hdr->profile != 1)
    226        hdr->monochrome = dav1d_get_bit(gb);
    227    hdr->color_description_present = dav1d_get_bit(gb);
    228    if (hdr->color_description_present) {
    229        hdr->pri = dav1d_get_bits(gb, 8);
    230        hdr->trc = dav1d_get_bits(gb, 8);
    231        hdr->mtrx = dav1d_get_bits(gb, 8);
    232    } else {
    233        hdr->pri = DAV1D_COLOR_PRI_UNKNOWN;
    234        hdr->trc = DAV1D_TRC_UNKNOWN;
    235        hdr->mtrx = DAV1D_MC_UNKNOWN;
    236    }
    237    if (hdr->monochrome) {
    238        hdr->color_range = dav1d_get_bit(gb);
    239        hdr->layout = DAV1D_PIXEL_LAYOUT_I400;
    240        hdr->ss_hor = hdr->ss_ver = 1;
    241        hdr->chr = DAV1D_CHR_UNKNOWN;
    242    } else if (hdr->pri == DAV1D_COLOR_PRI_BT709 &&
    243               hdr->trc == DAV1D_TRC_SRGB &&
    244               hdr->mtrx == DAV1D_MC_IDENTITY)
    245    {
    246        hdr->layout = DAV1D_PIXEL_LAYOUT_I444;
    247        hdr->color_range = 1;
    248        if (hdr->profile != 1 && !(hdr->profile == 2 && hdr->hbd == 2))
    249            goto error;
    250    } else {
    251        hdr->color_range = dav1d_get_bit(gb);
    252        switch (hdr->profile) {
    253        case 0: hdr->layout = DAV1D_PIXEL_LAYOUT_I420;
    254                hdr->ss_hor = hdr->ss_ver = 1;
    255                break;
    256        case 1: hdr->layout = DAV1D_PIXEL_LAYOUT_I444;
    257                break;
    258        case 2:
    259            if (hdr->hbd == 2) {
    260                hdr->ss_hor = dav1d_get_bit(gb);
    261                if (hdr->ss_hor)
    262                    hdr->ss_ver = dav1d_get_bit(gb);
    263            } else
    264                hdr->ss_hor = 1;
    265            hdr->layout = hdr->ss_hor ?
    266                          hdr->ss_ver ? DAV1D_PIXEL_LAYOUT_I420 :
    267                                        DAV1D_PIXEL_LAYOUT_I422 :
    268                                        DAV1D_PIXEL_LAYOUT_I444;
    269            break;
    270        }
    271        hdr->chr = (hdr->ss_hor & hdr->ss_ver) ?
    272                   dav1d_get_bits(gb, 2) : DAV1D_CHR_UNKNOWN;
    273    }
    274    if (strict_std_compliance &&
    275        hdr->mtrx == DAV1D_MC_IDENTITY && hdr->layout != DAV1D_PIXEL_LAYOUT_I444)
    276    {
    277        goto error;
    278    }
    279    if (!hdr->monochrome)
    280        hdr->separate_uv_delta_q = dav1d_get_bit(gb);
    281 #if DEBUG_SEQ_HDR
    282    printf("SEQHDR: post-colorinfo: off=%u\n",
    283           dav1d_get_bits_pos(gb) - init_bit_pos);
    284 #endif
    285 
    286    hdr->film_grain_present = dav1d_get_bit(gb);
    287 #if DEBUG_SEQ_HDR
    288    printf("SEQHDR: post-filmgrain: off=%u\n",
    289           dav1d_get_bits_pos(gb) - init_bit_pos);
    290 #endif
    291 
    292    // We needn't bother flushing the OBU here: we'll check we didn't
    293    // overrun in the caller and will then discard gb, so there's no
    294    // point in setting its position properly.
    295 
    296    return check_trailing_bits(gb, strict_std_compliance);
    297 
    298 error:
    299    return DAV1D_ERR(EINVAL);
    300 }
    301 
    302 int dav1d_parse_sequence_header(Dav1dSequenceHeader *const out,
    303                                const uint8_t *const ptr, const size_t sz)
    304 {
    305    validate_input_or_ret(out != NULL, DAV1D_ERR(EINVAL));
    306    validate_input_or_ret(ptr != NULL, DAV1D_ERR(EINVAL));
    307    validate_input_or_ret(sz > 0 && sz <= SIZE_MAX / 2, DAV1D_ERR(EINVAL));
    308 
    309    GetBits gb;
    310    dav1d_init_get_bits(&gb, ptr, sz);
    311    int res = DAV1D_ERR(ENOENT);
    312 
    313    do {
    314        dav1d_get_bit(&gb); // obu_forbidden_bit
    315        const enum Dav1dObuType type = dav1d_get_bits(&gb, 4);
    316        const int has_extension = dav1d_get_bit(&gb);
    317        const int has_length_field = dav1d_get_bit(&gb);
    318        dav1d_get_bits(&gb, 1 + 8 * has_extension); // ignore
    319 
    320        const uint8_t *obu_end = gb.ptr_end;
    321        if (has_length_field) {
    322            const size_t len = dav1d_get_uleb128(&gb);
    323            if (len > (size_t)(obu_end - gb.ptr)) return DAV1D_ERR(EINVAL);
    324            obu_end = gb.ptr + len;
    325        }
    326 
    327        if (type == DAV1D_OBU_SEQ_HDR) {
    328            if ((res = parse_seq_hdr(out, &gb, 0)) < 0) return res;
    329            if (gb.ptr > obu_end) return DAV1D_ERR(EINVAL);
    330            dav1d_bytealign_get_bits(&gb);
    331        }
    332 
    333        if (gb.error) return DAV1D_ERR(EINVAL);
    334        assert(gb.state == 0 && gb.bits_left == 0);
    335        gb.ptr = obu_end;
    336    } while (gb.ptr < gb.ptr_end);
    337 
    338    return res;
    339 }
    340 
    341 static int read_frame_size(Dav1dContext *const c, GetBits *const gb,
    342                           const int use_ref)
    343 {
    344    const Dav1dSequenceHeader *const seqhdr = c->seq_hdr;
    345    Dav1dFrameHeader *const hdr = c->frame_hdr;
    346 
    347    if (use_ref) {
    348        for (int i = 0; i < 7; i++) {
    349            if (dav1d_get_bit(gb)) {
    350                const Dav1dThreadPicture *const ref =
    351                    &c->refs[c->frame_hdr->refidx[i]].p;
    352                if (!ref->p.frame_hdr) return -1;
    353                hdr->width[1] = ref->p.frame_hdr->width[1];
    354                hdr->height = ref->p.frame_hdr->height;
    355                hdr->render_width = ref->p.frame_hdr->render_width;
    356                hdr->render_height = ref->p.frame_hdr->render_height;
    357                hdr->super_res.enabled = seqhdr->super_res && dav1d_get_bit(gb);
    358                if (hdr->super_res.enabled) {
    359                    const int d = hdr->super_res.width_scale_denominator =
    360                        9 + dav1d_get_bits(gb, 3);
    361                    hdr->width[0] = imax((hdr->width[1] * 8 + (d >> 1)) / d,
    362                                         imin(16, hdr->width[1]));
    363                } else {
    364                    hdr->super_res.width_scale_denominator = 8;
    365                    hdr->width[0] = hdr->width[1];
    366                }
    367                return 0;
    368            }
    369        }
    370    }
    371 
    372    if (hdr->frame_size_override) {
    373        hdr->width[1] = dav1d_get_bits(gb, seqhdr->width_n_bits) + 1;
    374        hdr->height = dav1d_get_bits(gb, seqhdr->height_n_bits) + 1;
    375    } else {
    376        hdr->width[1] = seqhdr->max_width;
    377        hdr->height = seqhdr->max_height;
    378    }
    379    hdr->super_res.enabled = seqhdr->super_res && dav1d_get_bit(gb);
    380    if (hdr->super_res.enabled) {
    381        const int d = hdr->super_res.width_scale_denominator = 9 + dav1d_get_bits(gb, 3);
    382        hdr->width[0] = imax((hdr->width[1] * 8 + (d >> 1)) / d, imin(16, hdr->width[1]));
    383    } else {
    384        hdr->super_res.width_scale_denominator = 8;
    385        hdr->width[0] = hdr->width[1];
    386    }
    387    hdr->have_render_size = dav1d_get_bit(gb);
    388    if (hdr->have_render_size) {
    389        hdr->render_width = dav1d_get_bits(gb, 16) + 1;
    390        hdr->render_height = dav1d_get_bits(gb, 16) + 1;
    391    } else {
    392        hdr->render_width = hdr->width[1];
    393        hdr->render_height = hdr->height;
    394    }
    395    return 0;
    396 }
    397 
    398 static inline int tile_log2(const int sz, const int tgt) {
    399    int k;
    400    for (k = 0; (sz << k) < tgt; k++) ;
    401    return k;
    402 }
    403 
    404 static const Dav1dLoopfilterModeRefDeltas default_mode_ref_deltas = {
    405    .mode_delta = { 0, 0 },
    406    .ref_delta = { 1, 0, 0, 0, -1, 0, -1, -1 },
    407 };
    408 
    409 static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb) {
    410 #define DEBUG_FRAME_HDR 0
    411 
    412 #if DEBUG_FRAME_HDR
    413    const uint8_t *const init_ptr = gb->ptr;
    414 #endif
    415    const Dav1dSequenceHeader *const seqhdr = c->seq_hdr;
    416    Dav1dFrameHeader *const hdr = c->frame_hdr;
    417 
    418    if (!seqhdr->reduced_still_picture_header)
    419        hdr->show_existing_frame = dav1d_get_bit(gb);
    420 #if DEBUG_FRAME_HDR
    421    printf("HDR: post-show_existing_frame: off=%td\n",
    422           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    423 #endif
    424    if (hdr->show_existing_frame) {
    425        hdr->existing_frame_idx = dav1d_get_bits(gb, 3);
    426        if (seqhdr->decoder_model_info_present && !seqhdr->equal_picture_interval)
    427            hdr->frame_presentation_delay = dav1d_get_bits(gb, seqhdr->frame_presentation_delay_length);
    428        if (seqhdr->frame_id_numbers_present) {
    429            hdr->frame_id = dav1d_get_bits(gb, seqhdr->frame_id_n_bits);
    430            Dav1dFrameHeader *const ref_frame_hdr = c->refs[hdr->existing_frame_idx].p.p.frame_hdr;
    431            if (!ref_frame_hdr || ref_frame_hdr->frame_id != hdr->frame_id) goto error;
    432        }
    433        return 0;
    434    }
    435 
    436    if (seqhdr->reduced_still_picture_header) {
    437        hdr->frame_type = DAV1D_FRAME_TYPE_KEY;
    438        hdr->show_frame = 1;
    439    } else {
    440        hdr->frame_type = dav1d_get_bits(gb, 2);
    441        hdr->show_frame = dav1d_get_bit(gb);
    442    }
    443    if (hdr->show_frame) {
    444        if (seqhdr->decoder_model_info_present && !seqhdr->equal_picture_interval)
    445            hdr->frame_presentation_delay = dav1d_get_bits(gb, seqhdr->frame_presentation_delay_length);
    446        hdr->showable_frame = hdr->frame_type != DAV1D_FRAME_TYPE_KEY;
    447    } else
    448        hdr->showable_frame = dav1d_get_bit(gb);
    449    hdr->error_resilient_mode =
    450        (hdr->frame_type == DAV1D_FRAME_TYPE_KEY && hdr->show_frame) ||
    451        hdr->frame_type == DAV1D_FRAME_TYPE_SWITCH ||
    452        seqhdr->reduced_still_picture_header || dav1d_get_bit(gb);
    453 #if DEBUG_FRAME_HDR
    454    printf("HDR: post-frametype_bits: off=%td\n",
    455           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    456 #endif
    457    hdr->disable_cdf_update = dav1d_get_bit(gb);
    458    hdr->allow_screen_content_tools = seqhdr->screen_content_tools == DAV1D_ADAPTIVE ?
    459                                      dav1d_get_bit(gb) : seqhdr->screen_content_tools;
    460    if (hdr->allow_screen_content_tools)
    461        hdr->force_integer_mv = seqhdr->force_integer_mv == DAV1D_ADAPTIVE ?
    462                                dav1d_get_bit(gb) : seqhdr->force_integer_mv;
    463 
    464    if (IS_KEY_OR_INTRA(hdr))
    465        hdr->force_integer_mv = 1;
    466 
    467    if (seqhdr->frame_id_numbers_present)
    468        hdr->frame_id = dav1d_get_bits(gb, seqhdr->frame_id_n_bits);
    469 
    470    if (!seqhdr->reduced_still_picture_header)
    471        hdr->frame_size_override = hdr->frame_type == DAV1D_FRAME_TYPE_SWITCH ? 1 : dav1d_get_bit(gb);
    472 #if DEBUG_FRAME_HDR
    473    printf("HDR: post-frame_size_override_flag: off=%td\n",
    474           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    475 #endif
    476    if (seqhdr->order_hint)
    477        hdr->frame_offset = dav1d_get_bits(gb, seqhdr->order_hint_n_bits);
    478    hdr->primary_ref_frame = !hdr->error_resilient_mode && IS_INTER_OR_SWITCH(hdr) ?
    479                             dav1d_get_bits(gb, 3) : DAV1D_PRIMARY_REF_NONE;
    480 
    481    if (seqhdr->decoder_model_info_present) {
    482        hdr->buffer_removal_time_present = dav1d_get_bit(gb);
    483        if (hdr->buffer_removal_time_present) {
    484            for (int i = 0; i < c->seq_hdr->num_operating_points; i++) {
    485                const struct Dav1dSequenceHeaderOperatingPoint *const seqop = &seqhdr->operating_points[i];
    486                struct Dav1dFrameHeaderOperatingPoint *const op = &hdr->operating_points[i];
    487                if (seqop->decoder_model_param_present) {
    488                    int in_temporal_layer = (seqop->idc >> hdr->temporal_id) & 1;
    489                    int in_spatial_layer  = (seqop->idc >> (hdr->spatial_id + 8)) & 1;
    490                    if (!seqop->idc || (in_temporal_layer && in_spatial_layer))
    491                        op->buffer_removal_time = dav1d_get_bits(gb, seqhdr->buffer_removal_delay_length);
    492                }
    493            }
    494        }
    495    }
    496 
    497    if (IS_KEY_OR_INTRA(hdr)) {
    498        hdr->refresh_frame_flags = (hdr->frame_type == DAV1D_FRAME_TYPE_KEY &&
    499                                    hdr->show_frame) ? 0xff : dav1d_get_bits(gb, 8);
    500        if (hdr->refresh_frame_flags != 0xff && hdr->error_resilient_mode && seqhdr->order_hint)
    501            for (int i = 0; i < 8; i++)
    502                dav1d_get_bits(gb, seqhdr->order_hint_n_bits);
    503        if (c->strict_std_compliance &&
    504            hdr->frame_type == DAV1D_FRAME_TYPE_INTRA && hdr->refresh_frame_flags == 0xff)
    505        {
    506            goto error;
    507        }
    508        if (read_frame_size(c, gb, 0) < 0) goto error;
    509        if (hdr->allow_screen_content_tools && !hdr->super_res.enabled)
    510            hdr->allow_intrabc = dav1d_get_bit(gb);
    511    } else {
    512        hdr->refresh_frame_flags = hdr->frame_type == DAV1D_FRAME_TYPE_SWITCH ? 0xff :
    513                                   dav1d_get_bits(gb, 8);
    514        if (hdr->error_resilient_mode && seqhdr->order_hint)
    515            for (int i = 0; i < 8; i++)
    516                dav1d_get_bits(gb, seqhdr->order_hint_n_bits);
    517        if (seqhdr->order_hint) {
    518            hdr->frame_ref_short_signaling = dav1d_get_bit(gb);
    519            if (hdr->frame_ref_short_signaling) {
    520                hdr->refidx[0] = dav1d_get_bits(gb, 3);
    521                hdr->refidx[1] = hdr->refidx[2] = -1;
    522                hdr->refidx[3] = dav1d_get_bits(gb, 3);
    523 
    524                /* +1 allows for unconditional stores, as unused
    525                 * values can be dumped into frame_offset[-1]. */
    526                int frame_offset_mem[8+1];
    527                int *const frame_offset = &frame_offset_mem[1];
    528                int earliest_ref = -1;
    529                for (int i = 0, earliest_offset = INT_MAX; i < 8; i++) {
    530                    const Dav1dFrameHeader *const refhdr = c->refs[i].p.p.frame_hdr;
    531                    if (!refhdr) goto error;
    532                    const int diff = get_poc_diff(seqhdr->order_hint_n_bits,
    533                                                  refhdr->frame_offset,
    534                                                  hdr->frame_offset);
    535                    frame_offset[i] = diff;
    536                    if (diff < earliest_offset) {
    537                        earliest_offset = diff;
    538                        earliest_ref = i;
    539                    }
    540                }
    541                frame_offset[hdr->refidx[0]] = INT_MIN; // = reference frame is used
    542                frame_offset[hdr->refidx[3]] = INT_MIN;
    543                assert(earliest_ref >= 0);
    544 
    545                int refidx = -1;
    546                for (int i = 0, latest_offset = 0; i < 8; i++) {
    547                    const int hint = frame_offset[i];
    548                    if (hint >= latest_offset) {
    549                        latest_offset = hint;
    550                        refidx = i;
    551                    }
    552                }
    553                frame_offset[refidx] = INT_MIN;
    554                hdr->refidx[6] = refidx;
    555 
    556                for (int i = 4; i < 6; i++) {
    557                    /* Unsigned compares to handle negative values. */
    558                    unsigned earliest_offset = UINT8_MAX;
    559                    refidx = -1;
    560                    for (int j = 0; j < 8; j++) {
    561                        const unsigned hint = frame_offset[j];
    562                        if (hint < earliest_offset) {
    563                            earliest_offset = hint;
    564                            refidx = j;
    565                        }
    566                    }
    567                    frame_offset[refidx] = INT_MIN;
    568                    hdr->refidx[i] = refidx;
    569                }
    570 
    571                for (int i = 1; i < 7; i++) {
    572                    refidx = hdr->refidx[i];
    573                    if (refidx < 0) {
    574                        unsigned latest_offset = ~UINT8_MAX;
    575                        for (int j = 0; j < 8; j++) {
    576                            const unsigned hint = frame_offset[j];
    577                            if (hint >= latest_offset) {
    578                                latest_offset = hint;
    579                                refidx = j;
    580                            }
    581                        }
    582                        frame_offset[refidx] = INT_MIN;
    583                        hdr->refidx[i] = refidx >= 0 ? refidx : earliest_ref;
    584                    }
    585                }
    586            }
    587        }
    588        for (int i = 0; i < 7; i++) {
    589            if (!hdr->frame_ref_short_signaling)
    590                hdr->refidx[i] = dav1d_get_bits(gb, 3);
    591            if (seqhdr->frame_id_numbers_present) {
    592                const unsigned delta_ref_frame_id = dav1d_get_bits(gb, seqhdr->delta_frame_id_n_bits) + 1;
    593                const unsigned ref_frame_id = (hdr->frame_id + (1 << seqhdr->frame_id_n_bits) - delta_ref_frame_id) & ((1 << seqhdr->frame_id_n_bits) - 1);
    594                Dav1dFrameHeader *const ref_frame_hdr = c->refs[hdr->refidx[i]].p.p.frame_hdr;
    595                if (!ref_frame_hdr || ref_frame_hdr->frame_id != ref_frame_id) goto error;
    596            }
    597        }
    598        const int use_ref = !hdr->error_resilient_mode &&
    599                            hdr->frame_size_override;
    600        if (read_frame_size(c, gb, use_ref) < 0) goto error;
    601        if (!hdr->force_integer_mv)
    602            hdr->hp = dav1d_get_bit(gb);
    603        hdr->subpel_filter_mode = dav1d_get_bit(gb) ? DAV1D_FILTER_SWITCHABLE :
    604                                                      dav1d_get_bits(gb, 2);
    605        hdr->switchable_motion_mode = dav1d_get_bit(gb);
    606        if (!hdr->error_resilient_mode && seqhdr->ref_frame_mvs &&
    607            seqhdr->order_hint && IS_INTER_OR_SWITCH(hdr))
    608        {
    609            hdr->use_ref_frame_mvs = dav1d_get_bit(gb);
    610        }
    611    }
    612 #if DEBUG_FRAME_HDR
    613    printf("HDR: post-frametype-specific-bits: off=%td\n",
    614           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    615 #endif
    616 
    617    if (!seqhdr->reduced_still_picture_header && !hdr->disable_cdf_update)
    618        hdr->refresh_context = !dav1d_get_bit(gb);
    619 #if DEBUG_FRAME_HDR
    620    printf("HDR: post-refresh_context: off=%td\n",
    621           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    622 #endif
    623 
    624    // tile data
    625    hdr->tiling.uniform = dav1d_get_bit(gb);
    626    const int sbsz_min1 = (64 << seqhdr->sb128) - 1;
    627    const int sbsz_log2 = 6 + seqhdr->sb128;
    628    const int sbw = (hdr->width[0] + sbsz_min1) >> sbsz_log2;
    629    const int sbh = (hdr->height + sbsz_min1) >> sbsz_log2;
    630    const int max_tile_width_sb = 4096 >> sbsz_log2;
    631    const int max_tile_area_sb = 4096 * 2304 >> (2 * sbsz_log2);
    632    hdr->tiling.min_log2_cols = tile_log2(max_tile_width_sb, sbw);
    633    hdr->tiling.max_log2_cols = tile_log2(1, imin(sbw, DAV1D_MAX_TILE_COLS));
    634    hdr->tiling.max_log2_rows = tile_log2(1, imin(sbh, DAV1D_MAX_TILE_ROWS));
    635    const int min_log2_tiles = imax(tile_log2(max_tile_area_sb, sbw * sbh),
    636                              hdr->tiling.min_log2_cols);
    637    if (hdr->tiling.uniform) {
    638        for (hdr->tiling.log2_cols = hdr->tiling.min_log2_cols;
    639             hdr->tiling.log2_cols < hdr->tiling.max_log2_cols && dav1d_get_bit(gb);
    640             hdr->tiling.log2_cols++) ;
    641        const int tile_w = 1 + ((sbw - 1) >> hdr->tiling.log2_cols);
    642        hdr->tiling.cols = 0;
    643        for (int sbx = 0; sbx < sbw; sbx += tile_w, hdr->tiling.cols++)
    644            hdr->tiling.col_start_sb[hdr->tiling.cols] = sbx;
    645        hdr->tiling.min_log2_rows =
    646            imax(min_log2_tiles - hdr->tiling.log2_cols, 0);
    647 
    648        for (hdr->tiling.log2_rows = hdr->tiling.min_log2_rows;
    649             hdr->tiling.log2_rows < hdr->tiling.max_log2_rows && dav1d_get_bit(gb);
    650             hdr->tiling.log2_rows++) ;
    651        const int tile_h = 1 + ((sbh - 1) >> hdr->tiling.log2_rows);
    652        hdr->tiling.rows = 0;
    653        for (int sby = 0; sby < sbh; sby += tile_h, hdr->tiling.rows++)
    654            hdr->tiling.row_start_sb[hdr->tiling.rows] = sby;
    655    } else {
    656        hdr->tiling.cols = 0;
    657        int widest_tile = 0, max_tile_area_sb = sbw * sbh;
    658        for (int sbx = 0; sbx < sbw && hdr->tiling.cols < DAV1D_MAX_TILE_COLS; hdr->tiling.cols++) {
    659            const int tile_width_sb = imin(sbw - sbx, max_tile_width_sb);
    660            const int tile_w = (tile_width_sb > 1) ? 1 + dav1d_get_uniform(gb, tile_width_sb) : 1;
    661            hdr->tiling.col_start_sb[hdr->tiling.cols] = sbx;
    662            sbx += tile_w;
    663            widest_tile = imax(widest_tile, tile_w);
    664        }
    665        hdr->tiling.log2_cols = tile_log2(1, hdr->tiling.cols);
    666        if (min_log2_tiles) max_tile_area_sb >>= min_log2_tiles + 1;
    667        const int max_tile_height_sb = imax(max_tile_area_sb / widest_tile, 1);
    668 
    669        hdr->tiling.rows = 0;
    670        for (int sby = 0; sby < sbh && hdr->tiling.rows < DAV1D_MAX_TILE_ROWS; hdr->tiling.rows++) {
    671            const int tile_height_sb = imin(sbh - sby, max_tile_height_sb);
    672            const int tile_h = (tile_height_sb > 1) ? 1 + dav1d_get_uniform(gb, tile_height_sb) : 1;
    673            hdr->tiling.row_start_sb[hdr->tiling.rows] = sby;
    674            sby += tile_h;
    675        }
    676        hdr->tiling.log2_rows = tile_log2(1, hdr->tiling.rows);
    677    }
    678    hdr->tiling.col_start_sb[hdr->tiling.cols] = sbw;
    679    hdr->tiling.row_start_sb[hdr->tiling.rows] = sbh;
    680    if (hdr->tiling.log2_cols || hdr->tiling.log2_rows) {
    681        hdr->tiling.update = dav1d_get_bits(gb, hdr->tiling.log2_cols + hdr->tiling.log2_rows);
    682        if (hdr->tiling.update >= hdr->tiling.cols * hdr->tiling.rows)
    683            goto error;
    684        hdr->tiling.n_bytes = dav1d_get_bits(gb, 2) + 1;
    685    }
    686 #if DEBUG_FRAME_HDR
    687    printf("HDR: post-tiling: off=%td\n",
    688           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    689 #endif
    690 
    691    // quant data
    692    hdr->quant.yac = dav1d_get_bits(gb, 8);
    693    if (dav1d_get_bit(gb))
    694        hdr->quant.ydc_delta = dav1d_get_sbits(gb, 7);
    695    if (!seqhdr->monochrome) {
    696        // If the sequence header says that delta_q might be different
    697        // for U, V, we must check whether it actually is for this
    698        // frame.
    699        const int diff_uv_delta = seqhdr->separate_uv_delta_q ? dav1d_get_bit(gb) : 0;
    700        if (dav1d_get_bit(gb))
    701            hdr->quant.udc_delta = dav1d_get_sbits(gb, 7);
    702        if (dav1d_get_bit(gb))
    703            hdr->quant.uac_delta = dav1d_get_sbits(gb, 7);
    704        if (diff_uv_delta) {
    705            if (dav1d_get_bit(gb))
    706                hdr->quant.vdc_delta = dav1d_get_sbits(gb, 7);
    707            if (dav1d_get_bit(gb))
    708                hdr->quant.vac_delta = dav1d_get_sbits(gb, 7);
    709        } else {
    710            hdr->quant.vdc_delta = hdr->quant.udc_delta;
    711            hdr->quant.vac_delta = hdr->quant.uac_delta;
    712        }
    713    }
    714 #if DEBUG_FRAME_HDR
    715    printf("HDR: post-quant: off=%td\n",
    716           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    717 #endif
    718    hdr->quant.qm = dav1d_get_bit(gb);
    719    if (hdr->quant.qm) {
    720        hdr->quant.qm_y = dav1d_get_bits(gb, 4);
    721        hdr->quant.qm_u = dav1d_get_bits(gb, 4);
    722        hdr->quant.qm_v = seqhdr->separate_uv_delta_q ? dav1d_get_bits(gb, 4) :
    723                                                        hdr->quant.qm_u;
    724    }
    725 #if DEBUG_FRAME_HDR
    726    printf("HDR: post-qm: off=%td\n",
    727           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    728 #endif
    729 
    730    // segmentation data
    731    hdr->segmentation.enabled = dav1d_get_bit(gb);
    732    if (hdr->segmentation.enabled) {
    733        if (hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
    734            hdr->segmentation.update_map = 1;
    735            hdr->segmentation.update_data = 1;
    736        } else {
    737            hdr->segmentation.update_map = dav1d_get_bit(gb);
    738            if (hdr->segmentation.update_map)
    739                hdr->segmentation.temporal = dav1d_get_bit(gb);
    740            hdr->segmentation.update_data = dav1d_get_bit(gb);
    741        }
    742 
    743        if (hdr->segmentation.update_data) {
    744            hdr->segmentation.seg_data.last_active_segid = -1;
    745            for (int i = 0; i < DAV1D_MAX_SEGMENTS; i++) {
    746                Dav1dSegmentationData *const seg =
    747                    &hdr->segmentation.seg_data.d[i];
    748                if (dav1d_get_bit(gb)) {
    749                    seg->delta_q = dav1d_get_sbits(gb, 9);
    750                    hdr->segmentation.seg_data.last_active_segid = i;
    751                }
    752                if (dav1d_get_bit(gb)) {
    753                    seg->delta_lf_y_v = dav1d_get_sbits(gb, 7);
    754                    hdr->segmentation.seg_data.last_active_segid = i;
    755                }
    756                if (dav1d_get_bit(gb)) {
    757                    seg->delta_lf_y_h = dav1d_get_sbits(gb, 7);
    758                    hdr->segmentation.seg_data.last_active_segid = i;
    759                }
    760                if (dav1d_get_bit(gb)) {
    761                    seg->delta_lf_u = dav1d_get_sbits(gb, 7);
    762                    hdr->segmentation.seg_data.last_active_segid = i;
    763                }
    764                if (dav1d_get_bit(gb)) {
    765                    seg->delta_lf_v = dav1d_get_sbits(gb, 7);
    766                    hdr->segmentation.seg_data.last_active_segid = i;
    767                }
    768                if (dav1d_get_bit(gb)) {
    769                    seg->ref = dav1d_get_bits(gb, 3);
    770                    hdr->segmentation.seg_data.last_active_segid = i;
    771                    hdr->segmentation.seg_data.preskip = 1;
    772                } else {
    773                    seg->ref = -1;
    774                }
    775                if ((seg->skip = dav1d_get_bit(gb))) {
    776                    hdr->segmentation.seg_data.last_active_segid = i;
    777                    hdr->segmentation.seg_data.preskip = 1;
    778                }
    779                if ((seg->globalmv = dav1d_get_bit(gb))) {
    780                    hdr->segmentation.seg_data.last_active_segid = i;
    781                    hdr->segmentation.seg_data.preskip = 1;
    782                }
    783            }
    784        } else {
    785            // segmentation.update_data was false so we should copy
    786            // segmentation data from the reference frame.
    787            assert(hdr->primary_ref_frame != DAV1D_PRIMARY_REF_NONE);
    788            const int pri_ref = hdr->refidx[hdr->primary_ref_frame];
    789            if (!c->refs[pri_ref].p.p.frame_hdr) goto error;
    790            hdr->segmentation.seg_data =
    791                c->refs[pri_ref].p.p.frame_hdr->segmentation.seg_data;
    792        }
    793    } else {
    794        for (int i = 0; i < DAV1D_MAX_SEGMENTS; i++)
    795            hdr->segmentation.seg_data.d[i].ref = -1;
    796    }
    797 #if DEBUG_FRAME_HDR
    798    printf("HDR: post-segmentation: off=%td\n",
    799           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    800 #endif
    801 
    802    // delta q
    803    if (hdr->quant.yac) {
    804        hdr->delta.q.present = dav1d_get_bit(gb);
    805        if (hdr->delta.q.present) {
    806            hdr->delta.q.res_log2 = dav1d_get_bits(gb, 2);
    807            if (!hdr->allow_intrabc) {
    808                hdr->delta.lf.present = dav1d_get_bit(gb);
    809                if (hdr->delta.lf.present) {
    810                    hdr->delta.lf.res_log2 = dav1d_get_bits(gb, 2);
    811                    hdr->delta.lf.multi = dav1d_get_bit(gb);
    812                }
    813            }
    814        }
    815    }
    816 #if DEBUG_FRAME_HDR
    817    printf("HDR: post-delta_q_lf_flags: off=%td\n",
    818           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    819 #endif
    820 
    821    // derive lossless flags
    822    const int delta_lossless = !hdr->quant.ydc_delta && !hdr->quant.udc_delta &&
    823        !hdr->quant.uac_delta && !hdr->quant.vdc_delta && !hdr->quant.vac_delta;
    824    hdr->all_lossless = 1;
    825    for (int i = 0; i < DAV1D_MAX_SEGMENTS; i++) {
    826        hdr->segmentation.qidx[i] = hdr->segmentation.enabled ?
    827            iclip_u8(hdr->quant.yac + hdr->segmentation.seg_data.d[i].delta_q) :
    828            hdr->quant.yac;
    829        hdr->segmentation.lossless[i] =
    830            !hdr->segmentation.qidx[i] && delta_lossless;
    831        hdr->all_lossless &= hdr->segmentation.lossless[i];
    832    }
    833 
    834    // loopfilter
    835    if (hdr->all_lossless || hdr->allow_intrabc) {
    836        hdr->loopfilter.mode_ref_delta_enabled = 1;
    837        hdr->loopfilter.mode_ref_delta_update = 1;
    838        hdr->loopfilter.mode_ref_deltas = default_mode_ref_deltas;
    839    } else {
    840        hdr->loopfilter.level_y[0] = dav1d_get_bits(gb, 6);
    841        hdr->loopfilter.level_y[1] = dav1d_get_bits(gb, 6);
    842        if (!seqhdr->monochrome &&
    843            (hdr->loopfilter.level_y[0] || hdr->loopfilter.level_y[1]))
    844        {
    845            hdr->loopfilter.level_u = dav1d_get_bits(gb, 6);
    846            hdr->loopfilter.level_v = dav1d_get_bits(gb, 6);
    847        }
    848        hdr->loopfilter.sharpness = dav1d_get_bits(gb, 3);
    849 
    850        if (hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
    851            hdr->loopfilter.mode_ref_deltas = default_mode_ref_deltas;
    852        } else {
    853            const int ref = hdr->refidx[hdr->primary_ref_frame];
    854            if (!c->refs[ref].p.p.frame_hdr) goto error;
    855            hdr->loopfilter.mode_ref_deltas =
    856                c->refs[ref].p.p.frame_hdr->loopfilter.mode_ref_deltas;
    857        }
    858        hdr->loopfilter.mode_ref_delta_enabled = dav1d_get_bit(gb);
    859        if (hdr->loopfilter.mode_ref_delta_enabled) {
    860            hdr->loopfilter.mode_ref_delta_update = dav1d_get_bit(gb);
    861            if (hdr->loopfilter.mode_ref_delta_update) {
    862                for (int i = 0; i < 8; i++)
    863                    if (dav1d_get_bit(gb))
    864                        hdr->loopfilter.mode_ref_deltas.ref_delta[i] =
    865                            dav1d_get_sbits(gb, 7);
    866                for (int i = 0; i < 2; i++)
    867                    if (dav1d_get_bit(gb))
    868                        hdr->loopfilter.mode_ref_deltas.mode_delta[i] =
    869                            dav1d_get_sbits(gb, 7);
    870            }
    871        }
    872    }
    873 #if DEBUG_FRAME_HDR
    874    printf("HDR: post-lpf: off=%td\n",
    875           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    876 #endif
    877 
    878    // cdef
    879    if (!hdr->all_lossless && seqhdr->cdef && !hdr->allow_intrabc) {
    880        hdr->cdef.damping = dav1d_get_bits(gb, 2) + 3;
    881        hdr->cdef.n_bits = dav1d_get_bits(gb, 2);
    882        for (int i = 0; i < (1 << hdr->cdef.n_bits); i++) {
    883            hdr->cdef.y_strength[i] = dav1d_get_bits(gb, 6);
    884            if (!seqhdr->monochrome)
    885                hdr->cdef.uv_strength[i] = dav1d_get_bits(gb, 6);
    886        }
    887    }
    888 #if DEBUG_FRAME_HDR
    889    printf("HDR: post-cdef: off=%td\n",
    890           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    891 #endif
    892 
    893    // restoration
    894    if ((!hdr->all_lossless || hdr->super_res.enabled) &&
    895        seqhdr->restoration && !hdr->allow_intrabc)
    896    {
    897        hdr->restoration.type[0] = dav1d_get_bits(gb, 2);
    898        if (!seqhdr->monochrome) {
    899            hdr->restoration.type[1] = dav1d_get_bits(gb, 2);
    900            hdr->restoration.type[2] = dav1d_get_bits(gb, 2);
    901        }
    902 
    903        if (hdr->restoration.type[0] || hdr->restoration.type[1] ||
    904            hdr->restoration.type[2])
    905        {
    906            // Log2 of the restoration unit size.
    907            hdr->restoration.unit_size[0] = 6 + seqhdr->sb128;
    908            if (dav1d_get_bit(gb)) {
    909                hdr->restoration.unit_size[0]++;
    910                if (!seqhdr->sb128)
    911                    hdr->restoration.unit_size[0] += dav1d_get_bit(gb);
    912            }
    913            hdr->restoration.unit_size[1] = hdr->restoration.unit_size[0];
    914            if ((hdr->restoration.type[1] || hdr->restoration.type[2]) &&
    915                seqhdr->ss_hor == 1 && seqhdr->ss_ver == 1)
    916            {
    917                hdr->restoration.unit_size[1] -= dav1d_get_bit(gb);
    918            }
    919        } else {
    920            hdr->restoration.unit_size[0] = 8;
    921        }
    922    }
    923 #if DEBUG_FRAME_HDR
    924    printf("HDR: post-restoration: off=%td\n",
    925           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    926 #endif
    927 
    928    if (!hdr->all_lossless)
    929        hdr->txfm_mode = dav1d_get_bit(gb) ? DAV1D_TX_SWITCHABLE : DAV1D_TX_LARGEST;
    930 #if DEBUG_FRAME_HDR
    931    printf("HDR: post-txfmmode: off=%td\n",
    932           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    933 #endif
    934    if (IS_INTER_OR_SWITCH(hdr))
    935        hdr->switchable_comp_refs = dav1d_get_bit(gb);
    936 #if DEBUG_FRAME_HDR
    937    printf("HDR: post-refmode: off=%td\n",
    938           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    939 #endif
    940    if (hdr->switchable_comp_refs && IS_INTER_OR_SWITCH(hdr) && seqhdr->order_hint) {
    941        const int poc = hdr->frame_offset;
    942        int off_before = -1, off_after = -1;
    943        int off_before_idx, off_after_idx;
    944        for (int i = 0; i < 7; i++) {
    945            if (!c->refs[hdr->refidx[i]].p.p.frame_hdr) goto error;
    946            const int refpoc = c->refs[hdr->refidx[i]].p.p.frame_hdr->frame_offset;
    947 
    948            const int diff = get_poc_diff(seqhdr->order_hint_n_bits, refpoc, poc);
    949            if (diff > 0) {
    950                if (off_after < 0 || get_poc_diff(seqhdr->order_hint_n_bits,
    951                                                  off_after, refpoc) > 0)
    952                {
    953                    off_after = refpoc;
    954                    off_after_idx = i;
    955                }
    956            } else if (diff < 0 && (off_before < 0 ||
    957                                    get_poc_diff(seqhdr->order_hint_n_bits,
    958                                                 refpoc, off_before) > 0))
    959            {
    960                off_before = refpoc;
    961                off_before_idx = i;
    962            }
    963        }
    964 
    965        if ((off_before | off_after) >= 0) {
    966            hdr->skip_mode_refs[0] = imin(off_before_idx, off_after_idx);
    967            hdr->skip_mode_refs[1] = imax(off_before_idx, off_after_idx);
    968            hdr->skip_mode_allowed = 1;
    969        } else if (off_before >= 0) {
    970            int off_before2 = -1;
    971            int off_before2_idx;
    972            for (int i = 0; i < 7; i++) {
    973                if (!c->refs[hdr->refidx[i]].p.p.frame_hdr) goto error;
    974                const int refpoc = c->refs[hdr->refidx[i]].p.p.frame_hdr->frame_offset;
    975                if (get_poc_diff(seqhdr->order_hint_n_bits,
    976                                 refpoc, off_before) < 0) {
    977                    if (off_before2 < 0 || get_poc_diff(seqhdr->order_hint_n_bits,
    978                                                        refpoc, off_before2) > 0)
    979                    {
    980                        off_before2 = refpoc;
    981                        off_before2_idx = i;
    982                    }
    983                }
    984            }
    985 
    986            if (off_before2 >= 0) {
    987                hdr->skip_mode_refs[0] = imin(off_before_idx, off_before2_idx);
    988                hdr->skip_mode_refs[1] = imax(off_before_idx, off_before2_idx);
    989                hdr->skip_mode_allowed = 1;
    990            }
    991        }
    992    }
    993    if (hdr->skip_mode_allowed)
    994        hdr->skip_mode_enabled = dav1d_get_bit(gb);
    995 #if DEBUG_FRAME_HDR
    996    printf("HDR: post-extskip: off=%td\n",
    997           (gb->ptr - init_ptr) * 8 - gb->bits_left);
    998 #endif
    999    if (!hdr->error_resilient_mode && IS_INTER_OR_SWITCH(hdr) && seqhdr->warped_motion)
   1000        hdr->warp_motion = dav1d_get_bit(gb);
   1001 #if DEBUG_FRAME_HDR
   1002    printf("HDR: post-warpmotionbit: off=%td\n",
   1003           (gb->ptr - init_ptr) * 8 - gb->bits_left);
   1004 #endif
   1005    hdr->reduced_txtp_set = dav1d_get_bit(gb);
   1006 #if DEBUG_FRAME_HDR
   1007    printf("HDR: post-reducedtxtpset: off=%td\n",
   1008           (gb->ptr - init_ptr) * 8 - gb->bits_left);
   1009 #endif
   1010 
   1011    for (int i = 0; i < 7; i++)
   1012        hdr->gmv[i] = dav1d_default_wm_params;
   1013 
   1014    if (IS_INTER_OR_SWITCH(hdr)) {
   1015        for (int i = 0; i < 7; i++) {
   1016            hdr->gmv[i].type = !dav1d_get_bit(gb) ? DAV1D_WM_TYPE_IDENTITY :
   1017                                dav1d_get_bit(gb) ? DAV1D_WM_TYPE_ROT_ZOOM :
   1018                                dav1d_get_bit(gb) ? DAV1D_WM_TYPE_TRANSLATION :
   1019                                                    DAV1D_WM_TYPE_AFFINE;
   1020 
   1021            if (hdr->gmv[i].type == DAV1D_WM_TYPE_IDENTITY) continue;
   1022 
   1023            const Dav1dWarpedMotionParams *ref_gmv;
   1024            if (hdr->primary_ref_frame == DAV1D_PRIMARY_REF_NONE) {
   1025                ref_gmv = &dav1d_default_wm_params;
   1026            } else {
   1027                const int pri_ref = hdr->refidx[hdr->primary_ref_frame];
   1028                if (!c->refs[pri_ref].p.p.frame_hdr) goto error;
   1029                ref_gmv = &c->refs[pri_ref].p.p.frame_hdr->gmv[i];
   1030            }
   1031            int32_t *const mat = hdr->gmv[i].matrix;
   1032            const int32_t *const ref_mat = ref_gmv->matrix;
   1033            int bits, shift;
   1034 
   1035            if (hdr->gmv[i].type >= DAV1D_WM_TYPE_ROT_ZOOM) {
   1036                mat[2] = (1 << 16) + 2 *
   1037                    dav1d_get_bits_subexp(gb, (ref_mat[2] - (1 << 16)) >> 1, 12);
   1038                mat[3] = 2 * dav1d_get_bits_subexp(gb, ref_mat[3] >> 1, 12);
   1039 
   1040                bits = 12;
   1041                shift = 10;
   1042            } else {
   1043                bits = 9 - !hdr->hp;
   1044                shift = 13 + !hdr->hp;
   1045            }
   1046 
   1047            if (hdr->gmv[i].type == DAV1D_WM_TYPE_AFFINE) {
   1048                mat[4] = 2 * dav1d_get_bits_subexp(gb, ref_mat[4] >> 1, 12);
   1049                mat[5] = (1 << 16) + 2 *
   1050                    dav1d_get_bits_subexp(gb, (ref_mat[5] - (1 << 16)) >> 1, 12);
   1051            } else {
   1052                mat[4] = -mat[3];
   1053                mat[5] = mat[2];
   1054            }
   1055 
   1056            mat[0] = dav1d_get_bits_subexp(gb, ref_mat[0] >> shift, bits) * (1 << shift);
   1057            mat[1] = dav1d_get_bits_subexp(gb, ref_mat[1] >> shift, bits) * (1 << shift);
   1058        }
   1059    }
   1060 #if DEBUG_FRAME_HDR
   1061    printf("HDR: post-gmv: off=%td\n",
   1062           (gb->ptr - init_ptr) * 8 - gb->bits_left);
   1063 #endif
   1064 
   1065    if (seqhdr->film_grain_present && (hdr->show_frame || hdr->showable_frame)) {
   1066        hdr->film_grain.present = dav1d_get_bit(gb);
   1067        if (hdr->film_grain.present) {
   1068            const unsigned seed = dav1d_get_bits(gb, 16);
   1069            hdr->film_grain.update = hdr->frame_type != DAV1D_FRAME_TYPE_INTER || dav1d_get_bit(gb);
   1070            if (!hdr->film_grain.update) {
   1071                const int refidx = dav1d_get_bits(gb, 3);
   1072                int i;
   1073                for (i = 0; i < 7; i++)
   1074                    if (hdr->refidx[i] == refidx)
   1075                        break;
   1076                if (i == 7 || !c->refs[refidx].p.p.frame_hdr) goto error;
   1077                hdr->film_grain.data = c->refs[refidx].p.p.frame_hdr->film_grain.data;
   1078                hdr->film_grain.data.seed = seed;
   1079            } else {
   1080                Dav1dFilmGrainData *const fgd = &hdr->film_grain.data;
   1081                fgd->seed = seed;
   1082 
   1083                fgd->num_y_points = dav1d_get_bits(gb, 4);
   1084                if (fgd->num_y_points > 14) goto error;
   1085                for (int i = 0; i < fgd->num_y_points; i++) {
   1086                    fgd->y_points[i][0] = dav1d_get_bits(gb, 8);
   1087                    if (i && fgd->y_points[i - 1][0] >= fgd->y_points[i][0])
   1088                        goto error;
   1089                    fgd->y_points[i][1] = dav1d_get_bits(gb, 8);
   1090                }
   1091 
   1092                if (!seqhdr->monochrome)
   1093                    fgd->chroma_scaling_from_luma = dav1d_get_bit(gb);
   1094                if (seqhdr->monochrome || fgd->chroma_scaling_from_luma ||
   1095                    (seqhdr->ss_ver == 1 && seqhdr->ss_hor == 1 && !fgd->num_y_points))
   1096                {
   1097                    fgd->num_uv_points[0] = fgd->num_uv_points[1] = 0;
   1098                } else for (int pl = 0; pl < 2; pl++) {
   1099                    fgd->num_uv_points[pl] = dav1d_get_bits(gb, 4);
   1100                    if (fgd->num_uv_points[pl] > 10) goto error;
   1101                    for (int i = 0; i < fgd->num_uv_points[pl]; i++) {
   1102                        fgd->uv_points[pl][i][0] = dav1d_get_bits(gb, 8);
   1103                        if (i && fgd->uv_points[pl][i - 1][0] >= fgd->uv_points[pl][i][0])
   1104                            goto error;
   1105                        fgd->uv_points[pl][i][1] = dav1d_get_bits(gb, 8);
   1106                    }
   1107                }
   1108 
   1109                if (seqhdr->ss_hor == 1 && seqhdr->ss_ver == 1 &&
   1110                    !!fgd->num_uv_points[0] != !!fgd->num_uv_points[1])
   1111                {
   1112                    goto error;
   1113                }
   1114 
   1115                fgd->scaling_shift = dav1d_get_bits(gb, 2) + 8;
   1116                fgd->ar_coeff_lag = dav1d_get_bits(gb, 2);
   1117                const int num_y_pos = 2 * fgd->ar_coeff_lag * (fgd->ar_coeff_lag + 1);
   1118                if (fgd->num_y_points)
   1119                    for (int i = 0; i < num_y_pos; i++)
   1120                        fgd->ar_coeffs_y[i] = dav1d_get_bits(gb, 8) - 128;
   1121                for (int pl = 0; pl < 2; pl++)
   1122                    if (fgd->num_uv_points[pl] || fgd->chroma_scaling_from_luma) {
   1123                        const int num_uv_pos = num_y_pos + !!fgd->num_y_points;
   1124                        for (int i = 0; i < num_uv_pos; i++)
   1125                            fgd->ar_coeffs_uv[pl][i] = dav1d_get_bits(gb, 8) - 128;
   1126                        if (!fgd->num_y_points)
   1127                            fgd->ar_coeffs_uv[pl][num_uv_pos] = 0;
   1128                    }
   1129                fgd->ar_coeff_shift = dav1d_get_bits(gb, 2) + 6;
   1130                fgd->grain_scale_shift = dav1d_get_bits(gb, 2);
   1131                for (int pl = 0; pl < 2; pl++)
   1132                    if (fgd->num_uv_points[pl]) {
   1133                        fgd->uv_mult[pl] = dav1d_get_bits(gb, 8) - 128;
   1134                        fgd->uv_luma_mult[pl] = dav1d_get_bits(gb, 8) - 128;
   1135                        fgd->uv_offset[pl] = dav1d_get_bits(gb, 9) - 256;
   1136                    }
   1137                fgd->overlap_flag = dav1d_get_bit(gb);
   1138                fgd->clip_to_restricted_range = dav1d_get_bit(gb);
   1139            }
   1140        }
   1141    }
   1142 #if DEBUG_FRAME_HDR
   1143    printf("HDR: post-filmgrain: off=%td\n",
   1144           (gb->ptr - init_ptr) * 8 - gb->bits_left);
   1145 #endif
   1146 
   1147    return 0;
   1148 
   1149 error:
   1150    dav1d_log(c, "Error parsing frame header\n");
   1151    return DAV1D_ERR(EINVAL);
   1152 }
   1153 
   1154 static void parse_tile_hdr(Dav1dContext *const c, GetBits *const gb) {
   1155    const int n_tiles = c->frame_hdr->tiling.cols * c->frame_hdr->tiling.rows;
   1156    const int have_tile_pos = n_tiles > 1 ? dav1d_get_bit(gb) : 0;
   1157 
   1158    if (have_tile_pos) {
   1159        const int n_bits = c->frame_hdr->tiling.log2_cols +
   1160                           c->frame_hdr->tiling.log2_rows;
   1161        c->tile[c->n_tile_data].start = dav1d_get_bits(gb, n_bits);
   1162        c->tile[c->n_tile_data].end = dav1d_get_bits(gb, n_bits);
   1163    } else {
   1164        c->tile[c->n_tile_data].start = 0;
   1165        c->tile[c->n_tile_data].end = n_tiles - 1;
   1166    }
   1167 }
   1168 
   1169 ptrdiff_t dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
   1170    GetBits gb;
   1171    int res;
   1172 
   1173    dav1d_init_get_bits(&gb, in->data, in->sz);
   1174 
   1175    // obu header
   1176    const int obu_forbidden_bit = dav1d_get_bit(&gb);
   1177    if (c->strict_std_compliance && obu_forbidden_bit) goto error;
   1178    const enum Dav1dObuType type = dav1d_get_bits(&gb, 4);
   1179    const int has_extension = dav1d_get_bit(&gb);
   1180    const int has_length_field = dav1d_get_bit(&gb);
   1181    dav1d_get_bit(&gb); // reserved
   1182 
   1183    int temporal_id = 0, spatial_id = 0;
   1184    if (has_extension) {
   1185        temporal_id = dav1d_get_bits(&gb, 3);
   1186        spatial_id = dav1d_get_bits(&gb, 2);
   1187        dav1d_get_bits(&gb, 3); // reserved
   1188    }
   1189 
   1190    if (has_length_field) {
   1191        const size_t len = dav1d_get_uleb128(&gb);
   1192        if (len > (size_t)(gb.ptr_end - gb.ptr)) goto error;
   1193        gb.ptr_end = gb.ptr + len;
   1194    }
   1195    if (gb.error) goto error;
   1196 
   1197    // We must have read a whole number of bytes at this point (1 byte
   1198    // for the header and whole bytes at a time when reading the
   1199    // leb128 length field).
   1200    assert(gb.bits_left == 0);
   1201 
   1202    // skip obu not belonging to the selected temporal/spatial layer
   1203    if (type != DAV1D_OBU_SEQ_HDR && type != DAV1D_OBU_TD &&
   1204        has_extension && c->operating_point_idc != 0)
   1205    {
   1206        const int in_temporal_layer = (c->operating_point_idc >> temporal_id) & 1;
   1207        const int in_spatial_layer = (c->operating_point_idc >> (spatial_id + 8)) & 1;
   1208        if (!in_temporal_layer || !in_spatial_layer)
   1209            return gb.ptr_end - gb.ptr_start;
   1210    }
   1211 
   1212    switch (type) {
   1213    case DAV1D_OBU_SEQ_HDR: {
   1214        Dav1dRef *ref = dav1d_ref_create_using_pool(c->seq_hdr_pool,
   1215                                                    sizeof(Dav1dSequenceHeader));
   1216        if (!ref) return DAV1D_ERR(ENOMEM);
   1217        Dav1dSequenceHeader *seq_hdr = ref->data;
   1218        if ((res = parse_seq_hdr(seq_hdr, &gb, c->strict_std_compliance)) < 0) {
   1219            dav1d_log(c, "Error parsing sequence header\n");
   1220            dav1d_ref_dec(&ref);
   1221            goto error;
   1222        }
   1223 
   1224        const int op_idx =
   1225            c->operating_point < seq_hdr->num_operating_points ? c->operating_point : 0;
   1226        c->operating_point_idc = seq_hdr->operating_points[op_idx].idc;
   1227        const unsigned spatial_mask = c->operating_point_idc >> 8;
   1228        c->max_spatial_id = spatial_mask ? ulog2(spatial_mask) : 0;
   1229 
   1230        // If we have read a sequence header which is different from
   1231        // the old one, this is a new video sequence and can't use any
   1232        // previous state. Free that state.
   1233 
   1234        if (!c->seq_hdr) {
   1235            c->frame_hdr = NULL;
   1236            c->frame_flags |= PICTURE_FLAG_NEW_SEQUENCE;
   1237        // see 7.5, operating_parameter_info is allowed to change in
   1238        // sequence headers of a single sequence
   1239        } else if (memcmp(seq_hdr, c->seq_hdr, offsetof(Dav1dSequenceHeader, operating_parameter_info))) {
   1240            c->frame_hdr = NULL;
   1241            c->mastering_display = NULL;
   1242            c->content_light = NULL;
   1243            dav1d_ref_dec(&c->mastering_display_ref);
   1244            dav1d_ref_dec(&c->content_light_ref);
   1245            for (int i = 0; i < 8; i++) {
   1246                if (c->refs[i].p.p.frame_hdr)
   1247                    dav1d_thread_picture_unref(&c->refs[i].p);
   1248                dav1d_ref_dec(&c->refs[i].segmap);
   1249                dav1d_ref_dec(&c->refs[i].refmvs);
   1250                dav1d_cdf_thread_unref(&c->cdf[i]);
   1251            }
   1252            c->frame_flags |= PICTURE_FLAG_NEW_SEQUENCE;
   1253        // If operating_parameter_info changed, signal it
   1254        } else if (memcmp(seq_hdr->operating_parameter_info, c->seq_hdr->operating_parameter_info,
   1255                          sizeof(seq_hdr->operating_parameter_info)))
   1256        {
   1257            c->frame_flags |= PICTURE_FLAG_NEW_OP_PARAMS_INFO;
   1258        }
   1259        dav1d_ref_dec(&c->seq_hdr_ref);
   1260        c->seq_hdr_ref = ref;
   1261        c->seq_hdr = seq_hdr;
   1262        break;
   1263    }
   1264    case DAV1D_OBU_REDUNDANT_FRAME_HDR:
   1265        if (c->frame_hdr) break;
   1266        // fall-through
   1267    case DAV1D_OBU_FRAME:
   1268    case DAV1D_OBU_FRAME_HDR:
   1269        if (!c->seq_hdr) goto error;
   1270        if (!c->frame_hdr_ref) {
   1271            c->frame_hdr_ref = dav1d_ref_create_using_pool(c->frame_hdr_pool,
   1272                                                           sizeof(Dav1dFrameHeader));
   1273            if (!c->frame_hdr_ref) return DAV1D_ERR(ENOMEM);
   1274        }
   1275 #ifndef NDEBUG
   1276        // ensure that the reference is writable
   1277        assert(dav1d_ref_is_writable(c->frame_hdr_ref));
   1278 #endif
   1279        c->frame_hdr = c->frame_hdr_ref->data;
   1280        memset(c->frame_hdr, 0, sizeof(*c->frame_hdr));
   1281        c->frame_hdr->temporal_id = temporal_id;
   1282        c->frame_hdr->spatial_id = spatial_id;
   1283        if ((res = parse_frame_hdr(c, &gb)) < 0) {
   1284            c->frame_hdr = NULL;
   1285            goto error;
   1286        }
   1287        for (int n = 0; n < c->n_tile_data; n++)
   1288            dav1d_data_unref_internal(&c->tile[n].data);
   1289        c->n_tile_data = 0;
   1290        c->n_tiles = 0;
   1291        if (type != DAV1D_OBU_FRAME) {
   1292            // This is actually a frame header OBU so read the
   1293            // trailing bit and check for overrun.
   1294            if (check_trailing_bits(&gb, c->strict_std_compliance) < 0) {
   1295                c->frame_hdr = NULL;
   1296                goto error;
   1297            }
   1298        }
   1299 
   1300        if (c->frame_size_limit && (int64_t)c->frame_hdr->width[1] *
   1301            c->frame_hdr->height > c->frame_size_limit)
   1302        {
   1303            dav1d_log(c, "Frame size %dx%d exceeds limit %u\n", c->frame_hdr->width[1],
   1304                      c->frame_hdr->height, c->frame_size_limit);
   1305            c->frame_hdr = NULL;
   1306            return DAV1D_ERR(ERANGE);
   1307        }
   1308 
   1309        if (type != DAV1D_OBU_FRAME)
   1310            break;
   1311        // OBU_FRAMEs shouldn't be signaled with show_existing_frame
   1312        if (c->frame_hdr->show_existing_frame) {
   1313            c->frame_hdr = NULL;
   1314            goto error;
   1315        }
   1316 
   1317        // This is the frame header at the start of a frame OBU.
   1318        // There's no trailing bit at the end to skip, but we do need
   1319        // to align to the next byte.
   1320        dav1d_bytealign_get_bits(&gb);
   1321        // fall-through
   1322    case DAV1D_OBU_TILE_GRP: {
   1323        if (!c->frame_hdr) goto error;
   1324        if (c->n_tile_data_alloc < c->n_tile_data + 1) {
   1325            if ((c->n_tile_data + 1) > INT_MAX / (int)sizeof(*c->tile)) goto error;
   1326            struct Dav1dTileGroup *tile = dav1d_realloc(ALLOC_TILE, c->tile,
   1327                                                        (c->n_tile_data + 1) * sizeof(*c->tile));
   1328            if (!tile) goto error;
   1329            c->tile = tile;
   1330            memset(c->tile + c->n_tile_data, 0, sizeof(*c->tile));
   1331            c->n_tile_data_alloc = c->n_tile_data + 1;
   1332        }
   1333        parse_tile_hdr(c, &gb);
   1334        // Align to the next byte boundary and check for overrun.
   1335        dav1d_bytealign_get_bits(&gb);
   1336        if (gb.error) goto error;
   1337 
   1338        dav1d_data_ref(&c->tile[c->n_tile_data].data, in);
   1339        c->tile[c->n_tile_data].data.data = gb.ptr;
   1340        c->tile[c->n_tile_data].data.sz = (size_t)(gb.ptr_end - gb.ptr);
   1341        // ensure tile groups are in order and sane, see 6.10.1
   1342        if (c->tile[c->n_tile_data].start > c->tile[c->n_tile_data].end ||
   1343            c->tile[c->n_tile_data].start != c->n_tiles)
   1344        {
   1345            for (int i = 0; i <= c->n_tile_data; i++)
   1346                dav1d_data_unref_internal(&c->tile[i].data);
   1347            c->n_tile_data = 0;
   1348            c->n_tiles = 0;
   1349            goto error;
   1350        }
   1351        c->n_tiles += 1 + c->tile[c->n_tile_data].end -
   1352                          c->tile[c->n_tile_data].start;
   1353        c->n_tile_data++;
   1354        break;
   1355    }
   1356    case DAV1D_OBU_METADATA: {
   1357 #define DEBUG_OBU_METADATA 0
   1358 #if DEBUG_OBU_METADATA
   1359        const uint8_t *const init_ptr = gb.ptr;
   1360 #endif
   1361        // obu metadta type field
   1362        const enum ObuMetaType meta_type = dav1d_get_uleb128(&gb);
   1363        if (gb.error) goto error;
   1364 
   1365        switch (meta_type) {
   1366        case OBU_META_HDR_CLL: {
   1367            Dav1dRef *ref = dav1d_ref_create(ALLOC_OBU_META,
   1368                                             sizeof(Dav1dContentLightLevel));
   1369            if (!ref) return DAV1D_ERR(ENOMEM);
   1370            Dav1dContentLightLevel *const content_light = ref->data;
   1371 
   1372            content_light->max_content_light_level = dav1d_get_bits(&gb, 16);
   1373 #if DEBUG_OBU_METADATA
   1374            printf("CLLOBU: max-content-light-level: %d [off=%td]\n",
   1375                   content_light->max_content_light_level,
   1376                   (gb.ptr - init_ptr) * 8 - gb.bits_left);
   1377 #endif
   1378            content_light->max_frame_average_light_level = dav1d_get_bits(&gb, 16);
   1379 #if DEBUG_OBU_METADATA
   1380            printf("CLLOBU: max-frame-average-light-level: %d [off=%td]\n",
   1381                   content_light->max_frame_average_light_level,
   1382                   (gb.ptr - init_ptr) * 8 - gb.bits_left);
   1383 #endif
   1384 
   1385            if (check_trailing_bits(&gb, c->strict_std_compliance) < 0) {
   1386                dav1d_ref_dec(&ref);
   1387                goto error;
   1388            }
   1389 
   1390            dav1d_ref_dec(&c->content_light_ref);
   1391            c->content_light = content_light;
   1392            c->content_light_ref = ref;
   1393            break;
   1394        }
   1395        case OBU_META_HDR_MDCV: {
   1396            Dav1dRef *ref = dav1d_ref_create(ALLOC_OBU_META,
   1397                                             sizeof(Dav1dMasteringDisplay));
   1398            if (!ref) return DAV1D_ERR(ENOMEM);
   1399            Dav1dMasteringDisplay *const mastering_display = ref->data;
   1400 
   1401            for (int i = 0; i < 3; i++) {
   1402                mastering_display->primaries[i][0] = dav1d_get_bits(&gb, 16);
   1403                mastering_display->primaries[i][1] = dav1d_get_bits(&gb, 16);
   1404 #if DEBUG_OBU_METADATA
   1405                printf("MDCVOBU: primaries[%d]: (%d, %d) [off=%td]\n", i,
   1406                       mastering_display->primaries[i][0],
   1407                       mastering_display->primaries[i][1],
   1408                       (gb.ptr - init_ptr) * 8 - gb.bits_left);
   1409 #endif
   1410            }
   1411            mastering_display->white_point[0] = dav1d_get_bits(&gb, 16);
   1412 #if DEBUG_OBU_METADATA
   1413            printf("MDCVOBU: white-point-x: %d [off=%td]\n",
   1414                   mastering_display->white_point[0],
   1415                   (gb.ptr - init_ptr) * 8 - gb.bits_left);
   1416 #endif
   1417            mastering_display->white_point[1] = dav1d_get_bits(&gb, 16);
   1418 #if DEBUG_OBU_METADATA
   1419            printf("MDCVOBU: white-point-y: %d [off=%td]\n",
   1420                   mastering_display->white_point[1],
   1421                   (gb.ptr - init_ptr) * 8 - gb.bits_left);
   1422 #endif
   1423            mastering_display->max_luminance = dav1d_get_bits(&gb, 32);
   1424 #if DEBUG_OBU_METADATA
   1425            printf("MDCVOBU: max-luminance: %d [off=%td]\n",
   1426                   mastering_display->max_luminance,
   1427                   (gb.ptr - init_ptr) * 8 - gb.bits_left);
   1428 #endif
   1429            mastering_display->min_luminance = dav1d_get_bits(&gb, 32);
   1430 #if DEBUG_OBU_METADATA
   1431            printf("MDCVOBU: min-luminance: %d [off=%td]\n",
   1432                   mastering_display->min_luminance,
   1433                   (gb.ptr - init_ptr) * 8 - gb.bits_left);
   1434 #endif
   1435            if (check_trailing_bits(&gb, c->strict_std_compliance) < 0) {
   1436                dav1d_ref_dec(&ref);
   1437                goto error;
   1438            }
   1439 
   1440            dav1d_ref_dec(&c->mastering_display_ref);
   1441            c->mastering_display = mastering_display;
   1442            c->mastering_display_ref = ref;
   1443            break;
   1444        }
   1445        case OBU_META_ITUT_T35: {
   1446            ptrdiff_t payload_size = gb.ptr_end - gb.ptr;
   1447            // Don't take into account all the trailing bits for payload_size
   1448            while (payload_size > 0 && !gb.ptr[payload_size - 1])
   1449                payload_size--; // trailing_zero_bit x 8
   1450            payload_size--; // trailing_one_bit + trailing_zero_bit x 7
   1451 
   1452            int country_code_extension_byte = 0;
   1453            const int country_code = dav1d_get_bits(&gb, 8);
   1454            payload_size--;
   1455            if (country_code == 0xFF) {
   1456                country_code_extension_byte = dav1d_get_bits(&gb, 8);
   1457                payload_size--;
   1458            }
   1459 
   1460            if (payload_size <= 0 || gb.ptr[payload_size] != 0x80) {
   1461                dav1d_log(c, "Malformed ITU-T T.35 metadata message format\n");
   1462                break;
   1463            }
   1464 
   1465            if ((c->n_itut_t35 + 1) > INT_MAX / (int)sizeof(*c->itut_t35)) goto error;
   1466            struct Dav1dITUTT35 *itut_t35 = dav1d_realloc(ALLOC_OBU_META, c->itut_t35,
   1467                                                          (c->n_itut_t35 + 1) * sizeof(*c->itut_t35));
   1468            if (!itut_t35) goto error;
   1469            c->itut_t35 = itut_t35;
   1470            memset(c->itut_t35 + c->n_itut_t35, 0, sizeof(*c->itut_t35));
   1471 
   1472            struct itut_t35_ctx_context *itut_t35_ctx;
   1473            if (!c->n_itut_t35) {
   1474                assert(!c->itut_t35_ref);
   1475                itut_t35_ctx = dav1d_malloc(ALLOC_OBU_META, sizeof(struct itut_t35_ctx_context));
   1476                if (!itut_t35_ctx) goto error;
   1477                c->itut_t35_ref = dav1d_ref_init(&itut_t35_ctx->ref, c->itut_t35,
   1478                                                 dav1d_picture_free_itut_t35, itut_t35_ctx, 0);
   1479            } else {
   1480                assert(c->itut_t35_ref && atomic_load(&c->itut_t35_ref->ref_cnt) == 1);
   1481                itut_t35_ctx = c->itut_t35_ref->user_data;
   1482                c->itut_t35_ref->const_data = (uint8_t *)c->itut_t35;
   1483            }
   1484            itut_t35_ctx->itut_t35 = c->itut_t35;
   1485            itut_t35_ctx->n_itut_t35 = c->n_itut_t35 + 1;
   1486 
   1487            Dav1dITUTT35 *const itut_t35_metadata = &c->itut_t35[c->n_itut_t35];
   1488            itut_t35_metadata->payload = dav1d_malloc(ALLOC_OBU_META, payload_size);
   1489            if (!itut_t35_metadata->payload) goto error;
   1490 
   1491            itut_t35_metadata->country_code = country_code;
   1492            itut_t35_metadata->country_code_extension_byte = country_code_extension_byte;
   1493            itut_t35_metadata->payload_size = payload_size;
   1494 
   1495            // We know that we've read a whole number of bytes and that the
   1496            // payload is within the OBU boundaries, so just use memcpy()
   1497            assert(gb.bits_left == 0);
   1498            memcpy(itut_t35_metadata->payload, gb.ptr, payload_size);
   1499 
   1500            c->n_itut_t35++;
   1501            break;
   1502        }
   1503        case OBU_META_SCALABILITY:
   1504        case OBU_META_TIMECODE:
   1505            // ignore metadata OBUs we don't care about
   1506            break;
   1507        default:
   1508            // print a warning but don't fail for unknown types
   1509            if (meta_type > 31) // Types 6 to 31 are "Unregistered user private", so ignore them.
   1510                dav1d_log(c, "Unknown Metadata OBU type %d\n", meta_type);
   1511            break;
   1512        }
   1513 
   1514        break;
   1515    }
   1516    case DAV1D_OBU_TD:
   1517        c->frame_flags |= PICTURE_FLAG_NEW_TEMPORAL_UNIT;
   1518        break;
   1519    case DAV1D_OBU_PADDING:
   1520        // ignore OBUs we don't care about
   1521        break;
   1522    default:
   1523        // print a warning but don't fail for unknown types
   1524        dav1d_log(c, "Unknown OBU type %d of size %td\n", type, gb.ptr_end - gb.ptr);
   1525        break;
   1526    }
   1527 
   1528    if (c->seq_hdr && c->frame_hdr) {
   1529        if (c->frame_hdr->show_existing_frame) {
   1530            if (!c->refs[c->frame_hdr->existing_frame_idx].p.p.frame_hdr) goto error;
   1531            switch (c->refs[c->frame_hdr->existing_frame_idx].p.p.frame_hdr->frame_type) {
   1532            case DAV1D_FRAME_TYPE_INTER:
   1533            case DAV1D_FRAME_TYPE_SWITCH:
   1534                if (c->decode_frame_type > DAV1D_DECODEFRAMETYPE_REFERENCE)
   1535                    goto skip;
   1536                break;
   1537            case DAV1D_FRAME_TYPE_INTRA:
   1538                if (c->decode_frame_type > DAV1D_DECODEFRAMETYPE_INTRA)
   1539                    goto skip;
   1540                // fall-through
   1541            default:
   1542                break;
   1543            }
   1544            if (!c->refs[c->frame_hdr->existing_frame_idx].p.p.data[0]) goto error;
   1545            if (c->strict_std_compliance &&
   1546                !c->refs[c->frame_hdr->existing_frame_idx].p.showable)
   1547            {
   1548                goto error;
   1549            }
   1550            if (c->n_fc == 1) {
   1551                dav1d_thread_picture_ref(&c->out,
   1552                                         &c->refs[c->frame_hdr->existing_frame_idx].p);
   1553                dav1d_picture_copy_props(&c->out.p,
   1554                                         c->content_light, c->content_light_ref,
   1555                                         c->mastering_display, c->mastering_display_ref,
   1556                                         c->itut_t35, c->itut_t35_ref, c->n_itut_t35,
   1557                                         &in->m);
   1558                // Must be removed from the context after being attached to the frame
   1559                dav1d_ref_dec(&c->itut_t35_ref);
   1560                c->itut_t35 = NULL;
   1561                c->n_itut_t35 = 0;
   1562                c->event_flags |= dav1d_picture_get_event_flags(&c->refs[c->frame_hdr->existing_frame_idx].p);
   1563            } else {
   1564                pthread_mutex_lock(&c->task_thread.lock);
   1565                // need to append this to the frame output queue
   1566                const unsigned next = c->frame_thread.next++;
   1567                if (c->frame_thread.next == c->n_fc)
   1568                    c->frame_thread.next = 0;
   1569 
   1570                Dav1dFrameContext *const f = &c->fc[next];
   1571                while (f->n_tile_data > 0)
   1572                    pthread_cond_wait(&f->task_thread.cond,
   1573                                      &f->task_thread.ttd->lock);
   1574                Dav1dThreadPicture *const out_delayed =
   1575                    &c->frame_thread.out_delayed[next];
   1576                if (out_delayed->p.data[0] || atomic_load(&f->task_thread.error)) {
   1577                    unsigned first = atomic_load(&c->task_thread.first);
   1578                    if (first + 1U < c->n_fc)
   1579                        atomic_fetch_add(&c->task_thread.first, 1U);
   1580                    else
   1581                        atomic_store(&c->task_thread.first, 0);
   1582                    atomic_compare_exchange_strong(&c->task_thread.reset_task_cur,
   1583                                                   &first, UINT_MAX);
   1584                    if (c->task_thread.cur && c->task_thread.cur < c->n_fc)
   1585                        c->task_thread.cur--;
   1586                }
   1587                const int error = f->task_thread.retval;
   1588                if (error) {
   1589                    c->cached_error = error;
   1590                    f->task_thread.retval = 0;
   1591                    dav1d_data_props_copy(&c->cached_error_props, &out_delayed->p.m);
   1592                    dav1d_thread_picture_unref(out_delayed);
   1593                } else if (out_delayed->p.data[0]) {
   1594                    const unsigned progress = atomic_load_explicit(&out_delayed->progress[1],
   1595                                                                   memory_order_relaxed);
   1596                    if ((out_delayed->visible || c->output_invisible_frames) &&
   1597                        progress != FRAME_ERROR)
   1598                    {
   1599                        dav1d_thread_picture_ref(&c->out, out_delayed);
   1600                        c->event_flags |= dav1d_picture_get_event_flags(out_delayed);
   1601                    }
   1602                    dav1d_thread_picture_unref(out_delayed);
   1603                }
   1604                dav1d_thread_picture_ref(out_delayed,
   1605                                         &c->refs[c->frame_hdr->existing_frame_idx].p);
   1606                out_delayed->visible = 1;
   1607                dav1d_picture_copy_props(&out_delayed->p,
   1608                                         c->content_light, c->content_light_ref,
   1609                                         c->mastering_display, c->mastering_display_ref,
   1610                                         c->itut_t35, c->itut_t35_ref, c->n_itut_t35,
   1611                                         &in->m);
   1612                // Must be removed from the context after being attached to the frame
   1613                dav1d_ref_dec(&c->itut_t35_ref);
   1614                c->itut_t35 = NULL;
   1615                c->n_itut_t35 = 0;
   1616 
   1617                pthread_mutex_unlock(&c->task_thread.lock);
   1618            }
   1619            if (c->refs[c->frame_hdr->existing_frame_idx].p.p.frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY) {
   1620                const int r = c->frame_hdr->existing_frame_idx;
   1621                c->refs[r].p.showable = 0;
   1622                for (int i = 0; i < 8; i++) {
   1623                    if (i == r) continue;
   1624 
   1625                    if (c->refs[i].p.p.frame_hdr)
   1626                        dav1d_thread_picture_unref(&c->refs[i].p);
   1627                    dav1d_thread_picture_ref(&c->refs[i].p, &c->refs[r].p);
   1628 
   1629                    dav1d_cdf_thread_unref(&c->cdf[i]);
   1630                    dav1d_cdf_thread_ref(&c->cdf[i], &c->cdf[r]);
   1631 
   1632                    dav1d_ref_dec(&c->refs[i].segmap);
   1633                    c->refs[i].segmap = c->refs[r].segmap;
   1634                    if (c->refs[r].segmap)
   1635                        dav1d_ref_inc(c->refs[r].segmap);
   1636                    dav1d_ref_dec(&c->refs[i].refmvs);
   1637                }
   1638            }
   1639            c->frame_hdr = NULL;
   1640        } else if (c->n_tiles == c->frame_hdr->tiling.cols * c->frame_hdr->tiling.rows) {
   1641            switch (c->frame_hdr->frame_type) {
   1642            case DAV1D_FRAME_TYPE_INTER:
   1643            case DAV1D_FRAME_TYPE_SWITCH:
   1644                if (c->decode_frame_type > DAV1D_DECODEFRAMETYPE_REFERENCE ||
   1645                    (c->decode_frame_type == DAV1D_DECODEFRAMETYPE_REFERENCE &&
   1646                     !c->frame_hdr->refresh_frame_flags))
   1647                    goto skip;
   1648                break;
   1649            case DAV1D_FRAME_TYPE_INTRA:
   1650                if (c->decode_frame_type > DAV1D_DECODEFRAMETYPE_INTRA ||
   1651                    (c->decode_frame_type == DAV1D_DECODEFRAMETYPE_REFERENCE &&
   1652                     !c->frame_hdr->refresh_frame_flags))
   1653                    goto skip;
   1654                // fall-through
   1655            default:
   1656                break;
   1657            }
   1658            if (!c->n_tile_data)
   1659                goto error;
   1660            if ((res = dav1d_submit_frame(c)) < 0)
   1661                return res;
   1662            assert(!c->n_tile_data);
   1663            c->frame_hdr = NULL;
   1664            c->n_tiles = 0;
   1665        }
   1666    }
   1667 
   1668    return gb.ptr_end - gb.ptr_start;
   1669 
   1670 skip:
   1671    // update refs with only the headers in case we skip the frame
   1672    for (int i = 0; i < 8; i++) {
   1673        if (c->frame_hdr->refresh_frame_flags & (1 << i)) {
   1674            dav1d_thread_picture_unref(&c->refs[i].p);
   1675            c->refs[i].p.p.frame_hdr = c->frame_hdr;
   1676            c->refs[i].p.p.seq_hdr = c->seq_hdr;
   1677            c->refs[i].p.p.frame_hdr_ref = c->frame_hdr_ref;
   1678            c->refs[i].p.p.seq_hdr_ref = c->seq_hdr_ref;
   1679            dav1d_ref_inc(c->frame_hdr_ref);
   1680            dav1d_ref_inc(c->seq_hdr_ref);
   1681        }
   1682    }
   1683 
   1684    dav1d_ref_dec(&c->frame_hdr_ref);
   1685    c->frame_hdr = NULL;
   1686    c->n_tiles = 0;
   1687 
   1688    return gb.ptr_end - gb.ptr_start;
   1689 
   1690 error:
   1691    dav1d_data_props_copy(&c->cached_error_props, &in->m);
   1692    dav1d_log(c, gb.error ? "Overrun in OBU bit buffer\n" :
   1693                            "Error parsing OBU data\n");
   1694    return DAV1D_ERR(EINVAL);
   1695 }