OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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/test/fake_encoder.h" | 11 #include "webrtc/test/fake_encoder.h" |
12 | 12 |
13 #include <string.h> | 13 #include <string.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 #include <memory> | 16 #include <memory> |
17 | 17 |
18 #include "webrtc/base/atomicops.h" | |
19 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
20 #include "webrtc/common_types.h" | 19 #include "webrtc/common_types.h" |
21 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 20 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
22 #include "webrtc/system_wrappers/include/sleep.h" | 21 #include "webrtc/system_wrappers/include/sleep.h" |
23 #include "webrtc/test/gtest.h" | 22 #include "webrtc/test/gtest.h" |
24 | 23 |
25 namespace webrtc { | 24 namespace webrtc { |
26 namespace test { | 25 namespace test { |
27 | 26 |
28 FakeEncoder::FakeEncoder(Clock* clock) | 27 FakeEncoder::FakeEncoder(Clock* clock) |
29 : clock_(clock), | 28 : clock_(clock), |
30 callback_(nullptr), | 29 callback_(nullptr), |
31 max_target_bitrate_kbps_(-1), | 30 max_target_bitrate_kbps_(-1), |
32 last_encode_time_ms_(0) { | 31 last_encode_time_ms_(0) { |
33 // Generate some arbitrary not-all-zero data | 32 // Generate some arbitrary not-all-zero data |
34 for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) { | 33 for (size_t i = 0; i < sizeof(encoded_buffer_); ++i) { |
35 encoded_buffer_[i] = static_cast<uint8_t>(i); | 34 encoded_buffer_[i] = static_cast<uint8_t>(i); |
36 } | 35 } |
37 } | 36 } |
38 | 37 |
39 FakeEncoder::~FakeEncoder() {} | |
40 | |
41 void FakeEncoder::SetMaxBitrate(int max_kbps) { | 38 void FakeEncoder::SetMaxBitrate(int max_kbps) { |
42 RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it. | 39 RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it. |
43 rtc::CritScope cs(&crit_sect_); | 40 rtc::CritScope cs(&crit_sect_); |
44 max_target_bitrate_kbps_ = max_kbps; | 41 max_target_bitrate_kbps_ = max_kbps; |
45 } | 42 } |
46 | 43 |
47 int32_t FakeEncoder::InitEncode(const VideoCodec* config, | 44 int32_t FakeEncoder::InitEncode(const VideoCodec* config, |
48 int32_t number_of_cores, | 45 int32_t number_of_cores, |
49 size_t max_payload_size) { | 46 size_t max_payload_size) { |
50 rtc::CritScope cs(&crit_sect_); | 47 rtc::CritScope cs(&crit_sect_); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 CodecSpecificInfo specifics; | 244 CodecSpecificInfo specifics; |
248 memset(&specifics, 0, sizeof(specifics)); | 245 memset(&specifics, 0, sizeof(specifics)); |
249 specifics.codecType = kVideoCodecH264; | 246 specifics.codecType = kVideoCodecH264; |
250 specifics.codecSpecific.H264.packetization_mode = | 247 specifics.codecSpecific.H264.packetization_mode = |
251 H264PacketizationMode::NonInterleaved; | 248 H264PacketizationMode::NonInterleaved; |
252 RTC_DCHECK(callback); | 249 RTC_DCHECK(callback); |
253 return callback->OnEncodedImage(encoded_image, &specifics, &fragmentation); | 250 return callback->OnEncodedImage(encoded_image, &specifics, &fragmentation); |
254 } | 251 } |
255 | 252 |
256 DelayedEncoder::DelayedEncoder(Clock* clock, int delay_ms) | 253 DelayedEncoder::DelayedEncoder(Clock* clock, int delay_ms) |
257 : test::FakeEncoder(clock), | 254 : test::FakeEncoder(clock), delay_ms_(delay_ms) { |
258 delay_ms_(delay_ms) {} | 255 // The encoder could be created on a different thread than |
| 256 // it is being used on. |
| 257 sequence_checker_.Detach(); |
| 258 } |
259 | 259 |
260 void DelayedEncoder::SetDelay(int delay_ms) { | 260 void DelayedEncoder::SetDelay(int delay_ms) { |
261 rtc::CritScope cs(&local_crit_sect_); | 261 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
262 delay_ms_ = delay_ms; | 262 delay_ms_ = delay_ms; |
263 } | 263 } |
264 | 264 |
265 int32_t DelayedEncoder::Encode(const VideoFrame& input_image, | 265 int32_t DelayedEncoder::Encode(const VideoFrame& input_image, |
266 const CodecSpecificInfo* codec_specific_info, | 266 const CodecSpecificInfo* codec_specific_info, |
267 const std::vector<FrameType>* frame_types) { | 267 const std::vector<FrameType>* frame_types) { |
268 int delay_ms = 0; | 268 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
269 { | 269 |
270 rtc::CritScope cs(&local_crit_sect_); | 270 SleepMs(delay_ms_); |
271 delay_ms = delay_ms_; | 271 |
272 } | |
273 SleepMs(delay_ms); | |
274 return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); | 272 return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); |
275 } | 273 } |
276 | 274 |
277 MultithreadedFakeH264Encoder::MultithreadedFakeH264Encoder(Clock* clock) | 275 MultithreadedFakeH264Encoder::MultithreadedFakeH264Encoder(Clock* clock) |
278 : test::FakeH264Encoder(clock), | 276 : test::FakeH264Encoder(clock), |
279 current_queue_(0), | 277 current_queue_(0), |
280 queue1_("Queue 1"), | 278 queue1_(nullptr), |
281 queue2_("Queue 2") {} | 279 queue2_(nullptr) { |
| 280 // The encoder could be created on a different thread than |
| 281 // it is being used on. |
| 282 sequence_checker_.Detach(); |
| 283 } |
282 | 284 |
283 MultithreadedFakeH264Encoder::~MultithreadedFakeH264Encoder() = default; | 285 int32_t MultithreadedFakeH264Encoder::InitEncode(const VideoCodec* config, |
| 286 int32_t number_of_cores, |
| 287 size_t max_payload_size) { |
| 288 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 289 |
| 290 queue1_.reset(new rtc::TaskQueue("Queue 1")); |
| 291 queue2_.reset(new rtc::TaskQueue("Queue 2")); |
| 292 |
| 293 return FakeH264Encoder::InitEncode(config, number_of_cores, max_payload_size); |
| 294 } |
284 | 295 |
285 class MultithreadedFakeH264Encoder::EncodeTask : public rtc::QueuedTask { | 296 class MultithreadedFakeH264Encoder::EncodeTask : public rtc::QueuedTask { |
286 public: | 297 public: |
287 EncodeTask(MultithreadedFakeH264Encoder* encoder, | 298 EncodeTask(MultithreadedFakeH264Encoder* encoder, |
288 const VideoFrame& input_image, | 299 const VideoFrame& input_image, |
289 const CodecSpecificInfo* codec_specific_info, | 300 const CodecSpecificInfo* codec_specific_info, |
290 const std::vector<FrameType>* frame_types) | 301 const std::vector<FrameType>* frame_types) |
291 : encoder_(encoder), | 302 : encoder_(encoder), |
292 input_image_(input_image), | 303 input_image_(input_image), |
293 codec_specific_info_(), | 304 codec_specific_info_(), |
(...skipping 12 matching lines...) Expand all Loading... |
306 MultithreadedFakeH264Encoder* const encoder_; | 317 MultithreadedFakeH264Encoder* const encoder_; |
307 VideoFrame input_image_; | 318 VideoFrame input_image_; |
308 CodecSpecificInfo codec_specific_info_; | 319 CodecSpecificInfo codec_specific_info_; |
309 std::vector<FrameType> frame_types_; | 320 std::vector<FrameType> frame_types_; |
310 }; | 321 }; |
311 | 322 |
312 int32_t MultithreadedFakeH264Encoder::Encode( | 323 int32_t MultithreadedFakeH264Encoder::Encode( |
313 const VideoFrame& input_image, | 324 const VideoFrame& input_image, |
314 const CodecSpecificInfo* codec_specific_info, | 325 const CodecSpecificInfo* codec_specific_info, |
315 const std::vector<FrameType>* frame_types) { | 326 const std::vector<FrameType>* frame_types) { |
316 int current_queue = rtc::AtomicOps::Increment(¤t_queue_); | 327 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
317 rtc::TaskQueue& queue = (current_queue % 2 == 0) ? queue1_ : queue2_; | |
318 | 328 |
319 queue.PostTask(std::unique_ptr<rtc::QueuedTask>( | 329 std::unique_ptr<rtc::TaskQueue>& queue = |
| 330 (current_queue_++ % 2 == 0) ? queue1_ : queue2_; |
| 331 |
| 332 if (!queue) { |
| 333 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 334 } |
| 335 |
| 336 queue->PostTask(std::unique_ptr<rtc::QueuedTask>( |
320 new EncodeTask(this, input_image, codec_specific_info, frame_types))); | 337 new EncodeTask(this, input_image, codec_specific_info, frame_types))); |
321 | 338 |
322 return 0; | 339 return WEBRTC_VIDEO_CODEC_OK; |
323 } | 340 } |
324 | 341 |
325 int32_t MultithreadedFakeH264Encoder::EncodeCallback( | 342 int32_t MultithreadedFakeH264Encoder::EncodeCallback( |
326 const VideoFrame& input_image, | 343 const VideoFrame& input_image, |
327 const CodecSpecificInfo* codec_specific_info, | 344 const CodecSpecificInfo* codec_specific_info, |
328 const std::vector<FrameType>* frame_types) { | 345 const std::vector<FrameType>* frame_types) { |
329 return FakeH264Encoder::Encode(input_image, codec_specific_info, frame_types); | 346 return FakeH264Encoder::Encode(input_image, codec_specific_info, frame_types); |
330 } | 347 } |
331 | 348 |
| 349 int32_t MultithreadedFakeH264Encoder::Release() { |
| 350 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); |
| 351 |
| 352 queue1_.reset(); |
| 353 queue2_.reset(); |
| 354 |
| 355 return FakeH264Encoder::Release(); |
| 356 } |
| 357 |
332 } // namespace test | 358 } // namespace test |
333 } // namespace webrtc | 359 } // namespace webrtc |
OLD | NEW |