Index: content/common/gpu/media/dxva_video_decode_accelerator.cc |
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc |
index 5f15f90e64654bfe1828231cee98fe7ba921c31b..d0e98b74574ed586700308879a70194c797c578e 100644 |
--- a/content/common/gpu/media/dxva_video_decode_accelerator.cc |
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc |
@@ -558,12 +558,25 @@ void DXVAVideoDecodeAccelerator::ReusePictureBuffer( |
RETURN_AND_NOTIFY_ON_FAILURE((state_ != kUninitialized), |
"Invalid state: " << state_, ILLEGAL_STATE,); |
- if (output_picture_buffers_.empty()) |
+ if (output_picture_buffers_.empty() && stale_output_picture_buffers_.empty()) |
return; |
OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id); |
- RETURN_AND_NOTIFY_ON_FAILURE(it != output_picture_buffers_.end(), |
- "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,); |
+ // If we didn't find the picture id in the |output_picture_buffers_| map we |
+ // try the |stale_output_picture_buffers_| map, as this may have been an |
+ // output picture buffer from before a resolution change, that at resolution |
+ // change time had yet to be displayed. The client is calling us back to tell |
+ // us that we can now recycle this picture buffer, so if we were waiting to |
+ // dispose of it we now can. |
+ if (it == output_picture_buffers_.end()) { |
+ it = stale_output_picture_buffers_.find(picture_buffer_id); |
+ RETURN_AND_NOTIFY_ON_FAILURE(it != stale_output_picture_buffers_.end(), |
+ "Invalid picture id: " << picture_buffer_id, INVALID_ARGUMENT,); |
+ base::MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer, |
+ weak_this_factory_.GetWeakPtr(), picture_buffer_id)); |
+ return; |
+ } |
it->second->ReusePictureBuffer(); |
ProcessPendingSamples(); |
@@ -996,6 +1009,7 @@ void DXVAVideoDecodeAccelerator::Invalidate() { |
return; |
weak_this_factory_.InvalidateWeakPtrs(); |
output_picture_buffers_.clear(); |
+ stale_output_picture_buffers_.clear(); |
pending_output_samples_.clear(); |
pending_input_buffers_.clear(); |
decoder_.Release(); |
@@ -1172,8 +1186,7 @@ void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width, |
base::MessageLoop::current()->PostTask( |
FROM_HERE, |
base::Bind(&DXVAVideoDecodeAccelerator::DismissStaleBuffers, |
- weak_this_factory_.GetWeakPtr(), |
- output_picture_buffers_)); |
+ weak_this_factory_.GetWeakPtr())); |
base::MessageLoop::current()->PostTask( |
FROM_HERE, |
@@ -1181,20 +1194,35 @@ void DXVAVideoDecodeAccelerator::HandleResolutionChanged(int width, |
weak_this_factory_.GetWeakPtr(), |
width, |
height)); |
- |
- output_picture_buffers_.clear(); |
} |
-void DXVAVideoDecodeAccelerator::DismissStaleBuffers( |
- const OutputBuffers& picture_buffers) { |
- OutputBuffers::const_iterator index; |
+void DXVAVideoDecodeAccelerator::DismissStaleBuffers() { |
+ OutputBuffers::iterator index; |
- for (index = picture_buffers.begin(); |
- index != picture_buffers.end(); |
+ for (index = output_picture_buffers_.begin(); |
+ index != output_picture_buffers_.end(); |
++index) { |
- DVLOG(1) << "Dismissing picture id: " << index->second->id(); |
- client_->DismissPictureBuffer(index->second->id()); |
+ if (index->second->available()) { |
+ DVLOG(1) << "Dismissing picture id: " << index->second->id(); |
+ client_->DismissPictureBuffer(index->second->id()); |
+ } else { |
+ // Move to |stale_output_picture_buffers_| for deferred deletion. |
+ stale_output_picture_buffers_.insert( |
+ std::make_pair(index->first, index->second)); |
+ } |
} |
+ |
+ output_picture_buffers_.clear(); |
+} |
+ |
+void DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer( |
+ int32 picture_buffer_id) { |
+ OutputBuffers::iterator it = stale_output_picture_buffers_.find( |
+ picture_buffer_id); |
+ DCHECK(it != stale_output_picture_buffers_.end()); |
+ DVLOG(1) << "Dismissing picture id: " << it->second->id(); |
+ client_->DismissPictureBuffer(it->second->id()); |
+ stale_output_picture_buffers_.erase(it); |
} |
} // namespace content |