diff options
Diffstat (limited to 'dom/media/ipc/RemoteVideoDecoder.cpp')
-rw-r--r-- | dom/media/ipc/RemoteVideoDecoder.cpp | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/dom/media/ipc/RemoteVideoDecoder.cpp b/dom/media/ipc/RemoteVideoDecoder.cpp new file mode 100644 index 000000000..c6131bb91 --- /dev/null +++ b/dom/media/ipc/RemoteVideoDecoder.cpp @@ -0,0 +1,176 @@ +/* -*- 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 "base/thread.h" +#include "MediaInfo.h" +#include "MediaPrefs.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(MediaDataDecoderCallback* aCallback) + : mActor(new VideoDecoderChild()) +{ +#ifdef DEBUG + mCallback = aCallback; +#endif + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); +} + +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; + VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([actor]() { + MOZ_ASSERT(actor); + actor->DestroyIPDL(); + }), NS_DISPATCH_NORMAL); +} + +RefPtr<MediaDataDecoder::InitPromise> +RemoteVideoDecoder::Init() +{ + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(), + this, __func__, &RemoteVideoDecoder::InitInternal); +} + +RefPtr<MediaDataDecoder::InitPromise> +RemoteVideoDecoder::InitInternal() +{ + MOZ_ASSERT(mActor); + MOZ_ASSERT(NS_GetCurrentThread() == VideoDecoderManagerChild::GetManagerThread()); + return mActor->Init(); +} + +void +RemoteVideoDecoder::Input(MediaRawData* aSample) +{ + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + RefPtr<RemoteVideoDecoder> self = this; + RefPtr<MediaRawData> sample = aSample; + VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([self, sample]() { + MOZ_ASSERT(self->mActor); + self->mActor->Input(sample); + }), NS_DISPATCH_NORMAL); +} + +void +RemoteVideoDecoder::Flush() +{ + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + RefPtr<RemoteVideoDecoder> self = this; + VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([self]() { + MOZ_ASSERT(self->mActor); + self->mActor->Flush(); + }), NS_DISPATCH_NORMAL); +} + +void +RemoteVideoDecoder::Drain() +{ + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + RefPtr<RemoteVideoDecoder> self = this; + VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([self]() { + MOZ_ASSERT(self->mActor); + self->mActor->Drain(); + }), NS_DISPATCH_NORMAL); +} + +void +RemoteVideoDecoder::Shutdown() +{ + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + SynchronousTask task("Shutdown"); + RefPtr<RemoteVideoDecoder> self = this; + VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([&]() { + AutoCompleteTask complete(&task); + MOZ_ASSERT(self->mActor); + self->mActor->Shutdown(); + }), NS_DISPATCH_NORMAL); + task.Wait(); +} + +bool +RemoteVideoDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const +{ + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + return mActor->IsHardwareAccelerated(aFailureReason); +} + +void +RemoteVideoDecoder::SetSeekThreshold(const media::TimeUnit& aTime) +{ + MOZ_ASSERT(mCallback->OnReaderTaskQueue()); + RefPtr<RemoteVideoDecoder> self = this; + media::TimeUnit time = aTime; + VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([=]() { + MOZ_ASSERT(self->mActor); + self->mActor->SetSeekThreshold(time); + }), NS_DISPATCH_NORMAL); + +} + +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); +} + +PlatformDecoderModule::ConversionRequired +RemoteDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const +{ + return mWrapped->DecoderNeedsConversion(aConfig); +} + +already_AddRefed<MediaDataDecoder> +RemoteDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams) +{ + if (!MediaPrefs::PDMUseGPUDecoder() || + !aParams.mKnowsCompositor || + aParams.mKnowsCompositor->GetTextureFactoryIdentifier().mParentProcessType != GeckoProcessType_GPU) { + return mWrapped->CreateVideoDecoder(aParams); + } + + MediaDataDecoderCallback* callback = aParams.mCallback; + MOZ_ASSERT(callback->OnReaderTaskQueue()); + RefPtr<RemoteVideoDecoder> object = new RemoteVideoDecoder(callback); + + VideoInfo info = aParams.VideoConfig(); + + TextureFactoryIdentifier ident = aParams.mKnowsCompositor->GetTextureFactoryIdentifier(); + VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([=]() { + object->mActor->InitIPDL(callback, info, ident); + }), NS_DISPATCH_NORMAL); + + return object.forget(); +} + +} // namespace dom +} // namespace mozilla |