Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef ChromiumCDMParent_h_
7 : #define ChromiumCDMParent_h_
8 :
9 : #include "DecryptJob.h"
10 : #include "GMPCrashHelper.h"
11 : #include "GMPCrashHelperHolder.h"
12 : #include "GMPMessageUtils.h"
13 : #include "mozilla/gmp/PChromiumCDMParent.h"
14 : #include "mozilla/RefPtr.h"
15 : #include "nsDataHashtable.h"
16 : #include "PlatformDecoderModule.h"
17 : #include "ImageContainer.h"
18 : #include "mozilla/Span.h"
19 : #include "ReorderQueue.h"
20 :
21 : namespace mozilla {
22 :
23 : class MediaRawData;
24 : class ChromiumCDMProxy;
25 :
26 : namespace gmp {
27 :
28 : class GMPContentParent;
29 :
30 : class ChromiumCDMParent final
31 : : public PChromiumCDMParent
32 : , public GMPCrashHelperHolder
33 : {
34 : public:
35 0 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMParent)
36 :
37 : ChromiumCDMParent(GMPContentParent* aContentParent, uint32_t aPluginId);
38 :
39 0 : uint32_t PluginId() const { return mPluginId; }
40 :
41 : bool Init(ChromiumCDMProxy* aProxy,
42 : bool aAllowDistinctiveIdentifier,
43 : bool aAllowPersistentState);
44 :
45 : void CreateSession(uint32_t aCreateSessionToken,
46 : uint32_t aSessionType,
47 : uint32_t aInitDataType,
48 : uint32_t aPromiseId,
49 : const nsTArray<uint8_t>& aInitData);
50 :
51 : void LoadSession(uint32_t aPromiseId,
52 : uint32_t aSessionType,
53 : nsString aSessionId);
54 :
55 : void SetServerCertificate(uint32_t aPromiseId,
56 : const nsTArray<uint8_t>& aCert);
57 :
58 : void UpdateSession(const nsCString& aSessionId,
59 : uint32_t aPromiseId,
60 : const nsTArray<uint8_t>& aResponse);
61 :
62 : void CloseSession(const nsCString& aSessionId, uint32_t aPromiseId);
63 :
64 : void RemoveSession(const nsCString& aSessionId, uint32_t aPromiseId);
65 :
66 : RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample);
67 :
68 : // TODO: Add functions for clients to send data to CDM, and
69 : // a Close() function.
70 : RefPtr<MediaDataDecoder::InitPromise> InitializeVideoDecoder(
71 : const gmp::CDMVideoDecoderConfig& aConfig,
72 : const VideoInfo& aInfo,
73 : RefPtr<layers::ImageContainer> aImageContainer);
74 :
75 : RefPtr<MediaDataDecoder::DecodePromise> DecryptAndDecodeFrame(
76 : MediaRawData* aSample);
77 :
78 : RefPtr<MediaDataDecoder::FlushPromise> FlushVideoDecoder();
79 :
80 : RefPtr<MediaDataDecoder::DecodePromise> Drain();
81 :
82 : RefPtr<ShutdownPromise> ShutdownVideoDecoder();
83 :
84 : void Shutdown();
85 :
86 : protected:
87 0 : ~ChromiumCDMParent() {}
88 :
89 : ipc::IPCResult Recv__delete__() override;
90 : ipc::IPCResult RecvOnResolveNewSessionPromise(
91 : const uint32_t& aPromiseId,
92 : const nsCString& aSessionId) override;
93 : ipc::IPCResult RecvResolveLoadSessionPromise(
94 : const uint32_t& aPromiseId,
95 : const bool& aSuccessful) override;
96 : ipc::IPCResult RecvOnResolvePromise(const uint32_t& aPromiseId) override;
97 : ipc::IPCResult RecvOnRejectPromise(const uint32_t& aPromiseId,
98 : const uint32_t& aError,
99 : const uint32_t& aSystemCode,
100 : const nsCString& aErrorMessage) override;
101 : ipc::IPCResult RecvOnSessionMessage(const nsCString& aSessionId,
102 : const uint32_t& aMessageType,
103 : nsTArray<uint8_t>&& aMessage) override;
104 : ipc::IPCResult RecvOnSessionKeysChange(
105 : const nsCString& aSessionId,
106 : nsTArray<CDMKeyInformation>&& aKeysInfo) override;
107 : ipc::IPCResult RecvOnExpirationChange(
108 : const nsCString& aSessionId,
109 : const double& aSecondsSinceEpoch) override;
110 : ipc::IPCResult RecvOnSessionClosed(const nsCString& aSessionId) override;
111 : ipc::IPCResult RecvOnLegacySessionError(const nsCString& aSessionId,
112 : const uint32_t& aError,
113 : const uint32_t& aSystemCode,
114 : const nsCString& aMessage) override;
115 : ipc::IPCResult RecvDecrypted(const uint32_t& aId,
116 : const uint32_t& aStatus,
117 : ipc::Shmem&& aData) override;
118 : ipc::IPCResult RecvDecryptFailed(const uint32_t& aId,
119 : const uint32_t& aStatus) override;
120 : ipc::IPCResult RecvOnDecoderInitDone(const uint32_t& aStatus) override;
121 : ipc::IPCResult RecvDecodedShmem(const CDMVideoFrame& aFrame,
122 : ipc::Shmem&& aShmem) override;
123 : ipc::IPCResult RecvDecodedData(const CDMVideoFrame& aFrame,
124 : nsTArray<uint8_t>&& aData) override;
125 : ipc::IPCResult RecvDecodeFailed(const uint32_t& aStatus) override;
126 : ipc::IPCResult RecvShutdown() override;
127 : ipc::IPCResult RecvResetVideoDecoderComplete() override;
128 : ipc::IPCResult RecvDrainComplete() override;
129 : void ActorDestroy(ActorDestroyReason aWhy) override;
130 : bool SendBufferToCDM(uint32_t aSizeInBytes);
131 :
132 : void ReorderAndReturnOutput(RefPtr<VideoData>&& aFrame);
133 :
134 : void RejectPromise(uint32_t aPromiseId,
135 : nsresult aError,
136 : const nsCString& aErrorMessage);
137 :
138 : void ResolvePromise(uint32_t aPromiseId);
139 :
140 : bool InitCDMInputBuffer(gmp::CDMInputBuffer& aBuffer, MediaRawData* aSample);
141 :
142 : bool PurgeShmems();
143 : bool EnsureSufficientShmems(size_t aVideoFrameSize);
144 : already_AddRefed<VideoData> CreateVideoFrame(const CDMVideoFrame& aFrame,
145 : Span<uint8_t> aData);
146 :
147 : const uint32_t mPluginId;
148 : GMPContentParent* mContentParent;
149 : // Note: this pointer is a weak reference because otherwise it would cause
150 : // a cycle, as ChromiumCDMProxy has a strong reference to the
151 : // ChromiumCDMParent.
152 : ChromiumCDMProxy* mProxy = nullptr;
153 : nsDataHashtable<nsUint32HashKey, uint32_t> mPromiseToCreateSessionToken;
154 : nsTArray<RefPtr<DecryptJob>> mDecrypts;
155 :
156 : MozPromiseHolder<MediaDataDecoder::InitPromise> mInitVideoDecoderPromise;
157 : MozPromiseHolder<MediaDataDecoder::DecodePromise> mDecodePromise;
158 :
159 : RefPtr<layers::ImageContainer> mImageContainer;
160 : VideoInfo mVideoInfo;
161 : uint64_t mLastStreamOffset = 0;
162 :
163 : MozPromiseHolder<MediaDataDecoder::FlushPromise> mFlushDecoderPromise;
164 :
165 : size_t mVideoFrameBufferSize = 0;
166 :
167 : // Count of the number of shmems in the set used to return decoded video
168 : // frames from the CDM to Gecko.
169 : uint32_t mVideoShmemsActive = 0;
170 : // Maximum number of shmems to use to return decoded video frames.
171 : uint32_t mVideoShmemLimit;
172 : // High water mark for mVideoShmemsActive, reported via telemetry.
173 : uint32_t mMaxVideoShmemsActive = 0;
174 :
175 : bool mIsShutdown = false;
176 : bool mVideoDecoderInitialized = false;
177 : bool mActorDestroyed = false;
178 :
179 : // The H.264 decoder in Widevine CDM versions 970 and later output in decode
180 : // order rather than presentation order, so we reorder in presentation order
181 : // before presenting. mMaxRefFrames is non-zero if we have an initialized
182 : // decoder and we are decoding H.264. If so, it stores the maximum length of
183 : // the reorder queue that we need. Note we may have multiple decoders for the
184 : // life time of this object, but never more than one active at once.
185 : uint32_t mMaxRefFrames = 0;
186 : ReorderQueue mReorderQueue;
187 : };
188 :
189 : } // namespace gmp
190 : } // namespace mozilla
191 :
192 : #endif // ChromiumCDMParent_h_
|