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