blob: b27a52ea8923cea3abb0735b043db3a61a8a27c1 [file] [log] [blame]
mflodmancfc8e3b2016-05-03 21:22:04 -07001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "video/video_stream_decoder.h"
mflodmancfc8e3b2016-05-03 21:22:04 -070012
13#include <algorithm>
14#include <map>
15#include <vector>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "common_video/include/frame_callback.h"
18#include "modules/video_coding/video_coding_impl.h"
19#include "rtc_base/checks.h"
20#include "rtc_base/logging.h"
21#include "system_wrappers/include/metrics.h"
22#include "video/call_stats.h"
23#include "video/payload_router.h"
24#include "video/receive_statistics_proxy.h"
mflodmancfc8e3b2016-05-03 21:22:04 -070025
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 00:26:43 -070033 bool enable_fec,
mflodmancfc8e3b2016-05-03 21:22:04 -070034 ReceiveStatisticsProxy* receive_statistics_proxy,
nisse76bc8e82017-02-07 09:37:41 -080035 rtc::VideoSinkInterface<VideoFrame>* incoming_video_stream)
mflodmancfc8e3b2016-05-03 21:22:04 -070036 : video_receiver_(video_receiver),
37 receive_stats_callback_(receive_statistics_proxy),
38 incoming_video_stream_(incoming_video_stream),
mflodmancfc8e3b2016-05-03 21:22:04 -070039 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);
mflodmancfc8e3b2016-05-03 21:22:04 -070049
tommi2e82f382016-06-21 00:26:43 -070050 VCMVideoProtection video_protection =
51 enable_nack ? (enable_fec ? kProtectionNackFEC : kProtectionNack)
52 : kProtectionNone;
philipelae284082016-05-09 12:14:29 +020053
mflodmancfc8e3b2016-05-03 21:22:04 -070054 VCMDecodeErrorMode decode_error_mode = enable_nack ? kNoErrors : kWithErrors;
55 video_receiver_->SetVideoProtection(video_protection, true);
56 video_receiver_->SetDecodeErrorMode(decode_error_mode);
57 VCMPacketRequestCallback* packet_request_callback =
58 enable_nack ? vcm_packet_request_callback : nullptr;
59 video_receiver_->RegisterPacketRequestCallback(packet_request_callback);
60}
61
tommi2e82f382016-06-21 00:26:43 -070062VideoStreamDecoder::~VideoStreamDecoder() {
tommid0a71ba2017-03-14 04:16:20 -070063 // Note: There's an assumption at this point that the decoder thread is
64 // *not* running. If it was, then there could be a race for each of these
65 // callbacks.
66
tommi2e82f382016-06-21 00:26:43 -070067 // Unset all the callback pointers that we set in the ctor.
68 video_receiver_->RegisterPacketRequestCallback(nullptr);
tommi2e82f382016-06-21 00:26:43 -070069 video_receiver_->RegisterReceiveStatisticsCallback(nullptr);
70 video_receiver_->RegisterFrameTypeCallback(nullptr);
71 video_receiver_->RegisterReceiveCallback(nullptr);
72}
mflodmancfc8e3b2016-05-03 21:22:04 -070073
74// Do not acquire the lock of |video_receiver_| in this function. Decode
75// callback won't necessarily be called from the decoding thread. The decoding
76// thread may have held the lock when calling VideoDecoder::Decode, Reset, or
77// Release. Acquiring the same lock in the path of decode callback can deadlock.
sakalcc452e12017-02-09 04:53:45 -080078int32_t VideoStreamDecoder::FrameToRender(VideoFrame& video_frame,
ilnik00d802b2017-04-11 10:34:31 -070079 rtc::Optional<uint8_t> qp,
80 VideoContentType content_type) {
81 receive_stats_callback_->OnDecodedFrame(qp, content_type);
sakal55d932b2016-09-30 06:19:08 -070082 incoming_video_stream_->OnFrame(video_frame);
mflodmancfc8e3b2016-05-03 21:22:04 -070083 return 0;
84}
85
86int32_t VideoStreamDecoder::ReceivedDecodedReferenceFrame(
87 const uint64_t picture_id) {
88 RTC_NOTREACHED();
89 return 0;
90}
91
92void VideoStreamDecoder::OnIncomingPayloadType(int payload_type) {
93 receive_stats_callback_->OnIncomingPayloadType(payload_type);
94}
95
96void VideoStreamDecoder::OnDecoderImplementationName(
97 const char* implementation_name) {
98 receive_stats_callback_->OnDecoderImplementationName(implementation_name);
99}
100
101void VideoStreamDecoder::OnReceiveRatesUpdated(uint32_t bit_rate,
102 uint32_t frame_rate) {
103 receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate);
104}
105
106void VideoStreamDecoder::OnDiscardedPacketsUpdated(int discarded_packets) {
107 receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
108}
109
110void VideoStreamDecoder::OnFrameCountsUpdated(const FrameCounts& frame_counts) {
111 receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
112}
113
philipela45102f2017-02-22 05:30:39 -0800114void VideoStreamDecoder::OnFrameBufferTimingsUpdated(int decode_ms,
115 int max_decode_ms,
116 int current_delay_ms,
117 int target_delay_ms,
118 int jitter_buffer_ms,
119 int min_playout_delay_ms,
120 int render_delay_ms) {}
121
ilnik2edc6842017-07-06 03:06:50 -0700122void VideoStreamDecoder::OnTimingFrameInfoUpdated(const TimingFrameInfo& info) {
123}
124
ilnik6d5b4d62017-08-30 03:32:14 -0700125void VideoStreamDecoder::OnCompleteFrame(bool is_keyframe,
126 size_t size_bytes,
127 VideoContentType content_type) {}
mflodmancfc8e3b2016-05-03 21:22:04 -0700128
129void VideoStreamDecoder::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
130 video_receiver_->SetReceiveChannelParameters(max_rtt_ms);
131
132 rtc::CritScope lock(&crit_);
133 last_rtt_ms_ = avg_rtt_ms;
134}
135} // namespace webrtc