summaryrefslogtreecommitdiffstats
path: root/dom/media/ipc/RemoteVideoDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/ipc/RemoteVideoDecoder.cpp')
-rw-r--r--dom/media/ipc/RemoteVideoDecoder.cpp176
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