/*
 *  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/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/common_video/include/frame_callback.h"
#include "webrtc/modules/video_coding/video_coding_impl.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::OnCompleteFrame(bool is_keyframe, size_t size_bytes) {}

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
