summaryrefslogtreecommitdiffstats
path: root/dom/media/ipc/RemoteMediaDataDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/ipc/RemoteMediaDataDecoder.cpp')
-rw-r--r--dom/media/ipc/RemoteMediaDataDecoder.cpp163
1 files changed, 163 insertions, 0 deletions
diff --git a/dom/media/ipc/RemoteMediaDataDecoder.cpp b/dom/media/ipc/RemoteMediaDataDecoder.cpp
new file mode 100644
index 0000000000..6db3c0d940
--- /dev/null
+++ b/dom/media/ipc/RemoteMediaDataDecoder.cpp
@@ -0,0 +1,163 @@
+/* -*- 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 "RemoteMediaDataDecoder.h"
+
+#include "RemoteDecoderChild.h"
+#include "RemoteDecoderManagerChild.h"
+
+namespace mozilla {
+
+#ifdef LOG
+# undef LOG
+#endif // LOG
+#define LOG(arg, ...) \
+ DDMOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, "::%s: " arg, __func__, \
+ ##__VA_ARGS__)
+
+RemoteMediaDataDecoder::RemoteMediaDataDecoder(RemoteDecoderChild* aChild)
+ : mChild(aChild) {
+ LOG("%p is created", this);
+}
+
+RemoteMediaDataDecoder::~RemoteMediaDataDecoder() {
+ if (mChild) {
+ // Shutdown didn't get called. This can happen if the creation of the
+ // decoder got interrupted while pending.
+ nsCOMPtr<nsISerialEventTarget> thread =
+ RemoteDecoderManagerChild::GetManagerThread();
+ MOZ_ASSERT(thread);
+ thread->Dispatch(NS_NewRunnableFunction(
+ "RemoteMediaDataDecoderShutdown", [child = std::move(mChild), thread] {
+ child->Shutdown()->Then(
+ thread, __func__,
+ [child](const ShutdownPromise::ResolveOrRejectValue& aValue) {
+ child->DestroyIPDL();
+ });
+ }));
+ }
+ LOG("%p is released", this);
+}
+
+RefPtr<MediaDataDecoder::InitPromise> RemoteMediaDataDecoder::Init() {
+ RefPtr<RemoteMediaDataDecoder> self = this;
+ return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__,
+ [self]() { return self->mChild->Init(); })
+ ->Then(
+ RemoteDecoderManagerChild::GetManagerThread(), __func__,
+ [self, this](TrackType aTrack) {
+ // If shutdown has started in the meantime shutdown promise may
+ // be resloved before this task. In this case mChild will be null
+ // and the init promise has to be canceled.
+ if (!mChild) {
+ return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_CANCELED,
+ __func__);
+ }
+ mDescription = mChild->GetDescriptionName();
+ mProcessName = mChild->GetProcessName();
+ mCodecName = mChild->GetCodecName();
+ mIsHardwareAccelerated =
+ mChild->IsHardwareAccelerated(mHardwareAcceleratedReason);
+ mConversion = mChild->NeedsConversion();
+ LOG("%p RemoteDecoderChild has been initialized - description: %s, "
+ "process: %s, codec: %s",
+ this, mDescription.get(), mProcessName.get(), mCodecName.get());
+ 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(
+ RemoteDecoderManagerChild::GetManagerThread(), __func__,
+ [self, sample]() {
+ return self->mChild->Decode(nsTArray<RefPtr<MediaRawData>>{sample});
+ });
+}
+
+RefPtr<MediaDataDecoder::DecodePromise> RemoteMediaDataDecoder::DecodeBatch(
+ nsTArray<RefPtr<MediaRawData>>&& aSamples) {
+ RefPtr<RemoteMediaDataDecoder> self = this;
+ return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__,
+ [self, samples = std::move(aSamples)]() {
+ return self->mChild->Decode(samples);
+ });
+}
+
+RefPtr<MediaDataDecoder::FlushPromise> RemoteMediaDataDecoder::Flush() {
+ RefPtr<RemoteMediaDataDecoder> self = this;
+ return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__,
+ [self]() { return self->mChild->Flush(); });
+}
+
+RefPtr<MediaDataDecoder::DecodePromise> RemoteMediaDataDecoder::Drain() {
+ RefPtr<RemoteMediaDataDecoder> self = this;
+ return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__,
+ [self]() { return self->mChild->Drain(); });
+}
+
+RefPtr<ShutdownPromise> RemoteMediaDataDecoder::Shutdown() {
+ RefPtr<RemoteMediaDataDecoder> self = this;
+ return InvokeAsync(
+ RemoteDecoderManagerChild::GetManagerThread(), __func__, [self]() {
+ RefPtr<ShutdownPromise> p = self->mChild->Shutdown();
+
+ // 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.
+ p->Then(RemoteDecoderManagerChild::GetManagerThread(), __func__,
+ [child = std::move(self->mChild)](
+ const ShutdownPromise::ResolveOrRejectValue& aValue) {
+ MOZ_ASSERT(aValue.IsResolve());
+ child->DestroyIPDL();
+ return ShutdownPromise::CreateAndResolveOrReject(aValue,
+ __func__);
+ });
+ return p;
+ });
+}
+
+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;
+ RemoteDecoderManagerChild::GetManagerThread()->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;
+}
+
+nsCString RemoteMediaDataDecoder::GetProcessName() const {
+ return mProcessName;
+}
+
+nsCString RemoteMediaDataDecoder::GetCodecName() const { return mCodecName; }
+
+#undef LOG
+
+} // namespace mozilla