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 LOG("%p is created", this);
25 RemoteMediaDataDecoder::~RemoteMediaDataDecoder() {
27 // Shutdown didn't get called. This can happen if the creation of the
28 // decoder got interrupted while pending.
29 nsCOMPtr
<nsISerialEventTarget
> thread
=
30 RemoteDecoderManagerChild::GetManagerThread();
32 thread
->Dispatch(NS_NewRunnableFunction(
33 "RemoteMediaDataDecoderShutdown", [child
= std::move(mChild
), thread
] {
34 child
->Shutdown()->Then(
36 [child
](const ShutdownPromise::ResolveOrRejectValue
& aValue
) {
41 LOG("%p is released", this);
44 RefPtr
<MediaDataDecoder::InitPromise
> RemoteMediaDataDecoder::Init() {
45 RefPtr
<RemoteMediaDataDecoder
> self
= this;
46 return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
47 [self
]() { return self
->mChild
->Init(); })
49 RemoteDecoderManagerChild::GetManagerThread(), __func__
,
50 [self
, this](TrackType aTrack
) {
51 // If shutdown has started in the meantime shutdown promise may
52 // be resloved before this task. In this case mChild will be null
53 // and the init promise has to be canceled.
55 return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_CANCELED
,
58 mDescription
= mChild
->GetDescriptionName();
59 mProcessName
= mChild
->GetProcessName();
60 mCodecName
= mChild
->GetCodecName();
61 mIsHardwareAccelerated
=
62 mChild
->IsHardwareAccelerated(mHardwareAcceleratedReason
);
63 mConversion
= mChild
->NeedsConversion();
64 LOG("%p RemoteDecoderChild has been initialized - description: %s, "
65 "process: %s, codec: %s",
66 this, mDescription
.get(), mProcessName
.get(), mCodecName
.get());
67 return InitPromise::CreateAndResolve(aTrack
, __func__
);
69 [self
](const MediaResult
& aError
) {
70 return InitPromise::CreateAndReject(aError
, __func__
);
74 RefPtr
<MediaDataDecoder::DecodePromise
> RemoteMediaDataDecoder::Decode(
75 MediaRawData
* aSample
) {
76 RefPtr
<RemoteMediaDataDecoder
> self
= this;
77 RefPtr
<MediaRawData
> sample
= aSample
;
79 RemoteDecoderManagerChild::GetManagerThread(), __func__
,
81 return self
->mChild
->Decode(nsTArray
<RefPtr
<MediaRawData
>>{sample
});
85 RefPtr
<MediaDataDecoder::DecodePromise
> RemoteMediaDataDecoder::DecodeBatch(
86 nsTArray
<RefPtr
<MediaRawData
>>&& aSamples
) {
87 RefPtr
<RemoteMediaDataDecoder
> self
= this;
88 return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
89 [self
, samples
= std::move(aSamples
)]() {
90 return self
->mChild
->Decode(samples
);
94 RefPtr
<MediaDataDecoder::FlushPromise
> RemoteMediaDataDecoder::Flush() {
95 RefPtr
<RemoteMediaDataDecoder
> self
= this;
96 return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
97 [self
]() { return self
->mChild
->Flush(); });
100 RefPtr
<MediaDataDecoder::DecodePromise
> RemoteMediaDataDecoder::Drain() {
101 RefPtr
<RemoteMediaDataDecoder
> self
= this;
102 return InvokeAsync(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
103 [self
]() { return self
->mChild
->Drain(); });
106 RefPtr
<ShutdownPromise
> RemoteMediaDataDecoder::Shutdown() {
107 RefPtr
<RemoteMediaDataDecoder
> self
= this;
109 RemoteDecoderManagerChild::GetManagerThread(), __func__
, [self
]() {
110 RefPtr
<ShutdownPromise
> p
= self
->mChild
->Shutdown();
112 // We're about to be destroyed and drop our ref to
113 // *DecoderChild. Make sure we put a ref into the
114 // task queue for the *DecoderChild thread to keep
115 // it alive until we send the delete message.
116 p
->Then(RemoteDecoderManagerChild::GetManagerThread(), __func__
,
117 [child
= std::move(self
->mChild
)](
118 const ShutdownPromise::ResolveOrRejectValue
& aValue
) {
119 MOZ_ASSERT(aValue
.IsResolve());
120 child
->DestroyIPDL();
121 return ShutdownPromise::CreateAndResolveOrReject(aValue
,
128 bool RemoteMediaDataDecoder::IsHardwareAccelerated(
129 nsACString
& aFailureReason
) const {
130 aFailureReason
= mHardwareAcceleratedReason
;
131 return mIsHardwareAccelerated
;
134 void RemoteMediaDataDecoder::SetSeekThreshold(const media::TimeUnit
& aTime
) {
135 RefPtr
<RemoteMediaDataDecoder
> self
= this;
136 media::TimeUnit time
= aTime
;
137 RemoteDecoderManagerChild::GetManagerThread()->Dispatch(
138 NS_NewRunnableFunction("dom::RemoteMediaDataDecoder::SetSeekThreshold",
140 MOZ_ASSERT(self
->mChild
);
141 self
->mChild
->SetSeekThreshold(time
);
146 MediaDataDecoder::ConversionRequired
RemoteMediaDataDecoder::NeedsConversion()
151 nsCString
RemoteMediaDataDecoder::GetDescriptionName() const {
155 nsCString
RemoteMediaDataDecoder::GetProcessName() const {
159 nsCString
RemoteMediaDataDecoder::GetCodecName() const { return mCodecName
; }
163 } // namespace mozilla