blob: 9dc4d70de6e5fd71bc86c143a9375bd820d4078e [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/gpu/ipc/service/media_gpu_channel.h"
#include <memory>
#include <utility>
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "gpu/ipc/service/command_buffer_stub.h"
#include "gpu/ipc/service/gpu_channel.h"
#include "ipc/ipc_mojo_bootstrap.h"
#include "media/gpu/ipc/service/gpu_video_decode_accelerator.h"
#include "media/mojo/mojom/gpu_accelerated_video_decoder.mojom.h"
namespace media {
namespace {
class DecoderProviderImpl : public mojom::GpuAcceleratedVideoDecoderProvider,
public gpu::CommandBufferStub::DestructionObserver {
public:
DecoderProviderImpl(gpu::CommandBufferStub* stub,
const AndroidOverlayMojoFactoryCB& overlay_factory_cb)
: stub_(stub), overlay_factory_cb_(overlay_factory_cb) {
stub_->AddDestructionObserver(this);
}
DecoderProviderImpl(const DecoderProviderImpl&) = delete;
DecoderProviderImpl& operator=(const DecoderProviderImpl&) = delete;
~DecoderProviderImpl() override {
if (stub_) {
stub_->RemoveDestructionObserver(this);
}
}
// mojom::GpuAcceleratedVideoDecoderProvider:
void CreateAcceleratedVideoDecoder(
const VideoDecodeAccelerator::Config& config,
mojo::PendingAssociatedReceiver<mojom::GpuAcceleratedVideoDecoder>
receiver,
mojo::PendingAssociatedRemote<mojom::GpuAcceleratedVideoDecoderClient>
client,
CreateAcceleratedVideoDecoderCallback callback) override {
TRACE_EVENT0("gpu", "DecoderProviderImpl::CreateAcceleratedVideoDecoder");
#if BUILDFLAG(IS_ANDROID)
NOTIMPLEMENTED()
<< "The legacy VideoDecodeAccelerator API is not supported on Android";
std::move(callback).Run(false);
return;
#else
// Only allow stubs that have a ContextGroup, that is, the GLES2 ones. Later
// code assumes the ContextGroup is valid.
if (!stub_ || !stub_->decoder_context()->GetContextGroup()) {
std::move(callback).Run(false);
return;
}
// Note that `decoder` is a self-deleting object.
GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator(
stub_, stub_->channel()->io_task_runner(), overlay_factory_cb_);
std::move(callback).Run(
decoder->Initialize(config, std::move(receiver), std::move(client)));
#endif
}
private:
// gpu::CommandBufferStub::DestructionObserver:
void OnWillDestroyStub(bool have_context) override { stub_ = nullptr; }
raw_ptr<gpu::CommandBufferStub> stub_;
const AndroidOverlayMojoFactoryCB overlay_factory_cb_;
};
} // namespace
MediaGpuChannel::MediaGpuChannel(
gpu::GpuChannel* channel,
const AndroidOverlayMojoFactoryCB& overlay_factory_cb)
: channel_(channel), overlay_factory_cb_(overlay_factory_cb) {
channel_->set_command_buffer_media_binder(
base::BindRepeating(&MediaGpuChannel::BindCommandBufferMediaReceiver,
base::Unretained(this)));
}
MediaGpuChannel::~MediaGpuChannel() = default;
void MediaGpuChannel::BindCommandBufferMediaReceiver(
gpu::CommandBufferStub* stub,
mojo::GenericPendingAssociatedReceiver receiver) {
if (auto r = receiver.As<mojom::GpuAcceleratedVideoDecoderProvider>()) {
IPC::ScopedAllowOffSequenceChannelAssociatedBindings allow_binding;
accelerated_video_decoder_providers_.Add(
std::make_unique<DecoderProviderImpl>(stub, overlay_factory_cb_),
std::move(r), stub->task_runner());
}
}
} // namespace media