summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-12-16 10:26:37 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-12-16 10:26:37 -0800
commitd0c5158d5244418880bb85122e9fd0e378892c2a (patch)
tree9c60c309328dc54f68ac4e39db999924bffbffa3
parenta6256238d9015c42129fe43791968768fe501efa (diff)
parent2c2814b900a61fa07ddfff860b143fbbe9c740e9 (diff)
downloadframeworks_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.h11
-rw-r--r--include/media/stagefright/foundation/AMessage.h3
-rw-r--r--media/libmediaplayerservice/nuplayer/DecoderWrapper.cpp109
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp27
-rw-r--r--media/libstagefright/foundation/AMessage.cpp11
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> &notify)
: 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", &notify));
- 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;