Index: content/common/gpu/media/video_encode_accelerator_unittest.cc |
diff --git a/content/common/gpu/media/video_encode_accelerator_unittest.cc b/content/common/gpu/media/video_encode_accelerator_unittest.cc |
index 56d40a240c5fe261c39b27e2d60c82fad134529a..8baf69e7bc966bf53bb90fcf0e2ff00936ada745 100644 |
--- a/content/common/gpu/media/video_encode_accelerator_unittest.cc |
+++ b/content/common/gpu/media/video_encode_accelerator_unittest.cc |
@@ -52,6 +52,12 @@ const double kDefaultSubsequentFramerateRatio = 0.1; |
const double kBitrateTolerance = 0.1; |
// Minimum required FPS throughput for the basic performance test. |
const uint32 kMinPerfFPS = 30; |
+// Minimum (arbitrary) number of frames required to enforce bitrate requirements |
+// over. Streams shorter than this may be too short to realistically require |
+// an encoder to be able to converge to the requested bitrate over. |
+// The input stream will be looped as many times as needed in bitrate tests |
+// to reach at least this number of frames before calculating final bitrate. |
+const unsigned int kMinFramesForBitrateTests = 300; |
// The syntax of multiple test streams is: |
// test-stream1;test-stream2;test-stream3 |
@@ -73,7 +79,7 @@ const uint32 kMinPerfFPS = 30; |
// - |requested_subsequent_framerate| framerate to switch to in the middle |
// of the stream. |
// Bitrate is only forced for tests that test bitrate. |
-const char* g_default_in_filename = "sync_192p20_frames.yuv"; |
+const char* g_default_in_filename = "bear_192p40_frames.yuv"; |
Ami GONE FROM CHROMIUM
2014/05/16 18:00:50
why this change?
Pawel Osciak
2014/05/16 22:49:15
Sync has a lot of black background and not as much
|
const char* g_default_in_parameters = ":320:192:1:out.h264:200000"; |
base::FilePath::StringType* g_test_stream_data; |
@@ -198,7 +204,6 @@ enum ClientState { |
CS_ENCODER_SET, |
CS_INITIALIZED, |
CS_ENCODING, |
- CS_FINISHING, |
CS_FINISHED, |
CS_ERROR, |
}; |
@@ -378,11 +383,6 @@ class VEAClient : public VideoEncodeAccelerator::Client { |
// Provide the encoder with a new output buffer. |
void FeedEncoderWithOutput(base::SharedMemory* shm); |
- // Feed the encoder with num_required_input_buffers_ of black frames to force |
- // it to encode and return all inputs that came before this, effectively |
- // flushing it. |
- void FlushEncoder(); |
- |
// Called on finding a complete frame (with |keyframe| set to true for |
// keyframes) in the stream, to perform codec-independent, per-frame checks |
// and accounting. Returns false once we have collected all frames we needed. |
@@ -422,7 +422,7 @@ class VEAClient : public VideoEncodeAccelerator::Client { |
// Current offset into input stream. |
off_t pos_in_input_stream_; |
- // Calculated from input_coded_size_, in bytes. |
+ // Byte size of an input frame. |
size_t input_buffer_size_; |
gfx::Size input_coded_size_; |
// Requested by encoder. |
@@ -432,6 +432,10 @@ class VEAClient : public VideoEncodeAccelerator::Client { |
// Precalculated number of frames in the stream. |
unsigned int num_frames_in_stream_; |
+ // Number of frames to encode. This may differ from num_frames_in_stream_ if |
+ // we need more frames for bitrate tests. |
+ unsigned int num_frames_to_encode_; |
+ |
// Number of encoded frames we've got from the encoder thus far. |
unsigned int num_encoded_frames_; |
@@ -468,8 +472,8 @@ class VEAClient : public VideoEncodeAccelerator::Client { |
scoped_ptr<StreamValidator> validator_; |
- // The time when the encoder has initialized. |
- base::TimeTicks encoder_initialized_time_; |
+ // The time when the encoding started. |
+ base::TimeTicks encode_start_time_; |
// The time when the last encoded frame is ready. |
base::TimeTicks last_frame_ready_time_; |
@@ -494,6 +498,7 @@ VEAClient::VEAClient(const TestStream& test_stream, |
num_required_input_buffers_(0), |
output_buffer_size_(0), |
num_frames_in_stream_(0), |
+ num_frames_to_encode_(0), |
num_encoded_frames_(0), |
num_frames_since_last_check_(0), |
seen_keyframe_in_this_buffer_(false), |
@@ -522,6 +527,29 @@ VEAClient::VEAClient(const TestStream& test_stream, |
EXPECT_EQ(0, base::WriteFile(out_filename, NULL, 0)); |
} |
+ input_buffer_size_ = |
+ media::VideoFrame::AllocationSize(kInputFormat, test_stream.size); |
+ CHECK_GT(input_buffer_size_, 0UL); |
+ |
+ // Calculate the number of frames in the input stream by dividing its length |
+ // in bytes by frame size in bytes. |
+ CHECK_EQ(test_stream_.input_file.length() % input_buffer_size_, 0) |
+ << "Stream byte size is not a product of calculated frame byte size"; |
+ num_frames_in_stream_ = test_stream_.input_file.length() / input_buffer_size_; |
+ CHECK_GT(num_frames_in_stream_, 0UL); |
+ CHECK_LE(num_frames_in_stream_, kMaxFrameNum); |
+ |
+ // We may need to loop over the stream more than once if more frames than |
+ // provided is required for bitrate tests. |
+ if (force_bitrate_ && num_frames_in_stream_ < kMinFramesForBitrateTests) { |
+ DVLOG(1) << "Stream too short for bitrate test (" << num_frames_in_stream_ |
+ << " frames), will loop it to reach " << kMinFramesForBitrateTests |
+ << " frames"; |
+ num_frames_to_encode_ = kMinFramesForBitrateTests; |
+ } else { |
+ num_frames_to_encode_ = num_frames_in_stream_; |
+ } |
+ |
thread_checker_.DetachFromThread(); |
} |
@@ -550,7 +578,6 @@ void VEAClient::CreateEncoder() { |
SetStreamParameters(test_stream_.requested_bitrate, |
test_stream_.requested_framerate); |
SetState(CS_INITIALIZED); |
- encoder_initialized_time_ = base::TimeTicks::Now(); |
} |
void VEAClient::DestroyEncoder() { |
@@ -561,7 +588,7 @@ void VEAClient::DestroyEncoder() { |
} |
double VEAClient::frames_per_second() { |
- base::TimeDelta duration = last_frame_ready_time_ - encoder_initialized_time_; |
+ base::TimeDelta duration = last_frame_ready_time_ - encode_start_time_; |
return num_encoded_frames_ / duration.InSecondsF(); |
} |
@@ -573,14 +600,15 @@ void VEAClient::RequireBitstreamBuffers(unsigned int input_count, |
SetState(CS_ENCODING); |
// TODO(posciak): For now we only support input streams that meet encoder |
- // size requirements exactly (i.e. coded size == visible size). |
+ // size requirements exactly (i.e. coded size == visible size), so that we |
+ // can simply mmap the stream file and feed the encoder directly with chunks |
+ // of that, instead of memcpying from mmapped file into a separate set of |
+ // input buffers that would meet the coded size and alignment requirements. |
+ // If/when this is changed, the ARM-specific alignment check below should be |
+ // redone as well. |
input_coded_size_ = input_coded_size; |
ASSERT_EQ(input_coded_size_, test_stream_.size); |
- |
- input_buffer_size_ = media::VideoFrame::AllocationSize(kInputFormat, |
- input_coded_size_); |
- CHECK_GT(input_buffer_size_, 0UL); |
- |
+#if defined(ARCH_CPU_ARMEL) |
// ARM performs CPU cache management with CPU cache line granularity. We thus |
// need to ensure our buffers are CPU cache line-aligned (64 byte-aligned). |
// Otherwise newer kernels will refuse to accept them, and on older kernels |
@@ -598,16 +626,11 @@ void VEAClient::RequireBitstreamBuffers(unsigned int input_count, |
<< "Frame size has to be a multiple of 64 bytes"; |
ASSERT_EQ(reinterpret_cast<off_t>(test_stream_.input_file.data()) & 63, 0) |
<< "Mapped file should be mapped at a 64 byte boundary"; |
+#endif |
num_required_input_buffers_ = input_count; |
ASSERT_GT(num_required_input_buffers_, 0UL); |
- num_frames_in_stream_ = test_stream_.input_file.length() / input_buffer_size_; |
- CHECK_GT(num_frames_in_stream_, 0UL); |
- CHECK_LE(num_frames_in_stream_, kMaxFrameNum); |
- CHECK_EQ(num_frames_in_stream_ * input_buffer_size_, |
- test_stream_.input_file.length()); |
- |
output_buffer_size_ = output_size; |
ASSERT_GT(output_buffer_size_, 0UL); |
@@ -618,6 +641,7 @@ void VEAClient::RequireBitstreamBuffers(unsigned int input_count, |
FeedEncoderWithOutput(shm); |
} |
+ encode_start_time_ = base::TimeTicks::Now(); |
FeedEncoderWithInputs(); |
} |
@@ -731,8 +755,12 @@ void VEAClient::FeedEncoderWithInputs() { |
size_t bytes_left = test_stream_.input_file.length() - pos_in_input_stream_; |
if (bytes_left < input_buffer_size_) { |
DCHECK_EQ(bytes_left, 0UL); |
- FlushEncoder(); |
- return; |
+ // Rewind if at the end of stream and we are still encoding. |
+ // This is to flush the encoder with additional frames from the beginning |
+ // of the stream, or if the stream is shorter that the number of frames |
+ // we require for bitrate tests. |
+ pos_in_input_stream_ = 0; |
+ continue; |
} |
bool force_keyframe = false; |
@@ -753,7 +781,7 @@ void VEAClient::FeedEncoderWithOutput(base::SharedMemory* shm) { |
if (!has_encoder()) |
return; |
- if (state_ != CS_ENCODING && state_ != CS_FINISHING) |
+ if (state_ != CS_ENCODING) |
return; |
base::SharedMemoryHandle dup_handle; |
@@ -766,23 +794,10 @@ void VEAClient::FeedEncoderWithOutput(base::SharedMemory* shm) { |
encoder_->UseOutputBitstreamBuffer(bitstream_buffer); |
} |
-void VEAClient::FlushEncoder() { |
- ASSERT_EQ(state_, CS_ENCODING); |
- SetState(CS_FINISHING); |
- |
- // Feed the encoder with an additional set of num_required_input_buffers_ |
- // to flush it, using the first frame in the input stream. The resulting |
- // encoded frames will be ignored. |
- for (unsigned int i = 0; i < num_required_input_buffers_; ++i) { |
- scoped_refptr<media::VideoFrame> frame = PrepareInputFrame(0); |
- encoder_->Encode(frame, false); |
- } |
-} |
- |
bool VEAClient::HandleEncodedFrame(bool keyframe) { |
// This would be a bug in the test, which should not ignore false |
// return value from this method. |
- CHECK_LE(num_encoded_frames_, num_frames_in_stream_); |
+ CHECK_LE(num_encoded_frames_, num_frames_to_encode_); |
++num_encoded_frames_; |
++num_frames_since_last_check_; |
@@ -807,7 +822,7 @@ bool VEAClient::HandleEncodedFrame(bool keyframe) { |
// it, comes back encoded. |
EXPECT_LE(num_encoded_frames_, keyframe_requested_at_ + kMaxKeyframeDelay); |
- if (num_encoded_frames_ == num_frames_in_stream_ / 2) { |
+ if (num_encoded_frames_ == num_frames_to_encode_ / 2) { |
VerifyStreamProperties(); |
if (test_stream_.requested_subsequent_bitrate != |
current_requested_bitrate_ || |
@@ -815,7 +830,7 @@ bool VEAClient::HandleEncodedFrame(bool keyframe) { |
SetStreamParameters(test_stream_.requested_subsequent_bitrate, |
test_stream_.requested_subsequent_framerate); |
} |
- } else if (num_encoded_frames_ == num_frames_in_stream_) { |
+ } else if (num_encoded_frames_ == num_frames_to_encode_) { |
VerifyPerf(); |
VerifyStreamProperties(); |
SetState(CS_FINISHED); |
@@ -918,7 +933,6 @@ TEST_P(VideoEncodeAcceleratorTest, TestSimpleEncode) { |
ASSERT_EQ(notes[i]->Wait(), CS_ENCODER_SET); |
ASSERT_EQ(notes[i]->Wait(), CS_INITIALIZED); |
ASSERT_EQ(notes[i]->Wait(), CS_ENCODING); |
- ASSERT_EQ(notes[i]->Wait(), CS_FINISHING); |
ASSERT_EQ(notes[i]->Wait(), CS_FINISHED); |
encoder_threads[i]->message_loop()->PostTask( |
FROM_HERE, |