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 "GMPVideoPlaneImpl.h"
7 : #include "mozilla/gmp/GMPTypes.h"
8 : #include "GMPVideoHost.h"
9 : #include "GMPSharedMemManager.h"
10 :
11 : namespace mozilla {
12 : namespace gmp {
13 :
14 0 : GMPPlaneImpl::GMPPlaneImpl(GMPVideoHostImpl* aHost)
15 : : mSize(0),
16 : mStride(0),
17 0 : mHost(aHost)
18 : {
19 0 : MOZ_ASSERT(mHost);
20 0 : mHost->PlaneCreated(this);
21 0 : }
22 :
23 0 : GMPPlaneImpl::GMPPlaneImpl(const GMPPlaneData& aPlaneData, GMPVideoHostImpl* aHost)
24 0 : : mBuffer(aPlaneData.mBuffer()),
25 0 : mSize(aPlaneData.mSize()),
26 0 : mStride(aPlaneData.mStride()),
27 0 : mHost(aHost)
28 : {
29 0 : MOZ_ASSERT(mHost);
30 0 : mHost->PlaneCreated(this);
31 0 : }
32 :
33 0 : GMPPlaneImpl::~GMPPlaneImpl()
34 : {
35 0 : DestroyBuffer();
36 0 : if (mHost) {
37 0 : mHost->PlaneDestroyed(this);
38 : }
39 0 : }
40 :
41 : void
42 0 : GMPPlaneImpl::DoneWithAPI()
43 : {
44 0 : DestroyBuffer();
45 :
46 : // Do this after destroying the buffer because destruction
47 : // involves deallocation, which requires a host.
48 0 : mHost = nullptr;
49 0 : }
50 :
51 : void
52 0 : GMPPlaneImpl::ActorDestroyed()
53 : {
54 : // Simply clear out Shmem reference, do not attempt to
55 : // properly free it. It has already been freed.
56 0 : mBuffer = ipc::Shmem();
57 : // No more host.
58 0 : mHost = nullptr;
59 0 : }
60 :
61 : bool
62 0 : GMPPlaneImpl::InitPlaneData(GMPPlaneData& aPlaneData)
63 : {
64 0 : aPlaneData.mBuffer() = mBuffer;
65 0 : aPlaneData.mSize() = mSize;
66 0 : aPlaneData.mStride() = mStride;
67 :
68 : // This method is called right before Shmem is sent to another process.
69 : // We need to effectively zero out our member copy so that we don't
70 : // try to delete memory we don't own later.
71 0 : mBuffer = ipc::Shmem();
72 :
73 0 : return true;
74 : }
75 :
76 : GMPErr
77 0 : GMPPlaneImpl::MaybeResize(int32_t aNewSize) {
78 0 : if (aNewSize <= AllocatedSize()) {
79 0 : return GMPNoErr;
80 : }
81 :
82 0 : if (!mHost) {
83 0 : return GMPGenericErr;
84 : }
85 :
86 0 : ipc::Shmem new_mem;
87 0 : if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMem::kGMPFrameData, aNewSize,
88 0 : ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
89 0 : !new_mem.get<uint8_t>()) {
90 0 : return GMPAllocErr;
91 : }
92 :
93 0 : if (mBuffer.IsReadable()) {
94 0 : memcpy(new_mem.get<uint8_t>(), Buffer(), mSize);
95 : }
96 :
97 0 : DestroyBuffer();
98 :
99 0 : mBuffer = new_mem;
100 :
101 0 : return GMPNoErr;
102 : }
103 :
104 : void
105 0 : GMPPlaneImpl::DestroyBuffer()
106 : {
107 0 : if (mHost && mBuffer.IsWritable()) {
108 0 : mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMem::kGMPFrameData, mBuffer);
109 : }
110 0 : mBuffer = ipc::Shmem();
111 0 : }
112 :
113 : GMPErr
114 0 : GMPPlaneImpl::CreateEmptyPlane(int32_t aAllocatedSize, int32_t aStride, int32_t aPlaneSize)
115 : {
116 0 : if (aAllocatedSize < 1 || aStride < 1 || aPlaneSize < 1) {
117 0 : return GMPGenericErr;
118 : }
119 :
120 0 : GMPErr err = MaybeResize(aAllocatedSize);
121 0 : if (err != GMPNoErr) {
122 0 : return err;
123 : }
124 :
125 0 : mSize = aPlaneSize;
126 0 : mStride = aStride;
127 :
128 0 : return GMPNoErr;
129 : }
130 :
131 : GMPErr
132 0 : GMPPlaneImpl::Copy(const GMPPlane& aPlane)
133 : {
134 0 : auto& planeimpl = static_cast<const GMPPlaneImpl&>(aPlane);
135 :
136 0 : GMPErr err = MaybeResize(planeimpl.mSize);
137 0 : if (err != GMPNoErr) {
138 0 : return err;
139 : }
140 :
141 0 : if (planeimpl.Buffer() && planeimpl.mSize > 0) {
142 0 : memcpy(Buffer(), planeimpl.Buffer(), mSize);
143 : }
144 :
145 0 : mSize = planeimpl.mSize;
146 0 : mStride = planeimpl.mStride;
147 :
148 0 : return GMPNoErr;
149 : }
150 :
151 : GMPErr
152 0 : GMPPlaneImpl::Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer)
153 : {
154 0 : GMPErr err = MaybeResize(aSize);
155 0 : if (err != GMPNoErr) {
156 0 : return err;
157 : }
158 :
159 0 : if (aBuffer && aSize > 0) {
160 0 : memcpy(Buffer(), aBuffer, aSize);
161 : }
162 :
163 0 : mSize = aSize;
164 0 : mStride = aStride;
165 :
166 0 : return GMPNoErr;
167 : }
168 :
169 : void
170 0 : GMPPlaneImpl::Swap(GMPPlane& aPlane)
171 : {
172 0 : auto& planeimpl = static_cast<GMPPlaneImpl&>(aPlane);
173 :
174 0 : std::swap(mStride, planeimpl.mStride);
175 0 : std::swap(mSize, planeimpl.mSize);
176 0 : std::swap(mBuffer, planeimpl.mBuffer);
177 0 : }
178 :
179 : int32_t
180 0 : GMPPlaneImpl::AllocatedSize() const
181 : {
182 0 : if (mBuffer.IsWritable()) {
183 0 : return mBuffer.Size<uint8_t>();
184 : }
185 0 : return 0;
186 : }
187 :
188 : void
189 0 : GMPPlaneImpl::ResetSize()
190 : {
191 0 : mSize = 0;
192 0 : }
193 :
194 : bool
195 0 : GMPPlaneImpl::IsZeroSize() const
196 : {
197 0 : return (mSize == 0);
198 : }
199 :
200 : int32_t
201 0 : GMPPlaneImpl::Stride() const
202 : {
203 0 : return mStride;
204 : }
205 :
206 : const uint8_t*
207 0 : GMPPlaneImpl::Buffer() const
208 : {
209 0 : return mBuffer.get<uint8_t>();
210 : }
211 :
212 : uint8_t*
213 0 : GMPPlaneImpl::Buffer()
214 : {
215 0 : return mBuffer.get<uint8_t>();
216 : }
217 :
218 : void
219 0 : GMPPlaneImpl::Destroy()
220 : {
221 0 : delete this;
222 0 : }
223 :
224 : } // namespace gmp
225 : } // namespace mozilla
|