Bug 1834537 - Part 6: Simplify GCRuntime::checkAllocatorState a little r=sfink
[gecko.git] / ipc / glue / UtilityAudioDecoderChild.cpp
bloba63775390dddf70e64728ec1826a063e4bf7ddec
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "UtilityAudioDecoderChild.h"
9 #include "base/basictypes.h"
10 #include "mozilla/AppShutdown.h"
11 #include "mozilla/dom/ContentParent.h"
13 #ifdef MOZ_WMF_MEDIA_ENGINE
14 # include "mozilla/StaticPrefs_media.h"
15 # include "mozilla/gfx/GPUProcessManager.h"
16 # include "mozilla/gfx/gfxVars.h"
17 # include "mozilla/ipc/UtilityProcessManager.h"
18 # include "mozilla/layers/PVideoBridge.h"
19 # include "mozilla/layers/VideoBridgeUtils.h"
20 #endif
22 namespace mozilla::ipc {
24 NS_IMETHODIMP UtilityAudioDecoderChildShutdownObserver::Observe(
25 nsISupports* aSubject, const char* aTopic, const char16_t* aData) {
26 MOZ_ASSERT(strcmp(aTopic, "ipc:utility-shutdown") == 0);
28 nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
29 if (observerService) {
30 observerService->RemoveObserver(this, "ipc:utility-shutdown");
33 UtilityAudioDecoderChild::Shutdown(mSandbox);
34 return NS_OK;
37 NS_IMPL_ISUPPORTS(UtilityAudioDecoderChildShutdownObserver, nsIObserver);
39 static EnumeratedArray<SandboxingKind, SandboxingKind::COUNT,
40 StaticRefPtr<UtilityAudioDecoderChild>>
41 sAudioDecoderChilds;
43 UtilityAudioDecoderChild::UtilityAudioDecoderChild(SandboxingKind aKind)
44 : mSandbox(aKind), mAudioDecoderChildStart(TimeStamp::Now()) {
45 MOZ_ASSERT(NS_IsMainThread());
46 nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
47 if (observerService) {
48 auto* obs = new UtilityAudioDecoderChildShutdownObserver(aKind);
49 observerService->AddObserver(obs, "ipc:utility-shutdown", false);
53 void UtilityAudioDecoderChild::ActorDestroy(ActorDestroyReason aReason) {
54 MOZ_ASSERT(NS_IsMainThread());
55 #ifdef MOZ_WMF_MEDIA_ENGINE
56 if (mSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM) {
57 gfx::gfxVars::RemoveReceiver(this);
59 #endif
60 Shutdown(mSandbox);
63 void UtilityAudioDecoderChild::Bind(
64 Endpoint<PUtilityAudioDecoderChild>&& aEndpoint) {
65 MOZ_ASSERT(NS_IsMainThread());
66 if (NS_WARN_IF(!aEndpoint.Bind(this))) {
67 MOZ_ASSERT_UNREACHABLE("Failed to bind UtilityAudioDecoderChild!");
68 return;
70 #ifdef MOZ_WMF_MEDIA_ENGINE
71 if (mSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM) {
72 gfx::gfxVars::AddReceiver(this);
74 #endif
77 /* static */
78 void UtilityAudioDecoderChild::Shutdown(SandboxingKind aKind) {
79 sAudioDecoderChilds[aKind] = nullptr;
82 /* static */
83 RefPtr<UtilityAudioDecoderChild> UtilityAudioDecoderChild::GetSingleton(
84 SandboxingKind aKind) {
85 MOZ_ASSERT(NS_IsMainThread());
86 bool shutdown = AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMWillShutdown);
87 if (!sAudioDecoderChilds[aKind] && !shutdown) {
88 sAudioDecoderChilds[aKind] = new UtilityAudioDecoderChild(aKind);
90 return sAudioDecoderChilds[aKind];
93 mozilla::ipc::IPCResult
94 UtilityAudioDecoderChild::RecvUpdateMediaCodecsSupported(
95 const RemoteDecodeIn& aLocation,
96 const media::MediaCodecsSupported& aSupported) {
97 dom::ContentParent::BroadcastMediaCodecsSupportedUpdate(aLocation,
98 aSupported);
99 return IPC_OK();
102 #ifdef MOZ_WMF_MEDIA_ENGINE
103 mozilla::ipc::IPCResult
104 UtilityAudioDecoderChild::RecvCompleteCreatedVideoBridge() {
105 MOZ_ASSERT(NS_IsMainThread());
106 MOZ_ASSERT(mSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM);
107 mHasCreatedVideoBridge = true;
108 return IPC_OK();
111 bool UtilityAudioDecoderChild::HasCreatedVideoBridge() const {
112 MOZ_ASSERT(NS_IsMainThread());
113 return mHasCreatedVideoBridge;
116 void UtilityAudioDecoderChild::OnVarChanged(const gfx::GfxVarUpdate& aVar) {
117 MOZ_ASSERT(mSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM);
118 SendUpdateVar(aVar);
121 void UtilityAudioDecoderChild::OnCompositorUnexpectedShutdown() {
122 MOZ_ASSERT(NS_IsMainThread());
123 MOZ_ASSERT(mSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM);
124 mHasCreatedVideoBridge = false;
125 CreateVideoBridge();
128 bool UtilityAudioDecoderChild::CreateVideoBridge() {
129 MOZ_ASSERT(NS_IsMainThread());
130 MOZ_ASSERT(mSandbox == SandboxingKind::MF_MEDIA_ENGINE_CDM);
132 if (HasCreatedVideoBridge()) {
133 return true;
136 // Build content device data first; this ensure that the GPU process is fully
137 // ready.
138 gfx::ContentDeviceData contentDeviceData;
139 gfxPlatform::GetPlatform()->BuildContentDeviceData(&contentDeviceData);
141 gfx::GPUProcessManager* gpuManager = gfx::GPUProcessManager::Get();
142 if (!gpuManager) {
143 NS_WARNING("Failed to get a gpu mananger!");
144 return false;
147 // The child end is the producer of video frames; the parent end is the
148 // consumer.
149 base::ProcessId childPid = UtilityProcessManager::GetSingleton()
150 ->GetProcessParent(mSandbox)
151 ->OtherPid();
152 base::ProcessId parentPid = gpuManager->GPUProcessPid();
153 if (parentPid == base::kInvalidProcessId) {
154 NS_WARNING("GPU process Id is invald!");
155 return false;
158 ipc::Endpoint<layers::PVideoBridgeParent> parentPipe;
159 ipc::Endpoint<layers::PVideoBridgeChild> childPipe;
160 nsresult rv = layers::PVideoBridge::CreateEndpoints(parentPid, childPid,
161 &parentPipe, &childPipe);
162 if (NS_FAILED(rv)) {
163 NS_WARNING("Failed to create endpoints for video bridge!");
164 return false;
167 nsTArray<gfx::GfxVarUpdate> updates = gfx::gfxVars::FetchNonDefaultVars();
168 gpuManager->InitVideoBridge(
169 std::move(parentPipe),
170 layers::VideoBridgeSource::MFMediaEngineCDMProcess);
171 SendInitVideoBridge(std::move(childPipe), updates, contentDeviceData);
172 return true;
174 #endif
176 } // namespace mozilla::ipc