summaryrefslogtreecommitdiff
path: root/media/codec2/sfplugin/Codec2Buffer.h
blob: dc788cd87e11a21fa35d623a2074ac1bb10fc146 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
/*
 * Copyright 2017, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef CODEC2_BUFFER_H_

#define CODEC2_BUFFER_H_

#include <C2Buffer.h>

#include <binder/IMemory.h>
#include <media/hardware/VideoAPI.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/MediaCodecBuffer.h>

namespace android {

namespace hardware {
class HidlMemory;
namespace cas {
namespace native {
namespace V1_0 {
struct SharedBuffer;
}  // namespace V1_0
}  // namespace native
}  // namespace cas
namespace drm {
namespace V1_0 {
struct SharedBuffer;
}  // namespace V1_0
}  // namespace drm
}  // namespace hardware

/**
 * Copies a graphic view into a media image.
 *
 * \param imgBase base of MediaImage
 * \param img MediaImage data
 * \param view graphic view
 *
 * \return OK on success
 */
status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view);

/**
 * Copies a media image into a graphic view.
 *
 * \param view graphic view
 * \param imgBase base of MediaImage
 * \param img MediaImage data
 *
 * \return OK on success
 */
status_t ImageCopy(C2GraphicView &view, const uint8_t *imgBase, const MediaImage2 *img);

class Codec2Buffer : public MediaCodecBuffer {
public:
    using MediaCodecBuffer::MediaCodecBuffer;
    ~Codec2Buffer() override = default;

    sp<ABuffer> getImageData() const { return mImageData; }

    virtual void clearC2BufferRefs() {}

protected:
    /**
     * canCopy() implementation for linear buffers.
     */
    bool canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const;

    /**
     * copy() implementation for linear buffers.
     */
    bool copyLinear(const std::shared_ptr<C2Buffer> &buffer);

    /**
     * sets MediaImage data for flexible graphic buffers
     */
    void setImageData(const sp<ABuffer> &imageData);

    sp<ABuffer> mImageData;
};

/**
 * MediaCodecBuffer implementation on top of local linear buffer. This cannot
 * cross process boundary so asC2Buffer() returns only nullptr.
 */
class LocalLinearBuffer : public Codec2Buffer {
public:
    using Codec2Buffer::Codec2Buffer;

    std::shared_ptr<C2Buffer> asC2Buffer() override { return nullptr; }
    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;
};

/**
 * MediaCodecBuffer implementation to be used only as a dummy wrapper around a
 * C2Buffer object.
 */
class DummyContainerBuffer : public Codec2Buffer {
public:
    DummyContainerBuffer(
            const sp<AMessage> &format,
            const std::shared_ptr<C2Buffer> &buffer = nullptr);

    std::shared_ptr<C2Buffer> asC2Buffer() override;
    void clearC2BufferRefs() override;
    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;

private:
    std::shared_ptr<C2Buffer> mBufferRef;
};

/**
 * MediaCodecBuffer implementation wraps around C2LinearBlock.
 */
class LinearBlockBuffer : public Codec2Buffer {
public:
    /**
     * Allocate a new LinearBufferBlock wrapping around C2LinearBlock object.
     *
     * \param   format  mandatory buffer format for MediaCodecBuffer
     * \param   block   C2LinearBlock object to wrap around.
     * \return          LinearBlockBuffer object with writable mapping.
     *                  nullptr if unsuccessful.
     */
    static sp<LinearBlockBuffer> Allocate(
            const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block);

    virtual ~LinearBlockBuffer() = default;

    std::shared_ptr<C2Buffer> asC2Buffer() override;
    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;

private:
    LinearBlockBuffer(
            const sp<AMessage> &format,
            C2WriteView &&writeView,
            const std::shared_ptr<C2LinearBlock> &block);
    LinearBlockBuffer() = delete;

    C2WriteView mWriteView;
    std::shared_ptr<C2LinearBlock> mBlock;
};

/**
 * MediaCodecBuffer implementation wraps around C2ConstLinearBlock.
 */
