1 /*
2  * Copyright (C) 2014 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 CODEC_BASE_H_
18 
19 #define CODEC_BASE_H_
20 
21 #include <list>
22 #include <memory>
23 
24 #include <stdint.h>
25 
26 #define STRINGIFY_ENUMS
27 
28 #include <media/hardware/CryptoAPI.h>
29 #include <media/hardware/HardwareAPI.h>
30 #include <media/MediaCodecInfo.h>
31 #include <media/stagefright/foundation/AHandler.h>
32 #include <media/stagefright/foundation/ColorUtils.h>
33 #include <media/stagefright/MediaErrors.h>
34 #include <system/graphics.h>
35 #include <utils/NativeHandle.h>
36 
37 class C2Buffer;
38 
39 namespace android {
40 class BufferChannelBase;
41 struct BufferProducerWrapper;
42 class MediaCodecBuffer;
43 struct PersistentSurface;
44 struct RenderedFrameInfo;
45 class Surface;
46 struct ICrypto;
47 class IMemory;
48 
49 namespace hardware {
50 class HidlMemory;
51 namespace cas {
52 namespace native {
53 namespace V1_0 {
54 struct IDescrambler;
55 }}}
56 namespace drm {
57 namespace V1_0 {
58 struct SharedBuffer;
59 }}
60 }
61 
62 using hardware::cas::native::V1_0::IDescrambler;
63 
64 struct CodecBase : public AHandler, /* static */ ColorUtils {
65     /**
66      * This interface defines events firing from CodecBase back to MediaCodec.
67      * All methods must not block.
68      */
69     class CodecCallback {
70     public:
71         virtual ~CodecCallback() = default;
72 
73         /**
74          * Notify MediaCodec for seeing an output EOS.
75          *
76          * @param err the underlying cause of the EOS. If the value is neither
77          *            OK nor ERROR_END_OF_STREAM, the EOS is declared
78          *            prematurely for that error.
79          */
80         virtual void onEos(status_t err) = 0;
81         /**
82          * Notify MediaCodec that start operation is complete.
83          */
84         virtual void onStartCompleted() = 0;
85         /**
86          * Notify MediaCodec that stop operation is complete.
87          */
88         virtual void onStopCompleted() = 0;
89         /**
90          * Notify MediaCodec that release operation is complete.
91          */
92         virtual void onReleaseCompleted() = 0;
93         /**
94          * Notify MediaCodec that flush operation is complete.
95          */
96         virtual void onFlushCompleted() = 0;
97         /**
98          * Notify MediaCodec that an error is occurred.
99          *
100          * @param err         an error code for the occurred error.
101          * @param actionCode  an action code for severity of the error.
102          */
103         virtual void onError(status_t err, enum ActionCode actionCode) = 0;
104         /**
105          * Notify MediaCodec that the underlying component is allocated.
106          *
107          * @param componentName the unique name of the component specified in
108          *                      MediaCodecList.
109          */
110         virtual void onComponentAllocated(const char *componentName) = 0;
111         /**
112          * Notify MediaCodec that the underlying component is configured.
113          *
114          * @param inputFormat   an input format at configure time.
115          * @param outputFormat  an output format at configure time.
116          */
117         virtual void onComponentConfigured(
118                 const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) = 0;
119         /**
120          * Notify MediaCodec that the input surface is created.
121          *
122          * @param inputFormat   an input format at surface creation. Formats
123          *                      could change from the previous state as a result
124          *                      of creating a surface.
125          * @param outputFormat  an output format at surface creation.
126          * @param inputSurface  the created surface.
127          */
128         virtual void onInputSurfaceCreated(
129                 const sp<AMessage> &inputFormat,
130                 const sp<AMessage> &outputFormat,
131                 const sp<BufferProducerWrapper> &inputSurface) = 0;
132         /**
133          * Notify MediaCodec that the input surface creation is failed.
134          *
135          * @param err an error code of the cause.
136          */
137         virtual void onInputSurfaceCreationFailed(status_t err) = 0;
138         /**
139          * Notify MediaCodec that the component accepted the provided input
140          * surface.
141          *
142          * @param inputFormat   an input format at surface assignment. Formats
143          *                      could change from the previous state as a result
144          *                      of assigning a surface.
145          * @param outputFormat  an output format at surface assignment.
146          */
147         virtual void onInputSurfaceAccepted(
148                 const sp<AMessage> &inputFormat,
149                 const sp<AMessage> &outputFormat) = 0;
150         /**
151          * Notify MediaCodec that the component declined the provided input
152          * surface.
153          *
154          * @param err an error code of the cause.
155          */
156         virtual void onInputSurfaceDeclined(status_t err) = 0;
157         /**
158          * Noitfy MediaCodec that the requested input EOS is sent to the input
159          * surface.
160          *
161          * @param err an error code returned from the surface. If there is no
162          *            input surface, the value is INVALID_OPERATION.
163          */
164         virtual void onSignaledInputEOS(status_t err) = 0;
165         /**
166          * Notify MediaCodec that output frames are rendered with information on
167          * those frames.
168          *
169          * @param done  a list of rendered frames.
170          */
171         virtual void onOutputFramesRendered(const std::list<RenderedFrameInfo> &done) = 0;
172         /**
173          * Notify MediaCodec that output buffers are changed.
174          */
175         virtual void onOutputBuffersChanged() = 0;
176     };
177 
178     /**
179      * This interface defines events firing from BufferChannelBase back to MediaCodec.
180      * All methods must not block.
181      */
182     class BufferCallback {
183     public:
184         virtual ~BufferCallback() = default;
185 
186         /**
187          * Notify MediaCodec that an input buffer is available with given index.
188          * When BufferChannelBase::getInputBufferArray() is not called,
189          * BufferChannelBase may report different buffers with the same index if
190          * MediaCodec already queued/discarded the buffer. After calling
191          * BufferChannelBase::getInputBufferArray(), the buffer and index match the
192          * returned array.
193          */
194         virtual void onInputBufferAvailable(
195                 size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
196         /**
197          * Notify MediaCodec that an output buffer is available with given index.
198          * When BufferChannelBase::getOutputBufferArray() is not called,
199          * BufferChannelBase may report different buffers with the same index if
200          * MediaCodec already queued/discarded the buffer. After calling
201          * BufferChannelBase::getOutputBufferArray(), the buffer and index match the
202          * returned array.
203          */
204         virtual void onOutputBufferAvailable(
205                 size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
206     };
207     enum {
208         kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA
209     };
210 
setCallbackCodecBase211     inline void setCallback(std::unique_ptr<CodecCallback> &&callback) {
212         mCallback = std::move(callback);
213     }
214     virtual std::shared_ptr<BufferChannelBase> getBufferChannel() = 0;
215 
216     virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
217     virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
218     virtual void initiateCreateInputSurface() = 0;
219     virtual void initiateSetInputSurface(
220             const sp<PersistentSurface> &surface) = 0;
221     virtual void initiateStart() = 0;
222     virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;
223 
224     // require an explicit message handler
225     virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
226 
setSurfaceCodecBase227     virtual status_t setSurface(const sp<Surface>& /*surface*/) { return INVALID_OPERATION; }
228 
229     virtual void signalFlush() = 0;
230     virtual void signalResume() = 0;
231 
232     virtual void signalRequestIDRFrame() = 0;
233     virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
234     virtual void signalEndOfInputStream() = 0;
235 
236     typedef CodecBase *(*CreateCodecFunc)(void);
237     typedef PersistentSurface *(*CreateInputSurfaceFunc)(void);
238 
239 protected:
240     CodecBase() = default;
241     virtual ~CodecBase() = default;
242 
243     std::unique_ptr<CodecCallback> mCallback;
244 
245 private:
246     DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
247 };
248 
249 /**
250  * A channel between MediaCodec and CodecBase object which manages buffer
251  * passing. Only MediaCodec is expected to call these methods, and
252  * underlying CodecBase implementation should define its own interface
253  * separately for itself.
254  *
255  * Concurrency assumptions:
256  *
257  * 1) Clients may access the object at multiple threads concurrently.
258  * 2) All methods do not call underlying CodecBase object while holding a lock.
259  * 3) Code inside critical section executes within 1ms.
260  */
261 class BufferChannelBase {
262 public:
263     BufferChannelBase() = default;
264     virtual ~BufferChannelBase() = default;
265 
setCallback(std::unique_ptr<CodecBase::BufferCallback> && callback)266     inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) {
267         mCallback = std::move(callback);
268     }
269 
setCrypto(const sp<ICrypto> &)270     virtual void setCrypto(const sp<ICrypto> &) {}
setDescrambler(const sp<IDescrambler> &)271     virtual void setDescrambler(const sp<IDescrambler> &) {}
272 
273     /**
274      * Queue an input buffer into the buffer channel.
275      *
276      * @return    OK if successful;
277      *            -ENOENT if the buffer is not known (TODO: this should be
278      *            handled gracefully in the future, here and below).
279      */
280     virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
281     /**
282      * Queue a secure input buffer into the buffer channel.
283      *
284      * @return    OK if successful;
285      *            -ENOENT if the buffer is not known;
286      *            -ENOSYS if mCrypto is not set so that decryption is not
287      *            possible;
288      *            other errors if decryption failed.
289      */
290     virtual status_t queueSecureInputBuffer(
291             const sp<MediaCodecBuffer> &buffer,
292             bool secure,
293             const uint8_t *key,
294             const uint8_t *iv,
295             CryptoPlugin::Mode mode,
296             CryptoPlugin::Pattern pattern,
297             const CryptoPlugin::SubSample *subSamples,
298             size_t numSubSamples,
299             AString *errorDetailMsg) = 0;
300     /**
301      * Attach a Codec 2.0 buffer to MediaCodecBuffer.
302      *
303      * @return    OK if successful;
304      *            -ENOENT if index is not recognized
305      *            -ENOSYS if attaching buffer is not possible or not supported
306      */
attachBuffer(const std::shared_ptr<C2Buffer> & c2Buffer,const sp<MediaCodecBuffer> & buffer)307     virtual status_t attachBuffer(
308             const std::shared_ptr<C2Buffer> &c2Buffer,
309             const sp<MediaCodecBuffer> &buffer) {
310         (void)c2Buffer;
311         (void)buffer;
312         return -ENOSYS;
313     }
314     /**
315      * Attach an encrypted HidlMemory buffer to an index
316      *
317      * @return    OK if successful;
318      *            -ENOENT if index is not recognized
319      *            -ENOSYS if attaching buffer is not possible or not supported
320      */
attachEncryptedBuffer(const sp<hardware::HidlMemory> & memory,bool secure,const uint8_t * key,const uint8_t * iv,CryptoPlugin::Mode mode,CryptoPlugin::Pattern pattern,size_t offset,const CryptoPlugin::SubSample * subSamples,size_t numSubSamples,const sp<MediaCodecBuffer> & buffer)321     virtual status_t attachEncryptedBuffer(
322             const sp<hardware::HidlMemory> &memory,
323             bool secure,
324             const uint8_t *key,
325             const uint8_t *iv,
326             CryptoPlugin::Mode mode,
327             CryptoPlugin::Pattern pattern,
328             size_t offset,
329             const CryptoPlugin::SubSample *subSamples,
330             size_t numSubSamples,
331             const sp<MediaCodecBuffer> &buffer) {
332         (void)memory;
333         (void)secure;
334         (void)key;
335         (void)iv;
336         (void)mode;
337         (void)pattern;
338         (void)offset;
339         (void)subSamples;
340         (void)numSubSamples;
341         (void)buffer;
342         return -ENOSYS;
343     }
344     /**
345      * Request buffer rendering at specified time.
346      *
347      * @param     timestampNs   nanosecond timestamp for rendering time.
348      * @return    OK if successful;
349      *            -ENOENT if the buffer is not known.
350      */
351     virtual status_t renderOutputBuffer(
352             const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0;
353     /**
354      * Discard a buffer to the underlying CodecBase object.
355      *
356      * TODO: remove once this operation can be handled by just clearing the
357      * reference.
358      *
359      * @return    OK if successful;
360      *            -ENOENT if the buffer is not known.
361      */
362     virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
363     /**
364      * Clear and fill array with input buffers.
365      */
366     virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
367     /**
368      * Clear and fill array with output buffers.
369      */
370     virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
371 
372     /**
373      * Convert binder IMemory to drm SharedBuffer
374      *
375      * \param   memory      IMemory object to store encrypted content.
376      * \param   heapSeqNum  Heap sequence number from ICrypto; -1 if N/A
377      * \param   buf         SharedBuffer structure to fill.
378      */
379     static void IMemoryToSharedBuffer(
380             const sp<IMemory> &memory,
381             int32_t heapSeqNum,
382             hardware::drm::V1_0::SharedBuffer *buf);
383 
384 protected:
385     std::unique_ptr<CodecBase::BufferCallback> mCallback;
386 };
387 
388 }  // namespace android
389 
390 #endif  // CODEC_BASE_H_
391