1 /*
2  * Copyright 2017, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CODEC2_BUFFER_H_
18 
19 #define CODEC2_BUFFER_H_
20 
21 #include <C2Buffer.h>
22 
23 #include <android/hardware/cas/native/1.0/types.h>
24 #include <binder/IMemory.h>
25 #include <media/hardware/VideoAPI.h>
26 #include <media/stagefright/foundation/ABuffer.h>
27 #include <media/MediaCodecBuffer.h>
28 #include <mediadrm/ICrypto.h>
29 
30 namespace android {
31 
32 /**
33  * Copies a graphic view into a media image.
34  *
35  * \param imgBase base of MediaImage
36  * \param img MediaImage data
37  * \param view graphic view
38  *
39  * \return OK on success
40  */
41 status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);
42 
43 /**
44  * Copies a media image into a graphic view.
45  *
46  * \param view graphic view
47  * \param imgBase base of MediaImage
48  * \param img MediaImage data
49  *
50  * \return OK on success
51  */
52 status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);
53 
54 class Codec2Buffer : public MediaCodecBuffer {
55 public:
56     using MediaCodecBuffer::MediaCodecBuffer;
57     ~Codec2Buffer() override = default;
58 
59     /**
60      * \return  C2Buffer object represents this buffer.
61      */
62     virtual std::shared_ptr<C2Buffer> asC2Buffer() = 0;
63 
64     /**
65      * Test if we can copy the content of |buffer| into this object.
66      *
67      * \param   buffer  C2Buffer object to copy.
68      * \return  true    if the content of buffer can be copied over to this buffer
69      *          false   otherwise.
70      */
canCopy(const std::shared_ptr<C2Buffer> & buffer)71     virtual bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const {
72         (void)buffer;
73         return false;
74     }
75 
76     /**
77      * Copy the content of |buffer| into this object. This method assumes that
78      * canCopy() check already passed.
79      *
80      * \param   buffer  C2Buffer object to copy.
81      * \return  true    if successful
82      *          false   otherwise.
83      */
copy(const std::shared_ptr<C2Buffer> & buffer)84     virtual bool copy(const std::shared_ptr<C2Buffer> &buffer) {
85         (void)buffer;
86         return false;
87     }
88 
getImageData()89     sp<ABuffer> getImageData() const { return mImageData; }
90 
91 protected:
92     /**
93      * canCopy() implementation for linear buffers.
94      */
95     bool canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const;
96 
97     /**
98      * copy() implementation for linear buffers.
99      */
100     bool copyLinear(const std::shared_ptr<C2Buffer> &buffer);
101 
102     /**
103      * sets MediaImage data for flexible graphic buffers
104      */
105     void setImageData(const sp<ABuffer> &imageData);
106 
107     sp<ABuffer> mImageData;
108 };
109 
110 /**
111  * MediaCodecBuffer implementation on top of local linear buffer. This cannot
112  * cross process boundary so asC2Buffer() returns only nullptr.
113  */
114 class LocalLinearBuffer : public Codec2Buffer {
115 public:
116     using Codec2Buffer::Codec2Buffer;
117 
asC2Buffer()118     std::shared_ptr<C2Buffer> asC2Buffer() override { return nullptr; }
119     bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
120     bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
121 };
122 
123 /**
124  * MediaCodecBuffer implementation to be used only as a dummy wrapper around a
125  * C2Buffer object.
126  */
127 class DummyContainerBuffer : public Codec2Buffer {
128 public:
129     DummyContainerBuffer(
130             const sp<AMessage> &format,
131             const std::shared_ptr<C2Buffer> &buffer = nullptr);
132 
133     std::shared_ptr<C2Buffer> asC2Buffer() override;
134     bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
135     bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
136 
137 private:
138     std::shared_ptr<C2Buffer> mBufferRef;
139 };
140 
141 /**
142  * MediaCodecBuffer implementation wraps around C2LinearBlock.
143  */
144 class LinearBlockBuffer : public Codec2Buffer {
145 public:
146     /**
147      * Allocate a new LinearBufferBlock wrapping around C2LinearBlock object.
148      *
149      * \param   format  mandatory buffer format for MediaCodecBuffer
150      * \param   block   C2LinearBlock object to wrap around.
151      * \return          LinearBlockBuffer object with writable mapping.
152      *                  nullptr if unsuccessful.
153      */
154     static sp<LinearBlockBuffer> Allocate(
155             const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block);
156 
157     virtual ~LinearBlockBuffer() = default;
158 
159     std::shared_ptr<C2Buffer> asC2Buffer() override;
160     bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
161     bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
162 
163 private:
164     LinearBlockBuffer(
165             const sp<AMessage> &format,
166             C2WriteView &&writeView,
167             const std::shared_ptr<C2LinearBlock> &block);
168     LinearBlockBuffer() = delete;
169 
170     C2WriteView mWriteView;
171     std::shared_ptr<C2LinearBlock> mBlock;
172 };
173 
174 /**
175  * MediaCodecBuffer implementation wraps around C2ConstLinearBlock.
176  */
177 class ConstLinearBlockBuffer : public Codec2Buffer {
178 public:
179     /**
180      * Allocate a new ConstLinearBlockBuffer wrapping around C2Buffer object.
181      *
182      * \param   format  mandatory buffer format for MediaCodecBuffer
183      * \param   buffer  linear C2Buffer object to wrap around.
184      * \return          ConstLinearBlockBuffer object with readable mapping.
185      *                  nullptr if unsuccessful.
186      */
187     static sp<ConstLinearBlockBuffer> Allocate(
188             const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer);
189 
190     virtual ~ConstLinearBlockBuffer() = default;
191 
192     std::shared_ptr<C2Buffer> asC2Buffer() override;
193 
194 private:
195     ConstLinearBlockBuffer(
196             const sp<AMessage> &format,
197             C2ReadView &&readView,
198             const std::shared_ptr<C2Buffer> &buffer);
199     ConstLinearBlockBuffer() = delete;
200 
201     C2ReadView mReadView;
202     std::shared_ptr<C2Buffer> mBufferRef;
203 };
204 
205 /**
206  * MediaCodecBuffer implementation wraps around C2GraphicBlock.
207  *
208  * This object exposes the underlying bits via accessor APIs and "image-data"
209  * metadata, created automatically at allocation time.
210  */
211 class GraphicBlockBuffer : public Codec2Buffer {
212 public:
213     /**
214      * Allocate a new GraphicBlockBuffer wrapping around C2GraphicBlock object.
215      * If |block| is not in good color formats, it allocates YV12 local buffer
216      * and copies the content over at asC2Buffer().
217      *
218      * \param   format  mandatory buffer format for MediaCodecBuffer
219      * \param   block   C2GraphicBlock object to wrap around.
220      * \param   alloc   a function to allocate backing ABuffer if needed.
221      * \return          GraphicBlockBuffer object with writable mapping.
222      *                  nullptr if unsuccessful.
223      */
224     static sp<GraphicBlockBuffer> Allocate(
225             const sp<AMessage> &format,
226             const std::shared_ptr<C2GraphicBlock> &block,
227             std::function<sp<ABuffer>(size_t)> alloc);
228 
229     virtual ~GraphicBlockBuffer() = default;
230 
231     std::shared_ptr<C2Buffer> asC2Buffer() override;
232 
233 private:
234     GraphicBlockBuffer(
235             const sp<AMessage> &format,
236             const sp<ABuffer> &buffer,
237             C2GraphicView &&view,
238             const std::shared_ptr<C2GraphicBlock> &block,
239             const sp<ABuffer> &imageData,
240             bool wrapped);
241     GraphicBlockBuffer() = delete;
242 
imageData()243     inline MediaImage2 *imageData() { return (MediaImage2 *)mImageData->data(); }
244 
245     C2GraphicView mView;
246     std::shared_ptr<C2GraphicBlock> mBlock;
247     const bool mWrapped;
248 };
249 
250 /**
251  * MediaCodecBuffer implementation wraps around VideoNativeMetadata.
252  */
253 class GraphicMetadataBuffer : public Codec2Buffer {
254 public:
255     /**
256      * Construct a new GraphicMetadataBuffer with local linear buffer for
257      * VideoNativeMetadata.
258      *
259      * \param   format      mandatory buffer format for MediaCodecBuffer
260      */
261     GraphicMetadataBuffer(
262             const sp<AMessage> &format, const std::shared_ptr<C2Allocator> &alloc);
263     virtual ~GraphicMetadataBuffer() = default;
264 
265     std::shared_ptr<C2Buffer> asC2Buffer() override;
266 
267 private:
268     GraphicMetadataBuffer() = delete;
269 
270     std::shared_ptr<C2Allocator> mAlloc;
271 };
272 
273 /**
274  * MediaCodecBuffer implementation wraps around graphic C2Buffer object.
275  *
276  * This object exposes the underlying bits via accessor APIs and "image-data"
277  * metadata, created automatically at allocation time.
278  */
279 class ConstGraphicBlockBuffer : public Codec2Buffer {
280 public:
281     /**
282      * Allocate a new ConstGraphicBlockBuffer wrapping around C2Buffer object.
283      * If |buffer| is not in good color formats, it allocates YV12 local buffer
284      * and copies the content of |buffer| over to expose.
285      *
286      * \param   format  mandatory buffer format for MediaCodecBuffer
287      * \param   buffer  graphic C2Buffer object to wrap around.
288      * \param   alloc   a function to allocate backing ABuffer if needed.
289      * \return          ConstGraphicBlockBuffer object with readable mapping.
290      *                  nullptr if unsuccessful.
291      */
292     static sp<ConstGraphicBlockBuffer> Allocate(
293             const sp<AMessage> &format,
294             const std::shared_ptr<C2Buffer> &buffer,
295             std::function<sp<ABuffer>(size_t)> alloc);
296 
297     /**
298      * Allocate a new ConstGraphicBlockBuffer which allocates YV12 local buffer
299      * and copies the content of |buffer| over to expose.
300      *
301      * \param   format  mandatory buffer format for MediaCodecBuffer
302      * \param   alloc   a function to allocate backing ABuffer if needed.
303      * \return          ConstGraphicBlockBuffer object with no wrapping buffer.
304      */
305     static sp<ConstGraphicBlockBuffer> AllocateEmpty(
306             const sp<AMessage> &format,
307             std::function<sp<ABuffer>(size_t)> alloc);
308 
309     virtual ~ConstGraphicBlockBuffer() = default;
310 
311     std::shared_ptr<C2Buffer> asC2Buffer() override;
312     bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
313     bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
314 
315 private:
316     ConstGraphicBlockBuffer(
317             const sp<AMessage> &format,
318             const sp<ABuffer> &aBuffer,
319             std::unique_ptr<const C2GraphicView> &&view,
320             const std::shared_ptr<C2Buffer> &buffer,
321             const sp<ABuffer> &imageData,
322             bool wrapped);
323     ConstGraphicBlockBuffer() = delete;
324 
325     sp<ABuffer> mImageData;
326     std::unique_ptr<const C2GraphicView> mView;
327     std::shared_ptr<C2Buffer> mBufferRef;
328     const bool mWrapped;
329 };
330 
331 /**
332  * MediaCodecBuffer implementation wraps around C2LinearBlock for component
333  * and IMemory for client. Underlying C2LinearBlock won't be mapped for secure
334  * usecases..
335  */
336 class EncryptedLinearBlockBuffer : public Codec2Buffer {
337 public:
338     /**
339      * Construct a new EncryptedLinearBufferBlock wrapping around C2LinearBlock
340      * object and writable IMemory region.
341      *
342      * \param   format      mandatory buffer format for MediaCodecBuffer
343      * \param   block       C2LinearBlock object to wrap around.
344      * \param   memory      IMemory object to store encrypted content.
345      * \param   heapSeqNum  Heap sequence number from ICrypto; -1 if N/A
346      */
347     EncryptedLinearBlockBuffer(
348             const sp<AMessage> &format,
349             const std::shared_ptr<C2LinearBlock> &block,
350             const sp<IMemory> &memory,
351             int32_t heapSeqNum = -1);
352     EncryptedLinearBlockBuffer() = delete;
353 
354     virtual ~EncryptedLinearBlockBuffer() = default;
355 
356     std::shared_ptr<C2Buffer> asC2Buffer() override;
357 
358     /**
359      * Fill the source buffer structure with appropriate value based on
360      * internal IMemory object.
361      *
362      * \param source  source buffer structure to fill.
363      */
364     void fillSourceBuffer(ICrypto::SourceBuffer *source);
365     void fillSourceBuffer(
366             hardware::cas::native::V1_0::SharedBuffer *source);
367 
368     /**
369      * Copy the content of |decrypted| into C2LinearBlock inside. This shall
370      * only be called in non-secure usecases.
371      *
372      * \param   decrypted   decrypted content to copy from.
373      * \param   length      length of the content
374      * \return  true        if successful
375      *          false       otherwise.
376      */
377     bool copyDecryptedContent(const sp<IMemory> &decrypted, size_t length);
378 
379     /**
380      * Copy the content of internal IMemory object into C2LinearBlock inside.
381      * This shall only be called in non-secure usecases.
382      *
383      * \param   length      length of the content
384      * \return  true        if successful
385      *          false       otherwise.
386      */
387     bool copyDecryptedContentFromMemory(size_t length);
388 
389     /**
390      * Return native handle of secure buffer understood by ICrypto.
391      *
392      * \return secure buffer handle
393      */
394     native_handle_t *handle() const;
395 
396 private:
397 
398     std::shared_ptr<C2LinearBlock> mBlock;
399     sp<IMemory> mMemory;
400     sp<hardware::HidlMemory> mHidlMemory;
401     int32_t mHeapSeqNum;
402 };
403 
404 }  // namespace android
405 
406 #endif  // CODEC2_BUFFER_H_
407