class ConstLinearBlockBuffer : public Codec2Buffer {
public:
    /**
     * Allocate a new ConstLinearBlockBuffer wrapping around C2Buffer object.
     *
     * \param   format  mandatory buffer format for MediaCodecBuffer
     * \param   buffer  linear C2Buffer object to wrap around.
     * \return          ConstLinearBlockBuffer object with readable mapping.
     *                  nullptr if unsuccessful.
     */
    static sp<ConstLinearBlockBuffer> Allocate(
            const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer);

    virtual ~ConstLinearBlockBuffer() = default;

    std::shared_ptr<C2Buffer> asC2Buffer() override;
    void clearC2BufferRefs() override;

private:
    ConstLinearBlockBuffer(
            const sp<AMessage> &format,
            C2ReadView &&readView,
            const std::shared_ptr<C2Buffer> &buffer);
    ConstLinearBlockBuffer() = delete;

    C2ReadView mReadView;
    std::shared_ptr<C2Buffer> mBufferRef;
};

/**
 * MediaCodecBuffer implementation wraps around C2GraphicBlock.
 *
 * This object exposes the underlying bits via accessor APIs and "image-data"
 * metadata, created automatically at allocation time.
 */
class GraphicBlockBuffer : public Codec2Buffer {
public:
    /**
     * Allocate a new GraphicBlockBuffer wrapping around C2GraphicBlock object.
     * If |block| is not in good color formats, it allocates YV12 local buffer
     * and copies the content over at asC2Buffer().
     *
     * \param   format  mandatory buffer format for MediaCodecBuffer
     * \param   block   C2GraphicBlock object to wrap around.
     * \param   alloc   a function to allocate backing ABuffer if needed.
     * \return          GraphicBlockBuffer object with writable mapping.
     *                  nullptr if unsuccessful.
     */
    static sp<GraphicBlockBuffer> Allocate(
            const sp<AMessage> &format,
            const std::shared_ptr<C2GraphicBlock> &block,
            std::function<sp<ABuffer>(size_t)> alloc);

    virtual ~GraphicBlockBuffer() = default;

    std::shared_ptr<C2Buffer> asC2Buffer() override;

private:
    GraphicBlockBuffer(
            const sp<AMessage> &format,
            const sp<ABuffer> &buffer,
            C2GraphicView &&view,
            const std::shared_ptr<C2GraphicBlock> &block,
            const sp<ABuffer> &imageData,
            bool wrapped);
    GraphicBlockBuffer() = delete;

    inline MediaImage2 *imageData() { return (MediaImage2 *)mImageData->data(); }

    C2GraphicView mView;
    std::shared_ptr<C2GraphicBlock> mBlock;
    const bool mWrapped;
};

/**
 * MediaCodecBuffer implementation wraps around VideoNativeMetadata.
 */
class GraphicMetadataBuffer : public Codec2Buffer {
public:
    /**
     * Construct a new GraphicMetadataBuffer with local linear buffer for
     * VideoNativeMetadata.
     *
     * \param   format      mandatory buffer format for MediaCodecBuffer
     */
    GraphicMetadataBuffer(
            const sp<AMessage> &format, const std::shared_ptr<C2Allocator> &alloc);
    virtual ~GraphicMetadataBuffer() = default;

    std::shared_ptr<C2Buffer> asC2Buffer() override;

private:
    GraphicMetadataBuffer() = delete;

    std::shared_ptr<C2Allocator> mAlloc;
};

/**
 * MediaCodecBuffer implementation wraps around graphic C2Buffer object.
 *
 * This object exposes the underlying bits via accessor APIs and "image-data"
 * metadata, created automatically at allocation time.
 */
class ConstGraphicBlockBuffer : public Codec2Buffer {
public:
    /**
     * Allocate a new ConstGraphicBlockBuffer wrapping around C2Buffer object.
     * If |buffer| is not in good color formats, it allocates YV12 local buffer
     * and copies the content of |buffer| over to expose.
     *
     * \param   format  mandatory buffer format for MediaCodecBuffer
     * \param   buffer  graphic C2Buffer object to wrap around.
     * \param   alloc   a function to allocate backing ABuffer if needed.
     * \return          ConstGraphicBlockBuffer object with readable mapping.
     *                  nullptr if unsuccessful.
     */
    static sp<ConstGraphicBlockBuffer> Allocate(
            const sp<AMessage> &format,
            const std::shared_ptr<C2Buffer> &buffer,
            std::function<sp<ABuffer>(size_t)> alloc);

