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 : #include "GMPVideoEncodedFrameImpl.h"
7 : #include "GMPVideoHost.h"
8 : #include "mozilla/gmp/GMPTypes.h"
9 : #include "GMPSharedMemManager.h"
10 : #include "GMPEncryptedBufferDataImpl.h"
11 :
12 : namespace mozilla {
13 : namespace gmp {
14 :
15 0 : GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(GMPVideoHostImpl* aHost)
16 : : mEncodedWidth(0),
17 : mEncodedHeight(0),
18 : mTimeStamp(0ll),
19 : mDuration(0ll),
20 : mFrameType(kGMPDeltaFrame),
21 : mSize(0),
22 : mCompleteFrame(false),
23 : mHost(aHost),
24 0 : mBufferType(GMP_BufferSingle)
25 : {
26 0 : MOZ_ASSERT(aHost);
27 0 : aHost->EncodedFrameCreated(this);
28 0 : }
29 :
30 0 : GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(const GMPVideoEncodedFrameData& aFrameData,
31 0 : GMPVideoHostImpl* aHost)
32 0 : : mEncodedWidth(aFrameData.mEncodedWidth()),
33 0 : mEncodedHeight(aFrameData.mEncodedHeight()),
34 0 : mTimeStamp(aFrameData.mTimestamp()),
35 0 : mDuration(aFrameData.mDuration()),
36 0 : mFrameType(static_cast<GMPVideoFrameType>(aFrameData.mFrameType())),
37 0 : mSize(aFrameData.mSize()),
38 0 : mCompleteFrame(aFrameData.mCompleteFrame()),
39 : mHost(aHost),
40 0 : mBuffer(aFrameData.mBuffer()),
41 0 : mBufferType(aFrameData.mBufferType())
42 : {
43 0 : MOZ_ASSERT(aHost);
44 0 : if (aFrameData.mDecryptionData().mKeyId().Length() > 0) {
45 0 : mCrypto = new GMPEncryptedBufferDataImpl(aFrameData.mDecryptionData());
46 : }
47 0 : aHost->EncodedFrameCreated(this);
48 0 : }
49 :
50 0 : GMPVideoEncodedFrameImpl::~GMPVideoEncodedFrameImpl()
51 : {
52 0 : DestroyBuffer();
53 0 : if (mHost) {
54 0 : mHost->EncodedFrameDestroyed(this);
55 : }
56 0 : }
57 :
58 : void
59 0 : GMPVideoEncodedFrameImpl::InitCrypto(const CryptoSample& aCrypto)
60 : {
61 0 : mCrypto = new GMPEncryptedBufferDataImpl(aCrypto);
62 0 : }
63 :
64 : const GMPEncryptedBufferMetadata*
65 0 : GMPVideoEncodedFrameImpl::GetDecryptionData() const
66 : {
67 0 : return mCrypto;
68 : }
69 :
70 : GMPVideoFrameFormat
71 0 : GMPVideoEncodedFrameImpl::GetFrameFormat()
72 : {
73 0 : return kGMPEncodedVideoFrame;
74 : }
75 :
76 : void
77 0 : GMPVideoEncodedFrameImpl::DoneWithAPI()
78 : {
79 0 : DestroyBuffer();
80 :
81 : // Do this after destroying the buffer because destruction
82 : // involves deallocation, which requires a host.
83 0 : mHost = nullptr;
84 0 : }
85 :
86 : void
87 0 : GMPVideoEncodedFrameImpl::ActorDestroyed()
88 : {
89 : // Simply clear out Shmem reference, do not attempt to
90 : // properly free it. It has already been freed.
91 0 : mBuffer = ipc::Shmem();
92 : // No more host.
93 0 : mHost = nullptr;
94 0 : }
95 :
96 : bool
97 0 : GMPVideoEncodedFrameImpl::RelinquishFrameData(GMPVideoEncodedFrameData& aFrameData)
98 : {
99 0 : aFrameData.mEncodedWidth() = mEncodedWidth;
100 0 : aFrameData.mEncodedHeight() = mEncodedHeight;
101 0 : aFrameData.mTimestamp() = mTimeStamp;
102 0 : aFrameData.mDuration() = mDuration;
103 0 : aFrameData.mFrameType() = mFrameType;
104 0 : aFrameData.mSize() = mSize;
105 0 : aFrameData.mCompleteFrame() = mCompleteFrame;
106 0 : aFrameData.mBuffer() = mBuffer;
107 0 : aFrameData.mBufferType() = mBufferType;
108 0 : if (mCrypto) {
109 0 : mCrypto->RelinquishData(aFrameData.mDecryptionData());
110 : }
111 :
112 : // This method is called right before Shmem is sent to another process.
113 : // We need to effectively zero out our member copy so that we don't
114 : // try to delete Shmem we don't own later.
115 0 : mBuffer = ipc::Shmem();
116 :
117 0 : return true;
118 : }
119 :
120 : void
121 0 : GMPVideoEncodedFrameImpl::DestroyBuffer()
122 : {
123 0 : if (mHost && mBuffer.IsWritable()) {
124 0 : mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPEncodedData, mBuffer);
125 : }
126 0 : mBuffer = ipc::Shmem();
127 0 : }
128 :
129 : GMPErr
130 0 : GMPVideoEncodedFrameImpl::CreateEmptyFrame(uint32_t aSize)
131 : {
132 0 : if (aSize == 0) {
133 0 : DestroyBuffer();
134 0 : } else if (aSize > AllocatedSize()) {
135 0 : DestroyBuffer();
136 0 : if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData, aSize,
137 0 : ipc::SharedMemory::TYPE_BASIC, &mBuffer) ||
138 0 : !Buffer()) {
139 0 : return GMPAllocErr;
140 : }
141 : }
142 0 : mSize = aSize;
143 :
144 0 : return GMPNoErr;
145 : }
146 :
147 : GMPErr
148 0 : GMPVideoEncodedFrameImpl::CopyFrame(const GMPVideoEncodedFrame& aFrame)
149 : {
150 0 : auto& f = static_cast<const GMPVideoEncodedFrameImpl&>(aFrame);
151 :
152 0 : if (f.mSize != 0) {
153 0 : GMPErr err = CreateEmptyFrame(f.mSize);
154 0 : if (err != GMPNoErr) {
155 0 : return err;
156 : }
157 0 : memcpy(Buffer(), f.Buffer(), f.mSize);
158 : }
159 0 : mEncodedWidth = f.mEncodedWidth;
160 0 : mEncodedHeight = f.mEncodedHeight;
161 0 : mTimeStamp = f.mTimeStamp;
162 0 : mDuration = f.mDuration;
163 0 : mFrameType = f.mFrameType;
164 0 : mSize = f.mSize; // already set...
165 0 : mCompleteFrame = f.mCompleteFrame;
166 0 : mBufferType = f.mBufferType;
167 0 : mCrypto = new GMPEncryptedBufferDataImpl(*(f.mCrypto));
168 : // Don't copy host, that should have been set properly on object creation via host.
169 :
170 0 : return GMPNoErr;
171 : }
172 :
173 : void
174 0 : GMPVideoEncodedFrameImpl::SetEncodedWidth(uint32_t aEncodedWidth)
175 : {
176 0 : mEncodedWidth = aEncodedWidth;
177 0 : }
178 :
179 : uint32_t
180 0 : GMPVideoEncodedFrameImpl::EncodedWidth()
181 : {
182 0 : return mEncodedWidth;
183 : }
184 :
185 : void
186 0 : GMPVideoEncodedFrameImpl::SetEncodedHeight(uint32_t aEncodedHeight)
187 : {
188 0 : mEncodedHeight = aEncodedHeight;
189 0 : }
190 :
191 : uint32_t
192 0 : GMPVideoEncodedFrameImpl::EncodedHeight()
193 : {
194 0 : return mEncodedHeight;
195 : }
196 :
197 : void
198 0 : GMPVideoEncodedFrameImpl::SetTimeStamp(uint64_t aTimeStamp)
199 : {
200 0 : mTimeStamp = aTimeStamp;
201 0 : }
202 :
203 : uint64_t
204 0 : GMPVideoEncodedFrameImpl::TimeStamp()
205 : {
206 0 : return mTimeStamp;
207 : }
208 :
209 : void
210 0 : GMPVideoEncodedFrameImpl::SetDuration(uint64_t aDuration)
211 : {
212 0 : mDuration = aDuration;
213 0 : }
214 :
215 : uint64_t
216 0 : GMPVideoEncodedFrameImpl::Duration() const
217 : {
218 0 : return mDuration;
219 : }
220 :
221 : void
222 0 : GMPVideoEncodedFrameImpl::SetFrameType(GMPVideoFrameType aFrameType)
223 : {
224 0 : mFrameType = aFrameType;
225 0 : }
226 :
227 : GMPVideoFrameType
228 0 : GMPVideoEncodedFrameImpl::FrameType()
229 : {
230 0 : return mFrameType;
231 : }
232 :
233 : void
234 0 : GMPVideoEncodedFrameImpl::SetAllocatedSize(uint32_t aNewSize)
235 : {
236 0 : if (aNewSize <= AllocatedSize()) {
237 0 : return;
238 : }
239 :
240 0 : if (!mHost) {
241 0 : return;
242 : }
243 :
244 0 : ipc::Shmem new_mem;
245 0 : if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPEncodedData, aNewSize,
246 0 : ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
247 0 : !new_mem.get<uint8_t>()) {
248 0 : return;
249 : }
250 :
251 0 : if (mBuffer.IsReadable()) {
252 0 : memcpy(new_mem.get<uint8_t>(), Buffer(), mSize);
253 : }
254 :
255 0 : DestroyBuffer();
256 :
257 0 : mBuffer = new_mem;
258 : }
259 :
260 : uint32_t
261 0 : GMPVideoEncodedFrameImpl::AllocatedSize()
262 : {
263 0 : if (mBuffer.IsWritable()) {
264 0 : return mBuffer.Size<uint8_t>();
265 : }
266 0 : return 0;
267 : }
268 :
269 : void
270 0 : GMPVideoEncodedFrameImpl::SetSize(uint32_t aSize)
271 : {
272 0 : mSize = aSize;
273 0 : }
274 :
275 : uint32_t
276 0 : GMPVideoEncodedFrameImpl::Size()
277 : {
278 0 : return mSize;
279 : }
280 :
281 : void
282 0 : GMPVideoEncodedFrameImpl::SetCompleteFrame(bool aCompleteFrame)
283 : {
284 0 : mCompleteFrame = aCompleteFrame;
285 0 : }
286 :
287 : bool
288 0 : GMPVideoEncodedFrameImpl::CompleteFrame()
289 : {
290 0 : return mCompleteFrame;
291 : }
292 :
293 : const uint8_t*
294 0 : GMPVideoEncodedFrameImpl::Buffer() const
295 : {
296 0 : return mBuffer.get<uint8_t>();
297 : }
298 :
299 : uint8_t*
300 0 : GMPVideoEncodedFrameImpl::Buffer()
301 : {
302 0 : return mBuffer.get<uint8_t>();
303 : }
304 :
305 : void
306 0 : GMPVideoEncodedFrameImpl::Destroy()
307 : {
308 0 : delete this;
309 0 : }
310 :
311 : GMPBufferType
312 0 : GMPVideoEncodedFrameImpl::BufferType() const
313 : {
314 0 : return mBufferType;
315 : }
316 :
317 : void
318 0 : GMPVideoEncodedFrameImpl::SetBufferType(GMPBufferType aBufferType)
319 : {
320 0 : mBufferType = aBufferType;
321 0 : }
322 :
323 : } // namespace gmp
324 : } // namespace mozilla
|