1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
media / mojo / services / gpu_mojo_media_client_android.cc [blame]
// Copyright 2021 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/mojo/services/gpu_mojo_media_client.h"
#include "base/android/build_info.h"
#include "base/task/sequenced_task_runner.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/media_buildflags.h"
#include "media/mojo/services/android_mojo_util.h"
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
#include "media/gpu/android/ndk_audio_encoder.h"
#endif
using media::android_mojo_util::CreateMediaDrmStorage;
using media::android_mojo_util::CreateProvisionFetcher;
namespace media {
class GpuMojoMediaClientAndroid final : public GpuMojoMediaClient {
public:
GpuMojoMediaClientAndroid(GpuMojoMediaClientTraits& traits)
: GpuMojoMediaClient(traits) {
android_overlay_factory_cb_ = std::move(traits.android_overlay_factory_cb);
}
~GpuMojoMediaClientAndroid() final = default;
protected:
std::unique_ptr<VideoDecoder> CreatePlatformVideoDecoder(
VideoDecoderTraits& traits) final {
scoped_refptr<gpu::RefCountedLock> ref_counted_lock;
// When this feature is enabled, CodecImage, CodecBufferWaitCoordinator 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 (AndroidVideoImageBacking, MRE,
// FrameInfoHelper etc.)
if (features::NeedThreadSafeAndroidMedia()) {
ref_counted_lock = base::MakeRefCounted<gpu::RefCountedLock>();
}
// Wrap |image_provider| in a pool.
auto image_provider = PooledSharedImageVideoProvider::Create(
gpu_task_runner_, traits.get_command_buffer_stub_cb,
std::make_unique<DirectSharedImageVideoProvider>(
gpu_task_runner_, traits.get_command_buffer_stub_cb,
ref_counted_lock),
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(
gpu_task_runner_, traits.get_command_buffer_stub_cb, ref_counted_lock);
return MediaCodecVideoDecoder::Create(
gpu_preferences_, gpu_feature_info_, traits.media_log->Clone(),
DeviceInfo::GetInstance(),
CodecAllocator::GetInstance(gpu_task_runner_),
std::make_unique<AndroidVideoSurfaceChooserImpl>(
DeviceInfo::GetInstance()->IsSetOutputSurfaceSupported()),
android_overlay_factory_cb_, std::move(traits.request_overlay_info_cb),
std::make_unique<VideoFrameFactoryImpl>(
gpu_task_runner_, gpu_preferences_, std::move(image_provider),
MaybeRenderEarlyManager::Create(gpu_task_runner_, ref_counted_lock),
std::move(frame_info_helper), ref_counted_lock),
ref_counted_lock);
}
std::optional<SupportedAudioDecoderConfigs>
GetPlatformSupportedAudioDecoderConfigs() final {
SupportedAudioDecoderConfigs audio_configs;
if (base::android::BuildInfo::GetInstance()->sdk_int() >=
base::android::SDK_VERSION_P) {
audio_configs.emplace_back(AudioCodec::kAAC, AudioCodecProfile::kXHE_AAC);
}
return audio_configs;
}
std::optional<SupportedVideoDecoderConfigs>
GetPlatformSupportedVideoDecoderConfigs() final {
return MediaCodecVideoDecoder::GetSupportedConfigs();
}
std::unique_ptr<AudioDecoder> CreatePlatformAudioDecoder(
scoped_refptr<base::SequencedTaskRunner> task_runner,
std::unique_ptr<MediaLog> media_log) final {
return std::make_unique<MediaCodecAudioDecoder>(std::move(task_runner));
}
std::unique_ptr<AudioEncoder> CreatePlatformAudioEncoder(
scoped_refptr<base::SequencedTaskRunner> task_runner) final {
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
if (__builtin_available(android NDK_MEDIA_CODEC_MIN_API, *)) {
return std::make_unique<NdkAudioEncoder>(std::move(task_runner));
}
#endif
return nullptr;
}
std::unique_ptr<CdmFactory> CreatePlatformCdmFactory(
mojom::FrameInterfaceFactory* frame_interfaces) final {
return std::make_unique<AndroidCdmFactory>(
base::BindRepeating(&CreateProvisionFetcher, frame_interfaces),
base::BindRepeating(&CreateMediaDrmStorage, frame_interfaces));
}
VideoDecoderType GetPlatformDecoderImplementationType() final {
return VideoDecoderType::kMediaCodec;
}
AndroidOverlayMojoFactoryCB android_overlay_factory_cb_;
};
std::unique_ptr<GpuMojoMediaClient> CreateGpuMediaService(
GpuMojoMediaClientTraits& traits) {
return std::make_unique<GpuMojoMediaClientAndroid>(traits);
}
} // namespace media