Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: content/common/gpu/media/video_decode_accelerator_unittest.cc

Issue 185403020: Make VEA client of command buffer; move sync. IPC to VDA/VEA::Initialize() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 7da5b6ec Rebase. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 double fps, 209 double fps,
210 ReusePictureCB reuse_picture_cb); 210 ReusePictureCB reuse_picture_cb);
211 virtual ~ThrottlingVDAClient(); 211 virtual ~ThrottlingVDAClient();
212 212
213 // VideoDecodeAccelerator::Client implementation 213 // VideoDecodeAccelerator::Client implementation
214 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, 214 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers,
215 const gfx::Size& dimensions, 215 const gfx::Size& dimensions,
216 uint32 texture_target) OVERRIDE; 216 uint32 texture_target) OVERRIDE;
217 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; 217 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE;
218 virtual void PictureReady(const media::Picture& picture) OVERRIDE; 218 virtual void PictureReady(const media::Picture& picture) OVERRIDE;
219 virtual void NotifyInitializeDone() OVERRIDE;
220 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; 219 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE;
221 virtual void NotifyFlushDone() OVERRIDE; 220 virtual void NotifyFlushDone() OVERRIDE;
222 virtual void NotifyResetDone() OVERRIDE; 221 virtual void NotifyResetDone() OVERRIDE;
223 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; 222 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE;
224 223
225 int num_decoded_frames() { return num_decoded_frames_; } 224 int num_decoded_frames() { return num_decoded_frames_; }
226 225
227 private: 226 private:
228 227
229 void CallClientPictureReady(int version); 228 void CallClientPictureReady(int version);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 if (!pending_pictures_.empty()) { 304 if (!pending_pictures_.empty()) {
306 base::MessageLoop::current()->PostDelayedTask( 305 base::MessageLoop::current()->PostDelayedTask(
307 FROM_HERE, 306 FROM_HERE,
308 base::Bind(&ThrottlingVDAClient::CallClientPictureReady, 307 base::Bind(&ThrottlingVDAClient::CallClientPictureReady,
309 AsWeakPtr(), 308 AsWeakPtr(),
310 stream_version_), 309 stream_version_),
311 next_frame_delivered_time_ - base::TimeTicks::Now()); 310 next_frame_delivered_time_ - base::TimeTicks::Now());
312 } 311 }
313 } 312 }
314 313
315 void ThrottlingVDAClient::NotifyInitializeDone() {
316 client_->NotifyInitializeDone();
317 }
318
319 void ThrottlingVDAClient::NotifyEndOfBitstreamBuffer( 314 void ThrottlingVDAClient::NotifyEndOfBitstreamBuffer(
320 int32 bitstream_buffer_id) { 315 int32 bitstream_buffer_id) {
321 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); 316 client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id);
322 } 317 }
323 318
324 void ThrottlingVDAClient::NotifyFlushDone() { 319 void ThrottlingVDAClient::NotifyFlushDone() {
325 if (!pending_pictures_.empty()) { 320 if (!pending_pictures_.empty()) {
326 base::MessageLoop::current()->PostDelayedTask( 321 base::MessageLoop::current()->PostDelayedTask(
327 FROM_HERE, 322 FROM_HERE,
328 base::Bind(&ThrottlingVDAClient::NotifyFlushDone, 323 base::Bind(&ThrottlingVDAClient::NotifyFlushDone,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 void CreateAndStartDecoder(); 385 void CreateAndStartDecoder();
391 386
392 // VideoDecodeAccelerator::Client implementation. 387 // VideoDecodeAccelerator::Client implementation.
393 // The heart of the Client. 388 // The heart of the Client.
394 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, 389 virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers,
395 const gfx::Size& dimensions, 390 const gfx::Size& dimensions,
396 uint32 texture_target) OVERRIDE; 391 uint32 texture_target) OVERRIDE;
397 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; 392 virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE;
398 virtual void PictureReady(const media::Picture& picture) OVERRIDE; 393 virtual void PictureReady(const media::Picture& picture) OVERRIDE;
399 // Simple state changes. 394 // Simple state changes.
400 virtual void NotifyInitializeDone() OVERRIDE;
401 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; 395 virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE;
402 virtual void NotifyFlushDone() OVERRIDE; 396 virtual void NotifyFlushDone() OVERRIDE;
403 virtual void NotifyResetDone() OVERRIDE; 397 virtual void NotifyResetDone() OVERRIDE;
404 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE; 398 virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE;
405 399
406 void OutputFrameDeliveryTimes(base::File* output); 400 void OutputFrameDeliveryTimes(base::File* output);
407 401
408 void NotifyFrameDropped(int32 picture_buffer_id); 402 void NotifyFrameDropped(int32 picture_buffer_id);
409 403
410 // Simple getters for inspecting the state of the Client. 404 // Simple getters for inspecting the state of the Client.
411 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; } 405 int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; }
412 int num_skipped_fragments() { return num_skipped_fragments_; } 406 int num_skipped_fragments() { return num_skipped_fragments_; }
413 int num_queued_fragments() { return num_queued_fragments_; } 407 int num_queued_fragments() { return num_queued_fragments_; }
414 int num_decoded_frames(); 408 int num_decoded_frames();
415 double frames_per_second(); 409 double frames_per_second();
416 // Return the median of the decode time in milliseconds. 410 // Return the median of the decode time in milliseconds.
417 int decode_time_median(); 411 int decode_time_median();
418 bool decoder_deleted() { return !decoder_.get(); } 412 bool decoder_deleted() { return !decoder_.get(); }
419 413
420 private: 414 private:
421 typedef std::map<int, media::PictureBuffer*> PictureBufferById; 415 typedef std::map<int, media::PictureBuffer*> PictureBufferById;
422 416
423 void SetState(ClientState new_state); 417 void SetState(ClientState new_state);
418 void FinishInitialization();
424 419
425 // Delete the associated decoder helper. 420 // Delete the associated decoder helper.
426 void DeleteDecoder(); 421 void DeleteDecoder();
427 422
428 // Compute & return the first encoded bytes (including a start frame) to send 423 // Compute & return the first encoded bytes (including a start frame) to send
429 // to the decoder, starting at |start_pos| and returning one fragment. Skips 424 // to the decoder, starting at |start_pos| and returning one fragment. Skips
430 // to the first decodable position. 425 // to the first decodable position.
431 std::string GetBytesForFirstFragment(size_t start_pos, size_t* end_pos); 426 std::string GetBytesForFirstFragment(size_t start_pos, size_t* end_pos);
432 // Compute & return the encoded bytes of next fragment to send to the decoder 427 // Compute & return the encoded bytes of next fragment to send to the decoder
433 // (based on |start_pos|). 428 // (based on |start_pos|).
434 std::string GetBytesForNextFragment(size_t start_pos, size_t* end_pos); 429 std::string GetBytesForNextFragment(size_t start_pos, size_t* end_pos);
435 // Helpers for GetBytesForNextFragment above. 430 // Helpers for GetBytesForNextFragment above.
436 void GetBytesForNextNALU(size_t start_pos, size_t* end_pos); // For h.264. 431 void GetBytesForNextNALU(size_t start_pos, size_t* end_pos); // For h.264.
437 std::string GetBytesForNextFrame( 432 std::string GetBytesForNextFrame(
438 size_t start_pos, size_t* end_pos); // For VP8. 433 size_t start_pos, size_t* end_pos); // For VP8.
439 434
440 // Request decode of the next fragment in the encoded data. 435 // Request decode of the next fragment in the encoded data.
441 void DecodeNextFragment(); 436 void DecodeNextFragment();
442 437
443 RenderingHelper* rendering_helper_; 438 RenderingHelper* rendering_helper_;
444 int rendering_window_id_; 439 int rendering_window_id_;
445 std::string encoded_data_; 440 std::string encoded_data_;
446 const int num_in_flight_decodes_; 441 const int num_in_flight_decodes_;
447 int outstanding_decodes_; 442 int outstanding_decodes_;
448 size_t encoded_data_next_pos_to_decode_; 443 size_t encoded_data_next_pos_to_decode_;
449 int next_bitstream_buffer_id_; 444 int next_bitstream_buffer_id_;
450 ClientStateNotification<ClientState>* note_; 445 ClientStateNotification<ClientState>* note_;
451 scoped_ptr<VideoDecodeAccelerator> decoder_; 446 scoped_ptr<VideoDecodeAccelerator> decoder_;
447 scoped_ptr<base::WeakPtrFactory<VideoDecodeAccelerator> >
448 weak_decoder_factory_;
452 std::set<int> outstanding_texture_ids_; 449 std::set<int> outstanding_texture_ids_;
453 int remaining_play_throughs_; 450 int remaining_play_throughs_;
454 int reset_after_frame_num_; 451 int reset_after_frame_num_;
455 int delete_decoder_state_; 452 int delete_decoder_state_;
456 ClientState state_; 453 ClientState state_;
457 int num_skipped_fragments_; 454 int num_skipped_fragments_;
458 int num_queued_fragments_; 455 int num_queued_fragments_;
459 int num_decoded_frames_; 456 int num_decoded_frames_;
460 int num_done_bitstream_buffers_; 457 int num_done_bitstream_buffers_;
461 PictureBufferById picture_buffers_by_id_; 458 PictureBufferById picture_buffers_by_id_;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 device.Pass(), 566 device.Pass(),
570 base::MessageLoopProxy::current())); 567 base::MessageLoopProxy::current()));
571 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) 568 #elif defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY)
572 CHECK_EQ(gfx::kGLImplementationDesktopGL, gfx::GetGLImplementation()) 569 CHECK_EQ(gfx::kGLImplementationDesktopGL, gfx::GetGLImplementation())
573 << "Hardware video decode does not work with OSMesa"; 570 << "Hardware video decode does not work with OSMesa";
574 decoder_.reset(new VaapiVideoDecodeAccelerator( 571 decoder_.reset(new VaapiVideoDecodeAccelerator(
575 static_cast<Display*>(rendering_helper_->GetGLDisplay()), 572 static_cast<Display*>(rendering_helper_->GetGLDisplay()),
576 base::Bind(&DoNothingReturnTrue))); 573 base::Bind(&DoNothingReturnTrue)));
577 #endif // OS_WIN 574 #endif // OS_WIN
578 CHECK(decoder_.get()); 575 CHECK(decoder_.get());
576 weak_decoder_factory_.reset(
577 new base::WeakPtrFactory<VideoDecodeAccelerator>(decoder_.get()));
579 SetState(CS_DECODER_SET); 578 SetState(CS_DECODER_SET);
580 if (decoder_deleted()) 579 if (decoder_deleted())
581 return; 580 return;
582 581
583 CHECK(decoder_->Initialize(profile_, client)); 582 CHECK(decoder_->Initialize(profile_, client));
583 FinishInitialization();
584 } 584 }
585 585
586 void GLRenderingVDAClient::ProvidePictureBuffers( 586 void GLRenderingVDAClient::ProvidePictureBuffers(
587 uint32 requested_num_of_buffers, 587 uint32 requested_num_of_buffers,
588 const gfx::Size& dimensions, 588 const gfx::Size& dimensions,
589 uint32 texture_target) { 589 uint32 texture_target) {
590 if (decoder_deleted()) 590 if (decoder_deleted())
591 return; 591 return;
592 std::vector<media::PictureBuffer> buffers; 592 std::vector<media::PictureBuffer> buffers;
593 593
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 CHECK(picture_buffer); 653 CHECK(picture_buffer);
654 if (!suppress_rendering_) { 654 if (!suppress_rendering_) {
655 rendering_helper_->RenderTexture(texture_target_, 655 rendering_helper_->RenderTexture(texture_target_,
656 picture_buffer->texture_id()); 656 picture_buffer->texture_id());
657 } 657 }
658 658
659 if (num_decoded_frames() > delay_reuse_after_frame_num_) { 659 if (num_decoded_frames() > delay_reuse_after_frame_num_) {
660 base::MessageLoop::current()->PostDelayedTask( 660 base::MessageLoop::current()->PostDelayedTask(
661 FROM_HERE, 661 FROM_HERE,
662 base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer, 662 base::Bind(&VideoDecodeAccelerator::ReusePictureBuffer,
663 decoder_->AsWeakPtr(), 663 weak_decoder_factory_->GetWeakPtr(),
664 picture.picture_buffer_id()), 664 picture.picture_buffer_id()),
665 kReuseDelay); 665 kReuseDelay);
666 } else { 666 } else {
667 decoder_->ReusePictureBuffer(picture.picture_buffer_id()); 667 decoder_->ReusePictureBuffer(picture.picture_buffer_id());
668 } 668 }
669 } 669 }
670 670
671 void GLRenderingVDAClient::NotifyInitializeDone() {
672 SetState(CS_INITIALIZED);
673 initialize_done_ticks_ = base::TimeTicks::Now();
674
675 if (reset_after_frame_num_ == START_OF_STREAM_RESET) {
676 reset_after_frame_num_ = MID_STREAM_RESET;
677 decoder_->Reset();
678 return;
679 }
680
681 for (int i = 0; i < num_in_flight_decodes_; ++i)
682 DecodeNextFragment();
683 DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_);
684 }
685
686 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer( 671 void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer(
687 int32 bitstream_buffer_id) { 672 int32 bitstream_buffer_id) {
688 // TODO(fischman): this test currently relies on this notification to make 673 // TODO(fischman): this test currently relies on this notification to make
689 // forward progress during a Reset(). But the VDA::Reset() API doesn't 674 // forward progress during a Reset(). But the VDA::Reset() API doesn't
690 // guarantee this, so stop relying on it (and remove the notifications from 675 // guarantee this, so stop relying on it (and remove the notifications from
691 // VaapiVideoDecodeAccelerator::FinishReset()). 676 // VaapiVideoDecodeAccelerator::FinishReset()).
692 ++num_done_bitstream_buffers_; 677 ++num_done_bitstream_buffers_;
693 --outstanding_decodes_; 678 --outstanding_decodes_;
694 if (decode_calls_per_second_ == 0) 679 if (decode_calls_per_second_ == 0)
695 DecodeNextFragment(); 680 DecodeNextFragment();
(...skipping 21 matching lines...) Expand all
717 return; 702 return;
718 } else if (reset_after_frame_num_ == START_OF_STREAM_RESET) { 703 } else if (reset_after_frame_num_ == START_OF_STREAM_RESET) {
719 reset_after_frame_num_ = END_OF_STREAM_RESET; 704 reset_after_frame_num_ = END_OF_STREAM_RESET;
720 for (int i = 0; i < num_in_flight_decodes_; ++i) 705 for (int i = 0; i < num_in_flight_decodes_; ++i)
721 DecodeNextFragment(); 706 DecodeNextFragment();
722 return; 707 return;
723 } 708 }
724 709
725 if (remaining_play_throughs_) { 710 if (remaining_play_throughs_) {
726 encoded_data_next_pos_to_decode_ = 0; 711 encoded_data_next_pos_to_decode_ = 0;
727 NotifyInitializeDone(); 712 FinishInitialization();
728 return; 713 return;
729 } 714 }
730 715
731 SetState(CS_RESET); 716 SetState(CS_RESET);
732 if (!decoder_deleted()) 717 if (!decoder_deleted())
733 DeleteDecoder(); 718 DeleteDecoder();
734 } 719 }
735 720
736 void GLRenderingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) { 721 void GLRenderingVDAClient::NotifyError(VideoDecodeAccelerator::Error error) {
737 SetState(CS_ERROR); 722 SetState(CS_ERROR);
(...skipping 24 matching lines...) Expand all
762 747
763 void GLRenderingVDAClient::SetState(ClientState new_state) { 748 void GLRenderingVDAClient::SetState(ClientState new_state) {
764 note_->Notify(new_state); 749 note_->Notify(new_state);
765 state_ = new_state; 750 state_ = new_state;
766 if (!remaining_play_throughs_ && new_state == delete_decoder_state_) { 751 if (!remaining_play_throughs_ && new_state == delete_decoder_state_) {
767 CHECK(!decoder_deleted()); 752 CHECK(!decoder_deleted());
768 DeleteDecoder(); 753 DeleteDecoder();
769 } 754 }
770 } 755 }
771 756
757 void GLRenderingVDAClient::FinishInitialization() {
758 SetState(CS_INITIALIZED);
759 initialize_done_ticks_ = base::TimeTicks::Now();
760
761 if (reset_after_frame_num_ == START_OF_STREAM_RESET) {
762 reset_after_frame_num_ = MID_STREAM_RESET;
763 decoder_->Reset();
764 return;
765 }
766
767 for (int i = 0; i < num_in_flight_decodes_; ++i)
768 DecodeNextFragment();
769 DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_);
770 }
771
772 void GLRenderingVDAClient::DeleteDecoder() { 772 void GLRenderingVDAClient::DeleteDecoder() {
773 if (decoder_deleted()) 773 if (decoder_deleted())
774 return; 774 return;
775 weak_decoder_factory_.reset();
775 decoder_.release()->Destroy(); 776 decoder_.release()->Destroy();
776 STLClearObject(&encoded_data_); 777 STLClearObject(&encoded_data_);
777 for (std::set<int>::iterator it = outstanding_texture_ids_.begin(); 778 for (std::set<int>::iterator it = outstanding_texture_ids_.begin();
778 it != outstanding_texture_ids_.end(); ++it) { 779 it != outstanding_texture_ids_.end(); ++it) {
779 rendering_helper_->DeleteTexture(*it); 780 rendering_helper_->DeleteTexture(*it);
780 } 781 }
781 outstanding_texture_ids_.clear(); 782 outstanding_texture_ids_.clear();
782 // Cascade through the rest of the states to simplify test code below. 783 // Cascade through the rest of the states to simplify test code below.
783 for (int i = state_ + 1; i < CS_MAX; ++i) 784 for (int i = state_ + 1; i < CS_MAX; ++i)
784 SetState(static_cast<ClientState>(i)); 785 SetState(static_cast<ClientState>(i));
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 } 1570 }
1570 if (it->first == "v" || it->first == "vmodule") 1571 if (it->first == "v" || it->first == "vmodule")
1571 continue; 1572 continue;
1572 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second; 1573 LOG(FATAL) << "Unexpected switch: " << it->first << ":" << it->second;
1573 } 1574 }
1574 1575
1575 base::ShadowingAtExitManager at_exit_manager; 1576 base::ShadowingAtExitManager at_exit_manager;
1576 1577
1577 return RUN_ALL_TESTS(); 1578 return RUN_ALL_TESTS();
1578 } 1579 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698