Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Unified Diff: content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc

Issue 1816203003: Add an additional VDA::Flush() mode to return all allocated buffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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.

Powered by Google App Engine
This is Rietveld 408576698