Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: webrtc/modules/video_coding/codecs/test/videoprocessor.cc

Issue 2510583002: Reland #2 of Issue 2434073003: Extract bitrate allocation ... (Closed)
Patch Set: Addressed comments Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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::CreateBitrateAllocator(
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698