diff options
| author | Lajos Molnar <lajos@google.com> | 2015-07-10 18:59:06 -0700 | 
|---|---|---|
| committer | Lajos Molnar <lajos@google.com> | 2015-07-13 16:33:41 -0700 | 
| commit | e3635355e4cae5af7550b49888c6a0e3530b8aea (patch) | |
| tree | e0abd9257076174e3a61a9f751dcbb0a472137bc | |
| parent | 4b33e0838fdb1b5e545449add02005916b512c99 (diff) | |
| download | frameworks_av-e3635355e4cae5af7550b49888c6a0e3530b8aea.zip frameworks_av-e3635355e4cae5af7550b49888c6a0e3530b8aea.tar.gz frameworks_av-e3635355e4cae5af7550b49888c6a0e3530b8aea.tar.bz2  | |
MediaCodec: consider usage bits when changing surface.
The new surface cannot add usage bits not already present (as
already existing buffers may become unusable for the surface).
Bug: 22414343
Change-Id: Id8169c79cd0994be134a16782dd04687e46ca1dd
| -rw-r--r-- | include/media/stagefright/ACodec.h | 4 | ||||
| -rw-r--r-- | media/libstagefright/ACodec.cpp | 24 | 
2 files changed, 23 insertions, 5 deletions
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index a4b24d7..2ca3f1c 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -215,6 +215,7 @@ private:      sp<MemoryDealer> mDealer[2];      sp<ANativeWindow> mNativeWindow; +    int mNativeWindowUsageBits;      sp<AMessage> mInputFormat;      sp<AMessage> mOutputFormat;      sp<AMessage> mBaseOutputFormat; @@ -266,7 +267,8 @@ private:      status_t freeBuffer(OMX_U32 portIndex, size_t i);      status_t handleSetSurface(const sp<Surface> &surface); -    status_t setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */); +    status_t setupNativeWindowSizeFormatAndUsage( +            ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */);      status_t configureOutputBuffersFromNativeWindow(              OMX_U32 *nBufferCount, OMX_U32 *nBufferSize, diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 9206b5c..ffd90b3 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -493,6 +493,7 @@ void ACodec::BufferInfo::checkReadFence(const char *dbg) {  ACodec::ACodec()      : mQuirks(0),        mNode(0), +      mNativeWindowUsageBits(0),        mSentFormat(false),        mIsVideo(false),        mIsEncoder(false), @@ -642,7 +643,7 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {          return OK;      } -    // allow keeping unset surface +    // cannot switch from bytebuffers to surface      if (mNativeWindow == NULL) {          ALOGW("component was not configured with a surface");          return INVALID_OPERATION; @@ -661,11 +662,20 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {          return INVALID_OPERATION;      } -    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow); +    int usageBits = 0; +    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);      if (err != OK) {          return err;      } +    int ignoredFlags = (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER +            | GRALLOC_USAGE_EXTERNAL_DISP); +    // New output surface is not allowed to add new usage flag except ignored ones. +    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) { +        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits); +        return BAD_VALUE; +    } +      // get min undequeued count. We cannot switch to a surface that has a higher      // undequeued count than we allocated.      int minUndequeuedBuffers = 0; @@ -747,6 +757,7 @@ status_t ACodec::handleSetSurface(const sp<Surface> &surface) {      }      mNativeWindow = nativeWindow; +    mNativeWindowUsageBits = usageBits;      return OK;  } @@ -868,7 +879,8 @@ status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {      return OK;  } -status_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) { +status_t ACodec::setupNativeWindowSizeFormatAndUsage( +        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {      OMX_PARAM_PORTDEFINITIONTYPE def;      InitOMXParams(&def);      def.nPortIndex = kPortIndexOutput; @@ -894,6 +906,7 @@ status_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow      }      usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP; +    *finalUsage = usage;      ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);      return setNativeWindowSizeFormatAndUsage( @@ -916,9 +929,10 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(              mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));      if (err == OK) { -        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get()); +        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);      }      if (err != OK) { +        mNativeWindowUsageBits = 0;          return err;      } @@ -1937,6 +1951,7 @@ status_t ACodec::configureCodec(                      // to SW renderer                      ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());                      mNativeWindow.clear(); +                    mNativeWindowUsageBits = 0;                      haveNativeWindow = false;                      usingSwRenderer = true;                      if (storingMetadataInDecodedBuffers()) { @@ -5341,6 +5356,7 @@ void ACodec::UninitializedState::stateEntered() {      }      mCodec->mNativeWindow.clear(); +    mCodec->mNativeWindowUsageBits = 0;      mCodec->mNode = 0;      mCodec->mOMX.clear();      mCodec->mQuirks = 0;  | 
