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

Reland "media/gpu: make VideoDecoderPipeline select VD implementation during Initialize()."

This reverts commit a1d47a7f.

Reason for revert: Fix build failure with target_os="chromeos"

Original change's description:
> Revert "media/gpu: make VideoDecoderPipeline select VD implementation during Initialize()."
>
> This reverts commit cae62756.
>
> Reason for revert: Breaks build with target_os="chromeos"
>
> FAILED: libmedia_gpu.so libmedia_gpu.so.TOC
> python "../../build/toolchain/gcc_solink_wrapper.py" --readelf="readelf" --nm="nm" --sofile="./libmedia_gpu.so" --tocfile="./libmedia_gpu.so.TOC" --output="./libmedia_gpu.so" -- ../../third_party/llvm-build/Release+Asserts/bin/clang++ -shared -Wl,-soname="libmedia_gpu.so" -Wl,--fatal-warnings -fPIC -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,defs -Wl,--as-needed -fuse-ld=lld -Wl,--color-diagnostics -m64 -Werror -Wl,--gdb-index -nostdlib++ --sysroot=../../build/linux/debian_sid_amd64-sysroot -L../../build/linux/debian_sid_amd64-sysroot/usr/local/lib/x86_64-linux-gnu -L../../build/linux/debian_sid_amd64-sysroot/lib/x86_64-linux-gnu -L../../build/linux/debian_sid_amd64-sysroot/usr/lib/x86_64-linux-gnu -Wl,-rpath=\$ORIGIN -Wl,-rpath=\$ORIGIN -o "./libmedia_gpu.so" @"./libmedia_gpu.so.rsp"
> ld.lld: error: undefined symbol: media::VideoDecoderPipeline::Create(scoped_refptr<base::SequencedTaskRunner>, std::__Cr::unique_ptr<media::DmabufVideoFramePool, std::__Cr::default_delete<media::DmabufVideoFramePool> >, std::__Cr::unique_ptr<media::VideoFrameConverter, std::__Cr::default_delete<media::VideoFrameConverter> >)
> >>> referenced by chromeos_video_decoder_factory.cc:54 (../../media/gpu/chromeos/chromeos_video_decoder_factory.cc:54)
> >>>               obj/media/gpu/chromeos/chromeos/chromeos_video_decoder_factory.o:(media::ChromeosVideoDecoderFactory::Create(scoped_refptr<base::SequencedTaskRunner>, std::__Cr::unique_ptr<media::DmabufVideoFramePool, std::__Cr::default_delete<media::DmabufVideoFramePool> >, std::__Cr::unique_ptr<media::VideoFrameConverter, std::__Cr::default_delete<media::VideoFrameConverter> >))
> clang: error: linker command failed with exit code 1 (use -v to see invocation)
>
> Original change's description:
> > media/gpu: make VideoDecoderPipeline select VD implementation during Initialize().
> >
> > Some devices select the video decoder implementation by the video
> > configuration (e.g. codec). VideoDecoderPipeline needs to select a
> > proper video decoder in Initialize() when a video configuration is
> > specified.
> >
> > This CL implements the mechanism of selecting VD at Initialize()
> > instead of Create() method.
> >
> > BUG=chromium:952730
> > TEST=Run video_decode_accelerator_tests on Kevin and Eve
> >
> > Change-Id: I76077df0bc1e1eeae730e618a62c6e1049e02500
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1708693
> > Reviewed-by: David Staessens <dstaessens@chromium.org>
> > Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
> > Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
> > Commit-Queue: Chih-Yu Huang <akahuang@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#691946}
>
> TBR=deanliao@chromium.org,akahuang@chromium.org,hiroh@chromium.org,acourbot@chromium.org,dstaessens@chromium.org
>
> Change-Id: I2edea554734a766fce1d61943297547159c8cbeb
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: chromium:952730
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1778048
> Reviewed-by: Elly Fong-Jones <ellyjones@chromium.org>
> Reviewed-by: Vladislav Kuzkokov <vkuzkokov@chromium.org>
> Commit-Queue: Vladislav Kuzkokov <vkuzkokov@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#692035}

TBR=ellyjones@chromium.org,deanliao@chromium.org,vkuzkokov@chromium.org,akahuang@chromium.org,hiroh@chromium.org,acourbot@chromium.org,dstaessens@chromium.org

