 Chromium Code Reviews
 Chromium Code Reviews Issue 2686103002:
  Do not encode frames in MultithreadedFakeH264Encoder after Release().  (Closed)
    
  
    Issue 2686103002:
  Do not encode frames in MultithreadedFakeH264Encoder after Release().  (Closed) 
  | 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 it being used on. | 
| 256 sequence_checker_.Detach(); | |
| 257 } | |
| 259 | 258 | 
| 260 void DelayedEncoder::SetDelay(int delay_ms) { | 259 void DelayedEncoder::SetDelay(int delay_ms) { | 
| 261 rtc::CritScope cs(&local_crit_sect_); | 260 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 
| 262 delay_ms_ = delay_ms; | 261 delay_ms_ = delay_ms; | 
| 263 } | 262 } | 
| 264 | 263 | 
| 265 int32_t DelayedEncoder::Encode(const VideoFrame& input_image, | 264 int32_t DelayedEncoder::Encode(const VideoFrame& input_image, | 
| 266 const CodecSpecificInfo* codec_specific_info, | 265 const CodecSpecificInfo* codec_specific_info, | 
| 267 const std::vector<FrameType>* frame_types) { | 266 const std::vector<FrameType>* frame_types) { | 
| 268 int delay_ms = 0; | 267 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 
| 269 { | 268 | 
| 270 rtc::CritScope cs(&local_crit_sect_); | 269 SleepMs(delay_ms_); | 
| 271 delay_ms = delay_ms_; | 270 | 
| 272 } | |
| 273 SleepMs(delay_ms); | |
| 274 return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); | 271 return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); | 
| 275 } | 272 } | 
| 276 | 273 | 
| 277 MultithreadedFakeH264Encoder::MultithreadedFakeH264Encoder(Clock* clock) | 274 MultithreadedFakeH264Encoder::MultithreadedFakeH264Encoder(Clock* clock) | 
| 278 : test::FakeH264Encoder(clock), | 275 : test::FakeH264Encoder(clock), | 
| 279 current_queue_(0), | 276 current_queue_(0), | 
| 280 queue1_("Queue 1"), | 277 queue1_(nullptr), | 
| 281 queue2_("Queue 2") {} | 278 queue2_(nullptr) { | 
| 279 // The encoder could be created on a different thread than it being used on. | |
| 
sprang_webrtc
2017/02/10 09:54:47
nit: ...than it is being used on.
 
brandtr
2017/02/10 10:00:10
Done. I was to eager to fit this on one line :(
 | |
| 280 sequence_checker_.Detach(); | |
| 281 } | |
| 282 | 282 | 
| 283 MultithreadedFakeH264Encoder::~MultithreadedFakeH264Encoder() = default; | 283 int32_t MultithreadedFakeH264Encoder::InitEncode(const VideoCodec* config, | 
| 284 int32_t number_of_cores, | |
| 285 size_t max_payload_size) { | |
| 286 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | |
| 287 | |
| 288 queue1_.reset(new rtc::TaskQueue("Queue 1")); | |
| 289 queue2_.reset(new rtc::TaskQueue("Queue 2")); | |
| 290 | |
| 291 return FakeH264Encoder::InitEncode(config, number_of_cores, max_payload_size); | |
| 292 } | |
| 284 | 293 | 
| 285 class MultithreadedFakeH264Encoder::EncodeTask : public rtc::QueuedTask { | 294 class MultithreadedFakeH264Encoder::EncodeTask : public rtc::QueuedTask { | 
| 286 public: | 295 public: | 
| 287 EncodeTask(MultithreadedFakeH264Encoder* encoder, | 296 EncodeTask(MultithreadedFakeH264Encoder* encoder, | 
| 288 const VideoFrame& input_image, | 297 const VideoFrame& input_image, | 
| 289 const CodecSpecificInfo* codec_specific_info, | 298 const CodecSpecificInfo* codec_specific_info, | 
| 290 const std::vector<FrameType>* frame_types) | 299 const std::vector<FrameType>* frame_types) | 
| 291 : encoder_(encoder), | 300 : encoder_(encoder), | 
| 292 input_image_(input_image), | 301 input_image_(input_image), | 
| 293 codec_specific_info_(), | 302 codec_specific_info_(), | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 306 MultithreadedFakeH264Encoder* const encoder_; | 315 MultithreadedFakeH264Encoder* const encoder_; | 
| 307 VideoFrame input_image_; | 316 VideoFrame input_image_; | 
| 308 CodecSpecificInfo codec_specific_info_; | 317 CodecSpecificInfo codec_specific_info_; | 
| 309 std::vector<FrameType> frame_types_; | 318 std::vector<FrameType> frame_types_; | 
| 310 }; | 319 }; | 
| 311 | 320 | 
| 312 int32_t MultithreadedFakeH264Encoder::Encode( | 321 int32_t MultithreadedFakeH264Encoder::Encode( | 
| 313 const VideoFrame& input_image, | 322 const VideoFrame& input_image, | 
| 314 const CodecSpecificInfo* codec_specific_info, | 323 const CodecSpecificInfo* codec_specific_info, | 
| 315 const std::vector<FrameType>* frame_types) { | 324 const std::vector<FrameType>* frame_types) { | 
| 316 int current_queue = rtc::AtomicOps::Increment(¤t_queue_); | 325 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | 
| 317 rtc::TaskQueue& queue = (current_queue % 2 == 0) ? queue1_ : queue2_; | |
| 318 | 326 | 
| 319 queue.PostTask(std::unique_ptr<rtc::QueuedTask>( | 327 std::unique_ptr<rtc::TaskQueue>& queue = | 
| 328 (current_queue_++ % 2 == 0) ? queue1_ : queue2_; | |
| 329 | |
| 330 if (!queue) { | |
| 331 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | |
| 332 } | |
| 333 | |
| 334 queue->PostTask(std::unique_ptr<rtc::QueuedTask>( | |
| 320 new EncodeTask(this, input_image, codec_specific_info, frame_types))); | 335 new EncodeTask(this, input_image, codec_specific_info, frame_types))); | 
| 321 | 336 | 
| 322 return 0; | 337 return WEBRTC_VIDEO_CODEC_OK; | 
| 323 } | 338 } | 
| 324 | 339 | 
| 325 int32_t MultithreadedFakeH264Encoder::EncodeCallback( | 340 int32_t MultithreadedFakeH264Encoder::EncodeCallback( | 
| 326 const VideoFrame& input_image, | 341 const VideoFrame& input_image, | 
| 327 const CodecSpecificInfo* codec_specific_info, | 342 const CodecSpecificInfo* codec_specific_info, | 
| 328 const std::vector<FrameType>* frame_types) { | 343 const std::vector<FrameType>* frame_types) { | 
| 329 return FakeH264Encoder::Encode(input_image, codec_specific_info, frame_types); | 344 return FakeH264Encoder::Encode(input_image, codec_specific_info, frame_types); | 
| 330 } | 345 } | 
| 331 | 346 | 
| 347 int32_t MultithreadedFakeH264Encoder::Release() { | |
| 348 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_); | |
| 349 | |
| 350 queue1_.reset(); | |
| 351 queue2_.reset(); | |
| 352 | |
| 353 return FakeH264Encoder::Release(); | |
| 354 } | |
| 355 | |
| 332 } // namespace test | 356 } // namespace test | 
| 333 } // namespace webrtc | 357 } // namespace webrtc | 
| OLD | NEW |