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     bool isConfiguredForAdaptivePlayback() { return mIsConfiguredForAdaptivePlayback; }
     71 
     72     struct PortDescription : public RefBase {
     73         size_t countBuffers();
     74         IOMX::buffer_id bufferIDAt(size_t index) const;
     75         sp<ABuffer> bufferAt(size_t index) const;
     76 
     77     private:
     78         friend struct ACodec;
     79 
     80         Vector<IOMX::buffer_id> mBufferIDs;
     81         Vector<sp<ABuffer> > mBuffers;
     82 
     83         PortDescription();
     84         void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer);
     85 
     86         DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
     87     };
     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     };
    123 
    124     enum {
    125         kPortIndexInput  = 0,
    126         kPortIndexOutput = 1
    127     };
    128 
    129     enum {
    130         kFlagIsSecure                                 = 1,
    131         kFlagPushBlankBuffersToNativeWindowOnShutdown = 2,
    132     };
    133 
    134     struct BufferInfo {
    135         enum Status {
    136             OWNED_BY_US,
    137             OWNED_BY_COMPONENT,
    138             OWNED_BY_UPSTREAM,
    139             OWNED_BY_DOWNSTREAM,
    140             OWNED_BY_NATIVE_WINDOW,
    141         };
    142 
    143         IOMX::buffer_id mBufferID;
    144         Status mStatus;
    145         unsigned mDequeuedAt;
    146 
    147         sp<ABuffer> mData;
    148         sp<GraphicBuffer> mGraphicBuffer;
    149     };
    150 
    151 #if TRACK_BUFFER_TIMING
    152     struct BufferStats {
    153         int64_t mEmptyBufferTimeUs;
    154         int64_t mFillBufferDoneTimeUs;
    155     };
    156 
    157     KeyedVector<int64_t, BufferStats> mBufferStats;
    158 #endif
    159 
    160     sp<AMessage> mNotify;
    161 
    162     sp<UninitializedState> mUninitializedState;
    163     sp<LoadedState> mLoadedState;
    164     sp<LoadedToIdleState> mLoadedToIdleState;
    165     sp<IdleToExecutingState> mIdleToExecutingState;
    166     sp<ExecutingState> mExecutingState;
    167     sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState;
    168     sp<ExecutingToIdleState> mExecutingToIdleState;
    169     sp<IdleToLoadedState> mIdleToLoadedState;
    170     sp<FlushingState> mFlushingState;
    171     sp<SkipCutBuffer> mSkipCutBuffer;
    172 
    173     AString mComponentName;
    174     uint32_t mFlags;
    175     uint32_t mQuirks;
    176     sp<IOMX> mOMX;
    177     IOMX::node_id mNode;
    178     sp<MemoryDealer> mDealer[2];
    179 
    180     sp<ANativeWindow> mNativeWindow;
    181 
    182     Vector<BufferInfo> mBuffers[2];
    183     bool mPortEOS[2];
    184     status_t mInputEOSResult;
    185 
    186     List<sp<AMessage> > mDeferredQueue;
    187 
    188     bool mSentFormat;
    189     bool mIsEncoder;
    190     bool mUseMetadataOnEncoderOutput;
    191     bool mShutdownInProgress;
    192     bool mIsConfiguredForAdaptivePlayback;
    193 
    194     // If "mKeepComponentAllocated" we only transition back to Loaded state
    195     // and do not release the component instance.
    196     bool mKeepComponentAllocated;
    197 
    198     int32_t mEncoderDelay;
    199     int32_t mEncoderPadding;
    200 
    201     bool mChannelMaskPresent;
    202     int32_t mChannelMask;
    203     unsigned mDequeueCounter;
    204     bool mStoreMetaDataInOutputBuffers;
    205     int32_t mMetaDataBuffersToSubmit;
    206 
    207     int64_t mRepeatFrameDelayUs;
    208     int64_t mMaxPtsGapUs;
    209 
    210     status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
    211     status_t allocateBuffersOnPort(OMX_U32 portIndex);
    212     status_t freeBuffersOnPort(OMX_U32 portIndex);
    213     status_t freeBuffer(OMX_U32 portIndex, size_t i);
    214 
    215     status_t configureOutputBuffersFromNativeWindow(
    216             OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
    217             OMX_U32 *nMinUndequeuedBuffers);
    218     status_t allocateOutputMetaDataBuffers();
    219     status_t submitOutputMetaDataBuffer();
    220     void signalSubmitOutputMetaDataBufferIfEOS_workaround();
    221     status_t allocateOutputBuffersFromNativeWindow();
    222     status_t cancelBufferToNativeWindow(BufferInfo *info);
    223     status_t freeOutputBuffersNotOwnedByComponent();
    224     BufferInfo *dequeueBufferFromNativeWindow();
    225 
    226     BufferInfo *findBufferByID(
    227             uint32_t portIndex, IOMX::buffer_id bufferID,
    228             ssize_t *index = NULL);
    229 
    230     status_t setComponentRole(bool isEncoder, const char *mime);
    231     status_t configureCodec(const char *mime, const sp<AMessage> &msg);
    232 
    233     status_t setVideoPortFormatType(
    234             OMX_U32 portIndex,
    235             OMX_VIDEO_CODINGTYPE compressionFormat,
    236             OMX_COLOR_FORMATTYPE colorFormat);
    237 
    238     status_t setSupportedOutputFormat();
    239 
    240     status_t setupVideoDecoder(
    241             const char *mime, int32_t width, int32_t height);
    242 
    243     status_t setupVideoEncoder(
    244             const char *mime, const sp<AMessage> &msg);
    245 
    246     status_t setVideoFormatOnPort(
    247             OMX_U32 portIndex,
    248             int32_t width, int32_t height,
    249             OMX_VIDEO_CODINGTYPE compressionFormat);
    250 
    251     status_t setupAACCodec(
    252             bool encoder,
    253             int32_t numChannels, int32_t sampleRate, int32_t bitRate,
    254             int32_t aacProfile, bool isADTS);
    255 
    256     status_t selectAudioPortFormat(
    257             OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
    258 
    259     status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
    260     status_t setupG711Codec(bool encoder, int32_t numChannels);
    261 
    262     status_t setupFlacCodec(
    263             bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
    264 
    265     status_t setupRawAudioFormat(
    266             OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
    267 
    268     status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
    269 
    270     status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
    271     status_t setupH263EncoderParameters(const sp<AMessage> &msg);
    272     status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
    273     status_t setupVPXEncoderParameters(const sp<AMessage> &msg);
    274 
    275     status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
    276 
    277     status_t configureBitrate(
    278             int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode);
    279 
    280     status_t setupErrorCorrectionParameters();
    281 
    282     status_t initNativeWindow();
    283 
    284     status_t pushBlankBuffersToNativeWindow();
    285 
    286     // Returns true iff all buffers on the given port have status
    287     // OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.
    288     bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
    289 
    290     bool allYourBuffersAreBelongToUs();
    291 
    292     void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
    293 
    294     size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
    295     size_t countBuffersOwnedByNativeWindow() const;
    296 
    297     void deferMessage(const sp<AMessage> &msg);
    298     void processDeferredMessages();
    299 
    300     void sendFormatChange(const sp<AMessage> &reply);
    301 
    302     void signalError(
    303             OMX_ERRORTYPE error = OMX_ErrorUndefined,
    304             status_t internalError = UNKNOWN_ERROR);
    305 
    306     status_t requestIDRFrame();
    307     status_t setParameters(const sp<AMessage> &params);
    308 
    309     // Send EOS on input stream.
    310     void onSignalEndOfInputStream();
    311 
    312     DISALLOW_EVIL_CONSTRUCTORS(ACodec);
    313 };
    314 
    315 }  // namespace android
    316 
    317 #endif  // A_CODEC_H_
    318