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