• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 CodecParameterDescriptor {
65     std::string name;
66     AMessage::Type type;
67 };
68 
69 struct CodecBase : public AHandler, /* static */ ColorUtils {
70     /**
71      * This interface defines events firing from CodecBase back to MediaCodec.
72      * All methods must not block.
73      */
74     class CodecCallback {
75     public:
76         virtual ~CodecCallback() = default;
77 
78         /**
79          * Notify MediaCodec for seeing an output EOS.
80          *
81          * @param err the underlying cause of the EOS. If the value is neither
82          *            OK nor ERROR_END_OF_STREAM, the EOS is declared
83          *            prematurely for that error.
84          */
85         virtual void onEos(status_t err) = 0;
86         /**
87          * Notify MediaCodec that start operation is complete.
88          */
89         virtual void onStartCompleted() = 0;
90         /**
91          * Notify MediaCodec that stop operation is complete.
92          */
93         virtual void onStopCompleted() = 0;
94         /**
95          * Notify MediaCodec that release operation is complete.
96          */
97         virtual void onReleaseCompleted() = 0;
98         /**
99          * Notify MediaCodec that flush operation is complete.
100          */
101         virtual void onFlushCompleted() = 0;
102         /**
103          * Notify MediaCodec that an error is occurred.
104          *
105          * @param err         an error code for the occurred error.
106          * @param actionCode  an action code for severity of the error.
107          */
108         virtual void onError(status_t err, enum ActionCode actionCode) = 0;
109         /**
110          * Notify MediaCodec that the underlying component is allocated.
111          *
112          * @param componentName the unique name of the component specified in
113          *                      MediaCodecList.
114          */
115         virtual void onComponentAllocated(const char *componentName) = 0;
116         /**
117          * Notify MediaCodec that the underlying component is configured.
118          *
119          * @param inputFormat   an input format at configure time.
120          * @param outputFormat  an output format at configure time.
121          */
122         virtual void onComponentConfigured(
123                 const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) = 0;
124         /**
125          * Notify MediaCodec that the input surface is created.
126          *
127          * @param inputFormat   an input format at surface creation. Formats
128          *                      could change from the previous state as a result
129          *                      of creating a surface.
130          * @param outputFormat  an output format at surface creation.
131          * @param inputSurface  the created surface.
132          */
133         virtual void onInputSurfaceCreated(
134                 const sp<AMessage> &inputFormat,
135                 const sp<AMessage> &outputFormat,
136                 const sp<BufferProducerWrapper> &inputSurface) = 0;
137         /**
138          * Notify MediaCodec that the input surface creation is failed.
139          *
140          * @param err an error code of the cause.
141          */
142         virtual void onInputSurfaceCreationFailed(status_t err) = 0;
143         /**
144          * Notify MediaCodec that the component accepted the provided input
145          * surface.
146          *
147          * @param inputFormat   an input format at surface assignment. Formats
148          *                      could change from the previous state as a result
149          *                      of assigning a surface.
150          * @param outputFormat  an output format at surface assignment.
151          */
152         virtual void onInputSurfaceAccepted(
153                 const sp<AMessage> &inputFormat,
154                 const sp<AMessage> &outputFormat) = 0;
155         /**
156          * Notify MediaCodec that the component declined the provided input
157          * surface.
158          *
159          * @param err an error code of the cause.
160          */
161         virtual void onInputSurfaceDeclined(status_t err) = 0;
162         /**
163          * Noitfy MediaCodec that the requested input EOS is sent to the input
164          * surface.
165          *
166          * @param err an error code returned from the surface. If there is no
167          *            input surface, the value is INVALID_OPERATION.
168          */
169         virtual void onSignaledInputEOS(status_t err) = 0;
170         /**
171          * Notify MediaCodec that output frames are rendered with information on
172          * those frames.
173          *
174          * @param done  a list of rendered frames.
175          */
176         virtual void onOutputFramesRendered(const std::list<RenderedFrameInfo> &done) = 0;
177         /**
178          * Notify MediaCodec that output buffers are changed.
179          */
180         virtual void onOutputBuffersChanged() = 0;
181         /**
182          * Notify MediaCodec that the first tunnel frame is ready.
183          */
184         virtual void onFirstTunnelFrameReady() = 0;
185     };
186 
187     /**
188      * This interface defines events firing from BufferChannelBase back to MediaCodec.
189      * All methods must not block.
190      */
191     class BufferCallback {
192     public:
193         virtual ~BufferCallback() = default;
194 
195         /**
196          * Notify MediaCodec that an input buffer is available with given index.
197          * When BufferChannelBase::getInputBufferArray() is not called,
198          * BufferChannelBase may report different buffers with the same index if
199          * MediaCodec already queued/discarded the buffer. After calling
200          * BufferChannelBase::getInputBufferArray(), the buffer and index match the
201          * returned array.
202          */
203         virtual void onInputBufferAvailable(
204                 size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
205         /**
206          * Notify MediaCodec that an output buffer is available with given index.
207          * When BufferChannelBase::getOutputBufferArray() is not called,
208          * BufferChannelBase may report different buffers with the same index if
209          * MediaCodec already queued/discarded the buffer. After calling
210          * BufferChannelBase::getOutputBufferArray(), the buffer and index match the
211          * returned array.
212          */
213         virtual void onOutputBufferAvailable(
214                 size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
215     };
216     enum {
217         kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA
218     };
219 
setCallbackCodecBase220     inline void setCallback(std::unique_ptr<CodecCallback> &&callback) {
221         mCallback = std::move(callback);
222     }
223     virtual std::shared_ptr<BufferChannelBase> getBufferChannel() = 0;
224 
225     virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
226     virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
227     virtual void initiateCreateInputSurface() = 0;
228     virtual void initiateSetInputSurface(
229             const sp<PersistentSurface> &surface) = 0;
230     virtual void initiateStart() = 0;
231     virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;
232 
233     // require an explicit message handler
234     virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
235 
setSurfaceCodecBase236     virtual status_t setSurface(const sp<Surface>& /*surface*/) { return INVALID_OPERATION; }
237 
238     virtual void signalFlush() = 0;
239     virtual void signalResume() = 0;
240 
241     virtual void signalRequestIDRFrame() = 0;
242     virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
243     virtual void signalEndOfInputStream() = 0;
244 
245     /**
246      * Query supported parameters from this instance, and fill |names| with the
247      * names of the parameters.
248      *
249      * \param names string vector to fill with supported parameters.
250      * \return OK if successful;
251      *         BAD_VALUE if |names| is null;
252      *         INVALID_OPERATION if already released;
253      *         ERROR_UNSUPPORTED if not supported.
254      */
255     virtual status_t querySupportedParameters(std::vector<std::string> *names);
256     /**
257      * Fill |desc| with description of the parameter with |name|.
258      *
259      * \param name name of the parameter to describe
260      * \param desc pointer to CodecParameterDescriptor to be filled
261      * \return OK if successful;
262      *         BAD_VALUE if |desc| is null;
263      *         NAME_NOT_FOUND if |name| is not recognized by the component;
264      *         INVALID_OPERATION if already released;
265      *         ERROR_UNSUPPORTED if not supported.
266      */
267     virtual status_t describeParameter(
268             const std::string &name,
269             CodecParameterDescriptor *desc);
270     /**
271      * Subscribe to parameters in |names| and get output format change event
272      * when they change.
273      * Unrecognized / already subscribed parameters are ignored.
274      *
275      * \param names names of parameters to subscribe
276      * \return OK if successful;
277      *         INVALID_OPERATION if already released;
278      *         ERROR_UNSUPPORTED if not supported.
279      */
280     virtual status_t subscribeToParameters(const std::vector<std::string> &names);
281     /**
282      * Unsubscribe from parameters in |names| and no longer get
283      * output format change event when they change.
284      * Unrecognized / already unsubscribed parameters are ignored.
285      *
286      * \param names names of parameters to unsubscribe
287      * \return OK if successful;
288      *         INVALID_OPERATION if already released;
289      *         ERROR_UNSUPPORTED if not supported.
290      */
291     virtual status_t unsubscribeFromParameters(const std::vector<std::string> &names);
292 
293     typedef CodecBase *(*CreateCodecFunc)(void);
294     typedef PersistentSurface *(*CreateInputSurfaceFunc)(void);
295 
296 protected:
297     CodecBase() = default;
298     virtual ~CodecBase() = default;
299 
300     std::unique_ptr<CodecCallback> mCallback;
301 
302 private:
303     DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
304 };
305 
306 /**
307  * A channel between MediaCodec and CodecBase object which manages buffer
308  * passing. Only MediaCodec is expected to call these methods, and
309  * underlying CodecBase implementation should define its own interface
310  * separately for itself.
311  *
312  * Concurrency assumptions:
313  *
314  * 1) Clients may access the object at multiple threads concurrently.
315  * 2) All methods do not call underlying CodecBase object while holding a lock.
316  * 3) Code inside critical section executes within 1ms.
317  */
318 class BufferChannelBase {
319 public:
320     BufferChannelBase() = default;
321     virtual ~BufferChannelBase() = default;
322 
setCallback(std::unique_ptr<CodecBase::BufferCallback> && callback)323     inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) {
324         mCallback = std::move(callback);
325     }
326 
setCrypto(const sp<ICrypto> &)327     virtual void setCrypto(const sp<ICrypto> &) {}
setDescrambler(const sp<IDescrambler> &)328     virtual void setDescrambler(const sp<IDescrambler> &) {}
329 
330     /**
331      * Queue an input buffer into the buffer channel.
332      *
333      * @return    OK if successful;
334      *            -ENOENT if the buffer is not known (TODO: this should be
335      *            handled gracefully in the future, here and below).
336      */
337     virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
338     /**
339      * Queue a secure input buffer into the buffer channel.
340      *
341      * @return    OK if successful;
342      *            -ENOENT if the buffer is not known;
343      *            -ENOSYS if mCrypto is not set so that decryption is not
344      *            possible;
345      *            other errors if decryption failed.
346      */
347     virtual status_t queueSecureInputBuffer(
348             const sp<MediaCodecBuffer> &buffer,
349             bool secure,
350             const uint8_t *key,
351             const uint8_t *iv,
352             CryptoPlugin::Mode mode,
353             CryptoPlugin::Pattern pattern,
354             const CryptoPlugin::SubSample *subSamples,
355             size_t numSubSamples,
356             AString *errorDetailMsg) = 0;
357     /**
358      * Attach a Codec 2.0 buffer to MediaCodecBuffer.
359      *
360      * @return    OK if successful;
361      *            -ENOENT if index is not recognized
362      *            -ENOSYS if attaching buffer is not possible or not supported
363      */
attachBuffer(const std::shared_ptr<C2Buffer> & c2Buffer,const sp<MediaCodecBuffer> & buffer)364     virtual status_t attachBuffer(
365             const std::shared_ptr<C2Buffer> &c2Buffer,
366             const sp<MediaCodecBuffer> &buffer) {
367         (void)c2Buffer;
368         (void)buffer;
369         return -ENOSYS;
370     }
371     /**
372      * Attach an encrypted HidlMemory buffer to an index
373      *
374      * @return    OK if successful;
375      *            -ENOENT if index is not recognized
376      *            -ENOSYS if attaching buffer is not possible or not supported
377      */
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)378     virtual status_t attachEncryptedBuffer(
379             const sp<hardware::HidlMemory> &memory,
380             bool secure,
381             const uint8_t *key,
382             const uint8_t *iv,
383             CryptoPlugin::Mode mode,
384             CryptoPlugin::Pattern pattern,
385             size_t offset,
386             const CryptoPlugin::SubSample *subSamples,
387             size_t numSubSamples,
388             const sp<MediaCodecBuffer> &buffer) {
389         (void)memory;
390         (void)secure;
391         (void)key;
392         (void)iv;
393         (void)mode;
394         (void)pattern;
395         (void)offset;
396         (void)subSamples;
397         (void)numSubSamples;
398         (void)buffer;
399         return -ENOSYS;
400     }
401     /**
402      * Request buffer rendering at specified time.
403      *
404      * @param     timestampNs   nanosecond timestamp for rendering time.
405      * @return    OK if successful;
406      *            -ENOENT if the buffer is not known.
407      */
408     virtual status_t renderOutputBuffer(
409             const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0;
410     /**
411      * Discard a buffer to the underlying CodecBase object.
412      *
413      * TODO: remove once this operation can be handled by just clearing the
414      * reference.
415      *
416      * @return    OK if successful;
417      *            -ENOENT if the buffer is not known.
418      */
419     virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
420     /**
421      * Clear and fill array with input buffers.
422      */
423     virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
424     /**
425      * Clear and fill array with output buffers.
426      */
427     virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
428 
429     /**
430      * Convert binder IMemory to drm SharedBuffer
431      *
432      * \param   memory      IMemory object to store encrypted content.
433      * \param   heapSeqNum  Heap sequence number from ICrypto; -1 if N/A
434      * \param   buf         SharedBuffer structure to fill.
435      */
436     static void IMemoryToSharedBuffer(
437             const sp<IMemory> &memory,
438             int32_t heapSeqNum,
439             hardware::drm::V1_0::SharedBuffer *buf);
440 
441 protected:
442     std::unique_ptr<CodecBase::BufferCallback> mCallback;
443 };
444 
445 }  // namespace android
446 
447 #endif  // CODEC_BASE_H_
448