/*
 *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "modules/video_coding/utility/vp9_uncompressed_header_parser.h"

#include "absl/strings/string_view.h"
#include "rtc_base/bit_buffer.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {

// Evaluates x and returns false if false.
#define RETURN_IF_FALSE(x) \
  if (!(x)) {              \
    return false;          \
  }

// Evaluates x, which is intended to return an optional. If result is nullopt,
// returns false. Else, calls fun() with the dereferenced optional as parameter.
#define READ_OR_RETURN(x, fun)     \
  do {                             \
    if (auto optional_val = (x)) { \
      fun(*optional_val);          \
    } else {                       \
      return false;                \
    }                              \
  } while (false)

namespace {
const size_t kVp9NumRefsPerFrame = 3;
const size_t kVp9MaxRefLFDeltas = 4;
const size_t kVp9MaxModeLFDeltas = 2;
const size_t kVp9MinTileWidthB64 = 4;
const size_t kVp9MaxTileWidthB64 = 64;

class BitstreamReader {
 public:
  explicit BitstreamReader(rtc::BitBuffer* buffer) : buffer_(buffer) {}

  // Reads on bit from the input stream and:
  // * returns false if bit cannot be read
  // * calls f_true() if bit is true, returns return value of that function
  // * calls f_else() if bit is false, returns return value of that function
  bool IfNextBoolean(
      std::function<bool()> f_true,
      std::function<bool()> f_false = [] { return true; }) {
    uint32_t val;
    if (!buffer_->ReadBits(1, val)) {
      return false;
    }
    if (val != 0) {
      return f_true();
    }
    return f_false();
  }

  absl::optional<bool> ReadBoolean() {
    uint32_t val;
    if (!buffer_->ReadBits(1, val)) {
      return {};
    }
    return {val != 0};
  }

  // Reads a bit from the input stream and returns:
  // * false if bit cannot be read
  // * true if bit matches expected_val
  // * false if bit does not match expected_val - in which case `error_msg` is
  //   logged as warning, if provided.
  bool VerifyNextBooleanIs(bool expected_val, absl::string_view error_msg) {
    uint32_t val;
    if (!buffer_->ReadBits(1, val)) {
      return false;
    }
    if ((val != 0) != expected_val) {
      if (!error_msg.empty()) {
        RTC_LOG(LS_WARNING) << error_msg;
      }
      return false;
    }
    return true;
  }

  // Reads `bits` bits from the bitstream and interprets them as an unsigned
  // integer that gets cast to the type T before returning.
  // Returns nullopt if all bits cannot be read.
  // If number of bits matches size of data type, the bits parameter may be
  // omitted. Ex:
  //  ReadUnsigned<uint8_t>(2);  // Returns uint8_t with 2 LSB populated.
  //  ReadUnsigned<uint8_t>();   // Returns uint8_t with all 8 bits populated.
  template <typename T>
  absl::optional<T> ReadUnsigned(int bits = sizeof(T) * 8) {
    RTC_DCHECK_LE(bits, 32);
    RTC_DCHECK_LE(bits, sizeof(T) * 8);
    uint32_t val;
    if (!buffer_->ReadBits(bits, val)) {
      return {};
    }
    return (static_cast<T>(val));
  }

  // Helper method that reads `num_bits` from the bitstream, returns:
  // * false if bits cannot be read.
  // * true if `expected_val` matches the read bits
  // * false if `expected_val` does not match the read bits, and logs
  //   `error_msg` as a warning (if provided).
  bool VerifyNextUnsignedIs(int num_bits,
                            uint32_t expected_val,
                            absl::string_view error_msg) {
    uint32_t val;
    if (!buffer_->ReadBits(num_bits, val)) {
      return false;
    }
    if (val != expected_val) {
      if (!error_msg.empty()) {
        RTC_LOG(LS_WARNING) << error_msg;
      }
      return false;
    }
    return true;
  }

  // Basically the same as ReadUnsigned() - but for signed integers.
  // Here `bits` indicates the size of the value - number of bits read from the
  // bit buffer is one higher (the sign bit). This is made to matche the spec in
  // which eg s(4) = f(1) sign-bit, plus an f(4).
  template <typename T>
  absl::optional<T> ReadSigned(int bits = sizeof(T) * 8) {
    uint32_t sign;
    if (!buffer_->ReadBits(1, sign)) {
      return {};
    }
    uint32_t val;
    if (!buffer_->ReadBits(bits, val)) {
      return {};
    }
    int64_t sign_val = val;
    if (sign != 0) {
      sign_val = -sign_val;
    }
    return {static_cast<T>(sign_val)};
  }

  // Reads `bits` from the bitstream, disregarding their value.
  // Returns true if full number of bits were read, false otherwise.
  bool ConsumeBits(int bits) { return buffer_->ConsumeBits(bits); }

  void GetPosition(size_t* out_byte_offset, size_t* out_bit_offset) const {
    buffer_->GetCurrentOffset(out_byte_offset, out_bit_offset);
  }

 private:
  rtc::BitBuffer* buffer_;
};

bool Vp9ReadColorConfig(BitstreamReader* br,
                        Vp9UncompressedHeader* frame_info) {
  if (frame_info->profile == 2 || frame_info->profile == 3) {
    READ_OR_RETURN(br->ReadBoolean(), [frame_info](bool ten_or_twelve_bits) {
      frame_info->bit_detph =
          ten_or_twelve_bits ? Vp9BitDept::k12Bit : Vp9BitDept::k10Bit;
    });
  } else {
    frame_info->bit_detph = Vp9BitDept::k8Bit;
  }

  READ_OR_RETURN(
      br->ReadUnsigned<uint8_t>(3), [frame_info](uint8_t color_space) {
        frame_info->color_space = static_cast<Vp9ColorSpace>(color_space);
      });

  if (frame_info->color_space != Vp9ColorSpace::CS_RGB) {
    READ_OR_RETURN(br->ReadBoolean(), [frame_info](bool color_range) {
      frame_info->color_range =
          color_range ? Vp9ColorRange::kFull : Vp9ColorRange::kStudio;
    });

    if (frame_info->profile == 1 || frame_info->profile == 3) {
      READ_OR_RETURN(br->ReadUnsigned<uint8_t>(2),
                     [frame_info](uint8_t subsampling) {
                       switch (subsampling) {
                         case 0b00:
                           frame_info->sub_sampling = Vp9YuvSubsampling::k444;
                           break;
                         case 0b01:
                           frame_info->sub_sampling = Vp9YuvSubsampling::k440;
                           break;
                         case 0b10:
                           frame_info->sub_sampling = Vp9YuvSubsampling::k422;
                           break;
                         case 0b11:
                           frame_info->sub_sampling = Vp9YuvSubsampling::k420;
                           break;
                       }
                     });

      RETURN_IF_FALSE(br->VerifyNextBooleanIs(
          0, "Failed to parse header. Reserved bit set."));
    } else {
      // Profile 0 or 2.
      frame_info->sub_sampling = Vp9YuvSubsampling::k420;
    }
  } else {
    // SRGB
    frame_info->color_range = Vp9ColorRange::kFull;
    if (frame_info->profile == 1 || frame_info->profile == 3) {
      frame_info->sub_sampling = Vp9YuvSubsampling::k444;
      RETURN_IF_FALSE(br->VerifyNextBooleanIs(
          0, "Failed to parse header. Reserved bit set."));
    } else {
      RTC_LOG(LS_WARNING) << "Failed to parse header. 4:4:4 color not supported"
                             " in profile 0 or 2.";
      return false;
    }
  }

  return true;
}

bool ReadRefreshFrameFlags(BitstreamReader* br,
                           Vp9UncompressedHeader* frame_info) {
  // Refresh frame flags.
  READ_OR_RETURN(br->ReadUnsigned<uint8_t>(), [frame_info](uint8_t flags) {
    for (int i = 0; i < 8; ++i) {
      frame_info->updated_buffers.set(i, (flags & (0x01 << (7 - i))) != 0);
    }
  });
  return true;
}

bool Vp9ReadFrameSize(BitstreamReader* br, Vp9UncompressedHeader* frame_info) {
  // 16 bits: frame (width|height) - 1.
  READ_OR_RETURN(br->ReadUnsigned<uint16_t>(), [frame_info](uint16_t width) {
    frame_info->frame_width = width + 1;
  });
  READ_OR_RETURN(br->ReadUnsigned<uint16_t>(), [frame_info](uint16_t height) {
    frame_info->frame_height = height + 1;
  });
  return true;
}

bool Vp9ReadRenderSize(BitstreamReader* br, Vp9UncompressedHeader* frame_info) {
  // render_and_frame_size_different
  return br->IfNextBoolean(
      [&] {
        auto& pos = frame_info->render_size_position.emplace();
        br->GetPosition(&pos.byte_offset, &pos.bit_offset);
        // 16 bits: render (width|height) - 1.
        READ_OR_RETURN(br->ReadUnsigned<uint16_t>(),
                       [frame_info](uint16_t width) {
                         frame_info->render_width = width + 1;
                       });
        READ_OR_RETURN(br->ReadUnsigned<uint16_t>(),
                       [frame_info](uint16_t height) {
                         frame_info->render_height = height + 1;
                       });
        return true;
      },
      /*else*/
      [&] {
        frame_info->render_height = frame_info->frame_height;
        frame_info->render_width = frame_info->frame_width;
        return true;
      });
}

