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/modules/video_coding/codecs/vp8/vp8_impl.h" | 11 #include "webrtc/modules/video_coding/codecs/vp8/vp8_impl.h" |
12 | 12 |
13 #include <stdlib.h> | 13 #include <stdlib.h> |
14 #include <string.h> | 14 #include <string.h> |
15 #include <time.h> | 15 #include <time.h> |
16 #include <algorithm> | 16 #include <algorithm> |
17 #include <string> | 17 #include <string> |
18 | 18 |
19 // NOTE(ajm): Path provided by gyp. | 19 // NOTE(ajm): Path provided by gyp. |
20 #include "libyuv/scale.h" // NOLINT | 20 #include "libyuv/scale.h" // NOLINT |
21 #include "libyuv/convert.h" // NOLINT | 21 #include "libyuv/convert.h" // NOLINT |
22 | 22 |
23 #include "webrtc/base/checks.h" | 23 #include "webrtc/base/checks.h" |
| 24 #include "webrtc/base/random.h" |
24 #include "webrtc/base/timeutils.h" | 25 #include "webrtc/base/timeutils.h" |
25 #include "webrtc/base/trace_event.h" | 26 #include "webrtc/base/trace_event.h" |
26 #include "webrtc/common_types.h" | 27 #include "webrtc/common_types.h" |
27 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 28 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
28 #include "webrtc/modules/include/module_common_types.h" | 29 #include "webrtc/modules/include/module_common_types.h" |
29 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | |
30 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 30 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
31 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" | 31 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" |
32 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" | 32 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" |
33 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" | 33 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" |
| 34 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
34 #include "webrtc/system_wrappers/include/clock.h" | 35 #include "webrtc/system_wrappers/include/clock.h" |
35 #include "webrtc/system_wrappers/include/field_trial.h" | 36 #include "webrtc/system_wrappers/include/field_trial.h" |
36 #include "webrtc/system_wrappers/include/metrics.h" | 37 #include "webrtc/system_wrappers/include/metrics.h" |
37 | 38 |
38 namespace webrtc { | 39 namespace webrtc { |
39 namespace { | 40 namespace { |
40 | 41 |
41 const char kVp8PostProcArmFieldTrial[] = "WebRTC-VP8-Postproc-Arm"; | 42 const char kVp8PostProcArmFieldTrial[] = "WebRTC-VP8-Postproc-Arm"; |
42 const char kVp8GfBoostFieldTrial[] = "WebRTC-VP8-GfBoost"; | 43 const char kVp8GfBoostFieldTrial[] = "WebRTC-VP8-GfBoost"; |
43 | 44 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 VP8EncoderImpl::VP8EncoderImpl() | 159 VP8EncoderImpl::VP8EncoderImpl() |
159 : use_gf_boost_(webrtc::field_trial::IsEnabled(kVp8GfBoostFieldTrial)), | 160 : use_gf_boost_(webrtc::field_trial::IsEnabled(kVp8GfBoostFieldTrial)), |
160 encoded_complete_callback_(nullptr), | 161 encoded_complete_callback_(nullptr), |
161 inited_(false), | 162 inited_(false), |
162 timestamp_(0), | 163 timestamp_(0), |
163 qp_max_(56), // Setting for max quantizer. | 164 qp_max_(56), // Setting for max quantizer. |
164 cpu_speed_default_(-6), | 165 cpu_speed_default_(-6), |
165 number_of_cores_(0), | 166 number_of_cores_(0), |
166 rc_max_intra_target_(0), | 167 rc_max_intra_target_(0), |
167 key_frame_request_(kMaxSimulcastStreams, false) { | 168 key_frame_request_(kMaxSimulcastStreams, false) { |
168 uint32_t seed = rtc::Time32(); | 169 Random random(rtc::TimeMicros()); |
169 srand(seed); | |
170 | |
171 picture_id_.reserve(kMaxSimulcastStreams); | 170 picture_id_.reserve(kMaxSimulcastStreams); |
| 171 for (int i = 0; i < kMaxSimulcastStreams; ++i) { |
| 172 picture_id_.push_back(random.Rand<uint16_t>() & 0x7FFF); |
| 173 tl0_pic_idx_.push_back(random.Rand<uint8_t>()); |
| 174 } |
172 temporal_layers_.reserve(kMaxSimulcastStreams); | 175 temporal_layers_.reserve(kMaxSimulcastStreams); |
173 raw_images_.reserve(kMaxSimulcastStreams); | 176 raw_images_.reserve(kMaxSimulcastStreams); |
174 encoded_images_.reserve(kMaxSimulcastStreams); | 177 encoded_images_.reserve(kMaxSimulcastStreams); |
175 send_stream_.reserve(kMaxSimulcastStreams); | 178 send_stream_.reserve(kMaxSimulcastStreams); |
176 cpu_speed_.assign(kMaxSimulcastStreams, cpu_speed_default_); | 179 cpu_speed_.assign(kMaxSimulcastStreams, cpu_speed_default_); |
177 encoders_.reserve(kMaxSimulcastStreams); | 180 encoders_.reserve(kMaxSimulcastStreams); |
178 configurations_.reserve(kMaxSimulcastStreams); | 181 configurations_.reserve(kMaxSimulcastStreams); |
179 downsampling_factors_.reserve(kMaxSimulcastStreams); | 182 downsampling_factors_.reserve(kMaxSimulcastStreams); |
180 } | 183 } |
181 | 184 |
(...skipping 16 matching lines...) Expand all Loading... |
198 } | 201 } |
199 encoders_.pop_back(); | 202 encoders_.pop_back(); |
200 } | 203 } |
201 configurations_.clear(); | 204 configurations_.clear(); |
202 send_stream_.clear(); | 205 send_stream_.clear(); |
203 cpu_speed_.clear(); | 206 cpu_speed_.clear(); |
204 while (!raw_images_.empty()) { | 207 while (!raw_images_.empty()) { |
205 vpx_img_free(&raw_images_.back()); | 208 vpx_img_free(&raw_images_.back()); |
206 raw_images_.pop_back(); | 209 raw_images_.pop_back(); |
207 } | 210 } |
208 while (!temporal_layers_.empty()) { | 211 for (size_t i = 0; i < temporal_layers_.size(); ++i) { |
209 delete temporal_layers_.back(); | 212 tl0_pic_idx_[i] = temporal_layers_[i]->Tl0PicIdx(); |
210 temporal_layers_.pop_back(); | |
211 } | 213 } |
| 214 temporal_layers_.clear(); |
212 inited_ = false; | 215 inited_ = false; |
213 return ret_val; | 216 return ret_val; |
214 } | 217 } |
215 | 218 |
216 int VP8EncoderImpl::SetRateAllocation(const BitrateAllocation& bitrate, | 219 int VP8EncoderImpl::SetRateAllocation(const BitrateAllocation& bitrate, |
217 uint32_t new_framerate) { | 220 uint32_t new_framerate) { |
218 if (!inited_) | 221 if (!inited_) |
219 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 222 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
220 | 223 |
221 if (encoders_[0].err) | 224 if (encoders_[0].err) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 } | 289 } |
287 send_stream_[stream_idx] = send_stream; | 290 send_stream_[stream_idx] = send_stream; |
288 } | 291 } |
289 | 292 |
290 void VP8EncoderImpl::SetupTemporalLayers(int num_streams, | 293 void VP8EncoderImpl::SetupTemporalLayers(int num_streams, |
291 int num_temporal_layers, | 294 int num_temporal_layers, |
292 const VideoCodec& codec) { | 295 const VideoCodec& codec) { |
293 RTC_DCHECK(codec.VP8().tl_factory != nullptr); | 296 RTC_DCHECK(codec.VP8().tl_factory != nullptr); |
294 const TemporalLayersFactory* tl_factory = codec.VP8().tl_factory; | 297 const TemporalLayersFactory* tl_factory = codec.VP8().tl_factory; |
295 if (num_streams == 1) { | 298 if (num_streams == 1) { |
296 temporal_layers_.push_back( | 299 temporal_layers_.emplace_back( |
297 tl_factory->Create(0, num_temporal_layers, rand())); | 300 tl_factory->Create(0, num_temporal_layers, tl0_pic_idx_[0])); |
298 } else { | 301 } else { |
299 for (int i = 0; i < num_streams; ++i) { | 302 for (int i = 0; i < num_streams; ++i) { |
300 RTC_CHECK_GT(num_temporal_layers, 0); | 303 RTC_CHECK_GT(num_temporal_layers, 0); |
301 int layers = std::max(static_cast<uint8_t>(1), | 304 int layers = std::max(static_cast<uint8_t>(1), |
302 codec.simulcastStream[i].numberOfTemporalLayers); | 305 codec.simulcastStream[i].numberOfTemporalLayers); |
303 temporal_layers_.push_back(tl_factory->Create(i, layers, rand())); | 306 temporal_layers_.emplace_back( |
| 307 tl_factory->Create(i, layers, tl0_pic_idx_[i])); |
304 } | 308 } |
305 } | 309 } |
306 } | 310 } |
307 | 311 |
308 int VP8EncoderImpl::InitEncode(const VideoCodec* inst, | 312 int VP8EncoderImpl::InitEncode(const VideoCodec* inst, |
309 int number_of_cores, | 313 int number_of_cores, |
310 size_t /*maxPayloadSize */) { | 314 size_t /*maxPayloadSize */) { |
311 if (inst == NULL) { | 315 if (inst == NULL) { |
312 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 316 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
313 } | 317 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 timestamp_ = 0; | 354 timestamp_ = 0; |
351 codec_ = *inst; | 355 codec_ = *inst; |
352 | 356 |
353 // Code expects simulcastStream resolutions to be correct, make sure they are | 357 // Code expects simulcastStream resolutions to be correct, make sure they are |
354 // filled even when there are no simulcast layers. | 358 // filled even when there are no simulcast layers. |
355 if (codec_.numberOfSimulcastStreams == 0) { | 359 if (codec_.numberOfSimulcastStreams == 0) { |
356 codec_.simulcastStream[0].width = codec_.width; | 360 codec_.simulcastStream[0].width = codec_.width; |
357 codec_.simulcastStream[0].height = codec_.height; | 361 codec_.simulcastStream[0].height = codec_.height; |
358 } | 362 } |
359 | 363 |
360 picture_id_.resize(number_of_streams); | |
361 encoded_images_.resize(number_of_streams); | 364 encoded_images_.resize(number_of_streams); |
362 encoders_.resize(number_of_streams); | 365 encoders_.resize(number_of_streams); |
363 configurations_.resize(number_of_streams); | 366 configurations_.resize(number_of_streams); |
364 downsampling_factors_.resize(number_of_streams); | 367 downsampling_factors_.resize(number_of_streams); |
365 raw_images_.resize(number_of_streams); | 368 raw_images_.resize(number_of_streams); |
366 send_stream_.resize(number_of_streams); | 369 send_stream_.resize(number_of_streams); |
367 send_stream_[0] = true; // For non-simulcast case. | 370 send_stream_[0] = true; // For non-simulcast case. |
368 cpu_speed_.resize(number_of_streams); | 371 cpu_speed_.resize(number_of_streams); |
369 std::fill(key_frame_request_.begin(), key_frame_request_.end(), false); | 372 std::fill(key_frame_request_.begin(), key_frame_request_.end(), false); |
370 | 373 |
371 int idx = number_of_streams - 1; | 374 int idx = number_of_streams - 1; |
372 for (int i = 0; i < (number_of_streams - 1); ++i, --idx) { | 375 for (int i = 0; i < (number_of_streams - 1); ++i, --idx) { |
373 int gcd = GCD(inst->simulcastStream[idx].width, | 376 int gcd = GCD(inst->simulcastStream[idx].width, |
374 inst->simulcastStream[idx - 1].width); | 377 inst->simulcastStream[idx - 1].width); |
375 downsampling_factors_[i].num = inst->simulcastStream[idx].width / gcd; | 378 downsampling_factors_[i].num = inst->simulcastStream[idx].width / gcd; |
376 downsampling_factors_[i].den = inst->simulcastStream[idx - 1].width / gcd; | 379 downsampling_factors_[i].den = inst->simulcastStream[idx - 1].width / gcd; |
377 send_stream_[i] = false; | 380 send_stream_[i] = false; |
378 } | 381 } |
379 if (number_of_streams > 1) { | 382 if (number_of_streams > 1) { |
380 send_stream_[number_of_streams - 1] = false; | 383 send_stream_[number_of_streams - 1] = false; |
381 downsampling_factors_[number_of_streams - 1].num = 1; | 384 downsampling_factors_[number_of_streams - 1].num = 1; |
382 downsampling_factors_[number_of_streams - 1].den = 1; | 385 downsampling_factors_[number_of_streams - 1].den = 1; |
383 } | 386 } |
384 for (int i = 0; i < number_of_streams; ++i) { | 387 for (int i = 0; i < number_of_streams; ++i) { |
385 // Random start, 16 bits is enough. | |
386 picture_id_[i] = static_cast<uint16_t>(rand()) & 0x7FFF; // NOLINT | |
387 // allocate memory for encoded image | 388 // allocate memory for encoded image |
388 if (encoded_images_[i]._buffer != NULL) { | 389 if (encoded_images_[i]._buffer != NULL) { |
389 delete[] encoded_images_[i]._buffer; | 390 delete[] encoded_images_[i]._buffer; |
390 } | 391 } |
391 encoded_images_[i]._size = | 392 encoded_images_[i]._size = |
392 CalcBufferSize(VideoType::kI420, codec_.width, codec_.height); | 393 CalcBufferSize(VideoType::kI420, codec_.width, codec_.height); |
393 encoded_images_[i]._buffer = new uint8_t[encoded_images_[i]._size]; | 394 encoded_images_[i]._buffer = new uint8_t[encoded_images_[i]._size]; |
394 encoded_images_[i]._completeFrame = true; | 395 encoded_images_[i]._completeFrame = true; |
395 } | 396 } |
396 // populate encoder configuration with default values | 397 // populate encoder configuration with default values |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 buffer_pool_.Release(); | 1143 buffer_pool_.Release(); |
1143 inited_ = false; | 1144 inited_ = false; |
1144 return WEBRTC_VIDEO_CODEC_OK; | 1145 return WEBRTC_VIDEO_CODEC_OK; |
1145 } | 1146 } |
1146 | 1147 |
1147 const char* VP8DecoderImpl::ImplementationName() const { | 1148 const char* VP8DecoderImpl::ImplementationName() const { |
1148 return "libvpx"; | 1149 return "libvpx"; |
1149 } | 1150 } |
1150 | 1151 |
1151 } // namespace webrtc | 1152 } // namespace webrtc |
OLD | NEW |