// Copyright 2018 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 <stdint.h>

#include <string>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "media/base/test_data_util.h"
#include "media/gpu/vp8_decoder.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Return;

namespace media {
namespace {

const std::string kNullFrame = "";
const std::string kIFrame = "vp8-I-frame-320x240";
const std::string kPFrame = "vp8-P-frame-320x240";
const std::string kCorruptFrame = "vp8-corrupt-I-frame";
constexpr gfx::Size kVideoSize(320, 240);
constexpr size_t kRequiredNumOfPictures = 9u;

class MockVP8Accelerator : public VP8Decoder::VP8Accelerator {
 public:
  MockVP8Accelerator() = default;

  MOCK_METHOD0(CreateVP8Picture, scoped_refptr<VP8Picture>());
  MOCK_METHOD2(SubmitDecode,
               bool(scoped_refptr<VP8Picture> pic,
                    const Vp8ReferenceFrameVector& reference_frames));
  MOCK_METHOD1(OutputPicture, bool(const scoped_refptr<VP8Picture>& pic));
};

// Test VP8Decoder by feeding different VP8 frame sequences and making sure it
// behaves as expected.
class VP8DecoderTest : public ::testing::Test {
 public:
  VP8DecoderTest() = default;

  void SetUp() override;

  AcceleratedVideoDecoder::DecodeResult Decode(std::string input_frame_file);

 protected:
  void SkipFrame() { bitstream_id_++; }
  void CompleteToDecodeFirstIFrame();

  std::unique_ptr<VP8Decoder> decoder_;
  MockVP8Accelerator* accelerator_ = nullptr;

 private:
  void DecodeFirstIFrame();

  int32_t bitstream_id_ = 0;
};

void VP8DecoderTest::SetUp() {
  auto mock_accelerator = std::make_unique<MockVP8Accelerator>();
  accelerator_ = mock_accelerator.get();
  decoder_.reset(new VP8Decoder(std::move(mock_accelerator)));

  // Sets default behaviors for mock methods for convenience.
  ON_CALL(*accelerator_, CreateVP8Picture())
      .WillByDefault(Return(new VP8Picture()));
  ON_CALL(*accelerator_, SubmitDecode(_, _)).WillByDefault(Return(true));
  ON_CALL(*accelerator_, OutputPicture(_)).WillByDefault(Return(true));

  DecodeFirstIFrame();
}

void VP8DecoderTest::DecodeFirstIFrame() {
  ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kNullFrame));
  ASSERT_EQ(AcceleratedVideoDecoder::kAllocateNewSurfaces, Decode(kIFrame));
  EXPECT_EQ(kVideoSize, decoder_->GetPicSize());
  EXPECT_LE(kRequiredNumOfPictures, decoder_->GetRequiredNumOfPictures());
}

// DecodeFirstIFrame() allocates new surfaces so VP8Decoder::Decode() must be
// called again to complete to decode the first frame.
void VP8DecoderTest::CompleteToDecodeFirstIFrame() {
  {
    InSequence sequence;
    EXPECT_CALL(*accelerator_, CreateVP8Picture());
    EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
    EXPECT_CALL(*accelerator_, OutputPicture(_));
  }
  ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kNullFrame));
}

AcceleratedVideoDecoder::DecodeResult VP8DecoderTest::Decode(
    std::string input_frame_file) {
  std::string bitstream;
  if (!input_frame_file.empty()) {
    auto input_file = GetTestDataFilePath(input_frame_file);
    EXPECT_TRUE(base::ReadFileToString(input_file, &bitstream));
    decoder_->SetStream(bitstream_id_++,
                        reinterpret_cast<const uint8_t*>(bitstream.data()),
                        bitstream.size());
  }

  return decoder_->Decode();
}

// Test Cases

TEST_F(VP8DecoderTest, DecodeSingleFrame) {
  CompleteToDecodeFirstIFrame();
  ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  ASSERT_TRUE(decoder_->Flush());
}

