Backed out 12 changesets (bug 1471535) for VideoDecoderChild failures CLOSED TREE

Backed out changeset 3d8a11458d79 (bug 1471535)
Backed out changeset 2176010bc1fe (bug 1471535)
Backed out changeset dfb4d3462b22 (bug 1471535)
Backed out changeset ea6b73ded74d (bug 1471535)
Backed out changeset 404d760a9e82 (bug 1471535)
Backed out changeset 28ae4b6fab68 (bug 1471535)
Backed out changeset af91e1f04c2d (bug 1471535)
Backed out changeset d39fef4334b3 (bug 1471535)
Backed out changeset a038821cd8ae (bug 1471535)
Backed out changeset 5dcc74a938c6 (bug 1471535)
Backed out changeset 53aff7e699b4 (bug 1471535)
Backed out changeset f3f6abc052f0 (bug 1471535)

--HG--
rename : dom/media/ipc/GpuDecoderModule.cpp => dom/media/ipc/RemoteVideoDecoder.cpp
rename : dom/media/ipc/GpuDecoderModule.h => dom/media/ipc/RemoteVideoDecoder.h
This commit is contained in:
Bogdan Tara 2018-11-13 23:31:56 +02:00
parent d9766a1241
commit fc8134a16a
67 changed files with 404 additions and 3693 deletions

View File

@ -20,7 +20,6 @@
#include "mozilla/NullPrincipal.h"
#include "mozilla/Preferences.h"
#include "mozilla/ProcessHangMonitorIPC.h"
#include "mozilla/RemoteDecoderManagerChild.h"
#include "mozilla/Unused.h"
#include "mozilla/StaticPrefs.h"
#include "mozilla/TelemetryIPC.h"
@ -1511,14 +1510,6 @@ ContentChild::RecvReinitRenderingForDeviceReset()
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvInitRemoteDecoder(
Endpoint<PRemoteDecoderManagerChild>&& aRemoteManager)
{
RemoteDecoderManagerChild::InitForContent(std::move(aRemoteManager));
return IPC_OK();
}
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
extern "C" {
CGError

View File

@ -211,10 +211,6 @@ public:
mozilla::ipc::IPCResult RecvReinitRenderingForDeviceReset() override;
virtual mozilla::ipc::IPCResult
RecvInitRemoteDecoder(
Endpoint<PRemoteDecoderManagerChild>&& aRemoteManager) override;
virtual mozilla::ipc::IPCResult RecvSetProcessSandbox(const MaybeFileDesc& aBroker) override;
virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,

View File

@ -95,7 +95,6 @@
#include "mozilla/Preferences.h"
#include "mozilla/ProcessHangMonitor.h"
#include "mozilla/ProcessHangMonitorIPC.h"
#include "mozilla/RDDProcessManager.h"
#include "mozilla/recordreplay/ParentIPC.h"
#include "mozilla/Scheduler.h"
#include "mozilla/ScopeExit.h"
@ -2656,23 +2655,6 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority)
gpm->AddListener(this);
if (StaticPrefs::MediaRddProcessEnabled()) {
RDDProcessManager* rdd = RDDProcessManager::Get();
Endpoint<PRemoteDecoderManagerChild> remoteManager;
bool rddOpened = rdd->CreateContentBridge(OtherPid(),
&remoteManager);
MOZ_ASSERT(rddOpened);
if (rddOpened) {
// not using std::move here (like in SendInitRendering above) because
// clang-tidy says:
// Warning: Passing result of std::move() as a const reference
// argument; no move will actually happen
Unused << SendInitRemoteDecoder(remoteManager);
}
}
nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
if (sheetService) {
// This looks like a lot of work, but in a normal browser session we just

View File

@ -5,7 +5,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MemoryReportRequest.h"
#include "mozilla/RDDParent.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/GPUParent.h"
@ -127,9 +126,6 @@ public:
case GeckoProcessType_GPU:
Unused << gfx::GPUParent::GetSingleton()->SendAddMemoryReport(memreport);
break;
case GeckoProcessType_RDD:
Unused << RDDParent::GetSingleton()->SendAddMemoryReport(memreport);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unhandled process type");
}
@ -167,9 +163,6 @@ public:
case GeckoProcessType_GPU:
sent = gfx::GPUParent::GetSingleton()->SendFinishMemoryReport(mGeneration);
break;
case GeckoProcessType_RDD:
sent = RDDParent::GetSingleton()->SendFinishMemoryReport(mGeneration);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unhandled process type");
}

View File

@ -43,7 +43,6 @@ include protocol PURLClassifier;
include protocol PURLClassifierLocal;
include protocol PVRManager;
include protocol PVideoDecoderManager;
include protocol PRemoteDecoderManager;
include protocol PProfiler;
include protocol PScriptCache;
include DOMTypes;
@ -398,8 +397,6 @@ child:
// Re-create the rendering stack for a device reset.
async ReinitRenderingForDeviceReset();
async InitRemoteDecoder(Endpoint<PRemoteDecoderManagerChild> decoder);
/**
* Enable system-level sandboxing features, if available. Can
* usually only be performed zero or one times. The child may

View File

@ -1,98 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GpuDecoderModule.h"
#include "base/thread.h"
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/StaticPrefs.h"
#include "RemoteMediaDataDecoder.h"
#include "VideoDecoderChild.h"
#include "VideoDecoderManagerChild.h"
namespace mozilla {
using base::Thread;
using dom::VideoDecoderChild;
using dom::VideoDecoderManagerChild;
using namespace ipc;
using namespace layers;
using namespace gfx;
nsresult
GpuDecoderModule::Startup()
{
if (!VideoDecoderManagerChild::GetManagerThread()) {
return NS_ERROR_FAILURE;
}
return mWrapped->Startup();
}
bool
GpuDecoderModule::SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const
{
return mWrapped->SupportsMimeType(aMimeType, aDiagnostics);
}
bool
GpuDecoderModule::Supports(const TrackInfo& aTrackInfo,
DecoderDoctorDiagnostics* aDiagnostics) const
{
return mWrapped->Supports(aTrackInfo, aDiagnostics);
}
static inline bool
IsRemoteAcceleratedCompositor(KnowsCompositor* aKnows)
{
TextureFactoryIdentifier ident = aKnows->GetTextureFactoryIdentifier();
return ident.mParentBackend != LayersBackend::LAYERS_BASIC &&
ident.mParentProcessType == GeckoProcessType_GPU;
}
already_AddRefed<MediaDataDecoder>
GpuDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
{
if (!StaticPrefs::MediaGpuProcessDecoder() ||
!aParams.mKnowsCompositor ||
!IsRemoteAcceleratedCompositor(aParams.mKnowsCompositor))
{
return mWrapped->CreateVideoDecoder(aParams);
}
RefPtr<VideoDecoderChild> child = new VideoDecoderChild();
RefPtr<RemoteMediaDataDecoder> object = new RemoteMediaDataDecoder(
child,
VideoDecoderManagerChild::GetManagerThread(),
VideoDecoderManagerChild::GetManagerAbstractThread());
SynchronousTask task("InitIPDL");
MediaResult result(NS_OK);
VideoDecoderManagerChild::GetManagerThread()->Dispatch(
NS_NewRunnableFunction(
"dom::GpuDecoderModule::CreateVideoDecoder",
[&, child]() {
AutoCompleteTask complete(&task);
result = child->InitIPDL(
aParams.VideoConfig(),
aParams.mRate.mValue,
aParams.mOptions,
aParams.mKnowsCompositor->GetTextureFactoryIdentifier());
}),
NS_DISPATCH_NORMAL);
task.Wait();
if (NS_FAILED(result)) {
if (aParams.mError) {
*aParams.mError = result;
}
return nullptr;
}
return object.forget();
}
} // namespace mozilla

View File

@ -1,50 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_media_ipc_GpuDecoderModule_h
#define include_dom_media_ipc_GpuDecoderModule_h
#include "PlatformDecoderModule.h"
#include "MediaData.h"
namespace mozilla {
// A PDM implementation that creates a RemoteMediaDataDecoder (a
// MediaDataDecoder) that proxies to a VideoDecoderChild. The
// VideoDecoderChild will talk to a VideoDecoderParent running on the
// GPU process.
// We currently require a 'wrapped' PDM in order to be able to answer
// SupportsMimeType and DecoderNeedsConversion. Ideally we'd check these
// over IPDL using the manager protocol
class GpuDecoderModule : public PlatformDecoderModule
{
public:
explicit GpuDecoderModule(PlatformDecoderModule* aWrapped)
: mWrapped(aWrapped)
{}
nsresult Startup() override;
bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override;
bool Supports(const TrackInfo& aTrackInfo,
DecoderDoctorDiagnostics* aDiagnostics) const override;
already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
const CreateDecoderParams& aParams) override;
already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
const CreateDecoderParams& aParams) override
{
return nullptr;
}
private:
RefPtr<PlatformDecoderModule> mWrapped;
};
} // namespace mozilla
#endif // include_dom_media_ipc_GpuDecoderModule_h

View File

@ -1,47 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_media_ipc_IRemoteDecoderChild_h
#define include_dom_media_ipc_IRemoteDecoderChild_h
#include "PlatformDecoderModule.h"
namespace mozilla {
// This interface mirrors the MediaDataDecoder plus a bit (DestroyIPDL)
// to allow proxying to a remote decoder in RemoteDecoderModule or
// GpuDecoderModule. RemoteAudioDecoderChild, RemoteVideoDecoderChild,
// and VideoDecoderChild (for GPU) implement this interface.
class IRemoteDecoderChild
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(IRemoteDecoderChild);
virtual RefPtr<MediaDataDecoder::InitPromise> Init() = 0;
virtual RefPtr<MediaDataDecoder::DecodePromise> Decode(
MediaRawData* aSample) = 0;
virtual RefPtr<MediaDataDecoder::DecodePromise> Drain() = 0;
virtual RefPtr<MediaDataDecoder::FlushPromise> Flush() = 0;
virtual void Shutdown() = 0;
virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const
{
return false;
}
virtual nsCString GetDescriptionName() const = 0;
virtual void SetSeekThreshold(const media::TimeUnit& aTime) {}
virtual MediaDataDecoder::ConversionRequired NeedsConversion() const
{
return MediaDataDecoder::ConversionRequired::kNeedNone;
}
virtual void DestroyIPDL() = 0;
protected:
virtual ~IRemoteDecoderChild() {}
};
} // namespace mozilla
#endif // include_dom_media_ipc_IRemoteDecoderChild_h

View File

@ -44,49 +44,6 @@ namespace IPC {
return false;
}
};
template<>
struct ParamTraits<mozilla::AudioInfo>
{
typedef mozilla::AudioInfo paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
// TrackInfo
WriteParam(aMsg, aParam.mMimeType);
// AudioInfo
WriteParam(aMsg, aParam.mRate);
WriteParam(aMsg, aParam.mChannels);
WriteParam(aMsg, aParam.mChannelMap);
WriteParam(aMsg, aParam.mBitDepth);
WriteParam(aMsg, aParam.mProfile);
WriteParam(aMsg, aParam.mExtendedProfile);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (ReadParam(aMsg, aIter, &aResult->mMimeType) &&
ReadParam(aMsg, aIter, &aResult->mRate) &&
ReadParam(aMsg, aIter, &aResult->mChannels) &&
ReadParam(aMsg, aIter, &aResult->mChannelMap) &&
ReadParam(aMsg, aIter, &aResult->mBitDepth) &&
ReadParam(aMsg, aIter, &aResult->mProfile) &&
ReadParam(aMsg, aIter, &aResult->mExtendedProfile)) {
return true;
}
return false;
}
};
template<>
struct ParamTraits<mozilla::MediaDataDecoder::ConversionRequired>
: public ContiguousEnumSerializerInclusive<
mozilla::MediaDataDecoder::ConversionRequired,
mozilla::MediaDataDecoder::ConversionRequired(0),
mozilla::MediaDataDecoder::ConversionRequired(
mozilla::MediaDataDecoder::ConversionRequired::kNeedAnnexB)> {};
} // namespace IPC
#endif // mozilla_dom_media_MediaIPCUtils_h

View File

@ -1,23 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
namespace mozilla {
struct MediaDataIPDL
{
int64_t offset;
int64_t time;
int64_t timecode;
int64_t duration;
uint32_t frames;
bool keyframe;
};
struct MediaRawDataIPDL
{
MediaDataIPDL base;
Shmem buffer;
};
} // namespace mozilla

View File

@ -1,47 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include MemoryReportTypes;
include protocol PProfiler;
include protocol PRemoteDecoderManager;
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
namespace mozilla {
// This protocol allows the UI process to talk to the RDD
// (RemoteDataDecoder) process. There is one instance of this protocol,
// with the RDDParent living on the main thread of the RDD process and
// the RDDChild living on the main thread of the UI process.
protocol PRDD
{
parent:
// args TBD, sent by UI process to initiate core settings
async Init();
async InitProfiler(Endpoint<PProfilerChild> endpoint);
async NewContentRemoteDecoderManager(
Endpoint<PRemoteDecoderManagerParent> endpoint);
async RequestMemoryReport(uint32_t generation,
bool anonymize,
bool minimizeMemoryUsage,
MaybeFileDesc DMDFile);
child:
// args TBD, sent when init complete. Occurs once, after Init().
async InitComplete();
async InitCrashReporter(Shmem shmem, NativeThreadId threadId);
async AddMemoryReport(MemoryReport aReport);
async FinishMemoryReport(uint32_t aGeneration);
};
} // namespace mozilla

View File

@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PRemoteVideoDecoder;
include "mozilla/dom/MediaIPCUtils.h";
using VideoInfo from "MediaInfo.h";
using AudioInfo from "MediaInfo.h";
using mozilla::CreateDecoderParams::OptionSet from "PlatformDecoderModule.h";
namespace mozilla {
sync protocol PRemoteDecoderManager
{
manages PRemoteVideoDecoder;
parent:
sync PRemoteVideoDecoder(VideoInfo info,
float framerate,
OptionSet options)
returns (bool success,
nsCString aErrorDescription);
};
} // namespace mozilla

View File

@ -1,60 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include "mozilla/dom/MediaIPCUtils.h";
include protocol PRemoteDecoderManager;
include PMediaDecoderParams;
include LayersSurfaces;
using mozilla::MediaDataDecoder::ConversionRequired from "PlatformDecoderModule.h";
namespace mozilla {
struct RemoteVideoDataIPDL
{
MediaDataIPDL base;
IntSize display;
IntSize frameSize;
SurfaceDescriptorBuffer sdBuffer;
int32_t frameID;
};
// This protocol provides a way to use MediaDataDecoder across processes.
// The parent side currently is only implemented to work with
// RemoteDecoderModule.
// The child side runs in the content process, and the parent side runs
// in the RDD process. We run a separate IPDL thread for both sides.
async protocol PRemoteVideoDecoder
{
manager PRemoteDecoderManager;
parent:
async Init();
async Input(MediaRawDataIPDL data);
async Flush();
async Drain();
async Shutdown();
async SetSeekThreshold(int64_t time);
async __delete__();
child:
async InitComplete(nsCString decoderDescription,
ConversionRequired conversion);
async InitFailed(nsresult reason);
async FlushComplete();
// Each output includes a SurfaceDescriptorBuffer that represents the decoded
// frame.
async VideoOutput(RemoteVideoDataIPDL data);
async InputExhausted();
async DrainComplete();
async Error(nsresult error);
};
} // namespace mozilla

View File

@ -6,13 +6,22 @@
include "mozilla/dom/MediaIPCUtils.h";
include protocol PVideoDecoderManager;
include PMediaDecoderParams;
include LayersSurfaces;
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
namespace mozilla {
namespace dom {
struct MediaDataIPDL
{
int64_t offset;
int64_t time;
int64_t timecode;
int64_t duration;
uint32_t frames;
bool keyframe;
};
struct VideoDataIPDL
{
MediaDataIPDL base;
@ -22,6 +31,12 @@ struct VideoDataIPDL
int32_t frameID;
};
struct MediaRawDataIPDL
{
MediaDataIPDL base;
Shmem buffer;
};
// This protocol provides a way to use MediaDataDecoder across processes.
// The parent side currently is only implemented to work with
// Window Media Foundation, but can be extended easily to support other backends.

View File

@ -1,145 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RDDChild.h"
#include "mozilla/dom/MemoryReportRequest.h"
#include "mozilla/ipc/CrashReporterHost.h"
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerParent.h"
#endif
#include "RDDProcessHost.h"
namespace mozilla {
using namespace layers;
RDDChild::RDDChild(RDDProcessHost* aHost)
: mHost(aHost),
mRDDReady(false)
{
MOZ_COUNT_CTOR(RDDChild);
}
RDDChild::~RDDChild()
{
MOZ_COUNT_DTOR(RDDChild);
}
void
RDDChild::Init()
{
SendInit();
#ifdef MOZ_GECKO_PROFILER
Unused << SendInitProfiler(ProfilerParent::CreateForProcess(OtherPid()));
#endif
}
bool
RDDChild::EnsureRDDReady()
{
if (mRDDReady) {
return true;
}
mRDDReady = true;
return true;
}
mozilla::ipc::IPCResult
RDDChild::RecvInitComplete()
{
// We synchronously requested RDD parameters before this arrived.
if (mRDDReady) {
return IPC_OK();
}
mRDDReady = true;
return IPC_OK();
}
mozilla::ipc::IPCResult
RDDChild::RecvInitCrashReporter(Shmem&& aShmem, const NativeThreadId& aThreadId)
{
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(
GeckoProcessType_RDD,
aShmem,
aThreadId);
return IPC_OK();
}
bool
RDDChild::SendRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
const MaybeFileDesc& aDMDFile)
{
mMemoryReportRequest = MakeUnique<MemoryReportRequestHost>(aGeneration);
Unused << PRDDChild::SendRequestMemoryReport(aGeneration,
aAnonymize,
aMinimizeMemoryUsage,
aDMDFile);
return true;
}
mozilla::ipc::IPCResult
RDDChild::RecvAddMemoryReport(const MemoryReport& aReport)
{
if (mMemoryReportRequest) {
mMemoryReportRequest->RecvReport(aReport);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
RDDChild::RecvFinishMemoryReport(const uint32_t& aGeneration)
{
if (mMemoryReportRequest) {
mMemoryReportRequest->Finish(aGeneration);
mMemoryReportRequest = nullptr;
}
return IPC_OK();
}
void
RDDChild::ActorDestroy(ActorDestroyReason aWhy)
{
if (aWhy == AbnormalShutdown) {
if (mCrashReporter) {
mCrashReporter->GenerateCrashReport(OtherPid());
mCrashReporter = nullptr;
}
}
mHost->OnChannelClosed();
}
class DeferredDeleteRDDChild : public Runnable
{
public:
explicit DeferredDeleteRDDChild(UniquePtr<RDDChild>&& aChild)
: Runnable("gfx::DeferredDeleteRDDChild")
, mChild(std::move(aChild))
{
}
NS_IMETHODIMP Run() override {
return NS_OK;
}
private:
UniquePtr<RDDChild> mChild;
};
/* static */ void
RDDChild::Destroy(UniquePtr<RDDChild>&& aChild)
{
NS_DispatchToMainThread(new DeferredDeleteRDDChild(std::move(aChild)));
}
} // namespace mozilla