bool Vp9ReadFrameSizeFromRefs(BitstreamReader* br,
                              Vp9UncompressedHeader* frame_info) {
  bool found_ref = false;
  for (size_t i = 0; !found_ref && i < kVp9NumRefsPerFrame; i++) {
    // Size in refs.
    br->IfNextBoolean([&] {
      frame_info->infer_size_from_reference = frame_info->reference_buffers[i];
      found_ref = true;
      return true;
    });
  }

  if (!found_ref) {
    if (!Vp9ReadFrameSize(br, frame_info)) {
      return false;
    }
  }
  return Vp9ReadRenderSize(br, frame_info);
}

bool Vp9ReadLoopfilter(BitstreamReader* br) {
  // 6 bits: filter level.
  // 3 bits: sharpness level.
  RETURN_IF_FALSE(br->ConsumeBits(9));

  return br->IfNextBoolean([&] {    // if mode_ref_delta_enabled
    return br->IfNextBoolean([&] {  // if mode_ref_delta_update
      for (size_t i = 0; i < kVp9MaxRefLFDeltas; i++) {
        RETURN_IF_FALSE(br->IfNextBoolean([&] { return br->ConsumeBits(7); }));
      }
      for (size_t i = 0; i < kVp9MaxModeLFDeltas; i++) {
        RETURN_IF_FALSE(br->IfNextBoolean([&] { return br->ConsumeBits(7); }));
      }
      return true;
    });
  });
}

