зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound. a=merge on a CLOSED TREE
This commit is contained in:
Коммит
66d4e9abff
|
@ -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",
|
||||
[&]() {
|
||||
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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -1,66 +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 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
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
@ -6,25 +6,19 @@
|
|||
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PMediaDecoderParams.ipdlh',
|
||||
'PVideoDecoder.ipdl',
|
||||
'PVideoDecoderManager.ipdl',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'GpuDecoderModule.h',
|
||||
'RemoteMediaDataDecoder.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'MediaIPCUtils.h',
|
||||
'RemoteVideoDecoder.h',
|
||||
'VideoDecoderManagerChild.h',
|
||||
'VideoDecoderManagerParent.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'GpuDecoderModule.cpp',
|
||||
'RemoteMediaDataDecoder.cpp',
|
||||
'RemoteVideoDecoder.cpp',
|
||||
'VideoDecoderChild.cpp',
|
||||
'VideoDecoderManagerChild.cpp',
|
||||
'VideoDecoderManagerParent.cpp',
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
#include "MP4Decoder.h"
|
||||
#include "VPXDecoder.h"
|
||||
#include "mozilla/GpuDecoderModule.h"
|
||||
#include "mozilla/dom/RemoteVideoDecoder.h"
|
||||
|
||||
#include "H264.h"
|
||||
|
||||
|
@ -355,7 +355,7 @@ PDMFactory::CreatePDMs()
|
|||
#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 {
|
||||
|
|
|
@ -33,7 +33,10 @@ namespace layers {
|
|||
class ImageContainer;
|
||||
} // namespace layers
|
||||
|
||||
class GpuDecoderModule;
|
||||
namespace dom {
|
||||
class RemoteDecoderModule;
|
||||
}
|
||||
|
||||
class MediaDataDecoder;
|
||||
class TaskQueue;
|
||||
class CDMProxy;
|
||||
|
@ -211,7 +214,7 @@ protected:
|
|||
|
||||
friend class MediaChangeMonitor;
|
||||
friend class PDMFactory;
|
||||
friend class GpuDecoderModule;
|
||||
friend class dom::RemoteDecoderModule;
|
||||
friend class EMEDecoderModule;
|
||||
|
||||
// Indicates if the PlatformDecoderModule supports decoding of aColorDepth.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче