| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |