summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/ACodec.cpp
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2015-01-30 19:30:05 -0800
committerLajos Molnar <lajos@google.com>2015-02-04 12:58:17 -0800
commit3a01a71dcbb467d06cc5da4a72a82bb588648cfc (patch)
treef35a84d74ff7cbcf6199d46c444acae9775880f8 /media/libstagefright/ACodec.cpp
parent57f75272fcd16b205ed60cdd0b33ffc19991fd10 (diff)
downloadframeworks_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.cpp90
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);