Chromium Code Reviews| Index: content/common/gpu/media/android_video_decode_accelerator.cc |
| diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc |
| index 7deb6f3dc81cbe36be666f2354ac8591e5b71950..65710ed1389523f26e359aa752b63f895f796c81 100644 |
| --- a/content/common/gpu/media/android_video_decode_accelerator.cc |
| +++ b/content/common/gpu/media/android_video_decode_accelerator.cc |
| @@ -574,23 +574,29 @@ bool AndroidVideoDecodeAccelerator::DequeueOutput() { |
| return false; |
| case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { |
| - 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
|
| - // TODO(chcunningham): This will likely dismiss a handful of decoded |
| - // frames that have not yet been drawn and returned to us for re-use. |
| - // Consider a more complicated design that would wait for them to be |
| - // drawn before dismissing. |
| - DismissPictureBuffers(); |
| - } |
| - |
| - picturebuffers_requested_ = true; |
| int32_t width, height; |
| media_codec_->GetOutputFormat(&width, &height); |
| size_ = gfx::Size(width, height); |
| - base::MessageLoop::current()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, |
| - weak_this_factory_.GetWeakPtr())); |
| - return false; |
| + DVLOG(4) << __FUNCTION__ |
| + << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); |
| + |
| + // Don't request picture buffers if we already have some. This avoids |
| + // having to dismiss the existing buffers which may actively reference |
| + // decoded images. Breaking their connection to the decoded image will |
| + // cause rendering of black frames. Instead, we let the existing |
| + // PictureBuffers live on and we simply update their size the next time |
| + // they're attachted to an image of the new resolution. See the |
| + // size update in |SendDecodedFrameToClient| and https://crbug/587994. |
| + if (output_picture_buffers_.empty()) { |
| + picturebuffers_requested_ = true; |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, |
| + weak_this_factory_.GetWeakPtr())); |
| + return false; |
| + } |
| + |
| + return true; |
| } |
| case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: |
| @@ -685,14 +691,24 @@ void AndroidVideoDecodeAccelerator::SendDecodedFrameToClient( |
| free_picture_ids_.pop(); |
| TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
| - OutputBufferMap::const_iterator i = |
| - output_picture_buffers_.find(picture_buffer_id); |
| + OutputBufferMap::iterator i = output_picture_buffers_.find(picture_buffer_id); |
| if (i == output_picture_buffers_.end()) { |
| POST_ERROR(PLATFORM_FAILURE, |
| "Can't find PictureBuffer id: " << picture_buffer_id); |
| return; |
| } |
| + if (i->second.size() != size_) { |
| + // Size may have changed due to resolution change since the last time this |
| + // PictureBuffer was used. The size of the PictureBuffer is purely |
| + // 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
|
| + DVLOG (3) << __FUNCTION__ |
| + << " Updating size for PictureBuffer[" << i->first << "]" |
| + << " from:" << i->second.size().ToString() |
| + << " to:" << size_.ToString(); |
| + 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
|
| + } |
| + |
| // Connect the PictureBuffer to the decoded frame, via whatever |
| // mechanism the strategy likes. |
| strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); |