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

#include <algorithm>

#include "webrtc/common_types.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/modules/video_coding/encoded_frame.h"
#include "webrtc/modules/video_coding/jitter_buffer.h"
#include "webrtc/modules/video_coding/packet.h"
#include "webrtc/system_wrappers/include/clock.h"

namespace webrtc {
namespace vcm {

int64_t VCMProcessTimer::Period() const {
  return _periodMs;
}

int64_t VCMProcessTimer::TimeUntilProcess() const {
  const int64_t time_since_process = _clock->TimeInMilliseconds() - _latestMs;
  const int64_t time_until_process = _periodMs - time_since_process;
  return std::max<int64_t>(time_until_process, 0);
}

void VCMProcessTimer::Processed() {
  _latestMs = _clock->TimeInMilliseconds();
}
}  // namespace vcm

namespace {
// This wrapper provides a way to modify the callback without the need to expose
// a register method all the way down to the function calling it.
class EncodedImageCallbackWrapper : public EncodedImageCallback {
 public:
  EncodedImageCallbackWrapper()
      : cs_(CriticalSectionWrapper::CreateCriticalSection()), callback_(NULL) {}

  virtual ~EncodedImageCallbackWrapper() {}

  void Register(EncodedImageCallback* callback) {
    CriticalSectionScoped cs(cs_.get());
    callback_ = callback;
  }

  virtual int32_t Encoded(const EncodedImage& encoded_image,
                          const CodecSpecificInfo* codec_specific_info,
                          const RTPFragmentationHeader* fragmentation) {
    CriticalSectionScoped cs(cs_.get());
    if (callback_)
      return callback_->Encoded(encoded_image, codec_specific_info,
                                fragmentation);
    return 0;
  }

 private:
  std::unique_ptr<CriticalSectionWrapper> cs_;
  EncodedImageCallback* callback_ GUARDED_BY(cs_);
};

class VideoCodingModuleImpl : public VideoCodingModule {
 public:
  VideoCodingModuleImpl(Clock* clock,
                        EventFactory* event_factory,
                        VideoEncoderRateObserver* encoder_rate_observer,
                        VCMQMSettingsCallback* qm_settings_callback,
                        NackSender* nack_sender,
                        KeyFrameRequestSender* keyframe_request_sender,
                        EncodedImageCallback* pre_decode_image_callback)
      : VideoCodingModule(),
        sender_(clock,
                &post_encode_callback_,
                encoder_rate_observer,
                qm_settings_callback,
                nullptr),
        receiver_(clock,
                  event_factory,
                  pre_decode_image_callback,
                  nack_sender,
                  keyframe_request_sender) {}

  virtual ~VideoCodingModuleImpl() {}

  int64_t TimeUntilNextProcess() override {
    int64_t sender_time = sender_.TimeUntilNextProcess();
    int64_t receiver_time = receiver_.TimeUntilNextProcess();
    assert(sender_time >= 0);
    assert(receiver_time >= 0);
    return VCM_MIN(sender_time, receiver_time);
  }

  void Process() override {
    sender_.Process();
    receiver_.Process();
  }

  int32_t RegisterSendCodec(const VideoCodec* sendCodec,
                            uint32_t numberOfCores,
                            uint32_t maxPayloadSize) override {
    return sender_.RegisterSendCodec(sendCodec, numberOfCores, maxPayloadSize);
  }

  int32_t RegisterExternalEncoder(VideoEncoder* externalEncoder,
                                  uint8_t payloadType,
                                  bool internalSource) override {
    sender_.RegisterExternalEncoder(externalEncoder, payloadType,
                                    internalSource);
    return 0;
  }

  int Bitrate(unsigned int* bitrate) const override {
    return sender_.Bitrate(bitrate);
  }

  int FrameRate(unsigned int* framerate) const override {
    return sender_.FrameRate(framerate);
  }

  int32_t SetChannelParameters(uint32_t target_bitrate,  // bits/s.
                               uint8_t lossRate,
                               int64_t rtt) override {
    return sender_.SetChannelParameters(target_bitrate, lossRate, rtt);
  }

  int32_t RegisterProtectionCallback(
      VCMProtectionCallback* protection) override {
    return sender_.RegisterProtectionCallback(protection);
  }

  int32_t SetVideoProtection(VCMVideoProtection videoProtection,
                             bool enable) override {
    // TODO(pbos): Remove enable from receive-side protection modes as well.
    if (enable)
      sender_.SetVideoProtection(videoProtection);
    return receiver_.SetVideoProtection(videoProtection, enable);
  }

  int32_t AddVideoFrame(const VideoFrame& videoFrame,
                        const VideoContentMetrics* contentMetrics,
                        const CodecSpecificInfo* codecSpecificInfo) override {
    return sender_.AddVideoFrame(videoFrame, contentMetrics, codecSpecificInfo);
  }

  int32_t IntraFrameRequest(int stream_index) override {
    return sender_.IntraFrameRequest(stream_index);
  }

  int32_t EnableFrameDropper(bool enable) override {
    return sender_.EnableFrameDropper(enable);
  }

  void SuspendBelowMinBitrate() override {
    return sender_.SuspendBelowMinBitrate();
  }

  bool VideoSuspended() const override { return sender_.VideoSuspended(); }

  int32_t RegisterReceiveCodec(const VideoCodec* receiveCodec,
                               int32_t numberOfCores,
                               bool requireKeyFrame) override {
    return receiver_.RegisterReceiveCodec(receiveCodec, numberOfCores,
                                          requireKeyFrame);
  }