View File

@ -1,65 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_dom_media_ipc_RDDChild_h_
#define _include_dom_media_ipc_RDDChild_h_
#include "mozilla/PRDDChild.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
namespace ipc {
class CrashReporterHost;
} // namespace ipc
namespace dom {
class MemoryReportRequestHost;
} // namespace dom
class RDDProcessHost;
class RDDChild final : public PRDDChild
{
typedef mozilla::dom::MemoryReportRequestHost MemoryReportRequestHost;
public:
explicit RDDChild(RDDProcessHost* aHost);
~RDDChild();
void Init();
bool EnsureRDDReady();
// PRDDChild overrides.
mozilla::ipc::IPCResult RecvInitComplete() override;
mozilla::ipc::IPCResult RecvInitCrashReporter(
Shmem&& shmem,
const NativeThreadId& aThreadId) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvAddMemoryReport(
const MemoryReport& aReport) override;
mozilla::ipc::IPCResult RecvFinishMemoryReport(
const uint32_t& aGeneration) override;
bool SendRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
const MaybeFileDesc& aDMDFile);
static void Destroy(UniquePtr<RDDChild>&& aChild);
private:
RDDProcessHost* mHost;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
UniquePtr<MemoryReportRequestHost> mMemoryReportRequest;
bool mRDDReady;
};
} // namespace mozilla
#endif // _include_dom_media_ipc_RDDChild_h_

View File

@ -1,160 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RDDParent.h"
#if defined(XP_WIN)
# include <process.h>
# include <dwrite.h>
#endif
#include "mozilla/Assertions.h"
#include "mozilla/HangDetails.h"
#include "mozilla/RemoteDecoderManagerChild.h"
#include "mozilla/RemoteDecoderManagerParent.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/MemoryReportRequest.h"
#include "mozilla/ipc/CrashReporterClient.h"
#include "mozilla/ipc/ProcessChild.h"
#ifdef MOZ_GECKO_PROFILER
#include "ChildProfilerController.h"
#endif
#include "nsDebugImpl.h"
#include "nsThreadManager.h"
#include "ProcessUtils.h"
namespace mozilla {
using namespace ipc;
static RDDParent* sRDDParent;
RDDParent::RDDParent()
: mLaunchTime(TimeStamp::Now())
{
sRDDParent = this;
}
RDDParent::~RDDParent()
{
sRDDParent = nullptr;
}
/* static */ RDDParent*
RDDParent::GetSingleton()
{
return sRDDParent;
}
bool
RDDParent::Init(base::ProcessId aParentPid,
const char* aParentBuildID,
MessageLoop* aIOLoop,
IPC::Channel* aChannel)
{
// Initialize the thread manager before starting IPC. Otherwise, messages
// may be posted to the main thread and we won't be able to process them.
if (NS_WARN_IF(NS_FAILED(nsThreadManager::get().Init()))) {
return false;
}
// Now it's safe to start IPC.
if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) {
return false;
}
nsDebugImpl::SetMultiprocessMode("RDD");
// This must be checked before any IPDL message, which may hit sentinel
// errors due to parent and content processes having different
// versions.
MessageChannel* channel = GetIPCChannel();
if (channel && !channel->SendBuildIDsMatchMessage(aParentBuildID)) {
// We need to quit this process if the buildID doesn't match the parent's.
// This can occur when an update occurred in the background.
ProcessChild::QuickExit();
}
// Init crash reporter support.
CrashReporterClient::InitSingleton(this);
if (NS_FAILED(NS_InitMinimalXPCOM())) {
return false;
}
mozilla::ipc::SetThisProcessName("RDD Process");
return true;
}
mozilla::ipc::IPCResult
RDDParent::RecvInit()
{
Unused << SendInitComplete();
return IPC_OK();
}
mozilla::ipc::IPCResult
RDDParent::RecvInitProfiler(Endpoint<PProfilerChild>&& aEndpoint)
{
#ifdef MOZ_GECKO_PROFILER
mProfilerController = ChildProfilerController::Create(std::move(aEndpoint));
#endif
return IPC_OK();
}
mozilla::ipc::IPCResult
RDDParent::RecvNewContentRemoteDecoderManager(
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint)
{
if (!RemoteDecoderManagerParent::CreateForContent(std::move(aEndpoint))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
RDDParent::RecvRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
const MaybeFileDesc& aDMDFile)
{
nsPrintfCString processName("RDD (pid %u)", (unsigned)getpid());
mozilla::dom::MemoryReportRequestClient::Start(aGeneration,
aAnonymize,
aMinimizeMemoryUsage,
aDMDFile,
processName);
return IPC_OK();
}
void
RDDParent::ActorDestroy(ActorDestroyReason aWhy)
{
if (AbnormalShutdown == aWhy) {
NS_WARNING("Shutting down RDD process early due to a crash!");
ProcessChild::QuickExit();
}
#ifndef NS_FREE_PERMANENT_DATA
// No point in going through XPCOM shutdown because we don't keep persistent
// state.
ProcessChild::QuickExit();
#endif
#ifdef MOZ_GECKO_PROFILER
if (mProfilerController) {
mProfilerController->Shutdown();
mProfilerController = nullptr;
}
#endif
CrashReporterClient::DestroySingleton();
XRE_ShutdownChildProcess();
}
} // namespace mozilla

View File

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_dom_media_ipc_RDDParent_h__
#define _include_dom_media_ipc_RDDParent_h__
#include "mozilla/PRDDParent.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
class TimeStamp;
class ChildProfilerController;
class RDDParent final : public PRDDParent
{
public:
RDDParent();
~RDDParent();
static RDDParent* GetSingleton();
bool Init(base::ProcessId aParentPid,
const char* aParentBuildID,
MessageLoop* aIOLoop,
IPC::Channel* aChannel);
mozilla::ipc::IPCResult RecvInit() override;
mozilla::ipc::IPCResult RecvInitProfiler(
Endpoint<PProfilerChild>&& aEndpoint) override;
mozilla::ipc::IPCResult RecvNewContentRemoteDecoderManager(
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint) override;
mozilla::ipc::IPCResult RecvRequestMemoryReport(
const uint32_t& generation,
const bool& anonymize,
const bool& minimizeMemoryUsage,
const MaybeFileDesc& DMDFile) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
private:
const TimeStamp mLaunchTime;
#ifdef MOZ_GECKO_PROFILER
RefPtr<ChildProfilerController> mProfilerController;
#endif
};
} // namespace mozilla
#endif // _include_dom_media_ipc_RDDParent_h__

View File

@ -1,257 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RDDProcessHost.h"
#include "chrome/common/process_watcher.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs.h"
#include "RDDChild.h"
namespace mozilla {
using namespace ipc;
RDDProcessHost::RDDProcessHost(Listener* aListener)
: GeckoChildProcessHost(GeckoProcessType_RDD),
mListener(aListener),
mTaskFactory(this),
mLaunchPhase(LaunchPhase::Unlaunched),
mProcessToken(0),
mShutdownRequested(false),
mChannelClosed(false)
{
MOZ_COUNT_CTOR(RDDProcessHost);
}
RDDProcessHost::~RDDProcessHost()
{
MOZ_COUNT_DTOR(RDDProcessHost);
}
bool
RDDProcessHost::Launch(StringVector aExtraOpts)
{
MOZ_ASSERT(mLaunchPhase == LaunchPhase::Unlaunched);
MOZ_ASSERT(!mRDDChild);
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mSandboxLevel = Preferences::GetInt("security.sandbox.rdd.level");
#endif
mLaunchPhase = LaunchPhase::Waiting;
mLaunchTime = TimeStamp::Now();
if (!GeckoChildProcessHost::AsyncLaunch(aExtraOpts)) {
mLaunchPhase = LaunchPhase::Complete;
return false;
}
return true;
}
bool
RDDProcessHost::WaitForLaunch()
{
if (mLaunchPhase == LaunchPhase::Complete) {
return !!mRDDChild;
}
int32_t timeoutMs = StaticPrefs::MediaRddProcessStartupTimeoutMs();
// If one of the following environment variables are set we can
// effectively ignore the timeout - as we can guarantee the RDD
// process will be terminated
if (PR_GetEnv("MOZ_DEBUG_CHILD_PROCESS") ||
PR_GetEnv("MOZ_DEBUG_CHILD_PAUSE")) {
timeoutMs = 0;
}
// Our caller expects the connection to be finished after we return, so we
// immediately set up the IPDL actor and fire callbacks. The IO thread will
// still dispatch a notification to the main thread - we'll just ignore it.
bool result = GeckoChildProcessHost::WaitUntilConnected(timeoutMs);
InitAfterConnect(result);
return result;
}
void
RDDProcessHost::OnChannelConnected(int32_t peer_pid)
{
MOZ_ASSERT(!NS_IsMainThread());
GeckoChildProcessHost::OnChannelConnected(peer_pid);
// Post a task to the main thread. Take the lock because mTaskFactory is not
// thread-safe.
RefPtr<Runnable> runnable;
{
MonitorAutoLock lock(mMonitor);
runnable =
mTaskFactory.NewRunnableMethod(&RDDProcessHost::OnChannelConnectedTask);
}
NS_DispatchToMainThread(runnable);
}
void
RDDProcessHost::OnChannelError()
{
MOZ_ASSERT(!NS_IsMainThread());
GeckoChildProcessHost::OnChannelError();
// Post a task to the main thread. Take the lock because mTaskFactory is not
// thread-safe.
RefPtr<Runnable> runnable;
{
MonitorAutoLock lock(mMonitor);
runnable =
mTaskFactory.NewRunnableMethod(&RDDProcessHost::OnChannelErrorTask);
}
NS_DispatchToMainThread(runnable);
}
void
RDDProcessHost::OnChannelConnectedTask()
{
if (mLaunchPhase == LaunchPhase::Waiting) {
InitAfterConnect(true);
}
}
void
RDDProcessHost::OnChannelErrorTask()
{
if (mLaunchPhase == LaunchPhase::Waiting) {
InitAfterConnect(false);
}
}
static uint64_t sRDDProcessTokenCounter = 0;
void
RDDProcessHost::InitAfterConnect(bool aSucceeded)
{
MOZ_ASSERT(mLaunchPhase == LaunchPhase::Waiting);
MOZ_ASSERT(!mRDDChild);
mLaunchPhase = LaunchPhase::Complete;
if (aSucceeded) {
mProcessToken = ++sRDDProcessTokenCounter;
mRDDChild = MakeUnique<RDDChild>(this);
DebugOnly<bool> rv =
mRDDChild->Open(GetChannel(), base::GetProcId(GetChildProcessHandle()));
MOZ_ASSERT(rv);
mRDDChild->Init();
}
if (mListener) {
mListener->OnProcessLaunchComplete(this);
}
}
void
RDDProcessHost::Shutdown()
{
MOZ_ASSERT(!mShutdownRequested);
mListener = nullptr;
if (mRDDChild) {
// OnChannelClosed uses this to check if the shutdown was expected or
// unexpected.
mShutdownRequested = true;
// The channel might already be closed if we got here unexpectedly.
if (!mChannelClosed) {
mRDDChild->Close();
}
#ifndef NS_FREE_PERMANENT_DATA
// No need to communicate shutdown, the RDD process doesn't need to
// communicate anything back.
KillHard("NormalShutdown");
#endif
// If we're shutting down unexpectedly, we're in the middle of handling an
// ActorDestroy for PRDDChild, which is still on the stack. We'll return
// back to OnChannelClosed.
//
// Otherwise, we'll wait for OnChannelClose to be called whenever PRDDChild
// acknowledges shutdown.
return;
}
DestroyProcess();
}
void
RDDProcessHost::OnChannelClosed()
{
mChannelClosed = true;
if (!mShutdownRequested && mListener) {
// This is an unclean shutdown. Notify our listener that we're going away.
mListener->OnProcessUnexpectedShutdown(this);
} else {
DestroyProcess();
}
// Release the actor.
RDDChild::Destroy(std::move(mRDDChild));
MOZ_ASSERT(!mRDDChild);
}
void
RDDProcessHost::KillHard(const char* aReason)
{
ProcessHandle handle = GetChildProcessHandle();
if (!base::KillProcess(handle, base::PROCESS_END_KILLED_BY_USER, false)) {
NS_WARNING("failed to kill subprocess!");
}
SetAlreadyDead();
}
uint64_t
RDDProcessHost::GetProcessToken() const
{
return mProcessToken;
}
static void
RDDDelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
{
XRE_GetIOMessageLoop()->
PostTask(
mozilla::MakeAndAddRef<DeleteTask<GeckoChildProcessHost>>(aSubprocess));
}
void
RDDProcessHost::KillProcess()
{
KillHard("DiagnosticKill");
}
void
RDDProcessHost::DestroyProcess()
{
// Cancel all tasks. We don't want anything triggering after our caller
// expects this to go away.
{
MonitorAutoLock lock(mMonitor);
mTaskFactory.RevokeAll();
}
MessageLoop::current()->
PostTask(NewRunnableFunction("DestroyProcessRunnable",
RDDDelayedDeleteSubprocess,
this));
}
} // namespace mozilla

View File

@ -1,143 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_dom_media_ipc_RDDProcessHost_h_
#define _include_dom_media_ipc_RDDProcessHost_h_
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/Maybe.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/ipc/TaskFactory.h"
class nsITimer;
namespace mozilla {
class RDDChild;
// RDDProcessHost is the "parent process" container for a subprocess handle and
// IPC connection. It owns the parent process IPDL actor, which in this case,
// is a RDDChild.
//
// RDDProcessHosts are allocated and managed by RDDProcessManager. For all
// intents and purposes it is a singleton, though more than one may be allocated
// at a time due to its shutdown being asynchronous.
class RDDProcessHost final : public mozilla::ipc::GeckoChildProcessHost
{
friend class RDDChild;
public:
class Listener {
public:
virtual void OnProcessLaunchComplete(RDDProcessHost* aHost)
{}
// The RDDProcessHost has unexpectedly shutdown or had its connection
// severed. This is not called if an error occurs after calling
// Shutdown().
virtual void OnProcessUnexpectedShutdown(RDDProcessHost* aHost)
{}
};
explicit RDDProcessHost(Listener* listener);
~RDDProcessHost();
// Launch the subprocess asynchronously. On failure, false is returned.
// Otherwise, true is returned, and the OnProcessLaunchComplete listener
// callback will be invoked either when a connection has been established, or
// if a connection could not be established due to an asynchronous error.
//
// @param aExtraOpts (StringVector)
// Extra options to pass to the subprocess.
bool Launch(StringVector aExtraOpts);
// If the process is being launched, block until it has launched and
// connected. If a launch task is pending, it will fire immediately.
//
// Returns true if the process is successfully connected; false otherwise.
bool WaitForLaunch();
// Inform the process that it should clean up its resources and shut
// down. This initiates an asynchronous shutdown sequence. After this
// method returns, it is safe for the caller to forget its pointer to
// the RDDProcessHost.
//
// After this returns, the attached Listener is no longer used.
void Shutdown();
// Return the actor for the top-level actor of the process. If the process
// has not connected yet, this returns null.
RDDChild* GetActor() const {
return mRDDChild.get();
}
// Return a unique id for this process, guaranteed not to be shared with any
// past or future instance of RDDProcessHost.
uint64_t GetProcessToken() const;
bool IsConnected() const {
return !!mRDDChild;
}
// Return the time stamp for when we tried to launch the RDD process.
// This is currently used for Telemetry so that we can determine how
// long RDD processes take to spin up. Note this doesn't denote a
// successful launch, just when we attempted launch.
TimeStamp GetLaunchTime() const {
return mLaunchTime;
}
// Called on the IO thread.
void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
void SetListener(Listener* aListener);
// Used for tests and diagnostics
void KillProcess();
private:
// Called on the main thread.
void OnChannelConnectedTask();
void OnChannelErrorTask();
// Called on the main thread after a connection has been established.
void InitAfterConnect(bool aSucceeded);
// Called on the main thread when the mRDDChild actor is shutting down.
void OnChannelClosed();
// Kill the remote process, triggering IPC shutdown.
void KillHard(const char* aReason);
void DestroyProcess();
private:
DISALLOW_COPY_AND_ASSIGN(RDDProcessHost);
Listener* mListener;
mozilla::ipc::TaskFactory<RDDProcessHost> mTaskFactory;
enum class LaunchPhase {
Unlaunched,
Waiting,
Complete
};
LaunchPhase mLaunchPhase;
UniquePtr<RDDChild> mRDDChild;
uint64_t mProcessToken;
bool mShutdownRequested;
bool mChannelClosed;
TimeStamp mLaunchTime;
};
} // namespace mozilla
#endif // _include_dom_media_ipc_RDDProcessHost_h_

View File

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RDDProcessImpl.h"
#include "mozilla/ipc/IOThreadChild.h"
#if defined(OS_WIN) && defined(MOZ_SANDBOX)
#include "mozilla/sandboxTarget.h"
#endif
namespace mozilla {
using namespace ipc;
RDDProcessImpl::RDDProcessImpl(ProcessId aParentPid)
: ProcessChild(aParentPid)
{
}
RDDProcessImpl::~RDDProcessImpl()
{
}
bool
RDDProcessImpl::Init(int aArgc, char* aArgv[])
{
#if defined(MOZ_SANDBOX) && defined(OS_WIN)
mozilla::SandboxTarget::Instance()->StartSandbox();
#endif
char* parentBuildID = nullptr;
for (int i = 1; i < aArgc; i++) {
if (strcmp(aArgv[i], "-parentBuildID") == 0) {
parentBuildID = aArgv[i + 1];
}
}
return mRDD.Init(ParentPid(),
parentBuildID,
IOThreadChild::message_loop(),
IOThreadChild::channel());
}
void
RDDProcessImpl::CleanUp()
{
NS_ShutdownXPCOM(nullptr);
}
} // namespace mozilla

View File

@ -1,42 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_dom_media_ipc_RDDProcessImpl_h__
#define _include_dom_media_ipc_RDDProcessImpl_h__
#include "mozilla/ipc/ProcessChild.h"
#if defined(XP_WIN)
# include "mozilla/mscom/MainThreadRuntime.h"
#endif
#include "RDDParent.h"
namespace mozilla {
// This class owns the subprocess instance of a PRDD - which in this case,
// is a RDDParent. It is instantiated as a singleton in XRE_InitChildProcess.
class RDDProcessImpl final : public ipc::ProcessChild
{
public:
explicit RDDProcessImpl(ProcessId aParentPid);
~RDDProcessImpl();
bool Init(int aArgc, char* aArgv[]) override;
void CleanUp() override;
private:
DISALLOW_COPY_AND_ASSIGN(RDDProcessImpl);
RDDParent mRDD;
#if defined(XP_WIN)
// This object initializes and configures COM.
mozilla::mscom::MainThreadRuntime mCOMRuntime;
#endif
};
} // namespace mozilla
#endif // _include_dom_media_ipc_RDDProcessImpl_h__

View File

@ -1,317 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RDDProcessManager.h"
#include "mozilla/RemoteDecoderManagerChild.h"
#include "mozilla/RemoteDecoderManagerParent.h"
#include "mozilla/StaticPrefs.h"
#include "mozilla/dom/ContentParent.h"
#include "nsAppRunner.h"
#include "nsContentUtils.h"
#include "RDDChild.h"
#include "RDDProcessHost.h"
namespace mozilla {
using namespace mozilla::layers;
static StaticAutoPtr<RDDProcessManager> sRDDSingleton;
RDDProcessManager*
RDDProcessManager::Get()
{
return sRDDSingleton;
}
void
RDDProcessManager::Initialize()
{
MOZ_ASSERT(XRE_IsParentProcess());
sRDDSingleton = new RDDProcessManager();
}
void
RDDProcessManager::Shutdown()
{
sRDDSingleton = nullptr;
}
RDDProcessManager::RDDProcessManager()
: mTaskFactory(this),
mNumProcessAttempts(0),
mProcess(nullptr),
mProcessToken(0),
mRDDChild(nullptr)
{
MOZ_COUNT_CTOR(RDDProcessManager);
mObserver = new Observer(this);
nsContentUtils::RegisterShutdownObserver(mObserver);
}
RDDProcessManager::~RDDProcessManager()
{
MOZ_COUNT_DTOR(RDDProcessManager);
// The RDD process should have already been shut down.
MOZ_ASSERT(!mProcess && !mRDDChild);
// We should have already removed observers.
MOZ_ASSERT(!mObserver);
}
NS_IMPL_ISUPPORTS(RDDProcessManager::Observer, nsIObserver);
RDDProcessManager::Observer::Observer(RDDProcessManager* aManager)
: mManager(aManager)
{
}
NS_IMETHODIMP
RDDProcessManager::Observer::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
mManager->OnXPCOMShutdown();
}
return NS_OK;
}
void
RDDProcessManager::OnXPCOMShutdown()
{
if (mObserver) {
nsContentUtils::UnregisterShutdownObserver(mObserver);
mObserver = nullptr;
}
CleanShutdown();
}
void
RDDProcessManager::LaunchRDDProcess()
{
if (mProcess) {
return;
}
mNumProcessAttempts++;
std::vector<std::string> extraArgs;
nsCString parentBuildID(mozilla::PlatformBuildID());
extraArgs.push_back("-parentBuildID");
extraArgs.push_back(parentBuildID.get());
// The subprocess is launched asynchronously, so we wait for a callback to
// acquire the IPDL actor.
mProcess = new RDDProcessHost(this);
if (!mProcess->Launch(extraArgs)) {
DestroyProcess();
}
}
bool
RDDProcessManager::EnsureRDDReady()
{
if (mProcess && !mProcess->IsConnected()) {
if (!mProcess->WaitForLaunch()) {
// If this fails, we should have fired OnProcessLaunchComplete and
// removed the process.
MOZ_ASSERT(!mProcess && !mRDDChild);
return false;
}
}
if (mRDDChild) {
if (mRDDChild->EnsureRDDReady()) {
return true;
}
// If the initialization above fails, we likely have a RDD process teardown
// waiting in our message queue (or will soon).
DestroyProcess();
}
return false;
}
void
RDDProcessManager::OnProcessLaunchComplete(RDDProcessHost* aHost)
{
MOZ_ASSERT(mProcess && mProcess == aHost);
if (!mProcess->IsConnected()) {
DestroyProcess();
return;
}
mRDDChild = mProcess->GetActor();
mProcessToken = mProcess->GetProcessToken();
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::RDDProcessStatus,
NS_LITERAL_CSTRING("Running"));
}
void
RDDProcessManager::OnProcessUnexpectedShutdown(RDDProcessHost* aHost)
{
MOZ_ASSERT(mProcess && mProcess == aHost);
DestroyProcess();
}
void
RDDProcessManager::NotifyRemoteActorDestroyed(const uint64_t& aProcessToken)
{
if (!NS_IsMainThread()) {
RefPtr<Runnable> task = mTaskFactory.NewRunnableMethod(
&RDDProcessManager::NotifyRemoteActorDestroyed, aProcessToken);
NS_DispatchToMainThread(task.forget());
return;
}
if (mProcessToken != aProcessToken) {
// This token is for an older process; we can safely ignore it.
return;
}
// One of the bridged top-level actors for the RDD process has been
// prematurely terminated, and we're receiving a notification. This
// can happen if the ActorDestroy for a bridged protocol fires
// before the ActorDestroy for PRDDChild.
OnProcessUnexpectedShutdown(mProcess);
}
void
RDDProcessManager::CleanShutdown()
{
DestroyProcess();
}
void
RDDProcessManager::KillProcess()
{
if (!mProcess) {
return;
}
mProcess->KillProcess();
}
void
RDDProcessManager::DestroyProcess()
{
if (!mProcess) {
return;
}
mProcess->Shutdown();
mProcessToken = 0;
mProcess = nullptr;
mRDDChild = nullptr;
CrashReporter::AnnotateCrashReport(
CrashReporter::Annotation::RDDProcessStatus,
NS_LITERAL_CSTRING("Destroyed"));
}
bool
RDDProcessManager::CreateContentBridge(
base::ProcessId aOtherProcess,
ipc::Endpoint<PRemoteDecoderManagerChild>* aOutRemoteDecoderManager)
{
if (!EnsureRDDReady() ||
!StaticPrefs::MediaRddProcessEnabled()) {
return false;
}
ipc::Endpoint<PRemoteDecoderManagerParent> parentPipe;
ipc::Endpoint<PRemoteDecoderManagerChild> childPipe;
nsresult rv = PRemoteDecoderManager::CreateEndpoints(
mRDDChild->OtherPid(),
aOtherProcess,
&parentPipe,
&childPipe);
if (NS_FAILED(rv)) {
MOZ_LOG(sPDMLog,
LogLevel::Debug,
("Could not create content remote decoder: %d", int(rv)));
return false;
}
mRDDChild->SendNewContentRemoteDecoderManager(std::move(parentPipe));
*aOutRemoteDecoderManager = std::move(childPipe);
return true;
}
base::ProcessId
RDDProcessManager::RDDProcessPid()
{
base::ProcessId rddPid = mRDDChild
? mRDDChild->OtherPid()
: -1;
return rddPid;
}
class RDDMemoryReporter : public MemoryReportingProcess
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RDDMemoryReporter, override)
bool IsAlive() const override {
return !!GetChild();
}
bool SendRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
const dom::MaybeFileDesc& aDMDFile) override
{
RDDChild* child = GetChild();
if (!child) {
return false;
}
return child->SendRequestMemoryReport(
aGeneration, aAnonymize, aMinimizeMemoryUsage, aDMDFile);
}
int32_t Pid() const override {
if (RDDChild* child = GetChild()) {
return (int32_t)child->OtherPid();
}
return 0;
}
private:
RDDChild* GetChild() const {
if (RDDProcessManager* rddpm = RDDProcessManager::Get()) {
if (RDDChild* child = rddpm->GetRDDChild()) {
return child;
}
}
return nullptr;
}
protected:
~RDDMemoryReporter() = default;
};
RefPtr<MemoryReportingProcess>
RDDProcessManager::GetProcessMemoryReporter()
{
if (!EnsureRDDReady()) {
return nullptr;
}
return new RDDMemoryReporter();
}
} // namespace mozilla

View File

@ -1,108 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_dom_media_ipc_RDDProcessManager_h_
#define _include_dom_media_ipc_RDDProcessManager_h_
#include "mozilla/RDDProcessHost.h"
#include "mozilla/ipc/TaskFactory.h"
namespace mozilla {
class MemoryReportingProcess;
class PRemoteDecoderManagerChild;
class RDDChild;
// The RDDProcessManager is a singleton responsible for creating RDD-bound
// objects that may live in another process. Currently, it provides access
// to the RDD process via ContentParent.
class RDDProcessManager final : public RDDProcessHost::Listener
{
public:
static void Initialize();
static void Shutdown();
static RDDProcessManager* Get();
~RDDProcessManager();
// If not using a RDD process, launch a new RDD process asynchronously.
void LaunchRDDProcess();
// Ensure that RDD-bound methods can be used. If no RDD process is being
// used, or one is launched and ready, this function returns immediately.
// Otherwise it blocks until the RDD process has finished launching.
bool EnsureRDDReady();
bool CreateContentBridge(
base::ProcessId aOtherProcess,
mozilla::ipc::Endpoint<PRemoteDecoderManagerChild>*
aOutRemoteDecoderManager);
void OnProcessLaunchComplete(RDDProcessHost* aHost) override;
void OnProcessUnexpectedShutdown(RDDProcessHost* aHost) override;
// Notify the RDDProcessManager that a top-level PRDD protocol has been
// terminated. This may be called from any thread.
void NotifyRemoteActorDestroyed(const uint64_t& aProcessToken);
// Used for tests and diagnostics
void KillProcess();
// Returns -1 if there is no RDD process, or the platform pid for it.
base::ProcessId RDDProcessPid();
// If a RDD process is present, create a MemoryReportingProcess object.
// Otherwise, return null.
RefPtr<MemoryReportingProcess> GetProcessMemoryReporter();
// Returns access to the PRDD protocol if a RDD process is present.
RDDChild* GetRDDChild() {
return mRDDChild;
}
// Returns whether or not a RDD process was ever launched.
bool AttemptedRDDProcess() const {
return mNumProcessAttempts > 0;
}
private:
// Called from our xpcom-shutdown observer.
void OnXPCOMShutdown();
RDDProcessManager();
// Shutdown the RDD process.
void CleanShutdown();
void DestroyProcess();
DISALLOW_COPY_AND_ASSIGN(RDDProcessManager);
class Observer final : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
explicit Observer(RDDProcessManager* aManager);
protected:
~Observer() {}
RDDProcessManager* mManager;
};
friend class Observer;
private:
RefPtr<Observer> mObserver;
mozilla::ipc::TaskFactory<RDDProcessManager> mTaskFactory;
uint32_t mNumProcessAttempts;
// Fields that are associated with the current RDD process.
RDDProcessHost* mProcess;
uint64_t mProcessToken;
RDDChild* mRDDChild;
};
} // namespace mozilla
#endif // _include_dom_media_ipc_RDDProcessManager_h_

View File

@ -1,151 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteDecoderManagerChild.h"
#include "base/task.h"
#include "RemoteVideoDecoderChild.h"
namespace mozilla {
// Only modified on the main-thread
StaticRefPtr<nsIThread> sRemoteDecoderManagerChildThread;
StaticRefPtr<AbstractThread> sRemoteDecoderManagerChildAbstractThread;
// Only accessed from sRemoteDecoderManagerChildThread
static StaticRefPtr<RemoteDecoderManagerChild> sRemoteDecoderManagerChild;
/* static */ void
RemoteDecoderManagerChild::InitializeThread()
{
MOZ_ASSERT(NS_IsMainThread());
if (!sRemoteDecoderManagerChildThread) {
RefPtr<nsIThread> childThread;
nsresult rv = NS_NewNamedThread("RemVidChild", getter_AddRefs(childThread));
NS_ENSURE_SUCCESS_VOID(rv);
sRemoteDecoderManagerChildThread = childThread;
sRemoteDecoderManagerChildAbstractThread =
AbstractThread::CreateXPCOMThreadWrapper(childThread, false);
}
}
/* static */ void
RemoteDecoderManagerChild::InitForContent(
Endpoint<PRemoteDecoderManagerChild>&& aVideoManager)
{
InitializeThread();
sRemoteDecoderManagerChildThread->Dispatch(
NewRunnableFunction("InitForContentRunnable",
&Open,
std::move(aVideoManager)),
NS_DISPATCH_NORMAL);
}
/* static */ void
RemoteDecoderManagerChild::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
if (sRemoteDecoderManagerChildThread) {
sRemoteDecoderManagerChildThread->Dispatch(
NS_NewRunnableFunction("dom::RemoteDecoderManagerChild::Shutdown",
[]() {
if (sRemoteDecoderManagerChild &&
sRemoteDecoderManagerChild->CanSend()) {
sRemoteDecoderManagerChild->Close();
sRemoteDecoderManagerChild = nullptr;
}
}),
NS_DISPATCH_NORMAL);
sRemoteDecoderManagerChildAbstractThread = nullptr;
sRemoteDecoderManagerChildThread->Shutdown();
sRemoteDecoderManagerChildThread = nullptr;
}
}
/* static */ RemoteDecoderManagerChild*
RemoteDecoderManagerChild::GetSingleton()
{
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
return sRemoteDecoderManagerChild;
}
/* static */ nsIThread*
RemoteDecoderManagerChild::GetManagerThread()
{
return sRemoteDecoderManagerChildThread;
}
/* static */ AbstractThread*
RemoteDecoderManagerChild::GetManagerAbstractThread()
{
return sRemoteDecoderManagerChildAbstractThread;
}
PRemoteVideoDecoderChild*
RemoteDecoderManagerChild::AllocPRemoteVideoDecoderChild(
const VideoInfo& /* not used */,
const float& /* not used */,
const CreateDecoderParams::OptionSet& /* not used */,
bool* /* not used */,
nsCString* /* not used */)
{
return new RemoteVideoDecoderChild();
}
bool
RemoteDecoderManagerChild::DeallocPRemoteVideoDecoderChild(
PRemoteVideoDecoderChild* actor)
{
RemoteVideoDecoderChild* child = static_cast<RemoteVideoDecoderChild*>(actor);
child->IPDLActorDestroyed();
return true;
}
void
RemoteDecoderManagerChild::Open(
Endpoint<PRemoteDecoderManagerChild>&& aEndpoint)
{
sRemoteDecoderManagerChild = nullptr;
if (aEndpoint.IsValid()) {
RefPtr<RemoteDecoderManagerChild> manager = new RemoteDecoderManagerChild();
if (aEndpoint.Bind(manager)) {
sRemoteDecoderManagerChild = manager;
manager->InitIPDL();
}
}
}
void
RemoteDecoderManagerChild::InitIPDL()
{
mCanSend = true;
mIPDLSelfRef = this;
}
void
RemoteDecoderManagerChild::ActorDestroy(ActorDestroyReason aWhy)
{
mCanSend = false;
}
void
RemoteDecoderManagerChild::DeallocPRemoteDecoderManagerChild()
{
mIPDLSelfRef = nullptr;
}
bool
RemoteDecoderManagerChild::CanSend()
{
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
return mCanSend;
}
} // namespace mozilla

View File

@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_media_ipc_RemoteDecoderManagerChild_h
#define include_dom_media_ipc_RemoteDecoderManagerChild_h
#include "mozilla/PRemoteDecoderManagerChild.h"
namespace mozilla {
class RemoteDecoderManagerChild final : public PRemoteDecoderManagerChild
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteDecoderManagerChild)
// Can only be called from the manager thread
static RemoteDecoderManagerChild* GetSingleton();
// Can be called from any thread.
static nsIThread* GetManagerThread();
static AbstractThread* GetManagerAbstractThread();
// Main thread only
static void InitForContent(
Endpoint<PRemoteDecoderManagerChild>&& aVideoManager);
static void Shutdown();
bool CanSend();
protected:
void InitIPDL();
void ActorDestroy(ActorDestroyReason aWhy) override;
void DeallocPRemoteDecoderManagerChild() override;
PRemoteVideoDecoderChild* AllocPRemoteVideoDecoderChild(
const VideoInfo& aVideoInfo,
const float& aFramerate,
const CreateDecoderParams::OptionSet& aOptions,
bool* aSuccess,
nsCString* aErrorDescription) override;
bool DeallocPRemoteVideoDecoderChild(
PRemoteVideoDecoderChild* actor) override;
private:
// Main thread only
static void InitializeThread();
RemoteDecoderManagerChild() = default;
~RemoteDecoderManagerChild() = default;
static void Open(Endpoint<PRemoteDecoderManagerChild>&& aEndpoint);
RefPtr<RemoteDecoderManagerChild> mIPDLSelfRef;
// Should only ever be accessed on the manager thread.
bool mCanSend = false;
};
} // namespace mozilla
#endif // include_dom_media_ipc_RemoteDecoderManagerChild_h

View File

@ -1,216 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteDecoderManagerParent.h"
#if XP_WIN
#include <objbase.h>
#endif
#include "RemoteVideoDecoderParent.h"
#include "VideoUtils.h" // for MediaThreadType
namespace mozilla {
StaticRefPtr<nsIThread> sRemoteDecoderManagerParentThread;
StaticRefPtr<TaskQueue> sRemoteDecoderManagerTaskQueue;
class RemoteDecoderManagerThreadHolder
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteDecoderManagerThreadHolder)
public:
RemoteDecoderManagerThreadHolder() { }
private:
~RemoteDecoderManagerThreadHolder()
{
NS_DispatchToMainThread(NS_NewRunnableFunction(
"dom::RemoteDecoderManagerThreadHolder::~RemoteDecoderManagerThreadHolder",
[]() {
sRemoteDecoderManagerParentThread->Shutdown();
sRemoteDecoderManagerParentThread = nullptr;
}));
}
};
StaticRefPtr<RemoteDecoderManagerThreadHolder>
sRemoteDecoderManagerParentThreadHolder;
class RemoteDecoderManagerThreadShutdownObserver : public nsIObserver
{
virtual ~RemoteDecoderManagerThreadShutdownObserver() = default;
public:
RemoteDecoderManagerThreadShutdownObserver() = default;
NS_DECL_ISUPPORTS
NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) override
{
MOZ_ASSERT(strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0);
RemoteDecoderManagerParent::ShutdownThreads();
return NS_OK;
}
};
NS_IMPL_ISUPPORTS(RemoteDecoderManagerThreadShutdownObserver, nsIObserver);
bool
RemoteDecoderManagerParent::StartupThreads()
{
MOZ_ASSERT(NS_IsMainThread());
if (sRemoteDecoderManagerParentThread) {
return true;
}
nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
if (!observerService) {
return false;
}
RefPtr<nsIThread> managerThread;
nsresult rv =
NS_NewNamedThread("RemVidParent", getter_AddRefs(managerThread));
if (NS_FAILED(rv)) {
return false;
}
sRemoteDecoderManagerParentThread = managerThread;
sRemoteDecoderManagerParentThreadHolder =
new RemoteDecoderManagerThreadHolder();
#if XP_WIN
sRemoteDecoderManagerParentThread->Dispatch(
NS_NewRunnableFunction(
"RemoteDecoderManagerParent::StartupThreads",
[]() {
DebugOnly<HRESULT> hr = CoInitializeEx(0, COINIT_MULTITHREADED);
MOZ_ASSERT(SUCCEEDED(hr));
}),
NS_DISPATCH_NORMAL);
#endif
sRemoteDecoderManagerTaskQueue = new TaskQueue(
managerThread.forget(),
"RemoteDecoderManagerParent::sRemoteDecoderManagerTaskQueue");
auto* obs = new RemoteDecoderManagerThreadShutdownObserver();
observerService->AddObserver(obs, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
return true;
}
void
RemoteDecoderManagerParent::ShutdownThreads()
{
sRemoteDecoderManagerTaskQueue = nullptr;
sRemoteDecoderManagerParentThreadHolder = nullptr;
while (sRemoteDecoderManagerParentThread) {
NS_ProcessNextEvent(nullptr, true);
}
}
bool
RemoteDecoderManagerParent::OnManagerThread()
{
return NS_GetCurrentThread() == sRemoteDecoderManagerParentThread;
}
bool
RemoteDecoderManagerParent::CreateForContent(
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint)
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_RDD);
MOZ_ASSERT(NS_IsMainThread());
if (!StartupThreads()) {
return false;
}
RefPtr<RemoteDecoderManagerParent> parent =
new RemoteDecoderManagerParent(sRemoteDecoderManagerParentThreadHolder);
RefPtr<Runnable> task =
NewRunnableMethod<Endpoint<PRemoteDecoderManagerParent>&&>(
"dom::RemoteDecoderManagerParent::Open",
parent,
&RemoteDecoderManagerParent::Open,
std::move(aEndpoint));
sRemoteDecoderManagerParentThread->Dispatch(task.forget(),
NS_DISPATCH_NORMAL);
return true;
}
RemoteDecoderManagerParent::RemoteDecoderManagerParent(
RemoteDecoderManagerThreadHolder* aHolder)
: mThreadHolder(aHolder)
{
MOZ_COUNT_CTOR(RemoteDecoderManagerParent);
}
RemoteDecoderManagerParent::~RemoteDecoderManagerParent()
{
MOZ_COUNT_DTOR(RemoteDecoderManagerParent);
}
void
RemoteDecoderManagerParent::ActorDestroy(
mozilla::ipc::IProtocol::ActorDestroyReason)
{
mThreadHolder = nullptr;
}
PRemoteVideoDecoderParent*
RemoteDecoderManagerParent::AllocPRemoteVideoDecoderParent(
const VideoInfo& aVideoInfo,
const float& aFramerate,
const CreateDecoderParams::OptionSet& aOptions,
bool* aSuccess,
nsCString* aErrorDescription)
{
RefPtr<TaskQueue> decodeTaskQueue = new TaskQueue(
GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER),
"RemoteVideoDecoderParent::mDecodeTaskQueue");
auto* parent = new RemoteVideoDecoderParent(this,
aVideoInfo,
aFramerate,
aOptions,
sRemoteDecoderManagerTaskQueue,
decodeTaskQueue,
aSuccess,
aErrorDescription);
return parent;
}
bool
RemoteDecoderManagerParent::DeallocPRemoteVideoDecoderParent(
PRemoteVideoDecoderParent* actor)
{
RemoteVideoDecoderParent* parent =
static_cast<RemoteVideoDecoderParent*>(actor);
parent->Destroy();
return true;
}
void
RemoteDecoderManagerParent::Open(
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint)
{
if (!aEndpoint.Bind(this)) {
// We can't recover from this.
MOZ_CRASH("Failed to bind RemoteDecoderManagerParent to endpoint");
}
AddRef();
}
void
RemoteDecoderManagerParent::DeallocPRemoteDecoderManagerParent()
{
Release();
}
} // namespace mozilla

View File

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_media_ipc_RemoteDecoderManagerParent_h
#define include_dom_media_ipc_RemoteDecoderManagerParent_h
#include "mozilla/PRemoteDecoderManagerParent.h"
namespace mozilla {
class RemoteDecoderManagerThreadHolder;
class RemoteDecoderManagerParent final : public PRemoteDecoderManagerParent
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteDecoderManagerParent)
static bool CreateForContent(
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint);
static bool StartupThreads();
static void ShutdownThreads();
bool OnManagerThread();
protected:
PRemoteVideoDecoderParent* AllocPRemoteVideoDecoderParent(
const VideoInfo& aVideoInfo,
const float& aFramerate,
const CreateDecoderParams::OptionSet& aOptions,
bool* aSuccess,
nsCString* aErrorDescription) override;
bool DeallocPRemoteVideoDecoderParent(
PRemoteVideoDecoderParent* actor) override;
void ActorDestroy(mozilla::ipc::IProtocol::ActorDestroyReason) override;
void DeallocPRemoteDecoderManagerParent() override;
private:
explicit RemoteDecoderManagerParent(
RemoteDecoderManagerThreadHolder* aThreadHolder);
~RemoteDecoderManagerParent();
void Open(Endpoint<PRemoteDecoderManagerParent>&& aEndpoint);
RefPtr<RemoteDecoderManagerThreadHolder> mThreadHolder;
};
} // namespace mozilla
#endif // include_dom_media_ipc_RemoteDecoderManagerParent_h

View File

@ -1,88 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteDecoderModule.h"
#include "base/thread.h"
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/StaticPrefs.h"
#ifdef MOZ_AV1
#include "AOMDecoder.h"
#endif
#include "RemoteDecoderManagerChild.h"
#include "RemoteMediaDataDecoder.h"
#include "RemoteVideoDecoderChild.h"
namespace mozilla {
using base::Thread;
using namespace ipc;
using namespace layers;
nsresult
RemoteDecoderModule::Startup()
{
if (!RemoteDecoderManagerChild::GetManagerThread()) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
bool
RemoteDecoderModule::SupportsMimeType(
const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const
{
bool supports = false;
#ifdef MOZ_AV1
if (StaticPrefs::MediaAv1Enabled()) {
supports |= AOMDecoder::IsAV1(aMimeType);
}
#endif
MOZ_LOG(sPDMLog, LogLevel::Debug, ("Sandbox decoder %s requested type",
supports ? "supports" : "rejects"));
return supports;
}
already_AddRefed<MediaDataDecoder>
RemoteDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
{
RemoteVideoDecoderChild* child = new RemoteVideoDecoderChild();
RefPtr<RemoteMediaDataDecoder> object =
new RemoteMediaDataDecoder(
child,
RemoteDecoderManagerChild::GetManagerThread(),
RemoteDecoderManagerChild::GetManagerAbstractThread());
// (per Matt Woodrow) We can't use NS_DISPATCH_SYNC here since that
// can spin the event loop while it waits.
SynchronousTask task("InitIPDL");
MediaResult result(NS_OK);
RemoteDecoderManagerChild::GetManagerThread()->Dispatch(
NS_NewRunnableFunction(
"dom::RemoteDecoderModule::CreateVideoDecoder",
[&, child]() {
AutoCompleteTask complete(&task);
result = child->InitIPDL(
aParams.VideoConfig(),
aParams.mRate.mValue,
aParams.mOptions);
}),
NS_DISPATCH_NORMAL);
task.Wait();
if (NS_FAILED(result)) {
if (aParams.mError) {
*aParams.mError = result;
}
return nullptr;
}
return object.forget();
}
} // namespace mozilla

View File

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_media_ipc_RemoteDecoderModule_h
#define include_dom_media_ipc_RemoteDecoderModule_h
#include "PlatformDecoderModule.h"
namespace mozilla {
// A PDM implementation that creates a RemoteMediaDataDecoder (a
// MediaDataDecoder) that proxies to a RemoteVideoDecoderChild.
// A decoder child will talk to its respective decoder parent
// (RemoteVideoDecoderParent) on the RDD process.
class RemoteDecoderModule : public PlatformDecoderModule
{
public:
RemoteDecoderModule() = default;
nsresult Startup() override;
bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override;
already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
const CreateDecoderParams& aParams) override;
already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
const CreateDecoderParams& aParams) override
{
return nullptr;
}
};
} // namespace mozilla
#endif // include_dom_media_ipc_RemoteDecoderModule_h

View File

@ -1,140 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteMediaDataDecoder.h"
#include "base/thread.h"
#include "IRemoteDecoderChild.h"
namespace mozilla {
using base::Thread;
RemoteMediaDataDecoder::RemoteMediaDataDecoder(
IRemoteDecoderChild* aChild,
nsIThread* aManagerThread,
AbstractThread* aAbstractManagerThread)
: mChild(aChild)
, mManagerThread(aManagerThread)
, mAbstractManagerThread(aAbstractManagerThread)
{
}
RemoteMediaDataDecoder::~RemoteMediaDataDecoder()
{
// We're about to be destroyed and drop our ref to
// *DecoderChild. Make sure we put a ref into the
// task queue for the *DecoderChild thread to keep
// it alive until we send the delete message.
RefPtr<IRemoteDecoderChild> child = mChild.forget();
RefPtr<Runnable> task = NS_NewRunnableFunction(
"dom::RemoteMediaDataDecoder::~RemoteMediaDataDecoder", [child]() {
MOZ_ASSERT(child);
child->DestroyIPDL();
});
// Drop our references to the child so that the last ref
// always gets released on the manager thread.
child = nullptr;
mManagerThread->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
}
RefPtr<MediaDataDecoder::InitPromise>
RemoteMediaDataDecoder::Init()
{
RefPtr<RemoteMediaDataDecoder> self = this;
return InvokeAsync(mAbstractManagerThread,
__func__,
[self]() { return self->mChild->Init(); })
->Then(mAbstractManagerThread,
__func__,
[self, this](TrackType aTrack) {
mDescription =
mChild->GetDescriptionName() + NS_LITERAL_CSTRING(" (remote)");
mIsHardwareAccelerated =
mChild->IsHardwareAccelerated(mHardwareAcceleratedReason);
mConversion = mChild->NeedsConversion();
return InitPromise::CreateAndResolve(aTrack, __func__);
},
[self](const MediaResult& aError) {
return InitPromise::CreateAndReject(aError, __func__);
});
}
RefPtr<MediaDataDecoder::DecodePromise>
RemoteMediaDataDecoder::Decode(MediaRawData* aSample)
{
RefPtr<RemoteMediaDataDecoder> self = this;
RefPtr<MediaRawData> sample = aSample;
return InvokeAsync(mAbstractManagerThread, __func__, [self, sample]() {
return self->mChild->Decode(sample);
});
}
RefPtr<MediaDataDecoder::FlushPromise>
RemoteMediaDataDecoder::Flush()
{
RefPtr<RemoteMediaDataDecoder> self = this;
return InvokeAsync(mAbstractManagerThread, __func__, [self]() {
return self->mChild->Flush();
});
}
RefPtr<MediaDataDecoder::DecodePromise>
RemoteMediaDataDecoder::Drain()
{
RefPtr<RemoteMediaDataDecoder> self = this;
return InvokeAsync(mAbstractManagerThread, __func__, [self]() {
return self->mChild->Drain();
});
}
RefPtr<ShutdownPromise>
RemoteMediaDataDecoder::Shutdown()
{
RefPtr<RemoteMediaDataDecoder> self = this;
return InvokeAsync(mAbstractManagerThread, __func__, [self]() {
self->mChild->Shutdown();
return ShutdownPromise::CreateAndResolve(true, __func__);
});
}
bool
RemoteMediaDataDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const
{
aFailureReason = mHardwareAcceleratedReason;
return mIsHardwareAccelerated;
}
void
RemoteMediaDataDecoder::SetSeekThreshold(const media::TimeUnit& aTime)
{
RefPtr<RemoteMediaDataDecoder> self = this;
media::TimeUnit time = aTime;
mManagerThread->Dispatch(
NS_NewRunnableFunction("dom::RemoteMediaDataDecoder::SetSeekThreshold",
[=]() {
MOZ_ASSERT(self->mChild);
self->mChild->SetSeekThreshold(time);
}),
NS_DISPATCH_NORMAL);
}
MediaDataDecoder::ConversionRequired
RemoteMediaDataDecoder::NeedsConversion() const
{
return mConversion;
}
nsCString
RemoteMediaDataDecoder::GetDescriptionName() const
{
return mDescription;
}
} // namespace mozilla

View File

@ -1,68 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_media_ipc_RemoteMediaDataDecoder_h
#define include_dom_media_ipc_RemoteMediaDataDecoder_h
#include "PlatformDecoderModule.h"
#include "MediaData.h"
namespace mozilla {
class GpuDecoderModule;
class IRemoteDecoderChild;
class RemoteDecoderModule;
class RemoteMediaDataDecoder;
DDLoggedTypeCustomNameAndBase(RemoteMediaDataDecoder,
RemoteMediaDataDecoder,
MediaDataDecoder);
// A MediaDataDecoder implementation that proxies through IPDL
// to a 'real' decoder in the GPU or RDD process.
// All requests get forwarded to a *DecoderChild instance that
// operates solely on the provided manager and abstract manager threads.
class RemoteMediaDataDecoder
: public MediaDataDecoder
, public DecoderDoctorLifeLogger<RemoteMediaDataDecoder>
{
public:
friend class GpuDecoderModule;
friend class RemoteDecoderModule;
// MediaDataDecoder
RefPtr<InitPromise> Init() override;
RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
RefPtr<DecodePromise> Drain() override;
RefPtr<FlushPromise> Flush() override;
RefPtr<ShutdownPromise> Shutdown() override;
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
void SetSeekThreshold(const media::TimeUnit& aTime) override;
nsCString GetDescriptionName() const override;
ConversionRequired NeedsConversion() const override;
private:
RemoteMediaDataDecoder(IRemoteDecoderChild* aChild,
nsIThread* aManagerThread,
AbstractThread* aAbstractManagerThread);
~RemoteMediaDataDecoder();
// Only ever written to from the reader task queue (during the constructor and
// destructor when we can guarantee no other threads are accessing it). Only
// read from the manager thread.
RefPtr<IRemoteDecoderChild> mChild;
nsIThread* mManagerThread;
AbstractThread* mAbstractManagerThread;
// Only ever written/modified during decoder initialisation.
// As such can be accessed from any threads after that.
nsCString mDescription = NS_LITERAL_CSTRING("RemoteMediaDataDecoder");
bool mIsHardwareAccelerated = false;
nsCString mHardwareAcceleratedReason;
ConversionRequired mConversion = ConversionRequired::kNeedNone;
};
} // namespace mozilla
#endif // include_dom_media_ipc_RemoteMediaDataDecoder_h

View File

@ -0,0 +1,218 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteVideoDecoder.h"
#include "VideoDecoderChild.h"
#include "VideoDecoderManagerChild.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/StaticPrefs.h"
#include "base/thread.h"
#include "MediaInfo.h"
#include "ImageContainer.h"
#include "mozilla/layers/SynchronousTask.h"
namespace mozilla {
namespace dom {
using base::Thread;
using namespace ipc;
using namespace layers;
using namespace gfx;
RemoteVideoDecoder::RemoteVideoDecoder()
: mActor(new VideoDecoderChild())
, mDescription("RemoteVideoDecoder")
, mIsHardwareAccelerated(false)
, mConversion(MediaDataDecoder::ConversionRequired::kNeedNone)
{
}
RemoteVideoDecoder::~RemoteVideoDecoder()
{
// We're about to be destroyed and drop our ref to
// VideoDecoderChild. Make sure we put a ref into the
// task queue for the VideoDecoderChild thread to keep
// it alive until we send the delete message.
RefPtr<VideoDecoderChild> actor = mActor;
RefPtr<Runnable> task = NS_NewRunnableFunction(
"dom::RemoteVideoDecoder::~RemoteVideoDecoder", [actor]() {
MOZ_ASSERT(actor);
actor->DestroyIPDL();
});
// Drop out references to the actor so that the last ref
// always gets released on the manager thread.
actor = nullptr;
mActor = nullptr;
VideoDecoderManagerChild::GetManagerThread()->Dispatch(task.forget(),
NS_DISPATCH_NORMAL);
}
RefPtr<MediaDataDecoder::InitPromise>
RemoteVideoDecoder::Init()
{
RefPtr<RemoteVideoDecoder> self = this;
return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
__func__,
[self]() { return self->mActor->Init(); })
->Then(VideoDecoderManagerChild::GetManagerAbstractThread(),
__func__,
[self, this](TrackType aTrack) {
mDescription =
mActor->GetDescriptionName() + NS_LITERAL_CSTRING(" (remote)");
mIsHardwareAccelerated =
mActor->IsHardwareAccelerated(mHardwareAcceleratedReason);
mConversion = mActor->NeedsConversion();
return InitPromise::CreateAndResolve(aTrack, __func__);
},
[self](const MediaResult& aError) {
return InitPromise::CreateAndReject(aError, __func__);
});
}
RefPtr<MediaDataDecoder::DecodePromise>
RemoteVideoDecoder::Decode(MediaRawData* aSample)
{
RefPtr<RemoteVideoDecoder> self = this;
RefPtr<MediaRawData> sample = aSample;
return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
__func__,
[self, sample]() { return self->mActor->Decode(sample); });
}
RefPtr<MediaDataDecoder::FlushPromise>
RemoteVideoDecoder::Flush()
{
RefPtr<RemoteVideoDecoder> self = this;
return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
__func__, [self]() { return self->mActor->Flush(); });
}
RefPtr<MediaDataDecoder::DecodePromise>
RemoteVideoDecoder::Drain()
{
RefPtr<RemoteVideoDecoder> self = this;
return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
__func__, [self]() { return self->mActor->Drain(); });
}
RefPtr<ShutdownPromise>
RemoteVideoDecoder::Shutdown()
{
RefPtr<RemoteVideoDecoder> self = this;
return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
__func__, [self]() {
self->mActor->Shutdown();
return ShutdownPromise::CreateAndResolve(true, __func__);
});
}
bool
RemoteVideoDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const
{
aFailureReason = mHardwareAcceleratedReason;
return mIsHardwareAccelerated;
}
void
RemoteVideoDecoder::SetSeekThreshold(const media::TimeUnit& aTime)
{
RefPtr<RemoteVideoDecoder> self = this;
media::TimeUnit time = aTime;
VideoDecoderManagerChild::GetManagerThread()->Dispatch(
NS_NewRunnableFunction("dom::RemoteVideoDecoder::SetSeekThreshold",
[=]() {
MOZ_ASSERT(self->mActor);
self->mActor->SetSeekThreshold(time);
}),
NS_DISPATCH_NORMAL);
}
MediaDataDecoder::ConversionRequired
RemoteVideoDecoder::NeedsConversion() const
{
return mConversion;
}
nsresult
RemoteDecoderModule::Startup()
{
if (!VideoDecoderManagerChild::GetManagerThread()) {
return NS_ERROR_FAILURE;
}
return mWrapped->Startup();
}
bool
RemoteDecoderModule::SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const
{
return mWrapped->SupportsMimeType(aMimeType, aDiagnostics);
}
bool
RemoteDecoderModule::Supports(const TrackInfo& aTrackInfo,
DecoderDoctorDiagnostics* aDiagnostics) const
{
return mWrapped->Supports(aTrackInfo, aDiagnostics);
}
static inline bool
IsRemoteAcceleratedCompositor(KnowsCompositor* aKnows)
{
TextureFactoryIdentifier ident = aKnows->GetTextureFactoryIdentifier();
return ident.mParentBackend != LayersBackend::LAYERS_BASIC &&
ident.mParentProcessType == GeckoProcessType_GPU;
}
already_AddRefed<MediaDataDecoder>
RemoteDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
{
if (!StaticPrefs::MediaGpuProcessDecoder() ||
!aParams.mKnowsCompositor ||
!IsRemoteAcceleratedCompositor(aParams.mKnowsCompositor))
{
return mWrapped->CreateVideoDecoder(aParams);
}
RefPtr<RemoteVideoDecoder> object = new RemoteVideoDecoder();
SynchronousTask task("InitIPDL");
MediaResult result(NS_OK);
VideoDecoderManagerChild::GetManagerThread()->Dispatch(
NS_NewRunnableFunction(
"dom::RemoteDecoderModule::CreateVideoDecoder",
[&]() {
AutoCompleteTask complete(&task);
result = object->mActor->InitIPDL(
aParams.VideoConfig(),
aParams.mRate.mValue,
aParams.mOptions,
aParams.mKnowsCompositor->GetTextureFactoryIdentifier());
}),
NS_DISPATCH_NORMAL);
task.Wait();
if (NS_FAILED(result)) {
if (aParams.mError) {
*aParams.mError = result;
}
return nullptr;
}
return object.forget();
}
nsCString
RemoteVideoDecoder::GetDescriptionName() const
{
return mDescription;
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_ipc_RemoteVideoDecoder_h
#define include_dom_ipc_RemoteVideoDecoder_h
#include "mozilla/RefPtr.h"
#include "mozilla/DebugOnly.h"
#include "MediaData.h"
#include "PlatformDecoderModule.h"
namespace mozilla {
namespace dom {
class RemoteVideoDecoder;
}
DDLoggedTypeCustomNameAndBase(dom::RemoteVideoDecoder,
RemoteVideoDecoder,
MediaDataDecoder);
namespace dom {
class VideoDecoderChild;
class RemoteDecoderModule;
// A MediaDataDecoder implementation that proxies through IPDL
// to a 'real' decoder in the GPU process.
// All requests get forwarded to a VideoDecoderChild instance that
// operates solely on the VideoDecoderManagerChild thread.
class RemoteVideoDecoder
: public MediaDataDecoder
, public DecoderDoctorLifeLogger<RemoteVideoDecoder>
{
public:
friend class RemoteDecoderModule;
// MediaDataDecoder
RefPtr<InitPromise> Init() override;
RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
RefPtr<DecodePromise> Drain() override;
RefPtr<FlushPromise> Flush() override;
RefPtr<ShutdownPromise> Shutdown() override;
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
void SetSeekThreshold(const media::TimeUnit& aTime) override;
nsCString GetDescriptionName() const override;
ConversionRequired NeedsConversion() const override;
private:
RemoteVideoDecoder();
~RemoteVideoDecoder();
// Only ever written to from the reader task queue (during the constructor and
// destructor when we can guarantee no other threads are accessing it). Only
// read from the manager thread.
RefPtr<VideoDecoderChild> mActor;
// Only ever written/modified during decoder initialisation.
// As such can be accessed from any threads after that.
nsCString mDescription;
bool mIsHardwareAccelerated;
nsCString mHardwareAcceleratedReason;
MediaDataDecoder::ConversionRequired mConversion;
};
// A PDM implementation that creates RemoteVideoDecoders.
// We currently require a 'wrapped' PDM in order to be able to answer SupportsMimeType
// and DecoderNeedsConversion. Ideally we'd check these over IPDL using the manager
// protocol
class RemoteDecoderModule : public PlatformDecoderModule
{
public:
explicit RemoteDecoderModule(PlatformDecoderModule* aWrapped)
: mWrapped(aWrapped)
{}
nsresult Startup() override;
bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override;
bool Supports(const TrackInfo& aTrackInfo,
DecoderDoctorDiagnostics* aDiagnostics) const override;
already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
const CreateDecoderParams& aParams) override;
already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
const CreateDecoderParams& aParams) override
{
return nullptr;
}
private:
RefPtr<PlatformDecoderModule> mWrapped;
};
} // namespace dom
} // namespace mozilla
#endif // include_dom_ipc_RemoteVideoDecoder_h

View File

@ -1,365 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteVideoDecoderChild.h"
#include "base/thread.h"
#include "mozilla/layers/ImageDataSerializer.h"
#include "ImageContainer.h" // for PlanarYCbCrData and BufferRecycleBin
#include "RemoteDecoderManagerChild.h"
namespace mozilla {
using base::Thread;
using namespace layers; // for PlanarYCbCrData and BufferRecycleBin
RemoteVideoDecoderChild::RemoteVideoDecoderChild()
: mThread(RemoteDecoderManagerChild::GetManagerThread())
, mCanSend(false)
, mInitialized(false)
, mIsHardwareAccelerated(false)
, mConversion(MediaDataDecoder::ConversionRequired::kNeedNone)
, mBufferRecycleBin(new BufferRecycleBin)
{
}
RemoteVideoDecoderChild::~RemoteVideoDecoderChild()
{
AssertOnManagerThread();
mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
}
RefPtr<mozilla::layers::Image>
RemoteVideoDecoderChild::DeserializeImage(
const SurfaceDescriptorBuffer& aSdBuffer,
const IntSize& aPicSize)
{
MOZ_ASSERT(aSdBuffer.desc().type() == BufferDescriptor::TYCbCrDescriptor);
if (aSdBuffer.desc().type() != BufferDescriptor::TYCbCrDescriptor) {
return nullptr;
}
const YCbCrDescriptor& descriptor = aSdBuffer.desc().get_YCbCrDescriptor();
uint8_t* buffer = nullptr;
const MemoryOrShmem& memOrShmem = aSdBuffer.data();
switch (memOrShmem.type()) {
case MemoryOrShmem::Tuintptr_t:
buffer = reinterpret_cast<uint8_t*>(memOrShmem.get_uintptr_t());
break;
case MemoryOrShmem::TShmem:
buffer = memOrShmem.get_Shmem().get<uint8_t>();
break;
default:
MOZ_ASSERT(false, "Unknown MemoryOrShmem type");
}
if (!buffer) {
return nullptr;
}
PlanarYCbCrData pData;
pData.mYSize = descriptor.ySize();
pData.mYStride = descriptor.yStride();
pData.mCbCrSize = descriptor.cbCrSize();
pData.mCbCrStride = descriptor.cbCrStride();
// default mYSkip, mCbSkip, mCrSkip because not held in YCbCrDescriptor
pData.mYSkip = pData.mCbSkip = pData.mCrSkip = 0;
// default mPicX, mPicY because not held in YCbCrDescriptor
pData.mPicX = pData.mPicY = 0;
pData.mPicSize = aPicSize;
pData.mStereoMode = descriptor.stereoMode();
pData.mColorDepth = descriptor.colorDepth();
pData.mYUVColorSpace = descriptor.yUVColorSpace();
pData.mYChannel = ImageDataSerializer::GetYChannel(buffer, descriptor);
pData.mCbChannel = ImageDataSerializer::GetCbChannel(buffer, descriptor);
pData.mCrChannel = ImageDataSerializer::GetCrChannel(buffer, descriptor);
// images coming from AOMDecoder are RecyclingPlanarYCbCrImages.
RefPtr<RecyclingPlanarYCbCrImage> image =
new RecyclingPlanarYCbCrImage(mBufferRecycleBin);
image->CopyData(pData);
switch (memOrShmem.type()) {
case MemoryOrShmem::Tuintptr_t:
delete [] reinterpret_cast<uint8_t*>(memOrShmem.get_uintptr_t());
break;
case MemoryOrShmem::TShmem:
DeallocShmem(memOrShmem.get_Shmem());
break;
default:
MOZ_ASSERT(false, "Unknown MemoryOrShmem type");
}
return image;
}
mozilla::ipc::IPCResult
RemoteVideoDecoderChild::RecvVideoOutput(const RemoteVideoDataIPDL& aData)
{
AssertOnManagerThread();
RefPtr<Image> image = DeserializeImage(aData.sdBuffer(), aData.frameSize());
RefPtr<VideoData> video = VideoData::CreateFromImage(
aData.display(),
aData.base().offset(),
media::TimeUnit::FromMicroseconds(aData.base().time()),
media::TimeUnit::FromMicroseconds(aData.base().duration()),
image,
aData.base().keyframe(),
media::TimeUnit::FromMicroseconds(aData.base().timecode()));
mDecodedData.AppendElement(std::move(video));
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderChild::RecvInputExhausted()
{
AssertOnManagerThread();
mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__);
mDecodedData = MediaDataDecoder::DecodedData();
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderChild::RecvDrainComplete()
{
AssertOnManagerThread();
mDrainPromise.ResolveIfExists(std::move(mDecodedData), __func__);
mDecodedData = MediaDataDecoder::DecodedData();
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderChild::RecvError(const nsresult& aError)
{
AssertOnManagerThread();
mDecodedData = MediaDataDecoder::DecodedData();
mDecodePromise.RejectIfExists(aError, __func__);
mDrainPromise.RejectIfExists(aError, __func__);
mFlushPromise.RejectIfExists(aError, __func__);
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderChild::RecvInitComplete(const nsCString& aDecoderDescription,
const ConversionRequired& aConversion)
{
AssertOnManagerThread();
mInitPromise.ResolveIfExists(TrackInfo::kVideoTrack, __func__);
mInitialized = true;
mDescription = aDecoderDescription;
mConversion = aConversion;
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderChild::RecvInitFailed(const nsresult& aReason)
{
AssertOnManagerThread();
mInitPromise.RejectIfExists(aReason, __func__);
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderChild::RecvFlushComplete()
{
AssertOnManagerThread();
mFlushPromise.ResolveIfExists(true, __func__);
return IPC_OK();
}
void
RemoteVideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy)
{
mCanSend = false;
}
MediaResult
RemoteVideoDecoderChild::InitIPDL(
const VideoInfo& aVideoInfo,
float aFramerate,
const CreateDecoderParams::OptionSet& aOptions)
{
RefPtr<RemoteDecoderManagerChild> manager =
RemoteDecoderManagerChild::GetSingleton();
// The manager isn't available because RemoteDecoderManagerChild has been
// initialized with null end points and we don't want to decode video on RDD
// process anymore. Return false here so that we can fallback to other PDMs.
if (!manager) {
return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("RemoteDecoderManager is not available."));
}
if (!manager->CanSend()) {
return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("RemoteDecoderManager unable to send."));
}
mIPDLSelfRef = this;
bool success = false;
nsCString errorDescription;
if (manager->SendPRemoteVideoDecoderConstructor(this,
aVideoInfo,
aFramerate,
aOptions,
&success,
&errorDescription)) {
mCanSend = true;
}
return success ? MediaResult(NS_OK) :
MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, errorDescription);
}
void
RemoteVideoDecoderChild::DestroyIPDL()
{
if (mCanSend) {
PRemoteVideoDecoderChild::Send__delete__(this);
}
}
void
RemoteVideoDecoderChild::IPDLActorDestroyed()
{
mIPDLSelfRef = nullptr;
}
// MediaDataDecoder methods
RefPtr<MediaDataDecoder::InitPromise>
RemoteVideoDecoderChild::Init()
{
AssertOnManagerThread();
if (!mIPDLSelfRef || !mCanSend) {
return MediaDataDecoder::InitPromise::CreateAndReject(
NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
}
SendInit();
return mInitPromise.Ensure(__func__);
}
RefPtr<MediaDataDecoder::DecodePromise>
RemoteVideoDecoderChild::Decode(MediaRawData* aSample)
{
AssertOnManagerThread();
if (!mCanSend) {
return MediaDataDecoder::DecodePromise::CreateAndReject(
NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
}
// TODO: It would be nice to add an allocator method to
// MediaDataDecoder so that the demuxer could write directly
// into shmem rather than requiring a copy here.
Shmem buffer;
if (!AllocShmem(aSample->Size(), Shmem::SharedMemory::TYPE_BASIC, &buffer)) {
return MediaDataDecoder::DecodePromise::CreateAndReject(
NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
}
memcpy(buffer.get<uint8_t>(), aSample->Data(), aSample->Size());
MediaRawDataIPDL sample(MediaDataIPDL(aSample->mOffset,
aSample->mTime.ToMicroseconds(),
aSample->mTimecode.ToMicroseconds(),
aSample->mDuration.ToMicroseconds(),
aSample->mFrames,
aSample->mKeyframe),
buffer);
SendInput(sample);
return mDecodePromise.Ensure(__func__);
}
RefPtr<MediaDataDecoder::FlushPromise>
RemoteVideoDecoderChild::Flush()
{
AssertOnManagerThread();
mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
mDrainPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
if (!mCanSend) {
return MediaDataDecoder::FlushPromise::CreateAndReject(
NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
}
SendFlush();
return mFlushPromise.Ensure(__func__);
}
RefPtr<MediaDataDecoder::DecodePromise>
RemoteVideoDecoderChild::Drain()
{
AssertOnManagerThread();
if (!mCanSend) {
return MediaDataDecoder::DecodePromise::CreateAndReject(
NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
}
SendDrain();
return mDrainPromise.Ensure(__func__);
}
void
RemoteVideoDecoderChild::Shutdown()
{
AssertOnManagerThread();
mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
if (mCanSend) {
SendShutdown();
}
mInitialized = false;
}
bool
RemoteVideoDecoderChild::IsHardwareAccelerated(nsACString& aFailureReason) const
{
AssertOnManagerThread();
aFailureReason = mHardwareAcceleratedReason;
return mIsHardwareAccelerated;
}
nsCString
RemoteVideoDecoderChild::GetDescriptionName() const
{
AssertOnManagerThread();
return mDescription;
}
void
RemoteVideoDecoderChild::SetSeekThreshold(const media::TimeUnit& aTime)
{
AssertOnManagerThread();
if (mCanSend) {
SendSetSeekThreshold(aTime.ToMicroseconds());
}
}
MediaDataDecoder::ConversionRequired
RemoteVideoDecoderChild::NeedsConversion() const
{
AssertOnManagerThread();
return mConversion;
}
void
RemoteVideoDecoderChild::AssertOnManagerThread() const
{
MOZ_ASSERT(NS_GetCurrentThread() == mThread);
}
RemoteDecoderManagerChild*
RemoteVideoDecoderChild::GetManager()
{
if (!mCanSend) {
return nullptr;
}
return static_cast<RemoteDecoderManagerChild*>(Manager());
}
} // namespace mozilla

View File

@ -1,94 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_media_ipc_RemoteVideoDecoderChild_h
#define include_dom_media_ipc_RemoteVideoDecoderChild_h
#include "mozilla/PRemoteVideoDecoderChild.h"
#include "IRemoteDecoderChild.h"
#include "MediaResult.h"
namespace mozilla {
namespace layers {
class BufferRecycleBin;
}
}
namespace mozilla {
class RemoteDecoderManagerChild;
using mozilla::MediaDataDecoder;
class RemoteVideoDecoderChild final : public PRemoteVideoDecoderChild
, public IRemoteDecoderChild
{
public:
explicit RemoteVideoDecoderChild();
// PRemoteVideoDecoderChild
mozilla::ipc::IPCResult RecvVideoOutput(
const RemoteVideoDataIPDL& aData) override;
mozilla::ipc::IPCResult RecvInputExhausted() override;
mozilla::ipc::IPCResult RecvDrainComplete() override;
mozilla::ipc::IPCResult RecvError(const nsresult& aError) override;
mozilla::ipc::IPCResult RecvInitComplete(
const nsCString& aDecoderDescription,
const ConversionRequired& aConversion) override;
mozilla::ipc::IPCResult RecvInitFailed(const nsresult& aReason) override;
mozilla::ipc::IPCResult RecvFlushComplete() override;
void ActorDestroy(ActorDestroyReason aWhy) override;
// IRemoteDecoderChild
RefPtr<MediaDataDecoder::InitPromise> Init() override;
RefPtr<MediaDataDecoder::DecodePromise> Decode(MediaRawData* aSample) override;
RefPtr<MediaDataDecoder::DecodePromise> Drain() override;
RefPtr<MediaDataDecoder::FlushPromise> Flush() override;
void Shutdown() override;
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
nsCString GetDescriptionName() const override;
void SetSeekThreshold(const media::TimeUnit& aTime) override;
MediaDataDecoder::ConversionRequired NeedsConversion() const override;
void DestroyIPDL() override;
MOZ_IS_CLASS_INIT
MediaResult InitIPDL(const VideoInfo& aVideoInfo,
float aFramerate,
const CreateDecoderParams::OptionSet& aOptions);
// Called from IPDL when our actor has been destroyed
void IPDLActorDestroyed();
RemoteDecoderManagerChild* GetManager();
private:
~RemoteVideoDecoderChild();
void AssertOnManagerThread() const;
RefPtr<mozilla::layers::Image> DeserializeImage(
const SurfaceDescriptorBuffer& sdBuffer,
const IntSize& aPicSize);
RefPtr<RemoteVideoDecoderChild> mIPDLSelfRef;
RefPtr<nsIThread> mThread;
MozPromiseHolder<MediaDataDecoder::InitPromise> mInitPromise;
MozPromiseHolder<MediaDataDecoder::DecodePromise> mDecodePromise;
MozPromiseHolder<MediaDataDecoder::DecodePromise> mDrainPromise;
MozPromiseHolder<MediaDataDecoder::FlushPromise> mFlushPromise;
nsCString mHardwareAcceleratedReason;
nsCString mDescription;
bool mCanSend;
bool mInitialized;
bool mIsHardwareAccelerated;
MediaDataDecoder::ConversionRequired mConversion;
MediaDataDecoder::DecodedData mDecodedData;
RefPtr<mozilla::layers::BufferRecycleBin> mBufferRecycleBin;
};
} // namespace mozilla
#endif // include_dom_media_ipc_RemoteVideoDecoderChild_h

View File

@ -1,261 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteVideoDecoderParent.h"
#include "mozilla/Unused.h"
#ifdef MOZ_AV1
#include "AOMDecoder.h"
#endif
#include "ImageContainer.h"
#include "RemoteDecoderManagerParent.h"
#include "RemoteDecoderModule.h"
namespace mozilla {
using media::TimeUnit;
using namespace layers; // for PlanarYCbCrImage and BufferRecycleBin
RemoteVideoDecoderParent::RemoteVideoDecoderParent(
RemoteDecoderManagerParent* aParent,
const VideoInfo& aVideoInfo,
float aFramerate,
const CreateDecoderParams::OptionSet& aOptions,
TaskQueue* aManagerTaskQueue,
TaskQueue* aDecodeTaskQueue,
bool* aSuccess,
nsCString* aErrorDescription)
: mParent(aParent)
, mManagerTaskQueue(aManagerTaskQueue)
, mDecodeTaskQueue(aDecodeTaskQueue)
, mDestroyed(false)
, mVideoInfo(aVideoInfo)
{
MOZ_COUNT_CTOR(RemoteVideoDecoderParent);
MOZ_ASSERT(OnManagerThread());
// We hold a reference to ourselves to keep us alive until IPDL
// explictly destroys us. There may still be refs held by
// tasks, but no new ones should be added after we're
// destroyed.
mIPDLSelfRef = this;
CreateDecoderParams params(mVideoInfo);
params.mTaskQueue = mDecodeTaskQueue;
params.mImageContainer = new layers::ImageContainer();
params.mRate = CreateDecoderParams::VideoFrameRate(aFramerate);
params.mOptions = aOptions;
MediaResult error(NS_OK);
params.mError = &error;
#ifdef MOZ_AV1
if (AOMDecoder::IsAV1(params.mConfig.mMimeType)) {
mDecoder = new AOMDecoder(params);
}
#endif
if (NS_FAILED(error)) {
MOZ_ASSERT(aErrorDescription);
*aErrorDescription = error.Description();
}
*aSuccess = !!mDecoder;
}
RemoteVideoDecoderParent::~RemoteVideoDecoderParent()
{
MOZ_COUNT_DTOR(RemoteVideoDecoderParent);
}
void
RemoteVideoDecoderParent::Destroy()
{
MOZ_ASSERT(OnManagerThread());
mDestroyed = true;
mIPDLSelfRef = nullptr;
}
mozilla::ipc::IPCResult
RemoteVideoDecoderParent::RecvInit()
{
MOZ_ASSERT(OnManagerThread());
RefPtr<RemoteVideoDecoderParent> self = this;
mDecoder->Init()->Then(mManagerTaskQueue, __func__,
[self] (TrackInfo::TrackType aTrack) {
MOZ_ASSERT(aTrack == TrackInfo::kVideoTrack);
if (self->mDecoder) {
Unused << self->SendInitComplete(self->mDecoder->GetDescriptionName(),
self->mDecoder->NeedsConversion());
}
},
[self] (MediaResult aReason) {
if (!self->mDestroyed) {
Unused << self->SendInitFailed(aReason);
}
});
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderParent::RecvInput(const MediaRawDataIPDL& aData)
{
MOZ_ASSERT(OnManagerThread());
// XXX: This copies the data into a buffer owned by the MediaRawData. Ideally
// we'd just take ownership of the shmem.
RefPtr<MediaRawData> data = new MediaRawData(aData.buffer().get<uint8_t>(),
aData.buffer().Size<uint8_t>());
if (aData.buffer().Size<uint8_t>() && !data->Data()) {
// OOM
Error(NS_ERROR_OUT_OF_MEMORY);
return IPC_OK();
}
data->mOffset = aData.base().offset();
data->mTime = TimeUnit::FromMicroseconds(aData.base().time());
data->mTimecode = TimeUnit::FromMicroseconds(aData.base().timecode());
data->mDuration = TimeUnit::FromMicroseconds(aData.base().duration());
data->mKeyframe = aData.base().keyframe();
DeallocShmem(aData.buffer());
RefPtr<RemoteVideoDecoderParent> self = this;
mDecoder->Decode(data)->Then(
mManagerTaskQueue, __func__,
[self, this](const MediaDataDecoder::DecodedData& aResults) {
if (mDestroyed) {
return;
}
ProcessDecodedData(aResults);
Unused << SendInputExhausted();
},
[self](const MediaResult& aError) { self->Error(aError); });
return IPC_OK();
}
void
RemoteVideoDecoderParent::ProcessDecodedData(
const MediaDataDecoder::DecodedData& aData)
{
MOZ_ASSERT(OnManagerThread());
for (const auto& data : aData) {
MOZ_ASSERT(data->mType == MediaData::VIDEO_DATA,
"Can only decode videos using RemoteVideoDecoderParent!");
VideoData* video = static_cast<VideoData*>(data.get());
MOZ_ASSERT(video->mImage, "Decoded video must output a layer::Image to "
"be used with RemoteVideoDecoderParent");
PlanarYCbCrImage* image =
static_cast<PlanarYCbCrImage*>(video->mImage.get());
SurfaceDescriptorBuffer sdBuffer;
Shmem buffer;
if (AllocShmem(image->GetDataSize(),
Shmem::SharedMemory::TYPE_BASIC, &buffer) &&
image->GetDataSize() == buffer.Size<uint8_t>()) {
sdBuffer.data() = buffer;
image->BuildSurfaceDescriptorBuffer(sdBuffer);
}
RemoteVideoDataIPDL output(
MediaDataIPDL(data->mOffset, data->mTime.ToMicroseconds(),
data->mTimecode.ToMicroseconds(),
data->mDuration.ToMicroseconds(),
data->mFrames, data->mKeyframe),
video->mDisplay,
image->GetSize(),
sdBuffer,
video->mFrameID);
Unused << SendVideoOutput(output);
}
}
mozilla::ipc::IPCResult
RemoteVideoDecoderParent::RecvFlush()
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(OnManagerThread());
RefPtr<RemoteVideoDecoderParent> self = this;
mDecoder->Flush()->Then(
mManagerTaskQueue, __func__,
[self]() {
if (!self->mDestroyed) {
Unused << self->SendFlushComplete();
}
},
[self](const MediaResult& aError) { self->Error(aError); });
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderParent::RecvDrain()
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(OnManagerThread());
RefPtr<RemoteVideoDecoderParent> self = this;
mDecoder->Drain()->Then(
mManagerTaskQueue, __func__,
[self, this](const MediaDataDecoder::DecodedData& aResults) {
if (!mDestroyed) {
ProcessDecodedData(aResults);
Unused << SendDrainComplete();
}
},
[self](const MediaResult& aError) { self->Error(aError); });
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderParent::RecvShutdown()
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(OnManagerThread());
if (mDecoder) {
mDecoder->Shutdown();
}
mDecoder = nullptr;
return IPC_OK();
}
mozilla::ipc::IPCResult
RemoteVideoDecoderParent::RecvSetSeekThreshold(const int64_t& aTime)
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(OnManagerThread());
mDecoder->SetSeekThreshold(TimeUnit::FromMicroseconds(aTime));
return IPC_OK();
}
void
RemoteVideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(OnManagerThread());
if (mDecoder) {
mDecoder->Shutdown();
mDecoder = nullptr;
}
if (mDecodeTaskQueue) {
mDecodeTaskQueue->BeginShutdown();
}
}
void
RemoteVideoDecoderParent::Error(const MediaResult& aError)
{
MOZ_ASSERT(OnManagerThread());
if (!mDestroyed) {
Unused << SendError(aError);
}
}
bool
RemoteVideoDecoderParent::OnManagerThread()
{
return mParent->OnManagerThread();
}
} // namespace mozilla

View File

@ -1,62 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef include_dom_media_ipc_RemoteVideoDecoderParent_h
#define include_dom_media_ipc_RemoteVideoDecoderParent_h
#include "mozilla/PRemoteVideoDecoderParent.h"
namespace mozilla {
class RemoteDecoderManagerParent;
class RemoteVideoDecoderParent final : public PRemoteVideoDecoderParent
{
public:
// We refcount this class since the task queue can have runnables
// that reference us.
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteVideoDecoderParent)
RemoteVideoDecoderParent(RemoteDecoderManagerParent* aParent,
const VideoInfo& aVideoInfo,
float aFramerate,
const CreateDecoderParams::OptionSet& aOptions,
TaskQueue* aManagerTaskQueue,
TaskQueue* aDecodeTaskQueue,
bool* aSuccess,
nsCString* aErrorDescription);
void Destroy();
// PRemoteVideoDecoderParent
mozilla::ipc::IPCResult RecvInit() override;
mozilla::ipc::IPCResult RecvInput(const MediaRawDataIPDL& aData) override;
mozilla::ipc::IPCResult RecvFlush() override;
mozilla::ipc::IPCResult RecvDrain() override;
mozilla::ipc::IPCResult RecvShutdown() override;
mozilla::ipc::IPCResult RecvSetSeekThreshold(const int64_t& aTime) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
private:
bool OnManagerThread();
void Error(const MediaResult& aError);
~RemoteVideoDecoderParent();
void ProcessDecodedData(const MediaDataDecoder::DecodedData& aData);
RefPtr<RemoteDecoderManagerParent> mParent;
RefPtr<RemoteVideoDecoderParent> mIPDLSelfRef;
RefPtr<TaskQueue> mManagerTaskQueue;
RefPtr<TaskQueue> mDecodeTaskQueue;
RefPtr<MediaDataDecoder> mDecoder;
// Can only be accessed from the manager thread
bool mDestroyed;
VideoInfo mVideoInfo;
};
} // namespace mozilla
#endif // include_dom_media_ipc_RemoteVideoDecoderParent_h

View File

@ -9,7 +9,6 @@
#include "MediaResult.h"
#include "PlatformDecoderModule.h"
#include "mozilla/dom/PVideoDecoderChild.h"
#include "IRemoteDecoderChild.h"
namespace mozilla {
namespace dom {
@ -19,11 +18,12 @@ class RemoteDecoderModule;
class VideoDecoderManagerChild;
class VideoDecoderChild final : public PVideoDecoderChild
, public IRemoteDecoderChild
{
public:
explicit VideoDecoderChild();
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoDecoderChild)
// PVideoDecoderChild
mozilla::ipc::IPCResult RecvOutput(const VideoDataIPDL& aData) override;
mozilla::ipc::IPCResult RecvInputExhausted() override;
@ -38,22 +38,22 @@ public:
void ActorDestroy(ActorDestroyReason aWhy) override;
RefPtr<MediaDataDecoder::InitPromise> Init() override;
RefPtr<MediaDataDecoder::DecodePromise> Decode(MediaRawData* aSample) override;
RefPtr<MediaDataDecoder::DecodePromise> Drain() override;
RefPtr<MediaDataDecoder::FlushPromise> Flush() override;
void Shutdown() override;
bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
nsCString GetDescriptionName() const override;
void SetSeekThreshold(const media::TimeUnit& aTime) override;
MediaDataDecoder::ConversionRequired NeedsConversion() const override;
void DestroyIPDL() override;
RefPtr<MediaDataDecoder::InitPromise> Init();
RefPtr<MediaDataDecoder::DecodePromise> Decode(MediaRawData* aSample);
RefPtr<MediaDataDecoder::DecodePromise> Drain();
RefPtr<MediaDataDecoder::FlushPromise> Flush();
void Shutdown();
bool IsHardwareAccelerated(nsACString& aFailureReason) const;
nsCString GetDescriptionName() const;
void SetSeekThreshold(const media::TimeUnit& aTime);
MediaDataDecoder::ConversionRequired NeedsConversion() const;
MOZ_IS_CLASS_INIT
MediaResult InitIPDL(const VideoInfo& aVideoInfo,
float aFramerate,
const CreateDecoderParams::OptionSet& aOptions,
const layers::TextureFactoryIdentifier& aIdentifier);
void DestroyIPDL();
// Called from IPDL when our actor has been destroyed
void IPDLActorDestroyed();

View File

@ -6,46 +6,19 @@
IPDL_SOURCES += [
'PMediaDecoderParams.ipdlh',
'PRDD.ipdl',
'PRemoteDecoderManager.ipdl',
'PRemoteVideoDecoder.ipdl',
'PVideoDecoder.ipdl',
'PVideoDecoderManager.ipdl',
]
EXPORTS.mozilla += [
'GpuDecoderModule.h',
'RDDChild.h',
'RDDParent.h',
'RDDProcessHost.h',
'RDDProcessImpl.h',
'RDDProcessManager.h',
'RemoteDecoderManagerChild.h',
'RemoteDecoderManagerParent.h',
'RemoteDecoderModule.h',
'RemoteMediaDataDecoder.h',
]
EXPORTS.mozilla.dom += [
'MediaIPCUtils.h',
'RemoteVideoDecoder.h',
'VideoDecoderManagerChild.h',
'VideoDecoderManagerParent.h',
]
SOURCES += [
'GpuDecoderModule.cpp',
'RDDChild.cpp',
'RDDParent.cpp',
'RDDProcessHost.cpp',
'RDDProcessImpl.cpp',
'RDDProcessManager.cpp',
'RemoteDecoderManagerChild.cpp',
'RemoteDecoderManagerParent.cpp',
'RemoteDecoderModule.cpp',
'RemoteMediaDataDecoder.cpp',
'RemoteVideoDecoderChild.cpp',
'RemoteVideoDecoderParent.cpp',
'RemoteVideoDecoder.cpp',
'VideoDecoderChild.cpp',
'VideoDecoderManagerChild.cpp',
'VideoDecoderManagerParent.cpp',

View File

@ -45,8 +45,7 @@
#include "MP4Decoder.h"
#include "VPXDecoder.h"
#include "mozilla/GpuDecoderModule.h"
#include "mozilla/RemoteDecoderModule.h"
#include "mozilla/dom/RemoteVideoDecoder.h"
#include "H264.h"
@ -353,15 +352,10 @@ PDMFactory::CreatePDMs()
return;
}
if (StaticPrefs::MediaRddProcessEnabled()) {
m = new RemoteDecoderModule;
StartupPDM(m);
}
#ifdef XP_WIN
if (StaticPrefs::MediaWmfEnabled() && !IsWin7AndPre2000Compatible()) {
m = new WMFDecoderModule();
RefPtr<PlatformDecoderModule> remote = new GpuDecoderModule(m);
RefPtr<PlatformDecoderModule> remote = new dom::RemoteDecoderModule(m);
StartupPDM(remote);
mWMFFailedToLoad = !StartupPDM(m);
} else {

View File

@ -33,9 +33,11 @@ namespace layers {
class ImageContainer;
} // namespace layers
class GpuDecoderModule;
class MediaDataDecoder;
namespace dom {
class RemoteDecoderModule;
}
class MediaDataDecoder;
class TaskQueue;
class CDMProxy;
@ -212,9 +214,8 @@ protected:
friend class MediaChangeMonitor;
friend class PDMFactory;
friend class GpuDecoderModule;
friend class dom::RemoteDecoderModule;
friend class EMEDecoderModule;
friend class RemoteDecoderModule;
// Indicates if the PlatformDecoderModule supports decoding of aColorDepth.
// Should override this method when the platform can support color depth != 8.

View File

@ -11,7 +11,6 @@
#include "AppleDecoderModule.h"
#include "AppleUtils.h"
#include "AppleVTLinker.h"
#include "MacIOSurfaceImage.h"
#include "MediaData.h"
#include "mozilla/ArrayUtils.h"
#include "H264.h"
@ -437,7 +436,7 @@ AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage,
RefPtr<MacIOSurface> macSurface = new MacIOSurface(surface);
RefPtr<layers::Image> image = new layers::MacIOSurfaceImage(macSurface);
RefPtr<layers::Image> image = new MacIOSurfaceImage(macSurface);
data =
VideoData::CreateFromImage(info.mDisplay,

View File

@ -4,12 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VsyncBridgeParent.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
using mozilla::layers::CompositorBridgeParent;
using mozilla::layers::CompositorThreadHolder;
namespace mozilla {
namespace gfx {

View File

@ -17,7 +17,6 @@
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/ImageBridgeChild.h" // for ImageBridgeChild
#include "mozilla/layers/ImageClient.h" // for ImageClient
#include "mozilla/layers/ImageDataSerializer.h" // for SurfaceDescriptorBuffer
#include "mozilla/layers/LayersMessages.h"
#include "mozilla/layers/SharedPlanarYCbCrImage.h"
#include "mozilla/layers/SharedSurfacesChild.h" // for SharedSurfacesAnimation
@ -52,10 +51,6 @@ Atomic<int32_t> Image::sSerialCounter(0);
Atomic<uint32_t> ImageContainer::sGenerationCounter(0);
static void
CopyPlane(uint8_t* aDst, const uint8_t* aSrc,
const gfx::IntSize& aSize, int32_t aStride, int32_t aSkip);
RefPtr<PlanarYCbCrImage>
ImageFactory::CreatePlanarYCbCrImage(const gfx::IntSize& aScaleHint, BufferRecycleBin *aRecycleBin)
{
@ -487,61 +482,6 @@ PlanarYCbCrImage::PlanarYCbCrImage()
{
}
nsresult
PlanarYCbCrImage::BuildSurfaceDescriptorBuffer(
SurfaceDescriptorBuffer& aSdBuffer)
{
const PlanarYCbCrData* pdata = GetData();
MOZ_ASSERT(pdata, "must have PlanarYCbCrData");
MOZ_ASSERT(pdata->mYSkip == 0 && pdata->mCbSkip == 0 && pdata->mCrSkip == 0,
"YCbCrDescriptor doesn't hold skip values");
MOZ_ASSERT(pdata->mPicX == 0 && pdata->mPicY == 0,
"YCbCrDescriptor doesn't hold picx or picy");
uint32_t yOffset;
uint32_t cbOffset;
uint32_t crOffset;
ImageDataSerializer::ComputeYCbCrOffsets(pdata->mYStride,
pdata->mYSize.height,
pdata->mCbCrStride,
pdata->mCbCrSize.height,
yOffset, cbOffset, crOffset);
aSdBuffer.desc() = YCbCrDescriptor(pdata->mYSize, pdata->mYStride,
pdata->mCbCrSize, pdata->mCbCrStride,
yOffset, cbOffset, crOffset,
pdata->mStereoMode,
pdata->mColorDepth,
pdata->mYUVColorSpace,
/*hasIntermediateBuffer*/ false);
uint8_t* buffer = nullptr;
const MemoryOrShmem& memOrShmem = aSdBuffer.data();
switch (memOrShmem.type()) {
case MemoryOrShmem::Tuintptr_t:
buffer = reinterpret_cast<uint8_t*>(memOrShmem.get_uintptr_t());
break;
case MemoryOrShmem::TShmem:
buffer = memOrShmem.get_Shmem().get<uint8_t>();
break;
default:
MOZ_ASSERT(false, "Unknown MemoryOrShmem type");
}
MOZ_ASSERT(buffer, "no valid buffer available to copy image data");
if (!buffer) {
return NS_ERROR_INVALID_ARG;
}
CopyPlane(buffer+yOffset, pdata->mYChannel,
pdata->mYSize, pdata->mYStride, pdata->mYSkip);
CopyPlane(buffer+cbOffset, pdata->mCbChannel,
pdata->mCbCrSize, pdata->mCbCrStride, pdata->mCbSkip);
CopyPlane(buffer+crOffset, pdata->mCrChannel,
pdata->mCbCrSize, pdata->mCbCrStride, pdata->mCrSkip);
return NS_OK;
}
RecyclingPlanarYCbCrImage::~RecyclingPlanarYCbCrImage()
{
if (mBuffer) {

View File

@ -170,7 +170,6 @@ class NVImage;
#ifdef XP_WIN
class D3D11YCbCrRecycleAllocator;
#endif
class SurfaceDescriptorBuffer;
struct ImageBackendData
{
@ -889,14 +888,6 @@ public:
PlanarYCbCrImage* AsPlanarYCbCrImage() override { return this; }
/**
* Build a SurfaceDescriptorBuffer with this image. The provided
* SurfaceDescriptorBuffer must already have a valid MemoryOrShmem set
* with a capacity large enough to hold |GetDataSize|.
*/
virtual nsresult BuildSurfaceDescriptorBuffer(
SurfaceDescriptorBuffer& aSdBuffer);
protected:
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;

View File

@ -4,7 +4,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/FontPropertyTypes.h"
#include "mozilla/RDDProcessManager.h"
#include "mozilla/image/ImageMemoryReporter.h"
#include "mozilla/layers/CompositorManagerChild.h"
#include "mozilla/layers/CompositorThread.h"
@ -768,7 +767,6 @@ void
gfxPlatform::Init()
{
MOZ_RELEASE_ASSERT(!XRE_IsGPUProcess(), "GFX: Not allowed in GPU process.");
MOZ_RELEASE_ASSERT(!XRE_IsRDDProcess(), "GFX: Not allowed in RDD process.");
MOZ_RELEASE_ASSERT(NS_IsMainThread(), "GFX: Not in main thread.");
if (gEverInitialized) {
@ -784,7 +782,6 @@ gfxPlatform::Init()
if (XRE_IsParentProcess() || recordreplay::IsRecordingOrReplaying()) {
GPUProcessManager::Initialize();
RDDProcessManager::Initialize();
if (Preferences::GetBool("media.wmf.skip-blacklist")) {
gfxVars::SetPDMWMFDisableD3D11Dlls(nsCString());
@ -886,12 +883,6 @@ gfxPlatform::Init()
gpu->LaunchGPUProcess();
}
if (XRE_IsParentProcess() &&
Preferences::GetBool("media.rdd-process.enabled", false)) {
RDDProcessManager* rdd = RDDProcessManager::Get();
if (rdd) { rdd->LaunchRDDProcess(); }
}
if (XRE_IsParentProcess() || recordreplay::IsRecordingOrReplaying()) {
if (gfxPlatform::ForceSoftwareVsync()) {
gPlatform->mVsyncSource = (gPlatform)->gfxPlatform::CreateHardwareVsyncSource();
@ -1170,7 +1161,6 @@ gfxPlatform::Shutdown()
if (XRE_IsParentProcess()) {
GPUProcessManager::Shutdown();
VRProcessManager::Shutdown();
RDDProcessManager::Shutdown();
}
gfx::Factory::ShutDown();

View File

@ -94,9 +94,6 @@ CrashReporterHost::FinalizeCrashReport()
case GeckoProcessType_GPU:
type = NS_LITERAL_CSTRING("gpu");
break;
case GeckoProcessType_RDD:
type = NS_LITERAL_CSTRING("rdd");
break;
default:
NS_ERROR("unknown process type");
break;
@ -169,10 +166,6 @@ CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType,
processType = nsICrashService::PROCESS_TYPE_GPU;
telemetryKey.AssignLiteral("gpu");
break;
case GeckoProcessType_RDD:
processType = nsICrashService::PROCESS_TYPE_RDD;
telemetryKey.AssignLiteral("rdd");
break;
default:
NS_ERROR("unknown process type");
return;

View File

@ -143,10 +143,8 @@ auto
GeckoChildProcessHost::GetPathToBinary(FilePath& exePath, GeckoProcessType processType) -> BinaryPathType
{
if (sRunSelfAsContentProc &&
(processType == GeckoProcessType_Content ||
processType == GeckoProcessType_GPU ||
processType == GeckoProcessType_VR ||
processType == GeckoProcessType_RDD)) {
(processType == GeckoProcessType_Content || processType == GeckoProcessType_GPU ||
processType == GeckoProcessType_VR)) {
#if defined(OS_WIN)
wchar_t exePathBuf[MAXPATHLEN];
if (!::GetModuleFileNameW(nullptr, exePathBuf, MAXPATHLEN)) {
@ -747,12 +745,9 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
// Add the application directory path (-appdir path)
AddAppDirToCommandLine(childArgv);
// Tmp dir that the GPU or RDD process should use for crash reports.
// This arg is always populated (but possibly with an empty value) for
// a GPU or RDD child process.
if (mProcessType == GeckoProcessType_GPU ||
mProcessType == GeckoProcessType_RDD ||
mProcessType == GeckoProcessType_VR) {
// Tmp dir that the GPU process should use for crash reports. This arg is
// always populated (but possibly with an empty value) for a GPU child process.
if (mProcessType == GeckoProcessType_GPU || mProcessType == GeckoProcessType_VR) {
nsCOMPtr<nsIFile> file;
CrashReporter::GetChildProcessTmpDir(getter_AddRefs(file));
nsAutoCString path;
@ -994,11 +989,6 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
// TODO: Implement sandbox for VR process, Bug 1430043.
}
break;
case GeckoProcessType_RDD:
if (mSandboxLevel > 0 && !PR_GetEnv("MOZ_DISABLE_RDD_SANDBOX")) {
// TODO: Implement sandbox for RDD process, Bug 1498624.
}
break;
case GeckoProcessType_Default:
default:
MOZ_CRASH("Bad process type in GeckoChildProcessHost");
@ -1024,11 +1014,9 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
// Win app model id
cmdLine.AppendLooseValue(mGroupId.get());
// Tmp dir that the GPU or RDD process should use for crash reports.
// This arg is always populated (but possibly with an empty value) for
// a GPU or RDD child process.
if (mProcessType == GeckoProcessType_GPU ||
mProcessType == GeckoProcessType_RDD) {
// Tmp dir that the GPU process should use for crash reports. This arg is
// always populated (but possibly with an empty value) for a GPU child process.
if (mProcessType == GeckoProcessType_GPU) {
nsCOMPtr<nsIFile> file;
CrashReporter::GetChildProcessTmpDir(getter_AddRefs(file));
nsString path;
@ -1083,7 +1071,6 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
// child processes.
if (mProcessType == GeckoProcessType_Content ||
mProcessType == GeckoProcessType_GPU ||
mProcessType == GeckoProcessType_RDD ||
mProcessType == GeckoProcessType_VR ||
mProcessType == GeckoProcessType_GMPlugin) {
if (!mSandboxBroker.AddTargetPeer(process)) {

View File

@ -914,8 +914,6 @@ description =
description =
[PGMPVideoEncoder::NeedShmem]
description =
[PRemoteDecoderManager::PRemoteVideoDecoder]
description = See Bug 1505976 - investigate changing to async instead of matching GPU pattern
[PVideoDecoderManager::PVideoDecoder]
description =
[PVideoDecoderManager::Readback]

View File

@ -226,12 +226,11 @@ nsLayoutModuleInitialize()
return;
}
if (XRE_GetProcessType() == GeckoProcessType_GPU ||
XRE_GetProcessType() == GeckoProcessType_RDD) {
// We mark the layout module as being available in the GPU and RDD
// process so that XPCOM's component manager initializes the power
// manager service, which is needed for nsAppShell. However, we
// don't actually need anything in the layout module itself.
if (XRE_GetProcessType() == GeckoProcessType_GPU) {
// We mark the layout module as being available in the GPU process so that
// XPCOM's component manager initializes the power manager service, which
// is needed for nsAppShell. However, we don't actually need anything in
// the layout module itself.
return;
}
@ -677,8 +676,7 @@ static void
LayoutModuleDtor()
{
if (XRE_GetProcessType() == GeckoProcessType_GPU ||
XRE_GetProcessType() == GeckoProcessType_VR ||
XRE_GetProcessType() == GeckoProcessType_RDD) {
XRE_GetProcessType() == GeckoProcessType_VR) {
return;
}

View File

@ -1069,18 +1069,6 @@ VARCACHE_PREF(
)
#undef PREF_VALUE
VARCACHE_PREF(
"media.rdd-process.enabled",
MediaRddProcessEnabled,
RelaxedAtomicBool, false
)
VARCACHE_PREF(
"media.rdd-process.startup_timeout_ms",
MediaRddProcessStartupTimeoutMs,
RelaxedAtomicInt32, 5000
)
#ifdef ANDROID
// Enable the MediaCodec PlatformDecoderModule by default.

View File

@ -177,9 +177,6 @@ this.CrashManager.prototype = Object.freeze({
// A crash in the GPU process.
PROCESS_TYPE_GPU: "gpu",
// A crash in the RDD process.
PROCESS_TYPE_RDD: "rdd",
// A real crash.
CRASH_TYPE_CRASH: "crash",
@ -463,8 +460,7 @@ this.CrashManager.prototype = Object.freeze({
// Send a telemetry ping for each non-main process crash
if (processType === this.PROCESS_TYPE_CONTENT ||
processType === this.PROCESS_TYPE_GPU ||
processType === this.PROCESS_TYPE_RDD) {
processType === this.PROCESS_TYPE_GPU) {
this._sendCrashPing(id, processType, date, metadata);
}
})();

View File

@ -179,9 +179,6 @@ CrashService.prototype = Object.freeze({
case Ci.nsICrashService.PROCESS_TYPE_GPU:
processType = Services.crashmanager.PROCESS_TYPE_GPU;
break;
case Ci.nsICrashService.PROCESS_TYPE_RDD:
processType = Services.crashmanager.PROCESS_TYPE_RDD;
break;
default:
throw new Error("Unrecognized PROCESS_TYPE: " + processType);
}

View File

@ -26,7 +26,6 @@ interface nsICrashService : nsISupports
const long PROCESS_TYPE_PLUGIN = 2;
const long PROCESS_TYPE_GMPLUGIN = 3;
const long PROCESS_TYPE_GPU = 4;
const long PROCESS_TYPE_RDD = 5;
const long CRASH_TYPE_CRASH = 0;
const long CRASH_TYPE_HANG = 1;

View File

@ -394,8 +394,6 @@ add_task(async function test_addCrash() {
"gmplugin-crash", DUMMY_DATE);
await m.addCrash(m.PROCESS_TYPE_GPU, m.CRASH_TYPE_CRASH,
"gpu-crash", DUMMY_DATE);
await m.addCrash(m.PROCESS_TYPE_RDD, m.CRASH_TYPE_CRASH,
"rdd-crash", DUMMY_DATE);
await m.addCrash(m.PROCESS_TYPE_MAIN, m.CRASH_TYPE_CRASH,
"changing-item", DUMMY_DATE);
@ -403,7 +401,7 @@ add_task(async function test_addCrash() {
"changing-item", DUMMY_DATE_2);
crashes = await m.getCrashes();
Assert.equal(crashes.length, 10);
Assert.equal(crashes.length, 9);
let map = new Map(crashes.map(crash => [crash.id, crash]));
@ -455,12 +453,6 @@ add_task(async function test_addCrash() {
Assert.equal(crash.type, m.PROCESS_TYPE_GPU + "-" + m.CRASH_TYPE_CRASH);
Assert.ok(crash.isOfType(m.PROCESS_TYPE_GPU, m.CRASH_TYPE_CRASH));
crash = map.get("rdd-crash");
Assert.ok(!!crash);
Assert.equal(crash.crashDate, DUMMY_DATE);
Assert.equal(crash.type, m.PROCESS_TYPE_RDD + "-" + m.CRASH_TYPE_CRASH);
Assert.ok(crash.isOfType(m.PROCESS_TYPE_RDD, m.CRASH_TYPE_CRASH));
crash = map.get("changing-item");
Assert.ok(!!crash);
Assert.equal(crash.crashDate, DUMMY_DATE_2);
@ -473,7 +465,6 @@ add_task(async function test_child_process_crash_ping() {
const EXPECTED_PROCESSES = [
m.PROCESS_TYPE_CONTENT,
m.PROCESS_TYPE_GPU,
m.PROCESS_TYPE_RDD,
];
const UNEXPECTED_PROCESSES = [

View File

@ -22,7 +22,6 @@ const {
PROCESS_TYPE_PLUGIN,
PROCESS_TYPE_GMPLUGIN,
PROCESS_TYPE_GPU,
PROCESS_TYPE_RDD,
CRASH_TYPE_CRASH,
CRASH_TYPE_HANG,
SUBMISSION_RESULT_OK,
@ -354,33 +353,6 @@ add_task(async function test_add_gpu_crash() {
Assert.equal(crashes.length, 2);
});
add_task(async function test_add_rdd_crash() {
let s = await getStore();
Assert.ok(
s.addCrash(PROCESS_TYPE_RDD, CRASH_TYPE_CRASH, "id1", new Date())
);
Assert.equal(s.crashesCount, 1);
let c = s.crashes[0];
Assert.ok(c.crashDate);
Assert.equal(c.type, PROCESS_TYPE_RDD + "-" + CRASH_TYPE_CRASH);
Assert.ok(c.isOfType(PROCESS_TYPE_RDD, CRASH_TYPE_CRASH));
Assert.ok(
s.addCrash(PROCESS_TYPE_RDD, CRASH_TYPE_CRASH, "id2", new Date())
);
Assert.equal(s.crashesCount, 2);
Assert.ok(
s.addCrash(PROCESS_TYPE_RDD, CRASH_TYPE_CRASH, "id1", new Date())
);
Assert.equal(s.crashesCount, 2);
let crashes = s.getCrashesOfType(PROCESS_TYPE_RDD, CRASH_TYPE_CRASH);
Assert.equal(crashes.length, 2);
});
add_task(async function test_add_mixed_types() {
let s = await getStore();
@ -392,11 +364,10 @@ add_task(async function test_add_mixed_types() {
s.addCrash(PROCESS_TYPE_PLUGIN, CRASH_TYPE_CRASH, "pcrash", new Date()) &&
s.addCrash(PROCESS_TYPE_PLUGIN, CRASH_TYPE_HANG, "phang", new Date()) &&
s.addCrash(PROCESS_TYPE_GMPLUGIN, CRASH_TYPE_CRASH, "gmpcrash", new Date()) &&
s.addCrash(PROCESS_TYPE_GPU, CRASH_TYPE_CRASH, "gpucrash", new Date()) &&
s.addCrash(PROCESS_TYPE_RDD, CRASH_TYPE_CRASH, "rddcrash", new Date())
s.addCrash(PROCESS_TYPE_GPU, CRASH_TYPE_CRASH, "gpucrash", new Date())
);
Assert.equal(s.crashesCount, 9);
Assert.equal(s.crashesCount, 8);
await s.save();
@ -405,7 +376,7 @@ add_task(async function test_add_mixed_types() {
await s.load();
Assert.equal(s.crashesCount, 9);
Assert.equal(s.crashesCount, 8);
let crashes = s.getCrashesOfType(PROCESS_TYPE_MAIN, CRASH_TYPE_CRASH);
Assert.equal(crashes.length, 1);
@ -423,8 +394,6 @@ add_task(async function test_add_mixed_types() {
Assert.equal(crashes.length, 1);
crashes = s.getCrashesOfType(PROCESS_TYPE_GPU, CRASH_TYPE_CRASH);
Assert.equal(crashes.length, 1);
crashes = s.getCrashesOfType(PROCESS_TYPE_RDD, CRASH_TYPE_CRASH);
Assert.equal(crashes.length, 1);
});
// Crashes added beyond the high water mark behave properly.

View File

@ -11467,9 +11467,7 @@
"gmplugin-crash",
"gmplugin-hang",
"gpu-crash",
"gpu-hang",
"rdd-crash",
"rdd-hang"
"gpu-hang"
],
"releaseChannelCollection": "opt-out",
"description": "An attempt to submit a crash. Keyed on the CrashManager Crash.type."

View File

@ -548,8 +548,8 @@ PluginVersion:
ProcessType:
description: >
Type of the process that crashed, can hold the values "content", "plugin",
"gpu" or "rdd" currently.
Type of the process that crashed, can hold the values "content", "plugin" or
"gpu" currently.
type: string
ProductName:
@ -586,11 +586,6 @@ ProxyStreamValid:
Set to "false" when encountering an invalid IPC proxy stream.
type: string
RDDProcessStatus:
description: >
Status of the RDD process, can be set to "Running" or "Destroyed"
type: string
RecordReplay:
description: >
Set to 1 if this crash happened in a Web Replay middleman, recording,

View File

@ -785,10 +785,9 @@ SYNC_ENUMS(GMPLUGIN, GMPlugin)
SYNC_ENUMS(GPU, GPU)
SYNC_ENUMS(PDFIUM, PDFium)
SYNC_ENUMS(VR, VR)
SYNC_ENUMS(RDD, RDD)
// .. and ensure that that is all of them:
static_assert(GeckoProcessType_RDD + 1 == GeckoProcessType_End,
static_assert(GeckoProcessType_VR + 1 == GeckoProcessType_End,
"Did not find the final GeckoProcessType");
NS_IMETHODIMP
@ -5128,12 +5127,6 @@ XRE_IsGPUProcess()
return XRE_GetProcessType() == GeckoProcessType_GPU;
}
bool
XRE_IsRDDProcess()
{
return XRE_GetProcessType() == GeckoProcessType_RDD;
}
bool
XRE_IsVRProcess()
{
@ -5171,11 +5164,6 @@ XRE_IsPluginProcess()
bool
XRE_UseNativeEventProcessing()
{
#ifdef XP_MACOSX
if (XRE_IsRDDProcess()) {
return false;
}
#endif
if (XRE_IsContentProcess()) {
static bool sInited = false;
static bool sUseNativeEventProcessing = false;

View File

@ -59,7 +59,6 @@
#include "mozilla/AbstractThread.h"
#include "mozilla/FilePreferences.h"
#include "mozilla/RDDProcessImpl.h"
#include "mozilla/ipc/BrowserProcessSubThread.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
@ -626,8 +625,7 @@ XRE_InitChildProcess(int aArgc,
MOZ_ASSERT(!*end, "invalid parent PID");
nsCOMPtr<nsIFile> crashReportTmpDir;
if (XRE_GetProcessType() == GeckoProcessType_GPU ||
XRE_GetProcessType() == GeckoProcessType_RDD) {
if (XRE_GetProcessType() == GeckoProcessType_GPU) {
aArgc--;
if (strlen(aArgv[aArgc])) { // if it's empty, ignore it
nsresult rv = XRE_GetFileFromPath(aArgv[aArgc], getter_AddRefs(crashReportTmpDir));
@ -678,7 +676,6 @@ XRE_InitChildProcess(int aArgc,
case GeckoProcessType_Content:
case GeckoProcessType_GPU:
case GeckoProcessType_VR:
case GeckoProcessType_RDD:
// Content processes need the XPCOM/chromium frankenventloop
uiLoopType = MessageLoop::TYPE_MOZILLA_CHILD;
break;
@ -750,10 +747,6 @@ XRE_InitChildProcess(int aArgc,
process = new gfx::VRProcessChild(parentPID);
break;
case GeckoProcessType_RDD:
process = new RDDProcessImpl(parentPID);
break;
default:
MOZ_CRASH("Unknown main thread class");
}

View File

@ -314,31 +314,29 @@ nsAppShell::Init()
mAutoreleasePools = ::CFArrayCreateMutable(nullptr, 0, nullptr);
NS_ENSURE_STATE(mAutoreleasePools);
if (XRE_GetProcessType() != GeckoProcessType_RDD) {
// Get the path of the nib file, which lives in the GRE location
nsCOMPtr<nsIFile> nibFile;
nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(nibFile));
NS_ENSURE_SUCCESS(rv, rv);
// Get the path of the nib file, which lives in the GRE location
nsCOMPtr<nsIFile> nibFile;
nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(nibFile));
NS_ENSURE_SUCCESS(rv, rv);
nibFile->AppendNative(NS_LITERAL_CSTRING("res"));
nibFile->AppendNative(NS_LITERAL_CSTRING("MainMenu.nib"));
nibFile->AppendNative(NS_LITERAL_CSTRING("res"));
nibFile->AppendNative(NS_LITERAL_CSTRING("MainMenu.nib"));
nsAutoCString nibPath;
rv = nibFile->GetNativePath(nibPath);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString nibPath;
rv = nibFile->GetNativePath(nibPath);
NS_ENSURE_SUCCESS(rv, rv);
// This call initializes NSApplication unless:
// 1) we're using xre -- NSApp's already been initialized by
// MacApplicationDelegate.mm's EnsureUseCocoaDockAPI().
// 2) an embedding app that uses NSApplicationMain() is running -- NSApp's
// already been initialized and its main run loop is already running.
[NSBundle loadNibFile:
[NSString stringWithUTF8String:(const char*)nibPath.get()]
externalNameTable:
[NSDictionary dictionaryWithObject:[GeckoNSApplication sharedApplication]
forKey:@"NSOwner"]
withZone:NSDefaultMallocZone()];
}
// This call initializes NSApplication unless:
// 1) we're using xre -- NSApp's already been initialized by
// MacApplicationDelegate.mm's EnsureUseCocoaDockAPI().
// 2) an embedding app that uses NSApplicationMain() is running -- NSApp's
// already been initialized and its main run loop is already running.
[NSBundle loadNibFile:
[NSString stringWithUTF8String:(const char*)nibPath.get()]
externalNameTable:
[NSDictionary dictionaryWithObject:[GeckoNSApplication sharedApplication]
forKey:@"NSOwner"]
withZone:NSDefaultMallocZone()];
mDelegate = [[AppShellDelegate alloc] initWithAppShell:this];
NS_ENSURE_STATE(mDelegate);
@ -373,7 +371,7 @@ nsAppShell::Init()
}
}
nsresult rv = nsBaseAppShell::Init();
rv = nsBaseAppShell::Init();
if (!gAppShellMethodsSwizzled) {
// We should only replace the original terminate: method if we're not

View File

@ -30,7 +30,6 @@
#include "mozilla/MemoryReportingProcess.h"
#include "mozilla/PodOperations.h"
#include "mozilla/Preferences.h"
#include "mozilla/RDDProcessManager.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/Services.h"
#include "mozilla/Telemetry.h"
@ -1926,12 +1925,6 @@ nsMemoryReporterManager::StartGettingReports()
}
}
if (RDDProcessManager* rdd = RDDProcessManager::Get()) {
if (RefPtr<MemoryReportingProcess> proc = rdd->GetProcessMemoryReporter()) {
s->mChildrenPending.AppendElement(proc.forget());
}
}
if (!s->mChildrenPending.IsEmpty()) {
nsCOMPtr<nsITimer> timer;
rv = NS_NewTimerWithFuncCallback(

View File

@ -8,7 +8,6 @@
#include "mozilla/Atomics.h"
#include "mozilla/Poison.h"
#include "mozilla/RemoteDecoderManagerChild.h"
#include "mozilla/SharedThreadPool.h"
#include "mozilla/XPCOM.h"
#include "nsXULAppAPI.h"
@ -901,7 +900,6 @@ ShutdownXPCOM(nsIServiceManager* aServMgr)
NS_ProcessPendingEvents(thread);
gfxPlatform::ShutdownLayersIPC();
mozilla::dom::VideoDecoderManagerChild::Shutdown();
mozilla::RemoteDecoderManagerChild::Shutdown();
mozilla::scache::StartupCache::DeleteSingleton();
if (observerService)

View File

@ -390,7 +390,6 @@ enum GeckoProcessType
GeckoProcessType_GPU, // GPU and compositor process
GeckoProcessType_PDFium, // Gecko PDFium process
GeckoProcessType_VR, // VR process
GeckoProcessType_RDD, // RDD (RemoteDataDecoder process)
GeckoProcessType_End,
GeckoProcessType_Invalid = GeckoProcessType_End
};
@ -403,8 +402,7 @@ static const char* const kGeckoProcessTypeString[] = {
"geckomediaplugin",
"gpu",
"pdfium",
"vr",
"rdd"
"vr"
};
static_assert(MOZ_ARRAY_LENGTH(kGeckoProcessTypeString) ==
@ -482,9 +480,6 @@ XRE_API(bool,
XRE_API(bool,
XRE_IsGPUProcess, ())
XRE_API(bool,
XRE_IsRDDProcess, ())
XRE_API(bool,
XRE_IsVRProcess, ())

View File

@ -360,8 +360,7 @@ nsComponentManagerImpl::Init()
nsLayoutModuleInitialize();
bool loadChromeManifests = (XRE_GetProcessType() != GeckoProcessType_GPU &&
XRE_GetProcessType() != GeckoProcessType_VR &&
XRE_GetProcessType() != GeckoProcessType_RDD);
XRE_GetProcessType() != GeckoProcessType_VR);
if (loadChromeManifests) {
// The overall order in which chrome.manifests are expected to be treated
// is the following:
@ -441,7 +440,7 @@ static bool
ProcessSelectorMatches(Module::ProcessSelector aSelector)
{
GeckoProcessType type = XRE_GetProcessType();
if (type == GeckoProcessType_GPU || type == GeckoProcessType_RDD) {
if (type == GeckoProcessType_GPU) {
return !!(aSelector & Module::ALLOW_IN_GPU_PROCESS);
}

View File

@ -78,7 +78,6 @@ interface nsIXULRuntime : nsISupports
const unsigned long PROCESS_TYPE_GPU = 5;
const unsigned long PROCESS_TYPE_PDFIUM = 6;
const unsigned long PROCESS_TYPE_VR = 7;
const unsigned long PROCESS_TYPE_RDD = 8;
/**
* The type of the caller's process. Returns one of the values above.