bool Vp9ReadQp(BitstreamReader* br, Vp9UncompressedHeader* frame_info) {
  READ_OR_RETURN(br->ReadUnsigned<uint8_t>(),
                 [frame_info](uint8_t qp) { frame_info->base_qp = qp; });

  // yuv offsets
  frame_info->is_lossless = frame_info->base_qp == 0;
  for (int i = 0; i < 3; ++i) {
    RETURN_IF_FALSE(br->IfNextBoolean([&] {  // if delta_coded
      READ_OR_RETURN(br->ReadUnsigned<int>(4), [&](int delta) {
        if (delta != 0) {
          frame_info->is_lossless = false;
        }
      });
      return true;
    }));
  }
  return true;
}

bool Vp9ReadSegmentationParams(BitstreamReader* br,
                               Vp9UncompressedHeader* frame_info) {
  constexpr int kSegmentationFeatureBits[kVp9SegLvlMax] = {8, 6, 2, 0};
  constexpr bool kSegmentationFeatureSigned[kVp9SegLvlMax] = {1, 1, 0, 0};

  return br->IfNextBoolean([&] {  // segmentation_enabled
    frame_info->segmentation_enabled = true;
    RETURN_IF_FALSE(br->IfNextBoolean([&] {  // update_map
      frame_info->segmentation_tree_probs.emplace();
      for (int i = 0; i < 7; ++i) {
        RETURN_IF_FALSE(br->IfNextBoolean(
            [&] {
              READ_OR_RETURN(br->ReadUnsigned<uint8_t>(), [&](uint8_t prob) {
                (*frame_info->segmentation_tree_probs)[i] = prob;
              });
              return true;
            },
            [&] {
              (*frame_info->segmentation_tree_probs)[i] = 255;
              return true;
            }));
      }

      // temporal_update
      frame_info->segmentation_pred_prob.emplace();
      return br->IfNextBoolean(
          [&] {
            for (int i = 0; i < 3; ++i) {
              RETURN_IF_FALSE(br->IfNextBoolean(
                  [&] {
                    READ_OR_RETURN(
                        br->ReadUnsigned<uint8_t>(), [&](uint8_t prob) {
                          (*frame_info->segmentation_pred_prob)[i] = prob;
                        });
                    return true;
                  },
                  [&] {
                    (*frame_info->segmentation_pred_prob)[i] = 255;
                    return true;
                  }));
            }
            return true;
          },
          [&] {
            frame_info->segmentation_pred_prob->fill(255);
            return true;
          });
    }));

    return br->IfNextBoolean([&] {  // segmentation_update_data
      RETURN_IF_FALSE(br->IfNextBoolean([&] {
        frame_info->segmentation_is_delta = true;
        return true;
      }));

      for (size_t i = 0; i < kVp9MaxSegments; ++i) {
        for (size_t j = 0; j < kVp9SegLvlMax; ++j) {
          RETURN_IF_FALSE(br->IfNextBoolean([&] {  // feature_enabled
            if (kSegmentationFeatureBits[j] == 0) {
              // No feature bits used and no sign, just mark it and return.
              frame_info->segmentation_features[i][j] = 1;
              return true;
            }
            READ_OR_RETURN(
                br->ReadUnsigned<uint8_t>(kSegmentationFeatureBits[j]),
                [&](uint8_t feature_value) {
                  frame_info->segmentation_features[i][j] = feature_value;
                });
            if (kSegmentationFeatureSigned[j]) {
              RETURN_IF_FALSE(br->IfNextBoolean([&] {
                (*frame_info->segmentation_features[i][j]) *= -1;
                return true;
              }));
            }
            return true;
          }));
        }
      }
      return true;
    });
  });
}

