summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-01-10 11:26:38 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-01-10 11:26:38 -0800
commit32ad210e4e4bcbdf912a01c9d2ff105cb3c5056f (patch)
tree57bc9bcd78d3844035a923a70b516e4dc2872a24 /media
parent14c858e80dfe2030c9f343dc0c6e2048e030731b (diff)
parent31e2508c75018145a8238925ff1a08cbde4e799a (diff)
downloadframeworks_av-32ad210e4e4bcbdf912a01c9d2ff105cb3c5056f.zip
frameworks_av-32ad210e4e4bcbdf912a01c9d2ff105cb3c5056f.tar.gz
frameworks_av-32ad210e4e4bcbdf912a01c9d2ff105cb3c5056f.tar.bz2
Merge "NuPlayer now properly sends MEDIA_SET_VIDEOSIZE notifications." into honeycomb
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp12
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp45
-rw-r--r--media/libstagefright/ACodec.cpp112
-rw-r--r--media/libstagefright/foundation/AMessage.cpp28
4 files changed, 183 insertions, 14 deletions
diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp
index 4d4cd8d..802d1fb 100644
--- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp
+++ b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp
@@ -309,6 +309,18 @@ void DecoderWrapper::WrapperReader::sendFormatChange() {
realNotify->setInt32("width", width);
realNotify->setInt32("height", height);
+
+ int32_t cropLeft, cropTop, cropRight, cropBottom;
+ if (!meta->findRect(
+ kKeyCropRect,
+ &cropLeft, &cropTop, &cropRight, &cropBottom)) {
+ cropLeft = 0;
+ cropTop = 0;
+ cropRight = width - 1;
+ cropBottom = height - 1;
+ }
+
+ realNotify->setRect("crop", cropLeft, cropTop, cropRight, cropBottom);
}
notify->post();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index e1b371e..7f534c0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -271,22 +271,43 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
finishFlushIfPossible();
} else if (what == ACodec::kWhatOutputFormatChanged) {
- CHECK(audio);
-
- int32_t numChannels;
- CHECK(codecRequest->findInt32("channel-count", &numChannels));
+ if (audio) {
+ int32_t numChannels;
+ CHECK(codecRequest->findInt32("channel-count", &numChannels));
- int32_t sampleRate;
- CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
+ int32_t sampleRate;
+ CHECK(codecRequest->findInt32("sample-rate", &sampleRate));
- LOGV("Audio output format changed to %d Hz, %d channels",
- sampleRate, numChannels);
+ LOGV("Audio output format changed to %d Hz, %d channels",
+ sampleRate, numChannels);
- mAudioSink->close();
- CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
- mAudioSink->start();
+ mAudioSink->close();
+ CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
+ mAudioSink->start();
- mRenderer->signalAudioSinkChanged();
+ mRenderer->signalAudioSinkChanged();
+ } else {
+ // video
+
+ int32_t width, height;
+ CHECK(codecRequest->findInt32("width", &width));
+ CHECK(codecRequest->findInt32("height", &height));
+
+ int32_t cropLeft, cropTop, cropRight, cropBottom;
+ CHECK(codecRequest->findRect(
+ "crop",
+ &cropLeft, &cropTop, &cropRight, &cropBottom));
+
+ LOGV("Video output format changed to %d x %d "
+ "(crop: %d, %d, %d, %d)",
+ width, height,
+ cropLeft, cropTop, cropRight, cropBottom);
+
+ notifyListener(
+ MEDIA_SET_VIDEO_SIZE,
+ cropRight - cropLeft + 1,
+ cropBottom - cropTop + 1);
+ }
} else if (what == ACodec::kWhatShutdownCompleted) {
LOGV("%s shutdown completed", audio ? "audio" : "video");
if (audio) {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 39e0c51..dfb4e00 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -299,7 +299,8 @@ private:
////////////////////////////////////////////////////////////////////////////////
ACodec::ACodec()
- : mNode(NULL) {
+ : mNode(NULL),
+ mSentFormat(false) {
mUninitializedState = new UninitializedState(this);
mLoadedToIdleState = new LoadedToIdleState(this);
mIdleToExecutingState = new IdleToExecutingState(this);
@@ -980,6 +981,103 @@ void ACodec::processDeferredMessages() {
}
}
+void ACodec::sendFormatChange() {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatOutputFormatChanged);
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = kPortIndexOutput;
+
+ CHECK_EQ(mOMX->getParameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
+ (status_t)OK);
+
+ CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
+
+ switch (def.eDomain) {
+ case OMX_PortDomainVideo:
+ {
+ OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
+
+ notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
+ notify->setInt32("width", videoDef->nFrameWidth);
+ notify->setInt32("height", videoDef->nFrameHeight);
+
+ OMX_CONFIG_RECTTYPE rect;
+ InitOMXParams(&rect);
+ rect.nPortIndex = kPortIndexOutput;
+
+ if (mOMX->getConfig(
+ mNode, OMX_IndexConfigCommonOutputCrop,
+ &rect, sizeof(rect)) != OK) {
+ rect.nLeft = 0;
+ rect.nTop = 0;
+ rect.nWidth = videoDef->nFrameWidth;
+ rect.nHeight = videoDef->nFrameHeight;
+ }
+
+ CHECK_GE(rect.nLeft, 0);
+ CHECK_GE(rect.nTop, 0);
+ CHECK_GE(rect.nWidth, 0u);
+ CHECK_GE(rect.nHeight, 0u);
+ CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
+ CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
+
+ notify->setRect(
+ "crop",
+ rect.nLeft,
+ rect.nTop,
+ rect.nLeft + rect.nWidth - 1,
+ rect.nTop + rect.nHeight - 1);
+
+ if (mNativeWindow != NULL) {
+ android_native_rect_t crop;
+ crop.left = rect.nLeft;
+ crop.top = rect.nTop;
+ crop.right = rect.nLeft + rect.nWidth - 1;
+ crop.bottom = rect.nTop + rect.nHeight - 1;
+
+ CHECK_EQ(0, native_window_set_crop(
+ mNativeWindow.get(), &crop));
+ }
+ break;
+ }
+
+ case OMX_PortDomainAudio:
+ {
+ OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
+ CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
+
+ OMX_AUDIO_PARAM_PCMMODETYPE params;
+ InitOMXParams(&params);
+ params.nPortIndex = kPortIndexOutput;
+
+ CHECK_EQ(mOMX->getParameter(
+ mNode, OMX_IndexParamAudioPcm,
+ &params, sizeof(params)),
+ (status_t)OK);
+
+ CHECK(params.nChannels == 1 || params.bInterleaved);
+ CHECK_EQ(params.nBitPerSample, 16u);
+ CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
+ CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
+
+ notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
+ notify->setInt32("channel-count", params.nChannels);
+ notify->setInt32("sample-rate", params.nSamplingRate);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+
+ notify->post();
+
+ mSentFormat = true;
+}
+
////////////////////////////////////////////////////////////////////////////////
ACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
@@ -1305,6 +1403,10 @@ bool ACodec::BaseState::onOMXFillBufferDone(
info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
}
} else {
+ if (!mCodec->mSentFormat) {
+ mCodec->sendFormatChange();
+ }
+
if (mCodec->mNativeWindow == NULL) {
info->mData->setRange(rangeOffset, rangeLength);
}
@@ -1717,7 +1819,7 @@ bool ACodec::ExecutingState::onOMXEvent(
{
CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
- if (data2 == OMX_IndexParamPortDefinition) {
+ if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
CHECK_EQ(mCodec->mOMX->sendCommand(
mCodec->mNode,
OMX_CommandPortDisable, kPortIndexOutput),
@@ -1729,6 +1831,8 @@ bool ACodec::ExecutingState::onOMXEvent(
}
mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
+ } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
+ mCodec->mSentFormat = false;
} else {
LOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
mCodec->mComponentName.c_str(), data2);
@@ -1816,6 +1920,8 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent(
} else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
+ mCodec->mSentFormat = false;
+
LOGV("[%s] Output port now reenabled.",
mCodec->mComponentName.c_str());
@@ -1869,6 +1975,8 @@ bool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
void ACodec::ExecutingToIdleState::stateEntered() {
LOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
+
+ mCodec->mSentFormat = false;
}
bool ACodec::ExecutingToIdleState::onOMXEvent(
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index 0e40acc..b592c3f 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -171,6 +171,18 @@ void AMessage::setMessage(const char *name, const sp<AMessage> &obj) {
item->u.refValue = obj.get();
}
+void AMessage::setRect(
+ const char *name,
+ int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ Item *item = allocateItem(name);
+ item->mType = kTypeRect;
+
+ item->u.rectValue.mLeft = left;
+ item->u.rectValue.mTop = top;
+ item->u.rectValue.mRight = right;
+ item->u.rectValue.mBottom = bottom;
+}
+
bool AMessage::findString(const char *name, AString *value) const {
const Item *item = findItem(name, kTypeString);
if (item) {
@@ -198,6 +210,22 @@ bool AMessage::findMessage(const char *name, sp<AMessage> *obj) const {
return false;
}
+bool AMessage::findRect(
+ const char *name,
+ int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) const {
+ const Item *item = findItem(name, kTypeRect);
+ if (item == NULL) {
+ return false;
+ }
+
+ *left = item->u.rectValue.mLeft;
+ *top = item->u.rectValue.mTop;
+ *right = item->u.rectValue.mRight;
+ *bottom = item->u.rectValue.mBottom;
+
+ return true;
+}
+
void AMessage::post(int64_t delayUs) {
extern ALooperRoster gLooperRoster;