| Index: content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
|
| diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
|
| index a338cc2672454382adf576efa46fa817e3c2c08d..a376ae295f176396c6d8cbcf24c094280f23c868 100644
|
| --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
|
| +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
|
| @@ -1623,19 +1623,21 @@ void V4L2SliceVideoDecodeAccelerator::ReusePictureBufferTask(
|
| surfaces_at_display_.erase(it);
|
| }
|
|
|
| -void V4L2SliceVideoDecodeAccelerator::Flush() {
|
| +void V4L2SliceVideoDecodeAccelerator::Flush(bool return_buffers) {
|
| DVLOGF(3);
|
| DCHECK(child_task_runner_->BelongsToCurrentThread());
|
|
|
| decoder_thread_task_runner_->PostTask(
|
| FROM_HERE, base::Bind(&V4L2SliceVideoDecodeAccelerator::FlushTask,
|
| - base::Unretained(this)));
|
| + base::Unretained(this), return_buffers));
|
| }
|
|
|
| -void V4L2SliceVideoDecodeAccelerator::FlushTask() {
|
| +void V4L2SliceVideoDecodeAccelerator::FlushTask(bool return_buffers) {
|
| DVLOGF(3);
|
| DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread());
|
|
|
| + flush_return_all_buffers_ = return_buffers;
|
| +
|
| if (!decoder_input_queue_.empty()) {
|
| // We are not done with pending inputs, so queue an empty buffer,
|
| // which - when reached - will trigger flush sequence.
|
| @@ -1697,14 +1699,25 @@ bool V4L2SliceVideoDecodeAccelerator::FinishFlush() {
|
| // out of hardware. There can be no other owners of input buffers.
|
| DCHECK_EQ(free_input_buffers_.size(), input_buffer_map_.size());
|
|
|
| - SendPictureReady();
|
| + if (flush_return_all_buffers_) {
|
| + for (auto& output : free_output_buffers_) {
|
| + scoped_refptr<V4L2DecodeSurface> dec_surface = new V4L2DecodeSurface(
|
| + -1, -1, output,
|
| + base::Bind(&V4L2SliceVideoDecodeAccelerator::ReuseOutputBuffer,
|
| + base::Unretained(this)));
|
| + OutputSurface(dec_surface);
|
| + }
|
| +
|
| + free_output_buffers_.clear();
|
| + }
|
|
|
| decoder_flushing_ = false;
|
| + flush_return_all_buffers_ = false;
|
| +
|
| DVLOGF(3) << "Flush finished";
|
|
|
| child_task_runner_->PostTask(FROM_HERE,
|
| base::Bind(&Client::NotifyFlushDone, client_));
|
| -
|
| return true;
|
| }
|
|
|
| @@ -2503,6 +2516,18 @@ void V4L2SliceVideoDecodeAccelerator::OutputSurface(
|
| DCHECK_NE(output_record.picture_id, -1);
|
| output_record.at_client = true;
|
|
|
| + // If the surface still has a sync object assigned, destroy it. This means
|
| + // we didn't use this buffer for decode and we did not need to wait on it
|
| + // before enqueuing the buffer to the device.
|
| + if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
|
| + if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) {
|
| + LOGF(ERROR) << "eglDestroySyncKHR failed!";
|
| + NOTIFY_ERROR(PLATFORM_FAILURE);
|
| + return;
|
| + }
|
| + output_record.egl_sync = EGL_NO_SYNC_KHR;
|
| + }
|
| +
|
| // TODO(posciak): Use visible size from decoder here instead
|
| // (crbug.com/402760). Passing (0, 0) results in the client using the
|
| // visible size extracted from the container instead.
|
|
|