Commit 07c99c39 authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Commit Bot

media/gpu/v4l2: clear v4l2 devices from their main thread

The introduction of a sequence checker in V4L2Devices means that we need
to be more careful about who destroys (i.e. who "owns") a given
V4L2Device. Make sure the IP device is destroyed by the IP thread, and
the decoder device by the decoder thread.

Bug: 1003223
Test: vdatests passing on Kevin.

Change-Id: I21d55163d5830b45afb882fcced2bd8cef069151
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1826300
Auto-Submit: Alexandre Courbot <acourbot@chromium.org>
Commit-Queue: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700086}
parent f65a6a6a
...@@ -384,6 +384,11 @@ void V4L2SliceVideoDecodeAccelerator::Destroy() { ...@@ -384,6 +384,11 @@ void V4L2SliceVideoDecodeAccelerator::Destroy() {
// executes after all the tasks potentially posted by the IP. // executes after all the tasks potentially posted by the IP.
base::BindOnce( base::BindOnce(
[](V4L2SliceVideoDecodeAccelerator* vda) { [](V4L2SliceVideoDecodeAccelerator* vda) {
vda->gl_image_device_ = nullptr;
// The image processor's thread was the user of the image
// processor device, so let it keep the last reference and destroy
// it in its own thread.
vda->image_processor_device_ = nullptr;
vda->image_processor_ = nullptr; vda->image_processor_ = nullptr;
vda->surfaces_at_ip_ = {}; vda->surfaces_at_ip_ = {};
vda->decoder_thread_task_runner_->PostTask( vda->decoder_thread_task_runner_->PostTask(
...@@ -428,6 +433,10 @@ void V4L2SliceVideoDecodeAccelerator::DestroyTask() { ...@@ -428,6 +433,10 @@ void V4L2SliceVideoDecodeAccelerator::DestroyTask() {
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this); this);
// Clear the V4L2 devices in the decoder thread so the V4L2Device's
// destructor is called from the thread that used it.
device_ = nullptr;
DCHECK(surfaces_at_device_.empty()); DCHECK(surfaces_at_device_.empty());
DCHECK(surfaces_at_display_.empty()); DCHECK(surfaces_at_display_.empty());
DCHECK(decoder_display_queue_.empty()); DCHECK(decoder_display_queue_.empty());
......
...@@ -1924,6 +1924,11 @@ void V4L2VideoDecodeAccelerator::DestroyTask() { ...@@ -1924,6 +1924,11 @@ void V4L2VideoDecodeAccelerator::DestroyTask() {
// First liberate all the frames held by the client. // First liberate all the frames held by the client.
buffers_at_client_.clear(); buffers_at_client_.clear();
egl_image_device_ = nullptr;
// The image processor's thread was the user of the image processor device,
// so let it keep the last reference and destroy it in its own thread.
image_processor_device_ = nullptr;
image_processor_ = nullptr; image_processor_ = nullptr;
while (!buffers_at_ip_.empty()) while (!buffers_at_ip_.empty())
buffers_at_ip_.pop(); buffers_at_ip_.pop();
...@@ -1937,6 +1942,10 @@ void V4L2VideoDecodeAccelerator::DestroyTask() { ...@@ -1937,6 +1942,10 @@ void V4L2VideoDecodeAccelerator::DestroyTask() {
decoder_h264_parser_ = nullptr; decoder_h264_parser_ = nullptr;
workarounds_.clear(); workarounds_.clear();
// Clear the V4L2 devices in the decoder thread so the V4L2Device's
// destructor is called from the thread that used it.
device_ = nullptr;
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this); this);
} }
......
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