// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/gpu/vp8_decoder.h"

#include "base/logging.h"
#include "base/notreached.h"
#include "media/base/limits.h"

namespace media {

namespace {
constexpr size_t kVP8NumFramesActive = 4;
}

VP8Decoder::VP8Accelerator::VP8Accelerator() {}

VP8Decoder::VP8Accelerator::~VP8Accelerator() {}

VP8Decoder::VP8Decoder(std::unique_ptr<VP8Accelerator> accelerator)
    : state_(kNeedStreamMetadata),
      curr_frame_start_(nullptr),
      frame_size_(0),
      accelerator_(std::move(accelerator)) {
  DCHECK(accelerator_);
}

VP8Decoder::~VP8Decoder() = default;

bool VP8Decoder::Flush() {
  DVLOG(2) << "Decoder flush";
  Reset();
  return true;
}

void VP8Decoder::SetStream(int32_t id, const DecoderBuffer& decoder_buffer) {
  const uint8_t* ptr = decoder_buffer.data();
  const size_t size = decoder_buffer.data_size();
  const DecryptConfig* decrypt_config = decoder_buffer.decrypt_config();

  DCHECK(ptr);
  DCHECK(size);
  if (decrypt_config) {
    NOTIMPLEMENTED();
    state_ = kError;
    return;
  }

  DVLOG(4) << "New input stream id: " << id << " at: " << (void*)ptr
           << " size: " << size;
  stream_id_ = id;
  curr_frame_start_ = ptr;
  frame_size_ = size;
}

void VP8Decoder::Reset() {
  curr_frame_hdr_ = nullptr;
  curr_frame_start_ = nullptr;
  frame_size_ = 0;

  ref_frames_.Clear();

  if (state_ == kDecoding)
    state_ = kAfterReset;
}

VP8Decoder::DecodeResult VP8Decoder::Decode() {
  if (!curr_frame_start_ || frame_size_ == 0)
    return kRanOutOfStreamData;

  if (!curr_frame_hdr_) {
    curr_frame_hdr_.reset(new Vp8FrameHeader());
    if (!parser_.ParseFrame(curr_frame_start_, frame_size_,
                            curr_frame_hdr_.get())) {
      DVLOG(1) << "Error during decode";
      state_ = kError;
      return kDecodeError;
    }
  }

  // The |stream_id_|s are expected to be monotonically increasing, and we've
  // lost (at least) a frame if this condition doesn't uphold.
  const bool have_skipped_frame = last_decoded_stream_id_ + 1 != stream_id_ &&
                                  last_decoded_stream_id_ != kInvalidId;
  if (curr_frame_hdr_->IsKeyframe()) {
    const gfx::Size new_picture_size(curr_frame_hdr_->width,
                                     curr_frame_hdr_->height);
    if (new_picture_size.IsEmpty())
      return kDecodeError;

    if (new_picture_size != pic_size_) {
      DVLOG(2) << "New resolution: " << new_picture_size.ToString();
      pic_size_ = new_picture_size;

      ref_frames_.Clear();
      last_decoded_stream_id_ = stream_id_;
      size_change_failure_counter_ = 0;

      return kConfigChange;
    }

    state_ = kDecoding;
  } else if (state_ != kDecoding || have_skipped_frame) {
    // Only trust the next frame. Otherwise, new keyframe might be missed, so
    // |pic_size_| might be stale.
    // TODO(dshwang): if rtc decoder can know the size of inter frame, change
    // this condition to check if new keyframe is missed.
    // https://crbug.com/832545
    DVLOG(4) << "Drop the frame because the size maybe stale.";
    if (have_skipped_frame &&
        ++size_change_failure_counter_ > kVPxMaxNumOfSizeChangeFailures) {
      state_ = kError;
      return kDecodeError;
    }

    // Need a resume point.
    curr_frame_hdr_ = nullptr;
    return kRanOutOfStreamData;
  }

  scoped_refptr<VP8Picture> pic = accelerator_->CreateVP8Picture();
  if (!pic)
    return kRanOutOfSurfaces;

  if (!DecodeAndOutputCurrentFrame(std::move(pic))) {
    state_ = kError;
    return kDecodeError;
  }

  last_decoded_stream_id_ = stream_id_;
  size_change_failure_counter_ = 0;
  return kRanOutOfStreamData;
}

bool VP8Decoder::DecodeAndOutputCurrentFrame(scoped_refptr<VP8Picture> pic) {
  DCHECK(pic);
  DCHECK(!pic_size_.IsEmpty());
  DCHECK(curr_frame_hdr_);

  pic->set_visible_rect(gfx::Rect(pic_size_));
  pic->set_bitstream_id(stream_id_);

  if (curr_frame_hdr_->IsKeyframe()) {
    horizontal_scale_ = curr_frame_hdr_->horizontal_scale;
    vertical_scale_ = curr_frame_hdr_->vertical_scale;
  } else {
    // Populate fields from decoder state instead.
    curr_frame_hdr_->width = pic_size_.width();
    curr_frame_hdr_->height = pic_size_.height();
    curr_frame_hdr_->horizontal_scale = horizontal_scale_;
    curr_frame_hdr_->vertical_scale = vertical_scale_;
  }

  const bool show_frame = curr_frame_hdr_->show_frame;
  pic->frame_hdr = std::move(curr_frame_hdr_);

  if (!accelerator_->SubmitDecode(pic, ref_frames_))
    return false;

  if (show_frame && !accelerator_->OutputPicture(pic))
    return false;

  ref_frames_.Refresh(pic);

  curr_frame_start_ = nullptr;
  frame_size_ = 0;
  return true;
}

gfx::Size VP8Decoder::GetPicSize() const {
  return pic_size_;
}

gfx::Rect VP8Decoder::GetVisibleRect() const {
  return gfx::Rect(pic_size_);
}

VideoCodecProfile VP8Decoder::GetProfile() const {
  return VP8PROFILE_ANY;
}

uint8_t VP8Decoder::GetBitDepth() const {
  return 8u;
}

size_t VP8Decoder::GetRequiredNumOfPictures() const {
  constexpr size_t kPicsInPipeline = limits::kMaxVideoFrames + 1;
  return kVP8NumFramesActive + kPicsInPipeline;
}

size_t VP8Decoder::GetNumReferenceFrames() const {
  // Maximum number of reference frames.
  return kVP8NumFramesActive;
}

}  // namespace media
