diff options
author | Lajos Molnar <lajos@google.com> | 2015-01-30 19:30:05 -0800 |
---|---|---|
committer | Lajos Molnar <lajos@google.com> | 2015-02-04 12:58:17 -0800 |
commit | 3a01a71dcbb467d06cc5da4a72a82bb588648cfc (patch) | |
tree | f35a84d74ff7cbcf6199d46c444acae9775880f8 /media/libstagefright/ACodec.cpp | |
parent | 57f75272fcd16b205ed60cdd0b33ffc19991fd10 (diff) | |
download | frameworks_av-3a01a71dcbb467d06cc5da4a72a82bb588648cfc.zip frameworks_av-3a01a71dcbb467d06cc5da4a72a82bb588648cfc.tar.gz frameworks_av-3a01a71dcbb467d06cc5da4a72a82bb588648cfc.tar.bz2 |
stagefright: add fallback for native flex-YUV support
Use software renderer if codec cannot support flex-YUV on a surface
Bug: 17906609
Change-Id: I3d0e3ff5fee7d7b3e2416892968fa18f6139598a
Diffstat (limited to 'media/libstagefright/ACodec.cpp')
-rw-r--r-- | media/libstagefright/ACodec.cpp | 90 |
1 files changed, 74 insertions, 16 deletions
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index 11043f8..72518a9 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -1258,9 +1258,10 @@ status_t ACodec::configureCodec( } } + // NOTE: we only use native window for video decoders sp<RefBase> obj; bool haveNativeWindow = msg->findObject("native-window", &obj) - && obj != NULL; + && obj != NULL && video && !encoder; mStoreMetaDataInOutputBuffers = false; if (video && !encoder) { inputFormat->setInt32("adaptive-playback", false); @@ -1275,7 +1276,7 @@ status_t ACodec::configureCodec( mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown; } } - if (!encoder && video && haveNativeWindow) { + if (haveNativeWindow) { sp<NativeWindowWrapper> windowWrapper( static_cast<NativeWindowWrapper *>(obj.get())); sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow(); @@ -1324,6 +1325,8 @@ status_t ACodec::configureCodec( if (err != OK) { ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d", mComponentName.c_str(), err); + // allow failure + err = OK; } else { inputFormat->setInt32("max-width", maxWidth); inputFormat->setInt32("max-height", maxHeight); @@ -1417,11 +1420,80 @@ status_t ACodec::configureCodec( } if (video) { + // determine need for software renderer + bool usingSwRenderer = false; + if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) { + usingSwRenderer = true; + haveNativeWindow = false; + } + if (encoder) { err = setupVideoEncoder(mime, msg); } else { err = setupVideoDecoder(mime, msg, haveNativeWindow); } + + if (err != OK) { + return err; + } + + if (haveNativeWindow) { + sp<NativeWindowWrapper> nativeWindow( + static_cast<NativeWindowWrapper *>(obj.get())); + CHECK(nativeWindow != NULL); + mNativeWindow = nativeWindow->getNativeWindow(); + + native_window_set_scaling_mode( + mNativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); + } + + // initialize native window now to get actual output format + // TODO: this is needed for some encoders even though they don't use native window + CHECK_EQ((status_t)OK, initNativeWindow()); + + // fallback for devices that do not handle flex-YUV for native buffers + if (haveNativeWindow) { + int32_t requestedColorFormat = OMX_COLOR_FormatUnused; + if (msg->findInt32("color-format", &requestedColorFormat) && + requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) { + CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK); + int32_t colorFormat = OMX_COLOR_FormatUnused; + OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused; + CHECK(outputFormat->findInt32("color-format", &colorFormat)); + ALOGD("[%s] Requested output format %#x and got %#x.", + mComponentName.c_str(), requestedColorFormat, colorFormat); + if (!isFlexibleColorFormat( + mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent) + || flexibleEquivalent != (OMX_U32)requestedColorFormat) { + // device did not handle flex-YUV request for native window, fall back + // to SW renderer + ALOGI("[%s] Falling back to software renderer", mComponentName.c_str()); + mNativeWindow.clear(); + haveNativeWindow = false; + usingSwRenderer = true; + if (mStoreMetaDataInOutputBuffers) { + err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_FALSE); + mStoreMetaDataInOutputBuffers = false; + // TODO: implement adaptive-playback support for bytebuffer mode. + // This is done by SW codecs, but most HW codecs don't support it. + inputFormat->setInt32("adaptive-playback", false); + } + if (err == OK) { + err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE); + } + if (mFlags & kFlagIsGrallocUsageProtected) { + // fallback is not supported for protected playback + err = PERMISSION_DENIED; + } else if (err == OK) { + err = setupVideoDecoder(mime, msg, false); + } + } + } + } + + if (usingSwRenderer) { + outputFormat->setInt32("using-sw-renderer", 1); + } } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) { int32_t numChannels, sampleRate; if (!msg->findInt32("channel-count", &numChannels) @@ -4922,20 +4994,6 @@ bool ACodec::LoadedState::onConfigureComponent( return false; } - sp<RefBase> obj; - if (msg->findObject("native-window", &obj) - && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) { - sp<NativeWindowWrapper> nativeWindow( - static_cast<NativeWindowWrapper *>(obj.get())); - CHECK(nativeWindow != NULL); - mCodec->mNativeWindow = nativeWindow->getNativeWindow(); - - native_window_set_scaling_mode( - mCodec->mNativeWindow.get(), - NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); - } - CHECK_EQ((status_t)OK, mCodec->initNativeWindow()); - { sp<AMessage> notify = mCodec->mNotify->dup(); notify->setInt32("what", CodecBase::kWhatComponentConfigured); |