bool Vp9ReadTileInfo(BitstreamReader* br, Vp9UncompressedHeader* frame_info) {
  size_t mi_cols = (frame_info->frame_width + 7) >> 3;
  size_t sb64_cols = (mi_cols + 7) >> 3;

  size_t min_log2 = 0;
  while ((kVp9MaxTileWidthB64 << min_log2) < sb64_cols) {
    ++min_log2;
  }

  size_t max_log2 = 1;
  while ((sb64_cols >> max_log2) >= kVp9MinTileWidthB64) {
    ++max_log2;
  }
  --max_log2;

  frame_info->tile_cols_log2 = min_log2;
  bool done = false;
  while (!done && frame_info->tile_cols_log2 < max_log2) {
    RETURN_IF_FALSE(br->IfNextBoolean(
        [&] {
          ++frame_info->tile_cols_log2;
          return true;
        },
        [&] {
          done = true;
          return true;
        }));
  }
  frame_info->tile_rows_log2 = 0;
  RETURN_IF_FALSE(br->IfNextBoolean([&] {
    ++frame_info->tile_rows_log2;
    return br->IfNextBoolean([&] {
      ++frame_info->tile_rows_log2;
      return true;
    });
  }));
  return true;
}

const Vp9InterpolationFilter kLiteralToType[4] = {
    Vp9InterpolationFilter::kEightTapSmooth, Vp9InterpolationFilter::kEightTap,
    Vp9InterpolationFilter::kEightTapSharp, Vp9InterpolationFilter::kBilinear};
}  // namespace

