Merge "Camera: Camera3InputStream: Stop after finding buffer to return" into nyc-dev
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 9e0e98b..bdd6372 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -830,6 +830,11 @@
bool isDirect_l() const
{ return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; }
+ // pure pcm data is mixable (which excludes HW_AV_SYNC, with embedded timing)
+ bool isPurePcmData_l() const
+ { return audio_is_linear_pcm(mFormat)
+ && (mAttributes.flags & AUDIO_FLAG_HW_AV_SYNC) == 0; }
+
// increment mPosition by the delta of mServer, and return new value of mPosition
Modulo<uint32_t> updateAndGetPosition_l();
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index a731354..e70c611 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1016,7 +1016,11 @@
}
AutoMutex lock(mLock);
- if (isOffloadedOrDirect_l()) {
+ // FIXME: offloaded and direct tracks call into the HAL for render positions
+ // for compressed/synced data; however, we use proxy position for pure linear pcm data
+ // as we do not know the capability of the HAL for pcm position support and standby.
+ // There may be some latency differences between the HAL position and the proxy position.
+ if (isOffloadedOrDirect_l() && !isPurePcmData_l()) {
uint32_t dspFrames = 0;
if (isOffloaded_l() && ((mState == STATE_PAUSED) || (mState == STATE_PAUSED_STOPPING))) {
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 25c9fb1..2795101 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -907,6 +907,7 @@
}
status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) {
+ Mutex::Autolock _l(mLock);
if (mPlayer == NULL) {
return NO_INIT;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 6c54e3f..42a82ac 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1150,8 +1150,8 @@
}
restartAudio(
- positionUs, false /* forceNonOffload */,
- reason == Renderer::kDueToError /* needsToCreateAudioDecoder */);
+ positionUs, reason == Renderer::kForceNonOffload /* forceNonOffload */,
+ reason != Renderer::kDueToTimeout /* needsToCreateAudioDecoder */);
}
break;
}
@@ -1490,9 +1490,11 @@
void NuPlayer::restartAudio(
int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
- mAudioDecoder->pause();
- mAudioDecoder.clear();
- ++mAudioDecoderGeneration;
+ if (mAudioDecoder != NULL) {
+ mAudioDecoder->pause();
+ mAudioDecoder.clear();
+ ++mAudioDecoderGeneration;
+ }
if (mFlushingAudio == FLUSHING_DECODER) {
mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
mFlushingAudio = FLUSHED;
@@ -1520,7 +1522,7 @@
mOffloadAudio = false;
}
if (needsToCreateAudioDecoder) {
- instantiateDecoder(true /* audio */, &mAudioDecoder);
+ instantiateDecoder(true /* audio */, &mAudioDecoder, !forceNonOffload);
}
}
@@ -1557,7 +1559,8 @@
}
}
-status_t NuPlayer::instantiateDecoder(bool audio, sp<DecoderBase> *decoder) {
+status_t NuPlayer::instantiateDecoder(
+ bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange) {
// The audio decoder could be cleared by tear down. If still in shut down
// process, no need to create a new audio decoder.
if (*decoder != NULL || (audio && mFlushingAudio == SHUT_DOWN)) {
@@ -1605,7 +1608,9 @@
++mAudioDecoderGeneration;
notify->setInt32("generation", mAudioDecoderGeneration);
- determineAudioModeChange();
+ if (checkAudioModeChange) {
+ determineAudioModeChange();
+ }
if (mOffloadAudio) {
mSource->setOffloadAudio(true /* offload */);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index a55aa5f..369590b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -234,10 +234,11 @@
void tryOpenAudioSinkForOffload(const sp<AMessage> &format, bool hasVideo);
void closeAudioSink();
void restartAudio(
- int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder);
+ int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder);
void determineAudioModeChange();
- status_t instantiateDecoder(bool audio, sp<DecoderBase> *decoder);
+ status_t instantiateDecoder(
+ bool audio, sp<DecoderBase> *decoder, bool checkAudioModeChange = true);
status_t onInstantiateSecureDecoders();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 0e6a6e6..cbb9d95 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -647,7 +647,10 @@
case kWhatAudioTearDown:
{
- onAudioTearDown(kDueToError);
+ int32_t reason;
+ CHECK(msg->findInt32("reason", &reason));
+
+ onAudioTearDown((AudioTearDownReason)reason);
break;
}
@@ -741,7 +744,7 @@
case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:
{
ALOGV("AudioSink::CB_EVENT_TEAR_DOWN");
- me->notifyAudioTearDown();
+ me->notifyAudioTearDown(kDueToError);
break;
}
}
@@ -946,7 +949,7 @@
ALOGE("AudioSink write error(%zd) when writing %zu bytes", written, copy);
// This can only happen when AudioSink was opened with doNotReconnect flag set to
// true, in which case the NuPlayer will handle the reconnect.
- notifyAudioTearDown();
+ notifyAudioTearDown(kDueToError);
}
break;
}
@@ -1299,8 +1302,10 @@
notify->post(delayUs);
}
-void NuPlayer::Renderer::notifyAudioTearDown() {
- (new AMessage(kWhatAudioTearDown, this))->post();
+void NuPlayer::Renderer::notifyAudioTearDown(AudioTearDownReason reason) {
+ sp<AMessage> msg = new AMessage(kWhatAudioTearDown, this);
+ msg->setInt32("reason", reason);
+ msg->post();
}
void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
@@ -1630,7 +1635,7 @@
status_t err = mAudioSink->start();
if (err != OK) {
ALOGE("cannot start AudioSink err %d", err);
- notifyAudioTearDown();
+ notifyAudioTearDown(kDueToError);
}
}
@@ -1823,6 +1828,9 @@
onDisableOffloadAudio();
mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
ALOGV("openAudioSink: offload failed");
+ if (offloadOnly) {
+ notifyAudioTearDown(kForceNonOffload);
+ }
} else {
mUseAudioCallback = true; // offload mode transfers data through callback
++mAudioDrainGeneration; // discard pending kWhatDrainAudioQueue message.
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index c3ce511..004e21c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -92,8 +92,9 @@
};
enum AudioTearDownReason {
- kDueToError = 0,
+ kDueToError = 0, // Could restart with either offload or non-offload.
kDueToTimeout,
+ kForceNonOffload, // Restart only with non-offload.
};
protected:
@@ -262,7 +263,7 @@
void notifyPosition();
void notifyVideoLateBy(int64_t lateByUs);
void notifyVideoRenderingStart();
- void notifyAudioTearDown();
+ void notifyAudioTearDown(AudioTearDownReason reason);
void flushQueue(List<QueueEntry> *queue);
bool dropBufferIfStale(bool audio, const sp<AMessage> &msg);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 04cd91f..b322a45 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1786,20 +1786,6 @@
// client expresses a preference for FAST, but we get the final say
if (*flags & IAudioFlinger::TRACK_FAST) {
if (
- // either of these use cases:
- (
- // use case 1: shared buffer with any frame count
- (
- (sharedBuffer != 0)
- ) ||
- // use case 2: frame count is default or at least as large as HAL
- (
- // we formerly checked for a callback handler (non-0 tid),
- // but that is no longer required for TRANSFER_OBTAIN mode
- ((frameCount == 0) ||
- (frameCount >= mFrameCount))
- )
- ) &&
// PCM data
audio_is_linear_pcm(format) &&
// TODO: extract as a data library function that checks that a computationally
@@ -1817,14 +1803,14 @@
// FIXME test that MixerThread for this fast track has a capable output HAL
// FIXME add a permission test also?
) {
- // if frameCount not specified, then it defaults to fast mixer (HAL) frame count
- if (frameCount == 0) {
+ // static tracks can have any nonzero framecount, streaming tracks check against minimum.
+ if (sharedBuffer == 0) {
// read the fast track multiplier property the first time it is needed
int ok = pthread_once(&sFastTrackMultiplierOnce, sFastTrackMultiplierInit);
if (ok != 0) {
ALOGE("%s pthread_once failed: %d", __func__, ok);
}
- frameCount = mFrameCount * sFastTrackMultiplier;
+ frameCount = max(frameCount, mFrameCount * sFastTrackMultiplier); // incl framecount 0
}
ALOGV("AUDIO_OUTPUT_FLAG_FAST accepted: frameCount=%zu mFrameCount=%zu",
frameCount, mFrameCount);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 51df203..ae8cf15 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -5211,23 +5211,30 @@
// Modify the list of surround sound formats supported.
void AudioPolicyManager::filterSurroundFormats(FormatVector &formats) {
+ // TODO Change the ALOGIs to ALOGVs in this function after the feature is verified.
+
+ // TODO Set this based on Config properties.
+ const bool alwaysForceAC3 = true;
audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
ALOGI("%s: forced use = %d", __FUNCTION__, forceUse);
// Analyze original support for various formats.
- bool supportsRawSurround = false;
+ bool supportsAC3 = false;
+ bool supportsOtherSurround = false;
bool supportsIEC61937 = false;
for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
audio_format_t format = formats[formatIndex];
- ALOGI("%s: original formats: %#x", __FUNCTION__, format);
+ ALOGI("%s: original formats: 0x%08x", __FUNCTION__, format);
switch (format) {
case AUDIO_FORMAT_AC3:
+ supportsAC3 = true;
+ break;
case AUDIO_FORMAT_E_AC3:
case AUDIO_FORMAT_DTS:
case AUDIO_FORMAT_DTS_HD:
- supportsRawSurround = true;
+ supportsOtherSurround = true;
break;
case AUDIO_FORMAT_IEC61937:
supportsIEC61937 = true;
@@ -5236,55 +5243,67 @@
break;
}
}
- ALOGI("%s: supportsRawSurround = %d, supportsIEC61937 = %d",
- __FUNCTION__, supportsRawSurround, supportsIEC61937);
+ ALOGI("%s: original, supportsAC3 = %d, supportsOtherSurround = %d, supportsIEC61937 = %d",
+ __FUNCTION__, supportsAC3, supportsOtherSurround, supportsIEC61937);
// Modify formats based on surround preferences.
// If NEVER, remove support for surround formats.
- if ((forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER)
- && (supportsRawSurround || supportsIEC61937)) {
- // Remove surround sound related formats.
- for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
- audio_format_t format = formats[formatIndex];
- switch(format) {
- case AUDIO_FORMAT_AC3:
- case AUDIO_FORMAT_E_AC3:
- case AUDIO_FORMAT_DTS:
- case AUDIO_FORMAT_DTS_HD:
- case AUDIO_FORMAT_IEC61937:
- ALOGI("%s: remove %#x", __FUNCTION__, format);
- formats.removeAt(formatIndex);
- break;
- default:
- formatIndex++; // keep it
- break;
+ if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
+ if (supportsAC3 || supportsOtherSurround || supportsIEC61937) {
+ // Remove surround sound related formats.
+ for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
+ audio_format_t format = formats[formatIndex];
+ switch(format) {
+ case AUDIO_FORMAT_AC3:
+ case AUDIO_FORMAT_E_AC3:
+ case AUDIO_FORMAT_DTS:
+ case AUDIO_FORMAT_DTS_HD:
+ case AUDIO_FORMAT_IEC61937:
+ ALOGI("%s: remove format 0x%08x", __FUNCTION__, format);
+ formats.removeAt(formatIndex);
+ break;
+ default:
+ formatIndex++; // keep it
+ break;
+ }
}
+ supportsAC3 = false;
+ supportsOtherSurround = false;
+ supportsIEC61937 = false;
}
- supportsRawSurround = false;
- supportsIEC61937 = false;
- }
- // If ALWAYS, add support for raw surround formats if all are missing.
- // This assumes that if any of these formats are reported by the HAL
- // then the report is valid and should not be modified.
- if ((forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS)
- && !supportsRawSurround) {
- formats.add(AUDIO_FORMAT_AC3);
- formats.add(AUDIO_FORMAT_E_AC3);
- formats.add(AUDIO_FORMAT_DTS);
- formats.add(AUDIO_FORMAT_DTS_HD);
- supportsRawSurround = true;
- }
- // Add support for IEC61937 if raw surround supported.
- // The HAL could do this but add it here, just in case.
- if (supportsRawSurround && !supportsIEC61937) {
- formats.add(AUDIO_FORMAT_IEC61937);
- // supportsIEC61937 = true;
+ } else { // AUTO or ALWAYS
+ // Most TVs support AC3 even if they do not report it in the EDID.
+ if ((alwaysForceAC3 || (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS))
+ && !supportsAC3) {
+ formats.add(AUDIO_FORMAT_AC3);
+ supportsAC3 = true;
+ }
+
+ // If ALWAYS, add support for raw surround formats if all are missing.
+ // This assumes that if any of these formats are reported by the HAL
+ // then the report is valid and should not be modified.
+ if ((forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS)
+ && !supportsOtherSurround) {
+ formats.add(AUDIO_FORMAT_E_AC3);
+ formats.add(AUDIO_FORMAT_DTS);
+ formats.add(AUDIO_FORMAT_DTS_HD);
+ supportsOtherSurround = true;
+ }
+
+ // Add support for IEC61937 if any raw surround supported.
+ // The HAL could do this but add it here, just in case.
+ if ((supportsAC3 || supportsOtherSurround) && !supportsIEC61937) {
+ formats.add(AUDIO_FORMAT_IEC61937);
+ supportsIEC61937 = true;
+ }
}
// Just for debugging.
for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
audio_format_t format = formats[formatIndex];
- ALOGI("%s: final formats: %#x", __FUNCTION__, format);
+ ALOGI("%s: final formats: 0x%08x", __FUNCTION__, format);
}
+ ALOGI("%s: final, supportsAC3 = %d, supportsOtherSurround = %d, supportsIEC61937 = %d",
+ __FUNCTION__, supportsAC3, supportsOtherSurround, supportsIEC61937);
}
void AudioPolicyManager::updateAudioProfiles(audio_io_handle_t ioHandle,