tor-browser

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

pps_parser.cc (6377B)


      1 /*
      2 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "common_video/h264/pps_parser.h"
     12 
     13 #include <cstdint>
     14 #include <limits>
     15 #include <optional>
     16 #include <vector>
     17 
     18 #include "absl/numeric/bits.h"
     19 #include "api/array_view.h"
     20 #include "common_video/h264/h264_common.h"
     21 #include "rtc_base/bitstream_reader.h"
     22 #include "rtc_base/checks.h"
     23 
     24 namespace webrtc {
     25 namespace {
     26 constexpr int kMaxPicInitQpDeltaValue = 25;
     27 constexpr int kMinPicInitQpDeltaValue = -26;
     28 }  // namespace
     29 
     30 // General note: this is based off the 02/2014 version of the H.264 standard.
     31 // You can find it on this page:
     32 // http://www.itu.int/rec/T-REC-H.264
     33 
     34 std::optional<PpsParser::PpsState> PpsParser::ParsePps(
     35    ArrayView<const uint8_t> data) {
     36  // First, parse out rbsp, which is basically the source buffer minus emulation
     37  // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
     38  // section 7.3.1 of the H.264 standard.
     39  return ParseInternal(H264::ParseRbsp(data));
     40 }
     41 
     42 bool PpsParser::ParsePpsIds(ArrayView<const uint8_t> data,
     43                            uint32_t* pps_id,
     44                            uint32_t* sps_id) {
     45  RTC_DCHECK(pps_id);
     46  RTC_DCHECK(sps_id);
     47  // First, parse out rbsp, which is basically the source buffer minus emulation
     48  // bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
     49  // section 7.3.1 of the H.264 standard.
     50  std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data);
     51  BitstreamReader reader(unpacked_buffer);
     52  *pps_id = reader.ReadExponentialGolomb();
     53  *sps_id = reader.ReadExponentialGolomb();
     54  return reader.Ok();
     55 }
     56 
     57 std::optional<PpsParser::SliceHeader> PpsParser::ParseSliceHeader(
     58    ArrayView<const uint8_t> data) {
     59  std::vector<uint8_t> unpacked_buffer = H264::ParseRbsp(data);
     60  BitstreamReader slice_reader(unpacked_buffer);
     61  PpsParser::SliceHeader slice_header;
     62 
     63  // first_mb_in_slice: ue(v)
     64  slice_header.first_mb_in_slice = slice_reader.ReadExponentialGolomb();
     65  // slice_type: ue(v)
     66  slice_reader.ReadExponentialGolomb();
     67  // pic_parameter_set_id: ue(v)
     68  slice_header.pic_parameter_set_id = slice_reader.ReadExponentialGolomb();
     69 
     70  // The rest of the slice header requires information from the SPS to parse.
     71 
     72  if (!slice_reader.Ok()) {
     73    return std::nullopt;
     74  }
     75  return slice_header;
     76 }
     77 
     78 std::optional<PpsParser::PpsState> PpsParser::ParseInternal(
     79    ArrayView<const uint8_t> buffer) {
     80  BitstreamReader reader(buffer);
     81  PpsState pps;
     82  pps.id = reader.ReadExponentialGolomb();
     83  pps.sps_id = reader.ReadExponentialGolomb();
     84 
     85  // entropy_coding_mode_flag: u(1)
     86  pps.entropy_coding_mode_flag = reader.Read<bool>();
     87  // bottom_field_pic_order_in_frame_present_flag: u(1)
     88  pps.bottom_field_pic_order_in_frame_present_flag = reader.Read<bool>();
     89 
     90  // num_slice_groups_minus1: ue(v)
     91  uint32_t num_slice_groups_minus1 = reader.ReadExponentialGolomb();
     92  if (num_slice_groups_minus1 > 0) {
     93    // slice_group_map_type: ue(v)
     94    uint32_t slice_group_map_type = reader.ReadExponentialGolomb();
     95    if (slice_group_map_type == 0) {
     96      for (uint32_t i_group = 0;
     97           i_group <= num_slice_groups_minus1 && reader.Ok(); ++i_group) {
     98        // run_length_minus1[iGroup]: ue(v)
     99        reader.ReadExponentialGolomb();
    100      }
    101    } else if (slice_group_map_type == 1) {
    102      // TODO(sprang): Implement support for dispersed slice group map type.
    103      // See 8.2.2.2 Specification for dispersed slice group map type.
    104    } else if (slice_group_map_type == 2) {
    105      for (uint32_t i_group = 0;
    106           i_group <= num_slice_groups_minus1 && reader.Ok(); ++i_group) {
    107        // top_left[iGroup]: ue(v)
    108        reader.ReadExponentialGolomb();
    109        // bottom_right[iGroup]: ue(v)
    110        reader.ReadExponentialGolomb();
    111      }
    112    } else if (slice_group_map_type == 3 || slice_group_map_type == 4 ||
    113               slice_group_map_type == 5) {
    114      // slice_group_change_direction_flag: u(1)
    115      reader.ConsumeBits(1);
    116      // slice_group_change_rate_minus1: ue(v)
    117      reader.ReadExponentialGolomb();
    118    } else if (slice_group_map_type == 6) {
    119      // pic_size_in_map_units_minus1: ue(v)
    120      uint32_t pic_size_in_map_units = reader.ReadExponentialGolomb() + 1;
    121      int slice_group_id_bits = 1 + absl::bit_width(num_slice_groups_minus1);
    122 
    123      // slice_group_id: array of size pic_size_in_map_units, each element
    124      // is represented by ceil(log2(num_slice_groups_minus1 + 1)) bits.
    125      int64_t bits_to_consume =
    126          int64_t{slice_group_id_bits} * pic_size_in_map_units;
    127      if (!reader.Ok() || bits_to_consume > std::numeric_limits<int>::max()) {
    128        return std::nullopt;
    129      }
    130      reader.ConsumeBits(bits_to_consume);
    131    }
    132  }
    133  // num_ref_idx_l0_default_active_minus1: ue(v)
    134  pps.num_ref_idx_l0_default_active_minus1 = reader.ReadExponentialGolomb();
    135  // num_ref_idx_l1_default_active_minus1: ue(v)
    136  pps.num_ref_idx_l1_default_active_minus1 = reader.ReadExponentialGolomb();
    137  if (!reader.Ok() ||
    138      pps.num_ref_idx_l0_default_active_minus1 > H264::kMaxReferenceIndex ||
    139      pps.num_ref_idx_l1_default_active_minus1 > H264::kMaxReferenceIndex) {
    140    return std::nullopt;
    141  }
    142  // weighted_pred_flag: u(1)
    143  pps.weighted_pred_flag = reader.Read<bool>();
    144  // weighted_bipred_idc: u(2)
    145  pps.weighted_bipred_idc = reader.ReadBits(2);
    146 
    147  // pic_init_qp_minus26: se(v)
    148  pps.pic_init_qp_minus26 = reader.ReadSignedExponentialGolomb();
    149  // Sanity-check parsed value
    150  if (!reader.Ok() || pps.pic_init_qp_minus26 > kMaxPicInitQpDeltaValue ||
    151      pps.pic_init_qp_minus26 < kMinPicInitQpDeltaValue) {
    152    return std::nullopt;
    153  }
    154  // pic_init_qs_minus26: se(v)
    155  reader.ReadExponentialGolomb();
    156  // chroma_qp_index_offset: se(v)
    157  reader.ReadExponentialGolomb();
    158  // deblocking_filter_control_present_flag: u(1)
    159  // constrained_intra_pred_flag: u(1)
    160  reader.ConsumeBits(2);
    161  // redundant_pic_cnt_present_flag: u(1)
    162  pps.redundant_pic_cnt_present_flag = reader.ReadBit();
    163  if (!reader.Ok()) {
    164    return std::nullopt;
    165  }
    166 
    167  return pps;
    168 }
    169 
    170 }  // namespace webrtc