summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonghua Wu <ronghuawu@google.com>2015-05-21 12:20:21 -0700
committerRonghua Wu <ronghuawu@google.com>2015-05-22 10:36:31 -0700
commitfaeb0f291330134dc4468359a36e099aae508449 (patch)
tree028333c0801e03826c4162cb35880236eaae3b3b
parent8eddd88568fe4da0ca0ceab5072bc488827f01b5 (diff)
downloadframeworks_av-faeb0f291330134dc4468359a36e099aae508449.zip
frameworks_av-faeb0f291330134dc4468359a36e099aae508449.tar.gz
frameworks_av-faeb0f291330134dc4468359a36e099aae508449.tar.bz2
libmediaplayerservice: try to open audio sink in offload mode in error.
Bug: 19061432 Bug: 21370108 Change-Id: Iaa757555ef37fd1ac87b6e2d5a9969bb58cc5ebc
-rw-r--r--include/media/AudioTrack.h15
-rw-r--r--include/media/MediaPlayerInterface.h3
-rw-r--r--media/libmedia/AudioTrack.cpp16
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp9
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h3
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp21
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp31
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h20
9 files changed, 76 insertions, 43 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 458f4b4..e9f0131 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -183,6 +183,10 @@ public:
* pid: Process ID of the app which initially requested this AudioTrack
* for power management tracking, or -1 for current process ID.
* pAttributes: If not NULL, supersedes streamType for use case selection.
+ * doNotReconnect: If set to true, AudioTrack won't automatically recreate the IAudioTrack
+ binder to AudioFlinger.
+ It will return an error instead. The application will recreate
+ the track based on offloading or different channel configuration, etc.
* threadCanCallJava: Not present in parameter list, and so is fixed at false.
*/
@@ -200,7 +204,8 @@ public:
const audio_offload_info_t *offloadInfo = NULL,
int uid = -1,
pid_t pid = -1,
- const audio_attributes_t* pAttributes = NULL);
+ const audio_attributes_t* pAttributes = NULL,
+ bool doNotReconnect = false);
/* Creates an audio track and registers it with AudioFlinger.
* With this constructor, the track is configured for static buffer mode.
@@ -228,7 +233,8 @@ public:
const audio_offload_info_t *offloadInfo = NULL,
int uid = -1,
pid_t pid = -1,
- const audio_attributes_t* pAttributes = NULL);
+ const audio_attributes_t* pAttributes = NULL,
+ bool doNotReconnect = false);
/* Terminates the AudioTrack and unregisters it from AudioFlinger.
* Also destroys all resources associated with the AudioTrack.
@@ -272,7 +278,8 @@ public:
const audio_offload_info_t *offloadInfo = NULL,
int uid = -1,
pid_t pid = -1,
- const audio_attributes_t* pAttributes = NULL);
+ const audio_attributes_t* pAttributes = NULL,
+ bool doNotReconnect = false);
/* Result of constructing the AudioTrack. This must be checked for successful initialization
* before using any AudioTrack API (except for set()), because using
@@ -877,6 +884,8 @@ protected:
// const after set(), except for bits AUDIO_OUTPUT_FLAG_FAST and AUDIO_OUTPUT_FLAG_OFFLOAD.
// mLock must be held to read or write those bits reliably.
+ bool mDoNotReconnect;
+
int mSessionId;
int mAuxEffectId;
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index fa917f9..8c36f0e 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -113,7 +113,8 @@ public:
AudioCallback cb = NULL,
void *cookie = NULL,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- const audio_offload_info_t *offloadInfo = NULL) = 0;
+ const audio_offload_info_t *offloadInfo = NULL,
+ bool doNotResuscitate = false) = 0;
virtual status_t start() = 0;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index db316b0..faf5935 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -178,7 +178,8 @@ AudioTrack::AudioTrack(
const audio_offload_info_t *offloadInfo,
int uid,
pid_t pid,
- const audio_attributes_t* pAttributes)
+ const audio_attributes_t* pAttributes,
+ bool doNotReconnect)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -189,7 +190,7 @@ AudioTrack::AudioTrack(
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
- offloadInfo, uid, pid, pAttributes);
+ offloadInfo, uid, pid, pAttributes, doNotReconnect);
}
AudioTrack::AudioTrack(
@@ -207,7 +208,8 @@ AudioTrack::AudioTrack(
const audio_offload_info_t *offloadInfo,
int uid,
pid_t pid,
- const audio_attributes_t* pAttributes)
+ const audio_attributes_t* pAttributes,
+ bool doNotReconnect)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -218,7 +220,7 @@ AudioTrack::AudioTrack(
mStatus = set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo,
- uid, pid, pAttributes);
+ uid, pid, pAttributes, doNotReconnect);
}
AudioTrack::~AudioTrack()
@@ -266,7 +268,8 @@ status_t AudioTrack::set(
const audio_offload_info_t *offloadInfo,
int uid,
pid_t pid,
- const audio_attributes_t* pAttributes)
+ const audio_attributes_t* pAttributes,
+ bool doNotReconnect)
{
ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
"flags #%x, notificationFrames %u, sessionId %d, transferType %d, uid %d, pid %d",
@@ -308,6 +311,7 @@ status_t AudioTrack::set(
}
mSharedBuffer = sharedBuffer;
mTransfer = transferType;
+ mDoNotReconnect = doNotReconnect;
ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
sharedBuffer->size());
@@ -2006,7 +2010,7 @@ status_t AudioTrack::restoreTrack_l(const char *from)
// output parameters and new IAudioFlinger in createTrack_l()
AudioSystem::clearAudioConfigCache();
- if (isOffloadedOrDirect_l()) {
+ if (isOffloadedOrDirect_l() || mDoNotReconnect) {
// FIXME re-creation of offloaded tracks is not yet implemented
return DEAD_OBJECT;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index efbc0d6..9c0af4a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1489,7 +1489,8 @@ status_t MediaPlayerService::AudioOutput::open(
audio_format_t format, int bufferCount,
AudioCallback cb, void *cookie,
audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+ const audio_offload_info_t *offloadInfo,
+ bool doNotReconnect)
{
mCallback = cb;
mCallbackCookie = cookie;
@@ -1605,7 +1606,8 @@ status_t MediaPlayerService::AudioOutput::open(
offloadInfo,
mUid,
mPid,
- mAttributes);
+ mAttributes,
+ doNotReconnect);
} else {
t = new AudioTrack(
mStreamType,
@@ -1622,7 +1624,8 @@ status_t MediaPlayerService::AudioOutput::open(
NULL, // offload info
mUid,
mPid,
- mAttributes);
+ mAttributes,
+ doNotReconnect);
}
if ((t == 0) || (t->initCheck() != NO_ERROR)) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 5103841..e9f72b8 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -97,7 +97,8 @@ class MediaPlayerService : public BnMediaPlayerService
audio_format_t format, int bufferCount,
AudioCallback cb, void *cookie,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- const audio_offload_info_t *offloadInfo = NULL);
+ const audio_offload_info_t *offloadInfo = NULL,
+ bool doNotReconnect = false);
virtual status_t start();
virtual ssize_t write(const void* buffer, size_t size, bool blocking = true);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 96a7adb..87074f0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1083,12 +1083,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
} else if (what == Renderer::kWhatMediaRenderingStart) {
ALOGV("media rendering started");
notifyListener(MEDIA_STARTED, 0, 0);
- } else if (what == Renderer::kWhatAudioOffloadTearDown) {
- ALOGV("Tear down audio offload, fall back to s/w path if due to error.");
+ } else if (what == Renderer::kWhatAudioTearDown) {
int64_t positionUs;
CHECK(msg->findInt64("positionUs", &positionUs));
int32_t reason;
CHECK(msg->findInt32("reason", &reason));
+ ALOGV("Tear down audio with reason %d.", reason);
closeAudioSink();
mAudioDecoder.clear();
++mAudioDecoderGeneration;
@@ -1100,9 +1100,22 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
}
performSeek(positionUs);
+
if (reason == Renderer::kDueToError) {
- mRenderer->signalDisableOffloadAudio();
- mOffloadAudio = false;
+ sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
+ sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
+ audio_stream_type_t streamType = mAudioSink->getAudioStreamType();
+ const bool hasVideo = (videoFormat != NULL);
+ const bool canOffload = canOffloadStream(
+ audioMeta, hasVideo, true /* is_streaming */, streamType);
+ if (canOffload) {
+ mRenderer->signalEnableOffloadAudio();
+ sp<AMessage> format = mSource->getFormat(true /*audio*/);
+ tryOpenAudioSinkForOffload(format, hasVideo);
+ } else {
+ mRenderer->signalDisableOffloadAudio();
+ mOffloadAudio = false;
+ }
instantiateDecoder(true /* audio */, &mAudioDecoder);
}
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 376c93a..73f8ba8 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -68,6 +68,7 @@ NuPlayer::Decoder::Decoder(
}
NuPlayer::Decoder::~Decoder() {
+ mCodec->release();
releaseAndResetMediaBuffers();
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 007a335..409dedf 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -82,7 +82,7 @@ NuPlayer::Renderer::Renderer(
mVideoRenderingStartGeneration(0),
mAudioRenderingStartGeneration(0),
mAudioOffloadPauseTimeoutGeneration(0),
- mAudioOffloadTornDown(false),
+ mAudioTornDown(false),
mCurrentOffloadInfo(AUDIO_INFO_INITIALIZER),
mCurrentPcmInfo(AUDIO_PCMINFO_INITIALIZER),
mTotalBuffersQueued(0),
@@ -566,9 +566,9 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- case kWhatAudioOffloadTearDown:
+ case kWhatAudioTearDown:
{
- onAudioOffloadTearDown(kDueToError);
+ onAudioTearDown(kDueToError);
break;
}
@@ -580,7 +580,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
break;
}
ALOGV("Audio Offload tear down due to pause timeout.");
- onAudioOffloadTearDown(kDueToTimeout);
+ onAudioTearDown(kDueToTimeout);
mWakeLock->release();
break;
}
@@ -648,7 +648,7 @@ size_t NuPlayer::Renderer::AudioSinkCallback(
case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:
{
- me->notifyAudioOffloadTearDown();
+ me->notifyAudioTearDown();
break;
}
}
@@ -792,6 +792,7 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
ALOGW("AudioSink write would block when writing %zu bytes", copy);
} else {
ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
+ notifyAudioTearDown();
}
break;
}
@@ -1060,8 +1061,8 @@ void NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult, int64_t del
notify->post(delayUs);
}
-void NuPlayer::Renderer::notifyAudioOffloadTearDown() {
- (new AMessage(kWhatAudioOffloadTearDown, this))->post();
+void NuPlayer::Renderer::notifyAudioTearDown() {
+ (new AMessage(kWhatAudioTearDown, this))->post();
}
void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
@@ -1480,11 +1481,11 @@ int64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) {
return durationUs;
}
-void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reason) {
- if (mAudioOffloadTornDown) {
+void NuPlayer::Renderer::onAudioTearDown(AudioTearDownReason reason) {
+ if (mAudioTornDown) {
return;
}
- mAudioOffloadTornDown = true;
+ mAudioTornDown = true;
int64_t currentPositionUs;
if (getCurrentPosition(&currentPositionUs) != OK) {
@@ -1495,7 +1496,7 @@ void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reaso
mAudioSink->flush();
sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatAudioOffloadTearDown);
+ notify->setInt32("what", kWhatAudioTearDown);
notify->setInt64("positionUs", currentPositionUs);
notify->setInt32("reason", reason);
notify->post();
@@ -1653,7 +1654,9 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
8 /* bufferCount */,
NULL,
NULL,
- (audio_output_flags_t)pcmFlags);
+ (audio_output_flags_t)pcmFlags,
+ NULL,
+ true /* doNotReconnect */);
if (err == OK) {
err = mAudioSink->setPlaybackRate(mPlaybackSettings);
}
@@ -1668,9 +1671,7 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
if (audioSinkChanged) {
onAudioSinkChanged();
}
- if (offloadingAudio()) {
- mAudioOffloadTornDown = false;
- }
+ mAudioTornDown = false;
return OK;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 928b71b..fbdf5bf 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -82,16 +82,16 @@ struct NuPlayer::Renderer : public AHandler {
void closeAudioSink();
enum {
- kWhatEOS = 'eos ',
- kWhatFlushComplete = 'fluC',
- kWhatPosition = 'posi',
- kWhatVideoRenderingStart = 'vdrd',
- kWhatMediaRenderingStart = 'mdrd',
- kWhatAudioOffloadTearDown = 'aOTD',
+ kWhatEOS = 'eos ',
+ kWhatFlushComplete = 'fluC',
+ kWhatPosition = 'posi',
+ kWhatVideoRenderingStart = 'vdrd',
+ kWhatMediaRenderingStart = 'mdrd',
+ kWhatAudioTearDown = 'adTD',
kWhatAudioOffloadPauseTimeout = 'aOPT',
};
- enum AudioOffloadTearDownReason {
+ enum AudioTearDownReason {
kDueToError = 0,
kDueToTimeout,
};
@@ -179,7 +179,7 @@ private:
int64_t mLastPositionUpdateUs;
int32_t mAudioOffloadPauseTimeoutGeneration;
- bool mAudioOffloadTornDown;
+ bool mAudioTornDown;
audio_offload_info_t mCurrentOffloadInfo;
struct PcmInfo {
@@ -242,7 +242,7 @@ private:
int32_t getQueueGeneration(bool audio);
int32_t getDrainGeneration(bool audio);
bool getSyncQueues();
- void onAudioOffloadTearDown(AudioOffloadTearDownReason reason);
+ void onAudioTearDown(AudioTearDownReason reason);
status_t onOpenAudioSink(
const sp<AMessage> &format,
bool offloadOnly,
@@ -255,7 +255,7 @@ private:
void notifyPosition();
void notifyVideoLateBy(int64_t lateByUs);
void notifyVideoRenderingStart();
- void notifyAudioOffloadTearDown();
+ void notifyAudioTearDown();
void flushQueue(List<QueueEntry> *queue);
bool dropBufferIfStale(bool audio, const sp<AMessage> &msg);