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/test/videoprocessor.h" | 11 #include "webrtc/modules/video_coding/codecs/test/videoprocessor.h" |
12 | 12 |
13 #include <assert.h> | |
14 #include <string.h> | 13 #include <string.h> |
15 | 14 |
16 #include <limits> | 15 #include <limits> |
17 #include <memory> | 16 #include <memory> |
| 17 #include <utility> |
18 #include <vector> | 18 #include <vector> |
19 | 19 |
| 20 #include "webrtc/base/checks.h" |
20 #include "webrtc/base/timeutils.h" | 21 #include "webrtc/base/timeutils.h" |
| 22 #include "webrtc/modules/video_coding/include/video_codec_initializer.h" |
| 23 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h" |
| 24 #include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h" |
21 #include "webrtc/system_wrappers/include/cpu_info.h" | 25 #include "webrtc/system_wrappers/include/cpu_info.h" |
22 | 26 |
23 namespace webrtc { | 27 namespace webrtc { |
24 namespace test { | 28 namespace test { |
25 | 29 |
26 TestConfig::TestConfig() | 30 TestConfig::TestConfig() |
27 : name(""), | 31 : name(""), |
28 description(""), | 32 description(""), |
29 test_number(0), | 33 test_number(0), |
30 input_filename(""), | 34 input_filename(""), |
31 output_filename(""), | 35 output_filename(""), |
32 output_dir("out"), | 36 output_dir("out"), |
33 networking_config(), | 37 networking_config(), |
34 exclude_frame_types(kExcludeOnlyFirstKeyFrame), | 38 exclude_frame_types(kExcludeOnlyFirstKeyFrame), |
35 frame_length_in_bytes(0), | 39 frame_length_in_bytes(0), |
36 use_single_core(false), | 40 use_single_core(false), |
37 keyframe_interval(0), | 41 keyframe_interval(0), |
38 codec_settings(NULL), | 42 codec_settings(nullptr), |
39 verbose(true) {} | 43 verbose(true) {} |
40 | 44 |
41 TestConfig::~TestConfig() {} | 45 TestConfig::~TestConfig() {} |
42 | 46 |
43 VideoProcessorImpl::VideoProcessorImpl(webrtc::VideoEncoder* encoder, | 47 VideoProcessorImpl::VideoProcessorImpl(webrtc::VideoEncoder* encoder, |
44 webrtc::VideoDecoder* decoder, | 48 webrtc::VideoDecoder* decoder, |
45 FrameReader* frame_reader, | 49 FrameReader* frame_reader, |
46 FrameWriter* frame_writer, | 50 FrameWriter* frame_writer, |
47 PacketManipulator* packet_manipulator, | 51 PacketManipulator* packet_manipulator, |
48 const TestConfig& config, | 52 const TestConfig& config, |
49 Stats* stats) | 53 Stats* stats) |
50 : encoder_(encoder), | 54 : encoder_(encoder), |
51 decoder_(decoder), | 55 decoder_(decoder), |
52 frame_reader_(frame_reader), | 56 frame_reader_(frame_reader), |
53 frame_writer_(frame_writer), | 57 frame_writer_(frame_writer), |
54 packet_manipulator_(packet_manipulator), | 58 packet_manipulator_(packet_manipulator), |
55 config_(config), | 59 config_(config), |
56 stats_(stats), | 60 stats_(stats), |
57 encode_callback_(NULL), | 61 encode_callback_(nullptr), |
58 decode_callback_(NULL), | 62 decode_callback_(nullptr), |
| 63 last_successful_frame_buffer_(nullptr), |
59 first_key_frame_has_been_excluded_(false), | 64 first_key_frame_has_been_excluded_(false), |
60 last_frame_missing_(false), | 65 last_frame_missing_(false), |
61 initialized_(false), | 66 initialized_(false), |
62 encoded_frame_size_(0), | 67 encoded_frame_size_(0), |
63 encoded_frame_type_(kVideoFrameKey), | 68 encoded_frame_type_(kVideoFrameKey), |
64 prev_time_stamp_(0), | 69 prev_time_stamp_(0), |
65 num_dropped_frames_(0), | 70 num_dropped_frames_(0), |
66 num_spatial_resizes_(0), | 71 num_spatial_resizes_(0), |
67 last_encoder_frame_width_(0), | 72 last_encoder_frame_width_(0), |
68 last_encoder_frame_height_(0) { | 73 last_encoder_frame_height_(0), |
69 assert(encoder); | 74 bit_rate_factor_(0.0), |
70 assert(decoder); | 75 encode_start_ns_(0), |
71 assert(frame_reader); | 76 decode_start_ns_(0) { |
72 assert(frame_writer); | 77 std::unique_ptr<TemporalLayersFactory> tl_factory; |
73 assert(packet_manipulator); | 78 if (config_.codec_settings->codecType == VideoCodecType::kVideoCodecVP8) { |
74 assert(stats); | 79 tl_factory.reset(new TemporalLayersFactory()); |
| 80 config.codec_settings->VP8()->tl_factory = tl_factory.get(); |
| 81 } |
| 82 bitrate_allocator_ = VideoCodecInitializer::GetBitrateAllocator( |
| 83 *config.codec_settings, std::move(tl_factory)); |
| 84 RTC_DCHECK(encoder); |
| 85 RTC_DCHECK(decoder); |
| 86 RTC_DCHECK(frame_reader); |
| 87 RTC_DCHECK(frame_writer); |
| 88 RTC_DCHECK(packet_manipulator); |
| 89 RTC_DCHECK(stats); |
75 } | 90 } |
76 | 91 |
77 bool VideoProcessorImpl::Init() { | 92 bool VideoProcessorImpl::Init() { |
78 // Calculate a factor used for bit rate calculations: | 93 // Calculate a factor used for bit rate calculations: |
79 bit_rate_factor_ = config_.codec_settings->maxFramerate * 0.001 * 8; // bits | 94 bit_rate_factor_ = config_.codec_settings->maxFramerate * 0.001 * 8; // bits |
80 | 95 |
81 // Initialize data structures used by the encoder/decoder APIs | 96 // Initialize data structures used by the encoder/decoder APIs |
82 size_t frame_length_in_bytes = frame_reader_->FrameLength(); | 97 size_t frame_length_in_bytes = frame_reader_->FrameLength(); |
83 last_successful_frame_buffer_ = new uint8_t[frame_length_in_bytes]; | 98 last_successful_frame_buffer_ = new uint8_t[frame_length_in_bytes]; |
84 // Set fixed properties common for all frames. | 99 // Set fixed properties common for all frames. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 | 157 |
143 VideoProcessorImpl::~VideoProcessorImpl() { | 158 VideoProcessorImpl::~VideoProcessorImpl() { |
144 delete[] last_successful_frame_buffer_; | 159 delete[] last_successful_frame_buffer_; |
145 encoder_->RegisterEncodeCompleteCallback(NULL); | 160 encoder_->RegisterEncodeCompleteCallback(NULL); |
146 delete encode_callback_; | 161 delete encode_callback_; |
147 decoder_->RegisterDecodeCompleteCallback(NULL); | 162 decoder_->RegisterDecodeCompleteCallback(NULL); |
148 delete decode_callback_; | 163 delete decode_callback_; |
149 } | 164 } |
150 | 165 |
151 void VideoProcessorImpl::SetRates(int bit_rate, int frame_rate) { | 166 void VideoProcessorImpl::SetRates(int bit_rate, int frame_rate) { |
152 int set_rates_result = encoder_->SetRates(bit_rate, frame_rate); | 167 int set_rates_result = encoder_->SetRateAllocation( |
153 assert(set_rates_result >= 0); | 168 bitrate_allocator_->GetAllocation(bit_rate * 1000, frame_rate), |
| 169 frame_rate); |
| 170 RTC_CHECK_GE(set_rates_result, 0); |
154 if (set_rates_result < 0) { | 171 if (set_rates_result < 0) { |
155 fprintf(stderr, | 172 fprintf(stderr, |
156 "Failed to update encoder with new rate %d, " | 173 "Failed to update encoder with new rate %d, " |
157 "return code: %d\n", | 174 "return code: %d\n", |
158 bit_rate, set_rates_result); | 175 bit_rate, set_rates_result); |
159 } | 176 } |
160 num_dropped_frames_ = 0; | 177 num_dropped_frames_ = 0; |
161 num_spatial_resizes_ = 0; | 178 num_spatial_resizes_ = 0; |
162 } | 179 } |
163 | 180 |
164 size_t VideoProcessorImpl::EncodedFrameSize() { | 181 size_t VideoProcessorImpl::EncodedFrameSize() { |
165 return encoded_frame_size_; | 182 return encoded_frame_size_; |
166 } | 183 } |
167 | 184 |
168 FrameType VideoProcessorImpl::EncodedFrameType() { | 185 FrameType VideoProcessorImpl::EncodedFrameType() { |
169 return encoded_frame_type_; | 186 return encoded_frame_type_; |
170 } | 187 } |
171 | 188 |
172 int VideoProcessorImpl::NumberDroppedFrames() { | 189 int VideoProcessorImpl::NumberDroppedFrames() { |
173 return num_dropped_frames_; | 190 return num_dropped_frames_; |
174 } | 191 } |
175 | 192 |
176 int VideoProcessorImpl::NumberSpatialResizes() { | 193 int VideoProcessorImpl::NumberSpatialResizes() { |
177 return num_spatial_resizes_; | 194 return num_spatial_resizes_; |
178 } | 195 } |
179 | 196 |
180 bool VideoProcessorImpl::ProcessFrame(int frame_number) { | 197 bool VideoProcessorImpl::ProcessFrame(int frame_number) { |
181 assert(frame_number >= 0); | 198 RTC_DCHECK_GE(frame_number, 0); |
182 if (!initialized_) { | 199 if (!initialized_) { |
183 fprintf(stderr, "Attempting to use uninitialized VideoProcessor!\n"); | 200 fprintf(stderr, "Attempting to use uninitialized VideoProcessor!\n"); |
184 return false; | 201 return false; |
185 } | 202 } |
186 // |prev_time_stamp_| is used for getting number of dropped frames. | 203 // |prev_time_stamp_| is used for getting number of dropped frames. |
187 if (frame_number == 0) { | 204 if (frame_number == 0) { |
188 prev_time_stamp_ = -1; | 205 prev_time_stamp_ = -1; |
189 } | 206 } |
190 rtc::scoped_refptr<VideoFrameBuffer> buffer(frame_reader_->ReadFrame()); | 207 rtc::scoped_refptr<VideoFrameBuffer> buffer(frame_reader_->ReadFrame()); |
191 if (buffer) { | 208 if (buffer) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 case kExcludeOnlyFirstKeyFrame: | 282 case kExcludeOnlyFirstKeyFrame: |
266 if (!first_key_frame_has_been_excluded_) { | 283 if (!first_key_frame_has_been_excluded_) { |
267 first_key_frame_has_been_excluded_ = true; | 284 first_key_frame_has_been_excluded_ = true; |
268 exclude_this_frame = true; | 285 exclude_this_frame = true; |
269 } | 286 } |
270 break; | 287 break; |
271 case kExcludeAllKeyFrames: | 288 case kExcludeAllKeyFrames: |
272 exclude_this_frame = true; | 289 exclude_this_frame = true; |
273 break; | 290 break; |
274 default: | 291 default: |
275 assert(false); | 292 RTC_NOTREACHED(); |
276 } | 293 } |
277 } | 294 } |
278 | 295 |
279 // Make a raw copy of the |encoded_image| buffer. | 296 // Make a raw copy of the |encoded_image| buffer. |
280 size_t copied_buffer_size = encoded_image._length + | 297 size_t copied_buffer_size = encoded_image._length + |
281 EncodedImage::GetBufferPaddingBytes(codec); | 298 EncodedImage::GetBufferPaddingBytes(codec); |
282 std::unique_ptr<uint8_t[]> copied_buffer(new uint8_t[copied_buffer_size]); | 299 std::unique_ptr<uint8_t[]> copied_buffer(new uint8_t[copied_buffer_size]); |
283 memcpy(copied_buffer.get(), encoded_image._buffer, encoded_image._length); | 300 memcpy(copied_buffer.get(), encoded_image._buffer, encoded_image._length); |
284 // The image to feed to the decoder. | 301 // The image to feed to the decoder. |
285 EncodedImage copied_image; | 302 EncodedImage copied_image; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 config_.codec_settings->height)); | 351 config_.codec_settings->height)); |
335 | 352 |
336 // Should be the same aspect ratio, no cropping needed. | 353 // Should be the same aspect ratio, no cropping needed. |
337 up_image->ScaleFrom(image.video_frame_buffer()); | 354 up_image->ScaleFrom(image.video_frame_buffer()); |
338 | 355 |
339 // TODO(mikhal): Extracting the buffer for now - need to update test. | 356 // TODO(mikhal): Extracting the buffer for now - need to update test. |
340 size_t length = | 357 size_t length = |
341 CalcBufferSize(kI420, up_image->width(), up_image->height()); | 358 CalcBufferSize(kI420, up_image->width(), up_image->height()); |
342 std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[length]); | 359 std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[length]); |
343 int extracted_length = ExtractBuffer(up_image, length, image_buffer.get()); | 360 int extracted_length = ExtractBuffer(up_image, length, image_buffer.get()); |
344 assert(extracted_length > 0); | 361 RTC_DCHECK_GT(extracted_length, 0); |
345 // Update our copy of the last successful frame: | 362 // Update our copy of the last successful frame: |
346 memcpy(last_successful_frame_buffer_, image_buffer.get(), extracted_length); | 363 memcpy(last_successful_frame_buffer_, image_buffer.get(), extracted_length); |
347 bool write_success = frame_writer_->WriteFrame(image_buffer.get()); | 364 bool write_success = frame_writer_->WriteFrame(image_buffer.get()); |
348 assert(write_success); | 365 RTC_DCHECK(write_success); |
349 if (!write_success) { | 366 if (!write_success) { |
350 fprintf(stderr, "Failed to write frame %d to disk!", frame_number); | 367 fprintf(stderr, "Failed to write frame %d to disk!", frame_number); |
351 } | 368 } |
352 } else { // No resize. | 369 } else { // No resize. |
353 // Update our copy of the last successful frame: | 370 // Update our copy of the last successful frame: |
354 // TODO(mikhal): Add as a member function, so won't be allocated per frame. | 371 // TODO(mikhal): Add as a member function, so won't be allocated per frame. |
355 size_t length = CalcBufferSize(kI420, image.width(), image.height()); | 372 size_t length = CalcBufferSize(kI420, image.width(), image.height()); |
356 std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[length]); | 373 std::unique_ptr<uint8_t[]> image_buffer(new uint8_t[length]); |
357 int extracted_length = ExtractBuffer(image, length, image_buffer.get()); | 374 int extracted_length = ExtractBuffer(image, length, image_buffer.get()); |
358 assert(extracted_length > 0); | 375 RTC_DCHECK_GT(extracted_length, 0); |
359 memcpy(last_successful_frame_buffer_, image_buffer.get(), extracted_length); | 376 memcpy(last_successful_frame_buffer_, image_buffer.get(), extracted_length); |
360 | 377 |
361 bool write_success = frame_writer_->WriteFrame(image_buffer.get()); | 378 bool write_success = frame_writer_->WriteFrame(image_buffer.get()); |
362 assert(write_success); | 379 RTC_DCHECK(write_success); |
363 if (!write_success) { | 380 if (!write_success) { |
364 fprintf(stderr, "Failed to write frame %d to disk!", frame_number); | 381 fprintf(stderr, "Failed to write frame %d to disk!", frame_number); |
365 } | 382 } |
366 } | 383 } |
367 } | 384 } |
368 | 385 |
369 int VideoProcessorImpl::GetElapsedTimeMicroseconds(int64_t start, | 386 int VideoProcessorImpl::GetElapsedTimeMicroseconds(int64_t start, |
370 int64_t stop) { | 387 int64_t stop) { |
371 uint64_t encode_time = (stop - start) / rtc::kNumNanosecsPerMicrosec; | 388 uint64_t encode_time = (stop - start) / rtc::kNumNanosecsPerMicrosec; |
372 assert(encode_time < | 389 RTC_DCHECK_LT(encode_time, |
373 static_cast<unsigned int>(std::numeric_limits<int>::max())); | 390 static_cast<unsigned int>(std::numeric_limits<int>::max())); |
374 return static_cast<int>(encode_time); | 391 return static_cast<int>(encode_time); |
375 } | 392 } |
376 | 393 |
377 const char* ExcludeFrameTypesToStr(ExcludeFrameTypes e) { | 394 const char* ExcludeFrameTypesToStr(ExcludeFrameTypes e) { |
378 switch (e) { | 395 switch (e) { |
379 case kExcludeOnlyFirstKeyFrame: | 396 case kExcludeOnlyFirstKeyFrame: |
380 return "ExcludeOnlyFirstKeyFrame"; | 397 return "ExcludeOnlyFirstKeyFrame"; |
381 case kExcludeAllKeyFrames: | 398 case kExcludeAllKeyFrames: |
382 return "ExcludeAllKeyFrames"; | 399 return "ExcludeAllKeyFrames"; |
383 default: | 400 default: |
384 assert(false); | 401 RTC_NOTREACHED(); |
385 return "Unknown"; | 402 return "Unknown"; |
386 } | 403 } |
387 } | 404 } |
388 | 405 |
389 const char* VideoCodecTypeToStr(webrtc::VideoCodecType e) { | 406 const char* VideoCodecTypeToStr(webrtc::VideoCodecType e) { |
390 switch (e) { | 407 switch (e) { |
391 case kVideoCodecVP8: | 408 case kVideoCodecVP8: |
392 return "VP8"; | 409 return "VP8"; |
393 case kVideoCodecI420: | 410 case kVideoCodecI420: |
394 return "I420"; | 411 return "I420"; |
395 case kVideoCodecRED: | 412 case kVideoCodecRED: |
396 return "RED"; | 413 return "RED"; |
397 case kVideoCodecULPFEC: | 414 case kVideoCodecULPFEC: |
398 return "ULPFEC"; | 415 return "ULPFEC"; |
399 case kVideoCodecUnknown: | 416 case kVideoCodecUnknown: |
400 return "Unknown"; | 417 return "Unknown"; |
401 default: | 418 default: |
402 assert(false); | 419 RTC_NOTREACHED(); |
403 return "Unknown"; | 420 return "Unknown"; |
404 } | 421 } |
405 } | 422 } |
406 | 423 |
407 // Callbacks | 424 // Callbacks |
408 EncodedImageCallback::Result | 425 EncodedImageCallback::Result |
409 VideoProcessorImpl::VideoProcessorEncodeCompleteCallback::OnEncodedImage( | 426 VideoProcessorImpl::VideoProcessorEncodeCompleteCallback::OnEncodedImage( |
410 const EncodedImage& encoded_image, | 427 const EncodedImage& encoded_image, |
411 const webrtc::CodecSpecificInfo* codec_specific_info, | 428 const webrtc::CodecSpecificInfo* codec_specific_info, |
412 const webrtc::RTPFragmentationHeader* fragmentation) { | 429 const webrtc::RTPFragmentationHeader* fragmentation) { |
413 // Forward to parent class. | 430 // Forward to parent class. |
414 RTC_CHECK(codec_specific_info); | 431 RTC_CHECK(codec_specific_info); |
415 video_processor_->FrameEncoded(codec_specific_info->codecType, | 432 video_processor_->FrameEncoded(codec_specific_info->codecType, |
416 encoded_image, | 433 encoded_image, |
417 fragmentation); | 434 fragmentation); |
418 return Result(Result::OK, 0); | 435 return Result(Result::OK, 0); |
419 } | 436 } |
420 int32_t VideoProcessorImpl::VideoProcessorDecodeCompleteCallback::Decoded( | 437 int32_t VideoProcessorImpl::VideoProcessorDecodeCompleteCallback::Decoded( |
421 VideoFrame& image) { | 438 VideoFrame& image) { |
422 // Forward to parent class. | 439 // Forward to parent class. |
423 video_processor_->FrameDecoded(image); | 440 video_processor_->FrameDecoded(image); |
424 return 0; | 441 return 0; |
425 } | 442 } |
426 | 443 |
427 } // namespace test | 444 } // namespace test |
428 } // namespace webrtc | 445 } // namespace webrtc |
OLD | NEW |