OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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/media/engine/simulcast_encoder_adapter.h" | 11 #include "webrtc/media/engine/simulcast_encoder_adapter.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 | 14 |
15 // NOTE(ajm): Path provided by gyp. | 15 // NOTE(ajm): Path provided by gyp. |
16 #include "libyuv/scale.h" // NOLINT | 16 #include "libyuv/scale.h" // NOLINT |
17 | 17 |
18 #include "webrtc/api/video/i420_buffer.h" | 18 #include "webrtc/api/video/i420_buffer.h" |
| 19 #include "webrtc/media/engine/scopedvideoencoder.h" |
19 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" | 20 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" |
20 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" | 21 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_rate_allocator.h" |
21 #include "webrtc/rtc_base/checks.h" | 22 #include "webrtc/rtc_base/checks.h" |
22 #include "webrtc/system_wrappers/include/clock.h" | 23 #include "webrtc/system_wrappers/include/clock.h" |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 const unsigned int kDefaultMinQp = 2; | 27 const unsigned int kDefaultMinQp = 2; |
27 const unsigned int kDefaultMaxQp = 56; | 28 const unsigned int kDefaultMaxQp = 56; |
28 // Max qp for lowest spatial resolution when doing simulcast. | 29 // Max qp for lowest spatial resolution when doing simulcast. |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 | 142 |
142 SimulcastEncoderAdapter::~SimulcastEncoderAdapter() { | 143 SimulcastEncoderAdapter::~SimulcastEncoderAdapter() { |
143 RTC_DCHECK(!Initialized()); | 144 RTC_DCHECK(!Initialized()); |
144 DestroyStoredEncoders(); | 145 DestroyStoredEncoders(); |
145 } | 146 } |
146 | 147 |
147 int SimulcastEncoderAdapter::Release() { | 148 int SimulcastEncoderAdapter::Release() { |
148 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_); | 149 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_); |
149 | 150 |
150 while (!streaminfos_.empty()) { | 151 while (!streaminfos_.empty()) { |
151 VideoEncoder* encoder = streaminfos_.back().encoder; | 152 std::unique_ptr<VideoEncoder> encoder = |
| 153 std::move(streaminfos_.back().encoder); |
152 encoder->Release(); | 154 encoder->Release(); |
153 // Even though it seems very unlikely, there are no guarantees that the | 155 // Even though it seems very unlikely, there are no guarantees that the |
154 // encoder will not call back after being Release()'d. Therefore, we disable | 156 // encoder will not call back after being Release()'d. Therefore, we disable |
155 // the callbacks here. | 157 // the callbacks here. |
156 encoder->RegisterEncodeCompleteCallback(nullptr); | 158 encoder->RegisterEncodeCompleteCallback(nullptr); |
157 streaminfos_.pop_back(); // Deletes callback adapter. | 159 streaminfos_.pop_back(); // Deletes callback adapter. |
158 stored_encoders_.push(encoder); | 160 stored_encoders_.push(std::move(encoder)); |
159 } | 161 } |
160 | 162 |
161 // It's legal to move the encoder to another queue now. | 163 // It's legal to move the encoder to another queue now. |
162 encoder_queue_.Detach(); | 164 encoder_queue_.Detach(); |
163 | 165 |
164 rtc::AtomicOps::ReleaseStore(&inited_, 0); | 166 rtc::AtomicOps::ReleaseStore(&inited_, 0); |
165 | 167 |
166 return WEBRTC_VIDEO_CODEC_OK; | 168 return WEBRTC_VIDEO_CODEC_OK; |
167 } | 169 } |
168 | 170 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 stream_codec.VP8()->tl_factory = &tl_factory_adapter; | 227 stream_codec.VP8()->tl_factory = &tl_factory_adapter; |
226 | 228 |
227 // TODO(ronghuawu): Remove once this is handled in VP8EncoderImpl. | 229 // TODO(ronghuawu): Remove once this is handled in VP8EncoderImpl. |
228 if (stream_codec.qpMax < kDefaultMinQp) { | 230 if (stream_codec.qpMax < kDefaultMinQp) { |
229 stream_codec.qpMax = kDefaultMaxQp; | 231 stream_codec.qpMax = kDefaultMaxQp; |
230 } | 232 } |
231 | 233 |
232 // If an existing encoder instance exists, reuse it. | 234 // If an existing encoder instance exists, reuse it. |
233 // TODO(brandtr): Set initial RTP state (e.g., picture_id/tl0_pic_idx) here, | 235 // TODO(brandtr): Set initial RTP state (e.g., picture_id/tl0_pic_idx) here, |
234 // when we start storing that state outside the encoder wrappers. | 236 // when we start storing that state outside the encoder wrappers. |
235 VideoEncoder* encoder; | 237 std::unique_ptr<VideoEncoder> encoder; |
236 if (!stored_encoders_.empty()) { | 238 if (!stored_encoders_.empty()) { |
237 encoder = stored_encoders_.top(); | 239 encoder = std::move(stored_encoders_.top()); |
238 stored_encoders_.pop(); | 240 stored_encoders_.pop(); |
239 } else { | 241 } else { |
240 encoder = factory_->CreateVideoEncoder(cricket::VideoCodec("VP8")); | 242 encoder = CreateScopedVideoEncoder(factory_, cricket::VideoCodec("VP8")); |
241 } | 243 } |
242 | 244 |
243 ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size); | 245 ret = encoder->InitEncode(&stream_codec, number_of_cores, max_payload_size); |
244 if (ret < 0) { | 246 if (ret < 0) { |
245 // Explicitly destroy the current encoder; because we haven't registered a | 247 // Explicitly destroy the current encoder; because we haven't registered a |
246 // StreamInfo for it yet, Release won't do anything about it. | 248 // StreamInfo for it yet, Release won't do anything about it. |
247 factory_->DestroyVideoEncoder(encoder); | 249 encoder.reset(); |
248 Release(); | 250 Release(); |
249 return ret; | 251 return ret; |
250 } | 252 } |
251 std::unique_ptr<EncodedImageCallback> callback( | 253 std::unique_ptr<EncodedImageCallback> callback( |
252 new AdapterEncodedImageCallback(this, i)); | 254 new AdapterEncodedImageCallback(this, i)); |
253 encoder->RegisterEncodeCompleteCallback(callback.get()); | 255 encoder->RegisterEncodeCompleteCallback(callback.get()); |
254 streaminfos_.emplace_back(encoder, std::move(callback), stream_codec.width, | 256 streaminfos_.emplace_back(std::move(encoder), std::move(callback), |
255 stream_codec.height, start_bitrate_kbps > 0); | 257 stream_codec.width, stream_codec.height, |
| 258 start_bitrate_kbps > 0); |
256 | 259 |
257 if (i != 0) { | 260 if (i != 0) { |
258 implementation_name += ", "; | 261 implementation_name += ", "; |
259 } | 262 } |
260 implementation_name += streaminfos_[i].encoder->ImplementationName(); | 263 implementation_name += streaminfos_[i].encoder->ImplementationName(); |
261 } | 264 } |
262 | 265 |
263 if (doing_simulcast) { | 266 if (doing_simulcast) { |
264 implementation_name_ = | 267 implementation_name_ = |
265 "SimulcastEncoderAdapter (" + implementation_name + ")"; | 268 "SimulcastEncoderAdapter (" + implementation_name + ")"; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 | 496 |
494 stream_codec->startBitrate = start_bitrate_kbps; | 497 stream_codec->startBitrate = start_bitrate_kbps; |
495 } | 498 } |
496 | 499 |
497 bool SimulcastEncoderAdapter::Initialized() const { | 500 bool SimulcastEncoderAdapter::Initialized() const { |
498 return rtc::AtomicOps::AcquireLoad(&inited_) == 1; | 501 return rtc::AtomicOps::AcquireLoad(&inited_) == 1; |
499 } | 502 } |
500 | 503 |
501 void SimulcastEncoderAdapter::DestroyStoredEncoders() { | 504 void SimulcastEncoderAdapter::DestroyStoredEncoders() { |
502 while (!stored_encoders_.empty()) { | 505 while (!stored_encoders_.empty()) { |
503 VideoEncoder* encoder = stored_encoders_.top(); | |
504 factory_->DestroyVideoEncoder(encoder); | |
505 stored_encoders_.pop(); | 506 stored_encoders_.pop(); |
506 } | 507 } |
507 } | 508 } |
508 | 509 |
509 bool SimulcastEncoderAdapter::SupportsNativeHandle() const { | 510 bool SimulcastEncoderAdapter::SupportsNativeHandle() const { |
510 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_); | 511 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_); |
511 // We should not be calling this method before streaminfos_ are configured. | 512 // We should not be calling this method before streaminfos_ are configured. |
512 RTC_DCHECK(!streaminfos_.empty()); | 513 RTC_DCHECK(!streaminfos_.empty()); |
513 for (const auto& streaminfo : streaminfos_) { | 514 for (const auto& streaminfo : streaminfos_) { |
514 if (!streaminfo.encoder->SupportsNativeHandle()) { | 515 if (!streaminfo.encoder->SupportsNativeHandle()) { |
(...skipping 13 matching lines...) Expand all Loading... |
528 } | 529 } |
529 return streaminfos_[0].encoder->GetScalingSettings(); | 530 return streaminfos_[0].encoder->GetScalingSettings(); |
530 } | 531 } |
531 | 532 |
532 const char* SimulcastEncoderAdapter::ImplementationName() const { | 533 const char* SimulcastEncoderAdapter::ImplementationName() const { |
533 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_); | 534 RTC_DCHECK_CALLED_SEQUENTIALLY(&encoder_queue_); |
534 return implementation_name_.c_str(); | 535 return implementation_name_.c_str(); |
535 } | 536 } |
536 | 537 |
537 } // namespace webrtc | 538 } // namespace webrtc |
OLD | NEW |