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