Bug: chromium:952730
Test: Run `autoninja media/gpu` with gn gargs: target_os="chromeos"
Change-Id: I34405281dbe106e3182456da154e3ceafd19f9b2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1781126Reviewed-by: default avatarChih-Yu Huang <akahuang@chromium.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Commit-Queue: Chih-Yu Huang <akahuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#692405}
parent d8ed38ab
...@@ -22,7 +22,7 @@ source_set("chromeos") { ...@@ -22,7 +22,7 @@ source_set("chromeos") {
] ]
if (use_vaapi || use_v4l2_codec) { if (use_vaapi || use_v4l2_codec) {
deps += [ "//media/gpu/linux:common" ] deps += [ "//media/gpu/linux" ]
} }
if (use_vaapi) { if (use_vaapi) {
......
...@@ -9,8 +9,12 @@ ...@@ -9,8 +9,12 @@
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "media/base/video_decoder.h" #include "media/base/video_decoder.h"
#include "media/gpu/buildflags.h" #include "media/gpu/buildflags.h"
#if BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
#include "media/gpu/linux/mailbox_video_frame_converter.h" #include "media/gpu/linux/mailbox_video_frame_converter.h"
#include "media/gpu/linux/platform_video_frame_pool.h" #include "media/gpu/linux/platform_video_frame_pool.h"
#include "media/gpu/linux/video_decoder_pipeline.h"
#endif // BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
#if BUILDFLAG(USE_VAAPI) #if BUILDFLAG(USE_VAAPI)
#include "media/gpu/vaapi/vaapi_video_decoder.h" #include "media/gpu/vaapi/vaapi_video_decoder.h"
...@@ -20,9 +24,6 @@ ...@@ -20,9 +24,6 @@
#include "media/gpu/v4l2/v4l2_slice_video_decoder.h" #include "media/gpu/v4l2/v4l2_slice_video_decoder.h"
#endif #endif
#if BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
#include "media/gpu/linux/video_decoder_pipeline.h"
#endif
namespace media { namespace media {
...@@ -52,29 +53,14 @@ std::unique_ptr<VideoDecoder> ChromeosVideoDecoderFactory::Create( ...@@ -52,29 +53,14 @@ std::unique_ptr<VideoDecoder> ChromeosVideoDecoderFactory::Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
std::unique_ptr<DmabufVideoFramePool> frame_pool, std::unique_ptr<DmabufVideoFramePool> frame_pool,
std::unique_ptr<VideoFrameConverter> frame_converter) { std::unique_ptr<VideoFrameConverter> frame_converter) {
if (!client_task_runner || !frame_pool || !frame_converter)
return nullptr;
std::unique_ptr<VideoDecoder> decoder;
// TODO(dstaessens@): We first try VAAPI as USE_V4L2_CODEC might also be
// set, even though initialization of V4L2SliceVideoDecoder would fail. We
// need to implement a better way to select the correct decoder.
#if BUILDFLAG(USE_VAAPI)
decoder =
VaapiVideoDecoder::Create(client_task_runner, std::move(frame_pool));
#elif BUILDFLAG(USE_V4L2_CODEC)
decoder =
V4L2SliceVideoDecoder::Create(client_task_runner, std::move(frame_pool));
#endif
#if BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC) #if BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
return std::make_unique<VideoDecoderPipeline>(std::move(client_task_runner), // TODO(akahuang): Remove ChromeosVideoDecoderFactory.
std::move(decoder), return VideoDecoderPipeline::Create(std::move(client_task_runner),
std::move(frame_converter)); std::move(frame_pool),
#else std::move(frame_converter));
#endif // BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
return nullptr; return nullptr;
#endif
} }
} // namespace media } // namespace media
...@@ -7,6 +7,36 @@ import("//media/gpu/args.gni") ...@@ -7,6 +7,36 @@ import("//media/gpu/args.gni")
assert(use_v4l2_codec || use_vaapi) assert(use_v4l2_codec || use_vaapi)
# The source that depends on //media/gpu/{vaapi,v4l2}. It is created to avoid
# circular dependency because //media/gpu/linux:common could be depended by
# //media/gpu/{vaapi,v4l2}.
source_set("linux") {
defines = [ "MEDIA_GPU_IMPLEMENTATION" ]
sources = [
"video_decoder_pipeline.cc",
"video_decoder_pipeline.h",
]
public_deps = [
":common",
]
deps = [
"//base",
"//media",
"//media/gpu:buildflags",
"//media/gpu:common",
]
if (use_vaapi) {
deps += [ "//media/gpu/vaapi" ]
}
if (use_v4l2_codec) {
deps += [ "//media/gpu/v4l2" ]
}
}
source_set("common") { source_set("common") {
defines = [ "MEDIA_GPU_IMPLEMENTATION" ] defines = [ "MEDIA_GPU_IMPLEMENTATION" ]
sources = [ sources = [
...@@ -18,8 +48,6 @@ source_set("common") { ...@@ -18,8 +48,6 @@ source_set("common") {
"platform_video_frame_pool.h", "platform_video_frame_pool.h",
"platform_video_frame_utils.cc", "platform_video_frame_utils.cc",
"platform_video_frame_utils.h", "platform_video_frame_utils.h",
"video_decoder_pipeline.cc",
"video_decoder_pipeline.h",
] ]
deps = [ deps = [
......
This diff is collapsed.
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
#include <memory> #include <memory>
#include "base/containers/queue.h"
#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 "media/base/video_decoder.h" #include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
#include "media/gpu/media_gpu_export.h" #include "media/gpu/media_gpu_export.h"
#include "media/gpu/video_frame_converter.h" #include "media/gpu/video_frame_converter.h"
...@@ -20,12 +22,15 @@ class SequencedTaskRunner; ...@@ -20,12 +22,15 @@ class SequencedTaskRunner;
namespace media { namespace media {
class DmabufVideoFramePool;
class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder {
public: public:
VideoDecoderPipeline( static std::unique_ptr<VideoDecoder> Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
std::unique_ptr<VideoDecoder> decoder, std::unique_ptr<DmabufVideoFramePool> frame_pool,
std::unique_ptr<VideoFrameConverter> frame_converter); std::unique_ptr<VideoFrameConverter> frame_converter);
~VideoDecoderPipeline() override; ~VideoDecoderPipeline() override;
// VideoDecoder implementation // VideoDecoder implementation
...@@ -45,7 +50,35 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { ...@@ -45,7 +50,35 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder {
void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override; void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override;
private: private:
// Function signature for creating VideoDecoder.
using CreateVDFunc = std::unique_ptr<VideoDecoder> (*)(
scoped_refptr<base::SequencedTaskRunner>,
scoped_refptr<base::SequencedTaskRunner>,
base::RepeatingCallback<DmabufVideoFramePool*()>);
// Get a list of the available functions for creating VideoDeocoder.
static base::queue<CreateVDFunc> GetCreateVDFunctions(
CreateVDFunc current_func);
VideoDecoderPipeline(
scoped_refptr<base::SequencedTaskRunner> client_task_runner,
std::unique_ptr<DmabufVideoFramePool> frame_pool,
std::unique_ptr<VideoFrameConverter> frame_converter);
void Destroy() override; void Destroy() override;
void DestroyTask();
void CreateAndInitializeVD(base::queue<CreateVDFunc> create_vd_funcs,
VideoDecoderConfig config,
bool low_delay,
CdmContext* cdm_context,
WaitingCB waiting_cb);
void OnInitializeDone(base::queue<CreateVDFunc> create_vd_funcs,
VideoDecoderConfig config,
bool low_delay,
CdmContext* cdm_context,
WaitingCB waiting_cb,
bool success);
void OnDecodeDone(bool eos_buffer, DecodeCB decode_cb, DecodeStatus status); void OnDecodeDone(bool eos_buffer, DecodeCB decode_cb, DecodeStatus status);
void OnResetDone(); void OnResetDone();
void OnFrameConverted(scoped_refptr<VideoFrame> frame); void OnFrameConverted(scoped_refptr<VideoFrame> frame);
...@@ -60,13 +93,34 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { ...@@ -60,13 +93,34 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder {
// Call |client_flush_cb_| with |status| if we need. // Call |client_flush_cb_| with |status| if we need.
void CallFlushCbIfNeeded(DecodeStatus status); void CallFlushCbIfNeeded(DecodeStatus status);
// Get the video frame pool without passing the ownership.
DmabufVideoFramePool* GetVideoFramePool() const;
// The client task runner and its sequence checker. All public methods should
// run on this task runner.
const scoped_refptr<base::SequencedTaskRunner> client_task_runner_; const scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
SEQUENCE_CHECKER(client_sequence_checker_);
const std::unique_ptr<VideoDecoder> decoder_; // The decoder task runner and its sequence checker. |decoder_| should post
const std::unique_ptr<VideoFrameConverter> frame_converter_; // time-consuming task and call |frame_pool_|'s methods on this task runner.
const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_;
SEQUENCE_CHECKER(decoder_sequence_checker_);
// The frame pool passed from the client. Destroyed on |decoder_task_runner_|.
std::unique_ptr<DmabufVideoFramePool> frame_pool_;
// The frame converter passed from the client. Destroyed on
// |client_task_runner_|.
std::unique_ptr<VideoFrameConverter> frame_converter_;
// The current video decoder implementation. Valid after initialization is
// successfully done.
std::unique_ptr<VideoDecoder> decoder_;
// The create function of |decoder_|. nullptr iff |decoder_| is nullptr.
CreateVDFunc used_create_vd_func_ = nullptr;
// Callback from the client. These callback are called on // Callback from the client. These callback are called on
// |client_task_runner_|. // |client_task_runner_|.
InitCB init_cb_;
OutputCB client_output_cb_; OutputCB client_output_cb_;
DecodeCB client_flush_cb_; DecodeCB client_flush_cb_;
base::OnceClosure client_reset_cb_; base::OnceClosure client_reset_cb_;
...@@ -74,9 +128,9 @@ class MEDIA_GPU_EXPORT VideoDecoderPipeline : public VideoDecoder { ...@@ -74,9 +128,9 @@ 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;
SEQUENCE_CHECKER(sequence_checker_); // The weak pointer of this, bound to |client_task_runner_|.
base::WeakPtr<VideoDecoderPipeline> weak_this_;
base::WeakPtrFactory<VideoDecoderPipeline> weak_this_factory_; base::WeakPtrFactory<VideoDecoderPipeline> weak_this_factory_{this};
}; };
} // namespace media } // namespace media
......
...@@ -71,6 +71,10 @@ source_set("v4l2") { ...@@ -71,6 +71,10 @@ source_set("v4l2") {
configs += [ "//third_party/libyuv:libyuv_config" ] configs += [ "//third_party/libyuv:libyuv_config" ]
public_deps = [
"//ui/gl",
]
deps = [ deps = [
"//base", "//base",
"//gpu/ipc/common", "//gpu/ipc/common",
......
...@@ -128,9 +128,10 @@ struct V4L2SliceVideoDecoder::OutputRequest { ...@@ -128,9 +128,10 @@ struct V4L2SliceVideoDecoder::OutputRequest {
// static // static
std::unique_ptr<VideoDecoder> V4L2SliceVideoDecoder::Create( std::unique_ptr<VideoDecoder> V4L2SliceVideoDecoder::Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
std::unique_ptr<DmabufVideoFramePool> frame_pool) { scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool_cb) {
DCHECK(client_task_runner->RunsTasksInCurrentSequence()); DCHECK(client_task_runner->RunsTasksInCurrentSequence());
DCHECK(frame_pool); DCHECK(get_pool_cb);
scoped_refptr<V4L2Device> device = V4L2Device::Create(); scoped_refptr<V4L2Device> device = V4L2Device::Create();
if (!device) { if (!device) {
...@@ -139,7 +140,8 @@ std::unique_ptr<VideoDecoder> V4L2SliceVideoDecoder::Create( ...@@ -139,7 +140,8 @@ std::unique_ptr<VideoDecoder> V4L2SliceVideoDecoder::Create(
} }
return base::WrapUnique<VideoDecoder>(new V4L2SliceVideoDecoder( return base::WrapUnique<VideoDecoder>(new V4L2SliceVideoDecoder(
std::move(client_task_runner), std::move(device), std::move(frame_pool))); std::move(client_task_runner), std::move(decoder_task_runner),
std::move(device), std::move(get_pool_cb)));
} }
// static // static
...@@ -156,22 +158,19 @@ SupportedVideoDecoderConfigs V4L2SliceVideoDecoder::GetSupportedConfigs() { ...@@ -156,22 +158,19 @@ SupportedVideoDecoderConfigs V4L2SliceVideoDecoder::GetSupportedConfigs() {
V4L2SliceVideoDecoder::V4L2SliceVideoDecoder( V4L2SliceVideoDecoder::V4L2SliceVideoDecoder(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
scoped_refptr<V4L2Device> device, scoped_refptr<V4L2Device> device,
std::unique_ptr<DmabufVideoFramePool> frame_pool) GetFramePoolCB get_pool_cb)
: device_(std::move(device)), : device_(std::move(device)),
frame_pool_(std::move(frame_pool)), get_pool_cb_(std::move(get_pool_cb)),
client_task_runner_(std::move(client_task_runner)), client_task_runner_(std::move(client_task_runner)),
decoder_task_runner_(base::CreateSequencedTaskRunner( decoder_task_runner_(std::move(decoder_task_runner)),
{base::ThreadPool(), base::WithBaseSyncPrimitives(),
base::TaskPriority::USER_VISIBLE})),
device_poll_thread_("V4L2SliceVideoDecoderDevicePollThread"), device_poll_thread_("V4L2SliceVideoDecoderDevicePollThread"),
weak_this_factory_(this) { weak_this_factory_(this) {
DETACH_FROM_SEQUENCE(client_sequence_checker_); DETACH_FROM_SEQUENCE(client_sequence_checker_);
DETACH_FROM_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();
frame_pool_->set_parent_task_runner(decoder_task_runner_);
} }
V4L2SliceVideoDecoder::~V4L2SliceVideoDecoder() { V4L2SliceVideoDecoder::~V4L2SliceVideoDecoder() {
...@@ -245,6 +244,7 @@ void V4L2SliceVideoDecoder::DestroyTask() { ...@@ -245,6 +244,7 @@ void V4L2SliceVideoDecoder::DestroyTask() {
DCHECK(surfaces_at_device_.empty()); DCHECK(surfaces_at_device_.empty());
weak_this_factory_.InvalidateWeakPtrs(); weak_this_factory_.InvalidateWeakPtrs();
delete this; delete this;
VLOGF(2) << "Destroyed"; VLOGF(2) << "Destroyed";
} }
...@@ -318,6 +318,9 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -318,6 +318,9 @@ void V4L2SliceVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
SetState(State::kUninitialized); SetState(State::kUninitialized);
} }
// Setup frame pool.
frame_pool_ = get_pool_cb_.Run();
// Open V4L2 device. // Open V4L2 device.
VideoCodecProfile profile = config.profile(); VideoCodecProfile profile = config.profile();
uint32_t input_format_fourcc = uint32_t input_format_fourcc =
......
...@@ -38,12 +38,15 @@ class V4L2DecodeSurface; ...@@ -38,12 +38,15 @@ class V4L2DecodeSurface;
class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder : public VideoDecoder, class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder : public VideoDecoder,
public V4L2DecodeSurfaceHandler { public V4L2DecodeSurfaceHandler {
public: public:
using GetFramePoolCB = base::RepeatingCallback<DmabufVideoFramePool*()>;
// Create V4L2SliceVideoDecoder instance. The success of the creation doesn't // Create V4L2SliceVideoDecoder instance. The success of the creation doesn't
// 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<VideoDecoder> Create( static std::unique_ptr<VideoDecoder> Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
std::unique_ptr<DmabufVideoFramePool> frame_pool); scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool_cb);
static SupportedVideoDecoderConfigs GetSupportedConfigs(); static SupportedVideoDecoderConfigs GetSupportedConfigs();
...@@ -80,8 +83,9 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder : public VideoDecoder, ...@@ -80,8 +83,9 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder : public VideoDecoder,
V4L2SliceVideoDecoder( V4L2SliceVideoDecoder(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
scoped_refptr<V4L2Device> device, scoped_refptr<V4L2Device> device,
std::unique_ptr<DmabufVideoFramePool> frame_pool); GetFramePoolCB get_pool_cb);
~V4L2SliceVideoDecoder() override; ~V4L2SliceVideoDecoder() override;
void Destroy() override; void Destroy() override;
...@@ -218,7 +222,8 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder : public VideoDecoder, ...@@ -218,7 +222,8 @@ class MEDIA_GPU_EXPORT V4L2SliceVideoDecoder : public VideoDecoder,
// V4L2 device in use. // V4L2 device in use.
scoped_refptr<V4L2Device> device_; scoped_refptr<V4L2Device> device_;
// VideoFrame manager used to allocate and recycle video frame. // VideoFrame manager used to allocate and recycle video frame.
std::unique_ptr<DmabufVideoFramePool> frame_pool_; GetFramePoolCB get_pool_cb_;
DmabufVideoFramePool* frame_pool_ = nullptr;
// Video decoder used to parse stream headers by software. // Video decoder used to parse stream headers by software.
std::unique_ptr<AcceleratedVideoDecoder> avd_; std::unique_ptr<AcceleratedVideoDecoder> avd_;
......
...@@ -68,9 +68,11 @@ VaapiVideoDecoder::DecodeTask::DecodeTask(DecodeTask&&) = default; ...@@ -68,9 +68,11 @@ VaapiVideoDecoder::DecodeTask::DecodeTask(DecodeTask&&) = default;
// static // static
std::unique_ptr<VideoDecoder> VaapiVideoDecoder::Create( std::unique_ptr<VideoDecoder> VaapiVideoDecoder::Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
std::unique_ptr<DmabufVideoFramePool> frame_pool) { scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool_cb) {
return base::WrapUnique<VideoDecoder>(new VaapiVideoDecoder( return base::WrapUnique<VideoDecoder>(new VaapiVideoDecoder(
std::move(client_task_runner), std::move(frame_pool))); std::move(client_task_runner), std::move(decoder_task_runner),
std::move(get_pool_cb)));
} }
// static // static
...@@ -81,10 +83,11 @@ SupportedVideoDecoderConfigs VaapiVideoDecoder::GetSupportedConfigs() { ...@@ -81,10 +83,11 @@ SupportedVideoDecoderConfigs VaapiVideoDecoder::GetSupportedConfigs() {
VaapiVideoDecoder::VaapiVideoDecoder( VaapiVideoDecoder::VaapiVideoDecoder(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
std::unique_ptr<DmabufVideoFramePool> frame_pool) scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
: frame_pool_(std::move(frame_pool)), GetFramePoolCB get_pool_cb)
: get_pool_cb_(std::move(get_pool_cb)),
client_task_runner_(std::move(client_task_runner)), client_task_runner_(std::move(client_task_runner)),
decoder_thread_("VaapiDecoderThread"), decoder_task_runner_(std::move(decoder_task_runner)),
weak_this_factory_(this) { weak_this_factory_(this) {
DETACH_FROM_SEQUENCE(decoder_sequence_checker_); DETACH_FROM_SEQUENCE(decoder_sequence_checker_);
VLOGF(2); VLOGF(2);
...@@ -149,17 +152,7 @@ void VaapiVideoDecoder::Initialize(const VideoDecoderConfig& config, ...@@ -149,17 +152,7 @@ void VaapiVideoDecoder::Initialize(const VideoDecoderConfig& config,
return; return;
} }
if (!decoder_thread_.IsRunning() && !decoder_thread_.Start()) { decoder_task_runner_->PostTask(
std::move(init_cb).Run(false);
return;
}
if (!decoder_thread_task_runner_) {
decoder_thread_task_runner_ = decoder_thread_.task_runner();
frame_pool_->set_parent_task_runner(decoder_thread_task_runner_);
}
decoder_thread_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&VaapiVideoDecoder::InitializeTask, weak_this_, config, base::BindOnce(&VaapiVideoDecoder::InitializeTask, weak_this_, config,
std::move(init_cb), std::move(output_cb))); std::move(init_cb), std::move(output_cb)));
...@@ -227,6 +220,9 @@ void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config, ...@@ -227,6 +220,9 @@ void VaapiVideoDecoder::InitializeTask(const VideoDecoderConfig& config,
} }
needs_bitstream_conversion_ = (config.codec() == kCodecH264); needs_bitstream_conversion_ = (config.codec() == kCodecH264);
// Get and initialize the frame pool.
frame_pool_ = get_pool_cb_.Run();
visible_rect_ = config.visible_rect(); visible_rect_ = config.visible_rect();
pixel_aspect_ratio_ = config.GetPixelAspectRatio(); pixel_aspect_ratio_ = config.GetPixelAspectRatio();
profile_ = profile; profile_ = profile;
...@@ -243,14 +239,8 @@ void VaapiVideoDecoder::Destroy() { ...@@ -243,14 +239,8 @@ void VaapiVideoDecoder::Destroy() {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
VLOGF(2); VLOGF(2);
if (decoder_thread_task_runner_) { decoder_task_runner_->PostTask(
decoder_thread_task_runner_->PostTask( FROM_HERE, base::BindOnce(&VaapiVideoDecoder::DestroyTask, weak_this_));
FROM_HERE, base::BindOnce(&VaapiVideoDecoder::DestroyTask, weak_this_));
decoder_thread_.Stop();
}
delete this;
VLOGF(2) << "Destroying VAAPI VD done";
} }
void VaapiVideoDecoder::DestroyTask() { void VaapiVideoDecoder::DestroyTask() {
...@@ -265,18 +255,17 @@ void VaapiVideoDecoder::DestroyTask() { ...@@ -265,18 +255,17 @@ void VaapiVideoDecoder::DestroyTask() {
decoder_ = nullptr; decoder_ = nullptr;
} }
// Drop all video frame references. This will cause the frames to be
// destroyed once the decoder's client is done using them.
frame_pool_ = nullptr;
weak_this_factory_.InvalidateWeakPtrs(); weak_this_factory_.InvalidateWeakPtrs();
delete this;
VLOGF(2) << "Destroying VAAPI VD done";
} }
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_); DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
decoder_thread_task_runner_->PostTask( decoder_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VaapiVideoDecoder::QueueDecodeTask, weak_this_, FROM_HERE, base::BindOnce(&VaapiVideoDecoder::QueueDecodeTask, weak_this_,
std::move(buffer), std::move(decode_cb))); std::move(buffer), std::move(decode_cb)));
} }
...@@ -324,7 +313,7 @@ void VaapiVideoDecoder::ScheduleNextDecodeTask() { ...@@ -324,7 +313,7 @@ void VaapiVideoDecoder::ScheduleNextDecodeTask() {
*current_decode_task_->buffer_); *current_decode_task_->buffer_);
} }
decoder_thread_task_runner_->PostTask( decoder_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_)); base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_));
} }
...@@ -541,7 +530,7 @@ void VaapiVideoDecoder::ChangeFrameResolutionTask() { ...@@ -541,7 +530,7 @@ void VaapiVideoDecoder::ChangeFrameResolutionTask() {
vaapi_wrapper_->CreateContext(pic_size); vaapi_wrapper_->CreateContext(pic_size);
// Retry the current decode task. // Retry the current decode task.
decoder_thread_task_runner_->PostTask( decoder_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_)); base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_));
} }
...@@ -570,7 +559,7 @@ void VaapiVideoDecoder::NotifyFrameAvailableTask() { ...@@ -570,7 +559,7 @@ void VaapiVideoDecoder::NotifyFrameAvailableTask() {
if (state_ == State::kWaitingForOutput) { if (state_ == State::kWaitingForOutput) {
DCHECK(current_decode_task_); DCHECK(current_decode_task_);
SetState(State::kDecoding); SetState(State::kDecoding);
decoder_thread_task_runner_->PostTask( decoder_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_)); base::BindOnce(&VaapiVideoDecoder::HandleDecodeTask, weak_this_));
} }
...@@ -610,7 +599,7 @@ void VaapiVideoDecoder::Reset(base::OnceClosure reset_cb) { ...@@ -610,7 +599,7 @@ void VaapiVideoDecoder::Reset(base::OnceClosure reset_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(client_sequence_checker_);
DVLOGF(2); DVLOGF(2);
decoder_thread_task_runner_->PostTask( decoder_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VaapiVideoDecoder::ResetTask, weak_this_, FROM_HERE, base::BindOnce(&VaapiVideoDecoder::ResetTask, weak_this_,
std::move(reset_cb))); std::move(reset_cb)));
} }
...@@ -632,7 +621,7 @@ void VaapiVideoDecoder::ResetTask(base::OnceClosure reset_cb) { ...@@ -632,7 +621,7 @@ void VaapiVideoDecoder::ResetTask(base::OnceClosure reset_cb) {
SetState(State::kResetting); SetState(State::kResetting);
// Wait until any pending decode task has been aborted. // Wait until any pending decode task has been aborted.
decoder_thread_task_runner_->PostTask( decoder_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VaapiVideoDecoder::ResetDoneTask, weak_this_, FROM_HERE, base::BindOnce(&VaapiVideoDecoder::ResetDoneTask, weak_this_,
std::move(reset_cb))); std::move(reset_cb)));
} }
......
...@@ -39,9 +39,12 @@ class VASurface; ...@@ -39,9 +39,12 @@ class VASurface;
class VaapiVideoDecoder : public media::VideoDecoder, class VaapiVideoDecoder : public media::VideoDecoder,
public DecodeSurfaceHandler<VASurface> { public DecodeSurfaceHandler<VASurface> {
public: public:
using GetFramePoolCB = base::RepeatingCallback<DmabufVideoFramePool*()>;
static std::unique_ptr<VideoDecoder> Create( static std::unique_ptr<VideoDecoder> Create(
scoped_refptr<base::SequencedTaskRunner> client_task_runner, scoped_refptr<base::SequencedTaskRunner> client_task_runner,
std::unique_ptr<DmabufVideoFramePool> frame_pool); scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool);
static SupportedVideoDecoderConfigs GetSupportedConfigs(); static SupportedVideoDecoderConfigs GetSupportedConfigs();
...@@ -91,8 +94,10 @@ class VaapiVideoDecoder : public media::VideoDecoder, ...@@ -91,8 +94,10 @@ class VaapiVideoDecoder : public media::VideoDecoder,
kError, // decoder encountered an error. kError, // decoder encountered an error.
}; };
VaapiVideoDecoder(scoped_refptr<base::SequencedTaskRunner> client_task_runner, VaapiVideoDecoder(
std::unique_ptr<DmabufVideoFramePool> frame_pool); scoped_refptr<base::SequencedTaskRunner> client_task_runner,
scoped_refptr<base::SequencedTaskRunner> decoder_task_runner,
GetFramePoolCB get_pool);
~VaapiVideoDecoder() override; ~VaapiVideoDecoder() override;
// Destroy the VAAPIVideoDecoder, aborts pending decode requests and blocks // Destroy the VAAPIVideoDecoder, aborts pending decode requests and blocks
...@@ -171,7 +176,8 @@ class VaapiVideoDecoder : public media::VideoDecoder, ...@@ -171,7 +176,8 @@ class VaapiVideoDecoder : public media::VideoDecoder,
double pixel_aspect_ratio_ = 0.0; double pixel_aspect_ratio_ = 0.0;
// Video frame pool used to allocate and recycle video frames. // Video frame pool used to allocate and recycle video frames.
std::unique_ptr<DmabufVideoFramePool> frame_pool_; GetFramePoolCB get_pool_cb_;
DmabufVideoFramePool* frame_pool_ = nullptr;
// The mapping between buffer id and the timestamp. // The mapping between buffer id and the timestamp.
std::map<int32_t, base::TimeDelta> buffer_id_to_timestamp_; std::map<int32_t, base::TimeDelta> buffer_id_to_timestamp_;
...@@ -191,8 +197,7 @@ class VaapiVideoDecoder : public media::VideoDecoder, ...@@ -191,8 +197,7 @@ class VaapiVideoDecoder : public media::VideoDecoder,
scoped_refptr<VaapiWrapper> vaapi_wrapper_; scoped_refptr<VaapiWrapper> vaapi_wrapper_;
const scoped_refptr<base::SequencedTaskRunner> client_task_runner_; const scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
base::Thread decoder_thread_; const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> decoder_thread_task_runner_;
SEQUENCE_CHECKER(client_sequence_checker_); SEQUENCE_CHECKER(client_sequence_checker_);
SEQUENCE_CHECKER(decoder_sequence_checker_); SEQUENCE_CHECKER(decoder_sequence_checker_);
......
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