/src/mozilla-central/dom/media/ipc/RemoteVideoDecoder.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=99: */ |
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 | | |
7 | | #include "RemoteVideoDecoder.h" |
8 | | #include "VideoDecoderChild.h" |
9 | | #include "VideoDecoderManagerChild.h" |
10 | | #include "mozilla/layers/TextureClient.h" |
11 | | #include "mozilla/StaticPrefs.h" |
12 | | #include "base/thread.h" |
13 | | #include "MediaInfo.h" |
14 | | #include "ImageContainer.h" |
15 | | #include "mozilla/layers/SynchronousTask.h" |
16 | | |
17 | | namespace mozilla { |
18 | | namespace dom { |
19 | | |
20 | | using base::Thread; |
21 | | using namespace ipc; |
22 | | using namespace layers; |
23 | | using namespace gfx; |
24 | | |
25 | | RemoteVideoDecoder::RemoteVideoDecoder() |
26 | | : mActor(new VideoDecoderChild()) |
27 | | , mDescription("RemoteVideoDecoder") |
28 | | , mIsHardwareAccelerated(false) |
29 | | , mConversion(MediaDataDecoder::ConversionRequired::kNeedNone) |
30 | 0 | { |
31 | 0 | } |
32 | | |
33 | | RemoteVideoDecoder::~RemoteVideoDecoder() |
34 | 0 | { |
35 | 0 | // We're about to be destroyed and drop our ref to |
36 | 0 | // VideoDecoderChild. Make sure we put a ref into the |
37 | 0 | // task queue for the VideoDecoderChild thread to keep |
38 | 0 | // it alive until we send the delete message. |
39 | 0 | RefPtr<VideoDecoderChild> actor = mActor; |
40 | 0 |
|
41 | 0 | RefPtr<Runnable> task = NS_NewRunnableFunction( |
42 | 0 | "dom::RemoteVideoDecoder::~RemoteVideoDecoder", [actor]() { |
43 | 0 | MOZ_ASSERT(actor); |
44 | 0 | actor->DestroyIPDL(); |
45 | 0 | }); |
46 | 0 |
|
47 | 0 | // Drop out references to the actor so that the last ref |
48 | 0 | // always gets released on the manager thread. |
49 | 0 | actor = nullptr; |
50 | 0 | mActor = nullptr; |
51 | 0 |
|
52 | 0 | VideoDecoderManagerChild::GetManagerThread()->Dispatch(task.forget(), |
53 | 0 | NS_DISPATCH_NORMAL); |
54 | 0 | } |
55 | | |
56 | | RefPtr<MediaDataDecoder::InitPromise> |
57 | | RemoteVideoDecoder::Init() |
58 | 0 | { |
59 | 0 | RefPtr<RemoteVideoDecoder> self = this; |
60 | 0 | return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(), |
61 | 0 | __func__, |
62 | 0 | [self]() { return self->mActor->Init(); }) |
63 | 0 | ->Then(VideoDecoderManagerChild::GetManagerAbstractThread(), |
64 | 0 | __func__, |
65 | 0 | [self, this](TrackType aTrack) { |
66 | 0 | mDescription = |
67 | 0 | mActor->GetDescriptionName() + NS_LITERAL_CSTRING(" (remote)"); |
68 | 0 | mIsHardwareAccelerated = |
69 | 0 | mActor->IsHardwareAccelerated(mHardwareAcceleratedReason); |
70 | 0 | mConversion = mActor->NeedsConversion(); |
71 | 0 | return InitPromise::CreateAndResolve(aTrack, __func__); |
72 | 0 | }, |
73 | 0 | [self](const MediaResult& aError) { |
74 | 0 | return InitPromise::CreateAndReject(aError, __func__); |
75 | 0 | }); |
76 | 0 | } |
77 | | |
78 | | RefPtr<MediaDataDecoder::DecodePromise> |
79 | | RemoteVideoDecoder::Decode(MediaRawData* aSample) |
80 | 0 | { |
81 | 0 | RefPtr<RemoteVideoDecoder> self = this; |
82 | 0 | RefPtr<MediaRawData> sample = aSample; |
83 | 0 | return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(), |
84 | 0 | __func__, |
85 | 0 | [self, sample]() { return self->mActor->Decode(sample); }); |
86 | 0 | } |
87 | | |
88 | | RefPtr<MediaDataDecoder::FlushPromise> |
89 | | RemoteVideoDecoder::Flush() |
90 | 0 | { |
91 | 0 | RefPtr<RemoteVideoDecoder> self = this; |
92 | 0 | return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(), |
93 | 0 | __func__, [self]() { return self->mActor->Flush(); }); |
94 | 0 | } |
95 | | |
96 | | RefPtr<MediaDataDecoder::DecodePromise> |
97 | | RemoteVideoDecoder::Drain() |
98 | 0 | { |
99 | 0 | RefPtr<RemoteVideoDecoder> self = this; |
100 | 0 | return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(), |
101 | 0 | __func__, [self]() { return self->mActor->Drain(); }); |
102 | 0 | } |
103 | | |
104 | | RefPtr<ShutdownPromise> |
105 | | RemoteVideoDecoder::Shutdown() |
106 | 0 | { |
107 | 0 | RefPtr<RemoteVideoDecoder> self = this; |
108 | 0 | return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(), |
109 | 0 | __func__, [self]() { |
110 | 0 | self->mActor->Shutdown(); |
111 | 0 | return ShutdownPromise::CreateAndResolve(true, __func__); |
112 | 0 | }); |
113 | 0 | } |
114 | | |
115 | | bool |
116 | | RemoteVideoDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const |
117 | 0 | { |
118 | 0 | aFailureReason = mHardwareAcceleratedReason; |
119 | 0 | return mIsHardwareAccelerated; |
120 | 0 | } |
121 | | |
122 | | void |
123 | | RemoteVideoDecoder::SetSeekThreshold(const media::TimeUnit& aTime) |
124 | 0 | { |
125 | 0 | RefPtr<RemoteVideoDecoder> self = this; |
126 | 0 | media::TimeUnit time = aTime; |
127 | 0 | VideoDecoderManagerChild::GetManagerThread()->Dispatch( |
128 | 0 | NS_NewRunnableFunction("dom::RemoteVideoDecoder::SetSeekThreshold", |
129 | 0 | [=]() { |
130 | 0 | MOZ_ASSERT(self->mActor); |
131 | 0 | self->mActor->SetSeekThreshold(time); |
132 | 0 | }), |
133 | 0 | NS_DISPATCH_NORMAL); |
134 | 0 | } |
135 | | |
136 | | MediaDataDecoder::ConversionRequired |
137 | | RemoteVideoDecoder::NeedsConversion() const |
138 | 0 | { |
139 | 0 | return mConversion; |
140 | 0 | } |
141 | | |
142 | | nsresult |
143 | | RemoteDecoderModule::Startup() |
144 | 0 | { |
145 | 0 | if (!VideoDecoderManagerChild::GetManagerThread()) { |
146 | 0 | return NS_ERROR_FAILURE; |
147 | 0 | } |
148 | 0 | return mWrapped->Startup(); |
149 | 0 | } |
150 | | |
151 | | bool |
152 | | RemoteDecoderModule::SupportsMimeType(const nsACString& aMimeType, |
153 | | DecoderDoctorDiagnostics* aDiagnostics) const |
154 | 0 | { |
155 | 0 | return mWrapped->SupportsMimeType(aMimeType, aDiagnostics); |
156 | 0 | } |
157 | | |
158 | | bool |
159 | | RemoteDecoderModule::Supports(const TrackInfo& aTrackInfo, |
160 | | DecoderDoctorDiagnostics* aDiagnostics) const |
161 | 0 | { |
162 | 0 | return mWrapped->Supports(aTrackInfo, aDiagnostics); |
163 | 0 | } |
164 | | |
165 | | static inline bool |
166 | | IsRemoteAcceleratedCompositor(KnowsCompositor* aKnows) |
167 | 0 | { |
168 | 0 | TextureFactoryIdentifier ident = aKnows->GetTextureFactoryIdentifier(); |
169 | 0 | return ident.mParentBackend != LayersBackend::LAYERS_BASIC && |
170 | 0 | ident.mParentProcessType == GeckoProcessType_GPU; |
171 | 0 | } |
172 | | |
173 | | already_AddRefed<MediaDataDecoder> |
174 | | RemoteDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams) |
175 | 0 | { |
176 | 0 | if (!StaticPrefs::MediaGpuProcessDecoder() || |
177 | 0 | !aParams.mKnowsCompositor || |
178 | 0 | !IsRemoteAcceleratedCompositor(aParams.mKnowsCompositor)) |
179 | 0 | { |
180 | 0 | return mWrapped->CreateVideoDecoder(aParams); |
181 | 0 | } |
182 | 0 | |
183 | 0 | RefPtr<RemoteVideoDecoder> object = new RemoteVideoDecoder(); |
184 | 0 |
|
185 | 0 | SynchronousTask task("InitIPDL"); |
186 | 0 | MediaResult result(NS_OK); |
187 | 0 | VideoDecoderManagerChild::GetManagerThread()->Dispatch( |
188 | 0 | NS_NewRunnableFunction( |
189 | 0 | "dom::RemoteDecoderModule::CreateVideoDecoder", |
190 | 0 | [&]() { |
191 | 0 | AutoCompleteTask complete(&task); |
192 | 0 | result = object->mActor->InitIPDL( |
193 | 0 | aParams.VideoConfig(), |
194 | 0 | aParams.mRate.mValue, |
195 | 0 | aParams.mKnowsCompositor->GetTextureFactoryIdentifier()); |
196 | 0 | }), |
197 | 0 | NS_DISPATCH_NORMAL); |
198 | 0 | task.Wait(); |
199 | 0 |
|
200 | 0 | if (NS_FAILED(result)) { |
201 | 0 | if (aParams.mError) { |
202 | 0 | *aParams.mError = result; |
203 | 0 | } |
204 | 0 | return nullptr; |
205 | 0 | } |
206 | 0 |
|
207 | 0 | return object.forget(); |
208 | 0 | } |
209 | | |
210 | | nsCString |
211 | | RemoteVideoDecoder::GetDescriptionName() const |
212 | 0 | { |
213 | 0 | return mDescription; |
214 | 0 | } |
215 | | |
216 | | } // namespace dom |
217 | | } // namespace mozilla |