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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 VP8EncoderImpl::VP8EncoderImpl() | 135 VP8EncoderImpl::VP8EncoderImpl() |
135 : use_gf_boost_(webrtc::field_trial::IsEnabled(kVp8GfBoostFieldTrial)), | 136 : use_gf_boost_(webrtc::field_trial::IsEnabled(kVp8GfBoostFieldTrial)), |
136 encoded_complete_callback_(nullptr), | 137 encoded_complete_callback_(nullptr), |
137 inited_(false), | 138 inited_(false), |
138 timestamp_(0), | 139 timestamp_(0), |
139 qp_max_(56), // Setting for max quantizer. | 140 qp_max_(56), // Setting for max quantizer. |
140 cpu_speed_default_(-6), | 141 cpu_speed_default_(-6), |
141 number_of_cores_(0), | 142 number_of_cores_(0), |
142 rc_max_intra_target_(0), | 143 rc_max_intra_target_(0), |
143 key_frame_request_(kMaxSimulcastStreams, false) { | 144 key_frame_request_(kMaxSimulcastStreams, false) { |
144 uint32_t seed = rtc::Time32(); | 145 Random random(rtc::TimeMillis()); |
145 srand(seed); | |
146 | |
147 picture_id_.reserve(kMaxSimulcastStreams); | 146 picture_id_.reserve(kMaxSimulcastStreams); |
| 147 for (int i = 0; i < kMaxSimulcastStreams; ++i) { |
| 148 picture_id_.push_back(random.Rand<uint16_t>() & 0x7FFF); |
| 149 tl0_pic_idx_.push_back(random.Rand<uint8_t>()); |
| 150 } |
148 last_key_frame_picture_id_.reserve(kMaxSimulcastStreams); | 151 last_key_frame_picture_id_.reserve(kMaxSimulcastStreams); |
149 temporal_layers_.reserve(kMaxSimulcastStreams); | 152 temporal_layers_.reserve(kMaxSimulcastStreams); |
150 raw_images_.reserve(kMaxSimulcastStreams); | 153 raw_images_.reserve(kMaxSimulcastStreams); |
151 encoded_images_.reserve(kMaxSimulcastStreams); | 154 encoded_images_.reserve(kMaxSimulcastStreams); |
152 send_stream_.reserve(kMaxSimulcastStreams); | 155 send_stream_.reserve(kMaxSimulcastStreams); |
153 cpu_speed_.assign(kMaxSimulcastStreams, cpu_speed_default_); | 156 cpu_speed_.assign(kMaxSimulcastStreams, cpu_speed_default_); |
154 encoders_.reserve(kMaxSimulcastStreams); | 157 encoders_.reserve(kMaxSimulcastStreams); |
155 configurations_.reserve(kMaxSimulcastStreams); | 158 configurations_.reserve(kMaxSimulcastStreams); |
156 downsampling_factors_.reserve(kMaxSimulcastStreams); | 159 downsampling_factors_.reserve(kMaxSimulcastStreams); |
157 } | 160 } |
(...skipping 17 matching lines...) Expand all Loading... |
175 } | 178 } |
176 encoders_.pop_back(); | 179 encoders_.pop_back(); |
177 } | 180 } |
178 configurations_.clear(); | 181 configurations_.clear(); |
179 send_stream_.clear(); | 182 send_stream_.clear(); |
180 cpu_speed_.clear(); | 183 cpu_speed_.clear(); |
181 while (!raw_images_.empty()) { | 184 while (!raw_images_.empty()) { |
182 vpx_img_free(&raw_images_.back()); | 185 vpx_img_free(&raw_images_.back()); |
183 raw_images_.pop_back(); | 186 raw_images_.pop_back(); |
184 } | 187 } |
185 while (!temporal_layers_.empty()) { | 188 for (size_t i = 0; i < temporal_layers_.size(); ++i) { |
186 delete temporal_layers_.back(); | 189 tl0_pic_idx_[i] = temporal_layers_[i]->Tl0PicIdx(); |
187 temporal_layers_.pop_back(); | |
188 } | 190 } |
| 191 temporal_layers_.clear(); |
189 inited_ = false; | 192 inited_ = false; |
190 return ret_val; | 193 return ret_val; |
191 } | 194 } |
192 | 195 |
193 int VP8EncoderImpl::SetRateAllocation(const BitrateAllocation& bitrate, | 196 int VP8EncoderImpl::SetRateAllocation(const BitrateAllocation& bitrate, |
194 uint32_t new_framerate) { | 197 uint32_t new_framerate) { |
195 if (!inited_) | 198 if (!inited_) |
196 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 199 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
197 | 200 |
198 if (encoders_[0].err) | 201 if (encoders_[0].err) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 } | 266 } |
264 send_stream_[stream_idx] = send_stream; | 267 send_stream_[stream_idx] = send_stream; |
265 } | 268 } |
266 | 269 |
267 void VP8EncoderImpl::SetupTemporalLayers(int num_streams, | 270 void VP8EncoderImpl::SetupTemporalLayers(int num_streams, |
268 int num_temporal_layers, | 271 int num_temporal_layers, |
269 const VideoCodec& codec) { | 272 const VideoCodec& codec) { |
270 RTC_DCHECK(codec.VP8().tl_factory != nullptr); | 273 RTC_DCHECK(codec.VP8().tl_factory != nullptr); |
271 const TemporalLayersFactory* tl_factory = codec.VP8().tl_factory; | 274 const TemporalLayersFactory* tl_factory = codec.VP8().tl_factory; |
272 if (num_streams == 1) { | 275 if (num_streams == 1) { |
273 temporal_layers_.push_back( | 276 temporal_layers_.emplace_back( |
274 tl_factory->Create(0, num_temporal_layers, rand())); | 277 tl_factory->Create(0, num_temporal_layers, tl0_pic_idx_[0])); |
275 } else { | 278 } else { |
276 for (int i = 0; i < num_streams; ++i) { | 279 for (int i = 0; i < num_streams; ++i) { |
277 RTC_CHECK_GT(num_temporal_layers, 0); | 280 RTC_CHECK_GT(num_temporal_layers, 0); |
278 int layers = std::max(static_cast<uint8_t>(1), | 281 int layers = std::max(static_cast<uint8_t>(1), |
279 codec.simulcastStream[i].numberOfTemporalLayers); | 282 codec.simulcastStream[i].numberOfTemporalLayers); |
280 temporal_layers_.push_back(tl_factory->Create(i, layers, rand())); | 283 temporal_layers_.emplace_back( |
| 284 tl_factory->Create(i, layers, tl0_pic_idx_[i])); |
281 } | 285 } |
282 } | 286 } |
283 } | 287 } |
284 | 288 |
285 int VP8EncoderImpl::InitEncode(const VideoCodec* inst, | 289 int VP8EncoderImpl::InitEncode(const VideoCodec* inst, |
286 int number_of_cores, | 290 int number_of_cores, |
287 size_t /*maxPayloadSize */) { | 291 size_t /*maxPayloadSize */) { |
288 if (inst == NULL) { | 292 if (inst == NULL) { |
289 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 293 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
290 } | 294 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 timestamp_ = 0; | 331 timestamp_ = 0; |
328 codec_ = *inst; | 332 codec_ = *inst; |
329 | 333 |
330 // Code expects simulcastStream resolutions to be correct, make sure they are | 334 // Code expects simulcastStream resolutions to be correct, make sure they are |
331 // filled even when there are no simulcast layers. | 335 // filled even when there are no simulcast layers. |
332 if (codec_.numberOfSimulcastStreams == 0) { | 336 if (codec_.numberOfSimulcastStreams == 0) { |
333 codec_.simulcastStream[0].width = codec_.width; | 337 codec_.simulcastStream[0].width = codec_.width; |
334 codec_.simulcastStream[0].height = codec_.height; | 338 codec_.simulcastStream[0].height = codec_.height; |
335 } | 339 } |
336 | 340 |
337 picture_id_.resize(number_of_streams); | |
338 last_key_frame_picture_id_.resize(number_of_streams); | 341 last_key_frame_picture_id_.resize(number_of_streams); |
339 encoded_images_.resize(number_of_streams); | 342 encoded_images_.resize(number_of_streams); |
340 encoders_.resize(number_of_streams); | 343 encoders_.resize(number_of_streams); |
341 configurations_.resize(number_of_streams); | 344 configurations_.resize(number_of_streams); |
342 downsampling_factors_.resize(number_of_streams); | 345 downsampling_factors_.resize(number_of_streams); |
343 raw_images_.resize(number_of_streams); | 346 raw_images_.resize(number_of_streams); |
344 send_stream_.resize(number_of_streams); | 347 send_stream_.resize(number_of_streams); |
345 send_stream_[0] = true; // For non-simulcast case. | 348 send_stream_[0] = true; // For non-simulcast case. |
346 cpu_speed_.resize(number_of_streams); | 349 cpu_speed_.resize(number_of_streams); |
347 std::fill(key_frame_request_.begin(), key_frame_request_.end(), false); | 350 std::fill(key_frame_request_.begin(), key_frame_request_.end(), false); |
348 | 351 |
349 int idx = number_of_streams - 1; | 352 int idx = number_of_streams - 1; |
350 for (int i = 0; i < (number_of_streams - 1); ++i, --idx) { | 353 for (int i = 0; i < (number_of_streams - 1); ++i, --idx) { |
351 int gcd = GCD(inst->simulcastStream[idx].width, | 354 int gcd = GCD(inst->simulcastStream[idx].width, |
352 inst->simulcastStream[idx - 1].width); | 355 inst->simulcastStream[idx - 1].width); |
353 downsampling_factors_[i].num = inst->simulcastStream[idx].width / gcd; | 356 downsampling_factors_[i].num = inst->simulcastStream[idx].width / gcd; |
354 downsampling_factors_[i].den = inst->simulcastStream[idx - 1].width / gcd; | 357 downsampling_factors_[i].den = inst->simulcastStream[idx - 1].width / gcd; |
355 send_stream_[i] = false; | 358 send_stream_[i] = false; |
356 } | 359 } |
357 if (number_of_streams > 1) { | 360 if (number_of_streams > 1) { |
358 send_stream_[number_of_streams - 1] = false; | 361 send_stream_[number_of_streams - 1] = false; |
359 downsampling_factors_[number_of_streams - 1].num = 1; | 362 downsampling_factors_[number_of_streams - 1].num = 1; |
360 downsampling_factors_[number_of_streams - 1].den = 1; | 363 downsampling_factors_[number_of_streams - 1].den = 1; |
361 } | 364 } |
362 for (int i = 0; i < number_of_streams; ++i) { | 365 for (int i = 0; i < number_of_streams; ++i) { |
363 // Random start, 16 bits is enough. | |
364 picture_id_[i] = static_cast<uint16_t>(rand()) & 0x7FFF; // NOLINT | |
365 last_key_frame_picture_id_[i] = -1; | 366 last_key_frame_picture_id_[i] = -1; |
366 // allocate memory for encoded image | 367 // allocate memory for encoded image |
367 if (encoded_images_[i]._buffer != NULL) { | 368 if (encoded_images_[i]._buffer != NULL) { |
368 delete[] encoded_images_[i]._buffer; | 369 delete[] encoded_images_[i]._buffer; |
369 } | 370 } |
370 encoded_images_[i]._size = | 371 encoded_images_[i]._size = |
371 CalcBufferSize(kI420, codec_.width, codec_.height); | 372 CalcBufferSize(kI420, codec_.width, codec_.height); |
372 encoded_images_[i]._buffer = new uint8_t[encoded_images_[i]._size]; | 373 encoded_images_[i]._buffer = new uint8_t[encoded_images_[i]._size]; |
373 encoded_images_[i]._completeFrame = true; | 374 encoded_images_[i]._completeFrame = true; |
374 } | 375 } |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 buffer_pool_.Release(); | 1153 buffer_pool_.Release(); |
1153 inited_ = false; | 1154 inited_ = false; |
1154 return WEBRTC_VIDEO_CODEC_OK; | 1155 return WEBRTC_VIDEO_CODEC_OK; |
1155 } | 1156 } |
1156 | 1157 |
1157 const char* VP8DecoderImpl::ImplementationName() const { | 1158 const char* VP8DecoderImpl::ImplementationName() const { |
1158 return "libvpx"; | 1159 return "libvpx"; |
1159 } | 1160 } |
1160 | 1161 |
1161 } // namespace webrtc | 1162 } // namespace webrtc |
OLD | NEW |