Commit 5118a5b3 authored by jchuang's avatar jchuang Committed by Commit bot

Reland: vea_unittest: Calculate per-frame encode latency

This is a reland of https://crrev.com/1117853002, which failed to compile
in CHECK_GT(size_t var, 0), and CHECK_LE(size_t var, 100) because the compiler
handles the numeric literals as signed. So compiler complained about comparing
signed and unsigned. This is fixed by using unsigned numeric literals like 0UL
and 100UL.

Calculates per-frame encode latency, which is basically the time delay from
input of each VideoFrame (VEA::Encode()) to output of the corresponding
BitstreamBuffer (VEA::Client::BitstreamBufferReady()).

It calculates encode latency values at the 50th(median), 75th, and 95th percentiles.

Also fix a wrong comment.

BUG=345181
TEST=Check "Encode latency for the 50%/75%/95%" in output logs.

Review URL: https://codereview.chromium.org/1139913009

Cr-Commit-Position: refs/heads/master@{#330060}
parent 547154b8
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <inttypes.h>
#include <algorithm>
#include "base/at_exit.h" #include "base/at_exit.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
...@@ -70,6 +74,8 @@ const uint32 kMinPerfFPS = 30; ...@@ -70,6 +74,8 @@ const uint32 kMinPerfFPS = 30;
// The input stream will be looped as many times as needed in bitrate tests // 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. // to reach at least this number of frames before calculating final bitrate.
const unsigned int kMinFramesForBitrateTests = 300; const unsigned int kMinFramesForBitrateTests = 300;
// The percentiles to measure for encode latency.
const unsigned int kLoggedLatencyPercentiles[] = {50, 75, 95};
// The syntax of multiple test streams is: // The syntax of multiple test streams is:
// test-stream1;test-stream2;test-stream3 // test-stream1;test-stream2;test-stream3
...@@ -190,6 +196,19 @@ static bool WriteFile(base::File* file, ...@@ -190,6 +196,19 @@ static bool WriteFile(base::File* file,
return true; return true;
} }
// Return the |percentile| from a sorted vector.
static base::TimeDelta Percentile(
const std::vector<base::TimeDelta>& sorted_values,
unsigned int percentile) {
size_t size = sorted_values.size();
CHECK_GT(size, 0UL);
CHECK_LE(percentile, 100UL);
// Use Nearest Rank method in http://en.wikipedia.org/wiki/Percentile.
int index =
std::max(static_cast<int>(ceil(0.01f * percentile * size)) - 1, 0);
return sorted_values[index];
}
static bool IsH264(media::VideoCodecProfile profile) { static bool IsH264(media::VideoCodecProfile profile) {
return profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX; return profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX;
} }
...@@ -361,10 +380,12 @@ class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment { ...@@ -361,10 +380,12 @@ class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment {
VideoEncodeAcceleratorTestEnvironment( VideoEncodeAcceleratorTestEnvironment(
scoped_ptr<base::FilePath::StringType> data, scoped_ptr<base::FilePath::StringType> data,
const base::FilePath& log_path, const base::FilePath& log_path,
bool run_at_fps) bool run_at_fps,
: run_at_fps_(run_at_fps), bool needs_encode_latency)
test_stream_data_(data.Pass()), : test_stream_data_(data.Pass()),
log_path_(log_path) {} log_path_(log_path),
run_at_fps_(run_at_fps),
needs_encode_latency_(needs_encode_latency) {}
virtual void SetUp() { virtual void SetUp() {
if (!log_path_.empty()) { if (!log_path_.empty()) {
...@@ -382,23 +403,35 @@ class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment { ...@@ -382,23 +403,35 @@ class VideoEncodeAcceleratorTestEnvironment : public ::testing::Environment {
log_file_.reset(); log_file_.reset();
} }
// Log one entry of machine-readable data to file. // Log one entry of machine-readable data to file and LOG(INFO).
// The log has one data entry per line in the format of "<key>: <value>". // The log has one data entry per line in the format of "<key>: <value>".
// Note that Chrome OS video_VEAPerf autotest parses the output key and value
// pairs. Be sure to keep the autotest in sync.
void LogToFile(const std::string& key, const std::string& value) { void LogToFile(const std::string& key, const std::string& value) {
std::string s = base::StringPrintf("%s: %s\n", key.c_str(), value.c_str());
LOG(INFO) << s;
if (log_file_) { if (log_file_) {
std::string s =
base::StringPrintf("%s: %s\n", key.c_str(), value.c_str());
log_file_->WriteAtCurrentPos(s.data(), s.length()); log_file_->WriteAtCurrentPos(s.data(), s.length());
} }
} }
// Feed the encoder with the input buffers at the requested framerate. If
// false, feed as fast as possible. This is set by the command line switch
// "--run_at_fps".
bool run_at_fps() const { return run_at_fps_; }
// Whether to measure encode latency. This is set by the command line switch
// "--measure_latency".
bool needs_encode_latency() const { return needs_encode_latency_; }
ScopedVector<TestStream> test_streams_; ScopedVector<TestStream> test_streams_;
bool run_at_fps_;
private: private:
scoped_ptr<base::FilePath::StringType> test_stream_data_; scoped_ptr<base::FilePath::StringType> test_stream_data_;
base::FilePath log_path_; base::FilePath log_path_;
scoped_ptr<base::File> log_file_; scoped_ptr<base::File> log_file_;
bool run_at_fps_;
bool needs_encode_latency_;
}; };
enum ClientState { enum ClientState {
...@@ -559,15 +592,11 @@ class VEAClient : public VideoEncodeAccelerator::Client { ...@@ -559,15 +592,11 @@ class VEAClient : public VideoEncodeAccelerator::Client {
bool force_bitrate, bool force_bitrate,
bool test_perf, bool test_perf,
bool mid_stream_bitrate_switch, bool mid_stream_bitrate_switch,
bool mid_stream_framerate_switch, bool mid_stream_framerate_switch);
bool run_at_fps);
~VEAClient() override; ~VEAClient() override;
void CreateEncoder(); void CreateEncoder();
void DestroyEncoder(); void DestroyEncoder();
// Return the number of encoded frames per second.
double frames_per_second();
// VideoDecodeAccelerator::Client implementation. // VideoDecodeAccelerator::Client implementation.
void RequireBitstreamBuffers(unsigned int input_count, void RequireBitstreamBuffers(unsigned int input_count,
const gfx::Size& input_coded_size, const gfx::Size& input_coded_size,
...@@ -580,6 +609,9 @@ class VEAClient : public VideoEncodeAccelerator::Client { ...@@ -580,6 +609,9 @@ class VEAClient : public VideoEncodeAccelerator::Client {
private: private:
bool has_encoder() { return encoder_.get(); } bool has_encoder() { return encoder_.get(); }
// Return the number of encoded frames per second.
double frames_per_second();
scoped_ptr<media::VideoEncodeAccelerator> CreateFakeVEA(); scoped_ptr<media::VideoEncodeAccelerator> CreateFakeVEA();
scoped_ptr<media::VideoEncodeAccelerator> CreateV4L2VEA(); scoped_ptr<media::VideoEncodeAccelerator> CreateV4L2VEA();
scoped_ptr<media::VideoEncodeAccelerator> CreateVaapiVEA(); scoped_ptr<media::VideoEncodeAccelerator> CreateVaapiVEA();
...@@ -603,15 +635,17 @@ class VEAClient : public VideoEncodeAccelerator::Client { ...@@ -603,15 +635,17 @@ class VEAClient : public VideoEncodeAccelerator::Client {
// and accounting. Returns false once we have collected all frames we needed. // and accounting. Returns false once we have collected all frames we needed.
bool HandleEncodedFrame(bool keyframe); bool HandleEncodedFrame(bool keyframe);
// Verify the minimum FPS requirement.
void VerifyMinFPS();
// Verify that stream bitrate has been close to current_requested_bitrate_, // Verify that stream bitrate has been close to current_requested_bitrate_,
// assuming current_framerate_ since the last time VerifyStreamProperties() // assuming current_framerate_ since the last time VerifyStreamProperties()
// was called. Fail the test if |force_bitrate_| is true and the bitrate // was called. Fail the test if |force_bitrate_| is true and the bitrate
// is not within kBitrateTolerance. // is not within kBitrateTolerance.
void VerifyStreamProperties(); void VerifyStreamProperties();
// Test codec performance, failing the test if we are currently running // Log the performance data.
// the performance test. void LogPerf();
void VerifyPerf();
// Write IVF file header to test_stream_->out_filename. // Write IVF file header to test_stream_->out_filename.
void WriteIvfFileHeader(); void WriteIvfFileHeader();
...@@ -619,9 +653,11 @@ class VEAClient : public VideoEncodeAccelerator::Client { ...@@ -619,9 +653,11 @@ class VEAClient : public VideoEncodeAccelerator::Client {
// Write an IVF frame header to test_stream_->out_filename. // Write an IVF frame header to test_stream_->out_filename.
void WriteIvfFrameHeader(int frame_index, size_t frame_size); void WriteIvfFrameHeader(int frame_index, size_t frame_size);
// Prepare and return a frame wrapping the data at |position| bytes in // Prepare and return a frame wrapping the data at |position| bytes in the
// the input stream, ready to be sent to encoder. // input stream, ready to be sent to encoder.
scoped_refptr<media::VideoFrame> PrepareInputFrame(off_t position); // The input frame id is returned in |input_id|.
scoped_refptr<media::VideoFrame> PrepareInputFrame(off_t position,
int32* input_id);
// Update the parameters according to |mid_stream_bitrate_switch| and // Update the parameters according to |mid_stream_bitrate_switch| and
// |mid_stream_framerate_switch|. // |mid_stream_framerate_switch|.
...@@ -639,11 +675,18 @@ class VEAClient : public VideoEncodeAccelerator::Client { ...@@ -639,11 +675,18 @@ class VEAClient : public VideoEncodeAccelerator::Client {
// Used to notify another thread about the state. VEAClient does not own this. // Used to notify another thread about the state. VEAClient does not own this.
ClientStateNotification<ClientState>* note_; ClientStateNotification<ClientState>* note_;
// Ids assigned to VideoFrames (start at 1 for easy comparison with // Ids assigned to VideoFrames.
// num_encoded_frames_).
std::set<int32> inputs_at_client_; std::set<int32> inputs_at_client_;
int32 next_input_id_; int32 next_input_id_;
// Encode start time of all encoded frames. The position in the vector is the
// frame input id.
std::vector<base::TimeTicks> encode_start_time_;
// The encode latencies of all encoded frames. We define encode latency as the
// time delay from input of each VideoFrame (VEA::Encode()) to output of the
// corresponding BitstreamBuffer (VEA::Client::BitstreamBufferReady()).
std::vector<base::TimeDelta> encode_latencies_;
// Ids for output BitstreamBuffers. // Ids for output BitstreamBuffers.
typedef std::map<int32, base::SharedMemory*> IdToSHM; typedef std::map<int32, base::SharedMemory*> IdToSHM;
ScopedVector<base::SharedMemory> output_shms_; ScopedVector<base::SharedMemory> output_shms_;
...@@ -700,9 +743,6 @@ class VEAClient : public VideoEncodeAccelerator::Client { ...@@ -700,9 +743,6 @@ class VEAClient : public VideoEncodeAccelerator::Client {
scoped_ptr<StreamValidator> validator_; scoped_ptr<StreamValidator> validator_;
// The time when the encoding started.
base::TimeTicks encode_start_time_;
// The time when the last encoded frame is ready. // The time when the last encoded frame is ready.
base::TimeTicks last_frame_ready_time_; base::TimeTicks last_frame_ready_time_;
...@@ -723,11 +763,6 @@ class VEAClient : public VideoEncodeAccelerator::Client { ...@@ -723,11 +763,6 @@ class VEAClient : public VideoEncodeAccelerator::Client {
// The timer used to feed the encoder with the input frames. // The timer used to feed the encoder with the input frames.
scoped_ptr<base::RepeatingTimer<VEAClient>> input_timer_; scoped_ptr<base::RepeatingTimer<VEAClient>> input_timer_;
// Feed the encoder with the input buffers at the |requested_framerate_|. If
// false, feed as fast as possible. This is set by the command line switch
// "--run_at_fps".
bool run_at_fps_;
}; };
VEAClient::VEAClient(TestStream* test_stream, VEAClient::VEAClient(TestStream* test_stream,
...@@ -737,8 +772,7 @@ VEAClient::VEAClient(TestStream* test_stream, ...@@ -737,8 +772,7 @@ VEAClient::VEAClient(TestStream* test_stream,
bool force_bitrate, bool force_bitrate,
bool test_perf, bool test_perf,
bool mid_stream_bitrate_switch, bool mid_stream_bitrate_switch,
bool mid_stream_framerate_switch, bool mid_stream_framerate_switch)
bool run_at_fps)
: state_(CS_CREATED), : state_(CS_CREATED),
test_stream_(test_stream), test_stream_(test_stream),
note_(note), note_(note),
...@@ -763,8 +797,7 @@ VEAClient::VEAClient(TestStream* test_stream, ...@@ -763,8 +797,7 @@ VEAClient::VEAClient(TestStream* test_stream,
requested_bitrate_(0), requested_bitrate_(0),
requested_framerate_(0), requested_framerate_(0),
requested_subsequent_bitrate_(0), requested_subsequent_bitrate_(0),
requested_subsequent_framerate_(0), requested_subsequent_framerate_(0) {
run_at_fps_(run_at_fps) {
if (keyframe_period_) if (keyframe_period_)
CHECK_LT(kMaxKeyframeDelay, keyframe_period_); CHECK_LT(kMaxKeyframeDelay, keyframe_period_);
...@@ -907,7 +940,8 @@ void VEAClient::UpdateTestStreamData(bool mid_stream_bitrate_switch, ...@@ -907,7 +940,8 @@ void VEAClient::UpdateTestStreamData(bool mid_stream_bitrate_switch,
} }
double VEAClient::frames_per_second() { double VEAClient::frames_per_second() {
base::TimeDelta duration = last_frame_ready_time_ - encode_start_time_; CHECK(!encode_start_time_.empty());
base::TimeDelta duration = last_frame_ready_time_ - encode_start_time_[0];
return num_encoded_frames_ / duration.InSecondsF(); return num_encoded_frames_ / duration.InSecondsF();
} }
...@@ -924,6 +958,11 @@ void VEAClient::RequireBitstreamBuffers(unsigned int input_count, ...@@ -924,6 +958,11 @@ void VEAClient::RequireBitstreamBuffers(unsigned int input_count,
if (g_num_frames_to_encode > 0) if (g_num_frames_to_encode > 0)
num_frames_to_encode_ = g_num_frames_to_encode; num_frames_to_encode_ = g_num_frames_to_encode;
// Speed up vector insertion.
encode_start_time_.reserve(num_frames_to_encode_);
if (g_env->needs_encode_latency())
encode_latencies_.reserve(num_frames_to_encode_);
// We may need to loop over the stream more than once if more frames than // We may need to loop over the stream more than once if more frames than
// provided is required for bitrate tests. // provided is required for bitrate tests.
if (force_bitrate_ && num_frames_to_encode_ < kMinFramesForBitrateTests) { if (force_bitrate_ && num_frames_to_encode_ < kMinFramesForBitrateTests) {
...@@ -949,8 +988,7 @@ void VEAClient::RequireBitstreamBuffers(unsigned int input_count, ...@@ -949,8 +988,7 @@ void VEAClient::RequireBitstreamBuffers(unsigned int input_count,
FeedEncoderWithOutput(shm); FeedEncoderWithOutput(shm);
} }
encode_start_time_ = base::TimeTicks::Now(); if (g_env->run_at_fps()) {
if (run_at_fps_) {
input_timer_.reset(new base::RepeatingTimer<VEAClient>()); input_timer_.reset(new base::RepeatingTimer<VEAClient>());
input_timer_->Start( input_timer_->Start(
FROM_HERE, base::TimeDelta::FromSeconds(1) / current_framerate_, FROM_HERE, base::TimeDelta::FromSeconds(1) / current_framerate_,
...@@ -1030,11 +1068,12 @@ void VEAClient::InputNoLongerNeededCallback(int32 input_id) { ...@@ -1030,11 +1068,12 @@ void VEAClient::InputNoLongerNeededCallback(int32 input_id) {
std::set<int32>::iterator it = inputs_at_client_.find(input_id); std::set<int32>::iterator it = inputs_at_client_.find(input_id);
ASSERT_NE(it, inputs_at_client_.end()); ASSERT_NE(it, inputs_at_client_.end());
inputs_at_client_.erase(it); inputs_at_client_.erase(it);
if (!run_at_fps_) if (!g_env->run_at_fps())
FeedEncoderWithOneInput(); FeedEncoderWithOneInput();
} }
scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame(off_t position) { scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame(off_t position,
int32* input_id) {
CHECK_LE(position + test_stream_->aligned_buffer_size, CHECK_LE(position + test_stream_->aligned_buffer_size,
test_stream_->mapped_aligned_in_file.length()); test_stream_->mapped_aligned_in_file.length());
...@@ -1065,8 +1104,8 @@ scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame(off_t position) { ...@@ -1065,8 +1104,8 @@ scoped_refptr<media::VideoFrame> VEAClient::PrepareInputFrame(off_t position) {
next_input_id_))); next_input_id_)));
CHECK(inputs_at_client_.insert(next_input_id_).second); CHECK(inputs_at_client_.insert(next_input_id_).second);
++next_input_id_;
*input_id = next_input_id_++;
return frame; return frame;
} }
...@@ -1095,16 +1134,19 @@ void VEAClient::FeedEncoderWithOneInput() { ...@@ -1095,16 +1134,19 @@ void VEAClient::FeedEncoderWithOneInput() {
pos_in_input_stream_ = 0; pos_in_input_stream_ = 0;
} }
int32 input_id;
scoped_refptr<media::VideoFrame> video_frame =
PrepareInputFrame(pos_in_input_stream_, &input_id);
pos_in_input_stream_ += test_stream_->aligned_buffer_size;
bool force_keyframe = false; bool force_keyframe = false;
if (keyframe_period_ && next_input_id_ % keyframe_period_ == 0) { if (keyframe_period_ && input_id % keyframe_period_ == 0) {
force_keyframe = true; force_keyframe = true;
++num_keyframes_requested_; ++num_keyframes_requested_;
} }
scoped_refptr<media::VideoFrame> video_frame = CHECK_EQ(input_id, static_cast<int32>(encode_start_time_.size()));
PrepareInputFrame(pos_in_input_stream_); encode_start_time_.push_back(base::TimeTicks::Now());
pos_in_input_stream_ += test_stream_->aligned_buffer_size;
encoder_->Encode(video_frame, force_keyframe); encoder_->Encode(video_frame, force_keyframe);
} }
...@@ -1130,11 +1172,18 @@ bool VEAClient::HandleEncodedFrame(bool keyframe) { ...@@ -1130,11 +1172,18 @@ bool VEAClient::HandleEncodedFrame(bool keyframe) {
// return value from this method. // return value from this method.
CHECK_LE(num_encoded_frames_, num_frames_to_encode_); CHECK_LE(num_encoded_frames_, num_frames_to_encode_);
last_frame_ready_time_ = base::TimeTicks::Now();
if (g_env->needs_encode_latency()) {
CHECK_LT(num_encoded_frames_, encode_start_time_.size());
base::TimeTicks start_time = encode_start_time_[num_encoded_frames_];
CHECK(!start_time.is_null());
encode_latencies_.push_back(last_frame_ready_time_ - start_time);
}
++num_encoded_frames_; ++num_encoded_frames_;
++num_frames_since_last_check_; ++num_frames_since_last_check_;
last_frame_ready_time_ = base::TimeTicks::Now();
// Because the keyframe behavior requirements are loose, we give // Because the keyframe behavior requirements are loose, we give
// the encoder more freedom here. It could either deliver a keyframe // the encoder more freedom here. It could either deliver a keyframe
// immediately after we requested it, which could be for a frame number // immediately after we requested it, which could be for a frame number
...@@ -1163,13 +1212,14 @@ bool VEAClient::HandleEncodedFrame(bool keyframe) { ...@@ -1163,13 +1212,14 @@ bool VEAClient::HandleEncodedFrame(bool keyframe) {
requested_subsequent_framerate_ != current_framerate_) { requested_subsequent_framerate_ != current_framerate_) {
SetStreamParameters(requested_subsequent_bitrate_, SetStreamParameters(requested_subsequent_bitrate_,
requested_subsequent_framerate_); requested_subsequent_framerate_);
if (run_at_fps_ && input_timer_) if (g_env->run_at_fps() && input_timer_)
input_timer_->Start( input_timer_->Start(
FROM_HERE, base::TimeDelta::FromSeconds(1) / current_framerate_, FROM_HERE, base::TimeDelta::FromSeconds(1) / current_framerate_,
base::Bind(&VEAClient::OnInputTimer, base::Unretained(this))); base::Bind(&VEAClient::OnInputTimer, base::Unretained(this)));
} }
} else if (num_encoded_frames_ == num_frames_to_encode_) { } else if (num_encoded_frames_ == num_frames_to_encode_) {
VerifyPerf(); LogPerf();
VerifyMinFPS();
VerifyStreamProperties(); VerifyStreamProperties();
SetState(CS_FINISHED); SetState(CS_FINISHED);
return false; return false;
...@@ -1178,13 +1228,26 @@ bool VEAClient::HandleEncodedFrame(bool keyframe) { ...@@ -1178,13 +1228,26 @@ bool VEAClient::HandleEncodedFrame(bool keyframe) {
return true; return true;
} }
void VEAClient::VerifyPerf() { void VEAClient::LogPerf() {
double measured_fps = frames_per_second();
LOG(INFO) << "Measured encoder FPS: " << measured_fps;
g_env->LogToFile("Measured encoder FPS", g_env->LogToFile("Measured encoder FPS",
base::StringPrintf("%.3f", measured_fps)); base::StringPrintf("%.3f", frames_per_second()));
// Log encode latencies.
if (g_env->needs_encode_latency()) {
std::sort(encode_latencies_.begin(), encode_latencies_.end());
for (const auto& percentile : kLoggedLatencyPercentiles) {
base::TimeDelta latency = Percentile(encode_latencies_, percentile);
g_env->LogToFile(
base::StringPrintf("Encode latency for the %dth percentile",
percentile),
base::StringPrintf("%" PRId64 " us", latency.InMicroseconds()));
}
}
}
void VEAClient::VerifyMinFPS() {
if (test_perf_) if (test_perf_)
EXPECT_GE(measured_fps, kMinPerfFPS); EXPECT_GE(frames_per_second(), kMinPerfFPS);
} }
void VEAClient::VerifyStreamProperties() { void VEAClient::VerifyStreamProperties() {
...@@ -1291,11 +1354,10 @@ TEST_P(VideoEncodeAcceleratorTest, TestSimpleEncode) { ...@@ -1291,11 +1354,10 @@ TEST_P(VideoEncodeAcceleratorTest, TestSimpleEncode) {
!g_env->test_streams_[test_stream_index]->out_filename.empty()); !g_env->test_streams_[test_stream_index]->out_filename.empty());
notes.push_back(new ClientStateNotification<ClientState>()); notes.push_back(new ClientStateNotification<ClientState>());
clients.push_back( clients.push_back(new VEAClient(
new VEAClient(g_env->test_streams_[test_stream_index], notes.back(), g_env->test_streams_[test_stream_index], notes.back(),
encoder_save_to_file, keyframe_period, force_bitrate, encoder_save_to_file, keyframe_period, force_bitrate, test_perf,
test_perf, mid_stream_bitrate_switch, mid_stream_bitrate_switch, mid_stream_framerate_switch));
mid_stream_framerate_switch, g_env->run_at_fps_));
encoder_thread.message_loop()->PostTask( encoder_thread.message_loop()->PostTask(
FROM_HERE, FROM_HERE,
...@@ -1395,6 +1457,7 @@ int main(int argc, char** argv) { ...@@ -1395,6 +1457,7 @@ int main(int argc, char** argv) {
DCHECK(cmd_line); DCHECK(cmd_line);
bool run_at_fps = false; bool run_at_fps = false;
bool needs_encode_latency = false;
base::FilePath log_path; base::FilePath log_path;
base::CommandLine::SwitchMap switches = cmd_line->GetSwitches(); base::CommandLine::SwitchMap switches = cmd_line->GetSwitches();
...@@ -1416,6 +1479,10 @@ int main(int argc, char** argv) { ...@@ -1416,6 +1479,10 @@ int main(int argc, char** argv) {
CHECK(base::StringToInt(input, &content::g_num_frames_to_encode)); CHECK(base::StringToInt(input, &content::g_num_frames_to_encode));
continue; continue;
} }
if (it->first == "measure_latency") {
needs_encode_latency = true;
continue;
}
if (it->first == "fake_encoder") { if (it->first == "fake_encoder") {
content::g_fake_encoder = true; content::g_fake_encoder = true;
continue; continue;
...@@ -1431,6 +1498,13 @@ int main(int argc, char** argv) { ...@@ -1431,6 +1498,13 @@ int main(int argc, char** argv) {
LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second;
} }
if (needs_encode_latency && !run_at_fps) {
// Encode latency can only be measured with --run_at_fps. Otherwise, we get
// skewed results since it may queue too many frames at once with the same
// encode start time.
LOG(FATAL) << "--measure_latency requires --run_at_fps enabled to work.";
}
#if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
content::VaapiWrapper::PreSandboxInitialization(); content::VaapiWrapper::PreSandboxInitialization();
#endif #endif
...@@ -1439,7 +1513,8 @@ int main(int argc, char** argv) { ...@@ -1439,7 +1513,8 @@ int main(int argc, char** argv) {
reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>( reinterpret_cast<content::VideoEncodeAcceleratorTestEnvironment*>(
testing::AddGlobalTestEnvironment( testing::AddGlobalTestEnvironment(
new content::VideoEncodeAcceleratorTestEnvironment( new content::VideoEncodeAcceleratorTestEnvironment(
test_stream_data.Pass(), log_path, run_at_fps))); test_stream_data.Pass(), log_path, run_at_fps,
needs_encode_latency)));
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment