• 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 class 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          * Notify MediaCodec that there are metrics to be updated.
187          *
188          * @param updatedMetrics metrics need to be updated.
189          */
190         virtual void onMetricsUpdated(const sp<AMessage> &updatedMetrics) = 0;
191     };
192 
193     /**
194      * This interface defines events firing from BufferChannelBase back to MediaCodec.
195      * All methods must not block.
196      */
197     class BufferCallback {
198     public:
199         virtual ~BufferCallback() = default;
200 
201         /**
202          * Notify MediaCodec that an input buffer is available with given index.
203          * When BufferChannelBase::getInputBufferArray() is not called,
204          * BufferChannelBase may report different buffers with the same index if
205          * MediaCodec already queued/discarded the buffer. After calling
206          * BufferChannelBase::getInputBufferArray(), the buffer and index match the
207          * returned array.
208          */
209         virtual void onInputBufferAvailable(
210                 size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
211         /**
212          * Notify MediaCodec that an output buffer is available with given index.
213          * When BufferChannelBase::getOutputBufferArray() is not called,
214          * BufferChannelBase may report different buffers with the same index if
215          * MediaCodec already queued/discarded the buffer. After calling
216          * BufferChannelBase::getOutputBufferArray(), the buffer and index match the
217          * returned array.
218          */
219         virtual void onOutputBufferAvailable(
220                 size_t index, const sp<MediaCodecBuffer> &buffer) = 0;
221     };
222     enum {
223         kMaxCodecBufferSize = 8192 * 4096 * 4, // 8K RGBA
224     };
225 
setCallbackCodecBase226     inline void setCallback(std::unique_ptr<CodecCallback> &&callback) {
227         mCallback = std::move(callback);
228     }
229     virtual std::shared_ptr<BufferChannelBase> getBufferChannel() = 0;
230 
231     virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
232     virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
233     virtual void initiateCreateInputSurface() = 0;
234     virtual void initiateSetInputSurface(
235             const sp<PersistentSurface> &surface) = 0;
236     virtual void initiateStart() = 0;
237     virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;
238 
239     // require an explicit message handler
240     virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
241 
setSurfaceCodecBase242     virtual status_t setSurface(const sp<Surface>& /*surface*/) { return INVALID_OPERATION; }
243 
244     virtual void signalFlush() = 0;
245     virtual void signalResume() = 0;
246 
247     virtual void signalRequestIDRFrame() = 0;
248     virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
249     virtual void signalEndOfInputStream() = 0;
250 
251     /**
252      * Query supported parameters from this instance, and fill |names| with the
253      * names of the parameters.
254      *
255      * \param names string vector to fill with supported parameters.
256      * \return OK if successful;
257      *         BAD_VALUE if |names| is null;
258      *         INVALID_OPERATION if already released;
259      *         ERROR_UNSUPPORTED if not supported.
260      */
261     virtual status_t querySupportedParameters(std::vector<std::string> *names);
262     /**
263      * Fill |desc| with description of the parameter with |name|.
264      *
265      * \param name name of the parameter to describe
266      * \param desc pointer to CodecParameterDescriptor to be filled
267      * \return OK if successful;
268      *         BAD_VALUE if |desc| is null;
269      *         NAME_NOT_FOUND if |name| is not recognized by the component;
270      *         INVALID_OPERATION if already released;
271      *         ERROR_UNSUPPORTED if not supported.
272      */
273     virtual status_t describeParameter(
274             const std::string &name,
275             CodecParameterDescriptor *desc);
276     /**
277      * Subscribe to parameters in |names| and get output format change event
278      * when they change.
279      * Unrecognized / already subscribed parameters are ignored.
280      *
281      * \param names names of parameters to subscribe
282      * \return OK if successful;
283      *         INVALID_OPERATION if already released;
284      *         ERROR_UNSUPPORTED if not supported.
285      */
286     virtual status_t subscribeToParameters(const std::vector<std::string> &names);
287     /**
288      * Unsubscribe from parameters in |names| and no longer get
289      * output format change event when they change.
290      * Unrecognized / already unsubscribed parameters are ignored.
291      *
292      * \param names names of parameters to unsubscribe
293      * \return OK if successful;
294      *         INVALID_OPERATION if already released;
295      *         ERROR_UNSUPPORTED if not supported.
296      */
297     virtual status_t unsubscribeFromParameters(const std::vector<std::string> &names);
298 
299     typedef CodecBase *(*CreateCodecFunc)(void);
300     typedef PersistentSurface *(*CreateInputSurfaceFunc)(void);
301 
302 protected:
303     CodecBase() = default;
304     virtual ~CodecBase() = default;
305 
306     std::unique_ptr<CodecCallback> mCallback;
307 
308 private:
309     DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
310 };
311 
312 /**
313  * A channel between MediaCodec and CodecBase object which manages buffer
314  * passing. Only MediaCodec is expected to call these methods, and
315  * underlying CodecBase implementation should define its own interface
316  * separately for itself.
317  *
318  * Concurrency assumptions:
319  *
320  * 1) Clients may access the object at multiple threads concurrently.
321  * 2) All methods do not call underlying CodecBase object while holding a lock.
322  * 3) Code inside critical section executes within 1ms.
323  */
324 class BufferChannelBase {
325 public:
326     BufferChannelBase() = default;
327     virtual ~BufferChannelBase() = default;
328 
setCallback(std::unique_ptr<CodecBase::BufferCallback> && callback)329     inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) {
330         mCallback = std::move(callback);
331     }
332 
setCrypto(const sp<ICrypto> &)333     virtual void setCrypto(const sp<ICrypto> &) {}
setDescrambler(const sp<IDescrambler> &)334     virtual void setDescrambler(const sp<IDescrambler> &) {}
335 
336     /**
337      * Queue an input buffer into the buffer channel.
338      *
339      * @return    OK if successful;
340      *            -ENOENT if the buffer is not known (TODO: this should be
341      *            handled gracefully in the future, here and below).
342      */
343     virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
344     /**
345      * Queue a secure input buffer into the buffer channel.
346      *
347      * @return    OK if successful;
348      *            -ENOENT if the buffer is not known;
349      *            -ENOSYS if mCrypto is not set so that decryption is not
350      *            possible;
351      *            other errors if decryption failed.
352      */
353     virtual status_t queueSecureInputBuffer(
354             const sp<MediaCodecBuffer> &buffer,
355             bool secure,
356             const uint8_t *key,
357             const uint8_t *iv,
358             CryptoPlugin::Mode mode,
359             CryptoPlugin::Pattern pattern,
360             const CryptoPlugin::SubSample *subSamples,
361             size_t numSubSamples,
362             AString *errorDetailMsg) = 0;
363     /**
364      * Attach a Codec 2.0 buffer to MediaCodecBuffer.
365      *
366      * @return    OK if successful;
367      *            -ENOENT if index is not recognized
368      *            -ENOSYS if attaching buffer is not possible or not supported
369      */
attachBuffer(const std::shared_ptr<C2Buffer> & c2Buffer,const sp<MediaCodecBuffer> & buffer)370     virtual status_t attachBuffer(
371             const std::shared_ptr<C2Buffer> &c2Buffer,
372             const sp<MediaCodecBuffer> &buffer) {
373         (void)c2Buffer;
374         (void)buffer;
375         return -ENOSYS;
376     }
377     /**
378      * Attach an encrypted HidlMemory buffer to an index
379      *
380      * @return    OK if successful;
381      *            -ENOENT if index is not recognized
382      *            -ENOSYS if attaching buffer is not possible or not supported
383      */
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,AString * errorDetailMsg)384     virtual status_t attachEncryptedBuffer(
385             const sp<hardware::HidlMemory> &memory,
386             bool secure,
387             const uint8_t *key,
388             const uint8_t *iv,
389             CryptoPlugin::Mode mode,
390             CryptoPlugin::Pattern pattern,
391             size_t offset,
392             const CryptoPlugin::SubSample *subSamples,
393             size_t numSubSamples,
394             const sp<MediaCodecBuffer> &buffer,
395             AString* errorDetailMsg) {
396         (void)memory;
397         (void)secure;
398         (void)key;
399         (void)iv;
400         (void)mode;
401         (void)pattern;
402         (void)offset;
403         (void)subSamples;
404         (void)numSubSamples;
405         (void)buffer;
406         (void)errorDetailMsg;
407         return -ENOSYS;
408     }
409     /**
410      * Request buffer rendering at specified time.
411      *
412      * @param     timestampNs   nanosecond timestamp for rendering time.
413      * @return    OK if successful;
414      *            -ENOENT if the buffer is not known.
415      */
416     virtual status_t renderOutputBuffer(
417             const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) = 0;
418 
419     /**
420      * Poll for updates about rendered buffers.
421      *
422      * Triggers callbacks to CodecCallback::onOutputFramesRendered.
423      */
424     virtual void pollForRenderedBuffers() = 0;
425 
426     /**
427      * Discard a buffer to the underlying CodecBase object.
428      *
429      * TODO: remove once this operation can be handled by just clearing the
430      * reference.
431      *
432      * @return    OK if successful;
433      *            -ENOENT if the buffer is not known.
434      */
435     virtual status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) = 0;
436     /**
437      * Clear and fill array with input buffers.
438      */
439     virtual void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
440     /**
441      * Clear and fill array with output buffers.
442      */
443     virtual void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) = 0;
444 
445     /**
446      * Convert binder IMemory to drm SharedBuffer
447      *
448      * \param   memory      IMemory object to store encrypted content.
449      * \param   heapSeqNum  Heap sequence number from ICrypto; -1 if N/A
450      * \param   buf         SharedBuffer structure to fill.
451      */
452     static void IMemoryToSharedBuffer(
453             const sp<IMemory> &memory,
454             int32_t heapSeqNum,
455             hardware::drm::V1_0::SharedBuffer *buf);
456 
457 protected:
458     std::unique_ptr<CodecBase::BufferCallback> mCallback;
459 };
460 
461 }  // namespace android
462 
463 #endif  // CODEC_BASE_H_
464