Commit a35c28a4 authored by Chih-Yu Huang's avatar Chih-Yu Huang Committed by Commit Bot

media/gpu/linux: Make VideoDecoderPipeline delegate VD tasks to decoder thread.

Originally, VideoDecoderPipeline delegates VD tasks to the client
thread. Each VD implementation then post the tasks to decoder thread.
Then VD implementations post the callback back to the client thread
when the task is done. In the future, ImageProcessor will also operate
on the decoder thread. We will pass the task and output frames by:

  VDPipeline (client)
  -> VD (client -> decoder -> client)
  -> VDPipeline (client)
  -> IP (client -> decoder -> client)
  -> VDPipeline (client)
  -> Converter (client -> GPU -> client)
  -> VDPipeline (client)
  Total 6 thread hopping.

This CL now posts the VD task on the decoder thread. We don't need to
hop thread inside each VD implementation. With this CL, we could save
2 thread hopping.

  VDPipeline (client -> decoder)
  -> VD (decoder)
  -> VDPipeline (decoder)
  -> IP (decoder)
  -> VDPipeline (decoder)
  -> Converter (decoder -> GPU -> decoder)
  -> VDPipeline (decoder -> client)
  Total 4 thread hopping.

BUG=chromium:998413
TEST=run video_decode_accelerator_tests on Eve and Kevin
     with dcheck_always_on = true

