/*
 *  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"

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 vp9 {
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); }

 private:
  rtc::BitBuffer* buffer_;
};

bool Vp9ReadColorConfig(BitstreamReader* br, FrameInfo* 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 ? BitDept::k12Bit : BitDept::k10Bit;
    });
  } else {
    frame_info->bit_detph = BitDept::k8Bit;
  }

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

  if (frame_info->color_space != ColorSpace::CS_RGB) {
    READ_OR_RETURN(br->ReadBoolean(), [frame_info](bool color_range) {
      frame_info->color_range =
          color_range ? ColorRange::kFull : ColorRange::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 = YuvSubsampling::k444;
                           break;
                         case 0b01:
                           frame_info->sub_sampling = YuvSubsampling::k440;
                           break;
                         case 0b10:
                           frame_info->sub_sampling = YuvSubsampling::k422;
                           break;
                         case 0b11:
                           frame_info->sub_sampling = YuvSubsampling::k420;
                           break;
                       }
                     });

      RETURN_IF_FALSE(br->VerifyNextBooleanIs(
          0, "Failed to parse header. Reserved bit set."));
    } else {
      // Profile 0 or 2.
      frame_info->sub_sampling = YuvSubsampling::k420;
    }
  } else {
    // SRGB
    frame_info->color_range = ColorRange::kFull;
    if (frame_info->profile == 1 || frame_info->profile == 3) {
      frame_info->sub_sampling = YuvSubsampling::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 Vp9ReadFrameSize(BitstreamReader* br, FrameInfo* 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, FrameInfo* frame_info) {
  // render_and_frame_size_different
  return br->IfNextBoolean(
      [&] {
        // 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, FrameInfo* frame_info) {
  bool found_ref = false;
  for (size_t i = 0; !found_ref && i < kVp9NumRefsPerFrame; i++) {
    // Size in refs.
    READ_OR_RETURN(br->ReadBoolean(), [&](bool ref) { found_ref = ref; });
  }

  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, FrameInfo* frame_info) {
  READ_OR_RETURN(br->ReadUnsigned<uint8_t>(),
                 [frame_info](uint8_t qp) { frame_info->base_qp = qp; });

  // yuv offsets
  for (int i = 0; i < 3; ++i) {
    RETURN_IF_FALSE(br->IfNextBoolean([br] {  // if delta_coded
      return br->ConsumeBits(5);
    }));
  }
  return true;
}

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

  RETURN_IF_FALSE(br->IfNextBoolean([&] {  // segmentation_enabled
    return br->IfNextBoolean([&] {  // update_map
      // Consume probs.
      for (int i = 0; i < 7; ++i) {
        RETURN_IF_FALSE(br->IfNextBoolean([br] { return br->ConsumeBits(7); }));
      }

      return br->IfNextBoolean([&] {  // temporal_update
        // Consume probs.
        for (int i = 0; i < 3; ++i) {
          RETURN_IF_FALSE(
              br->IfNextBoolean([br] { return br->ConsumeBits(7); }));
        }
        return true;
      });
    });
  }));

  return br->IfNextBoolean([&] {
    RETURN_IF_FALSE(br->ConsumeBits(1));  // abs_or_delta
    for (int i = 0; i < kVp9MaxSegments; ++i) {
      for (int j = 0; j < kVp9SegLvlMax; ++j) {
        RETURN_IF_FALSE(br->IfNextBoolean([&] {  // feature_enabled
          return br->ConsumeBits(kSegmentationFeatureBits[j] +
                                 kSegmentationFeatureSigned[j]);
        }));
      }
    }
    return true;
  });
}

bool Vp9ReadTileInfo(BitstreamReader* br, FrameInfo* 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;

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

  // rows_log2;
  return br->IfNextBoolean([&] { return br->ConsumeBits(1); });
}
}  // namespace

bool Parse(const uint8_t* buf, size_t length, FrameInfo* frame_info) {
  rtc::BitBuffer bit_buffer(buf, length);
  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;
  } 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;
      }
      // Refresh frame flags.
      RETURN_IF_FALSE(br.ConsumeBits(8));
      if (!Vp9ReadFrameSize(&br, frame_info))
        return false;
      if (!Vp9ReadRenderSize(&br, frame_info))
        return false;
    } else {
      // Refresh frame flags.
      RETURN_IF_FALSE(br.ConsumeBits(8));

      for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
        // 3 bits: Ref frame index.
        // 1 bit: Ref frame sign biases.
        RETURN_IF_FALSE(br.ConsumeBits(4));
      }

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

      // Allow high precision mv.
      RETURN_IF_FALSE(br.ConsumeBits(1));
      // Interpolation filter.
      RETURN_IF_FALSE(br.IfNextBoolean([] { return true; },
                                       [&br] { return br.ConsumeBits(2); }));
    }
  }

  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.
  RETURN_IF_FALSE(br.ConsumeBits(2));

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

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

  const bool kParseFullHeader = false;
  if (kParseFullHeader) {
    // Currently not used, but will be needed when parsing beyond the
    // uncompressed header.
    RETURN_IF_FALSE(Vp9ReadSegmentationParams(&br));

    RETURN_IF_FALSE(Vp9ReadTileInfo(&br, frame_info));

    RETURN_IF_FALSE(br.ConsumeBits(16));  // header_size_in_bytes
  }

  return true;
}

bool GetQp(const uint8_t* buf, size_t length, int* qp) {
  FrameInfo frame_info;
  if (!Parse(buf, length, &frame_info)) {
    return false;
  }
  *qp = frame_info.base_qp;
  return true;
}

absl::optional<FrameInfo> ParseIntraFrameInfo(const uint8_t* buf,
                                              size_t length) {
  FrameInfo frame_info;
  if (Parse(buf, length, &frame_info) && frame_info.frame_width > 0) {
    return frame_info;
  }
  return absl::nullopt;
}

}  // namespace vp9
}  // namespace webrtc
