OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/video/vie_encoder.h" | 11 #include "webrtc/video/vie_encoder.h" |
12 | 12 |
13 #include <assert.h> | |
14 | |
15 #include <algorithm> | 13 #include <algorithm> |
14 #include <limits> | |
16 | 15 |
17 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
18 #include "webrtc/base/logging.h" | 17 #include "webrtc/base/logging.h" |
19 #include "webrtc/base/trace_event.h" | 18 #include "webrtc/base/trace_event.h" |
20 #include "webrtc/base/timeutils.h" | 19 #include "webrtc/base/timeutils.h" |
21 #include "webrtc/modules/pacing/paced_sender.h" | 20 #include "webrtc/modules/pacing/paced_sender.h" |
22 #include "webrtc/modules/video_coding/include/video_coding.h" | 21 #include "webrtc/modules/video_coding/include/video_coding.h" |
23 #include "webrtc/modules/video_coding/include/video_coding_defines.h" | 22 #include "webrtc/modules/video_coding/include/video_coding_defines.h" |
24 #include "webrtc/system_wrappers/include/metrics.h" | 23 #include "webrtc/system_wrappers/include/metrics.h" |
25 #include "webrtc/video/overuse_frame_detector.h" | 24 #include "webrtc/video/overuse_frame_detector.h" |
26 #include "webrtc/video/send_statistics_proxy.h" | 25 #include "webrtc/video/send_statistics_proxy.h" |
27 #include "webrtc/video_frame.h" | 26 #include "webrtc/video_frame.h" |
28 | 27 |
29 namespace webrtc { | 28 namespace webrtc { |
30 | 29 |
31 ViEEncoder::ViEEncoder(uint32_t number_of_cores, | 30 ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
32 ProcessThread* module_process_thread, | 31 ProcessThread* module_process_thread, |
33 SendStatisticsProxy* stats_proxy, | 32 SendStatisticsProxy* stats_proxy, |
34 OveruseFrameDetector* overuse_detector, | 33 OveruseFrameDetector* overuse_detector, |
35 EncodedImageCallback* sink) | 34 EncodedImageCallback* sink) |
36 : number_of_cores_(number_of_cores), | 35 : number_of_cores_(number_of_cores), |
37 sink_(sink), | 36 sink_(sink), |
38 vp_(VideoProcessing::Create()), | 37 vp_(VideoProcessing::Create()), |
39 video_sender_(Clock::GetRealTimeClock(), this, this, this), | 38 video_sender_(Clock::GetRealTimeClock(), this, this, this), |
40 stats_proxy_(stats_proxy), | 39 stats_proxy_(stats_proxy), |
41 overuse_detector_(overuse_detector), | 40 overuse_detector_(overuse_detector), |
42 time_of_last_frame_activity_ms_(0), | 41 time_of_last_frame_activity_ms_(std::numeric_limits<int64_t>::max()), |
pbos-webrtc
2016/06/17 12:38:21
Can you use -1 instead as unset? This type should
perkj_webrtc
2016/06/17 13:06:32
It must be large value at the moment. I will be f
| |
43 encoder_config_(), | 42 encoder_config_(), |
44 last_observed_bitrate_bps_(0), | 43 last_observed_bitrate_bps_(0), |
45 encoder_paused_(true), | |
46 encoder_paused_and_dropped_frame_(false), | 44 encoder_paused_and_dropped_frame_(false), |
47 module_process_thread_(module_process_thread), | 45 module_process_thread_(module_process_thread), |
48 has_received_sli_(false), | 46 has_received_sli_(false), |
49 picture_id_sli_(0), | 47 picture_id_sli_(0), |
50 has_received_rpsi_(false), | 48 has_received_rpsi_(false), |
51 picture_id_rpsi_(0), | 49 picture_id_rpsi_(0), |
52 video_suspended_(false) { | 50 video_suspended_(false) { |
53 module_process_thread_->RegisterModule(&video_sender_); | 51 module_process_thread_->RegisterModule(&video_sender_); |
54 vp_->EnableTemporalDecimation(true); | 52 vp_->EnableTemporalDecimation(true); |
55 } | 53 } |
56 | 54 |
57 vcm::VideoSender* ViEEncoder::video_sender() { | 55 vcm::VideoSender* ViEEncoder::video_sender() { |
58 return &video_sender_; | 56 return &video_sender_; |
59 } | 57 } |
60 | 58 |
61 ViEEncoder::~ViEEncoder() { | 59 ViEEncoder::~ViEEncoder() { |
62 module_process_thread_->DeRegisterModule(&video_sender_); | 60 module_process_thread_->DeRegisterModule(&video_sender_); |
63 } | 61 } |
64 | 62 |
65 void ViEEncoder::Pause() { | |
66 rtc::CritScope lock(&data_cs_); | |
67 encoder_paused_ = true; | |
68 } | |
69 | |
70 void ViEEncoder::Start() { | |
71 rtc::CritScope lock(&data_cs_); | |
72 encoder_paused_ = false; | |
73 } | |
74 | |
75 int32_t ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder, | 63 int32_t ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder, |
76 uint8_t pl_type, | 64 uint8_t pl_type, |
77 bool internal_source) { | 65 bool internal_source) { |
78 video_sender_.RegisterExternalEncoder(encoder, pl_type, internal_source); | 66 video_sender_.RegisterExternalEncoder(encoder, pl_type, internal_source); |
79 return 0; | 67 return 0; |
80 } | 68 } |
81 | 69 |
82 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { | 70 int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { |
83 video_sender_.RegisterExternalEncoder(nullptr, pl_type, false); | 71 video_sender_.RegisterExternalEncoder(nullptr, pl_type, false); |
84 return 0; | 72 return 0; |
85 } | 73 } |
86 | 74 |
87 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, | 75 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec, |
88 size_t max_data_payload_length) { | 76 size_t max_data_payload_length) { |
89 // Setting target width and height for VPM. | 77 // Setting target width and height for VPM. |
90 RTC_CHECK_EQ(VPM_OK, | 78 RTC_CHECK_EQ(VPM_OK, |
91 vp_->SetTargetResolution(video_codec.width, video_codec.height, | 79 vp_->SetTargetResolution(video_codec.width, video_codec.height, |
92 video_codec.maxFramerate)); | 80 video_codec.maxFramerate)); |
93 | |
94 // Cache codec before calling AddBitrateObserver (which calls OnBitrateUpdated | |
95 // that makes use of the number of simulcast streams configured). | |
96 { | 81 { |
97 rtc::CritScope lock(&data_cs_); | 82 rtc::CritScope lock(&data_cs_); |
98 encoder_config_ = video_codec; | 83 encoder_config_ = video_codec; |
99 } | 84 } |
100 | 85 |
101 bool success = video_sender_.RegisterSendCodec( | 86 bool success = video_sender_.RegisterSendCodec( |
102 &video_codec, number_of_cores_, | 87 &video_codec, number_of_cores_, |
103 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; | 88 static_cast<uint32_t>(max_data_payload_length)) == VCM_OK; |
89 | |
104 if (!success) { | 90 if (!success) { |
105 LOG(LS_ERROR) << "Failed to configure encoder."; | 91 LOG(LS_ERROR) << "Failed to configure encoder."; |
106 RTC_DCHECK(success); | 92 RTC_DCHECK(success); |
107 } | 93 } |
108 | 94 |
109 if (stats_proxy_) { | 95 if (stats_proxy_) { |
110 VideoEncoderConfig::ContentType content_type = | 96 VideoEncoderConfig::ContentType content_type = |
111 VideoEncoderConfig::ContentType::kRealtimeVideo; | 97 VideoEncoderConfig::ContentType::kRealtimeVideo; |
112 switch (video_codec.mode) { | 98 switch (video_codec.mode) { |
113 case kRealtimeVideo: | 99 case kRealtimeVideo: |
114 content_type = VideoEncoderConfig::ContentType::kRealtimeVideo; | 100 content_type = VideoEncoderConfig::ContentType::kRealtimeVideo; |
115 break; | 101 break; |
116 case kScreensharing: | 102 case kScreensharing: |
117 content_type = VideoEncoderConfig::ContentType::kScreen; | 103 content_type = VideoEncoderConfig::ContentType::kScreen; |
118 break; | 104 break; |
119 default: | 105 default: |
120 RTC_NOTREACHED(); | 106 RTC_NOTREACHED(); |
121 break; | 107 break; |
122 } | 108 } |
123 stats_proxy_->SetContentType(content_type); | 109 stats_proxy_->SetContentType(content_type); |
124 } | 110 } |
125 } | 111 } |
126 | 112 |
127 bool ViEEncoder::EncoderPaused() const { | 113 bool ViEEncoder::EncoderPaused() const { |
128 // Pause video if paused by caller or as long as the network is down or the | 114 // Pause video if paused by caller or as long as the network is down or the |
129 // pacer queue has grown too large in buffered mode. | 115 // pacer queue has grown too large in buffered mode. |
130 // If the pacer queue has grown to large or the network is down, | 116 // If the pacer queue has grown too large or the network is down, |
131 // last_observed_bitrate_bps_ will be 0. | 117 // last_observed_bitrate_bps_ will be 0. |
132 return encoder_paused_ || video_suspended_ || last_observed_bitrate_bps_ == 0; | 118 return video_suspended_ || last_observed_bitrate_bps_ == 0; |
133 } | 119 } |
134 | 120 |
135 void ViEEncoder::TraceFrameDropStart() { | 121 void ViEEncoder::TraceFrameDropStart() { |
136 // Start trace event only on the first frame after encoder is paused. | 122 // Start trace event only on the first frame after encoder is paused. |
137 if (!encoder_paused_and_dropped_frame_) { | 123 if (!encoder_paused_and_dropped_frame_) { |
138 TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this); | 124 TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this); |
139 } | 125 } |
140 encoder_paused_and_dropped_frame_ = true; | 126 encoder_paused_and_dropped_frame_ = true; |
141 return; | 127 return; |
142 } | 128 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 << " rtt " << round_trip_time_ms; | 249 << " rtt " << round_trip_time_ms; |
264 video_sender_.SetChannelParameters(bitrate_bps, fraction_lost, | 250 video_sender_.SetChannelParameters(bitrate_bps, fraction_lost, |
265 round_trip_time_ms); | 251 round_trip_time_ms); |
266 bool video_suspension_changed; | 252 bool video_suspension_changed; |
267 bool video_is_suspended = bitrate_bps == 0; | 253 bool video_is_suspended = bitrate_bps == 0; |
268 { | 254 { |
269 rtc::CritScope lock(&data_cs_); | 255 rtc::CritScope lock(&data_cs_); |
270 last_observed_bitrate_bps_ = bitrate_bps; | 256 last_observed_bitrate_bps_ = bitrate_bps; |
271 video_suspension_changed = video_suspended_ != video_is_suspended; | 257 video_suspension_changed = video_suspended_ != video_is_suspended; |
272 video_suspended_ = video_is_suspended; | 258 video_suspended_ = video_is_suspended; |
259 // Set |time_of_last_frame_activity_ms_| to now if this is the first time | |
260 // the encoder is supposed to produce encoded frames. | |
261 // TODO(perkj): Remove this hack. It is here to avoid a race that the | |
262 // encoder report that it has timed out before it has processed the first | |
263 // frame. | |
264 if (last_observed_bitrate_bps_ != 0 && | |
265 time_of_last_frame_activity_ms_ == | |
266 std::numeric_limits<int64_t>::max()) { | |
267 time_of_last_frame_activity_ms_ = rtc::TimeMillis(); | |
268 } | |
273 } | 269 } |
274 | 270 |
275 if (stats_proxy_ && video_suspension_changed) { | 271 if (stats_proxy_ && video_suspension_changed) { |
276 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended; | 272 LOG(LS_INFO) << "Video suspend state changed " << video_is_suspended; |
277 stats_proxy_->OnSuspendChange(video_is_suspended); | 273 stats_proxy_->OnSuspendChange(video_is_suspended); |
278 } | 274 } |
279 } | 275 } |
280 | 276 |
281 } // namespace webrtc | 277 } // namespace webrtc |
OLD | NEW |