Change-Id: I7367663258adfd0f46ddca25493faff4633ae034
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1777449
Commit-Queue: Chih-Yu Huang <akahuang@chromium.org>
Reviewed-by: default avatarDavid Staessens <dstaessens@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707704}
parent 105403f9
This diff is collapsed.
...@@ -86,7 +86,6 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { ...@@ -86,7 +86,6 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder {
// Function signature for creating VideoDecoder. // Function signature for creating VideoDecoder.
using CreateVDFunc = std::unique_ptr<DecoderInterface> (*)( using CreateVDFunc = std::unique_ptr<DecoderInterface> (*)(
scoped_refptr<base::SequencedTaskRunner>,
scoped_refptr<base::SequencedTaskRunner>, scoped_refptr<base::SequencedTaskRunner>,
base::RepeatingCallback<DmabufVideoFramePool*()>); base::RepeatingCallback<DmabufVideoFramePool*()>);
using GetCreateVDFunctionsCB = using GetCreateVDFunctionsCB =
...@@ -129,6 +128,12 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { ...@@ -129,6 +128,12 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder {
void Destroy() override; void Destroy() override;
void DestroyTask(); void DestroyTask();
void InitializeTask(const VideoDecoderConfig& config,
InitCB init_cb,
const OutputCB& output_cb);
void ResetTask(base::OnceClosure closure);
void DecodeTask(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb);
void CreateAndInitializeVD(base::queue<CreateVDFunc> create_vd_funcs, void CreateAndInitializeVD(base::queue<CreateVDFunc> create_vd_funcs,
VideoDecoderConfig config); VideoDecoderConfig config);
void OnInitializeDone(base::queue<CreateVDFunc> create_vd_funcs, void OnInitializeDone(base::queue<CreateVDFunc> create_vd_funcs,
...@@ -140,10 +145,6 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { ...@@ -140,10 +145,6 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder {
void OnFrameConverted(scoped_refptr<VideoFrame> frame); void OnFrameConverted(scoped_refptr<VideoFrame> frame);
void OnError(const std::string& msg); void OnError(const std::string& msg);
static void OnFrameDecodedThunk(
scoped_refptr<base::SequencedTaskRunner> task_runner,
base::Optional<base::WeakPtr<VideoDecoderPipeline>> pipeline,
scoped_refptr<VideoFrame> frame);
void OnFrameDecoded(scoped_refptr<VideoFrame> frame); void OnFrameDecoded(scoped_refptr<VideoFrame> frame);
// Call |client_flush_cb_| with |status| if we need. // Call |client_flush_cb_| with |status| if we need.
...@@ -157,8 +158,8 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { ...@@ -157,8 +158,8 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder {
const scoped_refptr<base::SequencedTaskRunner> client_task_runner_; const scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
SEQUENCE_CHECKER(client_sequence_checker_); SEQUENCE_CHECKER(client_sequence_checker_);
// The decoder task runner and its sequence checker. |decoder_| should post // The decoder task runner and its sequence checker. Call |decoder_|'s,
// time-consuming task and call |frame_pool_|'s methods on this task runner. // |frame_pool_|'s, and |frame_converter_|'s methods on this task runner.
const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_; const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_;
SEQUENCE_CHECKER(decoder_sequence_checker_); SEQUENCE_CHECKER(decoder_sequence_checker_);
...@@ -190,9 +191,13 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { ...@@ -190,9 +191,13 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder {
// Set to true when any unexpected error occurs. // Set to true when any unexpected error occurs.
bool has_error_ = false; bool has_error_ = false;
base::WeakPtr<VideoDecoderPipeline> client_weak_this_;
base::WeakPtr<VideoDecoderPipeline> decoder_weak_this_;
// The weak pointer of this, bound to |client_task_runner_|. // The weak pointer of this, bound to |client_task_runner_|.
base::WeakPtr<VideoDecoderPipeline> weak_this_; base::WeakPtrFactory<VideoDecoderPipeline> client_weak_this_factory_{this};
base::WeakPtrFactory<VideoDecoderPipeline> weak_this_factory_{this}; // The weak pointer of this, bound to |decoder_task_runner_|.
base::WeakPtrFactory<VideoDecoderPipeline> decoder_weak_this_factory_{this};
}; };
} // namespace media } // namespace media
......
...@@ -42,10 +42,9 @@ constexpr uint32_t kSupportedInputFourccs[] = { ...@@ -42,10 +42,9 @@ constexpr uint32_t kSupportedInputFourccs[] = {
// static // static
std::unique_ptr<VideoDecoderPipeline::DecoderInterface> std::unique_ptr<VideoDecoderPipeline::DecoderInterface>
V4L2SliceVideoDecoder::Create( V4L2SliceVideoDecoder::Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool_cb) { GetFramePoolCB get_pool_cb) {
DCHECK(client_task_runner->RunsTasksInCurrentSequence()); DCHECK(decoder_task_runner->RunsTasksInCurrentSequence());
DCHECK(get_pool_cb); DCHECK(get_pool_cb);
scoped_refptr<V4L2Device> device = V4L2Device::Create(); scoped_refptr<V4L2Device> device = V4L2Device::Create();
...@@ -55,8 +54,7 @@ V4L2SliceVideoDecoder::Create( ...@@ -55,8 +54,7 @@ V4L2SliceVideoDecoder::Create(
} }
return base::WrapUnique<VideoDecoderPipeline::DecoderInterface>( return base::WrapUnique<VideoDecoderPipeline::DecoderInterface>(
new V4L2SliceVideoDecoder(std::move(client_task_runner), new V4L2SliceVideoDecoder(std::move(decoder_task_runner),
std::move(decoder_task_runner),
std::move(device), std::move(get_pool_cb))); std::move(device), std::move(get_pool_cb)));
} }
...@@ -73,36 +71,20 @@ SupportedVideoDecoderConfigs V4L2SliceVideoDecoder::GetSupportedConfigs() { ...@@ -73,36 +71,20 @@ SupportedVideoDecoderConfigs V4L2SliceVideoDecoder::GetSupportedConfigs() {
} }
V4L2SliceVideoDecoder::V4L2SliceVideoDecoder( V4L2SliceVideoDecoder::V4L2SliceVideoDecoder(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
scoped_refptr<V4L2Device> device, scoped_refptr<V4L2Device> device,
GetFramePoolCB get_pool_cb) GetFramePoolCB get_pool_cb)
: device_(std::move(device)), : device_(std::move(device)),
get_pool_cb_(std::move(get_pool_cb)), get_pool_cb_(std::move(get_pool_cb)),
client_task_runner_(std::move(client_task_runner)),
decoder_task_runner_(std::move(decoder_task_runner)), decoder_task_runner_(std::move(decoder_task_runner)),
weak_this_factory_(this) { weak_this_factory_(this) {
DETACH_FROM_SEQUENCE(client_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DETACH_FROM_SEQUENCE(decoder_sequence_checker_);
VLOGF(2); VLOGF(2);
weak_this_ = weak_this_factory_.GetWeakPtr(); weak_this_ = weak_this_factory_.GetWeakPtr();
} }
V4L2SliceVideoDecoder::~V4L2SliceVideoDecoder() { V4L2SliceVideoDecoder::~V4L2SliceVideoDecoder() {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
VLOGF(2);
// We need this event to synchronously destroy this instance.
// TODO(akahuang): Remove this event by manipulating this instance only on one
// sequence.
base::WaitableEvent event;
decoder_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&V4L2SliceVideoDecoder::DestroyTask, weak_this_,
base::Unretained(&event)));
event.Wait();
}
void V4L2SliceVideoDecoder::DestroyTask(base::WaitableEvent* event) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DVLOGF(2); DVLOGF(2);
...@@ -124,34 +106,20 @@ void V4L2SliceVideoDecoder::DestroyTask(base::WaitableEvent* event) { ...@@ -124,34 +106,20 @@ void V4L2SliceVideoDecoder::DestroyTask(base::WaitableEvent* event) {
} }
weak_this_factory_.InvalidateWeakPtrs(); weak_this_factory_.InvalidateWeakPtrs();
event->Signal();
} }
void V4L2SliceVideoDecoder::Initialize(const VideoDecoderConfig& config, void V4L2SliceVideoDecoder::Initialize(const VideoDecoderConfig& config,
InitCB init_cb, InitCB init_cb,
const OutputCB& output_cb) { const OutputCB& output_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
DCHECK(config.IsValidConfig());
decoder_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&V4L2SliceVideoDecoder::InitializeTask, weak_this_, config,
std::move(init_cb), std::move(output_cb)));
}
void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
InitCB init_cb,
const OutputCB& output_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DCHECK(config.IsValidConfig());
DCHECK(state_ == State::kUninitialized || state_ == State::kDecoding); DCHECK(state_ == State::kUninitialized || state_ == State::kDecoding);
DVLOGF(3); DVLOGF(3);
// Reset V4L2 device and queue if reinitializing decoder. // Reset V4L2 device and queue if reinitializing decoder.
if (state_ != State::kUninitialized) { if (state_ != State::kUninitialized) {
if (!StopStreamV4L2Queue()) { if (!StopStreamV4L2Queue()) {
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
...@@ -163,8 +131,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -163,8 +131,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
device_ = V4L2Device::Create(); device_ = V4L2Device::Create();
if (!device_) { if (!device_) {
VLOGF(1) << "Failed to create V4L2 device."; VLOGF(1) << "Failed to create V4L2 device.";
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
...@@ -185,8 +152,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -185,8 +152,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
!device_->Open(V4L2Device::Type::kDecoder, input_format_fourcc)) { !device_->Open(V4L2Device::Type::kDecoder, input_format_fourcc)) {
VLOGF(1) << "Failed to open device for profile: " << profile VLOGF(1) << "Failed to open device for profile: " << profile
<< " fourcc: " << FourccToString(input_format_fourcc); << " fourcc: " << FourccToString(input_format_fourcc);
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
...@@ -196,8 +162,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -196,8 +162,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
(caps.capabilities & kCapsRequired) != kCapsRequired) { (caps.capabilities & kCapsRequired) != kCapsRequired) {
VLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP, " VLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP, "
<< "caps check failed: 0x" << std::hex << caps.capabilities; << "caps check failed: 0x" << std::hex << caps.capabilities;
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
...@@ -208,8 +173,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -208,8 +173,7 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
output_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); output_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
if (!input_queue_ || !output_queue_) { if (!input_queue_ || !output_queue_) {
VLOGF(1) << "Failed to create V4L2 queue."; VLOGF(1) << "Failed to create V4L2 queue.";
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
...@@ -217,46 +181,40 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -217,46 +181,40 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>( backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>(
this, device_, frame_pool_, profile, decoder_task_runner_); this, device_, frame_pool_, profile, decoder_task_runner_);
if (!backend_->Initialize()) { if (!backend_->Initialize()) {
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
// Setup input format. // Setup input format.
if (!SetupInputFormat(input_format_fourcc)) { if (!SetupInputFormat(input_format_fourcc)) {
VLOGF(1) << "Failed to setup input format."; VLOGF(1) << "Failed to setup input format.";
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
if (!SetCodedSizeOnInputQueue(config.coded_size())) { if (!SetCodedSizeOnInputQueue(config.coded_size())) {
VLOGF(1) << "Failed to set coded size on input queue"; VLOGF(1) << "Failed to set coded size on input queue";
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
// Setup output format. // Setup output format.
if (!SetupOutputFormat(config.coded_size(), config.visible_rect())) { if (!SetupOutputFormat(config.coded_size(), config.visible_rect())) {
VLOGF(1) << "Failed to setup output format."; VLOGF(1) << "Failed to setup output format.";
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
if (input_queue_->AllocateBuffers(kNumInputBuffers, V4L2_MEMORY_MMAP) == 0) { if (input_queue_->AllocateBuffers(kNumInputBuffers, V4L2_MEMORY_MMAP) == 0) {
VLOGF(1) << "Failed to allocate input buffer."; VLOGF(1) << "Failed to allocate input buffer.";
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
// Call init_cb // Call init_cb
output_cb_ = output_cb; output_cb_ = output_cb;
SetState(State::kDecoding); SetState(State::kDecoding);
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(true);
base::BindOnce(std::move(init_cb), true));
} }
bool V4L2SliceVideoDecoder::SetupInputFormat(uint32_t input_format_fourcc) { bool V4L2SliceVideoDecoder::SetupInputFormat(uint32_t input_format_fourcc) {
...@@ -377,15 +335,6 @@ V4L2SliceVideoDecoder::UpdateVideoFramePoolFormat( ...@@ -377,15 +335,6 @@ V4L2SliceVideoDecoder::UpdateVideoFramePoolFormat(
} }
void V4L2SliceVideoDecoder::Reset(base::OnceClosure closure) { void V4L2SliceVideoDecoder::Reset(base::OnceClosure closure) {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
DVLOGF(3);
decoder_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&V4L2SliceVideoDecoder::ResetTask, weak_this_,
std::move(closure)));
}
void V4L2SliceVideoDecoder::ResetTask(base::OnceClosure closure) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DVLOGF(3); DVLOGF(3);
...@@ -404,22 +353,11 @@ void V4L2SliceVideoDecoder::ResetTask(base::OnceClosure closure) { ...@@ -404,22 +353,11 @@ void V4L2SliceVideoDecoder::ResetTask(base::OnceClosure closure) {
return; return;
} }
client_task_runner_->PostTask(FROM_HERE, std::move(closure)); std::move(closure).Run();
} }
void V4L2SliceVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, void V4L2SliceVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
DecodeCB decode_cb) { DecodeCB decode_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
decoder_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&V4L2SliceVideoDecoder::EnqueueDecodeTask, weak_this_,
std::move(buffer), std::move(decode_cb)));
}
void V4L2SliceVideoDecoder::EnqueueDecodeTask(
scoped_refptr<DecoderBuffer> buffer,
V4L2SliceVideoDecoder::DecodeCB decode_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DCHECK_NE(state_, State::kUninitialized); DCHECK_NE(state_, State::kUninitialized);
...@@ -584,13 +522,6 @@ void V4L2SliceVideoDecoder::ServiceDeviceTask(bool /* event */) { ...@@ -584,13 +522,6 @@ void V4L2SliceVideoDecoder::ServiceDeviceTask(bool /* event */) {
} }
} }
void V4L2SliceVideoDecoder::RunDecodeCB(DecodeCB cb, DecodeStatus status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
client_task_runner_->PostTask(FROM_HERE,
base::BindOnce(std::move(cb), status));
}
void V4L2SliceVideoDecoder::OutputFrame(scoped_refptr<VideoFrame> frame, void V4L2SliceVideoDecoder::OutputFrame(scoped_refptr<VideoFrame> frame,
const gfx::Rect& visible_rect, const gfx::Rect& visible_rect,
base::TimeDelta timestamp) { base::TimeDelta timestamp) {
...@@ -614,9 +545,7 @@ void V4L2SliceVideoDecoder::OutputFrame(scoped_refptr<VideoFrame> frame, ...@@ -614,9 +545,7 @@ void V4L2SliceVideoDecoder::OutputFrame(scoped_refptr<VideoFrame> frame,
frame = std::move(wrapped_frame); frame = std::move(wrapped_frame);
} }
output_cb_.Run(std::move(frame));
client_task_runner_->PostTask(FROM_HERE,
base::BindOnce(output_cb_, std::move(frame)));
} }
void V4L2SliceVideoDecoder::SetState(State new_state) { void V4L2SliceVideoDecoder::SetState(State new_state) {
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "base/optional.h" #include "base/optional.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "media/base/video_frame_layout.h" #include "media/base/video_frame_layout.h"
...@@ -46,7 +45,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder ...@@ -46,7 +45,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder
// ensure V4L2SliceVideoDecoder is available on the device. It will be // ensure V4L2SliceVideoDecoder is available on the device. It will be
// determined in Initialize(). // determined in Initialize().
static std::unique_ptr<VideoDecoderPipeline::DecoderInterface> Create( static std::unique_ptr<VideoDecoderPipeline::DecoderInterface> Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool_cb); GetFramePoolCB get_pool_cb);
...@@ -67,7 +65,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder ...@@ -67,7 +65,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder
bool ChangeResolution(gfx::Size pic_size, bool ChangeResolution(gfx::Size pic_size,
gfx::Rect visible_rect, gfx::Rect visible_rect,
size_t num_output_frames) override; size_t num_output_frames) override;
void RunDecodeCB(DecodeCB cb, DecodeStatus status) override;
void OutputFrame(scoped_refptr<VideoFrame> frame, void OutputFrame(scoped_refptr<VideoFrame> frame,
const gfx::Rect& visible_rect, const gfx::Rect& visible_rect,
base::TimeDelta timestamp) override; base::TimeDelta timestamp) override;
...@@ -76,7 +73,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder ...@@ -76,7 +73,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder
friend class V4L2SliceVideoDecoderTest; friend class V4L2SliceVideoDecoderTest;
V4L2SliceVideoDecoder( V4L2SliceVideoDecoder(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
scoped_refptr<V4L2Device> device, scoped_refptr<V4L2Device> device,
GetFramePoolCB get_pool_cb); GetFramePoolCB get_pool_cb);
...@@ -110,10 +106,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder ...@@ -110,10 +106,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
}; };
// Initialize on decoder thread.
void InitializeTask(const VideoDecoderConfig& config,
InitCB init_cb,
const OutputCB& output_cb);
// Setup format for input queue. // Setup format for input queue.
bool SetupInputFormat(uint32_t input_format_fourcc); bool SetupInputFormat(uint32_t input_format_fourcc);
...@@ -137,15 +129,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder ...@@ -137,15 +129,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder
const gfx::Size& size, const gfx::Size& size,
const gfx::Rect& visible_rect); const gfx::Rect& visible_rect);
// Destroy on decoder thread.
void DestroyTask(base::WaitableEvent* event);
// Reset on decoder thread.
void ResetTask(base::OnceClosure closure);
// Enqueue |buffer| to be decoded. |decode_cb| will be called once |buffer|
// is no longer used.
void EnqueueDecodeTask(scoped_refptr<DecoderBuffer> buffer,
V4L2SliceVideoDecoder::DecodeCB decode_cb);
// Start streaming V4L2 input and output queues. Attempt to start // Start streaming V4L2 input and output queues. Attempt to start
// |device_poll_thread_| before starting streaming. // |device_poll_thread_| before starting streaming.
bool StartStreamV4L2Queue(); bool StartStreamV4L2Queue();
...@@ -168,11 +151,8 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder ...@@ -168,11 +151,8 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder
GetFramePoolCB get_pool_cb_; GetFramePoolCB get_pool_cb_;
DmabufVideoFramePool* frame_pool_ = nullptr; DmabufVideoFramePool* frame_pool_ = nullptr;
// Client task runner. All public methods of // Decoder task runner. All public methods of
// VideoDecoderPipeline::DecoderInterface are executed at this task runner. // VideoDecoderPipeline::DecoderInterface are executed at this task runner.
const scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
// Thread to communicate with the device on. Most of internal methods and data
// members are manipulated on this thread.
const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_; const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_;
// State of the instance. // State of the instance.
...@@ -192,7 +172,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder ...@@ -192,7 +172,6 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder
BitstreamIdGenerator bitstream_id_generator_; BitstreamIdGenerator bitstream_id_generator_;
SEQUENCE_CHECKER(client_sequence_checker_);
SEQUENCE_CHECKER(decoder_sequence_checker_); SEQUENCE_CHECKER(decoder_sequence_checker_);
// |weak_this_| must be dereferenced and invalidated on // |weak_this_| must be dereferenced and invalidated on
......
...@@ -51,9 +51,6 @@ class V4L2VideoDecoderBackend { ...@@ -51,9 +51,6 @@ class V4L2VideoDecoderBackend {
virtual bool ChangeResolution(gfx::Size pic_size, virtual bool ChangeResolution(gfx::Size pic_size,
gfx::Rect visible_rect, gfx::Rect visible_rect,
size_t num_output_frames) = 0; size_t num_output_frames) = 0;
// Call the decode callback and count the number of pending callbacks.
virtual void RunDecodeCB(VideoDecoder::DecodeCB cb,
DecodeStatus status) = 0;
// Convert the frame and call the output callback. // Convert the frame and call the output callback.
virtual void OutputFrame(scoped_refptr<VideoFrame> frame, virtual void OutputFrame(scoped_refptr<VideoFrame> frame,
const gfx::Rect& visible_rect, const gfx::Rect& visible_rect,
...@@ -65,8 +62,7 @@ class V4L2VideoDecoderBackend { ...@@ -65,8 +62,7 @@ class V4L2VideoDecoderBackend {
virtual bool Initialize() = 0; virtual bool Initialize() = 0;
// Schedule |buffer| to be processed, with bitstream ID |bitstream_id|. // Schedule |buffer| to be processed, with bitstream ID |bitstream_id|.
// The backend must call V4L2SliceVideoDecoder::RunDecodeCB() with |decode_cb| // The backend must call |decode_cb| once the buffer is not used anymore.
// as argument once the buffer is not used anymore.
virtual void EnqueueDecodeTask(scoped_refptr<DecoderBuffer> buffer, virtual void EnqueueDecodeTask(scoped_refptr<DecoderBuffer> buffer,
VideoDecoder::DecodeCB decode_cb, VideoDecoder::DecodeCB decode_cb,
int32_t bitstream_id) = 0; int32_t bitstream_id) = 0;
......
...@@ -396,8 +396,7 @@ bool V4L2StatelessVideoDecoderBackend::PumpDecodeTask() { ...@@ -396,8 +396,7 @@ bool V4L2StatelessVideoDecoderBackend::PumpDecodeTask() {
// Current decode request is finished processing. // Current decode request is finished processing.
if (current_decode_request_) { if (current_decode_request_) {
DCHECK(current_decode_request_->decode_cb); DCHECK(current_decode_request_->decode_cb);
client_->RunDecodeCB(std::move(current_decode_request_->decode_cb), std::move(current_decode_request_->decode_cb).Run(DecodeStatus::OK);
DecodeStatus::OK);
current_decode_request_ = base::nullopt; current_decode_request_ = base::nullopt;
} }
...@@ -469,7 +468,7 @@ void V4L2StatelessVideoDecoderBackend::PumpOutputSurfaces() { ...@@ -469,7 +468,7 @@ void V4L2StatelessVideoDecoderBackend::PumpOutputSurfaces() {
case OutputRequest::kFlushFence: case OutputRequest::kFlushFence:
DCHECK(output_request_queue_.empty()); DCHECK(output_request_queue_.empty());
DVLOGF(2) << "Flush finished."; DVLOGF(2) << "Flush finished.";
client_->RunDecodeCB(std::move(flush_cb_), DecodeStatus::OK); std::move(flush_cb_).Run(DecodeStatus::OK);
resume_decode = true; resume_decode = true;
break; break;
...@@ -539,18 +538,18 @@ void V4L2StatelessVideoDecoderBackend::ClearPendingRequests( ...@@ -539,18 +538,18 @@ void V4L2StatelessVideoDecoderBackend::ClearPendingRequests(
output_request_queue_.pop(); output_request_queue_.pop();
if (flush_cb_) if (flush_cb_)
client_->RunDecodeCB(std::move(flush_cb_), status); std::move(flush_cb_).Run(status);
// Clear current_decode_request_ and decode_request_queue_. // Clear current_decode_request_ and decode_request_queue_.
if (current_decode_request_) { if (current_decode_request_) {
client_->RunDecodeCB(std::move(current_decode_request_->decode_cb), status); std::move(current_decode_request_->decode_cb).Run(status);
current_decode_request_ = base::nullopt; current_decode_request_ = base::nullopt;
} }
while (!decode_request_queue_.empty()) { while (!decode_request_queue_.empty()) {
auto request = std::move(decode_request_queue_.front()); auto request = std::move(decode_request_queue_.front());
decode_request_queue_.pop(); decode_request_queue_.pop();
client_->RunDecodeCB(std::move(request.decode_cb), status); std::move(request.decode_cb).Run(status);
} }
} }
......
...@@ -65,12 +65,10 @@ VaapiVideoDecoder::DecodeTask::DecodeTask(DecodeTask&&) = default; ...@@ -65,12 +65,10 @@ VaapiVideoDecoder::DecodeTask::DecodeTask(DecodeTask&&) = default;
// static // static
std::unique_ptr<VideoDecoderPipeline::DecoderInterface> std::unique_ptr<VideoDecoderPipeline::DecoderInterface>
VaapiVideoDecoder::Create( VaapiVideoDecoder::Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool_cb) { GetFramePoolCB get_pool_cb) {
return base::WrapUnique<VideoDecoderPipeline::DecoderInterface>( return base::WrapUnique<VideoDecoderPipeline::DecoderInterface>(
new VaapiVideoDecoder(std::move(client_task_runner), new VaapiVideoDecoder(std::move(decoder_task_runner),
std::move(decoder_task_runner),
std::move(get_pool_cb))); std::move(get_pool_cb)));
} }
...@@ -81,37 +79,21 @@ SupportedVideoDecoderConfigs VaapiVideoDecoder::GetSupportedConfigs() { ...@@ -81,37 +79,21 @@ SupportedVideoDecoderConfigs VaapiVideoDecoder::GetSupportedConfigs() {
} }
VaapiVideoDecoder::VaapiVideoDecoder( VaapiVideoDecoder::VaapiVideoDecoder(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool_cb) GetFramePoolCB get_pool_cb)
: get_pool_cb_(std::move(get_pool_cb)), : get_pool_cb_(std::move(get_pool_cb)),
buffer_id_to_timestamp_(kTimestampCacheSize), buffer_id_to_timestamp_(kTimestampCacheSize),
client_task_runner_(std::move(client_task_runner)),
decoder_task_runner_(std::move(decoder_task_runner)), decoder_task_runner_(std::move(decoder_task_runner)),
weak_this_factory_(this) { weak_this_factory_(this) {
DETACH_FROM_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
VLOGF(2); VLOGF(2);
weak_this_ = weak_this_factory_.GetWeakPtr(); weak_this_ = weak_this_factory_.GetWeakPtr();
} }
VaapiVideoDecoder::~VaapiVideoDecoder() { VaapiVideoDecoder::~VaapiVideoDecoder() {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
VLOGF(2);
// We need this event to synchronously destroy this instance.
// TODO(akahuang): Remove this event by manipulating this instance only on one
// sequence.
base::WaitableEvent event;
decoder_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VaapiVideoDecoder::DestroyTask, weak_this_,
base::Unretained(&event)));
event.Wait();
}
void VaapiVideoDecoder::DestroyTask(base::WaitableEvent* event) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DVLOGF(2); VLOGF(2);
// Abort all currently scheduled decode tasks. // Abort all currently scheduled decode tasks.
ClearDecodeTaskQueue(DecodeStatus::ABORTED); ClearDecodeTaskQueue(DecodeStatus::ABORTED);
...@@ -122,34 +104,20 @@ void VaapiVideoDecoder::DestroyTask(base::WaitableEvent* event) { ...@@ -122,34 +104,20 @@ void VaapiVideoDecoder::DestroyTask(base::WaitableEvent* event) {
} }
weak_this_factory_.InvalidateWeakPtrs(); weak_this_factory_.InvalidateWeakPtrs();
event->Signal();
} }
void VaapiVideoDecoder::Initialize(const VideoDecoderConfig& config, void VaapiVideoDecoder::Initialize(const VideoDecoderConfig& config,
InitCB init_cb, InitCB init_cb,
const OutputCB& output_cb) { const OutputCB& output_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
DCHECK(config.IsValidConfig());
decoder_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&VaapiVideoDecoder::InitializeTask, weak_this_, config,
std::move(init_cb), std::move(output_cb)));
}
void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
InitCB init_cb,
OutputCB output_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DCHECK(config.IsValidConfig());
DCHECK(state_ == State::kUninitialized || state_ == State::kWaitingForInput); DCHECK(state_ == State::kUninitialized || state_ == State::kWaitingForInput);
DVLOGF(3); DVLOGF(3);
// Reinitializing the decoder is allowed if there are no pending decodes. // Reinitializing the decoder is allowed if there are no pending decodes.
if (current_decode_task_ || !decode_task_queue_.empty()) { if (current_decode_task_ || !decode_task_queue_.empty()) {
VLOGF(1) << "Don't call Initialize() while there are pending decode tasks"; VLOGF(1) << "Don't call Initialize() while there are pending decode tasks";
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
...@@ -175,8 +143,7 @@ void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -175,8 +143,7 @@ void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
if (!vaapi_wrapper_.get()) { if (!vaapi_wrapper_.get()) {
VLOGF(1) << "Failed initializing VAAPI for profile " VLOGF(1) << "Failed initializing VAAPI for profile "
<< GetProfileName(profile); << GetProfileName(profile);
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
...@@ -194,8 +161,7 @@ void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -194,8 +161,7 @@ void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
config.color_space_info())); config.color_space_info()));
} else { } else {
VLOGF(1) << "Unsupported profile " << GetProfileName(profile); VLOGF(1) << "Unsupported profile " << GetProfileName(profile);
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(false);
base::BindOnce(std::move(init_cb), false));
return; return;
} }
...@@ -209,28 +175,18 @@ void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -209,28 +175,18 @@ void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
SetState(State::kWaitingForInput); SetState(State::kWaitingForInput);
// Notify client initialization was successful. // Notify client initialization was successful.
client_task_runner_->PostTask(FROM_HERE, std::move(init_cb).Run(true);
base::BindOnce(std::move(init_cb), true));
} }
void VaapiVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer, void VaapiVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
DecodeCB decode_cb) { DecodeCB decode_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
decoder_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VaapiVideoDecoder::QueueDecodeTask, weak_this_,
std::move(buffer), std::move(decode_cb)));
}
void VaapiVideoDecoder::QueueDecodeTask(scoped_refptr<DecoderBuffer> buffer,
DecodeCB decode_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DVLOGF(4) << "Queuing input buffer, id: " << next_buffer_id_ << ", size: " DVLOGF(4) << "Queuing input buffer, id: " << next_buffer_id_ << ", size: "
<< (buffer->end_of_stream() ? 0 : buffer->data_size()); << (buffer->end_of_stream() ? 0 : buffer->data_size());
// If we're in the error state, immediately fail the decode task. // If we're in the error state, immediately fail the decode task.
if (state_ == State::kError) { if (state_ == State::kError) {
RunDecodeCB(std::move(decode_cb), DecodeStatus::DECODE_ERROR); std::move(decode_cb).Run(DecodeStatus::DECODE_ERROR);
return; return;
} }
...@@ -291,8 +247,7 @@ void VaapiVideoDecoder::HandleDecodeTask() { ...@@ -291,8 +247,7 @@ void VaapiVideoDecoder::HandleDecodeTask() {
case AcceleratedVideoDecoder::kRanOutOfStreamData: case AcceleratedVideoDecoder::kRanOutOfStreamData:
// Decoding was successful, notify client and try to schedule the next // Decoding was successful, notify client and try to schedule the next
// task. Switch to the idle state if we ran out of buffers to decode. // task. Switch to the idle state if we ran out of buffers to decode.
RunDecodeCB(std::move(current_decode_task_->decode_done_cb_), std::move(current_decode_task_->decode_done_cb_).Run(DecodeStatus::OK);
DecodeStatus::OK);
current_decode_task_ = base::nullopt; current_decode_task_ = base::nullopt;
if (!decode_task_queue_.empty()) { if (!decode_task_queue_.empty()) {
ScheduleNextDecodeTask(); ScheduleNextDecodeTask();
...@@ -330,12 +285,12 @@ void VaapiVideoDecoder::ClearDecodeTaskQueue(DecodeStatus status) { ...@@ -330,12 +285,12 @@ void VaapiVideoDecoder::ClearDecodeTaskQueue(DecodeStatus status) {
DVLOGF(4); DVLOGF(4);
if (current_decode_task_) { if (current_decode_task_) {
RunDecodeCB(std::move(current_decode_task_->decode_done_cb_), status); std::move(current_decode_task_->decode_done_cb_).Run(status);
current_decode_task_ = base::nullopt; current_decode_task_ = base::nullopt;
} }
while (!decode_task_queue_.empty()) { while (!decode_task_queue_.empty()) {
RunDecodeCB(std::move(decode_task_queue_.front().decode_done_cb_), status); std::move(decode_task_queue_.front().decode_done_cb_).Run(status);
decode_task_queue_.pop(); decode_task_queue_.pop();
} }
} }
...@@ -439,8 +394,7 @@ void VaapiVideoDecoder::OutputFrameTask(scoped_refptr<VideoFrame> video_frame, ...@@ -439,8 +394,7 @@ void VaapiVideoDecoder::OutputFrameTask(scoped_refptr<VideoFrame> video_frame,
video_frame = std::move(wrapped_frame); video_frame = std::move(wrapped_frame);
} }
client_task_runner_->PostTask( output_cb_.Run(std::move(video_frame));
FROM_HERE, base::BindOnce(output_cb_, std::move(video_frame)));
} }
void VaapiVideoDecoder::ChangeFrameResolutionTask() { void VaapiVideoDecoder::ChangeFrameResolutionTask() {
...@@ -522,8 +476,7 @@ void VaapiVideoDecoder::FlushTask() { ...@@ -522,8 +476,7 @@ void VaapiVideoDecoder::FlushTask() {
DCHECK(output_frames_.empty()); DCHECK(output_frames_.empty());
// Notify the client flushing is done. // Notify the client flushing is done.
RunDecodeCB(std::move(current_decode_task_->decode_done_cb_), std::move(current_decode_task_->decode_done_cb_).Run(DecodeStatus::OK);
DecodeStatus::OK);
current_decode_task_ = base::nullopt; current_decode_task_ = base::nullopt;
// Wait for new decodes, no decode tasks should be queued while flushing. // Wait for new decodes, no decode tasks should be queued while flushing.
...@@ -531,21 +484,12 @@ void VaapiVideoDecoder::FlushTask() { ...@@ -531,21 +484,12 @@ void VaapiVideoDecoder::FlushTask() {
} }
void VaapiVideoDecoder::Reset(base::OnceClosure reset_cb) { void VaapiVideoDecoder::Reset(base::OnceClosure reset_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
DVLOGF(2);
decoder_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VaapiVideoDecoder::ResetTask, weak_this_,
std::move(reset_cb)));
}
void VaapiVideoDecoder::ResetTask(base::OnceClosure reset_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DVLOGF(2); DVLOGF(2);
// If we encountered an error, skip reset and notify client. // If we encountered an error, skip reset and notify client.
if (state_ == State::kError) { if (state_ == State::kError) {
client_task_runner_->PostTask(FROM_HERE, std::move(reset_cb)); std::move(reset_cb).Run();
return; return;
} }
...@@ -568,17 +512,10 @@ void VaapiVideoDecoder::ResetDoneTask(base::OnceClosure reset_cb) { ...@@ -568,17 +512,10 @@ void VaapiVideoDecoder::ResetDoneTask(base::OnceClosure reset_cb) {
DCHECK(decode_task_queue_.empty()); DCHECK(decode_task_queue_.empty());
DVLOGF(2); DVLOGF(2);
client_task_runner_->PostTask(FROM_HERE, std::move(reset_cb)); std::move(reset_cb).Run();
SetState(State::kWaitingForInput); SetState(State::kWaitingForInput);
} }
void VaapiVideoDecoder::RunDecodeCB(DecodeCB cb, DecodeStatus status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
client_task_runner_->PostTask(FROM_HERE,
base::BindOnce(std::move(cb), status));
}
void VaapiVideoDecoder::SetState(State state) { void VaapiVideoDecoder::SetState(State state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
DVLOGF(4) << static_cast<int>(state) DVLOGF(4) << static_cast<int>(state)
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "media/base/video_codecs.h" #include "media/base/video_codecs.h"
...@@ -45,7 +44,6 @@ class VaapiVideoDecoder : public VideoDecoderPipeline::DecoderInterface, ...@@ -45,7 +44,6 @@ class VaapiVideoDecoder : public VideoDecoderPipeline::DecoderInterface,
using GetFramePoolCB = base::RepeatingCallback<DmabufVideoFramePool*()>; using GetFramePoolCB = base::RepeatingCallback<DmabufVideoFramePool*()>;
static std::unique_ptr<VideoDecoderPipeline::DecoderInterface> Create( static std::unique_ptr<VideoDecoderPipeline::DecoderInterface> Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool); GetFramePoolCB get_pool);
...@@ -90,21 +88,10 @@ class VaapiVideoDecoder : public VideoDecoderPipeline::DecoderInterface, ...@@ -90,21 +88,10 @@ class VaapiVideoDecoder : public VideoDecoderPipeline::DecoderInterface,
}; };
VaapiVideoDecoder( VaapiVideoDecoder(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool); GetFramePoolCB get_pool);
~VaapiVideoDecoder() override; ~VaapiVideoDecoder() override;
// Initialize the VAAPI video decoder on the decoder thread.
void InitializeTask(const VideoDecoderConfig& config,
InitCB init_cb,
OutputCB output_cb);
// Destroy the VAAPI video decoder on the decoder thread.
void DestroyTask(base::WaitableEvent* event);
// Queue a decode task on the decoder thread. If the decoder is currently
// waiting for input buffers decoding will be started.
void QueueDecodeTask(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb);
// Schedule the next decode task in the queue to be executed. // Schedule the next decode task in the queue to be executed.
void ScheduleNextDecodeTask(); void ScheduleNextDecodeTask();
// Try to decode a single input buffer on the decoder thread. // Try to decode a single input buffer on the decoder thread.
...@@ -138,15 +125,9 @@ class VaapiVideoDecoder : public VideoDecoderPipeline::DecoderInterface, ...@@ -138,15 +125,9 @@ class VaapiVideoDecoder : public VideoDecoderPipeline::DecoderInterface,
// tasks have been executed and all frames have been output. // tasks have been executed and all frames have been output.
void FlushTask(); void FlushTask();
// Reset the decoder on the decoder thread. This will abort any pending decode // Called when resetting the decoder is done, executes |reset_cb|.
// task. The |reset_cb| will be passed to ResetDoneTask() and called when
// resetting has completed.
void ResetTask(base::OnceClosure reset_cb);
// Called on the decoder thread once resetting is done. Executes |reset_cb|.
void ResetDoneTask(base::OnceClosure reset_cb); void ResetDoneTask(base::OnceClosure reset_cb);
// Called on decoder thread to schedule |decode_cb| on the client task runner.
void RunDecodeCB(DecodeCB decode_cb, DecodeStatus status);
// Change the current |state_| to the specified |state| on the decoder thread. // Change the current |state_| to the specified |state| on the decoder thread.
void SetState(State state); void SetState(State state);
...@@ -188,10 +169,8 @@ class VaapiVideoDecoder : public VideoDecoderPipeline::DecoderInterface, ...@@ -188,10 +169,8 @@ class VaapiVideoDecoder : public VideoDecoderPipeline::DecoderInterface,
std::unique_ptr<AcceleratedVideoDecoder> decoder_; std::unique_ptr<AcceleratedVideoDecoder> decoder_;
scoped_refptr<VaapiWrapper> vaapi_wrapper_; scoped_refptr<VaapiWrapper> vaapi_wrapper_;
const scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_; const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_;
SEQUENCE_CHECKER(client_sequence_checker_);
SEQUENCE_CHECKER(decoder_sequence_checker_); SEQUENCE_CHECKER(decoder_sequence_checker_);
base::WeakPtr<VaapiVideoDecoder> weak_this_; base::WeakPtr<VaapiVideoDecoder> weak_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