Home | History | Annotate | Download | only in stagefright
      1 /*
      2  * Copyright (C) 2010 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 A_CODEC_H_
     18 
     19 #define A_CODEC_H_
     20 
     21 #include <stdint.h>
     22 #include <android/native_window.h>
     23 #include <media/IOMX.h>
     24 #include <media/stagefright/foundation/AHierarchicalStateMachine.h>
     25 #include <media/stagefright/CodecBase.h>
     26 #include <media/stagefright/SkipCutBuffer.h>
     27 #include <OMX_Audio.h>
     28 
     29 #define TRACK_BUFFER_TIMING     0
     30 
     31 namespace android {
     32 
     33 struct ABuffer;
     34 struct MemoryDealer;
     35 struct DescribeColorFormatParams;
     36 
     37 struct ACodec : public AHierarchicalStateMachine, public CodecBase {
     38     ACodec();
     39 
     40     virtual void setNotificationMessage(const sp<AMessage> &msg);
     41 
     42     void initiateSetup(const sp<AMessage> &msg);
     43 
     44     virtual void initiateAllocateComponent(const sp<AMessage> &msg);
     45     virtual void initiateConfigureComponent(const sp<AMessage> &msg);
     46     virtual void initiateCreateInputSurface();
     47     virtual void initiateStart();
     48     virtual void initiateShutdown(bool keepComponentAllocated = false);
     49 
     50     virtual void signalFlush();
     51     virtual void signalResume();
     52 
     53     virtual void signalSetParameters(const sp<AMessage> &msg);
     54     virtual void signalEndOfInputStream();
     55     virtual void signalRequestIDRFrame();
     56 
     57     // AHierarchicalStateMachine implements the message handling
     58     virtual void onMessageReceived(const sp<AMessage> &msg) {
     59         handleMessage(msg);
     60     }
     61 
     62     struct PortDescription : public CodecBase::PortDescription {
     63         size_t countBuffers();
     64         IOMX::buffer_id bufferIDAt(size_t index) const;
     65         sp<ABuffer> bufferAt(size_t index) const;
     66 
     67     private:
     68         friend struct ACodec;
     69 
     70         Vector<IOMX::buffer_id> mBufferIDs;
     71         Vector<sp<ABuffer> > mBuffers;
     72 
     73         PortDescription();
     74         void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer);
     75 
     76         DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
     77     };
     78 
     79     static bool isFlexibleColorFormat(
     80             const sp<IOMX> &omx, IOMX::node_id node,
     81             uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent);
     82 
     83     // Returns 0 if configuration is not supported.  NOTE: this is treated by
     84     // some OMX components as auto level, and by others as invalid level.
     85     static int /* OMX_VIDEO_AVCLEVELTYPE */ getAVCLevelFor(
     86             int width, int height, int rate, int bitrate,
     87             OMX_VIDEO_AVCPROFILETYPE profile = OMX_VIDEO_AVCProfileBaseline);
     88 
     89 protected:
     90     virtual ~ACodec();
     91 
     92 private:
     93     struct BaseState;
     94     struct UninitializedState;
     95     struct LoadedState;
     96     struct LoadedToIdleState;
     97     struct IdleToExecutingState;
     98     struct ExecutingState;
     99     struct OutputPortSettingsChangedState;
    100     struct ExecutingToIdleState;
    101     struct IdleToLoadedState;
    102     struct FlushingState;
    103     struct DeathNotifier;
    104 
    105     enum {
    106         kWhatSetup                   = 'setu',
    107         kWhatOMXMessage              = 'omx ',
    108         kWhatInputBufferFilled       = 'inpF',
    109         kWhatOutputBufferDrained     = 'outD',
    110         kWhatShutdown                = 'shut',
    111         kWhatFlush                   = 'flus',
    112         kWhatResume                  = 'resm',
    113         kWhatDrainDeferredMessages   = 'drai',
    114         kWhatAllocateComponent       = 'allo',
    115         kWhatConfigureComponent      = 'conf',
    116         kWhatCreateInputSurface      = 'cisf',
    117         kWhatSignalEndOfInputStream  = 'eois',
    118         kWhatStart                   = 'star',
    119         kWhatRequestIDRFrame         = 'ridr',
    120         kWhatSetParameters           = 'setP',
    121         kWhatSubmitOutputMetaDataBufferIfEOS = 'subm',
    122         kWhatOMXDied                 = 'OMXd',
    123         kWhatReleaseCodecInstance    = 'relC',
    124     };
    125 
    126     enum {
    127         kPortIndexInput  = 0,
    128         kPortIndexOutput = 1
    129     };
    130 
    131     enum {
    132         kFlagIsSecure                                 = 1,
    133         kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
    134         kFlagIsGrallocUsageProtected                  = 4,
    135     };
    136 
    137     struct BufferInfo {
    138         enum Status {
    139             OWNED_BY_US,
    140             OWNED_BY_COMPONENT,
    141             OWNED_BY_UPSTREAM,
    142             OWNED_BY_DOWNSTREAM,
    143             OWNED_BY_NATIVE_WINDOW,
    144         };
    145 
    146         IOMX::buffer_id mBufferID;
    147         Status mStatus;
    148         unsigned mDequeuedAt;
    149 
    150         sp<ABuffer> mData;
    151         sp<GraphicBuffer> mGraphicBuffer;
    152     };
    153 
    154 #if TRACK_BUFFER_TIMING
    155     struct BufferStats {
    156         int64_t mEmptyBufferTimeUs;
    157         int64_t mFillBufferDoneTimeUs;
    158     };
    159 
    160     KeyedVector<int64_t, BufferStats> mBufferStats;
    161 #endif
    162 
    163     sp<AMessage> mNotify;
    164 
    165     sp<UninitializedState> mUninitializedState;
    166     sp<LoadedState> mLoadedState;
    167     sp<LoadedToIdleState> mLoadedToIdleState;
    168     sp<IdleToExecutingState> mIdleToExecutingState;
    169     sp<ExecutingState> mExecutingState;
    170     sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState;
    171     sp<ExecutingToIdleState> mExecutingToIdleState;
    172     sp<IdleToLoadedState> mIdleToLoadedState;
    173     sp<FlushingState> mFlushingState;
    174     sp<SkipCutBuffer> mSkipCutBuffer;
    175 
    176     AString mComponentName;
    177     uint32_t mFlags;
    178     uint32_t mQuirks;
    179     sp<IOMX> mOMX;
    180     IOMX::node_id mNode;
    181     sp<MemoryDealer> mDealer[2];
    182 
    183     sp<ANativeWindow> mNativeWindow;
    184     sp<AMessage> mInputFormat;
    185     sp<AMessage> mOutputFormat;
    186     sp<AMessage> mBaseOutputFormat;
    187 
    188     Vector<BufferInfo> mBuffers[2];
    189     bool mPortEOS[2];
    190     status_t mInputEOSResult;
    191 
    192     List<sp<AMessage> > mDeferredQueue;
    193 
    194     bool mSentFormat;
    195     bool mIsEncoder;
    196     bool mUseMetadataOnEncoderOutput;
    197     bool mShutdownInProgress;
    198     bool mExplicitShutdown;
    199 
    200     // If "mKeepComponentAllocated" we only transition back to Loaded state
    201     // and do not release the component instance.
    202     bool mKeepComponentAllocated;
    203 
    204     int32_t mEncoderDelay;
    205     int32_t mEncoderPadding;
    206     int32_t mRotationDegrees;
    207 
    208     bool mChannelMaskPresent;
    209     int32_t mChannelMask;
    210     unsigned mDequeueCounter;
    211     bool mStoreMetaDataInOutputBuffers;
    212     int32_t mMetaDataBuffersToSubmit;
    213     size_t mNumUndequeuedBuffers;
    214 
    215     int64_t mRepeatFrameDelayUs;
    216     int64_t mMaxPtsGapUs;
    217 
    218     int64_t mTimePerFrameUs;
    219     int64_t mTimePerCaptureUs;
    220 
    221     bool mCreateInputBuffersSuspended;
    222 
    223     bool mTunneled;
    224 
    225     status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
    226     status_t allocateBuffersOnPort(OMX_U32 portIndex);
    227     status_t freeBuffersOnPort(OMX_U32 portIndex);
    228     status_t freeBuffer(OMX_U32 portIndex, size_t i);
    229 
    230     status_t configureOutputBuffersFromNativeWindow(
    231             OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
    232             OMX_U32 *nMinUndequeuedBuffers);
    233     status_t allocateOutputMetaDataBuffers();
    234     status_t submitOutputMetaDataBuffer();
    235     void signalSubmitOutputMetaDataBufferIfEOS_workaround();
    236     status_t allocateOutputBuffersFromNativeWindow();
    237     status_t cancelBufferToNativeWindow(BufferInfo *info);
    238     status_t freeOutputBuffersNotOwnedByComponent();
    239     BufferInfo *dequeueBufferFromNativeWindow();
    240 
    241     BufferInfo *findBufferByID(
    242             uint32_t portIndex, IOMX::buffer_id bufferID,
    243             ssize_t *index = NULL);
    244 
    245     status_t setComponentRole(bool isEncoder, const char *mime);
    246     status_t configureCodec(const char *mime, const sp<AMessage> &msg);
    247 
    248     status_t configureTunneledVideoPlayback(int32_t audioHwSync,
    249             const sp<ANativeWindow> &nativeWindow);
    250 
    251     status_t setVideoPortFormatType(
    252             OMX_U32 portIndex,
    253             OMX_VIDEO_CODINGTYPE compressionFormat,
    254             OMX_COLOR_FORMATTYPE colorFormat,
    255             bool usingNativeBuffers = false);
    256 
    257     status_t setSupportedOutputFormat(bool getLegacyFlexibleFormat);
    258 
    259     status_t setupVideoDecoder(
    260             const char *mime, const sp<AMessage> &msg, bool usingNativeBuffers);
    261 
    262     status_t setupVideoEncoder(
    263             const char *mime, const sp<AMessage> &msg);
    264 
    265     status_t setVideoFormatOnPort(
    266             OMX_U32 portIndex,
    267             int32_t width, int32_t height,
    268             OMX_VIDEO_CODINGTYPE compressionFormat, float frameRate = -1.0);
    269 
    270     typedef struct drcParams {
    271         int32_t drcCut;
    272         int32_t drcBoost;
    273         int32_t heavyCompression;
    274         int32_t targetRefLevel;
    275         int32_t encodedTargetLevel;
    276     } drcParams_t;
    277 
    278     status_t setupAACCodec(
    279             bool encoder,
    280             int32_t numChannels, int32_t sampleRate, int32_t bitRate,
    281             int32_t aacProfile, bool isADTS, int32_t sbrMode,
    282             int32_t maxOutputChannelCount, const drcParams_t& drc,
    283             int32_t pcmLimiterEnable);
    284 
    285     status_t setupAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
    286 
    287     status_t setupEAC3Codec(bool encoder, int32_t numChannels, int32_t sampleRate);
    288 
    289     status_t selectAudioPortFormat(
    290             OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
    291 
    292     status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
    293     status_t setupG711Codec(bool encoder, int32_t numChannels);
    294 
    295     status_t setupFlacCodec(
    296             bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
    297 
    298     status_t setupRawAudioFormat(
    299             OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
    300 
    301     status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
    302 
    303     status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
    304     status_t setupH263EncoderParameters(const sp<AMessage> &msg);
    305     status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
    306     status_t setupHEVCEncoderParameters(const sp<AMessage> &msg);
    307     status_t setupVPXEncoderParameters(const sp<AMessage> &msg);
    308 
    309     status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
    310 
    311     status_t configureBitrate(
    312             int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode);
    313 
    314     status_t setupErrorCorrectionParameters();
    315 
    316     status_t initNativeWindow();
    317 
    318     status_t pushBlankBuffersToNativeWindow();
    319 
    320     // Returns true iff all buffers on the given port have status
    321     // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.
    322     bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
    323 
    324     bool allYourBuffersAreBelongToUs();
    325 
    326     void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
    327 
    328     size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
    329     size_t countBuffersOwnedByNativeWindow() const;
    330 
    331     void deferMessage(const sp<AMessage> &msg);
    332     void processDeferredMessages();
    333 
    334     void sendFormatChange(const sp<AMessage> &reply);
    335     status_t getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify);
    336 
    337     void signalError(
    338             OMX_ERRORTYPE error = OMX_ErrorUndefined,
    339             status_t internalError = UNKNOWN_ERROR);
    340 
    341     static bool describeDefaultColorFormat(DescribeColorFormatParams &describeParams);
    342     static bool describeColorFormat(
    343         const sp<IOMX> &omx, IOMX::node_id node,
    344         DescribeColorFormatParams &describeParams);
    345 
    346     status_t requestIDRFrame();
    347     status_t setParameters(const sp<AMessage> &params);
    348 
    349     // Send EOS on input stream.
    350     void onSignalEndOfInputStream();
    351 
    352     DISALLOW_EVIL_CONSTRUCTORS(ACodec);
    353 };
    354 
    355 }  // namespace android
    356 
    357 #endif  // A_CODEC_H_
    358