summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2014-10-17 01:10:23 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-10-17 01:10:24 +0000
commit0ebf65be6642774c26e6fddd44b030ddd3eae492 (patch)
treea6d47890dc81b9aaaabb6857c9caf29b8b6cf016 /media
parentc40da54b34138856446e79245ac45600191962b5 (diff)
parent3b9eb1f8629c6264d924ab7043f80d824cdd39e2 (diff)
downloadframeworks_av-0ebf65be6642774c26e6fddd44b030ddd3eae492.zip
frameworks_av-0ebf65be6642774c26e6fddd44b030ddd3eae492.tar.gz
frameworks_av-0ebf65be6642774c26e6fddd44b030ddd3eae492.tar.bz2
Merge "move audio sink open/close to NuPlayerRenderer" into lmp-dev
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp130
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp199
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h16
4 files changed, 223 insertions, 123 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index eb5821b..a63a940 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -153,7 +153,6 @@ NuPlayer::NuPlayer()
mSourceFlags(0),
mVideoIsAVC(false),
mOffloadAudio(false),
- mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
mAudioDecoderGeneration(0),
mVideoDecoderGeneration(0),
mRendererGeneration(0),
@@ -1112,30 +1111,15 @@ void NuPlayer::postScanSources() {
}
void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) {
- ALOGV("openAudioSink: offloadOnly(%d) mOffloadAudio(%d)",
- offloadOnly, mOffloadAudio);
- bool audioSinkChanged = false;
-
- int32_t numChannels;
- CHECK(format->findInt32("channel-count", &numChannels));
-
- int32_t channelMask;
- if (!format->findInt32("channel-mask", &channelMask)) {
- // signal to the AudioSink to derive the mask from count.
- channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
- }
-
- int32_t sampleRate;
- CHECK(format->findInt32("sample-rate", &sampleRate));
-
uint32_t flags;
int64_t durationUs;
+ bool hasVideo = (mVideoDecoder != NULL);
// FIXME: we should handle the case where the video decoder
// is created after we receive the format change indication.
// Current code will just make that we select deep buffer
// with video which should not be a problem as it should
// not prevent from keeping A/V sync.
- if (mVideoDecoder == NULL &&
+ if (hasVideo &&
mSource->getDuration(&durationUs) == OK &&
durationUs
> AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
@@ -1144,114 +1128,18 @@ void NuPlayer::openAudioSink(const sp<AMessage> &format, bool offloadOnly) {
flags = AUDIO_OUTPUT_FLAG_NONE;
}
- if (mOffloadAudio) {
- audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
- AString mime;
- CHECK(format->findString("mime", &mime));
- status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
+ mOffloadAudio = mRenderer->openAudioSink(
+ format, offloadOnly, hasVideo, flags);
- if (err != OK) {
- ALOGE("Couldn't map mime \"%s\" to a valid "
- "audio_format", mime.c_str());
- mOffloadAudio = false;
- } else {
- ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
- mime.c_str(), audioFormat);
-
- int avgBitRate = -1;
- format->findInt32("bit-rate", &avgBitRate);
-
- int32_t aacProfile = -1;
- if (audioFormat == AUDIO_FORMAT_AAC
- && format->findInt32("aac-profile", &aacProfile)) {
- // Redefine AAC format as per aac profile
- mapAACProfileToAudioFormat(
- audioFormat,
- aacProfile);
- }
-
- audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
- offloadInfo.duration_us = -1;
- format->findInt64(
- "durationUs", &offloadInfo.duration_us);
- offloadInfo.sample_rate = sampleRate;
- offloadInfo.channel_mask = channelMask;
- offloadInfo.format = audioFormat;
- offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
- offloadInfo.bit_rate = avgBitRate;
- offloadInfo.has_video = (mVideoDecoder != NULL);
- offloadInfo.is_streaming = true;
-
- if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
- ALOGV("openAudioSink: no change in offload mode");
- return; // no change from previous configuration, everything ok.
- }
- ALOGV("openAudioSink: try to open AudioSink in offload mode");
- flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
- flags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
- audioSinkChanged = true;
- mAudioSink->close();
- err = mAudioSink->open(
- sampleRate,
- numChannels,
- (audio_channel_mask_t)channelMask,
- audioFormat,
- 8 /* bufferCount */,
- &NuPlayer::Renderer::AudioSinkCallback,
- mRenderer.get(),
- (audio_output_flags_t)flags,
- &offloadInfo);
-
- if (err == OK) {
- // If the playback is offloaded to h/w, we pass
- // the HAL some metadata information.
- // We don't want to do this for PCM because it
- // will be going through the AudioFlinger mixer
- // before reaching the hardware.
- sp<MetaData> audioMeta =
- mSource->getFormatMeta(true /* audio */);
- sendMetaDataToHal(mAudioSink, audioMeta);
- mCurrentOffloadInfo = offloadInfo;
- err = mAudioSink->start();
- ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
- }
- if (err != OK) {
- // Clean up, fall back to non offload mode.
- mAudioSink->close();
- mRenderer->signalDisableOffloadAudio();
- mOffloadAudio = false;
- mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
- ALOGV("openAudioSink: offload failed");
- }
- }
- }
- if (!offloadOnly && !mOffloadAudio) {
- flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
- ALOGV("openAudioSink: open AudioSink in NON-offload mode");
-
- audioSinkChanged = true;
- mAudioSink->close();
- mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
- CHECK_EQ(mAudioSink->open(
- sampleRate,
- numChannels,
- (audio_channel_mask_t)channelMask,
- AUDIO_FORMAT_PCM_16_BIT,
- 8 /* bufferCount */,
- NULL,
- NULL,
- (audio_output_flags_t)flags),
- (status_t)OK);
- mAudioSink->start();
- }
- if (audioSinkChanged) {
- mRenderer->signalAudioSinkChanged();
+ if (mOffloadAudio) {
+ sp<MetaData> audioMeta =
+ mSource->getFormatMeta(true /* audio */);
+ sendMetaDataToHal(mAudioSink, audioMeta);
}
}
void NuPlayer::closeAudioSink() {
- mAudioSink->close();
- mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
+ mRenderer->closeAudioSink();
}
status_t NuPlayer::instantiateDecoder(bool audio, sp<Decoder> *decoder) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index c61510c..d6120d2 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -132,7 +132,6 @@ private:
sp<Decoder> mVideoDecoder;
bool mVideoIsAVC;
bool mOffloadAudio;
- audio_offload_info_t mCurrentOffloadInfo;
sp<Decoder> mAudioDecoder;
sp<CCDecoder> mCCDecoder;
sp<Renderer> mRenderer;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 7b9dbb7..e5c83dd 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -28,6 +28,7 @@
#include <media/stagefright/foundation/AUtils.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
#include <VideoFrameScheduler.h>
@@ -80,7 +81,8 @@ NuPlayer::Renderer::Renderer(
mVideoRenderingStartGeneration(0),
mAudioRenderingStartGeneration(0),
mAudioOffloadPauseTimeoutGeneration(0),
- mAudioOffloadTornDown(false) {
+ mAudioOffloadTornDown(false),
+ mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER) {
readProperties();
}
@@ -237,8 +239,72 @@ void NuPlayer::Renderer::setPauseStartedTimeRealUs(int64_t realUs) {
mPauseStartedTimeRealUs = realUs;
}
+bool NuPlayer::Renderer::openAudioSink(
+ const sp<AMessage> &format,
+ bool offloadOnly,
+ bool hasVideo,
+ uint32_t flags) {
+ sp<AMessage> msg = new AMessage(kWhatOpenAudioSink, id());
+ msg->setMessage("format", format);
+ msg->setInt32("offload-only", offloadOnly);
+ msg->setInt32("has-video", hasVideo);
+ msg->setInt32("flags", flags);
+
+ sp<AMessage> response;
+ msg->postAndAwaitResponse(&response);
+
+ int32_t offload;
+ CHECK(response->findInt32("offload", &offload));
+ return (offload != 0);
+}
+
+void NuPlayer::Renderer::closeAudioSink() {
+ sp<AMessage> msg = new AMessage(kWhatCloseAudioSink, id());
+
+ sp<AMessage> response;
+ msg->postAndAwaitResponse(&response);
+}
+
void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
+ case kWhatOpenAudioSink:
+ {
+ sp<AMessage> format;
+ CHECK(msg->findMessage("format", &format));
+
+ int32_t offloadOnly;
+ CHECK(msg->findInt32("offload-only", &offloadOnly));
+
+ int32_t hasVideo;
+ CHECK(msg->findInt32("has-video", &hasVideo));
+
+ uint32_t flags;
+ CHECK(msg->findInt32("flags", (int32_t *)&flags));
+
+ bool offload = onOpenAudioSink(format, offloadOnly, hasVideo, flags);
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("offload", offload);
+
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+ response->postReply(replyID);
+
+ break;
+ }
+
+ case kWhatCloseAudioSink:
+ {
+ uint32_t replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ onCloseAudioSink();
+
+ sp<AMessage> response = new AMessage;
+ response->postReply(replyID);
+ break;
+ }
+
case kWhatStopAudioSink:
{
mAudioSink->stop();
@@ -1162,5 +1228,136 @@ void NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() {
}
}
+bool NuPlayer::Renderer::onOpenAudioSink(
+ const sp<AMessage> &format,
+ bool offloadOnly,
+ bool hasVideo,
+ uint32_t flags) {
+ ALOGV("openAudioSink: offloadOnly(%d) offloadingAudio(%d)",
+ offloadOnly, offloadingAudio());
+ bool audioSinkChanged = false;
+
+ int32_t numChannels;
+ CHECK(format->findInt32("channel-count", &numChannels));
+
+ int32_t channelMask;
+ if (!format->findInt32("channel-mask", &channelMask)) {
+ // signal to the AudioSink to derive the mask from count.
+ channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
+ }
+
+ int32_t sampleRate;
+ CHECK(format->findInt32("sample-rate", &sampleRate));
+
+ if (offloadingAudio()) {
+ audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
+ AString mime;
+ CHECK(format->findString("mime", &mime));
+ status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
+
+ if (err != OK) {
+ ALOGE("Couldn't map mime \"%s\" to a valid "
+ "audio_format", mime.c_str());
+ onDisableOffloadAudio();
+ } else {
+ ALOGV("Mime \"%s\" mapped to audio_format 0x%x",
+ mime.c_str(), audioFormat);
+
+ int avgBitRate = -1;
+ format->findInt32("bit-rate", &avgBitRate);
+
+ int32_t aacProfile = -1;
+ if (audioFormat == AUDIO_FORMAT_AAC
+ && format->findInt32("aac-profile", &aacProfile)) {
+ // Redefine AAC format as per aac profile
+ mapAACProfileToAudioFormat(
+ audioFormat,
+ aacProfile);
+ }
+
+ audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
+ offloadInfo.duration_us = -1;
+ format->findInt64(
+ "durationUs", &offloadInfo.duration_us);
+ offloadInfo.sample_rate = sampleRate;
+ offloadInfo.channel_mask = channelMask;
+ offloadInfo.format = audioFormat;
+ offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
+ offloadInfo.bit_rate = avgBitRate;
+ offloadInfo.has_video = hasVideo;
+ offloadInfo.is_streaming = true;
+
+ if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
+ ALOGV("openAudioSink: no change in offload mode");
+ // no change from previous configuration, everything ok.
+ return offloadingAudio();
+ }
+ ALOGV("openAudioSink: try to open AudioSink in offload mode");
+ flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+ flags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+ audioSinkChanged = true;
+ mAudioSink->close();
+ err = mAudioSink->open(
+ sampleRate,
+ numChannels,
+ (audio_channel_mask_t)channelMask,
+ audioFormat,
+ 8 /* bufferCount */,
+ &NuPlayer::Renderer::AudioSinkCallback,
+ this,
+ (audio_output_flags_t)flags,
+ &offloadInfo);
+
+ if (err == OK) {
+ // If the playback is offloaded to h/w, we pass
+ // the HAL some metadata information.
+ // We don't want to do this for PCM because it
+ // will be going through the AudioFlinger mixer
+ // before reaching the hardware.
+ // TODO
+ mCurrentOffloadInfo = offloadInfo;
+ err = mAudioSink->start();
+ ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
+ }
+ if (err != OK) {
+ // Clean up, fall back to non offload mode.
+ mAudioSink->close();
+ onDisableOffloadAudio();
+ mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
+ ALOGV("openAudioSink: offload failed");
+ }
+ }
+ }
+ if (!offloadOnly && !offloadingAudio()) {
+ flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+ ALOGV("openAudioSink: open AudioSink in NON-offload mode");
+
+ audioSinkChanged = true;
+ mAudioSink->close();
+ mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
+ CHECK_EQ(mAudioSink->open(
+ sampleRate,
+ numChannels,
+ (audio_channel_mask_t)channelMask,
+ AUDIO_FORMAT_PCM_16_BIT,
+ 8 /* bufferCount */,
+ NULL,
+ NULL,
+ (audio_output_flags_t)flags),
+ (status_t)OK);
+ mAudioSink->start();
+ }
+ if (audioSinkChanged) {
+ onAudioSinkChanged();
+ }
+
+ return offloadingAudio();
+}
+
+void NuPlayer::Renderer::onCloseAudioSink() {
+ mAudioSink->close();
+ mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index db1dab6..3e30226 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -70,6 +70,13 @@ struct NuPlayer::Renderer : public AHandler {
int64_t getVideoLateByUs();
void setPauseStartedTimeRealUs(int64_t realUs);
+ bool openAudioSink(
+ const sp<AMessage> &format,
+ bool offloadOnly,
+ bool hasVideo,
+ uint32_t flags);
+ void closeAudioSink();
+
enum {
kWhatEOS = 'eos ',
kWhatFlushComplete = 'fluC',
@@ -100,6 +107,8 @@ private:
kWhatAudioSinkChanged = 'auSC',
kWhatPause = 'paus',
kWhatResume = 'resm',
+ kWhatOpenAudioSink = 'opnA',
+ kWhatCloseAudioSink = 'clsA',
kWhatStopAudioSink = 'stpA',
kWhatDisableOffloadAudio = 'noOA',
kWhatSetVideoFrameRate = 'sVFR',
@@ -158,6 +167,7 @@ private:
int32_t mAudioOffloadPauseTimeoutGeneration;
bool mAudioOffloadTornDown;
+ audio_offload_info_t mCurrentOffloadInfo;
size_t fillAudioBuffer(void *buffer, size_t size);
@@ -183,6 +193,12 @@ private:
void onResume();
void onSetVideoFrameRate(float fps);
void onAudioOffloadTearDown(AudioOffloadTearDownReason reason);
+ bool onOpenAudioSink(
+ const sp<AMessage> &format,
+ bool offloadOnly,
+ bool hasVideo,
+ uint32_t flags);
+ void onCloseAudioSink();
void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
void notifyFlushComplete(bool audio);