blob: 52773c901b6de46e7c1097a7f3e7e45c00376bcf [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/mojo/services/gpu_mojo_media_client.h"
#include "base/memory/ptr_util.h"
#include "gpu/command_buffer/service/ref_counted_lock.h"
#include "gpu/config/gpu_finch_features.h"
#include "media/base/android/android_cdm_factory.h"
#include "media/base/media_log.h"
#include "media/base/media_switches.h"
#include "media/filters/android/media_codec_audio_decoder.h"
#include "media/gpu/android/android_video_surface_chooser_impl.h"
#include "media/gpu/android/codec_allocator.h"
#include "media/gpu/android/direct_shared_image_video_provider.h"
#include "media/gpu/android/maybe_render_early_manager.h"
#include "media/gpu/android/media_codec_video_decoder.h"
#include "media/gpu/android/pooled_shared_image_video_provider.h"
#include "media/gpu/android/video_frame_factory_impl.h"
#include "media/mojo/mojom/media_drm_storage.mojom.h"
#include "media/mojo/mojom/provision_fetcher.mojom.h"
#include "media/mojo/services/android_mojo_util.h"
#include "media/mojo/services/mojo_media_drm_storage.h"
#include "media/mojo/services/mojo_provision_fetcher.h"
using media::android_mojo_util::CreateMediaDrmStorage;
using media::android_mojo_util::CreateProvisionFetcher;
namespace media {
namespace {
class AndroidPlatformDelegate : public GpuMojoMediaClient::PlatformDelegate {
public:
explicit AndroidPlatformDelegate(GpuMojoMediaClient* client)
: client_(client) {}
~AndroidPlatformDelegate() override = default;
AndroidPlatformDelegate(const AndroidPlatformDelegate&) = delete;
void operator=(const AndroidPlatformDelegate&) = delete;
// GpuMojoMediaClient::PlatformDelegate implementation.
std::unique_ptr<VideoDecoder> CreateVideoDecoder(
const VideoDecoderTraits& traits) override {
scoped_refptr<gpu::RefCountedLock> ref_counted_lock;
// When this feature is enabled, CodecImage, CodecBufferWaitCorrdinator and
// other media classes used in MCVD path will be accessed by multiple gpu
// threads. To implement thread safetyness, we are using a global ref
// counted lock here. CodecImage, CodecOutputBufferRenderer,
// CodecBufferWaitCoordinator expects this ref counted lock to be held by
// the classes which are accessing them (SharedImageVideo, MRE,
// FrameInfoHelper etc.)
if (features::NeedThreadSafeAndroidMedia()) {
ref_counted_lock = base::MakeRefCounted<gpu::RefCountedLock>();
}
std::unique_ptr<SharedImageVideoProvider> image_provider =
std::make_unique<DirectSharedImageVideoProvider>(
traits.gpu_task_runner, traits.get_command_buffer_stub_cb,
ref_counted_lock);
if (base::FeatureList::IsEnabled(kUsePooledSharedImageVideoProvider)) {
// Wrap |image_provider| in a pool.
image_provider = PooledSharedImageVideoProvider::Create(
traits.gpu_task_runner, traits.get_command_buffer_stub_cb,
std::move(image_provider), ref_counted_lock);
}
// TODO(liberato): Create this only if we're using Vulkan, else it's
// ignored. If we can tell that here, then VideoFrameFactory can use it
// as a signal about whether it's supposed to get YCbCrInfo rather than
// requiring the provider to set |is_vulkan| in the ImageRecord.
auto frame_info_helper = FrameInfoHelper::Create(
traits.gpu_task_runner, traits.get_command_buffer_stub_cb,
ref_counted_lock);
return MediaCodecVideoDecoder::Create(
client_->gpu_preferences(), client_->gpu_feature_info(),
traits.media_log->Clone(), DeviceInfo::GetInstance(),
CodecAllocator::GetInstance(traits.gpu_task_runner),
std::make_unique<AndroidVideoSurfaceChooserImpl>(
DeviceInfo::GetInstance()->IsSetOutputSurfaceSupported()),
traits.android_overlay_factory_cb,
std::move(traits.request_overlay_info_cb),
std::make_unique<VideoFrameFactoryImpl>(
traits.gpu_task_runner, client_->gpu_preferences(),
std::move(image_provider),
MaybeRenderEarlyManager::Create(traits.gpu_task_runner,
ref_counted_lock),
std::move(frame_info_helper), ref_counted_lock),
ref_counted_lock);
}
void GetSupportedVideoDecoderConfigs(
MojoMediaClient::SupportedVideoDecoderConfigsCallback callback) override {
std::move(callback).Run(MediaCodecVideoDecoder::GetSupportedConfigs());
}
std::unique_ptr<AudioDecoder> CreateAudioDecoder(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
return std::make_unique<MediaCodecAudioDecoder>(std::move(task_runner));
}
std::unique_ptr<CdmFactory> CreateCdmFactory(
mojom::FrameInterfaceFactory* frame_interfaces) override {
return std::make_unique<AndroidCdmFactory>(
base::BindRepeating(&CreateProvisionFetcher, frame_interfaces),
base::BindRepeating(&CreateMediaDrmStorage, frame_interfaces));
}
VideoDecoderType GetDecoderImplementationType() override {
return VideoDecoderType::kMediaCodec;
}
private:
GpuMojoMediaClient* client_;
};
} // namespace
std::unique_ptr<GpuMojoMediaClient::PlatformDelegate>
GpuMojoMediaClient::PlatformDelegate::Create(GpuMojoMediaClient* client) {
return std::make_unique<AndroidPlatformDelegate>(client);
}
} // namespace media