| 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 cf0ad1c41f6c051818f186e70c2f67d3966089e5..0f8acf85940526ab32d97e2713957607ee003296 100644
|
| --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
|
| +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc
|
| @@ -396,7 +396,6 @@ V4L2SliceVideoDecodeAccelerator::V4L2SliceVideoDecodeAccelerator(
|
| video_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
|
| output_format_fourcc_(0),
|
| state_(kUninitialized),
|
| - output_mode_(Config::OutputMode::ALLOCATE),
|
| decoder_flushing_(false),
|
| decoder_resetting_(false),
|
| surface_set_change_pending_(false),
|
| @@ -457,6 +456,12 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config,
|
| return false;
|
| }
|
|
|
| + if (config.flush_mode != Config::FlushMode::KEEP_OUTPUT_BUFFERS &&
|
| + config.flush_mode != Config::FlushMode::RETURN_OUTPUT_BUFFERS) {
|
| + NOTIMPLEMENTED() << "Unsupported Config::FlushMode";
|
| + return false;
|
| + }
|
| +
|
| client_ptr_factory_.reset(
|
| new base::WeakPtrFactory<VideoDecodeAccelerator::Client>(client));
|
| client_ = client_ptr_factory_->GetWeakPtr();
|
| @@ -528,7 +533,7 @@ bool V4L2SliceVideoDecodeAccelerator::Initialize(const Config& config,
|
| decoder_thread_task_runner_ = decoder_thread_.task_runner();
|
|
|
| state_ = kInitialized;
|
| - output_mode_ = config.output_mode;
|
| + config_ = config;
|
|
|
| // InitializeTask will NOTIFY_ERROR on failure.
|
| decoder_thread_task_runner_->PostTask(
|
| @@ -929,9 +934,9 @@ void V4L2SliceVideoDecodeAccelerator::Dequeue() {
|
| memset(&dqbuf, 0, sizeof(dqbuf));
|
| memset(&planes, 0, sizeof(planes));
|
| dqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
| - dqbuf.memory =
|
| - (output_mode_ == Config::OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP
|
| - : V4L2_MEMORY_DMABUF);
|
| + dqbuf.memory = (config_.output_mode == Config::OutputMode::ALLOCATE
|
| + ? V4L2_MEMORY_MMAP
|
| + : V4L2_MEMORY_DMABUF);
|
| dqbuf.m.planes = planes;
|
| dqbuf.length = output_planes_count_;
|
| if (device_->Ioctl(VIDIOC_DQBUF, &dqbuf) != 0) {
|
| @@ -1105,7 +1110,7 @@ bool V4L2SliceVideoDecodeAccelerator::EnqueueOutputRecord(int index) {
|
| memset(qbuf_planes, 0, sizeof(qbuf_planes));
|
| qbuf.index = index;
|
| qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
| - if (output_mode_ == Config::OutputMode::ALLOCATE) {
|
| + if (config_.output_mode == Config::OutputMode::ALLOCATE) {
|
| qbuf.memory = V4L2_MEMORY_MMAP;
|
| } else {
|
| qbuf.memory = V4L2_MEMORY_DMABUF;
|
| @@ -1503,9 +1508,9 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask(
|
| memset(&reqbufs, 0, sizeof(reqbufs));
|
| reqbufs.count = buffers.size();
|
| reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
| - reqbufs.memory =
|
| - (output_mode_ == Config::OutputMode::ALLOCATE ? V4L2_MEMORY_MMAP
|
| - : V4L2_MEMORY_DMABUF);
|
| + reqbufs.memory = (config_.output_mode == Config::OutputMode::ALLOCATE
|
| + ? V4L2_MEMORY_MMAP
|
| + : V4L2_MEMORY_DMABUF);
|
| IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs);
|
|
|
| if (reqbufs.count != buffers.size()) {
|
| @@ -1535,7 +1540,7 @@ void V4L2SliceVideoDecodeAccelerator::AssignPictureBuffersTask(
|
| // This will remain true until ImportBufferForPicture is called, either by
|
| // the client, or by ourselves, if we are allocating.
|
| output_record.at_client = true;
|
| - if (output_mode_ == Config::OutputMode::ALLOCATE) {
|
| + if (config_.output_mode == Config::OutputMode::ALLOCATE) {
|
| std::vector<base::ScopedFD> dmabuf_fds =
|
| std::move(device_->GetDmabufsForV4L2Buffer(
|
| i, output_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE));
|
| @@ -1637,7 +1642,7 @@ void V4L2SliceVideoDecodeAccelerator::AssignEGLImage(
|
| DCHECK(!output_record.at_device);
|
|
|
| output_record.egl_image = egl_image;
|
| - if (output_mode_ == Config::OutputMode::IMPORT) {
|
| + if (config_.output_mode == Config::OutputMode::IMPORT) {
|
| DCHECK(output_record.dmabuf_fds.empty());
|
| output_record.dmabuf_fds = std::move(*passed_dmabuf_fds);
|
| }
|
| @@ -1665,7 +1670,7 @@ void V4L2SliceVideoDecodeAccelerator::ImportBufferForPicture(
|
| passed_dmabuf_fds->push_back(base::ScopedFD(fd));
|
| }
|
|
|
| - if (output_mode_ != Config::OutputMode::IMPORT) {
|
| + if (config_.output_mode != Config::OutputMode::IMPORT) {
|
| LOGF(ERROR) << "Cannot import in non-import mode";
|
| NOTIFY_ERROR(INVALID_ARGUMENT);
|
| return;
|
| @@ -1872,14 +1877,24 @@ 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 (config_.flush_mode == Config::FlushMode::RETURN_OUTPUT_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;
|
| +
|
| DVLOGF(3) << "Flush finished";
|
|
|
| child_task_runner_->PostTask(FROM_HERE,
|
| base::Bind(&Client::NotifyFlushDone, client_));
|
| -
|
| return true;
|
| }
|
|
|
| @@ -2675,6 +2690,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.
|
|
|