std::string Vp9UncompressedHeader::ToString() const {
  char buf[1024];
  rtc::SimpleStringBuilder oss(buf);

  oss << "Vp9UncompressedHeader { "
      << "profile = " << profile;

  if (show_existing_frame) {
    oss << ", show_existing_frame = " << *show_existing_frame << " }";
    return oss.str();
  }

  oss << ", frame type = " << (is_keyframe ? "key" : "delta")
      << ", show_frame = " << (show_frame ? "true" : "false")
      << ", error_resilient = " << (error_resilient ? "true" : "false");

  oss << ", bit_depth = ";
  switch (bit_detph) {
    case Vp9BitDept::k8Bit:
      oss << "8bit";
      break;
    case Vp9BitDept::k10Bit:
      oss << "10bit";
      break;
    case Vp9BitDept::k12Bit:
      oss << "12bit";
      break;
  }

  if (color_space) {
    oss << ", color_space = ";
    switch (*color_space) {
      case Vp9ColorSpace::CS_UNKNOWN:
        oss << "unknown";
        break;
      case Vp9ColorSpace::CS_BT_601:
        oss << "CS_BT_601 Rec. ITU-R BT.601-7";
        break;
      case Vp9ColorSpace::CS_BT_709:
        oss << "Rec. ITU-R BT.709-6";
        break;
      case Vp9ColorSpace::CS_SMPTE_170:
        oss << "SMPTE-170";
        break;
      case Vp9ColorSpace::CS_SMPTE_240:
        oss << "SMPTE-240";
        break;
      case Vp9ColorSpace::CS_BT_2020:
        oss << "Rec. ITU-R BT.2020-2";
        break;
      case Vp9ColorSpace::CS_RESERVED:
        oss << "Reserved";
        break;
      case Vp9ColorSpace::CS_RGB:
        oss << "sRGB (IEC 61966-2-1)";
        break;
    }
  }

  if (color_range) {
    oss << ", color_range = ";
    switch (*color_range) {
      case Vp9ColorRange::kFull:
        oss << "full";
        break;
      case Vp9ColorRange::kStudio:
        oss << "studio";
        break;
    }
  }

  if (sub_sampling) {
    oss << ", sub_sampling = ";
    switch (*sub_sampling) {
      case Vp9YuvSubsampling::k444:
        oss << "444";
        break;
      case Vp9YuvSubsampling::k440:
        oss << "440";
        break;
      case Vp9YuvSubsampling::k422:
        oss << "422";
        break;
      case Vp9YuvSubsampling::k420:
        oss << "420";
        break;
    }
  }

  if (infer_size_from_reference) {
    oss << ", infer_frame_resolution_from = " << *infer_size_from_reference;
  } else {
    oss << ", frame_width = " << frame_width
        << ", frame_height = " << frame_height;
  }
  if (render_width != 0 && render_height != 0) {
    oss << ", render_width = " << render_width
        << ", render_height = " << render_height;
  }

  oss << ", base qp = " << base_qp;
  if (reference_buffers[0] != -1) {
    oss << ", last_buffer = " << reference_buffers[0];
  }
  if (reference_buffers[1] != -1) {
    oss << ", golden_buffer = " << reference_buffers[1];
  }
  if (reference_buffers[2] != -1) {
    oss << ", altref_buffer = " << reference_buffers[2];
  }

  oss << ", updated buffers = { ";
  bool first = true;
  for (int i = 0; i < 8; ++i) {
    if (updated_buffers.test(i)) {
      if (first) {
        first = false;
      } else {
        oss << ", ";
      }
      oss << i;
    }
  }
  oss << " }";

  oss << ", compressed_header_size_bytes = " << compressed_header_size;

  oss << " }";
  return oss.str();
}

