summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2015-02-06 00:06:50 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-02-06 00:06:50 +0000
commite576086224f6e630159eaeec59ab5146c8533dc7 (patch)
tree5a9605c000abb905142dfad5e6597915ab51f784
parent7dbbc7ec95c3040668388162a0ffbc45b68af6f1 (diff)
parentbcd22f0f3a4cd5f78e03af23aafadb2d1aec6794 (diff)
downloadframeworks_av-e576086224f6e630159eaeec59ab5146c8533dc7.zip
frameworks_av-e576086224f6e630159eaeec59ab5146c8533dc7.tar.gz
frameworks_av-e576086224f6e630159eaeec59ab5146c8533dc7.tar.bz2
am bcd22f0f: am 0662f5b0: Merge "stagefright: add fallback for native flex-YUV support" into lmp-mr1-dev
* commit 'bcd22f0f3a4cd5f78e03af23aafadb2d1aec6794': stagefright: add fallback for native flex-YUV support
-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 6a84c11..f783ef0 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1257,9 +1257,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);
@@ -1274,7 +1275,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();
@@ -1323,6 +1324,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);
@@ -1416,11 +1419,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)
@@ -4919,20 +4991,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 eb323a4..6ca123a 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));