/*
 *  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 "webrtc/modules/video_coding/utility/vp9_uncompressed_header_parser.h"

#include "webrtc/rtc_base/bitbuffer.h"
#include "webrtc/rtc_base/logging.h"

namespace webrtc {

#define RETURN_FALSE_IF_ERROR(x) \
  if (!(x)) {                    \
    return false;                \
  }

namespace vp9 {
namespace {
const size_t kVp9NumRefsPerFrame = 3;
const size_t kVp9MaxRefLFDeltas = 4;
const size_t kVp9MaxModeLFDeltas = 2;

bool Vp9ReadProfile(rtc::BitBuffer* br, uint8_t* profile) {
  uint32_t high_bit;
  uint32_t low_bit;
  RETURN_FALSE_IF_ERROR(br->ReadBits(&low_bit, 1));
  RETURN_FALSE_IF_ERROR(br->ReadBits(&high_bit, 1));
  *profile = (high_bit << 1) + low_bit;
  if (*profile > 2) {
    uint32_t reserved_bit;
    RETURN_FALSE_IF_ERROR(br->ReadBits(&reserved_bit, 1));
    if (reserved_bit) {
      LOG(LS_WARNING) << "Failed to get QP. Unsupported bitstream profile.";
      return false;
    }
  }
  return true;
}

bool Vp9ReadSyncCode(rtc::BitBuffer* br) {
  uint32_t sync_code;
  RETURN_FALSE_IF_ERROR(br->ReadBits(&sync_code, 24));
  if (sync_code != 0x498342) {
    LOG(LS_WARNING) << "Failed to get QP. Invalid sync code.";
    return false;
  }
  return true;
}

bool Vp9ReadColorConfig(rtc::BitBuffer* br, uint8_t profile) {
  if (profile == 2 || profile == 3) {
    // Bitdepth.
    RETURN_FALSE_IF_ERROR(br->ConsumeBits(1));
  }
  uint32_t color_space;
  RETURN_FALSE_IF_ERROR(br->ReadBits(&color_space, 3));

  // SRGB is 7.
  if (color_space != 7) {
    // YUV range flag.
    RETURN_FALSE_IF_ERROR(br->ConsumeBits(1));
    if (profile == 1 || profile == 3) {
      // 1 bit: subsampling x.
      // 1 bit: subsampling y.
      RETURN_FALSE_IF_ERROR(br->ConsumeBits(2));
      uint32_t reserved_bit;
      RETURN_FALSE_IF_ERROR(br->ReadBits(&reserved_bit, 1));
      if (reserved_bit) {
        LOG(LS_WARNING) << "Failed to get QP. Reserved bit set.";
        return false;
      }
    }
  } else {
    if (profile == 1 || profile == 3) {
      uint32_t reserved_bit;
      RETURN_FALSE_IF_ERROR(br->ReadBits(&reserved_bit, 1));
      if (reserved_bit) {
        LOG(LS_WARNING) << "Failed to get QP. Reserved bit set.";
        return false;
      }
    } else {
      LOG(LS_WARNING) << "Failed to get QP. 4:4:4 color not supported in "
                         "profile 0 or 2.";
      return false;
    }
  }

  return true;
}

bool Vp9ReadFrameSize(rtc::BitBuffer* br) {
  // 2 bytes: frame width.
  // 2 bytes: frame height.
  return br->ConsumeBytes(4);
}

bool Vp9ReadRenderSize(rtc::BitBuffer* br) {
  uint32_t bit;
  RETURN_FALSE_IF_ERROR(br->ReadBits(&bit, 1));
  if (bit) {
    // 2 bytes: render width.
    // 2 bytes: render height.
    RETURN_FALSE_IF_ERROR(br->ConsumeBytes(4));
  }
  return true;
}

bool Vp9ReadFrameSizeFromRefs(rtc::BitBuffer* br) {
  uint32_t found_ref = 0;
  for (size_t i = 0; i < kVp9NumRefsPerFrame; i++) {
    // Size in refs.
    RETURN_FALSE_IF_ERROR(br->ReadBits(&found_ref, 1));
    if (found_ref)
      break;
  }

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

bool Vp9ReadInterpolationFilter(rtc::BitBuffer* br) {
  uint32_t bit;
  RETURN_FALSE_IF_ERROR(br->ReadBits(&bit, 1));
  if (bit)
    return true;

  return br->ConsumeBits(2);
}

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

  uint32_t mode_ref_delta_enabled;
  RETURN_FALSE_IF_ERROR(br->ReadBits(&mode_ref_delta_enabled, 1));
  if (mode_ref_delta_enabled) {
    uint32_t mode_ref_delta_update;
    RETURN_FALSE_IF_ERROR(br->ReadBits(&mode_ref_delta_update, 1));
    if (mode_ref_delta_update) {
      uint32_t bit;
      for (size_t i = 0; i < kVp9MaxRefLFDeltas; i++) {
        RETURN_FALSE_IF_ERROR(br->ReadBits(&bit, 1));
        if (bit) {
          RETURN_FALSE_IF_ERROR(br->ConsumeBits(7));
        }
      }
      for (size_t i = 0; i < kVp9MaxModeLFDeltas; i++) {
        RETURN_FALSE_IF_ERROR(br->ReadBits(&bit, 1));
        if (bit) {
          RETURN_FALSE_IF_ERROR(br->ConsumeBits(7));
        }
      }
    }
  }
  return true;
}
}  // namespace

bool GetQp(const uint8_t* buf, size_t length, int* qp) {
  rtc::BitBuffer br(buf, length);

  // Frame marker.
  uint32_t frame_marker;
  RETURN_FALSE_IF_ERROR(br.ReadBits(&frame_marker, 2));
  if (frame_marker != 0x2) {
    LOG(LS_WARNING) << "Failed to get QP. Frame marker should be 2.";
    return false;
  }

  // Profile.
  uint8_t profile;
  if (!Vp9ReadProfile(&br, &profile))
    return false;

  // Show existing frame.
  uint32_t show_existing_frame;
  RETURN_FALSE_IF_ERROR(br.ReadBits(&show_existing_frame, 1));
  if (show_existing_frame)
    return false;

  // Frame type: KEY_FRAME(0), INTER_FRAME(1).
  uint32_t frame_type;
  uint32_t show_frame;
  uint32_t error_resilient;
  RETURN_FALSE_IF_ERROR(br.ReadBits(&frame_type, 1));
  RETURN_FALSE_IF_ERROR(br.ReadBits(&show_frame, 1));
  RETURN_FALSE_IF_ERROR(br.ReadBits(&error_resilient, 1));

  if (!frame_type) {
    if (!Vp9ReadSyncCode(&br))
      return false;
    if (!Vp9ReadColorConfig(&br, profile))
      return false;
    if (!Vp9ReadFrameSize(&br))
      return false;
    if (!Vp9ReadRenderSize(&br))
      return false;

  } else {
    uint32_t intra_only = 0;
    if (!show_frame)
      RETURN_FALSE_IF_ERROR(br.ReadBits(&intra_only, 1));
    if (!error_resilient)
      RETURN_FALSE_IF_ERROR(br.ConsumeBits(2));  // Reset frame context.

    if (intra_only) {
      if (!Vp9ReadSyncCode(&br))
        return false;

      if (profile > 0) {
        if (!Vp9ReadColorConfig(&br, profile))
          return false;
      }
      // Refresh frame flags.
      RETURN_FALSE_IF_ERROR(br.ConsumeBits(8));
      if (!Vp9ReadFrameSize(&br))
        return false;
      if (!Vp9ReadRenderSize(&br))
        return false;
    } else {
      // Refresh frame flags.
      RETURN_FALSE_IF_ERROR(br.ConsumeBits(8));

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

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

      // Allow high precision mv.
      RETURN_FALSE_IF_ERROR(br.ConsumeBits(1));
      // Interpolation filter.
      if (!Vp9ReadInterpolationFilter(&br))
        return false;
    }
  }

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

  // Frame context index.
  RETURN_FALSE_IF_ERROR(br.ConsumeBits(2));

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

  // Base QP.
  uint8_t base_q0;
  RETURN_FALSE_IF_ERROR(br.ReadUInt8(&base_q0));
  *qp = base_q0;
  return true;
}

}  // namespace vp9

}  // namespace webrtc
