Commit 33c78b62 authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Commit Bot

media/gpu/v4l2ip: allocate/destroy buffers in device thread

We want to switch V4L2IP to V4L2Queue, but V4L2Queue is more strict
about all device access being done from the device thread. Currently
buffer allocation and deallocation is being done in the client thread,
so move them to be performed by the device thread instead.

BUG=792790
TEST=Checked that VDA passed on Hana and VEA on Peach

Change-Id: I4b06b3bb10676c3a902e5e91657da2ecca7b737c
Reviewed-on: https://chromium-review.googlesource.com/c/1071496
Commit-Queue: Alexandre Courbot <acourbot@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629119}
parent 820d9592
...@@ -99,9 +99,6 @@ V4L2ImageProcessor::~V4L2ImageProcessor() { ...@@ -99,9 +99,6 @@ V4L2ImageProcessor::~V4L2ImageProcessor() {
DCHECK(!device_thread_.IsRunning()); DCHECK(!device_thread_.IsRunning());
DCHECK(!device_poll_thread_.IsRunning()); DCHECK(!device_poll_thread_.IsRunning());
DestroyInputBuffers();
DestroyOutputBuffers();
} }
void V4L2ImageProcessor::NotifyError() { void V4L2ImageProcessor::NotifyError() {
...@@ -296,14 +293,22 @@ bool V4L2ImageProcessor::Initialize() { ...@@ -296,14 +293,22 @@ bool V4L2ImageProcessor::Initialize() {
return false; return false;
} }
if (!CreateInputBuffers() || !CreateOutputBuffers())
return false;
if (!device_thread_.Start()) { if (!device_thread_.Start()) {
VLOGF(1) << "Initialize(): device thread failed to start"; VLOGF(1) << "Initialize(): device thread failed to start";
return false; return false;
} }
// Call to AllocateBuffers must be asynchronous.
base::WaitableEvent done;
bool result;
device_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&V4L2ImageProcessor::AllocateBuffersTask,
base::Unretained(this), &result, &done));
done.Wait();
if (!result) {
return false;
}
// StartDevicePoll will NotifyError on failure. // StartDevicePoll will NotifyError on failure.
device_thread_.task_runner()->PostTask( device_thread_.task_runner()->PostTask(
FROM_HERE, FROM_HERE,
...@@ -465,6 +470,9 @@ void V4L2ImageProcessor::Destroy() { ...@@ -465,6 +470,9 @@ void V4L2ImageProcessor::Destroy() {
device_thread_.task_runner()->PostTask( device_thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&V4L2ImageProcessor::StopDevicePoll, FROM_HERE, base::BindOnce(&V4L2ImageProcessor::StopDevicePoll,
base::Unretained(this))); base::Unretained(this)));
device_thread_.task_runner()->PostTask(
FROM_HERE, base::Bind(&V4L2ImageProcessor::DestroyBuffersTask,
base::Unretained(this)));
// Wait for tasks to finish/early-exit. // Wait for tasks to finish/early-exit.
device_thread_.Stop(); device_thread_.Stop();
} else { } else {
...@@ -475,8 +483,7 @@ void V4L2ImageProcessor::Destroy() { ...@@ -475,8 +483,7 @@ void V4L2ImageProcessor::Destroy() {
bool V4L2ImageProcessor::CreateInputBuffers() { bool V4L2ImageProcessor::CreateInputBuffers() {
VLOGF(2); VLOGF(2);
DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_); DCHECK(device_thread_.task_runner()->BelongsToCurrentThread());
DCHECK(!input_streamon_); DCHECK(!input_streamon_);
struct v4l2_control control; struct v4l2_control control;
...@@ -543,7 +550,7 @@ bool V4L2ImageProcessor::CreateInputBuffers() { ...@@ -543,7 +550,7 @@ bool V4L2ImageProcessor::CreateInputBuffers() {
bool V4L2ImageProcessor::CreateOutputBuffers() { bool V4L2ImageProcessor::CreateOutputBuffers() {
VLOGF(2); VLOGF(2);
DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_); DCHECK(device_thread_.task_runner()->BelongsToCurrentThread());
DCHECK(!output_streamon_); DCHECK(!output_streamon_);
struct v4l2_rect visible_rect; struct v4l2_rect visible_rect;
...@@ -600,7 +607,7 @@ bool V4L2ImageProcessor::CreateOutputBuffers() { ...@@ -600,7 +607,7 @@ bool V4L2ImageProcessor::CreateOutputBuffers() {
void V4L2ImageProcessor::DestroyInputBuffers() { void V4L2ImageProcessor::DestroyInputBuffers() {
VLOGF(2); VLOGF(2);
DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_); DCHECK(device_thread_.task_runner()->BelongsToCurrentThread());
DCHECK(!input_streamon_); DCHECK(!input_streamon_);
struct v4l2_requestbuffers reqbufs; struct v4l2_requestbuffers reqbufs;
...@@ -616,7 +623,7 @@ void V4L2ImageProcessor::DestroyInputBuffers() { ...@@ -616,7 +623,7 @@ void V4L2ImageProcessor::DestroyInputBuffers() {
void V4L2ImageProcessor::DestroyOutputBuffers() { void V4L2ImageProcessor::DestroyOutputBuffers() {
VLOGF(2); VLOGF(2);
DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_); DCHECK(device_thread_.task_runner()->BelongsToCurrentThread());
DCHECK(!output_streamon_); DCHECK(!output_streamon_);
output_buffer_map_.clear(); output_buffer_map_.clear();
...@@ -896,6 +903,23 @@ bool V4L2ImageProcessor::EnqueueOutputRecord(const JobRecord* job_record) { ...@@ -896,6 +903,23 @@ bool V4L2ImageProcessor::EnqueueOutputRecord(const JobRecord* job_record) {
return true; return true;
} }
void V4L2ImageProcessor::AllocateBuffersTask(bool* result,
base::WaitableEvent* done) {
VLOGF(2);
DCHECK(device_thread_.task_runner()->BelongsToCurrentThread());
*result = CreateInputBuffers() && CreateOutputBuffers();
done->Signal();
}
void V4L2ImageProcessor::DestroyBuffersTask() {
VLOGF(2);
DCHECK(device_thread_.task_runner()->BelongsToCurrentThread());
DestroyInputBuffers();
DestroyOutputBuffers();
}
void V4L2ImageProcessor::StartDevicePoll() { void V4L2ImageProcessor::StartDevicePoll() {
DVLOGF(3) << "starting device poll"; DVLOGF(3) << "starting device poll";
DCHECK(device_thread_.task_runner()->BelongsToCurrentThread()); DCHECK(device_thread_.task_runner()->BelongsToCurrentThread());
......
...@@ -149,6 +149,10 @@ class MEDIA_GPU_EXPORT V4L2ImageProcessor : public ImageProcessor { ...@@ -149,6 +149,10 @@ class MEDIA_GPU_EXPORT V4L2ImageProcessor : public ImageProcessor {
void ProcessTask(std::unique_ptr<JobRecord> job_record); void ProcessTask(std::unique_ptr<JobRecord> job_record);
void ServiceDeviceTask(); void ServiceDeviceTask();
// Allocate/Destroy the input/output V4L2 buffers.
void AllocateBuffersTask(bool* result, base::WaitableEvent* done);
void DestroyBuffersTask();
// Attempt to start/stop device_poll_thread_. // Attempt to start/stop device_poll_thread_.
void StartDevicePoll(); void StartDevicePoll();
void StopDevicePoll(); void StopDevicePoll();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment