Bug 1471535 - pt1 - Split RemoteVideoDecoder into GpuDecoderModule and RemoteMediaDataDecoder preparing for new RDD decoder work. r=jya

- also makes RemoteMediaDecoder generic so it can work with the remote decoders on the RDD process
- changes VideoDecoderChild to subclass IRemoteDecoderChild

Differential Revision: https://phabricator.services.mozilla.com/D8482

--HG--
rename : dom/media/ipc/RemoteVideoDecoder.cpp => dom/media/ipc/GpuDecoderModule.cpp
rename : dom/media/ipc/RemoteVideoDecoder.h => dom/media/ipc/GpuDecoderModule.h
extra : moz-landing-system : lando
This commit is contained in:
Michael Froman 2018-11-08 03:45:54 +00:00
parent 9e02794565
commit 25ac4aee06
11 changed files with 424 additions and 339 deletions

View File

@ -0,0 +1,98 @@
/* -*- 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",
[&]() {
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

@ -0,0 +1,50 @@
/* -*- 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

@ -0,0 +1,47 @@
/* -*- 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

@ -0,0 +1,140 @@
/* -*- 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

@ -0,0 +1,66 @@
/* -*- 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 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;
// 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

@ -1,218 +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 "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

@ -1,100 +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_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

@ -9,6 +9,7 @@
#include "MediaResult.h"
#include "PlatformDecoderModule.h"
#include "mozilla/dom/PVideoDecoderChild.h"
#include "IRemoteDecoderChild.h"
namespace mozilla {
namespace dom {
@ -18,12 +19,11 @@ 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();
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;
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,
const layers::TextureFactoryIdentifier& aIdentifier);
void DestroyIPDL();
// Called from IPDL when our actor has been destroyed
void IPDLActorDestroyed();

View File

@ -10,15 +10,20 @@ IPDL_SOURCES += [
'PVideoDecoderManager.ipdl',
]
EXPORTS.mozilla += [
'GpuDecoderModule.h',
'RemoteMediaDataDecoder.h',
]
EXPORTS.mozilla.dom += [
'MediaIPCUtils.h',
'RemoteVideoDecoder.h',
'VideoDecoderManagerChild.h',
'VideoDecoderManagerParent.h',
]
SOURCES += [
'RemoteVideoDecoder.cpp',
'GpuDecoderModule.cpp',
'RemoteMediaDataDecoder.cpp',
'VideoDecoderChild.cpp',
'VideoDecoderManagerChild.cpp',
'VideoDecoderManagerParent.cpp',

View File

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

View File

@ -33,10 +33,7 @@ namespace layers {
class ImageContainer;
} // namespace layers
namespace dom {
class RemoteDecoderModule;
}
class GpuDecoderModule;
class MediaDataDecoder;
class TaskQueue;
class CDMProxy;
@ -214,7 +211,7 @@ protected:
friend class MediaChangeMonitor;
friend class PDMFactory;
friend class dom::RemoteDecoderModule;
friend class GpuDecoderModule;
friend class EMEDecoderModule;
// Indicates if the PlatformDecoderModule supports decoding of aColorDepth.