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