Merge "Properly announce decoder output format changes, make sure AMessage::dup does."
This commit is contained in:
committed by
Android (Google) Code Review
commit
52185ff754
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
sp<AMessage> realNotify;
|
||||
CHECK(notify->findMessage("real-notify", &realNotify));
|
||||
|
||||
if (err == OK) {
|
||||
if (!mSentFormat) {
|
||||
sendFormatChange();
|
||||
mSentFormat = true;
|
||||
}
|
||||
|
||||
sp<AMessage> notify = mNotify->dup();
|
||||
|
||||
sp<AMessage> realNotify;
|
||||
CHECK(notify->findMessage("real-notify", &realNotify));
|
||||
|
||||
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));
|
||||
|
||||
if (what == ACodec::kWhatDrainThisBuffer) {
|
||||
CHECK_GT(mNumPendingDecodes, 0);
|
||||
--mNumPendingDecodes;
|
||||
|
||||
sp<AMessage> reply =
|
||||
new AMessage(kWhatOutputBufferDrained, id());
|
||||
|
||||
notify->setMessage("reply", reply);
|
||||
|
||||
++mNumOutstandingOutputBuffers;
|
||||
} else if (what == ACodec::kWhatEOS) {
|
||||
CHECK_GT(mNumPendingDecodes, 0);
|
||||
--mNumPendingDecodes;
|
||||
|
||||
if (mFlushing) {
|
||||
completeFlushIfPossible();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
notify->setMessage("reply", reply);
|
||||
notify->post();
|
||||
|
||||
++mNumOutstandingOutputBuffers;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user