diff options
author | Robert Shih <robertshih@google.com> | 2014-01-23 16:18:22 -0800 |
---|---|---|
committer | Robert Shih <robertshih@google.com> | 2014-02-24 11:26:54 -0800 |
commit | 6d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aab (patch) | |
tree | ae76d5da5f6acb66e553abc039e7e8d4bfc6c0f5 /media/libmediaplayerservice/nuplayer | |
parent | 3a005b3b19b750afe24577ae322aff4602ca2740 (diff) | |
download | frameworks_av-6d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aab.zip frameworks_av-6d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aab.tar.gz frameworks_av-6d0a94ead4f6e62b8ca9b2b1d775ffcd0a7a7aab.tar.bz2 |
NuPlayer side support for seamless format switch.
Avoid reinstantiating decoder if seamless format switch is supported.
Change-Id: I2c2be08d6da90cc835ec747d04a76db2313dfc7c
Diffstat (limited to 'media/libmediaplayerservice/nuplayer')
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 9 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp | 61 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h | 5 |
3 files changed, 74 insertions, 1 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index d47ac98..a750ad0 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1006,7 +1006,14 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) { &NuPlayer::performScanSources)); } - flushDecoder(audio, formatChange); + sp<AMessage> newFormat = mSource->getFormat(audio); + sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder; + if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) { + flushDecoder(audio, /* needShutdown = */ true); + } else { + flushDecoder(audio, /* needShutdown = */ false); + err = OK; + } } else { // This stream is unaffected by the discontinuity diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp index 22f699e..2423fd5 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp @@ -67,6 +67,7 @@ void NuPlayer::Decoder::configure(const sp<AMessage> &format) { // queue. bool needDedicatedLooper = !strncasecmp(mime.c_str(), "video/", 6); + mFormat = format; mCodec = new ACodec; if (needDedicatedLooper && mCodecLooper == NULL) { @@ -147,5 +148,65 @@ void NuPlayer::Decoder::initiateShutdown() { } } +bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const { + if (targetFormat == NULL) { + return true; + } + + AString mime; + if (!targetFormat->findString("mime", &mime)) { + return false; + } + + if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { + // field-by-field comparison + const char * keys[] = { "channel-count", "sample-rate", "is-adts" }; + for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) { + int32_t oldVal, newVal; + if (!mFormat->findInt32(keys[i], &oldVal) || !targetFormat->findInt32(keys[i], &newVal) + || oldVal != newVal) { + return false; + } + } + + sp<ABuffer> oldBuf, newBuf; + if (mFormat->findBuffer("csd-0", &oldBuf) && targetFormat->findBuffer("csd-0", &newBuf)) { + if (oldBuf->size() != newBuf->size()) { + return false; + } + return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size()); + } + } + return false; +} + +bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const { + if (mFormat == NULL) { + return false; + } + + if (targetFormat == NULL) { + return true; + } + + AString oldMime, newMime; + if (!mFormat->findString("mime", &oldMime) + || !targetFormat->findString("mime", &newMime) + || !(oldMime == newMime)) { + return false; + } + + bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/")); + bool seamless; + if (audio) { + seamless = supportsSeamlessAudioFormatChange(targetFormat); + } else { + seamless = mCodec != NULL && mCodec->isConfiguredForAdaptivePlayback(); + } + + ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str()); + return seamless; +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h index a876148..78ea74a 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h @@ -36,6 +36,8 @@ struct NuPlayer::Decoder : public AHandler { void signalResume(); void initiateShutdown(); + bool supportsSeamlessFormatChange(const sp<AMessage> &to) const; + protected: virtual ~Decoder(); @@ -49,6 +51,7 @@ private: sp<AMessage> mNotify; sp<NativeWindowWrapper> mNativeWindow; + sp<AMessage> mFormat; sp<ACodec> mCodec; sp<ALooper> mCodecLooper; @@ -59,6 +62,8 @@ private: void onFillThisBuffer(const sp<AMessage> &msg); + bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const; + DISALLOW_EVIL_CONSTRUCTORS(Decoder); }; |