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

Side by Side Diff: media/gpu/android_video_decode_accelerator.cc

Issue 2487813002: Remove delayed error posting from AndroidVideoDecodeAccelerator (Closed)
Patch Set: Rebase Created 4 years, 1 month 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
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/avda_picture_buffer_manager.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 #include "media/gpu/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
(...skipping 28 matching lines...) Expand all
39 #include "media/gpu/shared_memory_region.h" 39 #include "media/gpu/shared_memory_region.h"
40 #include "media/video/picture.h" 40 #include "media/video/picture.h"
41 #include "ui/gl/android/scoped_java_surface.h" 41 #include "ui/gl/android/scoped_java_surface.h"
42 #include "ui/gl/android/surface_texture.h" 42 #include "ui/gl/android/surface_texture.h"
43 #include "ui/gl/gl_bindings.h" 43 #include "ui/gl/gl_bindings.h"
44 44
45 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 45 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
46 #include "media/mojo/services/mojo_cdm_service.h" 46 #include "media/mojo/services/mojo_cdm_service.h"
47 #endif 47 #endif
48 48
49 #define POST_ERROR(error_code, error_message) \ 49 #define NOTIFY_ERROR(error_code, error_message) \
50 do { \ 50 do { \
51 DLOG(ERROR) << error_message; \ 51 DLOG(ERROR) << error_message; \
52 PostError(FROM_HERE, VideoDecodeAccelerator::error_code); \ 52 NotifyError(VideoDecodeAccelerator::error_code); \
53 } while (0) 53 } while (0)
54 54
55 namespace media { 55 namespace media {
56 56
57 namespace { 57 namespace {
58 58
59 enum { kNumPictureBuffers = limits::kMaxVideoFrames + 1 }; 59 enum { kNumPictureBuffers = limits::kMaxVideoFrames + 1 };
60 60
61 // Max number of bitstreams notified to the client with 61 // Max number of bitstreams notified to the client with
62 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. 62 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 // pictures have been fed to saturate any internal buffering). This is 99 // pictures have been fed to saturate any internal buffering). This is
100 // speculative and it's unclear that this would be a win (nor that there's a 100 // speculative and it's unclear that this would be a win (nor that there's a
101 // reasonably device-agnostic way to fill in the "believes" above). 101 // reasonably device-agnostic way to fill in the "believes" above).
102 constexpr base::TimeDelta DecodePollDelay = 102 constexpr base::TimeDelta DecodePollDelay =
103 base::TimeDelta::FromMilliseconds(10); 103 base::TimeDelta::FromMilliseconds(10);
104 104
105 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); 105 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0);
106 106
107 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); 107 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1);
108 108
109 // Time between when we notice an error, and when we actually notify somebody.
110 // This is to prevent codec errors caused by SurfaceView fullscreen transitions
111 // from breaking the pipeline, if we're about to be reset anyway.
112 constexpr base::TimeDelta ErrorPostingDelay = base::TimeDelta::FromSeconds(2);
113
114 } // namespace 109 } // namespace
115 110
116 static base::LazyInstance<AVDACodecAllocator>::Leaky g_avda_codec_allocator = 111 static base::LazyInstance<AVDACodecAllocator>::Leaky g_avda_codec_allocator =
117 LAZY_INSTANCE_INITIALIZER; 112 LAZY_INSTANCE_INITIALIZER;
118 113
119 // AVDAManager manages shared resources for a number of AVDA instances. 114 // AVDAManager manages shared resources for a number of AVDA instances.
120 // Its responsibilities include: 115 // Its responsibilities include:
121 // - Starting and stopping a shared "construction" thread for instantiating and 116 // - Starting and stopping a shared "construction" thread for instantiating and
122 // releasing MediaCodecs. 117 // releasing MediaCodecs.
123 // - Detecting when a task has hung on the construction thread so AVDAs can 118 // - Detecting when a task has hung on the construction thread so AVDAs can
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 : client_(NULL), 301 : client_(NULL),
307 make_context_current_cb_(make_context_current_cb), 302 make_context_current_cb_(make_context_current_cb),
308 get_gles2_decoder_cb_(get_gles2_decoder_cb), 303 get_gles2_decoder_cb_(get_gles2_decoder_cb),
309 state_(NO_ERROR), 304 state_(NO_ERROR),
310 picturebuffers_requested_(false), 305 picturebuffers_requested_(false),
311 picture_buffer_manager_(this), 306 picture_buffer_manager_(this),
312 drain_type_(DRAIN_TYPE_NONE), 307 drain_type_(DRAIN_TYPE_NONE),
313 media_drm_bridge_cdm_context_(nullptr), 308 media_drm_bridge_cdm_context_(nullptr),
314 cdm_registration_id_(0), 309 cdm_registration_id_(0),
315 pending_input_buf_index_(-1), 310 pending_input_buf_index_(-1),
316 error_sequence_token_(0),
317 defer_errors_(false),
318 deferred_initialization_pending_(false), 311 deferred_initialization_pending_(false),
319 codec_needs_reset_(false), 312 codec_needs_reset_(false),
320 defer_surface_creation_(false), 313 defer_surface_creation_(false),
321 surface_id_(SurfaceManager::kNoSurfaceID), 314 surface_id_(SurfaceManager::kNoSurfaceID),
322 weak_this_factory_(this) {} 315 weak_this_factory_(this) {}
323 316
324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 317 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
325 DCHECK(thread_checker_.CalledOnValidThread()); 318 DCHECK(thread_checker_.CalledOnValidThread());
326 g_avda_manager.Get().StopTimer(this); 319 g_avda_manager.Get().StopTimer(this);
327 g_avda_codec_allocator.Get().StopThread(this); 320 g_avda_codec_allocator.Get().StopThread(this);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 if (did_input || did_output) 495 if (did_input || did_output)
503 did_work = true; 496 did_work = true;
504 } while (did_input || did_output); 497 } while (did_input || did_output);
505 498
506 ManageTimer(did_work || start_timer); 499 ManageTimer(did_work || start_timer);
507 } 500 }
508 501
509 bool AndroidVideoDecodeAccelerator::QueueInput() { 502 bool AndroidVideoDecodeAccelerator::QueueInput() {
510 DCHECK(thread_checker_.CalledOnValidThread()); 503 DCHECK(thread_checker_.CalledOnValidThread());
511 TRACE_EVENT0("media", "AVDA::QueueInput"); 504 TRACE_EVENT0("media", "AVDA::QueueInput");
512 base::AutoReset<bool> auto_reset(&defer_errors_, true);
513 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || 505 if (state_ == ERROR || state_ == WAITING_FOR_CODEC ||
514 state_ == WAITING_FOR_KEY) { 506 state_ == WAITING_FOR_KEY) {
515 return false; 507 return false;
516 } 508 }
517 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) 509 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance)
518 return false; 510 return false;
519 if (pending_bitstream_records_.empty()) 511 if (pending_bitstream_records_.empty())
520 return false; 512 return false;
521 513
522 int input_buf_index = pending_input_buf_index_; 514 int input_buf_index = pending_input_buf_index_;
523 515
524 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY. 516 // Do not dequeue a new input buffer if we failed with MEDIA_CODEC_NO_KEY.
525 // That status does not return this buffer back to the pool of 517 // That status does not return this buffer back to the pool of
526 // available input buffers. We have to reuse it in QueueSecureInputBuffer(). 518 // available input buffers. We have to reuse it in QueueSecureInputBuffer().
527 if (input_buf_index == -1) { 519 if (input_buf_index == -1) {
528 MediaCodecStatus status = 520 MediaCodecStatus status =
529 media_codec_->DequeueInputBuffer(NoWaitTimeOut, &input_buf_index); 521 media_codec_->DequeueInputBuffer(NoWaitTimeOut, &input_buf_index);
530 switch (status) { 522 switch (status) {
531 case MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER: 523 case MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER:
532 return false; 524 return false;
533 case MEDIA_CODEC_ERROR: 525 case MEDIA_CODEC_ERROR:
534 POST_ERROR(PLATFORM_FAILURE, "Failed to DequeueInputBuffer"); 526 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueInputBuffer failed");
535 return false; 527 return false;
536 case MEDIA_CODEC_OK: 528 case MEDIA_CODEC_OK:
537 break; 529 break;
538 default: 530 default:
539 NOTREACHED() << "Unknown DequeueInputBuffer status " << status; 531 NOTREACHED();
540 return false; 532 return false;
541 } 533 }
542 } 534 }
543 535
544 DCHECK_NE(input_buf_index, -1); 536 DCHECK_NE(input_buf_index, -1);
545 537
546 BitstreamBuffer bitstream_buffer = pending_bitstream_records_.front().buffer; 538 BitstreamBuffer bitstream_buffer = pending_bitstream_records_.front().buffer;
547 539
548 if (bitstream_buffer.id() == -1) { 540 if (bitstream_buffer.id() == -1) {
549 pending_bitstream_records_.pop(); 541 pending_bitstream_records_.pop();
550 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 542 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
551 pending_bitstream_records_.size()); 543 pending_bitstream_records_.size());
552 544
553 media_codec_->QueueEOS(input_buf_index); 545 media_codec_->QueueEOS(input_buf_index);
554 return true; 546 return true;
555 } 547 }
556 548
557 std::unique_ptr<SharedMemoryRegion> shm; 549 std::unique_ptr<SharedMemoryRegion> shm;
558 550
559 if (pending_input_buf_index_ == -1) { 551 if (pending_input_buf_index_ == -1) {
560 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued 552 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued
561 // from MediaCodec, filled with data and bitstream_buffer.handle() is 553 // from MediaCodec, filled with data and bitstream_buffer.handle() is
562 // closed. 554 // closed.
563 shm = std::move(pending_bitstream_records_.front().memory); 555 shm = std::move(pending_bitstream_records_.front().memory);
564 556
565 if (!shm->Map()) { 557 if (!shm->Map()) {
566 POST_ERROR(UNREADABLE_INPUT, "Failed to SharedMemoryRegion::Map()"); 558 NOTIFY_ERROR(UNREADABLE_INPUT, "SharedMemoryRegion::Map() failed");
567 return false; 559 return false;
568 } 560 }
569 } 561 }
570 562
571 const base::TimeDelta presentation_timestamp = 563 const base::TimeDelta presentation_timestamp =
572 bitstream_buffer.presentation_timestamp(); 564 bitstream_buffer.presentation_timestamp();
573 DCHECK(presentation_timestamp != kNoTimestamp) 565 DCHECK(presentation_timestamp != kNoTimestamp)
574 << "Bitstream buffers must have valid presentation timestamps"; 566 << "Bitstream buffers must have valid presentation timestamps";
575 567
576 // There may already be a bitstream buffer with this timestamp, e.g., VP9 alt 568 // There may already be a bitstream buffer with this timestamp, e.g., VP9 alt
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 // keep getting more bitstreams from the client, and throttle them by using 616 // keep getting more bitstreams from the client, and throttle them by using
625 // |bitstreams_notified_in_advance_|. 617 // |bitstreams_notified_in_advance_|.
626 // TODO(dwkang): check if there is a way to remove this workaround. 618 // TODO(dwkang): check if there is a way to remove this workaround.
627 base::ThreadTaskRunnerHandle::Get()->PostTask( 619 base::ThreadTaskRunnerHandle::Get()->PostTask(
628 FROM_HERE, 620 FROM_HERE,
629 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 621 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
630 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); 622 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
631 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id()); 623 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id());
632 624
633 if (status != MEDIA_CODEC_OK) { 625 if (status != MEDIA_CODEC_OK) {
634 POST_ERROR(PLATFORM_FAILURE, "Failed to QueueInputBuffer: " << status); 626 NOTIFY_ERROR(PLATFORM_FAILURE, "QueueInputBuffer failed:" << status);
635 return false; 627 return false;
636 } 628 }
637 629
638 return true; 630 return true;
639 } 631 }
640 632
641 bool AndroidVideoDecodeAccelerator::DequeueOutput() { 633 bool AndroidVideoDecodeAccelerator::DequeueOutput() {
642 DCHECK(thread_checker_.CalledOnValidThread()); 634 DCHECK(thread_checker_.CalledOnValidThread());
643 TRACE_EVENT0("media", "AVDA::DequeueOutput"); 635 TRACE_EVENT0("media", "AVDA::DequeueOutput");
644 base::AutoReset<bool> auto_reset(&defer_errors_, true);
645 if (state_ == ERROR || state_ == WAITING_FOR_CODEC) 636 if (state_ == ERROR || state_ == WAITING_FOR_CODEC)
646 return false; 637 return false;
647 // If we're draining for reset or destroy, then we don't need picture buffers 638 // If we're draining for reset or destroy, then we don't need picture buffers
648 // since we won't send any decoded frames anyway. There might not be any, 639 // since we won't send any decoded frames anyway. There might not be any,
649 // since the pipeline might not be sending them back and / or they don't 640 // since the pipeline might not be sending them back and / or they don't
650 // exist anymore. From the pipeline's point of view, for Destroy at least, 641 // exist anymore. From the pipeline's point of view, for Destroy at least,
651 // the VDA is already gone. 642 // the VDA is already gone.
652 if (picturebuffers_requested_ && output_picture_buffers_.empty() && 643 if (picturebuffers_requested_ && output_picture_buffers_.empty() &&
653 !IsDrainingForResetOrDestroy()) { 644 !IsDrainingForResetOrDestroy()) {
654 return false; 645 return false;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 677
687 switch (status) { 678 switch (status) {
688 case MEDIA_CODEC_ERROR: 679 case MEDIA_CODEC_ERROR:
689 // Do not post an error if we are draining for reset and destroy. 680 // Do not post an error if we are draining for reset and destroy.
690 // Instead, run the drain completion task. 681 // Instead, run the drain completion task.
691 if (IsDrainingForResetOrDestroy()) { 682 if (IsDrainingForResetOrDestroy()) {
692 DVLOG(1) << __FUNCTION__ << ": error while codec draining"; 683 DVLOG(1) << __FUNCTION__ << ": error while codec draining";
693 state_ = ERROR; 684 state_ = ERROR;
694 OnDrainCompleted(); 685 OnDrainCompleted();
695 } else { 686 } else {
696 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); 687 NOTIFY_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
697 } 688 }
698 return false; 689 return false;
699 690
700 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 691 case MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
701 return false; 692 return false;
702 693
703 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 694 case MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
704 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame 695 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame
705 // size does not change. Therefore we have to keep track on the format 696 // size does not change. Therefore we have to keep track on the format
706 // even if draining, unless we are draining for destroy. 697 // even if draining, unless we are draining for destroy.
707 if (drain_type_ == DRAIN_FOR_DESTROY) 698 if (drain_type_ == DRAIN_FOR_DESTROY)
708 return true; // ignore 699 return true; // ignore
709 700
710 if (media_codec_->GetOutputSize(&size_) != MEDIA_CODEC_OK) { 701 if (media_codec_->GetOutputSize(&size_) != MEDIA_CODEC_OK) {
711 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); 702 NOTIFY_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
712 return false; 703 return false;
713 } 704 }
714 705
715 DVLOG(3) << __FUNCTION__ 706 DVLOG(3) << __FUNCTION__
716 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); 707 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
717 708
718 // Don't request picture buffers if we already have some. This avoids 709 // Don't request picture buffers if we already have some. This avoids
719 // having to dismiss the existing buffers which may actively reference 710 // having to dismiss the existing buffers which may actively reference
720 // decoded images. Breaking their connection to the decoded image will 711 // decoded images. Breaking their connection to the decoded image will
721 // cause rendering of black frames. Instead, we let the existing 712 // cause rendering of black frames. Instead, we let the existing
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 748
758 if (IsDrainingForResetOrDestroy()) { 749 if (IsDrainingForResetOrDestroy()) {
759 media_codec_->ReleaseOutputBuffer(buf_index, false); 750 media_codec_->ReleaseOutputBuffer(buf_index, false);
760 return true; 751 return true;
761 } 752 }
762 753
763 if (!picturebuffers_requested_) { 754 if (!picturebuffers_requested_) {
764 // In 0.01% of playbacks MediaCodec returns a frame before FORMAT_CHANGED. 755 // In 0.01% of playbacks MediaCodec returns a frame before FORMAT_CHANGED.
765 // Occurs on JB and M. (See the Media.AVDA.MissingFormatChanged histogram.) 756 // Occurs on JB and M. (See the Media.AVDA.MissingFormatChanged histogram.)
766 media_codec_->ReleaseOutputBuffer(buf_index, false); 757 media_codec_->ReleaseOutputBuffer(buf_index, false);
767 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED."); 758 NOTIFY_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED.");
768 return false; 759 return false;
769 } 760 }
770 761
771 // Get the bitstream buffer id from the timestamp. 762 // Get the bitstream buffer id from the timestamp.
772 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); 763 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp);
773 764
774 if (it != bitstream_buffers_in_decoder_.end()) { 765 if (it != bitstream_buffers_in_decoder_.end()) {
775 const int32_t bitstream_buffer_id = it->second; 766 const int32_t bitstream_buffer_id = it->second;
776 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(), 767 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(),
777 ++it); 768 ++it);
(...skipping 29 matching lines...) Expand all
807 798
808 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( 799 void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient(
809 int32_t codec_buffer_index, 800 int32_t codec_buffer_index,
810 int32_t bitstream_id) { 801 int32_t bitstream_id) {
811 DCHECK(thread_checker_.CalledOnValidThread()); 802 DCHECK(thread_checker_.CalledOnValidThread());
812 DCHECK_NE(bitstream_id, -1); 803 DCHECK_NE(bitstream_id, -1);
813 DCHECK(!free_picture_ids_.empty()); 804 DCHECK(!free_picture_ids_.empty());
814 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient"); 805 TRACE_EVENT0("media", "AVDA::SendDecodedFrameToClient");
815 806
816 if (!make_context_current_cb_.Run()) { 807 if (!make_context_current_cb_.Run()) {
817 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 808 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
818 return; 809 return;
819 } 810 }
820 811
821 int32_t picture_buffer_id = free_picture_ids_.front(); 812 int32_t picture_buffer_id = free_picture_ids_.front();
822 free_picture_ids_.pop(); 813 free_picture_ids_.pop();
823 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 814 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
824 815
825 const auto it = output_picture_buffers_.find(picture_buffer_id); 816 const auto it = output_picture_buffers_.find(picture_buffer_id);
826 if (it == output_picture_buffers_.end()) { 817 if (it == output_picture_buffers_.end()) {
827 POST_ERROR(PLATFORM_FAILURE, 818 NOTIFY_ERROR(PLATFORM_FAILURE,
828 "Can't find PictureBuffer id: " << picture_buffer_id); 819 "Can't find PictureBuffer id: " << picture_buffer_id);
829 return; 820 return;
830 } 821 }
831 822
832 PictureBuffer& picture_buffer = it->second; 823 PictureBuffer& picture_buffer = it->second;
833 const bool size_changed = picture_buffer.size() != size_; 824 const bool size_changed = picture_buffer.size() != size_;
834 if (size_changed) 825 if (size_changed)
835 picture_buffer.set_size(size_); 826 picture_buffer.set_size(size_);
836 827
837 const bool allow_overlay = picture_buffer_manager_.ArePicturesOverlayable(); 828 const bool allow_overlay = picture_buffer_manager_.ArePicturesOverlayable();
838 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.FrameSentAsOverlay", allow_overlay); 829 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.FrameSentAsOverlay", allow_overlay);
(...skipping 11 matching lines...) Expand all
850 // Connect the PictureBuffer to the decoded frame. 841 // Connect the PictureBuffer to the decoded frame.
851 picture_buffer_manager_.UseCodecBufferForPictureBuffer(codec_buffer_index, 842 picture_buffer_manager_.UseCodecBufferForPictureBuffer(codec_buffer_index,
852 picture_buffer); 843 picture_buffer);
853 } 844 }
854 845
855 void AndroidVideoDecodeAccelerator::Decode( 846 void AndroidVideoDecodeAccelerator::Decode(
856 const BitstreamBuffer& bitstream_buffer) { 847 const BitstreamBuffer& bitstream_buffer) {
857 DCHECK(thread_checker_.CalledOnValidThread()); 848 DCHECK(thread_checker_.CalledOnValidThread());
858 849
859 if (defer_surface_creation_ && !InitializePictureBufferManager()) { 850 if (defer_surface_creation_ && !InitializePictureBufferManager()) {
860 POST_ERROR(PLATFORM_FAILURE, 851 NOTIFY_ERROR(PLATFORM_FAILURE,
861 "Failed deferred surface and MediaCodec initialization."); 852 "Failed deferred surface and MediaCodec initialization.");
862 return; 853 return;
863 } 854 }
864 855
865 // If we previously deferred a codec restart, take care of it now. This can 856 // If we previously deferred a codec restart, take care of it now. This can
866 // happen on older devices where configuration changes require a codec reset. 857 // happen on older devices where configuration changes require a codec reset.
867 if (codec_needs_reset_) { 858 if (codec_needs_reset_) {
868 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE); 859 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE);
869 ResetCodecState(); 860 ResetCodecState();
870 } 861 }
871 862
872 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { 863 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) {
873 DecodeBuffer(bitstream_buffer); 864 DecodeBuffer(bitstream_buffer);
874 return; 865 return;
875 } 866 }
876 867
877 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle())) 868 if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
878 base::SharedMemory::CloseHandle(bitstream_buffer.handle()); 869 base::SharedMemory::CloseHandle(bitstream_buffer.handle());
879 870
880 if (bitstream_buffer.id() < 0) { 871 if (bitstream_buffer.id() < 0) {
881 POST_ERROR(INVALID_ARGUMENT, 872 NOTIFY_ERROR(INVALID_ARGUMENT,
882 "Invalid bistream_buffer, id: " << bitstream_buffer.id()); 873 "Invalid bistream_buffer, id: " << bitstream_buffer.id());
883 } else { 874 } else {
884 base::ThreadTaskRunnerHandle::Get()->PostTask( 875 base::ThreadTaskRunnerHandle::Get()->PostTask(
885 FROM_HERE, 876 FROM_HERE,
886 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 877 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
887 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id())); 878 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
888 } 879 }
889 } 880 }
890 881
891 void AndroidVideoDecodeAccelerator::DecodeBuffer( 882 void AndroidVideoDecodeAccelerator::DecodeBuffer(
892 const BitstreamBuffer& bitstream_buffer) { 883 const BitstreamBuffer& bitstream_buffer) {
(...skipping 17 matching lines...) Expand all
910 } 901 }
911 } 902 }
912 903
913 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 904 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
914 const std::vector<PictureBuffer>& buffers) { 905 const std::vector<PictureBuffer>& buffers) {
915 DCHECK(thread_checker_.CalledOnValidThread()); 906 DCHECK(thread_checker_.CalledOnValidThread());
916 DCHECK(output_picture_buffers_.empty()); 907 DCHECK(output_picture_buffers_.empty());
917 DCHECK(free_picture_ids_.empty()); 908 DCHECK(free_picture_ids_.empty());
918 909
919 if (buffers.size() < kNumPictureBuffers) { 910 if (buffers.size() < kNumPictureBuffers) {
920 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 911 NOTIFY_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
921 return; 912 return;
922 } 913 }
923 914
924 const bool have_context = make_context_current_cb_.Run(); 915 const bool have_context = make_context_current_cb_.Run();
925 LOG_IF(WARNING, !have_context) 916 LOG_IF(WARNING, !have_context)
926 << "Failed to make GL context current for Assign, continuing."; 917 << "Failed to make GL context current for Assign, continuing.";
927 918
928 for (size_t i = 0; i < buffers.size(); ++i) { 919 for (size_t i = 0; i < buffers.size(); ++i) {
929 DCHECK(buffers[i].size() == size_); 920 DCHECK(buffers[i].size() == size_);
930 int32_t id = buffers[i].id(); 921 int32_t id = buffers[i].id();
931 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); 922 output_picture_buffers_.insert(std::make_pair(id, buffers[i]));
932 free_picture_ids_.push(id); 923 free_picture_ids_.push(id);
933 924
934 picture_buffer_manager_.AssignOnePictureBuffer(buffers[i], have_context); 925 picture_buffer_manager_.AssignOnePictureBuffer(buffers[i], have_context);
935 } 926 }
936 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 927 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
937 DoIOTask(true); 928 DoIOTask(true);
938 } 929 }
939 930
940 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( 931 void AndroidVideoDecodeAccelerator::ReusePictureBuffer(
941 int32_t picture_buffer_id) { 932 int32_t picture_buffer_id) {
942 DCHECK(thread_checker_.CalledOnValidThread()); 933 DCHECK(thread_checker_.CalledOnValidThread());
943 934
944 free_picture_ids_.push(picture_buffer_id); 935 free_picture_ids_.push(picture_buffer_id);
945 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 936 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
946 937
947 auto it = output_picture_buffers_.find(picture_buffer_id); 938 auto it = output_picture_buffers_.find(picture_buffer_id);
948 if (it == output_picture_buffers_.end()) { 939 if (it == output_picture_buffers_.end()) {
949 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " 940 NOTIFY_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id "
950 << picture_buffer_id); 941 << picture_buffer_id);
951 return; 942 return;
952 } 943 }
953 944
954 picture_buffer_manager_.ReuseOnePictureBuffer(it->second); 945 picture_buffer_manager_.ReuseOnePictureBuffer(it->second);
955 DoIOTask(true); 946 DoIOTask(true);
956 } 947 }
957 948
958 void AndroidVideoDecodeAccelerator::Flush() { 949 void AndroidVideoDecodeAccelerator::Flush() {
959 DVLOG(1) << __FUNCTION__; 950 DVLOG(1) << __FUNCTION__;
960 DCHECK(thread_checker_.CalledOnValidThread()); 951 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 1063
1073 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, 1064 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec,
1074 // then the codec is already invalid so we return early and drop it. 1065 // then the codec is already invalid so we return early and drop it.
1075 if (state_ == SURFACE_DESTROYED) 1066 if (state_ == SURFACE_DESTROYED)
1076 return; 1067 return;
1077 1068
1078 DCHECK(!media_codec_); 1069 DCHECK(!media_codec_);
1079 media_codec_ = std::move(media_codec); 1070 media_codec_ = std::move(media_codec);
1080 picture_buffer_manager_.CodecChanged(media_codec_.get()); 1071 picture_buffer_manager_.CodecChanged(media_codec_.get());
1081 if (!media_codec_) { 1072 if (!media_codec_) {
1082 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); 1073 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec");
1083 return; 1074 return;
1084 } 1075 }
1085 1076
1086 state_ = NO_ERROR; 1077 state_ = NO_ERROR;
1087 1078
1088 ManageTimer(true); 1079 ManageTimer(true);
1089 } 1080 }
1090 1081
1091 void AndroidVideoDecodeAccelerator::StartCodecDrain(DrainType drain_type) { 1082 void AndroidVideoDecodeAccelerator::StartCodecDrain(DrainType drain_type) {
1092 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type; 1083 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 1165
1175 // Don't reset the codec here if there's no error and we're only flushing; 1166 // Don't reset the codec here if there's no error and we're only flushing;
1176 // instead defer until the next decode call; this prevents us from unbacking 1167 // instead defer until the next decode call; this prevents us from unbacking
1177 // frames that might be out for display at end of stream. 1168 // frames that might be out for display at end of stream.
1178 codec_needs_reset_ = false; 1169 codec_needs_reset_ = false;
1179 if (drain_type_ == DRAIN_FOR_FLUSH && !did_codec_error_happen) { 1170 if (drain_type_ == DRAIN_FOR_FLUSH && !did_codec_error_happen) {
1180 codec_needs_reset_ = true; 1171 codec_needs_reset_ = true;
1181 return; 1172 return;
1182 } 1173 }
1183 1174
1184 // We might increment error_sequence_token here to cancel any delayed errors,
1185 // but right now it's unclear that it's safe to do so. If we are in an error
1186 // state because of a codec error, then it would be okay. Otherwise, it's
1187 // less obvious that we are exiting the error state. Since deferred errors
1188 // are only intended for fullscreen transitions right now, we take the more
1189 // conservative approach and let the errors post.
1190 // TODO(liberato): revisit this once we sort out the error state a bit more.
1191
1192 // Flush the codec if possible, or create a new one if not. 1175 // Flush the codec if possible, or create a new one if not.
1193 if (!did_codec_error_happen && 1176 if (!did_codec_error_happen &&
1194 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { 1177 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) {
1195 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec."; 1178 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec.";
1196 media_codec_->Flush(); 1179 media_codec_->Flush();
1197 // Since we just flushed all the output buffers, make sure that nothing is 1180 // Since we just flushed all the output buffers, make sure that nothing is
1198 // using them. 1181 // using them.
1199 picture_buffer_manager_.CodecChanged(media_codec_.get()); 1182 picture_buffer_manager_.CodecChanged(media_codec_.get());
1200 } else { 1183 } else {
1201 DVLOG(3) << __FUNCTION__ 1184 DVLOG(3) << __FUNCTION__
(...skipping 26 matching lines...) Expand all
1228 if (bitstream_buffer_id != -1) { 1211 if (bitstream_buffer_id != -1) {
1229 base::ThreadTaskRunnerHandle::Get()->PostTask( 1212 base::ThreadTaskRunnerHandle::Get()->PostTask(
1230 FROM_HERE, 1213 FROM_HERE,
1231 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 1214 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
1232 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); 1215 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1233 } 1216 }
1234 } 1217 }
1235 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 1218 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
1236 bitstreams_notified_in_advance_.clear(); 1219 bitstreams_notified_in_advance_.clear();
1237 1220
1238 // Any error that is waiting to post can be ignored.
1239 error_sequence_token_++;
1240
1241 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); 1221 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_);
1242 1222
1243 // Some VP8 files require complete MediaCodec drain before we can call 1223 // Some VP8 files require complete MediaCodec drain before we can call
1244 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. 1224 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1245 if (media_codec_ && codec_config_->codec_ == kCodecVP8 && 1225 if (media_codec_ && codec_config_->codec_ == kCodecVP8 &&
1246 !bitstream_buffers_in_decoder_.empty()) { 1226 !bitstream_buffers_in_decoder_.empty()) {
1247 // Postpone ResetCodecState() after the drain. 1227 // Postpone ResetCodecState() after the drain.
1248 StartCodecDrain(DRAIN_FOR_RESET); 1228 StartCodecDrain(DRAIN_FOR_RESET);
1249 } else { 1229 } else {
1250 ResetCodecState(); 1230 ResetCodecState();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 if (media_codec_) { 1343 if (media_codec_) {
1364 ReleaseMediaCodec(); 1344 ReleaseMediaCodec();
1365 picture_buffer_manager_.CodecChanged(media_codec_.get()); 1345 picture_buffer_manager_.CodecChanged(media_codec_.get());
1366 } 1346 }
1367 // If we're draining, signal completion now because the drain can no longer 1347 // If we're draining, signal completion now because the drain can no longer
1368 // proceed. 1348 // proceed.
1369 if (drain_type_ != DRAIN_TYPE_NONE) 1349 if (drain_type_ != DRAIN_TYPE_NONE)
1370 OnDrainCompleted(); 1350 OnDrainCompleted();
1371 } 1351 }
1372 1352
1373 void AndroidVideoDecodeAccelerator::PostError(
1374 const ::tracked_objects::Location& from_here,
1375 VideoDecodeAccelerator::Error error) {
1376 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1377 from_here,
1378 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError,
1379 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_),
1380 (defer_errors_ ? ErrorPostingDelay : base::TimeDelta()));
1381 state_ = ERROR;
1382 }
1383
1384 void AndroidVideoDecodeAccelerator::InitializeCdm() { 1353 void AndroidVideoDecodeAccelerator::InitializeCdm() {
1385 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id; 1354 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id;
1386 1355
1387 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 1356 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
1388 NOTIMPLEMENTED(); 1357 NOTIMPLEMENTED();
1389 NotifyInitializationComplete(false); 1358 NotifyInitializationComplete(false);
1390 #else 1359 #else
1391 // Store the CDM to hold a reference to it. 1360 // Store the CDM to hold a reference to it.
1392 cdm_for_reference_holding_only_ = 1361 cdm_for_reference_holding_only_ =
1393 MojoCdmService::LegacyGetCdm(config_.cdm_id); 1362 MojoCdmService::LegacyGetCdm(config_.cdm_id);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 void AndroidVideoDecodeAccelerator::NotifyFlushDone() { 1441 void AndroidVideoDecodeAccelerator::NotifyFlushDone() {
1473 if (client_) 1442 if (client_)
1474 client_->NotifyFlushDone(); 1443 client_->NotifyFlushDone();
1475 } 1444 }
1476 1445
1477 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 1446 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
1478 if (client_) 1447 if (client_)
1479 client_->NotifyResetDone(); 1448 client_->NotifyResetDone();
1480 } 1449 }
1481 1450
1482 void AndroidVideoDecodeAccelerator::NotifyError( 1451 void AndroidVideoDecodeAccelerator::NotifyError(Error error) {
1483 VideoDecodeAccelerator::Error error, 1452 state_ = ERROR;
1484 int token) {
1485 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token
1486 << " current: " << error_sequence_token_;
1487 if (token != error_sequence_token_)
1488 return;
1489
1490 if (client_) 1453 if (client_)
1491 client_->NotifyError(error); 1454 client_->NotifyError(error);
1492 } 1455 }
1493 1456
1494 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) { 1457 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) {
1495 bool should_be_running = true; 1458 bool should_be_running = true;
1496 1459
1497 base::TimeTicks now = base::TimeTicks::Now(); 1460 base::TimeTicks now = base::TimeTicks::Now();
1498 if (!did_work && !most_recent_work_.is_null()) { 1461 if (!did_work && !most_recent_work_.is_null()) {
1499 // Make sure that we have done work recently enough, else stop the timer. 1462 // Make sure that we have done work recently enough, else stop the timer.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1629 codec_config_->codec_ == kCodecVP9); 1592 codec_config_->codec_ == kCodecVP9);
1630 } 1593 }
1631 1594
1632 bool AndroidVideoDecodeAccelerator::UpdateSurface() { 1595 bool AndroidVideoDecodeAccelerator::UpdateSurface() {
1633 DCHECK(pending_surface_id_); 1596 DCHECK(pending_surface_id_);
1634 DCHECK_NE(surface_id_, pending_surface_id_.value()); 1597 DCHECK_NE(surface_id_, pending_surface_id_.value());
1635 1598
1636 // Ensure the current context is active when switching surfaces; we may need 1599 // Ensure the current context is active when switching surfaces; we may need
1637 // to create a new texture. 1600 // to create a new texture.
1638 if (!make_context_current_cb_.Run()) { 1601 if (!make_context_current_cb_.Run()) {
1639 POST_ERROR(PLATFORM_FAILURE, 1602 NOTIFY_ERROR(PLATFORM_FAILURE,
1640 "Failed to make this decoder's GL context current when " 1603 "Failed to make this decoder's GL context current when "
1641 "switching surfaces."); 1604 "switching surfaces.");
1642 return false; 1605 return false;
1643 } 1606 }
1644 1607
1645 surface_id_ = pending_surface_id_.value(); 1608 surface_id_ = pending_surface_id_.value();
1646 codec_config_->surface_ = 1609 codec_config_->surface_ =
1647 picture_buffer_manager_.Initialize(pending_surface_id_.value()); 1610 picture_buffer_manager_.Initialize(pending_surface_id_.value());
1648 if (codec_config_->surface_.IsEmpty()) { 1611 if (codec_config_->surface_.IsEmpty()) {
1649 POST_ERROR(PLATFORM_FAILURE, "An error occurred while switching surfaces."); 1612 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces.");
1650 return false; 1613 return false;
1651 } 1614 }
1652 1615
1653 if (media_codec_ && 1616 if (media_codec_ &&
1654 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) { 1617 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) {
1655 POST_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); 1618 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces.");
1656 return false; 1619 return false;
1657 } 1620 }
1658 1621
1659 pending_surface_id_.reset(); 1622 pending_surface_id_.reset();
1660 return true; 1623 return true;
1661 } 1624 }
1662 1625
1663 } // namespace media 1626 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | media/gpu/avda_picture_buffer_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698