RemoteAudioDecoder.cpp (5173B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #include "RemoteAudioDecoder.h" 7 8 #include "MediaDataDecoderProxy.h" 9 #include "PDMFactory.h" 10 #include "RemoteCDMParent.h" 11 #include "RemoteMediaManagerChild.h" 12 #include "RemoteMediaManagerParent.h" 13 #include "mozilla/StaticPrefs_media.h" 14 15 namespace mozilla { 16 17 RemoteAudioDecoderChild::RemoteAudioDecoderChild(RemoteMediaIn aLocation) 18 : RemoteDecoderChild(aLocation) {} 19 20 MediaResult RemoteAudioDecoderChild::ProcessOutput( 21 DecodedOutputIPDL&& aDecodedData) { 22 AssertOnManagerThread(); 23 24 MOZ_ASSERT(aDecodedData.type() == DecodedOutputIPDL::TArrayOfRemoteAudioData); 25 RefPtr<ArrayOfRemoteAudioData> arrayData = 26 aDecodedData.get_ArrayOfRemoteAudioData(); 27 28 for (size_t i = 0; i < arrayData->Count(); i++) { 29 RefPtr<AudioData> data = arrayData->ElementAt(i); 30 if (!data) { 31 // OOM 32 return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__); 33 } 34 mDecodedData.AppendElement(data); 35 } 36 return NS_OK; 37 } 38 39 MediaResult RemoteAudioDecoderChild::InitIPDL( 40 const AudioInfo& aAudioInfo, const CreateDecoderParams::OptionSet& aOptions, 41 const Maybe<uint64_t>& aMediaEngineId, PRemoteCDMActor* aCDM) { 42 RefPtr<RemoteMediaManagerChild> manager = 43 RemoteMediaManagerChild::GetSingleton(mLocation); 44 45 // The manager isn't available because RemoteMediaManagerChild has been 46 // initialized with null end points and we don't want to decode video on RDD 47 // process anymore. Return false here so that we can fallback to other PDMs. 48 if (!manager) { 49 return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, 50 RESULT_DETAIL("RemoteMediaManager is not available.")); 51 } 52 53 if (!manager->CanSend()) { 54 return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, 55 RESULT_DETAIL("RemoteMediaManager unable to send.")); 56 } 57 58 // If we are given a remote CDM, we need to make sure that it has been remoted 59 // into the same process as the decoder. 60 PRemoteCDMChild* cdm = nullptr; 61 if (aCDM) { 62 if (aCDM->GetLocation() != mLocation) { 63 return MediaResult( 64 NS_ERROR_DOM_MEDIA_FATAL_ERR, 65 RESULT_DETAIL("PRemoteCDMActor is not in same process.")); 66 } 67 68 cdm = aCDM->AsPRemoteCDMChild(); 69 if (!cdm) { 70 return MediaResult( 71 NS_ERROR_DOM_MEDIA_FATAL_ERR, 72 RESULT_DETAIL("PRemoteCDMActor is not PRemoteCDMChild.")); 73 } 74 } 75 76 mIPDLSelfRef = this; 77 MOZ_ALWAYS_TRUE(manager->SendPRemoteDecoderConstructor( 78 this, aAudioInfo, aOptions, Nothing(), aMediaEngineId, Nothing(), cdm)); 79 return NS_OK; 80 } 81 82 RemoteAudioDecoderParent::RemoteAudioDecoderParent( 83 RemoteMediaManagerParent* aParent, const AudioInfo& aAudioInfo, 84 const CreateDecoderParams::OptionSet& aOptions, 85 nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue, 86 Maybe<uint64_t> aMediaEngineId, RemoteCDMParent* aCDM) 87 : RemoteDecoderParent(aParent, aOptions, aManagerThread, aDecodeTaskQueue, 88 aMediaEngineId, Nothing(), aCDM), 89 mAudioInfo(aAudioInfo) {} 90 91 IPCResult RemoteAudioDecoderParent::RecvConstruct( 92 ConstructResolver&& aResolver) { 93 auto params = CreateDecoderParams{ 94 mAudioInfo, static_cast<PRemoteCDMActor*>(mCDM.get()), 95 mOptions, CreateDecoderParams::WrapperSet({/* No wrapper */}), 96 mMediaEngineId, mTrackingId}; 97 98 mParent->EnsurePDMFactory().CreateDecoder(params)->Then( 99 GetCurrentSerialEventTarget(), __func__, 100 [resolver = std::move(aResolver), self = RefPtr{this}]( 101 PlatformDecoderModule::CreateDecoderPromise::ResolveOrRejectValue&& 102 aValue) { 103 if (aValue.IsReject()) { 104 resolver(aValue.RejectValue()); 105 return; 106 } 107 MOZ_ASSERT(aValue.ResolveValue()); 108 self->mDecoder = 109 new MediaDataDecoderProxy(aValue.ResolveValue().forget(), 110 do_AddRef(self->mDecodeTaskQueue.get())); 111 resolver(NS_OK); 112 }); 113 114 return IPC_OK(); 115 } 116 117 MediaResult RemoteAudioDecoderParent::ProcessDecodedData( 118 MediaDataDecoder::DecodedData&& aData, DecodedOutputIPDL& aDecodedData) { 119 MOZ_ASSERT(OnManagerThread()); 120 121 // Converted array to array of RefPtr<AudioData> 122 nsTArray<RefPtr<AudioData>> data(aData.Length()); 123 for (auto&& element : aData) { 124 MOZ_ASSERT(element->mType == MediaData::Type::AUDIO_DATA, 125 "Can only decode audio using RemoteAudioDecoderParent!"); 126 AudioData* audio = static_cast<AudioData*>(element.get()); 127 data.AppendElement(audio); 128 } 129 auto array = MakeRefPtr<ArrayOfRemoteAudioData>(); 130 if (!array->Fill(std::move(data), 131 [&](size_t aSize) { return AllocateBuffer(aSize); })) { 132 return MediaResult( 133 NS_ERROR_OUT_OF_MEMORY, 134 "Failed in RemoteAudioDecoderParent::ProcessDecodedData"); 135 } 136 aDecodedData = std::move(array); 137 return NS_OK; 138 } 139 140 } // namespace mozilla