diff options
author | Andreas Huber <andih@google.com> | 2010-12-16 10:26:37 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-12-16 10:26:37 -0800 |
commit | d0c5158d5244418880bb85122e9fd0e378892c2a (patch) | |
tree | 9c60c309328dc54f68ac4e39db999924bffbffa3 | |
parent | a6256238d9015c42129fe43791968768fe501efa (diff) | |
parent | 2c2814b900a61fa07ddfff860b143fbbe9c740e9 (diff) | |
download | frameworks_av-d0c5158d5244418880bb85122e9fd0e378892c2a.zip frameworks_av-d0c5158d5244418880bb85122e9fd0e378892c2a.tar.gz frameworks_av-d0c5158d5244418880bb85122e9fd0e378892c2a.tar.bz2 |
Merge "Properly announce decoder output format changes, make sure AMessage::dup does."
-rw-r--r-- | include/media/stagefright/ACodec.h | 11 | ||||
-rw-r--r-- | include/media/stagefright/foundation/AMessage.h | 3 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp | 109 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 27 | ||||
-rw-r--r-- | media/libstagefright/foundation/AMessage.cpp | 11 |
5 files changed, 123 insertions, 38 deletions
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h index 940470d..b3815c4 100644 --- a/include/media/stagefright/ACodec.h +++ b/include/media/stagefright/ACodec.h @@ -14,11 +14,12 @@ struct MemoryDealer; struct ACodec : public AHierarchicalStateMachine { enum { - kWhatFillThisBuffer = 'fill', - kWhatDrainThisBuffer = 'drai', - kWhatEOS = 'eos ', - kWhatShutdownCompleted = 'scom', - kWhatFlushCompleted = 'fcom', + kWhatFillThisBuffer = 'fill', + kWhatDrainThisBuffer = 'drai', + kWhatEOS = 'eos ', + kWhatShutdownCompleted = 'scom', + kWhatFlushCompleted = 'fcom', + kWhatOutputFormatChanged = 'outC', }; ACodec(); diff --git a/include/media/stagefright/foundation/AMessage.h b/include/media/stagefright/foundation/AMessage.h index 941f6b9..91ec60c 100644 --- a/include/media/stagefright/foundation/AMessage.h +++ b/include/media/stagefright/foundation/AMessage.h @@ -64,6 +64,9 @@ struct AMessage : public RefBase { void post(int64_t delayUs = 0); + // Performs a deep-copy of "this", contained messages are in turn "dup'ed". + // Warning: RefBase items, i.e. "objects" are _not_ copied but only have + // their refcount incremented. sp<AMessage> dup() const; AString debugString(int32_t indent = 0) const; diff --git a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp index 89a5e69..9738e33 100644 --- a/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp +++ b/media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp @@ -166,6 +166,9 @@ private: sp<MediaSource> mDecoder; sp<AMessage> mNotify; bool mEOS; + bool mSentFormat; + + void sendFormatChange(); DISALLOW_EVIL_CONSTRUCTORS(WrapperReader); }; @@ -174,7 +177,8 @@ DecoderWrapper::WrapperReader::WrapperReader( const sp<MediaSource> &decoder, const sp<AMessage> ¬ify) : mDecoder(decoder), mNotify(notify), - mEOS(false) { + mEOS(false), + mSentFormat(false) { } DecoderWrapper::WrapperReader::~WrapperReader() { @@ -215,12 +219,17 @@ void DecoderWrapper::WrapperReader::onMessageReceived( MediaBuffer *src; status_t err = mDecoder->read(&src, &options); - sp<AMessage> notify = mNotify->dup(); + if (err == OK) { + if (!mSentFormat) { + sendFormatChange(); + mSentFormat = true; + } - sp<AMessage> realNotify; - CHECK(notify->findMessage("real-notify", &realNotify)); + sp<AMessage> notify = mNotify->dup(); + + sp<AMessage> realNotify; + CHECK(notify->findMessage("real-notify", &realNotify)); - if (err == OK) { realNotify->setInt32("what", ACodec::kWhatDrainThisBuffer); sp<ABuffer> dst = new ABuffer(src->range_length()); @@ -236,12 +245,23 @@ void DecoderWrapper::WrapperReader::onMessageReceived( dst->meta()->setInt64("timeUs", timeUs); realNotify->setObject("buffer", dst); + + notify->post(); + } else if (err == INFO_FORMAT_CHANGED) { + sendFormatChange(); + + readMore(false /* flush */); } else { + sp<AMessage> notify = mNotify->dup(); + + sp<AMessage> realNotify; + CHECK(notify->findMessage("real-notify", &realNotify)); + realNotify->setInt32("what", ACodec::kWhatEOS); mEOS = true; - } - notify->post(); + notify->post(); + } break; } @@ -251,6 +271,46 @@ void DecoderWrapper::WrapperReader::onMessageReceived( } } +void DecoderWrapper::WrapperReader::sendFormatChange() { + sp<AMessage> notify = mNotify->dup(); + + sp<AMessage> realNotify; + CHECK(notify->findMessage("real-notify", &realNotify)); + + realNotify->setInt32("what", ACodec::kWhatOutputFormatChanged); + + sp<MetaData> meta = mDecoder->getFormat(); + + const char *mime; + CHECK(meta->findCString(kKeyMIMEType, &mime)); + + realNotify->setString("mime", mime); + + if (!strncasecmp("audio/", mime, 6)) { + int32_t numChannels; + CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); + + int32_t sampleRate; + CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); + + realNotify->setInt32("channel-count", numChannels); + realNotify->setInt32("sample-rate", sampleRate); + } else { + CHECK(!strncasecmp("video/", mime, 6)); + + int32_t width, height; + CHECK(meta->findInt32(kKeyWidth, &width)); + CHECK(meta->findInt32(kKeyHeight, &height)); + + realNotify->setInt32("width", width); + realNotify->setInt32("height", height); + } + + notify->post(); + + mSentFormat = true; +} + //////////////////////////////////////////////////////////////////////////////// DecoderWrapper::DecoderWrapper() @@ -327,24 +387,33 @@ void DecoderWrapper::onMessageReceived(const sp<AMessage> &msg) { case kWhatFillBufferDone: { - CHECK_GT(mNumPendingDecodes, 0); - --mNumPendingDecodes; - - if (mFlushing) { - completeFlushIfPossible(); - break; - } - sp<AMessage> notify; CHECK(msg->findMessage("real-notify", ¬ify)); - sp<AMessage> reply = - new AMessage(kWhatOutputBufferDrained, id()); + int32_t what; + CHECK(notify->findInt32("what", &what)); - notify->setMessage("reply", reply); - notify->post(); + if (what == ACodec::kWhatDrainThisBuffer) { + CHECK_GT(mNumPendingDecodes, 0); + --mNumPendingDecodes; + + sp<AMessage> reply = + new AMessage(kWhatOutputBufferDrained, id()); - ++mNumOutstandingOutputBuffers; + notify->setMessage("reply", reply); + + ++mNumOutstandingOutputBuffers; + } else if (what == ACodec::kWhatEOS) { + CHECK_GT(mNumPendingDecodes, 0); + --mNumPendingDecodes; + + if (mFlushing) { + completeFlushIfPossible(); + break; + } + } + + notify->post(); break; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 403029a..e99c24a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -198,6 +198,21 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) { mFlushingAudio = NONE; mFlushingVideo = NONE; } + } else if (what == ACodec::kWhatOutputFormatChanged) { + CHECK(audio); + + int32_t numChannels; + CHECK(codecRequest->findInt32("channel-count", &numChannels)); + + int32_t sampleRate; + CHECK(codecRequest->findInt32("sample-rate", &sampleRate)); + + LOGI("Audio output format changed to %d Hz, %d channels", + sampleRate, numChannels); + + mAudioSink->close(); + CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK); + mAudioSink->start(); } else { CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer); @@ -365,18 +380,6 @@ status_t NuPlayer::instantiateDecoder( const sp<MetaData> &meta = source->getFormat(); (*decoder)->configure(meta); - if (audio) { - int32_t sampleRate; - int32_t channelCount; - CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); - CHECK(meta->findInt32(kKeyChannelCount, &channelCount)); - - channelCount = 2; // XXX - - CHECK_EQ(mAudioSink->open(sampleRate, channelCount), (status_t)OK); - mAudioSink->start(); - } - return OK; } diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp index 7da9cb8..0e40acc 100644 --- a/media/libstagefright/foundation/AMessage.cpp +++ b/media/libstagefright/foundation/AMessage.cpp @@ -224,13 +224,22 @@ sp<AMessage> AMessage::dup() const { } case kTypeObject: - case kTypeMessage: { to->u.refValue = from->u.refValue; to->u.refValue->incStrong(msg.get()); break; } + case kTypeMessage: + { + sp<AMessage> copy = + static_cast<AMessage *>(from->u.refValue)->dup(); + + to->u.refValue = copy.get(); + to->u.refValue->incStrong(msg.get()); + break; + } + default: { to->u = from->u; |