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 "RemoteMediaDataDecoder.h"
8 #include "RemoteDecoderChild.h"
9 #include "RemoteDecoderManagerChild.h"
16 #define LOG(arg, ...) \
17 DDMOZ_LOG(sPDMLog, mozilla::LogLevel::Debug, "::%s: " arg, __func__, \
20 RemoteMediaDataDecoder::RemoteMediaDataDecoder(RemoteDecoderChild
* aChild
)
22 mDescription("RemoteMediaDataDecoder"_ns
),
23 mProcessName("unknown"_ns
),
24 mCodecName("unknown"_ns
),
25 mIsHardwareAccelerated(false),
26 mConversion(ConversionRequired::kNeedNone
),
27 mShouldDecoderAlwaysBeRecycled(false) {
28 LOG("%p is created", this);
31 RemoteMediaDataDecoder::~RemoteMediaDataDecoder() {
33 // Shutdown didn't get called. This can happen if the creation of the
34 // decoder got interrupted while pending.
35 nsCOMPtr
<nsISerialEventTarget
> thread
=
36 RemoteDecoderManagerChild::GetManagerThread();
38 thread
->Dispatch(NS_NewRunnableFunction(
39 "RemoteMediaDataDecoderShutdown", [child
= std::move(mChild
), thread
] {
40 child
->Shutdown()->Then(
42 [child
](const ShutdownPromise::ResolveOrRejectValue
& aValue
) {
47 LOG("%p is released", this);
50 RefPtr
<MediaDataDecoder::InitPromise
> RemoteMediaDataDecoder::Init() {
51 RefPtr
<RemoteMediaDataDecoder
> self
= this;
52 return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
53 [self
]() { return self
->mChild
->Init(); })
55 RemoteDecoderManagerChild::GetManagerThread(), __func__
,
56 [self
, this](TrackType aTrack
) {
57 MutexAutoLock
lock(mMutex
);
58 // If shutdown has started in the meantime shutdown promise may
59 // be resloved before this task. In this case mChild will be null
60 // and the init promise has to be canceled.
62 return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_CANCELED
,
65 mDescription
= mChild
->GetDescriptionName();
66 mProcessName
= mChild
->GetProcessName();
67 mCodecName
= mChild
->GetCodecName();
68 mIsHardwareAccelerated
=
69 mChild
->IsHardwareAccelerated(mHardwareAcceleratedReason
);
70 mConversion
= mChild
->NeedsConversion();
71 mShouldDecoderAlwaysBeRecycled
=
72 mChild
->ShouldDecoderAlwaysBeRecycled();
73 LOG("%p RemoteDecoderChild has been initialized - description: %s, "
74 "process: %s, codec: %s",
75 this, mDescription
.get(), mProcessName
.get(), mCodecName
.get());
76 return InitPromise::CreateAndResolve(aTrack
, __func__
);
78 [self
](const MediaResult
& aError
) {
79 return InitPromise::CreateAndReject(aError
, __func__
);
83 RefPtr
<MediaDataDecoder::DecodePromise
> RemoteMediaDataDecoder::Decode(
84 MediaRawData
* aSample
) {
85 RefPtr
<RemoteMediaDataDecoder
> self
= this;
86 RefPtr
<MediaRawData
> sample
= aSample
;
88 RemoteDecoderManagerChild::GetManagerThread(), __func__
,
90 return self
->mChild
->Decode(nsTArray
<RefPtr
<MediaRawData
>>{sample
});
94 RefPtr
<MediaDataDecoder::DecodePromise
> RemoteMediaDataDecoder::DecodeBatch(
95 nsTArray
<RefPtr
<MediaRawData
>>&& aSamples
) {
96 RefPtr
<RemoteMediaDataDecoder
> self
= this;
97 return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
98 [self
, samples
= std::move(aSamples
)]() {
99 return self
->mChild
->Decode(samples
);
103 RefPtr
<MediaDataDecoder::FlushPromise
> RemoteMediaDataDecoder::Flush() {
104 RefPtr
<RemoteMediaDataDecoder
> self
= this;
105 return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
106 [self
]() { return self
->mChild
->Flush(); });
109 RefPtr
<MediaDataDecoder::DecodePromise
> RemoteMediaDataDecoder::Drain() {
110 RefPtr
<RemoteMediaDataDecoder
> self
= this;
111 return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
112 [self
]() { return self
->mChild
->Drain(); });
115 RefPtr
<ShutdownPromise
> RemoteMediaDataDecoder::Shutdown() {
116 RefPtr
<RemoteMediaDataDecoder
> self
= this;
118 RemoteDecoderManagerChild::GetManagerThread(), __func__
, [self
]() {
119 RefPtr
<ShutdownPromise
> p
= self
->mChild
->Shutdown();
121 // We're about to be destroyed and drop our ref to
122 // *DecoderChild. Make sure we put a ref into the
123 // task queue for the *DecoderChild thread to keep
124 // it alive until we send the delete message.
125 p
->Then(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
126 [child
= std::move(self
->mChild
)](
127 const ShutdownPromise::ResolveOrRejectValue
& aValue
) {
128 MOZ_ASSERT(aValue
.IsResolve());
129 child
->DestroyIPDL();
130 return ShutdownPromise::CreateAndResolveOrReject(aValue
,
137 bool RemoteMediaDataDecoder::IsHardwareAccelerated(
138 nsACString
& aFailureReason
) const {
139 MutexAutoLock
lock(mMutex
);
140 aFailureReason
= mHardwareAcceleratedReason
;
141 return mIsHardwareAccelerated
;
144 void RemoteMediaDataDecoder::SetSeekThreshold(const media::TimeUnit
& aTime
) {
145 RefPtr
<RemoteMediaDataDecoder
> self
= this;
146 media::TimeUnit time
= aTime
;
147 RemoteDecoderManagerChild::GetManagerThread()->Dispatch(
148 NS_NewRunnableFunction("dom::RemoteMediaDataDecoder::SetSeekThreshold",
150 MOZ_ASSERT(self
->mChild
);
151 self
->mChild
->SetSeekThreshold(time
);
156 MediaDataDecoder::ConversionRequired
RemoteMediaDataDecoder::NeedsConversion()
158 MutexAutoLock
lock(mMutex
);
162 nsCString
RemoteMediaDataDecoder::GetDescriptionName() const {
163 MutexAutoLock
lock(mMutex
);
167 nsCString
RemoteMediaDataDecoder::GetProcessName() const {
168 MutexAutoLock
lock(mMutex
);
172 nsCString
RemoteMediaDataDecoder::GetCodecName() const {
173 MutexAutoLock
lock(mMutex
);
177 bool RemoteMediaDataDecoder::ShouldDecoderAlwaysBeRecycled() const {
178 MutexAutoLock
lock(mMutex
);
179 return mShouldDecoderAlwaysBeRecycled
;
184 } // namespace mozilla