summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--include/media/stagefright/MediaCodec.h2
-rw-r--r--media/libstagefright/ACodec.cpp90
-rw-r--r--media/libstagefright/MediaCodec.cpp11
3 files changed, 83 insertions, 20 deletions
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 54a4e8b..d448097 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -194,7 +194,7 @@ private:
};
enum {
- kFlagIsSoftwareCodec = 1,
+ kFlagUsesSoftwareRenderer = 1,
kFlagOutputFormatChanged = 2,
kFlagOutputBuffersChanged = 4,
kFlagStickyError = 8,
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);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index c2381b4..a9c3a04 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -869,9 +869,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
CHECK(msg->findString("componentName", &mComponentName));
if (mComponentName.startsWith("OMX.google.")) {
- mFlags |= kFlagIsSoftwareCodec;
+ mFlags |= kFlagUsesSoftwareRenderer;
} else {
- mFlags &= ~kFlagIsSoftwareCodec;
+ mFlags &= ~kFlagUsesSoftwareRenderer;
}
if (mComponentName.endsWith(".secure")) {
@@ -894,6 +894,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
CHECK(msg->findMessage("input-format", &mInputFormat));
CHECK(msg->findMessage("output-format", &mOutputFormat));
+ int32_t usingSwRenderer;
+ if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
+ && usingSwRenderer) {
+ mFlags |= kFlagUsesSoftwareRenderer;
+ }
setState(CONFIGURED);
(new AMessage)->postReply(mReplyID);
break;
@@ -989,7 +994,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
if (mSoftRenderer == NULL &&
mNativeWindow != NULL &&
- (mFlags & kFlagIsSoftwareCodec)) {
+ (mFlags & kFlagUsesSoftwareRenderer)) {
AString mime;
CHECK(msg->findString("mime", &mime));