summaryrefslogtreecommitdiffstats
path: root/dom/media/ipc/RemoteAudioDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/media/ipc/RemoteAudioDecoder.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/dom/media/ipc/RemoteAudioDecoder.cpp b/dom/media/ipc/RemoteAudioDecoder.cpp
new file mode 100644
index 0000000000..09b420261f
--- /dev/null
+++ b/dom/media/ipc/RemoteAudioDecoder.cpp
@@ -0,0 +1,121 @@
+/* -*- 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 "RemoteAudioDecoder.h"
+
+#include "MediaDataDecoderProxy.h"
+#include "PDMFactory.h"
+#include "RemoteDecoderManagerChild.h"
+#include "RemoteDecoderManagerParent.h"
+#include "mozilla/PodOperations.h"
+#include "mozilla/StaticPrefs_media.h"
+
+namespace mozilla {
+
+RemoteAudioDecoderChild::RemoteAudioDecoderChild(RemoteDecodeIn aLocation)
+ : RemoteDecoderChild(aLocation) {}
+
+MediaResult RemoteAudioDecoderChild::ProcessOutput(
+ DecodedOutputIPDL&& aDecodedData) {
+ AssertOnManagerThread();
+
+ MOZ_ASSERT(aDecodedData.type() == DecodedOutputIPDL::TArrayOfRemoteAudioData);
+ RefPtr<ArrayOfRemoteAudioData> arrayData =
+ aDecodedData.get_ArrayOfRemoteAudioData();
+
+ for (size_t i = 0; i < arrayData->Count(); i++) {
+ RefPtr<AudioData> data = arrayData->ElementAt(i);
+ if (!data) {
+ // OOM
+ return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__);
+ }
+ mDecodedData.AppendElement(data);
+ }
+ return NS_OK;
+}
+
+MediaResult RemoteAudioDecoderChild::InitIPDL(
+ const AudioInfo& aAudioInfo, const CreateDecoderParams::OptionSet& aOptions,
+ const Maybe<uint64_t>& aMediaEngineId) {
+ RefPtr<RemoteDecoderManagerChild> manager =
+ RemoteDecoderManagerChild::GetSingleton(mLocation);
+
+ // The manager isn't available because RemoteDecoderManagerChild has been
+ // initialized with null end points and we don't want to decode video on RDD
+ // process anymore. Return false here so that we can fallback to other PDMs.
+ if (!manager) {
+ return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ RESULT_DETAIL("RemoteDecoderManager is not available."));
+ }
+
+ if (!manager->CanSend()) {
+ return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ RESULT_DETAIL("RemoteDecoderManager unable to send."));
+ }
+
+ mIPDLSelfRef = this;
+ Unused << manager->SendPRemoteDecoderConstructor(
+ this, aAudioInfo, aOptions, Nothing(), aMediaEngineId, Nothing());
+ return NS_OK;
+}
+
+RemoteAudioDecoderParent::RemoteAudioDecoderParent(
+ RemoteDecoderManagerParent* aParent, const AudioInfo& aAudioInfo,
+ const CreateDecoderParams::OptionSet& aOptions,
+ nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue,
+ Maybe<uint64_t> aMediaEngineId)
+ : RemoteDecoderParent(aParent, aOptions, aManagerThread, aDecodeTaskQueue,
+ aMediaEngineId, Nothing()),
+ mAudioInfo(aAudioInfo) {}
+
+IPCResult RemoteAudioDecoderParent::RecvConstruct(
+ ConstructResolver&& aResolver) {
+ auto params = CreateDecoderParams{mAudioInfo, mOptions,
+ CreateDecoderParams::NoWrapper(true),
+ mMediaEngineId, mTrackingId};
+
+ mParent->EnsurePDMFactory().CreateDecoder(params)->Then(
+ GetCurrentSerialEventTarget(), __func__,
+ [resolver = std::move(aResolver), self = RefPtr{this}](
+ PlatformDecoderModule::CreateDecoderPromise::ResolveOrRejectValue&&
+ aValue) {
+ if (aValue.IsReject()) {
+ resolver(aValue.RejectValue());
+ return;
+ }
+ MOZ_ASSERT(aValue.ResolveValue());
+ self->mDecoder =
+ new MediaDataDecoderProxy(aValue.ResolveValue().forget(),
+ do_AddRef(self->mDecodeTaskQueue.get()));
+ resolver(NS_OK);
+ });
+
+ return IPC_OK();
+}
+
+MediaResult RemoteAudioDecoderParent::ProcessDecodedData(
+ MediaDataDecoder::DecodedData&& aData, DecodedOutputIPDL& aDecodedData) {
+ MOZ_ASSERT(OnManagerThread());
+
+ // Converted array to array of RefPtr<AudioData>
+ nsTArray<RefPtr<AudioData>> data(aData.Length());
+ for (auto&& element : aData) {
+ MOZ_ASSERT(element->mType == MediaData::Type::AUDIO_DATA,
+ "Can only decode audio using RemoteAudioDecoderParent!");
+ AudioData* audio = static_cast<AudioData*>(element.get());
+ data.AppendElement(audio);
+ }
+ auto array = MakeRefPtr<ArrayOfRemoteAudioData>();
+ if (!array->Fill(std::move(data),
+ [&](size_t aSize) { return AllocateBuffer(aSize); })) {
+ return MediaResult(
+ NS_ERROR_OUT_OF_MEMORY,
+ "Failed in RemoteAudioDecoderParent::ProcessDecodedData");
+ }
+ aDecodedData = std::move(array);
+ return NS_OK;
+}
+
+} // namespace mozilla