blob: b0308f25d85fba6bad556bc4d0118fe5d1d026d9 [file] [log] [blame]
mflodmancfc8e3b2016-05-04 04:22:041/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/video/video_stream_decoder.h"
12
13#include <algorithm>
14#include <map>
15#include <vector>
16
17#include "webrtc/base/checks.h"
18#include "webrtc/base/logging.h"
19#include "webrtc/common_video/include/frame_callback.h"
mflodmancfc8e3b2016-05-04 04:22:0420#include "webrtc/modules/video_coding/video_coding_impl.h"
mflodmancfc8e3b2016-05-04 04:22:0421#include "webrtc/system_wrappers/include/metrics.h"
22#include "webrtc/video/call_stats.h"
23#include "webrtc/video/payload_router.h"
24#include "webrtc/video/receive_statistics_proxy.h"
25
26namespace webrtc {
27
28VideoStreamDecoder::VideoStreamDecoder(
29 vcm::VideoReceiver* video_receiver,
30 VCMFrameTypeCallback* vcm_frame_type_callback,
31 VCMPacketRequestCallback* vcm_packet_request_callback,
32 bool enable_nack,
tommi2e82f382016-06-21 07:26:4333 bool enable_fec,
mflodmancfc8e3b2016-05-04 04:22:0434 ReceiveStatisticsProxy* receive_statistics_proxy,
nisse76bc8e82017-02-07 17:37:4135 rtc::VideoSinkInterface<VideoFrame>* incoming_video_stream)
mflodmancfc8e3b2016-05-04 04:22:0436 : video_receiver_(video_receiver),
37 receive_stats_callback_(receive_statistics_proxy),
38 incoming_video_stream_(incoming_video_stream),
mflodmancfc8e3b2016-05-04 04:22:0439 last_rtt_ms_(0) {
40 RTC_DCHECK(video_receiver_);
41
42 static const int kMaxPacketAgeToNack = 450;
43 static const int kMaxNackListSize = 250;
44 video_receiver_->SetNackSettings(kMaxNackListSize,
45 kMaxPacketAgeToNack, 0);
46 video_receiver_->RegisterReceiveCallback(this);
47 video_receiver_->RegisterFrameTypeCallback(vcm_frame_type_callback);
48 video_receiver_->RegisterReceiveStatisticsCallback(this);
49 video_receiver_->RegisterDecoderTimingCallback(this);
mflodmancfc8e3b2016-05-04 04:22:0450
tommi2e82f382016-06-21 07:26:4351 VCMVideoProtection video_protection =
52 enable_nack ? (enable_fec ? kProtectionNackFEC : kProtectionNack)
53 : kProtectionNone;
philipelae284082016-05-09 10:14:2954
mflodmancfc8e3b2016-05-04 04:22:0455 VCMDecodeErrorMode decode_error_mode = enable_nack ? kNoErrors : kWithErrors;
56 video_receiver_->SetVideoProtection(video_protection, true);
57 video_receiver_->SetDecodeErrorMode(decode_error_mode);
58 VCMPacketRequestCallback* packet_request_callback =
59 enable_nack ? vcm_packet_request_callback : nullptr;
60 video_receiver_->RegisterPacketRequestCallback(packet_request_callback);
61}
62
tommi2e82f382016-06-21 07:26:4363VideoStreamDecoder::~VideoStreamDecoder() {
64 // Unset all the callback pointers that we set in the ctor.
65 video_receiver_->RegisterPacketRequestCallback(nullptr);
66 video_receiver_->RegisterDecoderTimingCallback(nullptr);
67 video_receiver_->RegisterReceiveStatisticsCallback(nullptr);
68 video_receiver_->RegisterFrameTypeCallback(nullptr);
69 video_receiver_->RegisterReceiveCallback(nullptr);
70}
mflodmancfc8e3b2016-05-04 04:22:0471
72// Do not acquire the lock of |video_receiver_| in this function. Decode
73// callback won't necessarily be called from the decoding thread. The decoding
74// thread may have held the lock when calling VideoDecoder::Decode, Reset, or
75// Release. Acquiring the same lock in the path of decode callback can deadlock.
sakalff0e72f2017-02-07 15:15:1776int32_t VideoStreamDecoder::FrameToRender(VideoFrame& video_frame,
77 rtc::Optional<uint8_t> qp) {
sakalff0e72f2017-02-07 15:15:1778 receive_stats_callback_->OnDecodedFrame(qp);
sakal55d932b2016-09-30 13:19:0879 incoming_video_stream_->OnFrame(video_frame);
tommi2e82f382016-06-21 07:26:4380
mflodmancfc8e3b2016-05-04 04:22:0481 return 0;
82}
83
84int32_t VideoStreamDecoder::ReceivedDecodedReferenceFrame(
85 const uint64_t picture_id) {
86 RTC_NOTREACHED();
87 return 0;
88}
89
90void VideoStreamDecoder::OnIncomingPayloadType(int payload_type) {
91 receive_stats_callback_->OnIncomingPayloadType(payload_type);
92}
93
94void VideoStreamDecoder::OnDecoderImplementationName(
95 const char* implementation_name) {
96 receive_stats_callback_->OnDecoderImplementationName(implementation_name);
97}
98
99void VideoStreamDecoder::OnReceiveRatesUpdated(uint32_t bit_rate,
100 uint32_t frame_rate) {
101 receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate);
102}
103
104void VideoStreamDecoder::OnDiscardedPacketsUpdated(int discarded_packets) {
105 receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
106}
107
108void VideoStreamDecoder::OnFrameCountsUpdated(const FrameCounts& frame_counts) {
109 receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
110}
111
112void VideoStreamDecoder::OnDecoderTiming(int decode_ms,
113 int max_decode_ms,
114 int current_delay_ms,
115 int target_delay_ms,
116 int jitter_buffer_ms,
117 int min_playout_delay_ms,
philipele5bd7022017-02-02 17:53:00118 int render_delay_ms) {}
mflodmancfc8e3b2016-05-04 04:22:04119
philipele5bd7022017-02-02 17:53:00120void VideoStreamDecoder::OnFrameBufferTimingsUpdated(int decode_ms,
121 int max_decode_ms,
122 int current_delay_ms,
123 int target_delay_ms,
124 int jitter_buffer_ms,
125 int min_playout_delay_ms,
126 int render_delay_ms) {}
127
128void VideoStreamDecoder::OnCompleteFrame(bool is_keyframe, size_t size_bytes) {}
mflodmancfc8e3b2016-05-04 04:22:04129
130void VideoStreamDecoder::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
131 video_receiver_->SetReceiveChannelParameters(max_rtt_ms);
132
133 rtc::CritScope lock(&crit_);
134 last_rtt_ms_ = avg_rtt_ms;
135}
136} // namespace webrtc