/*
 *  Copyright (c) 2015 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/video_decoder.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/video_coding/codecs/interface/video_error_codes.h"

namespace webrtc {

class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
 protected:
  VideoDecoderSoftwareFallbackWrapperTest()
      : fallback_wrapper_(kVideoCodecVP8, &fake_decoder_) {}

  class CountingFakeDecoder : public VideoDecoder {
   public:
    int32_t InitDecode(const VideoCodec* codec_settings,
                       int32_t number_of_cores) override {
      ++init_decode_count_;
      return WEBRTC_VIDEO_CODEC_OK;
    }

    int32_t Decode(const EncodedImage& input_image,
                   bool missing_frames,
                   const RTPFragmentationHeader* fragmentation,
                   const CodecSpecificInfo* codec_specific_info,
                   int64_t render_time_ms) override {
      ++decode_count_;
      return decode_return_code_;
    }

    int32_t RegisterDecodeCompleteCallback(
        DecodedImageCallback* callback) override {
      decode_complete_callback_ = callback;
      return WEBRTC_VIDEO_CODEC_OK;
    }

    int32_t Release() override {
      ++release_count_;
      return WEBRTC_VIDEO_CODEC_OK;
    }

    int32_t Reset() override {
      ++reset_count_;
      return WEBRTC_VIDEO_CODEC_OK;
    }
    int init_decode_count_ = 0;
    int decode_count_ = 0;
    int32_t decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
    DecodedImageCallback* decode_complete_callback_ = nullptr;
    int release_count_ = 0;
    int reset_count_ = 0;
  };
  CountingFakeDecoder fake_decoder_;
  VideoDecoderSoftwareFallbackWrapper fallback_wrapper_;
};

TEST_F(VideoDecoderSoftwareFallbackWrapperTest, InitializesDecoder) {
  VideoCodec codec = {};
  fallback_wrapper_.InitDecode(&codec, 2);
  EXPECT_EQ(1, fake_decoder_.init_decode_count_);
}

TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
       CanRecoverFromSoftwareFallback) {
  VideoCodec codec = {};
  fallback_wrapper_.InitDecode(&codec, 2);
  // Unfortunately faking a VP8 frame is hard. Rely on no Decode -> using SW
  // decoder.
  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
  EncodedImage encoded_image;
  fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
  EXPECT_EQ(1, fake_decoder_.decode_count_);

  // Fail -> fake_decoder shouldn't be used anymore.
  fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
  EXPECT_EQ(1, fake_decoder_.decode_count_)
      << "Decoder used even though fallback should be active.";

  // Should be able to recover on a keyframe.
  encoded_image._frameType = kVideoFrameKey;
  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
  fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
  EXPECT_EQ(2, fake_decoder_.decode_count_)
      << "Wrapper did not try to decode a keyframe using registered decoder.";

  encoded_image._frameType = kVideoFrameDelta;
  fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
  EXPECT_EQ(3, fake_decoder_.decode_count_)
      << "Decoder not used on future delta frames.";
}

TEST_F(VideoDecoderSoftwareFallbackWrapperTest, DoesNotFallbackOnEveryError) {
  VideoCodec codec = {};
  fallback_wrapper_.InitDecode(&codec, 2);
  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
  EncodedImage encoded_image;
  EXPECT_EQ(
      fake_decoder_.decode_return_code_,
      fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1));
  EXPECT_EQ(1, fake_decoder_.decode_count_);

  fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
  EXPECT_EQ(2, fake_decoder_.decode_count_)
      << "Decoder should be active even though previous decode failed.";
}

TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsReleaseCall) {
  VideoCodec codec = {};
  fallback_wrapper_.InitDecode(&codec, 2);
  fallback_wrapper_.Release();
  EXPECT_EQ(1, fake_decoder_.release_count_);

  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
  EncodedImage encoded_image;
  fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
  EXPECT_EQ(1, fake_decoder_.release_count_)
      << "Decoder should not be released during fallback.";
  fallback_wrapper_.Release();
  EXPECT_EQ(2, fake_decoder_.release_count_);
}

TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsResetCall) {
  VideoCodec codec = {};
  fallback_wrapper_.InitDecode(&codec, 2);
  fallback_wrapper_.Reset();
  EXPECT_EQ(1, fake_decoder_.reset_count_);

  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
  EncodedImage encoded_image;
  fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
  fallback_wrapper_.Reset();
  EXPECT_EQ(2, fake_decoder_.reset_count_)
      << "Reset not forwarded during fallback.";
}

// TODO(pbos): Fake a VP8 frame well enough to actually receive a callback from
// the software encoder.
TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
       ForwardsRegisterDecodeCompleteCallback) {
  class FakeDecodedImageCallback : public DecodedImageCallback {
    int32_t Decoded(VideoFrame& decodedImage) override { return 0; }
  } callback, callback2;

  VideoCodec codec = {};
  fallback_wrapper_.InitDecode(&codec, 2);
  fallback_wrapper_.RegisterDecodeCompleteCallback(&callback);
  EXPECT_EQ(&callback, fake_decoder_.decode_complete_callback_);

  fake_decoder_.decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
  EncodedImage encoded_image;
  fallback_wrapper_.Decode(encoded_image, false, nullptr, nullptr, -1);
  fallback_wrapper_.RegisterDecodeCompleteCallback(&callback2);
  EXPECT_EQ(&callback2, fake_decoder_.decode_complete_callback_);
}

}  // namespace webrtc
