diff options
author | Andreas Huber <andih@google.com> | 2011-01-10 11:26:38 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-01-10 11:26:38 -0800 |
commit | 32ad210e4e4bcbdf912a01c9d2ff105cb3c5056f (patch) | |
tree | 57bc9bcd78d3844035a923a70b516e4dc2872a24 /media | |
parent | 14c858e80dfe2030c9f343dc0c6e2048e030731b (diff) | |
parent | 31e2508c75018145a8238925ff1a08cbde4e799a (diff) | |
download | frameworks_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.cpp | 12 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 45 | ||||
-rw-r--r-- | media/libstagefright/ACodec.cpp | 112 | ||||
-rw-r--r-- | media/libstagefright/foundation/AMessage.cpp | 28 |
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(¶ms); + params.nPortIndex = kPortIndexOutput; + + CHECK_EQ(mOMX->getParameter( + mNode, OMX_IndexParamAudioPcm, + ¶ms, 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; |