TEST_F(VP8DecoderTest, FailCreatePicture) {
  EXPECT_CALL(*accelerator_, CreateVP8Picture()).WillOnce(Return(nullptr));
  ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfSurfaces, Decode(kNullFrame));
  ASSERT_TRUE(decoder_->Flush());
}

TEST_F(VP8DecoderTest, DecodeCorruptFrame) {
  CompleteToDecodeFirstIFrame();
  ASSERT_EQ(AcceleratedVideoDecoder::kDecodeError, Decode(kCorruptFrame));
  ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));

  ASSERT_TRUE(decoder_->Flush());
}

TEST_F(VP8DecoderTest, DecodeIAndPFrames) {
  CompleteToDecodeFirstIFrame();

  {
    InSequence sequence;
    EXPECT_CALL(*accelerator_, CreateVP8Picture());
    EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
    EXPECT_CALL(*accelerator_, OutputPicture(_));
  }
  ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));

  ASSERT_TRUE(decoder_->Flush());
}

TEST_F(VP8DecoderTest, DecodeIandMultiplePFrames) {
  CompleteToDecodeFirstIFrame();

  for (size_t i = 0; i < 5; i++) {
    {
      InSequence sequence;
      EXPECT_CALL(*accelerator_, CreateVP8Picture());
      EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
      EXPECT_CALL(*accelerator_, OutputPicture(_));
    }
    ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  }

  ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  ASSERT_TRUE(decoder_->Flush());
}

TEST_F(VP8DecoderTest, DecodeMultipleIAndPFrames) {
  CompleteToDecodeFirstIFrame();

  for (size_t i = 0; i < 10; i++) {
    {
      InSequence sequence;
      EXPECT_CALL(*accelerator_, CreateVP8Picture());
      EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
      EXPECT_CALL(*accelerator_, OutputPicture(_));
    }
    ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData,
              Decode((i % 3) == 0 ? kIFrame : kPFrame));
  }

  ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  ASSERT_TRUE(decoder_->Flush());
}

TEST_F(VP8DecoderTest, HaveSkippedFrames) {
  CompleteToDecodeFirstIFrame();

  SkipFrame();
  for (size_t i = 0; i < 5; i++) {
    // VP8Decoder::Decode() gives up decoding it and returns early.
    ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  }

  ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  ASSERT_TRUE(decoder_->Flush());
}

// Verify that |decoder_| returns kDecodeError if too many kPFrames are received
// while expecting a kIFrame.
TEST_F(VP8DecoderTest, HaveSkippedFramesAtMaxNumOfSizeChangeFailures) {
  CompleteToDecodeFirstIFrame();

  SkipFrame();
  for (size_t i = 0;
       i < AcceleratedVideoDecoder::kVPxMaxNumOfSizeChangeFailures; i++) {
    ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  }
  ASSERT_EQ(AcceleratedVideoDecoder::kDecodeError, Decode(kPFrame));

  ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  ASSERT_TRUE(decoder_->Flush());
}

// Verify that new kIFrame recovers |decoder_| to decode the frame when the
// previous I frame is missing.
TEST_F(VP8DecoderTest, RecoverFromSkippedFrames) {
  CompleteToDecodeFirstIFrame();

  SkipFrame();
  for (size_t i = 0; i < 5; i++)
    ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));

  // The new I frame recovers to decode it correctly.
  {
    InSequence sequence;
    EXPECT_CALL(*accelerator_, CreateVP8Picture());
    EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
    EXPECT_CALL(*accelerator_, OutputPicture(_));
  }
  ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kIFrame));

  for (size_t i = 0; i < 5; i++) {
    {
      InSequence sequence;
      EXPECT_CALL(*accelerator_, CreateVP8Picture());
      EXPECT_CALL(*accelerator_, SubmitDecode(_, _));
      EXPECT_CALL(*accelerator_, OutputPicture(_));
    }
    ASSERT_EQ(AcceleratedVideoDecoder::kRanOutOfStreamData, Decode(kPFrame));
  }

  ASSERT_TRUE(Mock::VerifyAndClearExpectations(accelerator_));
  ASSERT_TRUE(decoder_->Flush());
}

}  // namespace
}  // namespace media