bool Parse(rtc::ArrayView<const uint8_t> buf,
           Vp9UncompressedHeader* frame_info,
           bool qp_only) {
  rtc::BitBuffer bit_buffer(buf.data(), buf.size());
  BitstreamReader br(&bit_buffer);

  // Frame marker.
  RETURN_IF_FALSE(br.VerifyNextUnsignedIs(
      2, 0x2, "Failed to parse header. Frame marker should be 2."));

  // Profile has low bit first.
  READ_OR_RETURN(br.ReadBoolean(),
                 [frame_info](bool low) { frame_info->profile = int{low}; });
  READ_OR_RETURN(br.ReadBoolean(), [frame_info](bool high) {
    frame_info->profile |= int{high} << 1;
  });
  if (frame_info->profile > 2) {
    RETURN_IF_FALSE(br.VerifyNextBooleanIs(
        false, "Failed to get QP. Unsupported bitstream profile."));
  }

  // Show existing frame.
  RETURN_IF_FALSE(br.IfNextBoolean([&] {
    READ_OR_RETURN(br.ReadUnsigned<uint8_t>(3),
                   [frame_info](uint8_t frame_idx) {
                     frame_info->show_existing_frame = frame_idx;
                   });
    return true;
  }));
  if (frame_info->show_existing_frame.has_value()) {
    return true;
  }

  READ_OR_RETURN(br.ReadBoolean(), [frame_info](bool frame_type) {
    // Frame type: KEY_FRAME(0), INTER_FRAME(1).
    frame_info->is_keyframe = frame_type == 0;
  });
  READ_OR_RETURN(br.ReadBoolean(), [frame_info](bool show_frame) {
    frame_info->show_frame = show_frame;
  });
  READ_OR_RETURN(br.ReadBoolean(), [frame_info](bool error_resilient) {
    frame_info->error_resilient = error_resilient;
  });

  if (frame_info->is_keyframe) {
    RETURN_IF_FALSE(br.VerifyNextUnsignedIs(
        24, 0x498342, "Failed to get QP. Invalid sync code."));

    if (!Vp9ReadColorConfig(&br, frame_info))
      return false;
    if (!Vp9ReadFrameSize(&br, frame_info))
      return false;
    if (!Vp9ReadRenderSize(&br, frame_info))
      return false;

    // Key-frames implicitly update all buffers.
    frame_info->updated_buffers.set();
  } else {
    // Non-keyframe.
    bool is_intra_only = false;
    if (!frame_info->show_frame) {
      READ_OR_RETURN(br.ReadBoolean(),
                     [&](bool intra_only) { is_intra_only = intra_only; });
    }
    if (!frame_info->error_resilient) {
      RETURN_IF_FALSE(br.ConsumeBits(2));  // Reset frame context.
    }

    if (is_intra_only) {
      RETURN_IF_FALSE(br.VerifyNextUnsignedIs(
          24, 0x498342, "Failed to get QP. Invalid sync code."));

      if (frame_info->profile > 0) {
        if (!Vp9ReadColorConfig(&br, frame_info))
          return false;
      } else {
        frame_info->color_space = Vp9ColorSpace::CS_BT_601;
        frame_info->sub_sampling = Vp9YuvSubsampling::k420;
        frame_info->bit_detph = Vp9BitDept::k8Bit;
      }
      frame_info->reference_buffers.fill(-1);
      RETURN_IF_FALSE(ReadRefreshFrameFlags(&br, frame_info));
      RETURN_IF_FALSE(Vp9ReadFrameSize(&br, frame_info));
      RETURN_IF_FALSE(Vp9ReadRenderSize(&br, frame_info));
    } else {
      RETURN_IF_FALSE(ReadRefreshFrameFlags(&br, frame_info));

      frame_info->reference_buffers_sign_bias[0] = false;
      for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
        READ_OR_RETURN(br.ReadUnsigned<uint8_t>(3), [&](uint8_t idx) {
          frame_info->reference_buffers[i] = idx;
        });
        READ_OR_RETURN(br.ReadBoolean(), [&](bool sign_bias) {
          frame_info
              ->reference_buffers_sign_bias[Vp9ReferenceFrame::kLast + i] =
              sign_bias;
        });
      }

      if (!Vp9ReadFrameSizeFromRefs(&br, frame_info))
        return false;

      READ_OR_RETURN(br.ReadBoolean(), [&](bool allow_high_precision_mv) {
        frame_info->allow_high_precision_mv = allow_high_precision_mv;
      });

      // Interpolation filter.
      RETURN_IF_FALSE(br.IfNextBoolean(
          [frame_info] {
            frame_info->interpolation_filter =
                Vp9InterpolationFilter::kSwitchable;
            return true;
          },
          [&] {
            READ_OR_RETURN(
                br.ReadUnsigned<uint8_t>(2), [frame_info](uint8_t filter) {
                  frame_info->interpolation_filter = kLiteralToType[filter];
                });
            return true;
          }));
    }
  }

  if (!frame_info->error_resilient) {
    // 1 bit: Refresh frame context.
    // 1 bit: Frame parallel decoding mode.
    RETURN_IF_FALSE(br.ConsumeBits(2));
  }

  // Frame context index.
  READ_OR_RETURN(br.ReadUnsigned<uint8_t>(2),
                 [&](uint8_t idx) { frame_info->frame_context_idx = idx; });

  if (!Vp9ReadLoopfilter(&br))
    return false;

  // Read base QP.
  RETURN_IF_FALSE(Vp9ReadQp(&br, frame_info));

  if (qp_only) {
    // Not interested in the rest of the header, return early.
    return true;
  }

  RETURN_IF_FALSE(Vp9ReadSegmentationParams(&br, frame_info));
  RETURN_IF_FALSE(Vp9ReadTileInfo(&br, frame_info));
  READ_OR_RETURN(br.ReadUnsigned<uint16_t>(), [frame_info](uint16_t size) {
    frame_info->compressed_header_size = size;
  });

  // Trailing bits.
  RETURN_IF_FALSE(br.ConsumeBits(bit_buffer.RemainingBitCount() % 8));
  frame_info->uncompressed_header_size =
      buf.size() - (bit_buffer.RemainingBitCount() / 8);

  return true;
}

absl::optional<Vp9UncompressedHeader> ParseUncompressedVp9Header(
    rtc::ArrayView<const uint8_t> buf) {
  Vp9UncompressedHeader frame_info;
  if (Parse(buf, &frame_info, /*qp_only=*/false) &&
      frame_info.frame_width > 0) {
    return frame_info;
  }
  return absl::nullopt;
}

namespace vp9 {

bool GetQp(const uint8_t* buf, size_t length, int* qp) {
  Vp9UncompressedHeader frame_info;
  if (!Parse(rtc::MakeArrayView(buf, length), &frame_info, /*qp_only=*/true)) {
    return false;
  }
  *qp = frame_info.base_qp;
  return true;
}

}  // namespace vp9
}  // namespace webrtc
