/*
 *  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/video/video_stream_decoder.h"

#include <algorithm>
#include <map>
#include <vector>

#include "webrtc/common_video/include/frame_callback.h"
#include "webrtc/modules/video_coding/video_coding_impl.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/system_wrappers/include/metrics.h"
#include "webrtc/video/call_stats.h"
#include "webrtc/video/payload_router.h"
#include "webrtc/video/receive_statistics_proxy.h"

namespace webrtc {

VideoStreamDecoder::VideoStreamDecoder(
    vcm::VideoReceiver* video_receiver,
    VCMFrameTypeCallback* vcm_frame_type_callback,
    VCMPacketRequestCallback* vcm_packet_request_callback,
    bool enable_nack,
    bool enable_fec,
    ReceiveStatisticsProxy* receive_statistics_proxy,
    rtc::VideoSinkInterface<VideoFrame>* incoming_video_stream)
    : video_receiver_(video_receiver),
      receive_stats_callback_(receive_statistics_proxy),
      incoming_video_stream_(incoming_video_stream),
      last_rtt_ms_(0) {
  RTC_DCHECK(video_receiver_);

  static const int kMaxPacketAgeToNack = 450;
  static const int kMaxNackListSize = 250;
  video_receiver_->SetNackSettings(kMaxNackListSize,
                                   kMaxPacketAgeToNack, 0);
  video_receiver_->RegisterReceiveCallback(this);
  video_receiver_->RegisterFrameTypeCallback(vcm_frame_type_callback);
  video_receiver_->RegisterReceiveStatisticsCallback(this);

  VCMVideoProtection video_protection =
      enable_nack ? (enable_fec ? kProtectionNackFEC : kProtectionNack)
                  : kProtectionNone;

  VCMDecodeErrorMode decode_error_mode = enable_nack ? kNoErrors : kWithErrors;
  video_receiver_->SetVideoProtection(video_protection, true);
  video_receiver_->SetDecodeErrorMode(decode_error_mode);
  VCMPacketRequestCallback* packet_request_callback =
      enable_nack ? vcm_packet_request_callback : nullptr;
  video_receiver_->RegisterPacketRequestCallback(packet_request_callback);
}

VideoStreamDecoder::~VideoStreamDecoder() {
  // Note: There's an assumption at this point that the decoder thread is
  // *not* running. If it was, then there could be a race for each of these
  // callbacks.

  // Unset all the callback pointers that we set in the ctor.
  video_receiver_->RegisterPacketRequestCallback(nullptr);
  video_receiver_->RegisterReceiveStatisticsCallback(nullptr);
  video_receiver_->RegisterFrameTypeCallback(nullptr);
  video_receiver_->RegisterReceiveCallback(nullptr);
}

// Do not acquire the lock of |video_receiver_| in this function. Decode
// callback won't necessarily be called from the decoding thread. The decoding
// thread may have held the lock when calling VideoDecoder::Decode, Reset, or
// Release. Acquiring the same lock in the path of decode callback can deadlock.
int32_t VideoStreamDecoder::FrameToRender(VideoFrame& video_frame,
                                          rtc::Optional<uint8_t> qp,
                                          VideoContentType content_type) {
  receive_stats_callback_->OnDecodedFrame(qp, content_type);
  incoming_video_stream_->OnFrame(video_frame);
  return 0;
}

int32_t VideoStreamDecoder::ReceivedDecodedReferenceFrame(
  const uint64_t picture_id) {
  RTC_NOTREACHED();
  return 0;
}

void VideoStreamDecoder::OnIncomingPayloadType(int payload_type) {
  receive_stats_callback_->OnIncomingPayloadType(payload_type);
}

void VideoStreamDecoder::OnDecoderImplementationName(
    const char* implementation_name) {
  receive_stats_callback_->OnDecoderImplementationName(implementation_name);
}

void VideoStreamDecoder::OnReceiveRatesUpdated(uint32_t bit_rate,
                                               uint32_t frame_rate) {
  receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate);
}

void VideoStreamDecoder::OnDiscardedPacketsUpdated(int discarded_packets) {
  receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
}

void VideoStreamDecoder::OnFrameCountsUpdated(const FrameCounts& frame_counts) {
  receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
}

void VideoStreamDecoder::OnFrameBufferTimingsUpdated(int decode_ms,
                                                     int max_decode_ms,
                                                     int current_delay_ms,
                                                     int target_delay_ms,
                                                     int jitter_buffer_ms,
                                                     int min_playout_delay_ms,
                                                     int render_delay_ms) {}

void VideoStreamDecoder::OnTimingFrameInfoUpdated(const TimingFrameInfo& info) {
}

void VideoStreamDecoder::OnCompleteFrame(bool is_keyframe,
                                         size_t size_bytes,
                                         VideoContentType content_type) {}

void VideoStreamDecoder::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
  video_receiver_->SetReceiveChannelParameters(max_rtt_ms);

  rtc::CritScope lock(&crit_);
  last_rtt_ms_ = avg_rtt_ms;
}
}  // namespace webrtc
