Coverage Report

Created: 2018-09-25 14:53

/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