Line data Source code
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 : #include "RemoteVideoDecoder.h"
7 : #include "VideoDecoderChild.h"
8 : #include "VideoDecoderManagerChild.h"
9 : #include "mozilla/layers/TextureClient.h"
10 : #include "base/thread.h"
11 : #include "MediaInfo.h"
12 : #include "MediaPrefs.h"
13 : #include "ImageContainer.h"
14 : #include "mozilla/layers/SynchronousTask.h"
15 :
16 : namespace mozilla {
17 : namespace dom {
18 :
19 : using base::Thread;
20 : using namespace ipc;
21 : using namespace layers;
22 : using namespace gfx;
23 :
24 0 : RemoteVideoDecoder::RemoteVideoDecoder()
25 0 : : mActor(new VideoDecoderChild())
26 : {
27 0 : }
28 :
29 0 : RemoteVideoDecoder::~RemoteVideoDecoder()
30 : {
31 : // We're about to be destroyed and drop our ref to
32 : // VideoDecoderChild. Make sure we put a ref into the
33 : // task queue for the VideoDecoderChild thread to keep
34 : // it alive until we send the delete message.
35 0 : RefPtr<VideoDecoderChild> actor = mActor;
36 :
37 0 : RefPtr<Runnable> task = NS_NewRunnableFunction(
38 0 : "dom::RemoteVideoDecoder::~RemoteVideoDecoder", [actor]() {
39 0 : MOZ_ASSERT(actor);
40 0 : actor->DestroyIPDL();
41 0 : });
42 :
43 : // Drop out references to the actor so that the last ref
44 : // always gets released on the manager thread.
45 0 : actor = nullptr;
46 0 : mActor = nullptr;
47 :
48 0 : VideoDecoderManagerChild::GetManagerThread()->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
49 0 : }
50 :
51 : RefPtr<MediaDataDecoder::InitPromise>
52 0 : RemoteVideoDecoder::Init()
53 : {
54 0 : RefPtr<RemoteVideoDecoder> self = this;
55 0 : return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
56 0 : __func__, [self, this]() { return mActor->Init(); });
57 : }
58 :
59 : RefPtr<MediaDataDecoder::DecodePromise>
60 0 : RemoteVideoDecoder::Decode(MediaRawData* aSample)
61 : {
62 0 : RefPtr<RemoteVideoDecoder> self = this;
63 0 : RefPtr<MediaRawData> sample = aSample;
64 0 : return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
65 : __func__,
66 0 : [self, this, sample]() { return mActor->Decode(sample); });
67 : }
68 :
69 : RefPtr<MediaDataDecoder::FlushPromise>
70 0 : RemoteVideoDecoder::Flush()
71 : {
72 0 : RefPtr<RemoteVideoDecoder> self = this;
73 0 : return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
74 0 : __func__, [self, this]() { return mActor->Flush(); });
75 : }
76 :
77 : RefPtr<MediaDataDecoder::DecodePromise>
78 0 : RemoteVideoDecoder::Drain()
79 : {
80 0 : RefPtr<RemoteVideoDecoder> self = this;
81 0 : return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
82 0 : __func__, [self, this]() { return mActor->Drain(); });
83 : }
84 :
85 : RefPtr<ShutdownPromise>
86 0 : RemoteVideoDecoder::Shutdown()
87 : {
88 0 : RefPtr<RemoteVideoDecoder> self = this;
89 0 : return InvokeAsync(VideoDecoderManagerChild::GetManagerAbstractThread(),
90 0 : __func__, [self, this]() {
91 0 : mActor->Shutdown();
92 0 : return ShutdownPromise::CreateAndResolve(true, __func__);
93 0 : });
94 : }
95 :
96 : bool
97 0 : RemoteVideoDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const
98 : {
99 0 : return mActor->IsHardwareAccelerated(aFailureReason);
100 : }
101 :
102 : void
103 0 : RemoteVideoDecoder::SetSeekThreshold(const media::TimeUnit& aTime)
104 : {
105 0 : RefPtr<RemoteVideoDecoder> self = this;
106 0 : media::TimeUnit time = aTime;
107 0 : VideoDecoderManagerChild::GetManagerThread()->Dispatch(
108 0 : NS_NewRunnableFunction("dom::RemoteVideoDecoder::SetSeekThreshold",
109 0 : [=]() {
110 0 : MOZ_ASSERT(self->mActor);
111 0 : self->mActor->SetSeekThreshold(time);
112 0 : }),
113 0 : NS_DISPATCH_NORMAL);
114 0 : }
115 :
116 : MediaDataDecoder::ConversionRequired
117 0 : RemoteVideoDecoder::NeedsConversion() const
118 : {
119 0 : return mActor->NeedsConversion();
120 : }
121 :
122 : nsresult
123 0 : RemoteDecoderModule::Startup()
124 : {
125 0 : if (!VideoDecoderManagerChild::GetManagerThread()) {
126 0 : return NS_ERROR_FAILURE;
127 : }
128 0 : return mWrapped->Startup();
129 : }
130 :
131 : bool
132 0 : RemoteDecoderModule::SupportsMimeType(const nsACString& aMimeType,
133 : DecoderDoctorDiagnostics* aDiagnostics) const
134 : {
135 0 : return mWrapped->SupportsMimeType(aMimeType, aDiagnostics);
136 : }
137 :
138 : bool
139 0 : RemoteDecoderModule::Supports(const TrackInfo& aTrackInfo,
140 : DecoderDoctorDiagnostics* aDiagnostics) const
141 : {
142 0 : return mWrapped->Supports(aTrackInfo, aDiagnostics);
143 : }
144 :
145 : static inline bool
146 0 : IsRemoteAcceleratedCompositor(KnowsCompositor* aKnows)
147 : {
148 0 : TextureFactoryIdentifier ident = aKnows->GetTextureFactoryIdentifier();
149 0 : return ident.mParentBackend != LayersBackend::LAYERS_BASIC &&
150 0 : ident.mParentProcessType == GeckoProcessType_GPU;
151 : }
152 :
153 : already_AddRefed<MediaDataDecoder>
154 0 : RemoteDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
155 : {
156 0 : if (!MediaPrefs::PDMUseGPUDecoder() ||
157 0 : !aParams.mKnowsCompositor ||
158 0 : !IsRemoteAcceleratedCompositor(aParams.mKnowsCompositor))
159 : {
160 0 : return mWrapped->CreateVideoDecoder(aParams);
161 : }
162 :
163 0 : RefPtr<RemoteVideoDecoder> object = new RemoteVideoDecoder();
164 :
165 0 : SynchronousTask task("InitIPDL");
166 : bool success;
167 0 : VideoDecoderManagerChild::GetManagerThread()->Dispatch(
168 0 : NS_NewRunnableFunction(
169 : "dom::RemoteDecoderModule::CreateVideoDecoder",
170 0 : [&]() {
171 0 : AutoCompleteTask complete(&task);
172 0 : success = object->mActor->InitIPDL(
173 0 : aParams.VideoConfig(),
174 : aParams.mKnowsCompositor->GetTextureFactoryIdentifier());
175 0 : }),
176 0 : NS_DISPATCH_NORMAL);
177 0 : task.Wait();
178 :
179 0 : if (!success) {
180 0 : return nullptr;
181 : }
182 :
183 0 : return object.forget();
184 : }
185 :
186 : } // namespace dom
187 : } // namespace mozilla
|