Chromium Code Reviews| 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 "content/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 | 567 |
| 568 switch (status) { | 568 switch (status) { |
| 569 case media::MEDIA_CODEC_ERROR: | 569 case media::MEDIA_CODEC_ERROR: |
| 570 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); | 570 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); |
| 571 return false; | 571 return false; |
| 572 | 572 |
| 573 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: | 573 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: |
| 574 return false; | 574 return false; |
| 575 | 575 |
| 576 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { | 576 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { |
| 577 if (!output_picture_buffers_.empty()) { | |
|
liberato (no reviews please)
2016/03/01 17:13:08
i prefer that you ignore this comment, but i leave
| |
| 578 // TODO(chcunningham): This will likely dismiss a handful of decoded | |
| 579 // frames that have not yet been drawn and returned to us for re-use. | |
| 580 // Consider a more complicated design that would wait for them to be | |
| 581 // drawn before dismissing. | |
| 582 DismissPictureBuffers(); | |
| 583 } | |
| 584 | |
| 585 picturebuffers_requested_ = true; | |
| 586 int32_t width, height; | 577 int32_t width, height; |
| 587 media_codec_->GetOutputFormat(&width, &height); | 578 media_codec_->GetOutputFormat(&width, &height); |
| 588 size_ = gfx::Size(width, height); | 579 size_ = gfx::Size(width, height); |
| 589 base::MessageLoop::current()->PostTask( | 580 DVLOG(4) << __FUNCTION__ |
| 590 FROM_HERE, | 581 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); |
| 591 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, | 582 |
| 592 weak_this_factory_.GetWeakPtr())); | 583 // Don't request picture buffers if we already have some. This avoids |
| 593 return false; | 584 // having to dismiss the existing buffers which may actively reference |
| 585 // decoded images. Breaking their connection to the decoded image will | |
| 586 // cause rendering of black frames. Instead, we let the existing | |
| 587 // PictureBuffers live on and we simply update their size the next time | |
| 588 // they're attachted to an image of the new resolution. See the | |
| 589 // size update in |SendDecodedFrameToClient| and https://crbug/587994. | |
| 590 if (output_picture_buffers_.empty()) { | |
| 591 picturebuffers_requested_ = true; | |
| 592 base::MessageLoop::current()->PostTask( | |
| 593 FROM_HERE, | |
| 594 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, | |
| 595 weak_this_factory_.GetWeakPtr())); | |
| 596 return false; | |
| 597 } | |
| 598 | |
| 599 return true; | |
| 594 } | 600 } |
| 595 | 601 |
| 596 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: | 602 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: |
| 597 break; | 603 break; |
| 598 | 604 |
| 599 case media::MEDIA_CODEC_OK: | 605 case media::MEDIA_CODEC_OK: |
| 600 DCHECK_GE(buf_index, 0); | 606 DCHECK_GE(buf_index, 0); |
| 601 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp | 607 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp |
| 602 << " buf_index:" << buf_index << " offset:" << offset | 608 << " buf_index:" << buf_index << " offset:" << offset |
| 603 << " size:" << size << " eos:" << eos; | 609 << " size:" << size << " eos:" << eos; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 678 | 684 |
| 679 if (!make_context_current_.Run()) { | 685 if (!make_context_current_.Run()) { |
| 680 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); | 686 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); |
| 681 return; | 687 return; |
| 682 } | 688 } |
| 683 | 689 |
| 684 int32_t picture_buffer_id = free_picture_ids_.front(); | 690 int32_t picture_buffer_id = free_picture_ids_.front(); |
| 685 free_picture_ids_.pop(); | 691 free_picture_ids_.pop(); |
| 686 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 692 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
| 687 | 693 |
| 688 OutputBufferMap::const_iterator i = | 694 OutputBufferMap::iterator i = output_picture_buffers_.find(picture_buffer_id); |
| 689 output_picture_buffers_.find(picture_buffer_id); | |
| 690 if (i == output_picture_buffers_.end()) { | 695 if (i == output_picture_buffers_.end()) { |
| 691 POST_ERROR(PLATFORM_FAILURE, | 696 POST_ERROR(PLATFORM_FAILURE, |
| 692 "Can't find PictureBuffer id: " << picture_buffer_id); | 697 "Can't find PictureBuffer id: " << picture_buffer_id); |
| 693 return; | 698 return; |
| 694 } | 699 } |
| 695 | 700 |
| 701 if (i->second.size() != size_) { | |
| 702 // Size may have changed due to resolution change since the last time this | |
| 703 // PictureBuffer was used. The size of the PictureBuffer is purely | |
| 704 // meta-data and is not associated with OES texture it refers to. | |
|
liberato (no reviews please)
2016/03/01 17:13:08
whether it's an external texture or not depends on
chcunningham
2016/03/01 19:54:25
I like this symmetric proposal better. Patch comin
| |
| 705 DVLOG (3) << __FUNCTION__ | |
| 706 << " Updating size for PictureBuffer[" << i->first << "]" | |
| 707 << " from:" << i->second.size().ToString() | |
| 708 << " to:" << size_.ToString(); | |
| 709 i->second.set_size(size_); | |
|
liberato (no reviews please)
2016/03/01 17:13:08
i don't think that this is enough to get the size
| |
| 710 } | |
| 711 | |
| 696 // Connect the PictureBuffer to the decoded frame, via whatever | 712 // Connect the PictureBuffer to the decoded frame, via whatever |
| 697 // mechanism the strategy likes. | 713 // mechanism the strategy likes. |
| 698 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); | 714 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); |
| 699 | 715 |
| 700 const bool allow_overlay = strategy_->ArePicturesOverlayable(); | 716 const bool allow_overlay = strategy_->ArePicturesOverlayable(); |
| 701 base::MessageLoop::current()->PostTask( | 717 base::MessageLoop::current()->PostTask( |
| 702 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, | 718 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, |
| 703 weak_this_factory_.GetWeakPtr(), | 719 weak_this_factory_.GetWeakPtr(), |
| 704 media::Picture(picture_buffer_id, bitstream_id, | 720 media::Picture(picture_buffer_id, bitstream_id, |
| 705 gfx::Rect(size_), allow_overlay))); | 721 gfx::Rect(size_), allow_overlay))); |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1121 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 1137 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
| 1122 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | | 1138 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | |
| 1123 media::VideoDecodeAccelerator::Capabilities:: | 1139 media::VideoDecodeAccelerator::Capabilities:: |
| 1124 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1140 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1125 } | 1141 } |
| 1126 | 1142 |
| 1127 return capabilities; | 1143 return capabilities; |
| 1128 } | 1144 } |
| 1129 | 1145 |
| 1130 } // namespace content | 1146 } // namespace content |
| OLD | NEW |