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/SkipCutBuffer.h>
     26 #include <OMX_Audio.h>
     27 
     28 #define TRACK_BUFFER_TIMING     0
     29 
     30 namespace android {
     31 
     32 struct ABuffer;
     33 struct MemoryDealer;
     34 
     35 struct ACodec : public AHierarchicalStateMachine {
     36     enum {
     37         kWhatFillThisBuffer      = 'fill',
     38         kWhatDrainThisBuffer     = 'drai',
     39         kWhatEOS                 = 'eos ',
     40         kWhatShutdownCompleted   = 'scom',
     41         kWhatFlushCompleted      = 'fcom',
     42         kWhatOutputFormatChanged = 'outC',
     43         kWhatError               = 'erro',
     44         kWhatComponentAllocated  = 'cAll',
     45         kWhatComponentConfigured = 'cCon',
     46         kWhatInputSurfaceCreated = 'isfc',
     47         kWhatSignaledInputEOS    = 'seos',
     48         kWhatBuffersAllocated    = 'allc',
     49         kWhatOMXDied             = 'OMXd',
     50     };
     51 
     52     ACodec();
     53 
     54     void setNotificationMessage(const sp<AMessage> &msg);
     55     void initiateSetup(const sp<AMessage> &msg);
     56     void signalFlush();
     57     void signalResume();
     58     void initiateShutdown(bool keepComponentAllocated = false);
     59 
     60     void signalSetParameters(const sp<AMessage> &msg);
     61     void signalEndOfInputStream();
     62 
     63     void initiateAllocateComponent(const sp<AMessage> &msg);
     64     void initiateConfigureComponent(const sp<AMessage> &msg);
     65     void initiateCreateInputSurface();
     66     void initiateStart();
     67 
     68     void signalRequestIDRFrame();
     69 
     70     struct PortDescription : public RefBase {
     71         size_t countBuffers();
     72         IOMX::buffer_id bufferIDAt(size_t index) const;
     73         sp<ABuffer> bufferAt(size_t index) const;
     74 
     75     private:
     76         friend struct ACodec;
     77 
     78         Vector<IOMX::buffer_id> mBufferIDs;
     79         Vector<sp<ABuffer> > mBuffers;
     80 
     81         PortDescription();
     82         void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer);
     83 
     84         DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
     85     };
     86 
     87 protected:
     88     virtual ~ACodec();
     89 
     90 private:
     91     struct BaseState;
     92     struct UninitializedState;
     93     struct LoadedState;
     94     struct LoadedToIdleState;
     95     struct IdleToExecutingState;
     96     struct ExecutingState;
     97     struct OutputPortSettingsChangedState;
     98     struct ExecutingToIdleState;
     99     struct IdleToLoadedState;
    100     struct FlushingState;
    101     struct DeathNotifier;
    102 
    103     enum {
    104         kWhatSetup                   = 'setu',
    105         kWhatOMXMessage              = 'omx ',
    106         kWhatInputBufferFilled       = 'inpF',
    107         kWhatOutputBufferDrained     = 'outD',
    108         kWhatShutdown                = 'shut',
    109         kWhatFlush                   = 'flus',
    110         kWhatResume                  = 'resm',
    111         kWhatDrainDeferredMessages   = 'drai',
    112         kWhatAllocateComponent       = 'allo',
    113         kWhatConfigureComponent      = 'conf',
    114         kWhatCreateInputSurface      = 'cisf',
    115         kWhatSignalEndOfInputStream  = 'eois',
    116         kWhatStart                   = 'star',
    117         kWhatRequestIDRFrame         = 'ridr',
    118         kWhatSetParameters           = 'setP',
    119         kWhatSubmitOutputMetaDataBufferIfEOS = 'subm',
    120     };
    121 
    122     enum {
    123         kPortIndexInput  = 0,
    124         kPortIndexOutput = 1
    125     };
    126 
    127     enum {
    128         kFlagIsSecure                                 = 1,
    129         kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
    130     };
    131 
    132     struct BufferInfo {
    133         enum Status {
    134             OWNED_BY_US,
    135             OWNED_BY_COMPONENT,
    136             OWNED_BY_UPSTREAM,
    137             OWNED_BY_DOWNSTREAM,
    138             OWNED_BY_NATIVE_WINDOW,
    139         };
    140 
    141         IOMX::buffer_id mBufferID;
    142         Status mStatus;
    143         unsigned mDequeuedAt;
    144 
    145         sp<ABuffer> mData;
    146         sp<GraphicBuffer> mGraphicBuffer;
    147     };
    148 
    149 #if TRACK_BUFFER_TIMING
    150     struct BufferStats {
    151         int64_t mEmptyBufferTimeUs;
    152         int64_t mFillBufferDoneTimeUs;
    153     };
    154 
    155     KeyedVector<int64_t, BufferStats> mBufferStats;
    156 #endif
    157 
    158     sp<AMessage> mNotify;
    159 
    160     sp<UninitializedState> mUninitializedState;
    161     sp<LoadedState> mLoadedState;
    162     sp<LoadedToIdleState> mLoadedToIdleState;
    163     sp<IdleToExecutingState> mIdleToExecutingState;
    164     sp<ExecutingState> mExecutingState;
    165     sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState;
    166     sp<ExecutingToIdleState> mExecutingToIdleState;
    167     sp<IdleToLoadedState> mIdleToLoadedState;
    168     sp<FlushingState> mFlushingState;
    169     sp<SkipCutBuffer> mSkipCutBuffer;
    170 
    171     AString mComponentName;
    172     uint32_t mFlags;
    173     uint32_t mQuirks;
    174     sp<IOMX> mOMX;
    175     IOMX::node_id mNode;
    176     sp<MemoryDealer> mDealer[2];
    177 
    178     sp<ANativeWindow> mNativeWindow;
    179 
    180     Vector<BufferInfo> mBuffers[2];
    181     bool mPortEOS[2];
    182     status_t mInputEOSResult;
    183 
    184     List<sp<AMessage> > mDeferredQueue;
    185 
    186     bool mSentFormat;
    187     bool mIsEncoder;
    188     bool mUseMetadataOnEncoderOutput;
    189     bool mShutdownInProgress;
    190 
    191     // If "mKeepComponentAllocated" we only transition back to Loaded state
    192     // and do not release the component instance.
    193     bool mKeepComponentAllocated;
    194 
    195     int32_t mEncoderDelay;
    196     int32_t mEncoderPadding;
    197 
    198     bool mChannelMaskPresent;
    199     int32_t mChannelMask;
    200     unsigned mDequeueCounter;
    201     bool mStoreMetaDataInOutputBuffers;
    202     int32_t mMetaDataBuffersToSubmit;
    203 
    204     int64_t mRepeatFrameDelayUs;
    205 
    206     status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
    207     status_t allocateBuffersOnPort(OMX_U32 portIndex);
    208     status_t freeBuffersOnPort(OMX_U32 portIndex);
    209     status_t freeBuffer(OMX_U32 portIndex, size_t i);
    210 
    211     status_t configureOutputBuffersFromNativeWindow(
    212             OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
    213             OMX_U32 *nMinUndequeuedBuffers);
    214     status_t allocateOutputMetaDataBuffers();
    215     status_t submitOutputMetaDataBuffer();
    216     void signalSubmitOutputMetaDataBufferIfEOS_workaround();
    217     status_t allocateOutputBuffersFromNativeWindow();
    218     status_t cancelBufferToNativeWindow(BufferInfo *info);
    219     status_t freeOutputBuffersNotOwnedByComponent();
    220     BufferInfo *dequeueBufferFromNativeWindow();
    221 
    222     BufferInfo *findBufferByID(
    223             uint32_t portIndex, IOMX::buffer_id bufferID,
    224             ssize_t *index = NULL);
    225 
    226     status_t setComponentRole(bool isEncoder, const char *mime);
    227     status_t configureCodec(const char *mime, const sp<AMessage> &msg);
    228 
    229     status_t setVideoPortFormatType(
    230             OMX_U32 portIndex,
    231             OMX_VIDEO_CODINGTYPE compressionFormat,
    232             OMX_COLOR_FORMATTYPE colorFormat);
    233 
    234     status_t setSupportedOutputFormat();
    235 
    236     status_t setupVideoDecoder(
    237             const char *mime, int32_t width, int32_t height);
    238 
    239     status_t setupVideoEncoder(
    240             const char *mime, const sp<AMessage> &msg);
    241 
    242     status_t setVideoFormatOnPort(
    243             OMX_U32 portIndex,
    244             int32_t width, int32_t height,
    245             OMX_VIDEO_CODINGTYPE compressionFormat);
    246 
    247     status_t setupAACCodec(
    248             bool encoder,
    249             int32_t numChannels, int32_t sampleRate, int32_t bitRate,
    250             int32_t aacProfile, bool isADTS);
    251 
    252     status_t selectAudioPortFormat(
    253             OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
    254 
    255     status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
    256     status_t setupG711Codec(bool encoder, int32_t numChannels);
    257 
    258     status_t setupFlacCodec(
    259             bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
    260 
    261     status_t setupRawAudioFormat(
    262             OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
    263 
    264     status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
    265 
    266     status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
    267     status_t setupH263EncoderParameters(const sp<AMessage> &msg);
    268     status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
    269     status_t setupVPXEncoderParameters(const sp<AMessage> &msg);
    270 
    271     status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
    272 
    273     status_t configureBitrate(
    274             int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode);
    275 
    276     status_t setupErrorCorrectionParameters();
    277 
    278     status_t initNativeWindow();
    279 
    280     status_t pushBlankBuffersToNativeWindow();
    281 
    282     // Returns true iff all buffers on the given port have status
    283     // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.
    284     bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
    285 
    286     bool allYourBuffersAreBelongToUs();
    287 
    288     void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
    289 
    290     size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
    291     size_t countBuffersOwnedByNativeWindow() const;
    292 
    293     void deferMessage(const sp<AMessage> &msg);
    294     void processDeferredMessages();
    295 
    296     void sendFormatChange(const sp<AMessage> &reply);
    297 
    298     void signalError(
    299             OMX_ERRORTYPE error = OMX_ErrorUndefined,
    300             status_t internalError = UNKNOWN_ERROR);
    301 
    302     status_t requestIDRFrame();
    303     status_t setParameters(const sp<AMessage> &params);
    304 
    305     // Send EOS on input stream.
    306     void onSignalEndOfInputStream();
    307 
    308     DISALLOW_EVIL_CONSTRUCTORS(ACodec);
    309 };
    310 
    311 }  // namespace android
    312 
    313 #endif  // A_CODEC_H_
    314