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

Side by Side Diff: content/common/gpu/media/video_encode_accelerator_unittest.cc

Issue 290643003: veatest: Fixes for bitrate tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 6 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/at_exit.h" 5 #include "base/at_exit.h"
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/files/memory_mapped_file.h" 9 #include "base/files/memory_mapped_file.h"
10 #include "base/memory/scoped_vector.h" 10 #include "base/memory/scoped_vector.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 const double kDefaultSubsequentBitrateRatio = 2.0; 45 const double kDefaultSubsequentBitrateRatio = 2.0;
46 // Default initial framerate. 46 // Default initial framerate.
47 const uint32 kDefaultFramerate = 30; 47 const uint32 kDefaultFramerate = 30;
48 // Default ratio of requested_subsequent_framerate to initial_framerate 48 // Default ratio of requested_subsequent_framerate to initial_framerate
49 // (see test parameters below) if one is not provided. 49 // (see test parameters below) if one is not provided.
50 const double kDefaultSubsequentFramerateRatio = 0.1; 50 const double kDefaultSubsequentFramerateRatio = 0.1;
51 // Tolerance factor for how encoded bitrate can differ from requested bitrate. 51 // Tolerance factor for how encoded bitrate can differ from requested bitrate.
52 const double kBitrateTolerance = 0.1; 52 const double kBitrateTolerance = 0.1;
53 // Minimum required FPS throughput for the basic performance test. 53 // Minimum required FPS throughput for the basic performance test.
54 const uint32 kMinPerfFPS = 30; 54 const uint32 kMinPerfFPS = 30;
55 // Minimum (arbitrary) number of frames required to enforce bitrate requirements
56 // over. Streams shorter than this may be too short to realistically require
57 // an encoder to be able to converge to the requested bitrate over.
58 // The input stream will be looped as many times as needed in bitrate tests
59 // to reach at least this number of frames before calculating final bitrate.
60 const unsigned int kMinFramesForBitrateTests = 300;
55 61
56 // The syntax of multiple test streams is: 62 // The syntax of multiple test streams is:
57 // test-stream1;test-stream2;test-stream3 63 // test-stream1;test-stream2;test-stream3
58 // The syntax of each test stream is: 64 // The syntax of each test stream is:
59 // "in_filename:width:height:out_filename:requested_bitrate:requested_framerate 65 // "in_filename:width:height:out_filename:requested_bitrate:requested_framerate
60 // :requested_subsequent_bitrate:requested_subsequent_framerate" 66 // :requested_subsequent_bitrate:requested_subsequent_framerate"
61 // - |in_filename| must be an I420 (YUV planar) raw stream 67 // - |in_filename| must be an I420 (YUV planar) raw stream
62 // (see http://www.fourcc.org/yuv.php#IYUV). 68 // (see http://www.fourcc.org/yuv.php#IYUV).
63 // - |width| and |height| are in pixels. 69 // - |width| and |height| are in pixels.
64 // - |profile| to encode into (values of media::VideoCodecProfile). 70 // - |profile| to encode into (values of media::VideoCodecProfile).
65 // - |out_filename| filename to save the encoded stream to (optional). 71 // - |out_filename| filename to save the encoded stream to (optional).
66 // Output stream is saved for the simple encode test only. 72 // Output stream is saved for the simple encode test only.
67 // Further parameters are optional (need to provide preceding positional 73 // Further parameters are optional (need to provide preceding positional
68 // parameters if a specific subsequent parameter is required): 74 // parameters if a specific subsequent parameter is required):
69 // - |requested_bitrate| requested bitrate in bits per second. 75 // - |requested_bitrate| requested bitrate in bits per second.
70 // - |requested_framerate| requested initial framerate. 76 // - |requested_framerate| requested initial framerate.
71 // - |requested_subsequent_bitrate| bitrate to switch to in the middle of the 77 // - |requested_subsequent_bitrate| bitrate to switch to in the middle of the
72 // stream. 78 // stream.
73 // - |requested_subsequent_framerate| framerate to switch to in the middle 79 // - |requested_subsequent_framerate| framerate to switch to in the middle
74 // of the stream. 80 // of the stream.
75 // Bitrate is only forced for tests that test bitrate. 81 // Bitrate is only forced for tests that test bitrate.
76 const char* g_default_in_filename = "sync_192p20_frames.yuv"; 82 const char* g_default_in_filename = "bear_320x192_40frames.yuv";
77 const char* g_default_in_parameters = ":320:192:1:out.h264:200000"; 83 const char* g_default_in_parameters = ":320:192:1:out.h264:200000";
78 base::FilePath::StringType* g_test_stream_data; 84 base::FilePath::StringType* g_test_stream_data;
79 85
80 struct TestStream { 86 struct TestStream {
81 TestStream() 87 TestStream()
82 : requested_bitrate(0), 88 : requested_bitrate(0),
83 requested_framerate(0), 89 requested_framerate(0),
84 requested_subsequent_bitrate(0), 90 requested_subsequent_bitrate(0),
85 requested_subsequent_framerate(0) {} 91 requested_subsequent_framerate(0) {}
86 ~TestStream() {} 92 ~TestStream() {}
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 if (test_stream->requested_subsequent_framerate == 0) 197 if (test_stream->requested_subsequent_framerate == 0)
192 test_stream->requested_subsequent_framerate = 1; 198 test_stream->requested_subsequent_framerate = 1;
193 } 199 }
194 } 200 }
195 201
196 enum ClientState { 202 enum ClientState {
197 CS_CREATED, 203 CS_CREATED,
198 CS_ENCODER_SET, 204 CS_ENCODER_SET,
199 CS_INITIALIZED, 205 CS_INITIALIZED,
200 CS_ENCODING, 206 CS_ENCODING,
201 CS_FINISHING,
202 CS_FINISHED, 207 CS_FINISHED,
203 CS_ERROR, 208 CS_ERROR,
204 }; 209 };
205 210
206 // Performs basic, codec-specific sanity checks on the stream buffers passed 211 // Performs basic, codec-specific sanity checks on the stream buffers passed
207 // to ProcessStreamBuffer(): whether we've seen keyframes before non-keyframes, 212 // to ProcessStreamBuffer(): whether we've seen keyframes before non-keyframes,
208 // correct sequences of H.264 NALUs (SPS before PPS and before slices), etc. 213 // correct sequences of H.264 NALUs (SPS before PPS and before slices), etc.
209 // Calls given FrameFoundCallback when a complete frame is found while 214 // Calls given FrameFoundCallback when a complete frame is found while
210 // processing. 215 // processing.
211 class StreamValidator { 216 class StreamValidator {
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 // Called when encoder is done with a VideoFrame. 376 // Called when encoder is done with a VideoFrame.
372 void InputNoLongerNeededCallback(int32 input_id); 377 void InputNoLongerNeededCallback(int32 input_id);
373 378
374 // Ensure encoder has at least as many inputs as it asked for 379 // Ensure encoder has at least as many inputs as it asked for
375 // via RequireBitstreamBuffers(). 380 // via RequireBitstreamBuffers().
376 void FeedEncoderWithInputs(); 381 void FeedEncoderWithInputs();
377 382
378 // Provide the encoder with a new output buffer. 383 // Provide the encoder with a new output buffer.
379 void FeedEncoderWithOutput(base::SharedMemory* shm); 384 void FeedEncoderWithOutput(base::SharedMemory* shm);
380 385
381 // Feed the encoder with num_required_input_buffers_ of black frames to force
382 // it to encode and return all inputs that came before this, effectively
383 // flushing it.
384 void FlushEncoder();
385
386 // Called on finding a complete frame (with |keyframe| set to true for 386 // Called on finding a complete frame (with |keyframe| set to true for
387 // keyframes) in the stream, to perform codec-independent, per-frame checks 387 // keyframes) in the stream, to perform codec-independent, per-frame checks
388 // and accounting. Returns false once we have collected all frames we needed. 388 // and accounting. Returns false once we have collected all frames we needed.
389 bool HandleEncodedFrame(bool keyframe); 389 bool HandleEncodedFrame(bool keyframe);
390 390
391 // Verify that stream bitrate has been close to current_requested_bitrate_, 391 // Verify that stream bitrate has been close to current_requested_bitrate_,
392 // assuming current_framerate_ since the last time VerifyStreamProperties() 392 // assuming current_framerate_ since the last time VerifyStreamProperties()
393 // was called. Fail the test if |force_bitrate_| is true and the bitrate 393 // was called. Fail the test if |force_bitrate_| is true and the bitrate
394 // is not within kBitrateTolerance. 394 // is not within kBitrateTolerance.
395 void VerifyStreamProperties(); 395 void VerifyStreamProperties();
(...skipping 19 matching lines...) Expand all
415 int32 next_input_id_; 415 int32 next_input_id_;
416 416
417 // Ids for output BitstreamBuffers. 417 // Ids for output BitstreamBuffers.
418 typedef std::map<int32, base::SharedMemory*> IdToSHM; 418 typedef std::map<int32, base::SharedMemory*> IdToSHM;
419 ScopedVector<base::SharedMemory> output_shms_; 419 ScopedVector<base::SharedMemory> output_shms_;
420 IdToSHM output_buffers_at_client_; 420 IdToSHM output_buffers_at_client_;
421 int32 next_output_buffer_id_; 421 int32 next_output_buffer_id_;
422 422
423 // Current offset into input stream. 423 // Current offset into input stream.
424 off_t pos_in_input_stream_; 424 off_t pos_in_input_stream_;
425 // Calculated from input_coded_size_, in bytes. 425 // Byte size of an input frame.
426 size_t input_buffer_size_; 426 size_t input_buffer_size_;
427 gfx::Size input_coded_size_; 427 gfx::Size input_coded_size_;
428 // Requested by encoder. 428 // Requested by encoder.
429 unsigned int num_required_input_buffers_; 429 unsigned int num_required_input_buffers_;
430 size_t output_buffer_size_; 430 size_t output_buffer_size_;
431 431
432 // Precalculated number of frames in the stream. 432 // Precalculated number of frames in the stream.
433 unsigned int num_frames_in_stream_; 433 unsigned int num_frames_in_stream_;
434 434
435 // Number of frames to encode. This may differ from num_frames_in_stream_ if
436 // we need more frames for bitrate tests.
437 unsigned int num_frames_to_encode_;
438
435 // Number of encoded frames we've got from the encoder thus far. 439 // Number of encoded frames we've got from the encoder thus far.
436 unsigned int num_encoded_frames_; 440 unsigned int num_encoded_frames_;
437 441
438 // Frames since last bitrate verification. 442 // Frames since last bitrate verification.
439 unsigned int num_frames_since_last_check_; 443 unsigned int num_frames_since_last_check_;
440 444
441 // True if received a keyframe while processing current bitstream buffer. 445 // True if received a keyframe while processing current bitstream buffer.
442 bool seen_keyframe_in_this_buffer_; 446 bool seen_keyframe_in_this_buffer_;
443 447
444 // True if we are to save the encoded stream to a file. 448 // True if we are to save the encoded stream to a file.
(...skipping 16 matching lines...) Expand all
461 465
462 // Byte size of the encoded stream (for bitrate calculation) since last 466 // Byte size of the encoded stream (for bitrate calculation) since last
463 // time we checked bitrate. 467 // time we checked bitrate.
464 size_t encoded_stream_size_since_last_check_; 468 size_t encoded_stream_size_since_last_check_;
465 469
466 // If true, verify performance at the end of the test. 470 // If true, verify performance at the end of the test.
467 bool test_perf_; 471 bool test_perf_;
468 472
469 scoped_ptr<StreamValidator> validator_; 473 scoped_ptr<StreamValidator> validator_;
470 474
471 // The time when the encoder has initialized. 475 // The time when the encoding started.
472 base::TimeTicks encoder_initialized_time_; 476 base::TimeTicks encode_start_time_;
473 477
474 // The time when the last encoded frame is ready. 478 // The time when the last encoded frame is ready.
475 base::TimeTicks last_frame_ready_time_; 479 base::TimeTicks last_frame_ready_time_;
476 480
477 // All methods of this class should be run on the same thread. 481 // All methods of this class should be run on the same thread.
478 base::ThreadChecker thread_checker_; 482 base::ThreadChecker thread_checker_;
479 }; 483 };
480 484
481 VEAClient::VEAClient(const TestStream& test_stream, 485 VEAClient::VEAClient(const TestStream& test_stream,
482 ClientStateNotification<ClientState>* note, 486 ClientStateNotification<ClientState>* note,
483 bool save_to_file, 487 bool save_to_file,
484 unsigned int keyframe_period, 488 unsigned int keyframe_period,
485 bool force_bitrate, 489 bool force_bitrate,
486 bool test_perf) 490 bool test_perf)
487 : state_(CS_CREATED), 491 : state_(CS_CREATED),
488 test_stream_(test_stream), 492 test_stream_(test_stream),
489 note_(note), 493 note_(note),
490 next_input_id_(1), 494 next_input_id_(1),
491 next_output_buffer_id_(0), 495 next_output_buffer_id_(0),
492 pos_in_input_stream_(0), 496 pos_in_input_stream_(0),
493 input_buffer_size_(0), 497 input_buffer_size_(0),
494 num_required_input_buffers_(0), 498 num_required_input_buffers_(0),
495 output_buffer_size_(0), 499 output_buffer_size_(0),
496 num_frames_in_stream_(0), 500 num_frames_in_stream_(0),
501 num_frames_to_encode_(0),
497 num_encoded_frames_(0), 502 num_encoded_frames_(0),
498 num_frames_since_last_check_(0), 503 num_frames_since_last_check_(0),
499 seen_keyframe_in_this_buffer_(false), 504 seen_keyframe_in_this_buffer_(false),
500 save_to_file_(save_to_file), 505 save_to_file_(save_to_file),
501 keyframe_period_(keyframe_period), 506 keyframe_period_(keyframe_period),
502 keyframe_requested_at_(kMaxFrameNum), 507 keyframe_requested_at_(kMaxFrameNum),
503 force_bitrate_(force_bitrate), 508 force_bitrate_(force_bitrate),
504 current_requested_bitrate_(0), 509 current_requested_bitrate_(0),
505 current_framerate_(0), 510 current_framerate_(0),
506 encoded_stream_size_since_last_check_(0), 511 encoded_stream_size_since_last_check_(0),
507 test_perf_(test_perf) { 512 test_perf_(test_perf) {
508 if (keyframe_period_) 513 if (keyframe_period_)
509 CHECK_LT(kMaxKeyframeDelay, keyframe_period_); 514 CHECK_LT(kMaxKeyframeDelay, keyframe_period_);
510 515
511 validator_ = StreamValidator::Create( 516 validator_ = StreamValidator::Create(
512 test_stream_.requested_profile, 517 test_stream_.requested_profile,
513 base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this))); 518 base::Bind(&VEAClient::HandleEncodedFrame, base::Unretained(this)));
514 519
515 CHECK(validator_.get()); 520 CHECK(validator_.get());
516 521
517 if (save_to_file_) { 522 if (save_to_file_) {
518 CHECK(!test_stream_.out_filename.empty()); 523 CHECK(!test_stream_.out_filename.empty());
519 base::FilePath out_filename(test_stream_.out_filename); 524 base::FilePath out_filename(test_stream_.out_filename);
520 // This creates or truncates out_filename. 525 // This creates or truncates out_filename.
521 // Without it, AppendToFile() will not work. 526 // Without it, AppendToFile() will not work.
522 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); 527 EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0));
523 } 528 }
524 529
530 input_buffer_size_ =
531 media::VideoFrame::AllocationSize(kInputFormat, test_stream.size);
532 CHECK_GT(input_buffer_size_, 0UL);
533
534 // Calculate the number of frames in the input stream by dividing its length
535 // in bytes by frame size in bytes.
536 CHECK_EQ(test_stream_.input_file.length() % input_buffer_size_, 0)
537 << "Stream byte size is not a product of calculated frame byte size";
538 num_frames_in_stream_ = test_stream_.input_file.length() / input_buffer_size_;
539 CHECK_GT(num_frames_in_stream_, 0UL);
540 CHECK_LE(num_frames_in_stream_, kMaxFrameNum);
541
542 // We may need to loop over the stream more than once if more frames than
543 // provided is required for bitrate tests.
544 if (force_bitrate_ && num_frames_in_stream_ < kMinFramesForBitrateTests) {
545 DVLOG(1) << "Stream too short for bitrate test (" << num_frames_in_stream_
546 << " frames), will loop it to reach " << kMinFramesForBitrateTests
547 << " frames";
548 num_frames_to_encode_ = kMinFramesForBitrateTests;
549 } else {
550 num_frames_to_encode_ = num_frames_in_stream_;
551 }
552
525 thread_checker_.DetachFromThread(); 553 thread_checker_.DetachFromThread();
526 } 554 }
527 555
528 VEAClient::~VEAClient() { CHECK(!has_encoder()); } 556 VEAClient::~VEAClient() { CHECK(!has_encoder()); }
529 557
530 void VEAClient::CreateEncoder() { 558 void VEAClient::CreateEncoder() {
531 DCHECK(thread_checker_.CalledOnValidThread()); 559 DCHECK(thread_checker_.CalledOnValidThread());
532 CHECK(!has_encoder()); 560 CHECK(!has_encoder());
533 561
534 scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder); 562 scoped_ptr<V4L2Device> device = V4L2Device::Create(V4L2Device::kEncoder);
535 encoder_.reset(new V4L2VideoEncodeAccelerator(device.Pass())); 563 encoder_.reset(new V4L2VideoEncodeAccelerator(device.Pass()));
536 SetState(CS_ENCODER_SET); 564 SetState(CS_ENCODER_SET);
537 565
538 DVLOG(1) << "Profile: " << test_stream_.requested_profile 566 DVLOG(1) << "Profile: " << test_stream_.requested_profile
539 << ", initial bitrate: " << test_stream_.requested_bitrate; 567 << ", initial bitrate: " << test_stream_.requested_bitrate;
540 if (!encoder_->Initialize(kInputFormat, 568 if (!encoder_->Initialize(kInputFormat,
541 test_stream_.size, 569 test_stream_.size,
542 test_stream_.requested_profile, 570 test_stream_.requested_profile,
543 test_stream_.requested_bitrate, 571 test_stream_.requested_bitrate,
544 this)) { 572 this)) {
545 DLOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed"; 573 DLOG(ERROR) << "VideoEncodeAccelerator::Initialize() failed";
546 SetState(CS_ERROR); 574 SetState(CS_ERROR);
547 return; 575 return;
548 } 576 }
549 577
550 SetStreamParameters(test_stream_.requested_bitrate, 578 SetStreamParameters(test_stream_.requested_bitrate,
551 test_stream_.requested_framerate); 579 test_stream_.requested_framerate);
552 SetState(CS_INITIALIZED); 580 SetState(CS_INITIALIZED);
553 encoder_initialized_time_ = base::TimeTicks::Now();
554 } 581 }
555 582
556 void VEAClient::DestroyEncoder() { 583 void VEAClient::DestroyEncoder() {
557 DCHECK(thread_checker_.CalledOnValidThread()); 584 DCHECK(thread_checker_.CalledOnValidThread());
558 if (!has_encoder()) 585 if (!has_encoder())
559 return; 586 return;
560 encoder_.release()->Destroy(); 587 encoder_.release()->Destroy();
561 } 588 }
562 589
563 double VEAClient::frames_per_second() { 590 double VEAClient::frames_per_second() {
564 base::TimeDelta duration = last_frame_ready_time_ - encoder_initialized_time_; 591 base::TimeDelta duration = last_frame_ready_time_ - encode_start_time_;
565 return num_encoded_frames_ / duration.InSecondsF(); 592 return num_encoded_frames_ / duration.InSecondsF();
566 } 593 }
567 594
568 void VEAClient::RequireBitstreamBuffers(unsigned int input_count, 595 void VEAClient::RequireBitstreamBuffers(unsigned int input_count,
569 const gfx::Size& input_coded_size, 596 const gfx::Size& input_coded_size,
570 size_t output_size) { 597 size_t output_size) {
571 DCHECK(thread_checker_.CalledOnValidThread()); 598 DCHECK(thread_checker_.CalledOnValidThread());
572 ASSERT_EQ(state_, CS_INITIALIZED); 599 ASSERT_EQ(state_, CS_INITIALIZED);
573 SetState(CS_ENCODING); 600 SetState(CS_ENCODING);
574 601
575 // TODO(posciak): For now we only support input streams that meet encoder 602 // TODO(posciak): For now we only support input streams that meet encoder
576 // size requirements exactly (i.e. coded size == visible size). 603 // size requirements exactly (i.e. coded size == visible size), so that we
604 // can simply mmap the stream file and feed the encoder directly with chunks
605 // of that, instead of memcpying from mmapped file into a separate set of
606 // input buffers that would meet the coded size and alignment requirements.
607 // If/when this is changed, the ARM-specific alignment check below should be
608 // redone as well.
577 input_coded_size_ = input_coded_size; 609 input_coded_size_ = input_coded_size;
578 ASSERT_EQ(input_coded_size_, test_stream_.size); 610 ASSERT_EQ(input_coded_size_, test_stream_.size);
579 611 #if defined(ARCH_CPU_ARMEL)
580 input_buffer_size_ = media::VideoFrame::AllocationSize(kInputFormat,
581 input_coded_size_);
582 CHECK_GT(input_buffer_size_, 0UL);
583
584 // ARM performs CPU cache management with CPU cache line granularity. We thus 612 // ARM performs CPU cache management with CPU cache line granularity. We thus
585 // need to ensure our buffers are CPU cache line-aligned (64 byte-aligned). 613 // need to ensure our buffers are CPU cache line-aligned (64 byte-aligned).
586 // Otherwise newer kernels will refuse to accept them, and on older kernels 614 // Otherwise newer kernels will refuse to accept them, and on older kernels
587 // we'll be treating ourselves to random corruption. 615 // we'll be treating ourselves to random corruption.
588 // Since we are just mmapping and passing chunks of the input file, to ensure 616 // Since we are just mmapping and passing chunks of the input file, to ensure
589 // alignment, if the starting virtual addresses of the frames in it were not 617 // alignment, if the starting virtual addresses of the frames in it were not
590 // 64 byte-aligned, we'd have to use a separate set of input buffers and copy 618 // 64 byte-aligned, we'd have to use a separate set of input buffers and copy
591 // the frames into them before sending to the encoder. It would have been an 619 // the frames into them before sending to the encoder. It would have been an
592 // overkill here though, because, for now at least, we only test resolutions 620 // overkill here though, because, for now at least, we only test resolutions
593 // that result in proper alignment, and it would have also interfered with 621 // that result in proper alignment, and it would have also interfered with
594 // performance testing. So just assert that the frame size is a multiple of 622 // performance testing. So just assert that the frame size is a multiple of
595 // 64 bytes. This ensures all frames start at 64-byte boundary, because 623 // 64 bytes. This ensures all frames start at 64-byte boundary, because
596 // MemoryMappedFile should be mmapp()ed at virtual page start as well. 624 // MemoryMappedFile should be mmapp()ed at virtual page start as well.
597 ASSERT_EQ(input_buffer_size_ & 63, 0u) 625 ASSERT_EQ(input_buffer_size_ & 63, 0u)
598 << "Frame size has to be a multiple of 64 bytes"; 626 << "Frame size has to be a multiple of 64 bytes";
599 ASSERT_EQ(reinterpret_cast<off_t>(test_stream_.input_file.data()) & 63, 0) 627 ASSERT_EQ(reinterpret_cast<off_t>(test_stream_.input_file.data()) & 63, 0)
600 << "Mapped file should be mapped at a 64 byte boundary"; 628 << "Mapped file should be mapped at a 64 byte boundary";
629 #endif
601 630
602 num_required_input_buffers_ = input_count; 631 num_required_input_buffers_ = input_count;
603 ASSERT_GT(num_required_input_buffers_, 0UL); 632 ASSERT_GT(num_required_input_buffers_, 0UL);
604 633
605 num_frames_in_stream_ = test_stream_.input_file.length() / input_buffer_size_;
606 CHECK_GT(num_frames_in_stream_, 0UL);
607 CHECK_LE(num_frames_in_stream_, kMaxFrameNum);
608 CHECK_EQ(num_frames_in_stream_ * input_buffer_size_,
609 test_stream_.input_file.length());
610
611 output_buffer_size_ = output_size; 634 output_buffer_size_ = output_size;
612 ASSERT_GT(output_buffer_size_, 0UL); 635 ASSERT_GT(output_buffer_size_, 0UL);
613 636
614 for (unsigned int i = 0; i < kNumOutputBuffers; ++i) { 637 for (unsigned int i = 0; i < kNumOutputBuffers; ++i) {
615 base::SharedMemory* shm = new base::SharedMemory(); 638 base::SharedMemory* shm = new base::SharedMemory();
616 CHECK(shm->CreateAndMapAnonymous(output_buffer_size_)); 639 CHECK(shm->CreateAndMapAnonymous(output_buffer_size_));
617 output_shms_.push_back(shm); 640 output_shms_.push_back(shm);
618 FeedEncoderWithOutput(shm); 641 FeedEncoderWithOutput(shm);
619 } 642 }
620 643
644 encode_start_time_ = base::TimeTicks::Now();
621 FeedEncoderWithInputs(); 645 FeedEncoderWithInputs();
622 } 646 }
623 647
624 void VEAClient::BitstreamBufferReady(int32 bitstream_buffer_id, 648 void VEAClient::BitstreamBufferReady(int32 bitstream_buffer_id,
625 size_t payload_size, 649 size_t payload_size,
626 bool key_frame) { 650 bool key_frame) {
627 DCHECK(thread_checker_.CalledOnValidThread()); 651 DCHECK(thread_checker_.CalledOnValidThread());
628 ASSERT_LE(payload_size, output_buffer_size_); 652 ASSERT_LE(payload_size, output_buffer_size_);
629 653
630 IdToSHM::iterator it = output_buffers_at_client_.find(bitstream_buffer_id); 654 IdToSHM::iterator it = output_buffers_at_client_.find(bitstream_buffer_id);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 return; 748 return;
725 749
726 if (state_ != CS_ENCODING) 750 if (state_ != CS_ENCODING)
727 return; 751 return;
728 752
729 while (inputs_at_client_.size() < 753 while (inputs_at_client_.size() <
730 num_required_input_buffers_ + kNumExtraInputFrames) { 754 num_required_input_buffers_ + kNumExtraInputFrames) {
731 size_t bytes_left = test_stream_.input_file.length() - pos_in_input_stream_; 755 size_t bytes_left = test_stream_.input_file.length() - pos_in_input_stream_;
732 if (bytes_left < input_buffer_size_) { 756 if (bytes_left < input_buffer_size_) {
733 DCHECK_EQ(bytes_left, 0UL); 757 DCHECK_EQ(bytes_left, 0UL);
734 FlushEncoder(); 758 // Rewind if at the end of stream and we are still encoding.
735 return; 759 // This is to flush the encoder with additional frames from the beginning
760 // of the stream, or if the stream is shorter that the number of frames
761 // we require for bitrate tests.
762 pos_in_input_stream_ = 0;
763 continue;
736 } 764 }
737 765
738 bool force_keyframe = false; 766 bool force_keyframe = false;
739 if (keyframe_period_ && next_input_id_ % keyframe_period_ == 0) { 767 if (keyframe_period_ && next_input_id_ % keyframe_period_ == 0) {
740 keyframe_requested_at_ = next_input_id_; 768 keyframe_requested_at_ = next_input_id_;
741 force_keyframe = true; 769 force_keyframe = true;
742 } 770 }
743 771
744 scoped_refptr<media::VideoFrame> video_frame = 772 scoped_refptr<media::VideoFrame> video_frame =
745 PrepareInputFrame(pos_in_input_stream_); 773 PrepareInputFrame(pos_in_input_stream_);
746 pos_in_input_stream_ += input_buffer_size_; 774 pos_in_input_stream_ += input_buffer_size_;
747 775
748 encoder_->Encode(video_frame, force_keyframe); 776 encoder_->Encode(video_frame, force_keyframe);
749 } 777 }
750 } 778 }
751 779
752 void VEAClient::FeedEncoderWithOutput(base::SharedMemory* shm) { 780 void VEAClient::FeedEncoderWithOutput(base::SharedMemory* shm) {
753 if (!has_encoder()) 781 if (!has_encoder())
754 return; 782 return;
755 783
756 if (state_ != CS_ENCODING && state_ != CS_FINISHING) 784 if (state_ != CS_ENCODING)
757 return; 785 return;
758 786
759 base::SharedMemoryHandle dup_handle; 787 base::SharedMemoryHandle dup_handle;
760 CHECK(shm->ShareToProcess(base::Process::Current().handle(), &dup_handle)); 788 CHECK(shm->ShareToProcess(base::Process::Current().handle(), &dup_handle));
761 789
762 media::BitstreamBuffer bitstream_buffer( 790 media::BitstreamBuffer bitstream_buffer(
763 next_output_buffer_id_++, dup_handle, output_buffer_size_); 791 next_output_buffer_id_++, dup_handle, output_buffer_size_);
764 CHECK(output_buffers_at_client_.insert(std::make_pair(bitstream_buffer.id(), 792 CHECK(output_buffers_at_client_.insert(std::make_pair(bitstream_buffer.id(),
765 shm)).second); 793 shm)).second);
766 encoder_->UseOutputBitstreamBuffer(bitstream_buffer); 794 encoder_->UseOutputBitstreamBuffer(bitstream_buffer);
767 } 795 }
768 796
769 void VEAClient::FlushEncoder() {
770 ASSERT_EQ(state_, CS_ENCODING);
771 SetState(CS_FINISHING);
772
773 // Feed the encoder with an additional set of num_required_input_buffers_
774 // to flush it, using the first frame in the input stream. The resulting
775 // encoded frames will be ignored.
776 for (unsigned int i = 0; i < num_required_input_buffers_; ++i) {
777 scoped_refptr<media::VideoFrame> frame = PrepareInputFrame(0);
778 encoder_->Encode(frame, false);
779 }
780 }
781
782 bool VEAClient::HandleEncodedFrame(bool keyframe) { 797 bool VEAClient::HandleEncodedFrame(bool keyframe) {
783 // This would be a bug in the test, which should not ignore false 798 // This would be a bug in the test, which should not ignore false
784 // return value from this method. 799 // return value from this method.
785 CHECK_LE(num_encoded_frames_, num_frames_in_stream_); 800 CHECK_LE(num_encoded_frames_, num_frames_to_encode_);
786 801
787 ++num_encoded_frames_; 802 ++num_encoded_frames_;
788 ++num_frames_since_last_check_; 803 ++num_frames_since_last_check_;
789 804
790 last_frame_ready_time_ = base::TimeTicks::Now(); 805 last_frame_ready_time_ = base::TimeTicks::Now();
791 if (keyframe) { 806 if (keyframe) {
792 // Got keyframe, reset keyframe detection regardless of whether we 807 // Got keyframe, reset keyframe detection regardless of whether we
793 // got a frame in time or not. 808 // got a frame in time or not.
794 keyframe_requested_at_ = kMaxFrameNum; 809 keyframe_requested_at_ = kMaxFrameNum;
795 seen_keyframe_in_this_buffer_ = true; 810 seen_keyframe_in_this_buffer_ = true;
796 } 811 }
797 812
798 // Because the keyframe behavior requirements are loose, we give 813 // Because the keyframe behavior requirements are loose, we give
799 // the encoder more freedom here. It could either deliver a keyframe 814 // the encoder more freedom here. It could either deliver a keyframe
800 // immediately after we requested it, which could be for a frame number 815 // immediately after we requested it, which could be for a frame number
801 // before the one we requested it for (if the keyframe request 816 // before the one we requested it for (if the keyframe request
802 // is asynchronous, i.e. not bound to any concrete frame, and because 817 // is asynchronous, i.e. not bound to any concrete frame, and because
803 // the pipeline can be deeper than one frame), at that frame, or after. 818 // the pipeline can be deeper than one frame), at that frame, or after.
804 // So the only constraints we put here is that we get a keyframe not 819 // So the only constraints we put here is that we get a keyframe not
805 // earlier than we requested one (in time), and not later than 820 // earlier than we requested one (in time), and not later than
806 // kMaxKeyframeDelay frames after the frame, for which we requested 821 // kMaxKeyframeDelay frames after the frame, for which we requested
807 // it, comes back encoded. 822 // it, comes back encoded.
808 EXPECT_LE(num_encoded_frames_, keyframe_requested_at_ + kMaxKeyframeDelay); 823 EXPECT_LE(num_encoded_frames_, keyframe_requested_at_ + kMaxKeyframeDelay);
809 824
810 if (num_encoded_frames_ == num_frames_in_stream_ / 2) { 825 if (num_encoded_frames_ == num_frames_to_encode_ / 2) {
811 VerifyStreamProperties(); 826 VerifyStreamProperties();
812 if (test_stream_.requested_subsequent_bitrate != 827 if (test_stream_.requested_subsequent_bitrate !=
813 current_requested_bitrate_ || 828 current_requested_bitrate_ ||
814 test_stream_.requested_subsequent_framerate != current_framerate_) { 829 test_stream_.requested_subsequent_framerate != current_framerate_) {
815 SetStreamParameters(test_stream_.requested_subsequent_bitrate, 830 SetStreamParameters(test_stream_.requested_subsequent_bitrate,
816 test_stream_.requested_subsequent_framerate); 831 test_stream_.requested_subsequent_framerate);
817 } 832 }
818 } else if (num_encoded_frames_ == num_frames_in_stream_) { 833 } else if (num_encoded_frames_ == num_frames_to_encode_) {
819 VerifyPerf(); 834 VerifyPerf();
820 VerifyStreamProperties(); 835 VerifyStreamProperties();
821 SetState(CS_FINISHED); 836 SetState(CS_FINISHED);
822 return false; 837 return false;
823 } 838 }
824 839
825 return true; 840 return true;
826 } 841 }
827 842
828 void VEAClient::VerifyPerf() { 843 void VEAClient::VerifyPerf() {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 base::Bind(&VEAClient::CreateEncoder, 926 base::Bind(&VEAClient::CreateEncoder,
912 base::Unretained(clients.back()))); 927 base::Unretained(clients.back())));
913 encoder_threads.push_back(encoder_thread); 928 encoder_threads.push_back(encoder_thread);
914 } 929 }
915 930
916 // Wait all the encoders to finish. 931 // Wait all the encoders to finish.
917 for (int i = 0; i < num_concurrent_encoders; i++) { 932 for (int i = 0; i < num_concurrent_encoders; i++) {
918 ASSERT_EQ(notes[i]->Wait(), CS_ENCODER_SET); 933 ASSERT_EQ(notes[i]->Wait(), CS_ENCODER_SET);
919 ASSERT_EQ(notes[i]->Wait(), CS_INITIALIZED); 934 ASSERT_EQ(notes[i]->Wait(), CS_INITIALIZED);
920 ASSERT_EQ(notes[i]->Wait(), CS_ENCODING); 935 ASSERT_EQ(notes[i]->Wait(), CS_ENCODING);
921 ASSERT_EQ(notes[i]->Wait(), CS_FINISHING);
922 ASSERT_EQ(notes[i]->Wait(), CS_FINISHED); 936 ASSERT_EQ(notes[i]->Wait(), CS_FINISHED);
923 encoder_threads[i]->message_loop()->PostTask( 937 encoder_threads[i]->message_loop()->PostTask(
924 FROM_HERE, 938 FROM_HERE,
925 base::Bind(&VEAClient::DestroyEncoder, base::Unretained(clients[i]))); 939 base::Bind(&VEAClient::DestroyEncoder, base::Unretained(clients[i])));
926 encoder_threads[i]->Stop(); 940 encoder_threads[i]->Stop();
927 } 941 }
928 } 942 }
929 943
930 INSTANTIATE_TEST_CASE_P( 944 INSTANTIATE_TEST_CASE_P(
931 SimpleEncode, 945 SimpleEncode,
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 test_stream_data->assign(it->second.c_str()); 1018 test_stream_data->assign(it->second.c_str());
1005 continue; 1019 continue;
1006 } 1020 }
1007 if (it->first == "v" || it->first == "vmodule") 1021 if (it->first == "v" || it->first == "vmodule")
1008 continue; 1022 continue;
1009 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; 1023 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second;
1010 } 1024 }
1011 1025
1012 return RUN_ALL_TESTS(); 1026 return RUN_ALL_TESTS();
1013 } 1027 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698