Commit 50dfde31 authored by sandersd's avatar sandersd Committed by Commit bot

Add MediaGpuChannelManager::LookupChannel().

This adds a path for VDAv2 clients to look up a command buffer identified by |command_buffer_id|.

Also in this CL is a method to look up the route ID from the accelerated GPU factories so that it's easy to pass the |command_buffer_id|.

BUG=522298
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel

Review-Url: https://codereview.chromium.org/2526953003
Cr-Commit-Position: refs/heads/master@{#443097}
parent ff1a6112
...@@ -127,6 +127,13 @@ base::UnguessableToken RendererGpuVideoAcceleratorFactories::GetChannelToken() { ...@@ -127,6 +127,13 @@ base::UnguessableToken RendererGpuVideoAcceleratorFactories::GetChannelToken() {
return channel_token_; return channel_token_;
} }
int32_t RendererGpuVideoAcceleratorFactories::GetCommandBufferRouteId() {
DCHECK(task_runner_->BelongsToCurrentThread());
if (CheckContextLost())
return 0;
return context_provider_->GetCommandBufferProxy()->route_id();
}
std::unique_ptr<media::VideoDecodeAccelerator> std::unique_ptr<media::VideoDecodeAccelerator>
RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator() { RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator() {
DCHECK(video_accelerator_enabled_); DCHECK(video_accelerator_enabled_);
......
...@@ -59,6 +59,7 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories ...@@ -59,6 +59,7 @@ class CONTENT_EXPORT RendererGpuVideoAcceleratorFactories
// media::GpuVideoAcceleratorFactories implementation. // media::GpuVideoAcceleratorFactories implementation.
bool IsGpuVideoAcceleratorEnabled() override; bool IsGpuVideoAcceleratorEnabled() override;
base::UnguessableToken GetChannelToken() override; base::UnguessableToken GetChannelToken() override;
int32_t GetCommandBufferRouteId() override;
std::unique_ptr<media::VideoDecodeAccelerator> CreateVideoDecodeAccelerator() std::unique_ptr<media::VideoDecodeAccelerator> CreateVideoDecodeAccelerator()
override; override;
std::unique_ptr<media::VideoEncodeAccelerator> CreateVideoEncodeAccelerator() std::unique_ptr<media::VideoEncodeAccelerator> CreateVideoEncodeAccelerator()
......
...@@ -89,9 +89,10 @@ class MediaGpuChannelFilter : public IPC::MessageFilter { ...@@ -89,9 +89,10 @@ class MediaGpuChannelFilter : public IPC::MessageFilter {
base::UnguessableToken channel_token_; base::UnguessableToken channel_token_;
}; };
MediaGpuChannel::MediaGpuChannel(gpu::GpuChannel* channel) : channel_(channel) { MediaGpuChannel::MediaGpuChannel(gpu::GpuChannel* channel,
channel_->AddFilter( const base::UnguessableToken& channel_token)
new MediaGpuChannelFilter(base::UnguessableToken::Create())); : channel_(channel) {
channel_->AddFilter(new MediaGpuChannelFilter(channel_token));
} }
MediaGpuChannel::~MediaGpuChannel() {} MediaGpuChannel::~MediaGpuChannel() {}
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include "base/unguessable_token.h"
#include "ipc/ipc_listener.h" #include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h" #include "ipc/ipc_sender.h"
#include "media/gpu/ipc/service/gpu_jpeg_decode_accelerator.h" #include "media/gpu/ipc/service/gpu_jpeg_decode_accelerator.h"
...@@ -26,7 +27,8 @@ class MediaGpuChannelDispatchHelper; ...@@ -26,7 +27,8 @@ class MediaGpuChannelDispatchHelper;
class MediaGpuChannel : public IPC::Listener, public IPC::Sender { class MediaGpuChannel : public IPC::Listener, public IPC::Sender {
public: public:
explicit MediaGpuChannel(gpu::GpuChannel* channel); MediaGpuChannel(gpu::GpuChannel* channel,
const base::UnguessableToken& channel_token);
~MediaGpuChannel() override; ~MediaGpuChannel() override;
// IPC::Sender implementation: // IPC::Sender implementation:
...@@ -49,6 +51,7 @@ class MediaGpuChannel : public IPC::Listener, public IPC::Sender { ...@@ -49,6 +51,7 @@ class MediaGpuChannel : public IPC::Listener, public IPC::Sender {
IPC::Message* reply_message); IPC::Message* reply_message);
gpu::GpuChannel* const channel_; gpu::GpuChannel* const channel_;
base::UnguessableToken channel_token_;
std::unique_ptr<GpuJpegDecodeAccelerator> jpeg_decoder_; std::unique_ptr<GpuJpegDecodeAccelerator> jpeg_decoder_;
DISALLOW_COPY_AND_ASSIGN(MediaGpuChannel); DISALLOW_COPY_AND_ASSIGN(MediaGpuChannel);
}; };
......
...@@ -26,18 +26,36 @@ MediaGpuChannelManager::~MediaGpuChannelManager() {} ...@@ -26,18 +26,36 @@ MediaGpuChannelManager::~MediaGpuChannelManager() {}
void MediaGpuChannelManager::AddChannel(int32_t client_id) { void MediaGpuChannelManager::AddChannel(int32_t client_id) {
gpu::GpuChannel* gpu_channel = channel_manager_->LookupChannel(client_id); gpu::GpuChannel* gpu_channel = channel_manager_->LookupChannel(client_id);
DCHECK(gpu_channel); DCHECK(gpu_channel);
base::UnguessableToken channel_token = base::UnguessableToken::Create();
std::unique_ptr<MediaGpuChannel> media_gpu_channel( std::unique_ptr<MediaGpuChannel> media_gpu_channel(
new MediaGpuChannel(gpu_channel)); new MediaGpuChannel(gpu_channel, channel_token));
gpu_channel->SetUnhandledMessageListener(media_gpu_channel.get()); gpu_channel->SetUnhandledMessageListener(media_gpu_channel.get());
media_gpu_channels_[client_id] = std::move(media_gpu_channel); media_gpu_channels_[client_id] = std::move(media_gpu_channel);
channel_to_token_[client_id] = channel_token;
token_to_channel_[channel_token] = client_id;
} }
void MediaGpuChannelManager::RemoveChannel(int32_t client_id) { void MediaGpuChannelManager::RemoveChannel(int32_t client_id) {
media_gpu_channels_.erase(client_id); media_gpu_channels_.erase(client_id);
const auto it = channel_to_token_.find(client_id);
if (it != channel_to_token_.end()) {
token_to_channel_.erase(it->second);
channel_to_token_.erase(it);
}
} }
void MediaGpuChannelManager::DestroyAllChannels() { void MediaGpuChannelManager::DestroyAllChannels() {
media_gpu_channels_.clear(); media_gpu_channels_.clear();
token_to_channel_.clear();
channel_to_token_.clear();
}
gpu::GpuChannel* MediaGpuChannelManager::LookupChannel(
const base::UnguessableToken& channel_token) {
const auto it = token_to_channel_.find(channel_token);
if (it == token_to_channel_.end())
return nullptr;
return channel_manager_->LookupChannel(it->second);
} }
} // namespace media } // namespace media
...@@ -12,11 +12,13 @@ ...@@ -12,11 +12,13 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/unguessable_token.h"
#include "ipc/ipc_listener.h" #include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h" #include "ipc/ipc_sender.h"
#include "media/video/video_decode_accelerator.h" #include "media/video/video_decode_accelerator.h"
namespace gpu { namespace gpu {
class GpuChannel;
class GpuChannelManager; class GpuChannelManager;
} }
...@@ -34,10 +36,15 @@ class MediaGpuChannelManager ...@@ -34,10 +36,15 @@ class MediaGpuChannelManager
void RemoveChannel(int32_t client_id); void RemoveChannel(int32_t client_id);
void DestroyAllChannels(); void DestroyAllChannels();
// TODO(sandersd): Should we expose the MediaGpuChannel instead?
gpu::GpuChannel* LookupChannel(const base::UnguessableToken& channel_token);
private: private:
gpu::GpuChannelManager* const channel_manager_; gpu::GpuChannelManager* const channel_manager_;
std::unordered_map<int32_t, std::unique_ptr<MediaGpuChannel>> std::unordered_map<int32_t, std::unique_ptr<MediaGpuChannel>>
media_gpu_channels_; media_gpu_channels_;
std::map<base::UnguessableToken, int32_t> token_to_channel_;
std::map<int32_t, base::UnguessableToken> channel_to_token_;
DISALLOW_COPY_AND_ASSIGN(MediaGpuChannelManager); DISALLOW_COPY_AND_ASSIGN(MediaGpuChannelManager);
}; };
......
...@@ -10,11 +10,14 @@ ...@@ -10,11 +10,14 @@
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/unguessable_token.h"
#include "media/base/decoder_buffer.h" #include "media/base/decoder_buffer.h"
#include "media/base/demuxer_stream.h" #include "media/base/demuxer_stream.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/mojo/common/media_type_converters.h" #include "media/mojo/common/media_type_converters.h"
#include "media/mojo/common/mojo_decoder_buffer_converter.h" #include "media/mojo/common/mojo_decoder_buffer_converter.h"
#include "media/mojo/interfaces/media_types.mojom.h"
#include "media/renderers/gpu_video_accelerator_factories.h"
namespace media { namespace media {
...@@ -23,10 +26,9 @@ MojoVideoDecoder::MojoVideoDecoder( ...@@ -23,10 +26,9 @@ MojoVideoDecoder::MojoVideoDecoder(
GpuVideoAcceleratorFactories* gpu_factories, GpuVideoAcceleratorFactories* gpu_factories,
mojom::VideoDecoderPtr remote_decoder) mojom::VideoDecoderPtr remote_decoder)
: task_runner_(task_runner), : task_runner_(task_runner),
gpu_factories_(gpu_factories),
remote_decoder_info_(remote_decoder.PassInterface()), remote_decoder_info_(remote_decoder.PassInterface()),
gpu_factories_(gpu_factories),
client_binding_(this) { client_binding_(this) {
(void)gpu_factories_;
DVLOG(1) << __func__; DVLOG(1) << __func__;
} }
...@@ -180,8 +182,19 @@ void MojoVideoDecoder::BindRemoteDecoder() { ...@@ -180,8 +182,19 @@ void MojoVideoDecoder::BindRemoteDecoder() {
mojo_decoder_buffer_writer_ = MojoDecoderBufferWriter::Create( mojo_decoder_buffer_writer_ = MojoDecoderBufferWriter::Create(
DemuxerStream::VIDEO, &remote_consumer_handle); DemuxerStream::VIDEO, &remote_consumer_handle);
media::mojom::CommandBufferIdPtr command_buffer_id;
if (gpu_factories_) {
base::UnguessableToken channel_token = gpu_factories_->GetChannelToken();
if (channel_token) {
command_buffer_id = media::mojom::CommandBufferId::New();
command_buffer_id->channel_token = std::move(channel_token);
command_buffer_id->route_id = gpu_factories_->GetCommandBufferRouteId();
}
}
remote_decoder_->Construct(std::move(client_ptr_info), remote_decoder_->Construct(std::move(client_ptr_info),
std::move(remote_consumer_handle)); std::move(remote_consumer_handle),
std::move(command_buffer_id));
} }
void MojoVideoDecoder::Stop() { void MojoVideoDecoder::Stop() {
......
...@@ -61,13 +61,15 @@ class MojoVideoDecoder final : public VideoDecoder, ...@@ -61,13 +61,15 @@ class MojoVideoDecoder final : public VideoDecoder,
// Cleans up callbacks and blocks future calls. // Cleans up callbacks and blocks future calls.
void Stop(); void Stop();
// Task runner that the decoder runs on (media thread).
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
GpuVideoAcceleratorFactories* gpu_factories_;
// Used to pass the remote decoder from the constructor (on the main thread) // Used to pass the remote decoder from the constructor (on the main thread)
// to Initialize() (on the media thread). // to Initialize() (on the media thread).
mojom::VideoDecoderPtrInfo remote_decoder_info_; mojom::VideoDecoderPtrInfo remote_decoder_info_;
GpuVideoAcceleratorFactories* gpu_factories_ = nullptr;
InitCB init_cb_; InitCB init_cb_;
OutputCB output_cb_; OutputCB output_cb_;
uint64_t decode_counter_ = 0; uint64_t decode_counter_ = 0;
......
...@@ -5,17 +5,30 @@ ...@@ -5,17 +5,30 @@
module media.mojom; module media.mojom;
import "media/mojo/interfaces/media_types.mojom"; import "media/mojo/interfaces/media_types.mojom";
import "mojo/common/unguessable_token.mojom";
// Identifies a GpuCommandBufferStub. MediaGpuChannelManager is responsible
// for minting |channel_token| objects.
struct CommandBufferId {
mojo.common.mojom.UnguessableToken channel_token;
int32 route_id;
};
interface VideoDecoder { interface VideoDecoder {
// Initialize the decoder. This must be called before any other method. // Initialize the decoder. This must be called before any other method.
// //
// |command_buffer_id|, when present, identifies a GpuCommandBufferStub that
// the decoder can use for GL operations. Implementations that require GL will
// fail Initialize() if |command_buffer_id| is not provided.
//
// |decoder_buffer_pipe| will be used to transfer encoded data for each // |decoder_buffer_pipe| will be used to transfer encoded data for each
// DecoderBuffer. // DecoderBuffer.
// //
// TODO(sandersd): Rename to Initialize() if/when // TODO(sandersd): Rename to Initialize() if/when
// media::VideoDecoder::Initialize() is renamed to Configure(). // media::VideoDecoder::Initialize() is renamed to Configure().
Construct(associated VideoDecoderClient client, Construct(associated VideoDecoderClient client,
handle<data_pipe_consumer> decoder_buffer_pipe); handle<data_pipe_consumer> decoder_buffer_pipe,
CommandBufferId? command_buffer_id);
// Configure (or reconfigure) the decoder. This must be called before decoding // Configure (or reconfigure) the decoder. This must be called before decoding
// any frames, and must not be called while there are pending Initialize(), // any frames, and must not be called while there are pending Initialize(),
......
...@@ -51,7 +51,8 @@ std::unique_ptr<AudioDecoder> GpuMojoMediaClient::CreateAudioDecoder( ...@@ -51,7 +51,8 @@ std::unique_ptr<AudioDecoder> GpuMojoMediaClient::CreateAudioDecoder(
} }
std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder( std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) { scoped_refptr<base::SingleThreadTaskRunner> task_runner,
mojom::CommandBufferIdPtr command_buffer_id) {
static_cast<void>(media_gpu_channel_manager_); static_cast<void>(media_gpu_channel_manager_);
// TODO(sandersd): Factory for VideoDecoders. // TODO(sandersd): Factory for VideoDecoders.
......
...@@ -30,7 +30,8 @@ class GpuMojoMediaClient : public MojoMediaClient { ...@@ -30,7 +30,8 @@ class GpuMojoMediaClient : public MojoMediaClient {
std::unique_ptr<AudioDecoder> CreateAudioDecoder( std::unique_ptr<AudioDecoder> CreateAudioDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) final; scoped_refptr<base::SingleThreadTaskRunner> task_runner) final;
std::unique_ptr<VideoDecoder> CreateVideoDecoder( std::unique_ptr<VideoDecoder> CreateVideoDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) final; scoped_refptr<base::SingleThreadTaskRunner> task_runner,
mojom::CommandBufferIdPtr command_buffer_id) final;
std::unique_ptr<CdmFactory> CreateCdmFactory( std::unique_ptr<CdmFactory> CreateCdmFactory(
service_manager::mojom::InterfaceProvider* interface_provider) final; service_manager::mojom::InterfaceProvider* interface_provider) final;
......
...@@ -27,7 +27,8 @@ std::unique_ptr<AudioDecoder> MojoMediaClient::CreateAudioDecoder( ...@@ -27,7 +27,8 @@ std::unique_ptr<AudioDecoder> MojoMediaClient::CreateAudioDecoder(
} }
std::unique_ptr<VideoDecoder> MojoMediaClient::CreateVideoDecoder( std::unique_ptr<VideoDecoder> MojoMediaClient::CreateVideoDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) { scoped_refptr<base::SingleThreadTaskRunner> task_runner,
mojom::CommandBufferIdPtr command_buffer_id) {
return nullptr; return nullptr;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "media/mojo/interfaces/video_decoder.mojom.h"
#include "media/mojo/services/media_mojo_export.h" #include "media/mojo/services/media_mojo_export.h"
namespace base { namespace base {
...@@ -47,7 +48,8 @@ class MEDIA_MOJO_EXPORT MojoMediaClient { ...@@ -47,7 +48,8 @@ class MEDIA_MOJO_EXPORT MojoMediaClient {
scoped_refptr<base::SingleThreadTaskRunner> task_runner); scoped_refptr<base::SingleThreadTaskRunner> task_runner);
virtual std::unique_ptr<VideoDecoder> CreateVideoDecoder( virtual std::unique_ptr<VideoDecoder> CreateVideoDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner); scoped_refptr<base::SingleThreadTaskRunner> task_runner,
mojom::CommandBufferIdPtr command_buffer_id);
// Returns the output sink used for rendering audio on |audio_device_id|. // Returns the output sink used for rendering audio on |audio_device_id|.
// May be null if the RendererFactory doesn't need an audio sink. // May be null if the RendererFactory doesn't need an audio sink.
......
...@@ -31,15 +31,17 @@ MojoVideoDecoderService::~MojoVideoDecoderService() {} ...@@ -31,15 +31,17 @@ MojoVideoDecoderService::~MojoVideoDecoderService() {}
void MojoVideoDecoderService::Construct( void MojoVideoDecoderService::Construct(
mojom::VideoDecoderClientAssociatedPtrInfo client, mojom::VideoDecoderClientAssociatedPtrInfo client,
mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe) { mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe,
mojom::CommandBufferIdPtr command_buffer_id) {
DVLOG(1) << __func__; DVLOG(1) << __func__;
// TODO(sandersd): Enter an error state.
if (decoder_) if (decoder_)
return; return;
// TODO(sandersd): Provide callback for requesting a GpuCommandBufferStub. // TODO(sandersd): Provide callback for requesting a GpuCommandBufferStub.
decoder_ = mojo_media_client_->CreateVideoDecoder( decoder_ = mojo_media_client_->CreateVideoDecoder(
base::ThreadTaskRunnerHandle::Get()); base::ThreadTaskRunnerHandle::Get(), std::move(command_buffer_id));
client_.Bind(std::move(client)); client_.Bind(std::move(client));
......
...@@ -28,7 +28,8 @@ class MojoVideoDecoderService : public mojom::VideoDecoder { ...@@ -28,7 +28,8 @@ class MojoVideoDecoderService : public mojom::VideoDecoder {
// mojom::VideoDecoder implementation // mojom::VideoDecoder implementation
void Construct(mojom::VideoDecoderClientAssociatedPtrInfo client, void Construct(mojom::VideoDecoderClientAssociatedPtrInfo client,
mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe) final; mojo::ScopedDataPipeConsumerHandle decoder_buffer_pipe,
mojom::CommandBufferIdPtr command_buffer_id) final;
void Initialize(mojom::VideoDecoderConfigPtr config, void Initialize(mojom::VideoDecoderConfigPtr config,
bool low_delay, bool low_delay,
const InitializeCallback& callback) final; const InitializeCallback& callback) final;
......
...@@ -73,6 +73,9 @@ class MEDIA_EXPORT GpuVideoAcceleratorFactories { ...@@ -73,6 +73,9 @@ class MEDIA_EXPORT GpuVideoAcceleratorFactories {
// Return the channel token, or an empty token if the channel is unusable. // Return the channel token, or an empty token if the channel is unusable.
virtual base::UnguessableToken GetChannelToken() = 0; virtual base::UnguessableToken GetChannelToken() = 0;
// Returns the |route_id| of the command buffer, or 0 if there is none.
virtual int32_t GetCommandBufferRouteId() = 0;
// Caller owns returned pointer, but should call Destroy() on it (instead of // Caller owns returned pointer, but should call Destroy() on it (instead of
// directly deleting) for proper destruction, as per the // directly deleting) for proper destruction, as per the
// VideoDecodeAccelerator interface. // VideoDecodeAccelerator interface.
......
...@@ -32,6 +32,7 @@ class MockGpuVideoAcceleratorFactories : public GpuVideoAcceleratorFactories { ...@@ -32,6 +32,7 @@ class MockGpuVideoAcceleratorFactories : public GpuVideoAcceleratorFactories {
bool IsGpuVideoAcceleratorEnabled() override; bool IsGpuVideoAcceleratorEnabled() override;
MOCK_METHOD0(GetChannelToken, base::UnguessableToken()); MOCK_METHOD0(GetChannelToken, base::UnguessableToken());
MOCK_METHOD0(GetCommandBufferRouteId, int32_t());
// CreateVideo{Decode,Encode}Accelerator returns scoped_ptr, which the mocking // CreateVideo{Decode,Encode}Accelerator returns scoped_ptr, which the mocking
// framework does not want. Trampoline them. // framework does not want. Trampoline them.
......
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