| Index: content/common/gpu/media/video_decode_accelerator_unittest.cc
|
| diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc
|
| index dc08fb112bf518564fde919ee16ad91b0a44dd5b..528acb9eb844951ba04d0bcbcbfeac43b9d3bc0c 100644
|
| --- a/content/common/gpu/media/video_decode_accelerator_unittest.cc
|
| +++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc
|
| @@ -18,6 +18,7 @@
|
| #include <math.h>
|
| #include <sys/stat.h>
|
| #include <sys/types.h>
|
| +#include <deque>
|
|
|
| // Include gtest.h out of order because <X11/X.h> #define's Bool & None, which
|
| // gtest uses as struct names (inside a namespace). This means that
|
| @@ -82,13 +83,19 @@ namespace {
|
| // (the latter tests just decode speed).
|
| // - |profile| is the media::VideoCodecProfile set during Initialization.
|
| // An empty value for a numeric field means "ignore".
|
| -const base::FilePath::CharType* test_video_data =
|
| +const base::FilePath::CharType* g_test_video_data =
|
| // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11");
|
| FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1");
|
|
|
| // The path of the frame delivery time log. We can enable the log and specify
|
| // the filename by the "--frame_delivery_log" switch.
|
| -const base::FilePath::CharType* frame_delivery_log = NULL;
|
| +const base::FilePath::CharType* g_frame_delivery_log = NULL;
|
| +
|
| +// The value is set by the switch "--rendering_fps".
|
| +double g_rendering_fps = 0;
|
| +
|
| +// Disable rendering, the value is set by the switch "--disable_rendering".
|
| +bool g_disable_rendering = false;
|
|
|
| // Magic constants for differentiating the reasons for NotifyResetDone being
|
| // called.
|
| @@ -100,7 +107,7 @@ enum ResetPoint {
|
|
|
| const int kMaxResetAfterFrameNum = 100;
|
| const int kMaxFramesToDelayReuse = 64;
|
| -const int kReuseDelayMs = 1000;
|
| +const base::TimeDelta kReuseDelay = base::TimeDelta::FromSeconds(1);
|
|
|
| struct TestVideoFile {
|
| explicit TestVideoFile(base::FilePath::StringType file_name)
|
| @@ -223,11 +230,10 @@ enum ClientState {
|
| CS_INITIALIZED = 2,
|
| CS_FLUSHING = 3,
|
| CS_FLUSHED = 4,
|
| - CS_DONE = 5,
|
| - CS_RESETTING = 6,
|
| - CS_RESET = 7,
|
| - CS_ERROR = 8,
|
| - CS_DESTROYED = 9,
|
| + CS_RESETTING = 5,
|
| + CS_RESET = 6,
|
| + CS_ERROR = 7,
|
| + CS_DESTROYED = 8,
|
| CS_MAX, // Must be last entry.
|
| };
|
|
|
| @@ -269,6 +275,157 @@ ClientState ClientStateNotification::Wait() {
|
| return ret;
|
| }
|
|
|
| +// A wrapper client that throttles the PictureReady callbacks to a given rate.
|
| +// It may drops or queues frame to deliver them on time.
|
| +class ThrottlingVDAClient : public VideoDecodeAccelerator::Client,
|
| + public base::SupportsWeakPtr<ThrottlingVDAClient> {
|
| + public:
|
| + // Callback invoked whan the picture is dropped and should be reused for
|
| + // the decoder again.
|
| + typedef base::Callback<void(int32 picture_buffer_id)> ReusePictureCB;
|
| +
|
| + ThrottlingVDAClient(VideoDecodeAccelerator::Client* client,
|
| + double fps,
|
| + ReusePictureCB reuse_picture_cb);
|
| + virtual ~ThrottlingVDAClient();
|
| +
|
| + // VideoDecodeAccelerator::Client implementation
|
| + virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers,
|
| + const gfx::Size& dimensions,
|
| + uint32 texture_target) OVERRIDE;
|
| + virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE;
|
| + virtual void PictureReady(const media::Picture& picture) OVERRIDE;
|
| + virtual void NotifyInitializeDone() OVERRIDE;
|
| + virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE;
|
| + virtual void NotifyFlushDone() OVERRIDE;
|
| + virtual void NotifyResetDone() OVERRIDE;
|
| + virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE;
|
| +
|
| + int num_decoded_frames() { return num_decoded_frames_; }
|
| +
|
| + private:
|
| +
|
| + void CallClientPictureReady(int version);
|
| +
|
| + VideoDecodeAccelerator::Client* client_;
|
| + ReusePictureCB reuse_picture_cb_;
|
| + base::TimeTicks next_frame_delivered_time_;
|
| + base::TimeDelta frame_duration_;
|
| +
|
| + int num_decoded_frames_;
|
| + int stream_version_;
|
| + std::deque<media::Picture> pending_pictures_;
|
| +
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(ThrottlingVDAClient);
|
| +};
|
| +
|
| +ThrottlingVDAClient::ThrottlingVDAClient(VideoDecodeAccelerator::Client* client,
|
| + double fps,
|
| + ReusePictureCB reuse_picture_cb)
|
| + : client_(client),
|
| + reuse_picture_cb_(reuse_picture_cb),
|
| + num_decoded_frames_(0),
|
| + stream_version_(0) {
|
| + CHECK(client_);
|
| + CHECK_GT(fps, 0);
|
| + frame_duration_ = base::TimeDelta::FromSeconds(1) / fps;
|
| +}
|
| +
|
| +ThrottlingVDAClient::~ThrottlingVDAClient() {}
|
| +
|
| +void ThrottlingVDAClient::ProvidePictureBuffers(uint32 requested_num_of_buffers,
|
| + const gfx::Size& dimensions,
|
| + uint32 texture_target) {
|
| + client_->ProvidePictureBuffers(
|
| + requested_num_of_buffers, dimensions, texture_target);
|
| +}
|
| +
|
| +void ThrottlingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) {
|
| + client_->DismissPictureBuffer(picture_buffer_id);
|
| +}
|
| +
|
| +void ThrottlingVDAClient::PictureReady(const media::Picture& picture) {
|
| + ++num_decoded_frames_;
|
| +
|
| + if (pending_pictures_.empty()) {
|
| + base::TimeDelta delay =
|
| + next_frame_delivered_time_.is_null()
|
| + ? base::TimeDelta()
|
| + : next_frame_delivered_time_ - base::TimeTicks::Now();
|
| + base::MessageLoop::current()->PostDelayedTask(
|
| + FROM_HERE,
|
| + base::Bind(&ThrottlingVDAClient::CallClientPictureReady,
|
| + AsWeakPtr(),
|
| + stream_version_),
|
| + delay);
|
| + }
|
| + pending_pictures_.push_back(picture);
|
| +}
|
| +
|
| +void ThrottlingVDAClient::CallClientPictureReady(int version) {
|
| + // Just return if we have reset the decoder
|
| + if (version != stream_version_)
|
| + return;
|
| +
|
| + base::TimeTicks now = base::TimeTicks::Now();
|
| +
|
| + if (next_frame_delivered_time_.is_null())
|
| + next_frame_delivered_time_ = now;
|
| +
|
| + if (next_frame_delivered_time_ + frame_duration_ < now) {
|
| + // Too late, drop the frame
|
| + reuse_picture_cb_.Run(pending_pictures_.front().picture_buffer_id());
|
| + } else {
|
| + client_->PictureReady(pending_pictures_.front());
|
| + }
|
| +
|
| + pending_pictures_.pop_front();
|
| + next_frame_delivered_time_ += frame_duration_;
|
| + if (!pending_pictures_.empty()) {
|
| + base::MessageLoop::current()->PostDelayedTask(
|
| + FROM_HERE,
|
| + base::Bind(&ThrottlingVDAClient::CallClientPictureReady,
|
| + AsWeakPtr(),
|
| + stream_version_),
|
| + next_frame_delivered_time_ - base::TimeTicks::Now());
|
| + }
|
| +}
|
| +
|
| +void ThrottlingVDAClient::NotifyInitializeDone() {
|
| + client_->NotifyInitializeDone();
|
| +}
|
| +
|
| +void ThrottlingVDAClient::NotifyEndOfBitstreamBuffer(
|
| + int32 bitstream_buffer_id) {
|
| + client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
|
| +}
|
| +
|
| +void ThrottlingVDAClient::NotifyFlushDone() {
|
| + if (!pending_pictures_.empty()) {
|
| + base::MessageLoop::current()->PostDelayedTask(
|
| + FROM_HERE,
|
| + base::Bind(&ThrottlingVDAClient::NotifyFlushDone,
|
| + base::Unretained(this)),
|
| + next_frame_delivered_time_ - base::TimeTicks::Now());
|
| + return;
|
| + }
|
| + client_->NotifyFlushDone();
|
| +}
|
| +
|
| +void ThrottlingVDAClient::NotifyResetDone() {
|
| + ++stream_version_;
|
| + while (!pending_pictures_.empty()) {
|
| + reuse_picture_cb_.Run(pending_pictures_.front().picture_buffer_id());
|
| + pending_pictures_.pop_front();
|
| + }
|
| + next_frame_delivered_time_ = base::TimeTicks();
|
| + client_->NotifyResetDone();
|
| +}
|
| +
|
| +void ThrottlingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) {
|
| + client_->NotifyError(error);
|
| +}
|
| +
|
| // Client that can accept callbacks from a VideoDecodeAccelerator and is used by
|
| // the TESTs below.
|
| class GLRenderingVDAClient : public VideoDecodeAccelerator::Client {
|
| @@ -285,8 +442,11 @@ class GLRenderingVDAClient : public VideoDecodeAccelerator::Client {
|
| // calls have been made, N>=0 means interpret as ClientState.
|
| // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the
|
| // last play-through (governed by |num_play_throughs|).
|
| + // |rendering_fps| indicates the target rendering fps. 0 means no target fps
|
| + // and it would render as fast as possible.
|
| + // |suppress_rendering| indicates GL rendering is suppressed or not.
|
| // After |delay_reuse_after_frame_num| frame has been delivered, the client
|
| - // will start delaying the call to ReusePictureBuffer() for kReuseDelayMs.
|
| + // will start delaying the call to ReusePictureBuffer() for kReuseDelay.
|
| GLRenderingVDAClient(RenderingHelper* rendering_helper,
|
| int rendering_window_id,
|
| ClientStateNotification* note,
|
| @@ -299,6 +459,7 @@ class GLRenderingVDAClient : public VideoDecodeAccelerator::Client {
|
| int frame_width,
|
| int frame_height,
|
| int profile,
|
| + double rendering_fps,
|
| bool suppress_rendering,
|
| int delay_reuse_after_frame_num);
|
| virtual ~GLRenderingVDAClient();
|
| @@ -320,11 +481,13 @@ class GLRenderingVDAClient : public VideoDecodeAccelerator::Client {
|
|
|
| void OutputFrameDeliveryTimes(base::PlatformFile output);
|
|
|
| + void NotifyFrameDropped(int32 picture_buffer_id);
|
| +
|
| // Simple getters for inspecting the state of the Client.
|
| int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; }
|
| int num_skipped_fragments() { return num_skipped_fragments_; }
|
| int num_queued_fragments() { return num_queued_fragments_; }
|
| - int num_decoded_frames() { return num_decoded_frames_; }
|
| + int num_decoded_frames();
|
| double frames_per_second();
|
| bool decoder_deleted() { return !decoder_.get(); }
|
|
|
| @@ -376,42 +539,56 @@ class GLRenderingVDAClient : public VideoDecodeAccelerator::Client {
|
| bool suppress_rendering_;
|
| std::vector<base::TimeTicks> frame_delivery_times_;
|
| int delay_reuse_after_frame_num_;
|
| + scoped_ptr<ThrottlingVDAClient> throttling_client_;
|
| +
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient);
|
| };
|
|
|
| -GLRenderingVDAClient::GLRenderingVDAClient(
|
| - RenderingHelper* rendering_helper,
|
| - int rendering_window_id,
|
| - ClientStateNotification* note,
|
| - const std::string& encoded_data,
|
| - int num_fragments_per_decode,
|
| - int num_in_flight_decodes,
|
| - int num_play_throughs,
|
| - int reset_after_frame_num,
|
| - int delete_decoder_state,
|
| - int frame_width,
|
| - int frame_height,
|
| - int profile,
|
| - bool suppress_rendering,
|
| - int delay_reuse_after_frame_num)
|
| +GLRenderingVDAClient::GLRenderingVDAClient(RenderingHelper* rendering_helper,
|
| + int rendering_window_id,
|
| + ClientStateNotification* note,
|
| + const std::string& encoded_data,
|
| + int num_fragments_per_decode,
|
| + int num_in_flight_decodes,
|
| + int num_play_throughs,
|
| + int reset_after_frame_num,
|
| + int delete_decoder_state,
|
| + int frame_width,
|
| + int frame_height,
|
| + int profile,
|
| + double rendering_fps,
|
| + bool suppress_rendering,
|
| + int delay_reuse_after_frame_num)
|
| : rendering_helper_(rendering_helper),
|
| rendering_window_id_(rendering_window_id),
|
| encoded_data_(encoded_data),
|
| num_fragments_per_decode_(num_fragments_per_decode),
|
| - num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0),
|
| - encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0),
|
| + num_in_flight_decodes_(num_in_flight_decodes),
|
| + outstanding_decodes_(0),
|
| + encoded_data_next_pos_to_decode_(0),
|
| + next_bitstream_buffer_id_(0),
|
| note_(note),
|
| remaining_play_throughs_(num_play_throughs),
|
| reset_after_frame_num_(reset_after_frame_num),
|
| delete_decoder_state_(delete_decoder_state),
|
| state_(CS_CREATED),
|
| - num_skipped_fragments_(0), num_queued_fragments_(0),
|
| - num_decoded_frames_(0), num_done_bitstream_buffers_(0),
|
| + num_skipped_fragments_(0),
|
| + num_queued_fragments_(0),
|
| + num_decoded_frames_(0),
|
| + num_done_bitstream_buffers_(0),
|
| profile_(profile),
|
| suppress_rendering_(suppress_rendering),
|
| delay_reuse_after_frame_num_(delay_reuse_after_frame_num) {
|
| CHECK_GT(num_fragments_per_decode, 0);
|
| CHECK_GT(num_in_flight_decodes, 0);
|
| CHECK_GT(num_play_throughs, 0);
|
| + CHECK_GE(rendering_fps, 0);
|
| + if (rendering_fps > 0)
|
| + throttling_client_.reset(new ThrottlingVDAClient(
|
| + this,
|
| + rendering_fps,
|
| + base::Bind(&GLRenderingVDAClient::NotifyFrameDropped,
|
| + base::Unretained(this))));
|
| }
|
|
|
| GLRenderingVDAClient::~GLRenderingVDAClient() {
|
| @@ -426,21 +603,26 @@ static bool DoNothingReturnTrue() { return true; }
|
| void GLRenderingVDAClient::CreateDecoder() {
|
| CHECK(decoder_deleted());
|
| CHECK(!decoder_.get());
|
| +
|
| + VideoDecodeAccelerator::Client* client = this;
|
| + if (throttling_client_)
|
| + client = throttling_client_.get();
|
| #if defined(OS_WIN)
|
| - decoder_.reset(new DXVAVideoDecodeAccelerator(
|
| - this, base::Bind(&DoNothingReturnTrue)));
|
| + decoder_.reset(
|
| + new DXVAVideoDecodeAccelerator(client, base::Bind(&DoNothingReturnTrue)));
|
| #elif defined(OS_CHROMEOS)
|
| #if defined(ARCH_CPU_ARMEL)
|
| - decoder_.reset(
|
| - new ExynosVideoDecodeAccelerator(
|
| - static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()),
|
| - static_cast<EGLContext>(rendering_helper_->GetGLContext()),
|
| - this, base::Bind(&DoNothingReturnTrue)));
|
| + decoder_.reset(new ExynosVideoDecodeAccelerator(
|
| + static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()),
|
| + static_cast<EGLContext>(rendering_helper_->GetGLContext()),
|
| + client,
|
| + base::Bind(&DoNothingReturnTrue)));
|
| #elif defined(ARCH_CPU_X86_FAMILY)
|
| decoder_.reset(new VaapiVideoDecodeAccelerator(
|
| static_cast<Display*>(rendering_helper_->GetGLDisplay()),
|
| static_cast<GLXContext>(rendering_helper_->GetGLContext()),
|
| - this, base::Bind(&DoNothingReturnTrue)));
|
| + client,
|
| + base::Bind(&DoNothingReturnTrue)));
|
| #endif // ARCH_CPU_ARMEL
|
| #endif // OS_WIN
|
| CHECK(decoder_.get());
|
| @@ -495,6 +677,7 @@ void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
|
|
|
| if (decoder_deleted())
|
| return;
|
| +
|
| frame_delivery_times_.push_back(base::TimeTicks::Now());
|
|
|
| CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_);
|
| @@ -503,7 +686,7 @@ void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
|
| // Mid-stream reset applies only to the last play-through per constructor
|
| // comment.
|
| if (remaining_play_throughs_ == 1 &&
|
| - reset_after_frame_num_ == num_decoded_frames_) {
|
| + reset_after_frame_num_ == num_decoded_frames()) {
|
| reset_after_frame_num_ = MID_STREAM_RESET;
|
| decoder_->Reset();
|
| // Re-start decoding from the beginning of the stream to avoid needing to
|
| @@ -518,11 +701,13 @@ void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
|
| rendering_helper_->RenderTexture(picture_buffer->texture_id());
|
| }
|
|
|
| - if (num_decoded_frames_ > delay_reuse_after_frame_num_) {
|
| - base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(
|
| - &VideoDecodeAccelerator::ReusePictureBuffer,
|
| - decoder_->AsWeakPtr(), picture.picture_buffer_id()),
|
| - base::TimeDelta::FromMilliseconds(kReuseDelayMs));
|
| + if (num_decoded_frames() > delay_reuse_after_frame_num_) {
|
| + base::MessageLoop::current()->PostDelayedTask(
|
| + FROM_HERE,
|
| + base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer,
|
| + decoder_->AsWeakPtr(),
|
| + picture.picture_buffer_id()),
|
| + kReuseDelay);
|
| } else {
|
| decoder_->ReusePictureBuffer(picture.picture_buffer_id());
|
| }
|
| @@ -609,6 +794,10 @@ void GLRenderingVDAClient::OutputFrameDeliveryTimes(base::PlatformFile output) {
|
| }
|
| }
|
|
|
| +void GLRenderingVDAClient::NotifyFrameDropped(int32 picture_buffer_id) {
|
| + decoder_->ReusePictureBuffer(picture_buffer_id);
|
| +}
|
| +
|
| static bool LookingAtNAL(const std::string& encoded, size_t pos) {
|
| return encoded[pos] == 0 && encoded[pos + 1] == 0 &&
|
| encoded[pos + 2] == 0 && encoded[pos + 3] == 1;
|
| @@ -748,11 +937,16 @@ void GLRenderingVDAClient::DecodeNextFragments() {
|
| }
|
| }
|
|
|
| +int GLRenderingVDAClient::num_decoded_frames() {
|
| + return throttling_client_ ? throttling_client_->num_decoded_frames()
|
| + : num_decoded_frames_;
|
| +}
|
| +
|
| double GLRenderingVDAClient::frames_per_second() {
|
| base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_;
|
| if (delta.InSecondsF() == 0)
|
| return 0;
|
| - return num_decoded_frames_ / delta.InSecondsF();
|
| + return num_decoded_frames() / delta.InSecondsF();
|
| }
|
|
|
| // Test parameters:
|
| @@ -798,9 +992,6 @@ enum { kMinSupportedNumConcurrentDecoders = 3 };
|
| // Test the most straightforward case possible: data is decoded from a single
|
| // chunk and rendered to the screen.
|
| TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
|
| - // Can be useful for debugging VLOGs from OVDA.
|
| - // logging::SetMinLogLevel(-1);
|
| -
|
| // Required for Thread to work. Not used otherwise.
|
| base::ShadowingAtExitManager at_exit_manager;
|
|
|
| @@ -814,13 +1005,16 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
|
| const bool render_as_thumbnails = GetParam().h;
|
|
|
| std::vector<TestVideoFile*> test_video_files;
|
| - ParseAndReadTestVideoData(test_video_data, num_concurrent_decoders,
|
| - reset_point, &test_video_files);
|
| + ParseAndReadTestVideoData(g_test_video_data,
|
| + num_concurrent_decoders,
|
| + reset_point,
|
| + &test_video_files);
|
|
|
| - // Suppress GL rendering when we are logging the frame delivery time and a
|
| - // few other tests, to cut down overall test runtime.
|
| - const bool suppress_rendering = num_fragments_per_decode > 1 ||
|
| - frame_delivery_log != NULL;
|
| + // Suppress GL rendering for all tests when the "--disable_rendering" is set.
|
| + // Otherwise, suppress rendering in all but a few tests, to cut down overall
|
| + // test runtime.
|
| + const bool suppress_rendering =
|
| + num_fragments_per_decode > 1 || g_disable_rendering;
|
|
|
| std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL);
|
| std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL);
|
| @@ -880,12 +1074,22 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
|
| delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse;
|
| }
|
|
|
| - GLRenderingVDAClient* client = new GLRenderingVDAClient(
|
| - rendering_helper.get(), index, note, video_file->data_str,
|
| - num_fragments_per_decode, num_in_flight_decodes, num_play_throughs,
|
| - video_file->reset_after_frame_num, delete_decoder_state,
|
| - video_file->width, video_file->height, video_file->profile,
|
| - suppress_rendering, delay_after_frame_num);
|
| + GLRenderingVDAClient* client =
|
| + new GLRenderingVDAClient(rendering_helper.get(),
|
| + index,
|
| + note,
|
| + video_file->data_str,
|
| + num_fragments_per_decode,
|
| + num_in_flight_decodes,
|
| + num_play_throughs,
|
| + video_file->reset_after_frame_num,
|
| + delete_decoder_state,
|
| + video_file->width,
|
| + video_file->height,
|
| + video_file->profile,
|
| + g_rendering_fps,
|
| + suppress_rendering,
|
| + delay_after_frame_num);
|
| clients[index] = client;
|
|
|
| rendering_thread.message_loop()->PostTask(
|
| @@ -1011,9 +1215,9 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
|
| // Output the frame delivery time to file
|
| // We can only make performance/correctness assertions if the decoder was
|
| // allowed to finish.
|
| - if (frame_delivery_log != NULL && delete_decoder_state >= CS_FLUSHED) {
|
| + if (g_frame_delivery_log != NULL && delete_decoder_state >= CS_FLUSHED) {
|
| base::PlatformFile output_file = base::CreatePlatformFile(
|
| - base::FilePath(frame_delivery_log),
|
| + base::FilePath(g_frame_delivery_log),
|
| base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE,
|
| NULL,
|
| NULL);
|
| @@ -1153,11 +1357,22 @@ int main(int argc, char **argv) {
|
| for (CommandLine::SwitchMap::const_iterator it = switches.begin();
|
| it != switches.end(); ++it) {
|
| if (it->first == "test_video_data") {
|
| - content::test_video_data = it->second.c_str();
|
| + content::g_test_video_data = it->second.c_str();
|
| continue;
|
| }
|
| if (it->first == "frame_delivery_log") {
|
| - content::frame_delivery_log = it->second.c_str();
|
| + content::g_frame_delivery_log = it->second.c_str();
|
| + continue;
|
| + }
|
| + if (it->first == "rendering_fps") {
|
| + // On Windows, CommandLine::StringType is wstring. We need to convert
|
| + // it to std::string first
|
| + std::string input(it->second.begin(), it->second.end());
|
| + CHECK(base::StringToDouble(input, &content::g_rendering_fps));
|
| + continue;
|
| + }
|
| + if (it->first == "disable_rendering") {
|
| + content::g_disable_rendering = true;
|
| continue;
|
| }
|
| if (it->first == "v" || it->first == "vmodule")
|
|
|