OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // The bulk of this file is support code; sorry about that. Here's an overview | 5 // The bulk of this file is support code; sorry about that. Here's an overview |
6 // to hopefully help readers of this code: | 6 // to hopefully help readers of this code: |
7 // - RenderingHelper is charged with interacting with X11/{EGL/GLES2,GLX/GL} or | 7 // - RenderingHelper is charged with interacting with X11/{EGL/GLES2,GLX/GL} or |
8 // Win/EGL. | 8 // Win/EGL. |
9 // - ClientState is an enum for the state of the decode client used by the test. | 9 // - ClientState is an enum for the state of the decode client used by the test. |
10 // - ClientStateNotification is a barrier abstraction that allows the test code | 10 // - ClientStateNotification is a barrier abstraction that allows the test code |
11 // to be written sequentially and wait for the decode client to see certain | 11 // to be written sequentially and wait for the decode client to see certain |
12 // state transitions. | 12 // state transitions. |
13 // - GLRenderingVDAClient is a VideoDecodeAccelerator::Client implementation | 13 // - GLRenderingVDAClient is a VideoDecodeAccelerator::Client implementation |
14 // - Finally actual TEST cases are at the bottom of this file, using the above | 14 // - Finally actual TEST cases are at the bottom of this file, using the above |
15 // infrastructure. | 15 // infrastructure. |
16 | 16 |
17 #include <fcntl.h> | 17 #include <fcntl.h> |
18 #include <math.h> | 18 #include <math.h> |
19 #include <sys/stat.h> | 19 #include <sys/stat.h> |
20 #include <sys/types.h> | 20 #include <sys/types.h> |
| 21 #include <deque> |
21 | 22 |
22 // Include gtest.h out of order because <X11/X.h> #define's Bool & None, which | 23 // Include gtest.h out of order because <X11/X.h> #define's Bool & None, which |
23 // gtest uses as struct names (inside a namespace). This means that | 24 // gtest uses as struct names (inside a namespace). This means that |
24 // #include'ing gtest after anything that pulls in X.h fails to compile. | 25 // #include'ing gtest after anything that pulls in X.h fails to compile. |
25 // This is http://code.google.com/p/googletest/issues/detail?id=371 | 26 // This is http://code.google.com/p/googletest/issues/detail?id=371 |
26 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
27 | 28 |
28 #include "base/at_exit.h" | 29 #include "base/at_exit.h" |
29 #include "base/bind.h" | 30 #include "base/bind.h" |
30 #include "base/command_line.h" | 31 #include "base/command_line.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 // where only the first field is required. Value details: | 76 // where only the first field is required. Value details: |
76 // - |filename| must be an h264 Annex B (NAL) stream or an IVF VP8 stream. | 77 // - |filename| must be an h264 Annex B (NAL) stream or an IVF VP8 stream. |
77 // - |width| and |height| are in pixels. | 78 // - |width| and |height| are in pixels. |
78 // - |numframes| is the number of picture frames in the file. | 79 // - |numframes| is the number of picture frames in the file. |
79 // - |numfragments| NALU (h264) or frame (VP8) count in the stream. | 80 // - |numfragments| NALU (h264) or frame (VP8) count in the stream. |
80 // - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds | 81 // - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds |
81 // expected to be achieved with and without rendering to the screen, resp. | 82 // expected to be achieved with and without rendering to the screen, resp. |
82 // (the latter tests just decode speed). | 83 // (the latter tests just decode speed). |
83 // - |profile| is the media::VideoCodecProfile set during Initialization. | 84 // - |profile| is the media::VideoCodecProfile set during Initialization. |
84 // An empty value for a numeric field means "ignore". | 85 // An empty value for a numeric field means "ignore". |
85 const base::FilePath::CharType* test_video_data = | 86 const base::FilePath::CharType* g_test_video_data = |
86 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); | 87 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); |
87 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); | 88 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); |
88 | 89 |
89 // The path of the frame delivery time log. We can enable the log and specify | 90 // The path of the frame delivery time log. We can enable the log and specify |
90 // the filename by the "--frame_delivery_log" switch. | 91 // the filename by the "--frame_delivery_log" switch. |
91 const base::FilePath::CharType* frame_delivery_log = NULL; | 92 const base::FilePath::CharType* g_frame_delivery_log = NULL; |
| 93 |
| 94 // The value is set by the switch "--rendering_fps". |
| 95 double g_rendering_fps = 0; |
| 96 |
| 97 // Disable rendering, the value is set by the switch "--disable_rendering". |
| 98 bool g_disable_rendering = false; |
92 | 99 |
93 // Magic constants for differentiating the reasons for NotifyResetDone being | 100 // Magic constants for differentiating the reasons for NotifyResetDone being |
94 // called. | 101 // called. |
95 enum ResetPoint { | 102 enum ResetPoint { |
96 START_OF_STREAM_RESET = -3, | 103 START_OF_STREAM_RESET = -3, |
97 MID_STREAM_RESET = -2, | 104 MID_STREAM_RESET = -2, |
98 END_OF_STREAM_RESET = -1 | 105 END_OF_STREAM_RESET = -1 |
99 }; | 106 }; |
100 | 107 |
101 const int kMaxResetAfterFrameNum = 100; | 108 const int kMaxResetAfterFrameNum = 100; |
102 const int kMaxFramesToDelayReuse = 64; | 109 const int kMaxFramesToDelayReuse = 64; |
103 const int kReuseDelayMs = 1000; | 110 const base::TimeDelta kReuseDelay = base::TimeDelta::FromSeconds(1); |
104 | 111 |
105 struct TestVideoFile { | 112 struct TestVideoFile { |
106 explicit TestVideoFile(base::FilePath::StringType file_name) | 113 explicit TestVideoFile(base::FilePath::StringType file_name) |
107 : file_name(file_name), | 114 : file_name(file_name), |
108 width(-1), | 115 width(-1), |
109 height(-1), | 116 height(-1), |
110 num_frames(-1), | 117 num_frames(-1), |
111 num_fragments(-1), | 118 num_fragments(-1), |
112 min_fps_render(-1), | 119 min_fps_render(-1), |
113 min_fps_no_render(-1), | 120 min_fps_no_render(-1), |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 } | 223 } |
217 | 224 |
218 // State of the GLRenderingVDAClient below. Order matters here as the test | 225 // State of the GLRenderingVDAClient below. Order matters here as the test |
219 // makes assumptions about it. | 226 // makes assumptions about it. |
220 enum ClientState { | 227 enum ClientState { |
221 CS_CREATED = 0, | 228 CS_CREATED = 0, |
222 CS_DECODER_SET = 1, | 229 CS_DECODER_SET = 1, |
223 CS_INITIALIZED = 2, | 230 CS_INITIALIZED = 2, |
224 CS_FLUSHING = 3, | 231 CS_FLUSHING = 3, |
225 CS_FLUSHED = 4, | 232 CS_FLUSHED = 4, |
226 CS_DONE = 5, | 233 CS_RESETTING = 5, |
227 CS_RESETTING = 6, | 234 CS_RESET = 6, |
228 CS_RESET = 7, | 235 CS_ERROR = 7, |
229 CS_ERROR = 8, | 236 CS_DESTROYED = 8, |
230 CS_DESTROYED = 9, | |
231 CS_MAX, // Must be last entry. | 237 CS_MAX, // Must be last entry. |
232 }; | 238 }; |
233 | 239 |
234 // Helper class allowing one thread to wait on a notification from another. | 240 // Helper class allowing one thread to wait on a notification from another. |
235 // If notifications come in faster than they are Wait()'d for, they are | 241 // If notifications come in faster than they are Wait()'d for, they are |
236 // accumulated (so exactly as many Wait() calls will unblock as Notify() calls | 242 // accumulated (so exactly as many Wait() calls will unblock as Notify() calls |
237 // were made, regardless of order). | 243 // were made, regardless of order). |
238 class ClientStateNotification { | 244 class ClientStateNotification { |
239 public: | 245 public: |
240 ClientStateNotification(); | 246 ClientStateNotification(); |
(...skipping 21 matching lines...) Expand all Loading... |
262 | 268 |
263 ClientState ClientStateNotification::Wait() { | 269 ClientState ClientStateNotification::Wait() { |
264 base::AutoLock auto_lock(lock_); | 270 base::AutoLock auto_lock(lock_); |
265 while (pending_states_for_notification_.empty()) | 271 while (pending_states_for_notification_.empty()) |
266 cv_.Wait(); | 272 cv_.Wait(); |
267 ClientState ret = pending_states_for_notification_.front(); | 273 ClientState ret = pending_states_for_notification_.front(); |
268 pending_states_for_notification_.pop(); | 274 pending_states_for_notification_.pop(); |
269 return ret; | 275 return ret; |
270 } | 276 } |
271 | 277 |
| 278 // A wrapper client that throttles the PictureReady callbacks to a given rate. |
| 279 // It may drops or queues frame to deliver them on time. |
| 280 class ThrottlingVDAClient : public VideoDecodeAccelerator::Client, |
| 281 public base::SupportsWeakPtr<ThrottlingVDAClient> { |
| 282 public: |
| 283 // Callback invoked whan the picture is dropped and should be reused for |
| 284 // the decoder again. |
| 285 typedef base::Callback<void(int32 picture_buffer_id)> ReusePictureCB; |
| 286 |
| 287 ThrottlingVDAClient(VideoDecodeAccelerator::Client* client, |
| 288 double fps, |
| 289 ReusePictureCB reuse_picture_cb); |
| 290 virtual ~ThrottlingVDAClient(); |
| 291 |
| 292 // VideoDecodeAccelerator::Client implementation |
| 293 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, |
| 294 const gfx::Size& dimensions, |
| 295 uint32 texture_target) OVERRIDE; |
| 296 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; |
| 297 virtual void PictureReady(const media::Picture& picture) OVERRIDE; |
| 298 virtual void NotifyInitializeDone() OVERRIDE; |
| 299 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; |
| 300 virtual void NotifyFlushDone() OVERRIDE; |
| 301 virtual void NotifyResetDone() OVERRIDE; |
| 302 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; |
| 303 |
| 304 int num_decoded_frames() { return num_decoded_frames_; } |
| 305 |
| 306 private: |
| 307 |
| 308 void CallClientPictureReady(int version); |
| 309 |
| 310 VideoDecodeAccelerator::Client* client_; |
| 311 ReusePictureCB reuse_picture_cb_; |
| 312 base::TimeTicks next_frame_delivered_time_; |
| 313 base::TimeDelta frame_duration_; |
| 314 |
| 315 int num_decoded_frames_; |
| 316 int stream_version_; |
| 317 std::deque<media::Picture> pending_pictures_; |
| 318 |
| 319 DISALLOW_IMPLICIT_CONSTRUCTORS(ThrottlingVDAClient); |
| 320 }; |
| 321 |
| 322 ThrottlingVDAClient::ThrottlingVDAClient(VideoDecodeAccelerator::Client* client, |
| 323 double fps, |
| 324 ReusePictureCB reuse_picture_cb) |
| 325 : client_(client), |
| 326 reuse_picture_cb_(reuse_picture_cb), |
| 327 num_decoded_frames_(0), |
| 328 stream_version_(0) { |
| 329 CHECK(client_); |
| 330 CHECK_GT(fps, 0); |
| 331 frame_duration_ = base::TimeDelta::FromSeconds(1) / fps; |
| 332 } |
| 333 |
| 334 ThrottlingVDAClient::~ThrottlingVDAClient() {} |
| 335 |
| 336 void ThrottlingVDAClient::ProvidePictureBuffers(uint32 requested_num_of_buffers, |
| 337 const gfx::Size& dimensions, |
| 338 uint32 texture_target) { |
| 339 client_->ProvidePictureBuffers( |
| 340 requested_num_of_buffers, dimensions, texture_target); |
| 341 } |
| 342 |
| 343 void ThrottlingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) { |
| 344 client_->DismissPictureBuffer(picture_buffer_id); |
| 345 } |
| 346 |
| 347 void ThrottlingVDAClient::PictureReady(const media::Picture& picture) { |
| 348 ++num_decoded_frames_; |
| 349 |
| 350 if (pending_pictures_.empty()) { |
| 351 base::TimeDelta delay = |
| 352 next_frame_delivered_time_.is_null() |
| 353 ? base::TimeDelta() |
| 354 : next_frame_delivered_time_ - base::TimeTicks::Now(); |
| 355 base::MessageLoop::current()->PostDelayedTask( |
| 356 FROM_HERE, |
| 357 base::Bind(&ThrottlingVDAClient::CallClientPictureReady, |
| 358 AsWeakPtr(), |
| 359 stream_version_), |
| 360 delay); |
| 361 } |
| 362 pending_pictures_.push_back(picture); |
| 363 } |
| 364 |
| 365 void ThrottlingVDAClient::CallClientPictureReady(int version) { |
| 366 // Just return if we have reset the decoder |
| 367 if (version != stream_version_) |
| 368 return; |
| 369 |
| 370 base::TimeTicks now = base::TimeTicks::Now(); |
| 371 |
| 372 if (next_frame_delivered_time_.is_null()) |
| 373 next_frame_delivered_time_ = now; |
| 374 |
| 375 if (next_frame_delivered_time_ + frame_duration_ < now) { |
| 376 // Too late, drop the frame |
| 377 reuse_picture_cb_.Run(pending_pictures_.front().picture_buffer_id()); |
| 378 } else { |
| 379 client_->PictureReady(pending_pictures_.front()); |
| 380 } |
| 381 |
| 382 pending_pictures_.pop_front(); |
| 383 next_frame_delivered_time_ += frame_duration_; |
| 384 if (!pending_pictures_.empty()) { |
| 385 base::MessageLoop::current()->PostDelayedTask( |
| 386 FROM_HERE, |
| 387 base::Bind(&ThrottlingVDAClient::CallClientPictureReady, |
| 388 AsWeakPtr(), |
| 389 stream_version_), |
| 390 next_frame_delivered_time_ - base::TimeTicks::Now()); |
| 391 } |
| 392 } |
| 393 |
| 394 void ThrottlingVDAClient::NotifyInitializeDone() { |
| 395 client_->NotifyInitializeDone(); |
| 396 } |
| 397 |
| 398 void ThrottlingVDAClient::NotifyEndOfBitstreamBuffer( |
| 399 int32 bitstream_buffer_id) { |
| 400 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); |
| 401 } |
| 402 |
| 403 void ThrottlingVDAClient::NotifyFlushDone() { |
| 404 if (!pending_pictures_.empty()) { |
| 405 base::MessageLoop::current()->PostDelayedTask( |
| 406 FROM_HERE, |
| 407 base::Bind(&ThrottlingVDAClient::NotifyFlushDone, |
| 408 base::Unretained(this)), |
| 409 next_frame_delivered_time_ - base::TimeTicks::Now()); |
| 410 return; |
| 411 } |
| 412 client_->NotifyFlushDone(); |
| 413 } |
| 414 |
| 415 void ThrottlingVDAClient::NotifyResetDone() { |
| 416 ++stream_version_; |
| 417 while (!pending_pictures_.empty()) { |
| 418 reuse_picture_cb_.Run(pending_pictures_.front().picture_buffer_id()); |
| 419 pending_pictures_.pop_front(); |
| 420 } |
| 421 next_frame_delivered_time_ = base::TimeTicks(); |
| 422 client_->NotifyResetDone(); |
| 423 } |
| 424 |
| 425 void ThrottlingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) { |
| 426 client_->NotifyError(error); |
| 427 } |
| 428 |
272 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by | 429 // Client that can accept callbacks from a VideoDecodeAccelerator and is used by |
273 // the TESTs below. | 430 // the TESTs below. |
274 class GLRenderingVDAClient : public VideoDecodeAccelerator::Client { | 431 class GLRenderingVDAClient : public VideoDecodeAccelerator::Client { |
275 public: | 432 public: |
276 // Doesn't take ownership of |rendering_helper| or |note|, which must outlive | 433 // Doesn't take ownership of |rendering_helper| or |note|, which must outlive |
277 // |*this|. | 434 // |*this|. |
278 // |num_fragments_per_decode| counts NALUs for h264 and frames for VP8. | 435 // |num_fragments_per_decode| counts NALUs for h264 and frames for VP8. |
279 // |num_play_throughs| indicates how many times to play through the video. | 436 // |num_play_throughs| indicates how many times to play through the video. |
280 // |reset_after_frame_num| can be a frame number >=0 indicating a mid-stream | 437 // |reset_after_frame_num| can be a frame number >=0 indicating a mid-stream |
281 // Reset() should be done after that frame number is delivered, or | 438 // Reset() should be done after that frame number is delivered, or |
282 // END_OF_STREAM_RESET to indicate no mid-stream Reset(). | 439 // END_OF_STREAM_RESET to indicate no mid-stream Reset(). |
283 // |delete_decoder_state| indicates when the underlying decoder should be | 440 // |delete_decoder_state| indicates when the underlying decoder should be |
284 // Destroy()'d and deleted and can take values: N<0: delete after -N Decode() | 441 // Destroy()'d and deleted and can take values: N<0: delete after -N Decode() |
285 // calls have been made, N>=0 means interpret as ClientState. | 442 // calls have been made, N>=0 means interpret as ClientState. |
286 // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the | 443 // Both |reset_after_frame_num| & |delete_decoder_state| apply only to the |
287 // last play-through (governed by |num_play_throughs|). | 444 // last play-through (governed by |num_play_throughs|). |
| 445 // |rendering_fps| indicates the target rendering fps. 0 means no target fps |
| 446 // and it would render as fast as possible. |
| 447 // |suppress_rendering| indicates GL rendering is suppressed or not. |
288 // After |delay_reuse_after_frame_num| frame has been delivered, the client | 448 // After |delay_reuse_after_frame_num| frame has been delivered, the client |
289 // will start delaying the call to ReusePictureBuffer() for kReuseDelayMs. | 449 // will start delaying the call to ReusePictureBuffer() for kReuseDelay. |
290 GLRenderingVDAClient(RenderingHelper* rendering_helper, | 450 GLRenderingVDAClient(RenderingHelper* rendering_helper, |
291 int rendering_window_id, | 451 int rendering_window_id, |
292 ClientStateNotification* note, | 452 ClientStateNotification* note, |
293 const std::string& encoded_data, | 453 const std::string& encoded_data, |
294 int num_fragments_per_decode, | 454 int num_fragments_per_decode, |
295 int num_in_flight_decodes, | 455 int num_in_flight_decodes, |
296 int num_play_throughs, | 456 int num_play_throughs, |
297 int reset_after_frame_num, | 457 int reset_after_frame_num, |
298 int delete_decoder_state, | 458 int delete_decoder_state, |
299 int frame_width, | 459 int frame_width, |
300 int frame_height, | 460 int frame_height, |
301 int profile, | 461 int profile, |
| 462 double rendering_fps, |
302 bool suppress_rendering, | 463 bool suppress_rendering, |
303 int delay_reuse_after_frame_num); | 464 int delay_reuse_after_frame_num); |
304 virtual ~GLRenderingVDAClient(); | 465 virtual ~GLRenderingVDAClient(); |
305 void CreateDecoder(); | 466 void CreateDecoder(); |
306 | 467 |
307 // VideoDecodeAccelerator::Client implementation. | 468 // VideoDecodeAccelerator::Client implementation. |
308 // The heart of the Client. | 469 // The heart of the Client. |
309 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, | 470 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, |
310 const gfx::Size& dimensions, | 471 const gfx::Size& dimensions, |
311 uint32 texture_target) OVERRIDE; | 472 uint32 texture_target) OVERRIDE; |
312 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; | 473 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; |
313 virtual void PictureReady(const media::Picture& picture) OVERRIDE; | 474 virtual void PictureReady(const media::Picture& picture) OVERRIDE; |
314 // Simple state changes. | 475 // Simple state changes. |
315 virtual void NotifyInitializeDone() OVERRIDE; | 476 virtual void NotifyInitializeDone() OVERRIDE; |
316 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; | 477 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; |
317 virtual void NotifyFlushDone() OVERRIDE; | 478 virtual void NotifyFlushDone() OVERRIDE; |
318 virtual void NotifyResetDone() OVERRIDE; | 479 virtual void NotifyResetDone() OVERRIDE; |
319 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; | 480 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; |
320 | 481 |
321 void OutputFrameDeliveryTimes(base::PlatformFile output); | 482 void OutputFrameDeliveryTimes(base::PlatformFile output); |
322 | 483 |
| 484 void NotifyFrameDropped(int32 picture_buffer_id); |
| 485 |
323 // Simple getters for inspecting the state of the Client. | 486 // Simple getters for inspecting the state of the Client. |
324 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } | 487 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } |
325 int num_skipped_fragments() { return num_skipped_fragments_; } | 488 int num_skipped_fragments() { return num_skipped_fragments_; } |
326 int num_queued_fragments() { return num_queued_fragments_; } | 489 int num_queued_fragments() { return num_queued_fragments_; } |
327 int num_decoded_frames() { return num_decoded_frames_; } | 490 int num_decoded_frames(); |
328 double frames_per_second(); | 491 double frames_per_second(); |
329 bool decoder_deleted() { return !decoder_.get(); } | 492 bool decoder_deleted() { return !decoder_.get(); } |
330 | 493 |
331 private: | 494 private: |
332 typedef std::map<int, media::PictureBuffer*> PictureBufferById; | 495 typedef std::map<int, media::PictureBuffer*> PictureBufferById; |
333 | 496 |
334 void SetState(ClientState new_state); | 497 void SetState(ClientState new_state); |
335 | 498 |
336 // Delete the associated OMX decoder helper. | 499 // Delete the associated OMX decoder helper. |
337 void DeleteDecoder(); | 500 void DeleteDecoder(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 int num_skipped_fragments_; | 532 int num_skipped_fragments_; |
370 int num_queued_fragments_; | 533 int num_queued_fragments_; |
371 int num_decoded_frames_; | 534 int num_decoded_frames_; |
372 int num_done_bitstream_buffers_; | 535 int num_done_bitstream_buffers_; |
373 PictureBufferById picture_buffers_by_id_; | 536 PictureBufferById picture_buffers_by_id_; |
374 base::TimeTicks initialize_done_ticks_; | 537 base::TimeTicks initialize_done_ticks_; |
375 int profile_; | 538 int profile_; |
376 bool suppress_rendering_; | 539 bool suppress_rendering_; |
377 std::vector<base::TimeTicks> frame_delivery_times_; | 540 std::vector<base::TimeTicks> frame_delivery_times_; |
378 int delay_reuse_after_frame_num_; | 541 int delay_reuse_after_frame_num_; |
| 542 scoped_ptr<ThrottlingVDAClient> throttling_client_; |
| 543 |
| 544 DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient); |
379 }; | 545 }; |
380 | 546 |
381 GLRenderingVDAClient::GLRenderingVDAClient( | 547 GLRenderingVDAClient::GLRenderingVDAClient(RenderingHelper* rendering_helper, |
382 RenderingHelper* rendering_helper, | 548 int rendering_window_id, |
383 int rendering_window_id, | 549 ClientStateNotification* note, |
384 ClientStateNotification* note, | 550 const std::string& encoded_data, |
385 const std::string& encoded_data, | 551 int num_fragments_per_decode, |
386 int num_fragments_per_decode, | 552 int num_in_flight_decodes, |
387 int num_in_flight_decodes, | 553 int num_play_throughs, |
388 int num_play_throughs, | 554 int reset_after_frame_num, |
389 int reset_after_frame_num, | 555 int delete_decoder_state, |
390 int delete_decoder_state, | 556 int frame_width, |
391 int frame_width, | 557 int frame_height, |
392 int frame_height, | 558 int profile, |
393 int profile, | 559 double rendering_fps, |
394 bool suppress_rendering, | 560 bool suppress_rendering, |
395 int delay_reuse_after_frame_num) | 561 int delay_reuse_after_frame_num) |
396 : rendering_helper_(rendering_helper), | 562 : rendering_helper_(rendering_helper), |
397 rendering_window_id_(rendering_window_id), | 563 rendering_window_id_(rendering_window_id), |
398 encoded_data_(encoded_data), | 564 encoded_data_(encoded_data), |
399 num_fragments_per_decode_(num_fragments_per_decode), | 565 num_fragments_per_decode_(num_fragments_per_decode), |
400 num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0), | 566 num_in_flight_decodes_(num_in_flight_decodes), |
401 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), | 567 outstanding_decodes_(0), |
| 568 encoded_data_next_pos_to_decode_(0), |
| 569 next_bitstream_buffer_id_(0), |
402 note_(note), | 570 note_(note), |
403 remaining_play_throughs_(num_play_throughs), | 571 remaining_play_throughs_(num_play_throughs), |
404 reset_after_frame_num_(reset_after_frame_num), | 572 reset_after_frame_num_(reset_after_frame_num), |
405 delete_decoder_state_(delete_decoder_state), | 573 delete_decoder_state_(delete_decoder_state), |
406 state_(CS_CREATED), | 574 state_(CS_CREATED), |
407 num_skipped_fragments_(0), num_queued_fragments_(0), | 575 num_skipped_fragments_(0), |
408 num_decoded_frames_(0), num_done_bitstream_buffers_(0), | 576 num_queued_fragments_(0), |
| 577 num_decoded_frames_(0), |
| 578 num_done_bitstream_buffers_(0), |
409 profile_(profile), | 579 profile_(profile), |
410 suppress_rendering_(suppress_rendering), | 580 suppress_rendering_(suppress_rendering), |
411 delay_reuse_after_frame_num_(delay_reuse_after_frame_num) { | 581 delay_reuse_after_frame_num_(delay_reuse_after_frame_num) { |
412 CHECK_GT(num_fragments_per_decode, 0); | 582 CHECK_GT(num_fragments_per_decode, 0); |
413 CHECK_GT(num_in_flight_decodes, 0); | 583 CHECK_GT(num_in_flight_decodes, 0); |
414 CHECK_GT(num_play_throughs, 0); | 584 CHECK_GT(num_play_throughs, 0); |
| 585 CHECK_GE(rendering_fps, 0); |
| 586 if (rendering_fps > 0) |
| 587 throttling_client_.reset(new ThrottlingVDAClient( |
| 588 this, |
| 589 rendering_fps, |
| 590 base::Bind(&GLRenderingVDAClient::NotifyFrameDropped, |
| 591 base::Unretained(this)))); |
415 } | 592 } |
416 | 593 |
417 GLRenderingVDAClient::~GLRenderingVDAClient() { | 594 GLRenderingVDAClient::~GLRenderingVDAClient() { |
418 DeleteDecoder(); // Clean up in case of expected error. | 595 DeleteDecoder(); // Clean up in case of expected error. |
419 CHECK(decoder_deleted()); | 596 CHECK(decoder_deleted()); |
420 STLDeleteValues(&picture_buffers_by_id_); | 597 STLDeleteValues(&picture_buffers_by_id_); |
421 SetState(CS_DESTROYED); | 598 SetState(CS_DESTROYED); |
422 } | 599 } |
423 | 600 |
424 static bool DoNothingReturnTrue() { return true; } | 601 static bool DoNothingReturnTrue() { return true; } |
425 | 602 |
426 void GLRenderingVDAClient::CreateDecoder() { | 603 void GLRenderingVDAClient::CreateDecoder() { |
427 CHECK(decoder_deleted()); | 604 CHECK(decoder_deleted()); |
428 CHECK(!decoder_.get()); | 605 CHECK(!decoder_.get()); |
| 606 |
| 607 VideoDecodeAccelerator::Client* client = this; |
| 608 if (throttling_client_) |
| 609 client = throttling_client_.get(); |
429 #if defined(OS_WIN) | 610 #if defined(OS_WIN) |
430 decoder_.reset(new DXVAVideoDecodeAccelerator( | 611 decoder_.reset( |
431 this, base::Bind(&DoNothingReturnTrue))); | 612 new DXVAVideoDecodeAccelerator(client, base::Bind(&DoNothingReturnTrue))); |
432 #elif defined(OS_CHROMEOS) | 613 #elif defined(OS_CHROMEOS) |
433 #if defined(ARCH_CPU_ARMEL) | 614 #if defined(ARCH_CPU_ARMEL) |
434 decoder_.reset( | 615 decoder_.reset(new ExynosVideoDecodeAccelerator( |
435 new ExynosVideoDecodeAccelerator( | 616 static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()), |
436 static_cast<EGLDisplay>(rendering_helper_->GetGLDisplay()), | 617 static_cast<EGLContext>(rendering_helper_->GetGLContext()), |
437 static_cast<EGLContext>(rendering_helper_->GetGLContext()), | 618 client, |
438 this, base::Bind(&DoNothingReturnTrue))); | 619 base::Bind(&DoNothingReturnTrue))); |
439 #elif defined(ARCH_CPU_X86_FAMILY) | 620 #elif defined(ARCH_CPU_X86_FAMILY) |
440 decoder_.reset(new VaapiVideoDecodeAccelerator( | 621 decoder_.reset(new VaapiVideoDecodeAccelerator( |
441 static_cast<Display*>(rendering_helper_->GetGLDisplay()), | 622 static_cast<Display*>(rendering_helper_->GetGLDisplay()), |
442 static_cast<GLXContext>(rendering_helper_->GetGLContext()), | 623 static_cast<GLXContext>(rendering_helper_->GetGLContext()), |
443 this, base::Bind(&DoNothingReturnTrue))); | 624 client, |
| 625 base::Bind(&DoNothingReturnTrue))); |
444 #endif // ARCH_CPU_ARMEL | 626 #endif // ARCH_CPU_ARMEL |
445 #endif // OS_WIN | 627 #endif // OS_WIN |
446 CHECK(decoder_.get()); | 628 CHECK(decoder_.get()); |
447 SetState(CS_DECODER_SET); | 629 SetState(CS_DECODER_SET); |
448 if (decoder_deleted()) | 630 if (decoder_deleted()) |
449 return; | 631 return; |
450 | 632 |
451 // Configure the decoder. | 633 // Configure the decoder. |
452 media::VideoCodecProfile profile = media::H264PROFILE_BASELINE; | 634 media::VideoCodecProfile profile = media::H264PROFILE_BASELINE; |
453 if (profile_ != -1) | 635 if (profile_ != -1) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 delete it->second; | 670 delete it->second; |
489 picture_buffers_by_id_.erase(it); | 671 picture_buffers_by_id_.erase(it); |
490 } | 672 } |
491 | 673 |
492 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { | 674 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { |
493 // We shouldn't be getting pictures delivered after Reset has completed. | 675 // We shouldn't be getting pictures delivered after Reset has completed. |
494 CHECK_LT(state_, CS_RESET); | 676 CHECK_LT(state_, CS_RESET); |
495 | 677 |
496 if (decoder_deleted()) | 678 if (decoder_deleted()) |
497 return; | 679 return; |
| 680 |
498 frame_delivery_times_.push_back(base::TimeTicks::Now()); | 681 frame_delivery_times_.push_back(base::TimeTicks::Now()); |
499 | 682 |
500 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); | 683 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); |
501 ++num_decoded_frames_; | 684 ++num_decoded_frames_; |
502 | 685 |
503 // Mid-stream reset applies only to the last play-through per constructor | 686 // Mid-stream reset applies only to the last play-through per constructor |
504 // comment. | 687 // comment. |
505 if (remaining_play_throughs_ == 1 && | 688 if (remaining_play_throughs_ == 1 && |
506 reset_after_frame_num_ == num_decoded_frames_) { | 689 reset_after_frame_num_ == num_decoded_frames()) { |
507 reset_after_frame_num_ = MID_STREAM_RESET; | 690 reset_after_frame_num_ = MID_STREAM_RESET; |
508 decoder_->Reset(); | 691 decoder_->Reset(); |
509 // Re-start decoding from the beginning of the stream to avoid needing to | 692 // Re-start decoding from the beginning of the stream to avoid needing to |
510 // know how to find I-frames and so on in this test. | 693 // know how to find I-frames and so on in this test. |
511 encoded_data_next_pos_to_decode_ = 0; | 694 encoded_data_next_pos_to_decode_ = 0; |
512 } | 695 } |
513 | 696 |
514 media::PictureBuffer* picture_buffer = | 697 media::PictureBuffer* picture_buffer = |
515 picture_buffers_by_id_[picture.picture_buffer_id()]; | 698 picture_buffers_by_id_[picture.picture_buffer_id()]; |
516 CHECK(picture_buffer); | 699 CHECK(picture_buffer); |
517 if (!suppress_rendering_) { | 700 if (!suppress_rendering_) { |
518 rendering_helper_->RenderTexture(picture_buffer->texture_id()); | 701 rendering_helper_->RenderTexture(picture_buffer->texture_id()); |
519 } | 702 } |
520 | 703 |
521 if (num_decoded_frames_ > delay_reuse_after_frame_num_) { | 704 if (num_decoded_frames() > delay_reuse_after_frame_num_) { |
522 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind( | 705 base::MessageLoop::current()->PostDelayedTask( |
523 &VideoDecodeAccelerator::ReusePictureBuffer, | 706 FROM_HERE, |
524 decoder_->AsWeakPtr(), picture.picture_buffer_id()), | 707 base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer, |
525 base::TimeDelta::FromMilliseconds(kReuseDelayMs)); | 708 decoder_->AsWeakPtr(), |
| 709 picture.picture_buffer_id()), |
| 710 kReuseDelay); |
526 } else { | 711 } else { |
527 decoder_->ReusePictureBuffer(picture.picture_buffer_id()); | 712 decoder_->ReusePictureBuffer(picture.picture_buffer_id()); |
528 } | 713 } |
529 } | 714 } |
530 | 715 |
531 void GLRenderingVDAClient::NotifyInitializeDone() { | 716 void GLRenderingVDAClient::NotifyInitializeDone() { |
532 SetState(CS_INITIALIZED); | 717 SetState(CS_INITIALIZED); |
533 initialize_done_ticks_ = base::TimeTicks::Now(); | 718 initialize_done_ticks_ = base::TimeTicks::Now(); |
534 | 719 |
535 if (reset_after_frame_num_ == START_OF_STREAM_RESET) { | 720 if (reset_after_frame_num_ == START_OF_STREAM_RESET) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 base::TimeTicks t0 = initialize_done_ticks_; | 787 base::TimeTicks t0 = initialize_done_ticks_; |
603 for (size_t i = 0; i < frame_delivery_times_.size(); ++i) { | 788 for (size_t i = 0; i < frame_delivery_times_.size(); ++i) { |
604 s = base::StringPrintf("frame %04" PRIuS ": %" PRId64 " us\n", | 789 s = base::StringPrintf("frame %04" PRIuS ": %" PRId64 " us\n", |
605 i, | 790 i, |
606 (frame_delivery_times_[i] - t0).InMicroseconds()); | 791 (frame_delivery_times_[i] - t0).InMicroseconds()); |
607 t0 = frame_delivery_times_[i]; | 792 t0 = frame_delivery_times_[i]; |
608 base::WritePlatformFileAtCurrentPos(output, s.data(), s.length()); | 793 base::WritePlatformFileAtCurrentPos(output, s.data(), s.length()); |
609 } | 794 } |
610 } | 795 } |
611 | 796 |
| 797 void GLRenderingVDAClient::NotifyFrameDropped(int32 picture_buffer_id) { |
| 798 decoder_->ReusePictureBuffer(picture_buffer_id); |
| 799 } |
| 800 |
612 static bool LookingAtNAL(const std::string& encoded, size_t pos) { | 801 static bool LookingAtNAL(const std::string& encoded, size_t pos) { |
613 return encoded[pos] == 0 && encoded[pos + 1] == 0 && | 802 return encoded[pos] == 0 && encoded[pos + 1] == 0 && |
614 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; | 803 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; |
615 } | 804 } |
616 | 805 |
617 void GLRenderingVDAClient::SetState(ClientState new_state) { | 806 void GLRenderingVDAClient::SetState(ClientState new_state) { |
618 note_->Notify(new_state); | 807 note_->Notify(new_state); |
619 state_ = new_state; | 808 state_ = new_state; |
620 if (!remaining_play_throughs_ && new_state == delete_decoder_state_) { | 809 if (!remaining_play_throughs_ && new_state == delete_decoder_state_) { |
621 CHECK(!decoder_deleted()); | 810 CHECK(!decoder_deleted()); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 decoder_->Decode(bitstream_buffer); | 930 decoder_->Decode(bitstream_buffer); |
742 ++outstanding_decodes_; | 931 ++outstanding_decodes_; |
743 encoded_data_next_pos_to_decode_ = end_pos; | 932 encoded_data_next_pos_to_decode_ = end_pos; |
744 | 933 |
745 if (!remaining_play_throughs_ && | 934 if (!remaining_play_throughs_ && |
746 -delete_decoder_state_ == next_bitstream_buffer_id_) { | 935 -delete_decoder_state_ == next_bitstream_buffer_id_) { |
747 DeleteDecoder(); | 936 DeleteDecoder(); |
748 } | 937 } |
749 } | 938 } |
750 | 939 |
| 940 int GLRenderingVDAClient::num_decoded_frames() { |
| 941 return throttling_client_ ? throttling_client_->num_decoded_frames() |
| 942 : num_decoded_frames_; |
| 943 } |
| 944 |
751 double GLRenderingVDAClient::frames_per_second() { | 945 double GLRenderingVDAClient::frames_per_second() { |
752 base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_; | 946 base::TimeDelta delta = frame_delivery_times_.back() - initialize_done_ticks_; |
753 if (delta.InSecondsF() == 0) | 947 if (delta.InSecondsF() == 0) |
754 return 0; | 948 return 0; |
755 return num_decoded_frames_ / delta.InSecondsF(); | 949 return num_decoded_frames() / delta.InSecondsF(); |
756 } | 950 } |
757 | 951 |
758 // Test parameters: | 952 // Test parameters: |
759 // - Number of fragments per Decode() call. | 953 // - Number of fragments per Decode() call. |
760 // - Number of concurrent decoders. | 954 // - Number of concurrent decoders. |
761 // - Number of concurrent in-flight Decode() calls per decoder. | 955 // - Number of concurrent in-flight Decode() calls per decoder. |
762 // - Number of play-throughs. | 956 // - Number of play-throughs. |
763 // - reset_after_frame_num: see GLRenderingVDAClient ctor. | 957 // - reset_after_frame_num: see GLRenderingVDAClient ctor. |
764 // - delete_decoder_phase: see GLRenderingVDAClient ctor. | 958 // - delete_decoder_phase: see GLRenderingVDAClient ctor. |
765 // - whether to test slow rendering by delaying ReusePictureBuffer(). | 959 // - whether to test slow rendering by delaying ReusePictureBuffer(). |
(...skipping 25 matching lines...) Expand all Loading... |
791 } | 985 } |
792 | 986 |
793 // We assert a minimal number of concurrent decoders we expect to succeed. | 987 // We assert a minimal number of concurrent decoders we expect to succeed. |
794 // Different platforms can support more concurrent decoders, so we don't assert | 988 // Different platforms can support more concurrent decoders, so we don't assert |
795 // failure above this. | 989 // failure above this. |
796 enum { kMinSupportedNumConcurrentDecoders = 3 }; | 990 enum { kMinSupportedNumConcurrentDecoders = 3 }; |
797 | 991 |
798 // Test the most straightforward case possible: data is decoded from a single | 992 // Test the most straightforward case possible: data is decoded from a single |
799 // chunk and rendered to the screen. | 993 // chunk and rendered to the screen. |
800 TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { | 994 TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { |
801 // Can be useful for debugging VLOGs from OVDA. | |
802 // logging::SetMinLogLevel(-1); | |
803 | |
804 // Required for Thread to work. Not used otherwise. | 995 // Required for Thread to work. Not used otherwise. |
805 base::ShadowingAtExitManager at_exit_manager; | 996 base::ShadowingAtExitManager at_exit_manager; |
806 | 997 |
807 const int num_fragments_per_decode = GetParam().a; | 998 const int num_fragments_per_decode = GetParam().a; |
808 const size_t num_concurrent_decoders = GetParam().b; | 999 const size_t num_concurrent_decoders = GetParam().b; |
809 const size_t num_in_flight_decodes = GetParam().c; | 1000 const size_t num_in_flight_decodes = GetParam().c; |
810 const int num_play_throughs = GetParam().d; | 1001 const int num_play_throughs = GetParam().d; |
811 const int reset_point = GetParam().e; | 1002 const int reset_point = GetParam().e; |
812 const int delete_decoder_state = GetParam().f; | 1003 const int delete_decoder_state = GetParam().f; |
813 bool test_reuse_delay = GetParam().g; | 1004 bool test_reuse_delay = GetParam().g; |
814 const bool render_as_thumbnails = GetParam().h; | 1005 const bool render_as_thumbnails = GetParam().h; |
815 | 1006 |
816 std::vector<TestVideoFile*> test_video_files; | 1007 std::vector<TestVideoFile*> test_video_files; |
817 ParseAndReadTestVideoData(test_video_data, num_concurrent_decoders, | 1008 ParseAndReadTestVideoData(g_test_video_data, |
818 reset_point, &test_video_files); | 1009 num_concurrent_decoders, |
| 1010 reset_point, |
| 1011 &test_video_files); |
819 | 1012 |
820 // Suppress GL rendering when we are logging the frame delivery time and a | 1013 // Suppress GL rendering for all tests when the "--disable_rendering" is set. |
821 // few other tests, to cut down overall test runtime. | 1014 // Otherwise, suppress rendering in all but a few tests, to cut down overall |
822 const bool suppress_rendering = num_fragments_per_decode > 1 || | 1015 // test runtime. |
823 frame_delivery_log != NULL; | 1016 const bool suppress_rendering = |
| 1017 num_fragments_per_decode > 1 || g_disable_rendering; |
824 | 1018 |
825 std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL); | 1019 std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL); |
826 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); | 1020 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); |
827 | 1021 |
828 // Initialize the rendering helper. | 1022 // Initialize the rendering helper. |
829 base::Thread rendering_thread("GLRenderingVDAClientThread"); | 1023 base::Thread rendering_thread("GLRenderingVDAClientThread"); |
830 base::Thread::Options options; | 1024 base::Thread::Options options; |
831 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | 1025 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; |
832 #if defined(OS_WIN) | 1026 #if defined(OS_WIN) |
833 // For windows the decoding thread initializes the media foundation decoder | 1027 // For windows the decoding thread initializes the media foundation decoder |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 test_video_files[index % test_video_files.size()]; | 1067 test_video_files[index % test_video_files.size()]; |
874 ClientStateNotification* note = new ClientStateNotification(); | 1068 ClientStateNotification* note = new ClientStateNotification(); |
875 notes[index] = note; | 1069 notes[index] = note; |
876 | 1070 |
877 int delay_after_frame_num = std::numeric_limits<int>::max(); | 1071 int delay_after_frame_num = std::numeric_limits<int>::max(); |
878 if (test_reuse_delay && | 1072 if (test_reuse_delay && |
879 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { | 1073 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { |
880 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; | 1074 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; |
881 } | 1075 } |
882 | 1076 |
883 GLRenderingVDAClient* client = new GLRenderingVDAClient( | 1077 GLRenderingVDAClient* client = |
884 rendering_helper.get(), index, note, video_file->data_str, | 1078 new GLRenderingVDAClient(rendering_helper.get(), |
885 num_fragments_per_decode, num_in_flight_decodes, num_play_throughs, | 1079 index, |
886 video_file->reset_after_frame_num, delete_decoder_state, | 1080 note, |
887 video_file->width, video_file->height, video_file->profile, | 1081 video_file->data_str, |
888 suppress_rendering, delay_after_frame_num); | 1082 num_fragments_per_decode, |
| 1083 num_in_flight_decodes, |
| 1084 num_play_throughs, |
| 1085 video_file->reset_after_frame_num, |
| 1086 delete_decoder_state, |
| 1087 video_file->width, |
| 1088 video_file->height, |
| 1089 video_file->profile, |
| 1090 g_rendering_fps, |
| 1091 suppress_rendering, |
| 1092 delay_after_frame_num); |
889 clients[index] = client; | 1093 clients[index] = client; |
890 | 1094 |
891 rendering_thread.message_loop()->PostTask( | 1095 rendering_thread.message_loop()->PostTask( |
892 FROM_HERE, | 1096 FROM_HERE, |
893 base::Bind(&GLRenderingVDAClient::CreateDecoder, | 1097 base::Bind(&GLRenderingVDAClient::CreateDecoder, |
894 base::Unretained(client))); | 1098 base::Unretained(client))); |
895 | 1099 |
896 ASSERT_EQ(note->Wait(), CS_DECODER_SET); | 1100 ASSERT_EQ(note->Wait(), CS_DECODER_SET); |
897 } | 1101 } |
898 // Then wait for all the decodes to finish. | 1102 // Then wait for all the decodes to finish. |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 png.size()); | 1208 png.size()); |
1005 ASSERT_EQ(num_bytes, static_cast<int>(png.size())); | 1209 ASSERT_EQ(num_bytes, static_cast<int>(png.size())); |
1006 } | 1210 } |
1007 ASSERT_NE(match, golden_md5s.end()); | 1211 ASSERT_NE(match, golden_md5s.end()); |
1008 EXPECT_EQ(alpha_solid, true) << "RGBA frame had incorrect alpha"; | 1212 EXPECT_EQ(alpha_solid, true) << "RGBA frame had incorrect alpha"; |
1009 } | 1213 } |
1010 | 1214 |
1011 // Output the frame delivery time to file | 1215 // Output the frame delivery time to file |
1012 // We can only make performance/correctness assertions if the decoder was | 1216 // We can only make performance/correctness assertions if the decoder was |
1013 // allowed to finish. | 1217 // allowed to finish. |
1014 if (frame_delivery_log != NULL && delete_decoder_state >= CS_FLUSHED) { | 1218 if (g_frame_delivery_log != NULL && delete_decoder_state >= CS_FLUSHED) { |
1015 base::PlatformFile output_file = base::CreatePlatformFile( | 1219 base::PlatformFile output_file = base::CreatePlatformFile( |
1016 base::FilePath(frame_delivery_log), | 1220 base::FilePath(g_frame_delivery_log), |
1017 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, | 1221 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, |
1018 NULL, | 1222 NULL, |
1019 NULL); | 1223 NULL); |
1020 for (size_t i = 0; i < num_concurrent_decoders; ++i) { | 1224 for (size_t i = 0; i < num_concurrent_decoders; ++i) { |
1021 clients[i]->OutputFrameDeliveryTimes(output_file); | 1225 clients[i]->OutputFrameDeliveryTimes(output_file); |
1022 } | 1226 } |
1023 base::ClosePlatformFile(output_file); | 1227 base::ClosePlatformFile(output_file); |
1024 } | 1228 } |
1025 | 1229 |
1026 rendering_thread.message_loop()->PostTask( | 1230 rendering_thread.message_loop()->PostTask( |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS; | 1350 logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS; |
1147 CHECK(logging::InitLogging(settings)); | 1351 CHECK(logging::InitLogging(settings)); |
1148 | 1352 |
1149 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 1353 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
1150 DCHECK(cmd_line); | 1354 DCHECK(cmd_line); |
1151 | 1355 |
1152 CommandLine::SwitchMap switches = cmd_line->GetSwitches(); | 1356 CommandLine::SwitchMap switches = cmd_line->GetSwitches(); |
1153 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); | 1357 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); |
1154 it != switches.end(); ++it) { | 1358 it != switches.end(); ++it) { |
1155 if (it->first == "test_video_data") { | 1359 if (it->first == "test_video_data") { |
1156 content::test_video_data = it->second.c_str(); | 1360 content::g_test_video_data = it->second.c_str(); |
1157 continue; | 1361 continue; |
1158 } | 1362 } |
1159 if (it->first == "frame_delivery_log") { | 1363 if (it->first == "frame_delivery_log") { |
1160 content::frame_delivery_log = it->second.c_str(); | 1364 content::g_frame_delivery_log = it->second.c_str(); |
| 1365 continue; |
| 1366 } |
| 1367 if (it->first == "rendering_fps") { |
| 1368 // On Windows, CommandLine::StringType is wstring. We need to convert |
| 1369 // it to std::string first |
| 1370 std::string input(it->second.begin(), it->second.end()); |
| 1371 CHECK(base::StringToDouble(input, &content::g_rendering_fps)); |
| 1372 continue; |
| 1373 } |
| 1374 if (it->first == "disable_rendering") { |
| 1375 content::g_disable_rendering = true; |
1161 continue; | 1376 continue; |
1162 } | 1377 } |
1163 if (it->first == "v" || it->first == "vmodule") | 1378 if (it->first == "v" || it->first == "vmodule") |
1164 continue; | 1379 continue; |
1165 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 1380 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
1166 } | 1381 } |
1167 | 1382 |
1168 base::ShadowingAtExitManager at_exit_manager; | 1383 base::ShadowingAtExitManager at_exit_manager; |
1169 | 1384 |
1170 #if defined(OS_WIN) | 1385 #if defined(OS_WIN) |
1171 content::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | 1386 content::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); |
1172 #elif defined(OS_CHROMEOS) | 1387 #elif defined(OS_CHROMEOS) |
1173 #if defined(ARCH_CPU_ARMEL) | 1388 #if defined(ARCH_CPU_ARMEL) |
1174 content::ExynosVideoDecodeAccelerator::PreSandboxInitialization(); | 1389 content::ExynosVideoDecodeAccelerator::PreSandboxInitialization(); |
1175 #elif defined(ARCH_CPU_X86_FAMILY) | 1390 #elif defined(ARCH_CPU_X86_FAMILY) |
1176 content::VaapiWrapper::PreSandboxInitialization(); | 1391 content::VaapiWrapper::PreSandboxInitialization(); |
1177 #endif // ARCH_CPU_ARMEL | 1392 #endif // ARCH_CPU_ARMEL |
1178 #endif // OS_CHROMEOS | 1393 #endif // OS_CHROMEOS |
1179 | 1394 |
1180 return RUN_ALL_TESTS(); | 1395 return RUN_ALL_TESTS(); |
1181 } | 1396 } |
OLD | NEW |