diff options
| author | ApurupaPattapu <apurupa@codeaurora.org> | 2012-06-28 15:00:26 -0700 | 
|---|---|---|
| committer | Steve Kondik <shade@chemlab.org> | 2013-02-19 11:10:37 -0800 | 
| commit | 63614c132b320a6146b6be85b8f3131135db4ba2 (patch) | |
| tree | 6f73a22e9d25aee77ce18876c7dd926984f00c92 | |
| parent | 739845fdb768402d6ad94f153b674aa7c044d703 (diff) | |
| download | frameworks_av-63614c132b320a6146b6be85b8f3131135db4ba2.zip frameworks_av-63614c132b320a6146b6be85b8f3131135db4ba2.tar.gz frameworks_av-63614c132b320a6146b6be85b8f3131135db4ba2.tar.bz2  | |
ACodec: Support for dynamic port reconfig
- On port settings changed first flush output port
- Move ACodec to new state called FlushingOutputState
- Flush all output buffers, wait till all decoded buffers
  are rendered
- Then disable output port, and allocate output buffers
  with new resolution, and reset native window
Change-Id: Iafa266371ed2a87b909fbcb4eeae6b64208df617
| -rw-r--r-- | include/media/stagefright/ACodec.h | 6 | ||||
| -rw-r--r-- | media/libstagefright/ACodec.cpp | 167 | 
2 files changed, 171 insertions, 2 deletions
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index b42a4ac..08601aa 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -91,6 +91,9 @@ private:      struct ExecutingToIdleState;      struct IdleToLoadedState;      struct FlushingState; +#ifdef QCOM_HARDWARE +    struct FlushingOutputState; +#endif      enum {          kWhatSetup                   = 'setu', @@ -152,6 +155,9 @@ private:      sp<ExecutingToIdleState> mExecutingToIdleState;      sp<IdleToLoadedState> mIdleToLoadedState;      sp<FlushingState> mFlushingState; +#ifdef QCOM_HARDWARE +    sp<FlushingOutputState> mFlushingOutputState; +#endif      sp<SkipCutBuffer> mSkipCutBuffer;      AString mComponentName; diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 19bf28a..ddf95dc 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -337,8 +337,33 @@ private:      DISALLOW_EVIL_CONSTRUCTORS(FlushingState);  }; +#ifdef QCOM_HARDWARE  //////////////////////////////////////////////////////////////////////////////// +struct ACodec::FlushingOutputState : public ACodec::BaseState { +    FlushingOutputState(ACodec *codec); + +protected: +    virtual PortMode getPortMode(OMX_U32 portIndex); +    virtual bool onMessageReceived(const sp<AMessage> &msg); +    virtual void stateEntered(); + +    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2); + +    virtual void onOutputBufferDrained(const sp<AMessage> &msg); +    virtual void onInputBufferFilled(const sp<AMessage> &msg); + +private: +    bool mFlushComplete; + +    void changeStateIfWeOwnAllBuffers(); + +    DISALLOW_EVIL_CONSTRUCTORS(FlushingOutputState); +}; + +//////////////////////////////////////////////////////////////////////////////// +#endif +  ACodec::ACodec()      : mQuirks(0),        mNode(NULL), @@ -361,6 +386,9 @@ ACodec::ACodec()      mExecutingToIdleState = new ExecutingToIdleState(this);      mIdleToLoadedState = new IdleToLoadedState(this);      mFlushingState = new FlushingState(this); +#ifdef QCOM_HARDWARE +    mFlushingOutputState = new FlushingOutputState(this); +#endif      mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;      mInputEOSResult = OK; @@ -3599,14 +3627,22 @@ bool ACodec::ExecutingState::onOMXEvent(              CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);              if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { +#ifdef QCOM_HARDWARE +                ALOGV("Flush output port before disable"); +                CHECK_EQ(mCodec->mOMX->sendCommand( +                        mCodec->mNode, OMX_CommandFlush, kPortIndexOutput), +                     (status_t)OK); + +                mCodec->changeState(mCodec->mFlushingOutputState); +#else                  CHECK_EQ(mCodec->mOMX->sendCommand(                              mCodec->mNode,                              OMX_CommandPortDisable, kPortIndexOutput), -                         (status_t)OK); +                        (status_t)OK);                  mCodec->freeOutputBuffersNotOwnedByComponent(); -                  mCodec->changeState(mCodec->mOutputPortSettingsChangedState); +#endif              } else if (data2 == OMX_IndexConfigCommonOutputCrop) {                  mCodec->mSentFormat = false;              } else { @@ -4018,4 +4054,131 @@ void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {      }  } +#ifdef QCOM_HARDWARE +//////////////////////////////////////////////////////////////////////////////// + +ACodec::FlushingOutputState::FlushingOutputState(ACodec *codec) +    : BaseState(codec) { +} + +ACodec::BaseState::PortMode ACodec::FlushingOutputState::getPortMode(OMX_U32 portIndex) { +    if (portIndex == kPortIndexOutput) +    { +        return KEEP_BUFFERS; +    } +    return RESUBMIT_BUFFERS; +} + +void ACodec::FlushingOutputState::stateEntered() { +    ALOGV("[%s] Now Flushing Output Port", mCodec->mComponentName.c_str()); + +    mFlushComplete = false; +} + +bool ACodec::FlushingOutputState::onMessageReceived(const sp<AMessage> &msg) { +    bool handled = false; + +    switch (msg->what()) { +        case kWhatShutdown: +        { +            mCodec->deferMessage(msg); +            handled = true; +            break; +        } + +        case kWhatFlush: +        { +            ALOGV("Flush received during port reconfig, deferring it"); +            mCodec->deferMessage(msg); +            handled = true; +            break; +        } + +        case kWhatInputBufferFilled: +        { +            mCodec->deferMessage(msg); +            changeStateIfWeOwnAllBuffers(); +            handled = true; +            break; +        } + +        default: +            handled = BaseState::onMessageReceived(msg); +            break; +    } + +    return handled; +} + +bool ACodec::FlushingOutputState::onOMXEvent( +        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { +    switch (event) { +        case OMX_EventCmdComplete: +        { +            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush); +            CHECK_EQ(data2,(OMX_U32)kPortIndexOutput); +            ALOGV("FlushingOutputState::onOMXEvent Output port flush complete"); +            mFlushComplete = true; +            changeStateIfWeOwnAllBuffers(); +            return true; +        } + +        case OMX_EventPortSettingsChanged: +        { +            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id()); +            msg->setInt32("type", omx_message::EVENT); +            msg->setPointer("node", mCodec->mNode); +            msg->setInt32("event", event); +            msg->setInt32("data1", data1); +            msg->setInt32("data2", data2); + +            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged", +                 mCodec->mComponentName.c_str()); + +            mCodec->deferMessage(msg); + +            return true; +        } + +        default: +            return BaseState::onOMXEvent(event, data1, data2); +    } + +    return true; +} + +void ACodec::FlushingOutputState::onOutputBufferDrained(const sp<AMessage> &msg) { +    BaseState::onOutputBufferDrained(msg); + +    changeStateIfWeOwnAllBuffers(); +} + +void ACodec::FlushingOutputState::onInputBufferFilled(const sp<AMessage> &msg) { +    BaseState::onInputBufferFilled(msg); + +    changeStateIfWeOwnAllBuffers(); +} + +void ACodec::FlushingOutputState::changeStateIfWeOwnAllBuffers() { +   ALOGV("FlushingOutputState::ChangeState %d",mFlushComplete); + +   if (mFlushComplete && mCodec->allYourBuffersAreBelongToUs( kPortIndexOutput )) { +        ALOGV("FlushingOutputState Sending port disable "); +        CHECK_EQ(mCodec->mOMX->sendCommand( +                            mCodec->mNode, +                            OMX_CommandPortDisable, kPortIndexOutput), +                         (status_t)OK); + +        mCodec->mPortEOS[kPortIndexInput] = false; +        mCodec->mPortEOS[kPortIndexOutput] = false; + +        ALOGV("FlushingOutputState Calling freeOutputBuffersNotOwnedByComponent"); +        mCodec->freeOutputBuffersNotOwnedByComponent(); + +        ALOGV("FlushingOutputState Change state to port settings changed"); +        mCodec->changeState(mCodec->mOutputPortSettingsChangedState); +    } +} +#endif +  }  // namespace android  | 
