1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ChromiumCDMChild_h_
#define ChromiumCDMChild_h_
#include "content_decryption_module.h"
#include "mozilla/gmp/PChromiumCDMChild.h"
#include "SimpleMap.h"
#include "WidevineVideoFrame.h"
namespace mozilla::gmp {
class GMPContentChild;
class ChromiumCDMChild : public PChromiumCDMChild, public cdm::Host_10 {
public:
// Mark AddRef and Release as `final`, as they overload pure virtual
// implementations in PChromiumCDMChild.
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMChild, final);
explicit ChromiumCDMChild(GMPContentChild* aPlugin);
void Init(cdm::ContentDecryptionModule_10* aCDM,
const nsACString& aStorageId);
void TimerExpired(void* aContext);
// cdm::Host_10 implementation
cdm::Buffer* Allocate(uint32_t aCapacity) override;
void SetTimer(int64_t aDelayMs, void* aContext) override;
cdm::Time GetCurrentWallTime() override;
void OnResolveKeyStatusPromise(uint32_t aPromiseId,
cdm::KeyStatus aKeyStatus) override;
void OnResolveNewSessionPromise(uint32_t aPromiseId, const char* aSessionId,
uint32_t aSessionIdSize) override;
void OnResolvePromise(uint32_t aPromiseId) override;
void OnRejectPromise(uint32_t aPromiseId, cdm::Exception aException,
uint32_t aSystemCode, const char* aErrorMessage,
uint32_t aErrorMessageSize) override;
void OnSessionMessage(const char* aSessionId, uint32_t aSessionIdSize,
cdm::MessageType aMessageType, const char* aMessage,
uint32_t aMessageSize) override;
void OnSessionKeysChange(const char* aSessionId, uint32_t aSessionIdSize,
bool aHasAdditionalUsableKey,
const cdm::KeyInformation* aKeysInfo,
uint32_t aKeysInfoCount) override;
void OnExpirationChange(const char* aSessionId, uint32_t aSessionIdSize,
cdm::Time aNewExpiryTime) override;
void OnSessionClosed(const char* aSessionId,
uint32_t aSessionIdSize) override;
void SendPlatformChallenge(const char* aServiceId, uint32_t aServiceIdSize,
const char* aChallenge,
uint32_t aChallengeSize) override {}
void EnableOutputProtection(uint32_t aDesiredProtectionMask) override {}
void QueryOutputProtectionStatus() override;
void OnDeferredInitializationDone(cdm::StreamType aStreamType,
cdm::Status aDecoderStatus) override {}
void RequestStorageId(uint32_t aVersion) override;
cdm::FileIO* CreateFileIO(cdm::FileIOClient* aClient) override;
void OnInitialized(bool aSuccess) override;
// end cdm::Host_10 specific methods
void GiveBuffer(ipc::Shmem&& aBuffer);
protected:
~ChromiumCDMChild();
bool OnResolveNewSessionPromiseInternal(uint32_t aPromiseId,
const nsACString& aSessionId);
bool IsOnMessageLoopThread();
void ActorDestroy(ActorDestroyReason aReason) override;
ipc::IPCResult RecvGiveBuffer(ipc::Shmem&& aShmem) override;
ipc::IPCResult RecvPurgeShmems() override;
void PurgeShmems();
ipc::IPCResult RecvInit(const bool& aAllowDistinctiveIdentifier,
const bool& aAllowPersistentState,
InitResolver&& aResolver) override;
ipc::IPCResult RecvSetServerCertificate(
const uint32_t& aPromiseId, nsTArray<uint8_t>&& aServerCert) override;
ipc::IPCResult RecvCreateSessionAndGenerateRequest(
const uint32_t& aPromiseId, const uint32_t& aSessionType,
const uint32_t& aInitDataType, nsTArray<uint8_t>&& aInitData) override;
ipc::IPCResult RecvLoadSession(const uint32_t& aPromiseId,
const uint32_t& aSessionType,
const nsACString& aSessionId) override;
ipc::IPCResult RecvUpdateSession(const uint32_t& aPromiseId,
const nsACString& aSessionId,
nsTArray<uint8_t>&& aResponse) override;
ipc::IPCResult RecvCloseSession(const uint32_t& aPromiseId,
const nsACString& aSessionId) override;
ipc::IPCResult RecvRemoveSession(const uint32_t& aPromiseId,
const nsACString& aSessionId) override;
ipc::IPCResult RecvCompleteQueryOutputProtectionStatus(
const bool& aSuccess, const uint32_t& aLinkMask,
const uint32_t& aProtectionMask) override;
ipc::IPCResult RecvGetStatusForPolicy(
const uint32_t& aPromiseId,
const cdm::HdcpVersion& aMinHdcpVersion) override;
ipc::IPCResult RecvDecrypt(const uint32_t& aId,
const CDMInputBuffer& aBuffer) override;
ipc::IPCResult RecvInitializeVideoDecoder(
const CDMVideoDecoderConfig& aConfig) override;
ipc::IPCResult RecvDeinitializeVideoDecoder() override;
ipc::IPCResult RecvResetVideoDecoder() override;
ipc::IPCResult RecvDecryptAndDecodeFrame(
const CDMInputBuffer& aBuffer) override;
ipc::IPCResult RecvDrain() override;
ipc::IPCResult RecvDestroy() override;
void ReturnOutput(WidevineVideoFrame& aFrame);
bool HasShmemOfSize(size_t aSize) const;
template <typename MethodType, typename... ParamType>
void CallMethod(MethodType, ParamType&&...);
template <typename MethodType, typename... ParamType>
void CallOnMessageLoopThread(const char* const, MethodType, ParamType&&...);
GMPContentChild* mPlugin = nullptr;
cdm::ContentDecryptionModule_10* mCDM = nullptr;
typedef SimpleMap<int64_t, uint64_t, ThreadSafePolicy> DurationMap;
DurationMap mFrameDurations;
nsTArray<uint32_t> mLoadSessionPromiseIds;
cdm::Size mCodedSize = {0, 0};
nsTArray<ipc::Shmem> mBuffers;
bool mDecoderInitialized = false;
bool mPersistentStateAllowed = false;
bool mDestroyed = false;
nsCString mStorageId;
typedef MozPromise<bool, nsresult, /* IsExclusive = */ true> InitPromise;
// Created when we RecvInit, should be resolved once the CDM is initialized
// or rejected if init fails.
MozPromiseHolder<InitPromise> mInitPromise;
};
} // namespace mozilla::gmp
#endif // ChromiumCDMChild_h_
|