    /**
     * Allocate a new ConstGraphicBlockBuffer which allocates YV12 local buffer
     * and copies the content of |buffer| over to expose.
     *
     * \param   format  mandatory buffer format for MediaCodecBuffer
     * \param   alloc   a function to allocate backing ABuffer if needed.
     * \return          ConstGraphicBlockBuffer object with no wrapping buffer.
     */
    static sp<ConstGraphicBlockBuffer> AllocateEmpty(
            const sp<AMessage> &format,
            std::function<sp<ABuffer>(size_t)> alloc);

    virtual ~ConstGraphicBlockBuffer() = default;

    std::shared_ptr<C2Buffer> asC2Buffer() override;
    void clearC2BufferRefs() override;
    bool canCopy(const std::shared_ptr<C2Buffer> &buffer) const override;
    bool copy(const std::shared_ptr<C2Buffer> &buffer) override;

private:
    ConstGraphicBlockBuffer(
            const sp<AMessage> &format,
            const sp<ABuffer> &aBuffer,
            std::unique_ptr<const C2GraphicView> &&view,
            const std::shared_ptr<C2Buffer> &buffer,
            const sp<ABuffer> &imageData,
            bool wrapped);
    ConstGraphicBlockBuffer() = delete;

    sp<ABuffer> mImageData;
    std::unique_ptr<const C2GraphicView> mView;
    std::shared_ptr<C2Buffer> mBufferRef;
    const bool mWrapped;
};

/**
 * MediaCodecBuffer implementation wraps around C2LinearBlock for component
 * and IMemory for client. Underlying C2LinearBlock won't be mapped for secure
 * usecases..
 */
class EncryptedLinearBlockBuffer : public Codec2Buffer {
public:
    /**
     * Construct a new EncryptedLinearBufferBlock wrapping around C2LinearBlock
     * object and writable IMemory region.
     *
     * \param   format      mandatory buffer format for MediaCodecBuffer
     * \param   block       C2LinearBlock object to wrap around.
     * \param   memory      IMemory object to store encrypted content.
     * \param   heapSeqNum  Heap sequence number from ICrypto; -1 if N/A
     */
    EncryptedLinearBlockBuffer(
            const sp<AMessage> &format,
            const std::shared_ptr<C2LinearBlock> &block,
            const sp<IMemory> &memory,
            int32_t heapSeqNum = -1);
    EncryptedLinearBlockBuffer() = delete;

    virtual ~EncryptedLinearBlockBuffer() = default;

    std::shared_ptr<C2Buffer> asC2Buffer() override;

    /**
     * Fill the source buffer structure with appropriate value based on
     * internal IMemory object.
     *
     * \param source  source buffer structure to fill.
     */
    void fillSourceBuffer(
            hardware::drm::V1_0::SharedBuffer *source);
    void fillSourceBuffer(
            hardware::cas::native::V1_0::SharedBuffer *source);

    /**
     * Copy the content of |decrypted| into C2LinearBlock inside. This shall
     * only be called in non-secure usecases.
     *
     * \param   decrypted   decrypted content to copy from.
     * \param   length      length of the content
     * \return  true        if successful
     *          false       otherwise.
     */
    bool copyDecryptedContent(const sp<IMemory> &decrypted, size_t length);

    /**
     * Copy the content of internal IMemory object into C2LinearBlock inside.
     * This shall only be called in non-secure usecases.
     *
     * \param   length      length of the content
     * \return  true        if successful
     *          false       otherwise.
     */
    bool copyDecryptedContentFromMemory(size_t length);

    /**
     * Return native handle of secure buffer understood by ICrypto.
     *
     * \return secure buffer handle
     */
    native_handle_t *handle() const;

private:

    std::shared_ptr<C2LinearBlock> mBlock;
    sp<IMemory> mMemory;
    sp<hardware::HidlMemory> mHidlMemory;
    int32_t mHeapSeqNum;
};

}  // namespace android

#endif  // CODEC2_BUFFER_H_