Home | History | Annotate | Download | only in stagefright
      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 
    200     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 
    216     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 
    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