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