  void RegisterExternalDecoder(VideoDecoder* externalDecoder,
                               uint8_t payloadType) override {
    receiver_.RegisterExternalDecoder(externalDecoder, payloadType);
  }

  int32_t RegisterReceiveCallback(
      VCMReceiveCallback* receiveCallback) override {
    return receiver_.RegisterReceiveCallback(receiveCallback);
  }

  int32_t RegisterReceiveStatisticsCallback(
      VCMReceiveStatisticsCallback* receiveStats) override {
    return receiver_.RegisterReceiveStatisticsCallback(receiveStats);
  }

  int32_t RegisterDecoderTimingCallback(
      VCMDecoderTimingCallback* decoderTiming) override {
    return receiver_.RegisterDecoderTimingCallback(decoderTiming);
  }

  int32_t RegisterFrameTypeCallback(
      VCMFrameTypeCallback* frameTypeCallback) override {
    return receiver_.RegisterFrameTypeCallback(frameTypeCallback);
  }

  int32_t RegisterPacketRequestCallback(
      VCMPacketRequestCallback* callback) override {
    return receiver_.RegisterPacketRequestCallback(callback);
  }

  int32_t Decode(uint16_t maxWaitTimeMs) override {
    return receiver_.Decode(maxWaitTimeMs);
  }

  int32_t ReceiveCodec(VideoCodec* currentReceiveCodec) const override {
    return receiver_.ReceiveCodec(currentReceiveCodec);
  }

  VideoCodecType ReceiveCodec() const override {
    return receiver_.ReceiveCodec();
  }

  int32_t IncomingPacket(const uint8_t* incomingPayload,
                         size_t payloadLength,
                         const WebRtcRTPHeader& rtpInfo) override {
    return receiver_.IncomingPacket(incomingPayload, payloadLength, rtpInfo);
  }

  int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs) override {
    return receiver_.SetMinimumPlayoutDelay(minPlayoutDelayMs);
  }

  int32_t SetRenderDelay(uint32_t timeMS) override {
    return receiver_.SetRenderDelay(timeMS);
  }

  int32_t Delay() const override { return receiver_.Delay(); }

  uint32_t DiscardedPackets() const override {
    return receiver_.DiscardedPackets();
  }

  int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
                                VCMDecodeErrorMode errorMode) override {
    return receiver_.SetReceiverRobustnessMode(robustnessMode, errorMode);
  }

  void SetNackSettings(size_t max_nack_list_size,
                       int max_packet_age_to_nack,
                       int max_incomplete_time_ms) override {
    return receiver_.SetNackSettings(max_nack_list_size, max_packet_age_to_nack,
                                     max_incomplete_time_ms);
  }

  void SetDecodeErrorMode(VCMDecodeErrorMode decode_error_mode) override {
    return receiver_.SetDecodeErrorMode(decode_error_mode);
  }

  int SetMinReceiverDelay(int desired_delay_ms) override {
    return receiver_.SetMinReceiverDelay(desired_delay_ms);
  }

  int32_t SetReceiveChannelParameters(int64_t rtt) override {
    return receiver_.SetReceiveChannelParameters(rtt);
  }

  void RegisterPostEncodeImageCallback(
      EncodedImageCallback* observer) override {
    post_encode_callback_.Register(observer);
  }

  void TriggerDecoderShutdown() override { receiver_.TriggerDecoderShutdown(); }

 private:
  EncodedImageCallbackWrapper post_encode_callback_;
  vcm::VideoSender sender_;
  vcm::VideoReceiver receiver_;
};
}  // namespace

void VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) {
  VCMCodecDataBase::Codec(codecType, codec);
}

// Create method for current interface, will be removed when the
// new jitter buffer is in place.
VideoCodingModule* VideoCodingModule::Create(
    Clock* clock,
    VideoEncoderRateObserver* encoder_rate_observer,
    VCMQMSettingsCallback* qm_settings_callback) {
  return VideoCodingModule::Create(clock, encoder_rate_observer,
                                   qm_settings_callback,
                                   nullptr,   // NackSender
                                   nullptr,   // KeyframeRequestSender
                                   nullptr);  // Pre-decode image callback
}

// Create method for the new jitter buffer.
VideoCodingModule* VideoCodingModule::Create(
    Clock* clock,
    VideoEncoderRateObserver* encoder_rate_observer,
    VCMQMSettingsCallback* qm_settings_callback,
    NackSender* nack_sender,
    KeyFrameRequestSender* keyframe_request_sender,
    EncodedImageCallback* pre_decode_image_callback) {
  return new VideoCodingModuleImpl(
      clock, nullptr, encoder_rate_observer, qm_settings_callback, nack_sender,
      keyframe_request_sender, pre_decode_image_callback);
}

// Create method for current interface, will be removed when the
// new jitter buffer is in place.
VideoCodingModule* VideoCodingModule::Create(Clock* clock,
                                             EventFactory* event_factory) {
  return VideoCodingModule::Create(clock, event_factory,
                                   nullptr,   // NackSender
                                   nullptr);  // KeyframeRequestSender
}

// Create method for the new jitter buffer.
VideoCodingModule* VideoCodingModule::Create(
    Clock* clock,
    EventFactory* event_factory,
    NackSender* nack_sender,
    KeyFrameRequestSender* keyframe_request_sender) {
  assert(clock);
  assert(event_factory);
  return new VideoCodingModuleImpl(clock, event_factory, nullptr, nullptr,
                                   nack_sender, keyframe_request_sender,
                                   nullptr);
}

}  // namespace webrtc
