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 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 // - |profile| is the media::VideoCodecProfile set during Initialization. | 81 // - |profile| is the media::VideoCodecProfile set during Initialization. |
82 // An empty value for a numeric field means "ignore". | 82 // An empty value for a numeric field means "ignore". |
83 const base::FilePath::CharType* test_video_data = | 83 const base::FilePath::CharType* test_video_data = |
84 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); | 84 // FILE_PATH_LITERAL("test-25fps.vp8:320:240:250:250:50:175:11"); |
85 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); | 85 FILE_PATH_LITERAL("test-25fps.h264:320:240:250:258:50:175:1"); |
86 | 86 |
87 // The path of the frame delivery time log. We can enable the log and specify | 87 // The path of the frame delivery time log. We can enable the log and specify |
88 // the filename by the "--frame_delivery_log" switch. | 88 // the filename by the "--frame_delivery_log" switch. |
89 const base::FilePath::CharType* frame_delivery_log = NULL; | 89 const base::FilePath::CharType* frame_delivery_log = NULL; |
90 | 90 |
91 // The value is set by the switch "--target_fps". | |
92 float target_fps = 0; | |
Ami GONE FROM CHROMIUM
2013/07/15 18:54:14
"target_fps" is too vague IMO.
IIUC you want it to
Owen Lin
2013/07/16 10:46:54
Done.
| |
93 | |
94 // Disable rendering, the value is set by the switch "--disable_rendering". | |
95 bool disable_rendering = false; | |
96 | |
91 // Magic constants for differentiating the reasons for NotifyResetDone being | 97 // Magic constants for differentiating the reasons for NotifyResetDone being |
92 // called. | 98 // called. |
93 enum ResetPoint { | 99 enum ResetPoint { |
94 MID_STREAM_RESET = -2, | 100 MID_STREAM_RESET = -2, |
95 END_OF_STREAM_RESET = -1 | 101 END_OF_STREAM_RESET = -1 |
96 }; | 102 }; |
97 | 103 |
98 const int kMaxResetAfterFrameNum = 100; | 104 const int kMaxResetAfterFrameNum = 100; |
99 const int kMaxFramesToDelayReuse = 64; | 105 const int kMaxFramesToDelayReuse = 64; |
100 const int kReuseDelayMs = 1000; | 106 const int kReuseDelayMs = 1000; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 } | 186 } |
181 | 187 |
182 // State of the GLRenderingVDAClient below. Order matters here as the test | 188 // State of the GLRenderingVDAClient below. Order matters here as the test |
183 // makes assumptions about it. | 189 // makes assumptions about it. |
184 enum ClientState { | 190 enum ClientState { |
185 CS_CREATED = 0, | 191 CS_CREATED = 0, |
186 CS_DECODER_SET = 1, | 192 CS_DECODER_SET = 1, |
187 CS_INITIALIZED = 2, | 193 CS_INITIALIZED = 2, |
188 CS_FLUSHING = 3, | 194 CS_FLUSHING = 3, |
189 CS_FLUSHED = 4, | 195 CS_FLUSHED = 4, |
190 CS_DONE = 5, | 196 CS_COMPLETE_RENDERING = 5, |
Pawel Osciak
2013/07/15 08:07:06
I'd call this RENDERED or RENDERING_DONE. IMHO thi
Ami GONE FROM CHROMIUM
2013/07/15 18:54:14
I think none of these names is good enough to use
Owen Lin
2013/07/16 10:46:54
Are you suggesting removing this state ? My intent
Owen Lin
2013/07/16 10:46:54
Done.
| |
191 CS_RESETTING = 6, | 197 CS_RESETTING = 6, |
192 CS_RESET = 7, | 198 CS_RESET = 7, |
193 CS_ERROR = 8, | 199 CS_ERROR = 8, |
194 CS_DESTROYED = 9, | 200 CS_DESTROYED = 9, |
195 CS_MAX, // Must be last entry. | 201 CS_MAX, // Must be last entry. |
196 }; | 202 }; |
197 | 203 |
198 // Helper class allowing one thread to wait on a notification from another. | 204 // Helper class allowing one thread to wait on a notification from another. |
199 // If notifications come in faster than they are Wait()'d for, they are | 205 // If notifications come in faster than they are Wait()'d for, they are |
200 // accumulated (so exactly as many Wait() calls will unblock as Notify() calls | 206 // accumulated (so exactly as many Wait() calls will unblock as Notify() calls |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 ClientStateNotification* note, | 262 ClientStateNotification* note, |
257 const std::string& encoded_data, | 263 const std::string& encoded_data, |
258 int num_fragments_per_decode, | 264 int num_fragments_per_decode, |
259 int num_in_flight_decodes, | 265 int num_in_flight_decodes, |
260 int num_play_throughs, | 266 int num_play_throughs, |
261 int reset_after_frame_num, | 267 int reset_after_frame_num, |
262 int delete_decoder_state, | 268 int delete_decoder_state, |
263 int frame_width, | 269 int frame_width, |
264 int frame_height, | 270 int frame_height, |
265 int profile, | 271 int profile, |
272 float target_fps, | |
Pawel Osciak
2013/07/15 08:07:06
Add doc above?
Owen Lin
2013/07/16 10:46:54
Done.
| |
266 bool suppress_rendering, | 273 bool suppress_rendering, |
267 int delay_reuse_after_frame_num); | 274 int delay_reuse_after_frame_num); |
268 virtual ~GLRenderingVDAClient(); | 275 virtual ~GLRenderingVDAClient(); |
269 void CreateDecoder(); | 276 void CreateDecoder(); |
270 | 277 |
271 // VideoDecodeAccelerator::Client implementation. | 278 // VideoDecodeAccelerator::Client implementation. |
272 // The heart of the Client. | 279 // The heart of the Client. |
273 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, | 280 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, |
274 const gfx::Size& dimensions, | 281 const gfx::Size& dimensions, |
275 uint32 texture_target) OVERRIDE; | 282 uint32 texture_target) OVERRIDE; |
(...skipping 13 matching lines...) Expand all Loading... | |
289 int num_skipped_fragments() { return num_skipped_fragments_; } | 296 int num_skipped_fragments() { return num_skipped_fragments_; } |
290 int num_queued_fragments() { return num_queued_fragments_; } | 297 int num_queued_fragments() { return num_queued_fragments_; } |
291 int num_decoded_frames() { return num_decoded_frames_; } | 298 int num_decoded_frames() { return num_decoded_frames_; } |
292 double frames_per_second(); | 299 double frames_per_second(); |
293 bool decoder_deleted() { return !decoder_.get(); } | 300 bool decoder_deleted() { return !decoder_.get(); } |
294 | 301 |
295 private: | 302 private: |
296 typedef std::map<int, media::PictureBuffer*> PictureBufferById; | 303 typedef std::map<int, media::PictureBuffer*> PictureBufferById; |
297 | 304 |
298 void SetState(ClientState new_state); | 305 void SetState(ClientState new_state); |
306 void RenderPicture(const media::Picture& picture); | |
299 | 307 |
300 // Delete the associated OMX decoder helper. | 308 // Delete the associated OMX decoder helper. |
301 void DeleteDecoder(); | 309 void DeleteDecoder(); |
302 | 310 |
303 // Compute & return the first encoded bytes (including a start frame) to send | 311 // Compute & return the first encoded bytes (including a start frame) to send |
304 // to the decoder, starting at |start_pos| and returning | 312 // to the decoder, starting at |start_pos| and returning |
305 // |num_fragments_per_decode| units. Skips to the first decodable position. | 313 // |num_fragments_per_decode| units. Skips to the first decodable position. |
306 std::string GetBytesForFirstFragments(size_t start_pos, size_t* end_pos); | 314 std::string GetBytesForFirstFragments(size_t start_pos, size_t* end_pos); |
307 // Compute & return the next encoded bytes to send to the decoder (based on | 315 // Compute & return the next encoded bytes to send to the decoder (based on |
308 // |start_pos| & |num_fragments_per_decode_|). | 316 // |start_pos| & |num_fragments_per_decode_|). |
(...skipping 24 matching lines...) Expand all Loading... | |
333 int num_skipped_fragments_; | 341 int num_skipped_fragments_; |
334 int num_queued_fragments_; | 342 int num_queued_fragments_; |
335 int num_decoded_frames_; | 343 int num_decoded_frames_; |
336 int num_done_bitstream_buffers_; | 344 int num_done_bitstream_buffers_; |
337 PictureBufferById picture_buffers_by_id_; | 345 PictureBufferById picture_buffers_by_id_; |
338 base::TimeTicks initialize_done_ticks_; | 346 base::TimeTicks initialize_done_ticks_; |
339 int profile_; | 347 int profile_; |
340 bool suppress_rendering_; | 348 bool suppress_rendering_; |
341 std::vector<base::TimeTicks> frame_delivery_times_; | 349 std::vector<base::TimeTicks> frame_delivery_times_; |
342 int delay_reuse_after_frame_num_; | 350 int delay_reuse_after_frame_num_; |
351 base::TimeTicks next_frame_delivered_time_; | |
352 base::TimeDelta frame_interval_; | |
Ami GONE FROM CHROMIUM
2013/07/15 18:54:14
s/interval/duration/
Owen Lin
2013/07/16 10:46:54
Done.
| |
353 int pending_rendering_; | |
343 }; | 354 }; |
344 | 355 |
345 GLRenderingVDAClient::GLRenderingVDAClient( | 356 GLRenderingVDAClient::GLRenderingVDAClient( |
346 RenderingHelper* rendering_helper, | 357 RenderingHelper* rendering_helper, |
347 int rendering_window_id, | 358 int rendering_window_id, |
348 ClientStateNotification* note, | 359 ClientStateNotification* note, |
349 const std::string& encoded_data, | 360 const std::string& encoded_data, |
350 int num_fragments_per_decode, | 361 int num_fragments_per_decode, |
351 int num_in_flight_decodes, | 362 int num_in_flight_decodes, |
352 int num_play_throughs, | 363 int num_play_throughs, |
353 int reset_after_frame_num, | 364 int reset_after_frame_num, |
354 int delete_decoder_state, | 365 int delete_decoder_state, |
355 int frame_width, | 366 int frame_width, |
356 int frame_height, | 367 int frame_height, |
357 int profile, | 368 int profile, |
369 float target_fps, | |
358 bool suppress_rendering, | 370 bool suppress_rendering, |
359 int delay_reuse_after_frame_num) | 371 int delay_reuse_after_frame_num) |
360 : rendering_helper_(rendering_helper), | 372 : rendering_helper_(rendering_helper), |
361 rendering_window_id_(rendering_window_id), | 373 rendering_window_id_(rendering_window_id), |
362 encoded_data_(encoded_data), | 374 encoded_data_(encoded_data), |
363 num_fragments_per_decode_(num_fragments_per_decode), | 375 num_fragments_per_decode_(num_fragments_per_decode), |
364 num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0), | 376 num_in_flight_decodes_(num_in_flight_decodes), outstanding_decodes_(0), |
365 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), | 377 encoded_data_next_pos_to_decode_(0), next_bitstream_buffer_id_(0), |
366 note_(note), | 378 note_(note), |
367 remaining_play_throughs_(num_play_throughs), | 379 remaining_play_throughs_(num_play_throughs), |
368 reset_after_frame_num_(reset_after_frame_num), | 380 reset_after_frame_num_(reset_after_frame_num), |
369 delete_decoder_state_(delete_decoder_state), | 381 delete_decoder_state_(delete_decoder_state), |
370 state_(CS_CREATED), | 382 state_(CS_CREATED), |
371 num_skipped_fragments_(0), num_queued_fragments_(0), | 383 num_skipped_fragments_(0), num_queued_fragments_(0), |
372 num_decoded_frames_(0), num_done_bitstream_buffers_(0), | 384 num_decoded_frames_(0), num_done_bitstream_buffers_(0), |
373 profile_(profile), | 385 profile_(profile), |
374 suppress_rendering_(suppress_rendering), | 386 suppress_rendering_(suppress_rendering), |
375 delay_reuse_after_frame_num_(delay_reuse_after_frame_num) { | 387 delay_reuse_after_frame_num_(delay_reuse_after_frame_num) { |
376 CHECK_GT(num_fragments_per_decode, 0); | 388 CHECK_GT(num_fragments_per_decode, 0); |
377 CHECK_GT(num_in_flight_decodes, 0); | 389 CHECK_GT(num_in_flight_decodes, 0); |
378 CHECK_GT(num_play_throughs, 0); | 390 CHECK_GT(num_play_throughs, 0); |
391 CHECK_GE(target_fps, 0); | |
392 if (target_fps > 0) | |
393 frame_interval_ = base::TimeDelta::FromSeconds(1) / target_fps; | |
379 } | 394 } |
380 | 395 |
381 GLRenderingVDAClient::~GLRenderingVDAClient() { | 396 GLRenderingVDAClient::~GLRenderingVDAClient() { |
382 DeleteDecoder(); // Clean up in case of expected error. | 397 DeleteDecoder(); // Clean up in case of expected error. |
383 CHECK(decoder_deleted()); | 398 CHECK(decoder_deleted()); |
384 STLDeleteValues(&picture_buffers_by_id_); | 399 STLDeleteValues(&picture_buffers_by_id_); |
385 SetState(CS_DESTROYED); | 400 SetState(CS_DESTROYED); |
386 } | 401 } |
387 | 402 |
388 static bool DoNothingReturnTrue() { return true; } | 403 static bool DoNothingReturnTrue() { return true; } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 delete it->second; | 467 delete it->second; |
453 picture_buffers_by_id_.erase(it); | 468 picture_buffers_by_id_.erase(it); |
454 } | 469 } |
455 | 470 |
456 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { | 471 void GLRenderingVDAClient::PictureReady(const media::Picture& picture) { |
457 // We shouldn't be getting pictures delivered after Reset has completed. | 472 // We shouldn't be getting pictures delivered after Reset has completed. |
458 CHECK_LT(state_, CS_RESET); | 473 CHECK_LT(state_, CS_RESET); |
459 | 474 |
460 if (decoder_deleted()) | 475 if (decoder_deleted()) |
461 return; | 476 return; |
462 frame_delivery_times_.push_back(base::TimeTicks::Now()); | |
463 | |
464 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); | |
465 ++num_decoded_frames_; | |
466 | 477 |
467 // Mid-stream reset applies only to the last play-through per constructor | 478 // Mid-stream reset applies only to the last play-through per constructor |
468 // comment. | 479 // comment. |
469 if (remaining_play_throughs_ == 1 && | 480 if (remaining_play_throughs_ == 1 && |
470 reset_after_frame_num_ == num_decoded_frames_) { | 481 reset_after_frame_num_ == num_decoded_frames_) { |
471 reset_after_frame_num_ = MID_STREAM_RESET; | 482 reset_after_frame_num_ = MID_STREAM_RESET; |
472 decoder_->Reset(); | 483 decoder_->Reset(); |
473 // Re-start decoding from the beginning of the stream to avoid needing to | 484 // Re-start decoding from the beginning of the stream to avoid needing to |
474 // know how to find I-frames and so on in this test. | 485 // know how to find I-frames and so on in this test. |
475 encoded_data_next_pos_to_decode_ = 0; | 486 encoded_data_next_pos_to_decode_ = 0; |
476 } | 487 } |
477 | 488 |
489 base::TimeTicks now = base::TimeTicks::Now(); | |
490 | |
491 // Play immediately if it is the first frame or there is no target_fps | |
492 if (num_decoded_frames_ == 0 || frame_interval_ == base::TimeDelta()) | |
493 next_frame_delivered_time_ = now; | |
494 | |
495 CHECK_LE(picture.bitstream_buffer_id(), next_bitstream_buffer_id_); | |
496 ++num_decoded_frames_; | |
497 | |
498 while (next_frame_delivered_time_ < now) { | |
499 // frame dropped | |
Pawel Osciak
2013/07/15 08:07:06
Actually, there might be more than one frame dropp
Owen Lin
2013/07/16 10:46:54
Done.
| |
500 next_frame_delivered_time_ += frame_interval_; | |
501 } | |
502 | |
503 base::MessageLoop::current()->PostDelayedTask( | |
504 FROM_HERE, | |
505 base::Bind(&GLRenderingVDAClient::RenderPicture, | |
506 base::Unretained(this), | |
507 picture), | |
508 next_frame_delivered_time_ - now); | |
509 next_frame_delivered_time_ += frame_interval_; | |
510 ++pending_rendering_; | |
Pawel Osciak
2013/07/15 08:07:06
There is a chance that when you loop in l.498, nex
Owen Lin
2013/07/16 10:46:54
Hi, I don't really get it. When we exit the loop i
| |
511 } | |
512 | |
513 void GLRenderingVDAClient::RenderPicture(const media::Picture& picture) { | |
514 if (decoder_deleted()) | |
515 return; | |
516 frame_delivery_times_.push_back(base::TimeTicks::Now()); | |
517 | |
Pawel Osciak
2013/07/15 08:07:06
This is render time, not frame delivery time, whic
Owen Lin
2013/07/16 10:46:54
You're right. It just makes it simple to write the
| |
478 media::PictureBuffer* picture_buffer = | 518 media::PictureBuffer* picture_buffer = |
479 picture_buffers_by_id_[picture.picture_buffer_id()]; | 519 picture_buffers_by_id_[picture.picture_buffer_id()]; |
480 CHECK(picture_buffer); | 520 CHECK(picture_buffer); |
481 if (!suppress_rendering_) { | 521 if (!suppress_rendering_) { |
482 rendering_helper_->RenderTexture(picture_buffer->texture_id()); | 522 rendering_helper_->RenderTexture(picture_buffer->texture_id()); |
483 } | 523 } |
484 | |
485 if (num_decoded_frames_ > delay_reuse_after_frame_num_) { | 524 if (num_decoded_frames_ > delay_reuse_after_frame_num_) { |
486 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind( | 525 base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind( |
487 &VideoDecodeAccelerator::ReusePictureBuffer, | 526 &VideoDecodeAccelerator::ReusePictureBuffer, |
488 base::Unretained(decoder_.get()), picture.picture_buffer_id()), | 527 base::Unretained(decoder_.get()), picture.picture_buffer_id()), |
489 base::TimeDelta::FromMilliseconds(kReuseDelayMs)); | 528 base::TimeDelta::FromMilliseconds(kReuseDelayMs)); |
490 } else { | 529 } else { |
491 decoder_->ReusePictureBuffer(picture.picture_buffer_id()); | 530 decoder_->ReusePictureBuffer(picture.picture_buffer_id()); |
492 } | 531 } |
532 if (--pending_rendering_ == 0 && state_ == CS_FLUSHED) { | |
533 SetState(CS_COMPLETE_RENDERING); | |
534 decoder_->Reset(); | |
535 SetState(CS_RESETTING); | |
536 } | |
493 } | 537 } |
494 | 538 |
495 void GLRenderingVDAClient::NotifyInitializeDone() { | 539 void GLRenderingVDAClient::NotifyInitializeDone() { |
496 SetState(CS_INITIALIZED); | 540 SetState(CS_INITIALIZED); |
497 initialize_done_ticks_ = base::TimeTicks::Now(); | 541 initialize_done_ticks_ = base::TimeTicks::Now(); |
498 for (int i = 0; i < num_in_flight_decodes_; ++i) | 542 for (int i = 0; i < num_in_flight_decodes_; ++i) |
499 DecodeNextFragments(); | 543 DecodeNextFragments(); |
500 DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_); | 544 DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_); |
501 } | 545 } |
502 | 546 |
503 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( | 547 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( |
504 int32 bitstream_buffer_id) { | 548 int32 bitstream_buffer_id) { |
505 // TODO(fischman): this test currently relies on this notification to make | 549 // TODO(fischman): this test currently relies on this notification to make |
506 // forward progress during a Reset(). But the VDA::Reset() API doesn't | 550 // forward progress during a Reset(). But the VDA::Reset() API doesn't |
507 // guarantee this, so stop relying on it (and remove the notifications from | 551 // guarantee this, so stop relying on it (and remove the notifications from |
508 // VaapiVideoDecodeAccelerator::FinishReset()). | 552 // VaapiVideoDecodeAccelerator::FinishReset()). |
509 ++num_done_bitstream_buffers_; | 553 ++num_done_bitstream_buffers_; |
510 --outstanding_decodes_; | 554 --outstanding_decodes_; |
511 DecodeNextFragments(); | 555 DecodeNextFragments(); |
512 } | 556 } |
513 | 557 |
514 void GLRenderingVDAClient::NotifyFlushDone() { | 558 void GLRenderingVDAClient::NotifyFlushDone() { |
515 if (decoder_deleted()) | 559 if (decoder_deleted()) |
516 return; | 560 return; |
517 SetState(CS_FLUSHED); | 561 SetState(CS_FLUSHED); |
518 --remaining_play_throughs_; | 562 --remaining_play_throughs_; |
519 DCHECK_GE(remaining_play_throughs_, 0); | 563 DCHECK_GE(remaining_play_throughs_, 0); |
520 if (decoder_deleted()) | 564 if (decoder_deleted()) |
521 return; | 565 return; |
522 decoder_->Reset(); | 566 if (pending_rendering_ == 0) { |
Ami GONE FROM CHROMIUM
2013/07/15 18:54:14
Why do none of the other notifications test for th
Owen Lin
2013/07/16 10:46:54
I don't get it. Can you be more specific ?
Do you
| |
523 SetState(CS_RESETTING); | 567 SetState(CS_COMPLETE_RENDERING); |
568 decoder_->Reset(); | |
569 SetState(CS_RESETTING); | |
Ami GONE FROM CHROMIUM
2013/07/15 18:54:14
Duplicating this block here and at l.532 is a code
Owen Lin
2013/07/16 10:46:54
Do you suggest me the following:
if (pending_rend
| |
570 } | |
524 } | 571 } |
525 | 572 |
526 void GLRenderingVDAClient::NotifyResetDone() { | 573 void GLRenderingVDAClient::NotifyResetDone() { |
527 if (decoder_deleted()) | 574 if (decoder_deleted()) |
528 return; | 575 return; |
529 | 576 |
530 if (reset_after_frame_num_ == MID_STREAM_RESET) { | 577 if (reset_after_frame_num_ == MID_STREAM_RESET) { |
531 reset_after_frame_num_ = END_OF_STREAM_RESET; | 578 reset_after_frame_num_ = END_OF_STREAM_RESET; |
532 DecodeNextFragments(); | 579 DecodeNextFragments(); |
533 return; | 580 return; |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
718 // - whether to test slow rendering by delaying ReusePictureBuffer(). | 765 // - whether to test slow rendering by delaying ReusePictureBuffer(). |
719 class VideoDecodeAcceleratorTest | 766 class VideoDecodeAcceleratorTest |
720 : public ::testing::TestWithParam< | 767 : public ::testing::TestWithParam< |
721 Tuple7<int, int, int, int, ResetPoint, ClientState, bool> > { | 768 Tuple7<int, int, int, int, ResetPoint, ClientState, bool> > { |
722 }; | 769 }; |
723 | 770 |
724 // Helper so that gtest failures emit a more readable version of the tuple than | 771 // Helper so that gtest failures emit a more readable version of the tuple than |
725 // its byte representation. | 772 // its byte representation. |
726 ::std::ostream& operator<<( | 773 ::std::ostream& operator<<( |
727 ::std::ostream& os, | 774 ::std::ostream& os, |
728 const Tuple6<int, int, int, int, ResetPoint, ClientState>& t) { | 775 const Tuple7<int, int, int, int, ResetPoint, ClientState, bool>& t) { |
729 return os << t.a << ", " << t.b << ", " << t.c << ", " << t.d << ", " << t.e | 776 return os << t.a << ", " << t.b << ", " << t.c << ", " << t.d << ", " << t.e |
730 << ", " << t.f; | 777 << ", " << t.f << ", " << t.g; |
731 } | 778 } |
732 | 779 |
733 // Wait for |note| to report a state and if it's not |expected_state| then | 780 // Wait for |note| to report a state and if it's not |expected_state| then |
734 // assert |client| has deleted its decoder. | 781 // assert |client| has deleted its decoder. |
735 static void AssertWaitForStateOrDeleted(ClientStateNotification* note, | 782 static void AssertWaitForStateOrDeleted(ClientStateNotification* note, |
736 GLRenderingVDAClient* client, | 783 GLRenderingVDAClient* client, |
737 ClientState expected_state) { | 784 ClientState expected_state) { |
738 ClientState state = note->Wait(); | 785 ClientState state = note->Wait(); |
739 if (state == expected_state) return; | 786 if (state == expected_state) return; |
740 ASSERT_TRUE(client->decoder_deleted()) | 787 ASSERT_TRUE(client->decoder_deleted()) |
741 << "Decoder not deleted but Wait() returned " << state | 788 << "Decoder not deleted but Wait() returned " << state |
742 << ", instead of " << expected_state; | 789 << ", instead of " << expected_state; |
743 } | 790 } |
744 | 791 |
745 // We assert a minimal number of concurrent decoders we expect to succeed. | 792 // We assert a minimal number of concurrent decoders we expect to succeed. |
746 // Different platforms can support more concurrent decoders, so we don't assert | 793 // Different platforms can support more concurrent decoders, so we don't assert |
747 // failure above this. | 794 // failure above this. |
748 enum { kMinSupportedNumConcurrentDecoders = 3 }; | 795 enum { kMinSupportedNumConcurrentDecoders = 3 }; |
749 | 796 |
750 // Test the most straightforward case possible: data is decoded from a single | 797 // Test the most straightforward case possible: data is decoded from a single |
751 // chunk and rendered to the screen. | 798 // chunk and rendered to the screen. |
752 TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { | 799 TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) { |
753 // Can be useful for debugging VLOGs from OVDA. | |
754 // logging::SetMinLogLevel(-1); | |
755 | |
756 // Required for Thread to work. Not used otherwise. | 800 // Required for Thread to work. Not used otherwise. |
757 base::ShadowingAtExitManager at_exit_manager; | 801 base::ShadowingAtExitManager at_exit_manager; |
758 | 802 |
759 const int num_fragments_per_decode = GetParam().a; | 803 const int num_fragments_per_decode = GetParam().a; |
760 const size_t num_concurrent_decoders = GetParam().b; | 804 const size_t num_concurrent_decoders = GetParam().b; |
761 const size_t num_in_flight_decodes = GetParam().c; | 805 const size_t num_in_flight_decodes = GetParam().c; |
762 const int num_play_throughs = GetParam().d; | 806 const int num_play_throughs = GetParam().d; |
763 const int reset_point = GetParam().e; | 807 const int reset_point = GetParam().e; |
764 const int delete_decoder_state = GetParam().f; | 808 const int delete_decoder_state = GetParam().f; |
765 bool test_reuse_delay = GetParam().g; | 809 bool test_reuse_delay = GetParam().g; |
766 | 810 |
767 std::vector<TestVideoFile*> test_video_files; | 811 std::vector<TestVideoFile*> test_video_files; |
768 ParseAndReadTestVideoData(test_video_data, num_concurrent_decoders, | 812 ParseAndReadTestVideoData(test_video_data, num_concurrent_decoders, |
769 reset_point, &test_video_files); | 813 reset_point, &test_video_files); |
770 | 814 |
771 // Suppress GL rendering when we are logging the frame delivery time and a | 815 // Suppress GL rendering when we are logging the frame delivery time and a |
772 // few other tests, to cut down overall test runtime. | 816 // few other tests, to cut down overall test runtime. |
773 const bool suppress_rendering = num_fragments_per_decode > 1 || | 817 const bool suppress_rendering = num_fragments_per_decode > 1 || |
774 frame_delivery_log != NULL; | 818 content::disable_rendering; |
775 | 819 |
776 std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL); | 820 std::vector<ClientStateNotification*> notes(num_concurrent_decoders, NULL); |
777 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); | 821 std::vector<GLRenderingVDAClient*> clients(num_concurrent_decoders, NULL); |
778 | 822 |
779 // Initialize the rendering helper. | 823 // Initialize the rendering helper. |
780 base::Thread rendering_thread("GLRenderingVDAClientThread"); | 824 base::Thread rendering_thread("GLRenderingVDAClientThread"); |
781 base::Thread::Options options; | 825 base::Thread::Options options; |
782 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | 826 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; |
783 #if defined(OS_WIN) | 827 #if defined(OS_WIN) |
784 // For windows the decoding thread initializes the media foundation decoder | 828 // For windows the decoding thread initializes the media foundation decoder |
(...skipping 29 matching lines...) Expand all Loading... | |
814 if (test_reuse_delay && | 858 if (test_reuse_delay && |
815 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { | 859 kMaxFramesToDelayReuse * 2 < video_file->num_frames) { |
816 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; | 860 delay_after_frame_num = video_file->num_frames - kMaxFramesToDelayReuse; |
817 } | 861 } |
818 | 862 |
819 GLRenderingVDAClient* client = new GLRenderingVDAClient( | 863 GLRenderingVDAClient* client = new GLRenderingVDAClient( |
820 rendering_helper.get(), index, note, video_file->data_str, | 864 rendering_helper.get(), index, note, video_file->data_str, |
821 num_fragments_per_decode, num_in_flight_decodes, num_play_throughs, | 865 num_fragments_per_decode, num_in_flight_decodes, num_play_throughs, |
822 video_file->reset_after_frame_num, delete_decoder_state, | 866 video_file->reset_after_frame_num, delete_decoder_state, |
823 video_file->width, video_file->height, video_file->profile, | 867 video_file->width, video_file->height, video_file->profile, |
824 suppress_rendering, delay_after_frame_num); | 868 target_fps, suppress_rendering, delay_after_frame_num); |
825 clients[index] = client; | 869 clients[index] = client; |
826 | 870 |
827 rendering_thread.message_loop()->PostTask( | 871 rendering_thread.message_loop()->PostTask( |
828 FROM_HERE, | 872 FROM_HERE, |
829 base::Bind(&GLRenderingVDAClient::CreateDecoder, | 873 base::Bind(&GLRenderingVDAClient::CreateDecoder, |
830 base::Unretained(client))); | 874 base::Unretained(client))); |
831 | 875 |
832 ASSERT_EQ(note->Wait(), CS_DECODER_SET); | 876 ASSERT_EQ(note->Wait(), CS_DECODER_SET); |
833 } | 877 } |
834 // Then wait for all the decodes to finish. | 878 // Then wait for all the decodes to finish. |
(...skipping 18 matching lines...) Expand all Loading... | |
853 if (n > 0) { | 897 if (n > 0) { |
854 ASSERT_NO_FATAL_FAILURE( | 898 ASSERT_NO_FATAL_FAILURE( |
855 AssertWaitForStateOrDeleted(note, clients[i], CS_INITIALIZED)); | 899 AssertWaitForStateOrDeleted(note, clients[i], CS_INITIALIZED)); |
856 } | 900 } |
857 // InitializeDone kicks off decoding inside the client, so we just need to | 901 // InitializeDone kicks off decoding inside the client, so we just need to |
858 // wait for Flush. | 902 // wait for Flush. |
859 ASSERT_NO_FATAL_FAILURE( | 903 ASSERT_NO_FATAL_FAILURE( |
860 AssertWaitForStateOrDeleted(note, clients[i], CS_FLUSHING)); | 904 AssertWaitForStateOrDeleted(note, clients[i], CS_FLUSHING)); |
861 ASSERT_NO_FATAL_FAILURE( | 905 ASSERT_NO_FATAL_FAILURE( |
862 AssertWaitForStateOrDeleted(note, clients[i], CS_FLUSHED)); | 906 AssertWaitForStateOrDeleted(note, clients[i], CS_FLUSHED)); |
863 // FlushDone requests Reset(). | 907 ASSERT_NO_FATAL_FAILURE( |
908 AssertWaitForStateOrDeleted(note, clients[i], CS_COMPLETE_RENDERING)); | |
864 ASSERT_NO_FATAL_FAILURE( | 909 ASSERT_NO_FATAL_FAILURE( |
865 AssertWaitForStateOrDeleted(note, clients[i], CS_RESETTING)); | 910 AssertWaitForStateOrDeleted(note, clients[i], CS_RESETTING)); |
866 } | 911 } |
867 ASSERT_NO_FATAL_FAILURE( | 912 ASSERT_NO_FATAL_FAILURE( |
868 AssertWaitForStateOrDeleted(note, clients[i], CS_RESET)); | 913 AssertWaitForStateOrDeleted(note, clients[i], CS_RESET)); |
914 | |
869 // ResetDone requests Destroy(). | 915 // ResetDone requests Destroy(). |
870 ASSERT_NO_FATAL_FAILURE( | 916 ASSERT_NO_FATAL_FAILURE( |
871 AssertWaitForStateOrDeleted(note, clients[i], CS_DESTROYED)); | 917 AssertWaitForStateOrDeleted(note, clients[i], CS_DESTROYED)); |
872 } | 918 } |
873 // Finally assert that decoding went as expected. | 919 // Finally assert that decoding went as expected. |
874 for (size_t i = 0; i < num_concurrent_decoders && | 920 for (size_t i = 0; i < num_concurrent_decoders && |
875 !skip_performance_and_correctness_checks; ++i) { | 921 !skip_performance_and_correctness_checks; ++i) { |
876 // We can only make performance/correctness assertions if the decoder was | 922 // We can only make performance/correctness assertions if the decoder was |
877 // allowed to finish. | 923 // allowed to finish. |
878 if (delete_decoder_state < CS_FLUSHED) | 924 if (delete_decoder_state < CS_FLUSHED) |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1032 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); | 1078 for (CommandLine::SwitchMap::const_iterator it = switches.begin(); |
1033 it != switches.end(); ++it) { | 1079 it != switches.end(); ++it) { |
1034 if (it->first == "test_video_data") { | 1080 if (it->first == "test_video_data") { |
1035 content::test_video_data = it->second.c_str(); | 1081 content::test_video_data = it->second.c_str(); |
1036 continue; | 1082 continue; |
1037 } | 1083 } |
1038 if (it->first == "frame_delivery_log") { | 1084 if (it->first == "frame_delivery_log") { |
1039 content::frame_delivery_log = it->second.c_str(); | 1085 content::frame_delivery_log = it->second.c_str(); |
1040 continue; | 1086 continue; |
1041 } | 1087 } |
1088 if (it->first == "target_fps") { | |
1089 double input_value = 0; | |
1090 CHECK(base::StringToDouble(it->second, &input_value)); | |
1091 content::target_fps = static_cast<float>(input_value); | |
Ami GONE FROM CHROMIUM
2013/07/15 18:54:14
why not just use double instead of float and avoid
Owen Lin
2013/07/16 10:46:54
Done.
| |
1092 continue; | |
1093 } | |
1094 if (it->first == "disable_rendering") { | |
1095 content::disable_rendering = true; | |
1096 continue; | |
1097 } | |
1042 if (it->first == "v" || it->first == "vmodule") | 1098 if (it->first == "v" || it->first == "vmodule") |
1043 continue; | 1099 continue; |
1044 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; | 1100 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; |
1045 } | 1101 } |
1046 | 1102 |
1047 base::ShadowingAtExitManager at_exit_manager; | 1103 base::ShadowingAtExitManager at_exit_manager; |
1048 | 1104 |
1049 #if defined(OS_WIN) | 1105 #if defined(OS_WIN) |
1050 content::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); | 1106 content::DXVAVideoDecodeAccelerator::PreSandboxInitialization(); |
1051 #elif defined(OS_CHROMEOS) | 1107 #elif defined(OS_CHROMEOS) |
1052 #if defined(ARCH_CPU_ARMEL) | 1108 #if defined(ARCH_CPU_ARMEL) |
1053 content::ExynosVideoDecodeAccelerator::PreSandboxInitialization(); | 1109 content::ExynosVideoDecodeAccelerator::PreSandboxInitialization(); |
1054 #elif defined(ARCH_CPU_X86_FAMILY) | 1110 #elif defined(ARCH_CPU_X86_FAMILY) |
1055 content::VaapiWrapper::PreSandboxInitialization(); | 1111 content::VaapiWrapper::PreSandboxInitialization(); |
1056 #endif // ARCH_CPU_ARMEL | 1112 #endif // ARCH_CPU_ARMEL |
1057 #endif // OS_CHROMEOS | 1113 #endif // OS_CHROMEOS |
1058 | 1114 |
1059 return RUN_ALL_TESTS(); | 1115 return RUN_ALL_TESTS(); |
1060 } | 1116 } |
OLD | NEW |