/*
 *  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 = kKeyFrame;
  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 = kDeltaFrame;
  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
