summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-06-09 17:22:27 -0700
committerEric Laurent <elaurent@google.com>2014-06-19 10:05:57 -0700
commitab5cdbaf65ca509681d2726aacdf3ac8bfb6b3fa (patch)
tree0d406acdfea2d44cd430ef16ee2a25b7722e4b1d /services
parent29a8b2fe294a34ac7f004203426961a599e725ea (diff)
downloadframeworks_av-ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3fa.zip
frameworks_av-ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3fa.tar.gz
frameworks_av-ab5cdbaf65ca509681d2726aacdf3ac8bfb6b3fa.tar.bz2
AudioTrack: add support for compressed audio
Add support for compressed audio playback by use of an AudioTrack attached to a direct output thread. Bug: 9428304. Change-Id: I4a61be9cf0e31003ca85935d6e0ee38ca8192e03
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/PlaybackTracks.h1
-rwxr-xr-xservices/audioflinger/Threads.cpp37
-rw-r--r--services/audioflinger/Tracks.cpp6
-rw-r--r--services/audiopolicy/AudioPolicyManager.cpp5
4 files changed, 33 insertions, 16 deletions
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 6130084..79bdfe8 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -54,6 +54,7 @@ public:
return mStreamType;
}
bool isOffloaded() const { return (mFlags & IAudioFlinger::TRACK_OFFLOAD) != 0; }
+ bool isDirect() const { return (mFlags & IAudioFlinger::TRACK_DIRECT) != 0; }
status_t setParameters(const String8& keyValuePairs);
status_t attachAuxEffect(int EffectId);
void setAuxBuffer(int EffectId, int32_t *buffer);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d6390b1..8ce819c 100755
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1660,7 +1660,7 @@ bool AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track)
track->mState = TrackBase::STOPPED;
if (!trackActive) {
removeTrack_l(track);
- } else if (track->isFastTrack() || track->isOffloaded()) {
+ } else if (track->isFastTrack() || track->isOffloaded() || track->isDirect()) {
track->mState = TrackBase::STOPPING_1;
}
@@ -1868,7 +1868,9 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l()
}
mNormalFrameCount = multiplier * mFrameCount;
// round up to nearest 16 frames to satisfy AudioMixer
- mNormalFrameCount = (mNormalFrameCount + 15) & ~15;
+ if (mType == MIXER || mType == DUPLICATING) {
+ mNormalFrameCount = (mNormalFrameCount + 15) & ~15;
+ }
ALOGI("HAL output buffer size %u frames, normal sink buffer size %u frames", mFrameCount,
mNormalFrameCount);
@@ -2656,7 +2658,7 @@ status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)
if (mNormalSink != 0) {
return mNormalSink->getTimestamp(timestamp);
}
- if (mType == OFFLOAD && mOutput->stream->get_presentation_position) {
+ if ((mType == OFFLOAD || mType == DIRECT) && mOutput->stream->get_presentation_position) {
uint64_t position64;
int ret = mOutput->stream->get_presentation_position(
mOutput->stream, &position64, &timestamp.mTime);
@@ -3947,14 +3949,16 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
// The first time a track is added we wait
// for all its buffers to be filled before processing it
uint32_t minFrames;
- if ((track->sharedBuffer() == 0) && !track->isStopped() && !track->isPausing()) {
+ if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing()) {
minFrames = mNormalFrameCount;
} else {
minFrames = 1;
}
- if ((track->framesReady() >= minFrames) && track->isReady() &&
- !track->isPaused() && !track->isTerminated())
+ ALOGI("prepareTracks_l minFrames %d state %d frames ready %d, ",
+ minFrames, track->mState, track->framesReady());
+ if ((track->framesReady() >= minFrames) && track->isReady() && !track->isPaused() &&
+ !track->isStopping_2() && !track->isStopped())
{
ALOGVV("track %d s=%08x [OK]", track->name(), cblk->mServer);
@@ -3981,17 +3985,26 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
if (!mEffectChains.isEmpty() && last) {
mEffectChains[0]->clearInputBuffer();
}
-
- ALOGVV("track %d s=%08x [NOT READY]", track->name(), cblk->mServer);
- if ((track->sharedBuffer() != 0) || track->isTerminated() ||
- track->isStopped() || track->isPaused()) {
+ if (track->isStopping_1()) {
+ track->mState = TrackBase::STOPPING_2;
+ }
+ if ((track->sharedBuffer() != 0) || track->isStopped() ||
+ track->isStopping_2() || track->isPaused()) {
// We have consumed all the buffers of this track.
// Remove it from the list of active tracks.
- // TODO: implement behavior for compressed audio
- size_t audioHALFrames = (latency_l() * mSampleRate) / 1000;
+ size_t audioHALFrames;
+ if (audio_is_linear_pcm(mFormat)) {
+ audioHALFrames = (latency_l() * mSampleRate) / 1000;
+ } else {
+ audioHALFrames = 0;
+ }
+
size_t framesWritten = mBytesWritten / mFrameSize;
if (mStandby || !last ||
track->presentationComplete(framesWritten, audioHALFrames)) {
+ if (track->isStopping_2()) {
+ track->mState = TrackBase::STOPPED;
+ }
if (track->isStopped()) {
track->reset();
}
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1e906ad..4fbb973 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -706,7 +706,7 @@ void AudioFlinger::PlaybackThread::Track::stop()
if (playbackThread->mActiveTracks.indexOf(this) < 0) {
reset();
mState = STOPPED;
- } else if (!isFastTrack() && !isOffloaded()) {
+ } else if (!isFastTrack() && !isOffloaded() && !isDirect()) {
mState = STOPPED;
} else {
// For fast tracks prepareTracks_l() will set state to STOPPING_2
@@ -860,7 +860,7 @@ status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& times
}
Mutex::Autolock _l(thread->mLock);
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
- if (!isOffloaded()) {
+ if (!isOffloaded() && !isDirect()) {
if (!playbackThread->mLatchQValid) {
mPreviousValid = false;
return INVALID_OPERATION;
@@ -980,8 +980,6 @@ bool AudioFlinger::PlaybackThread::Track::presentationComplete(size_t framesWrit
}
if (framesWritten >= mPresentationCompleteFrames || isOffloaded()) {
- ALOGV("presentationComplete() session %d complete: framesWritten %d",
- mSessionId, framesWritten);
triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
mAudioTrackServerProxy->setStreamEndDone();
return true;
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 70dcb4c..aa810bc 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -122,6 +122,11 @@ const StringToEnum sFormatNameToEnumTable[] = {
STRING_TO_ENUM(AUDIO_FORMAT_MP3),
STRING_TO_ENUM(AUDIO_FORMAT_AAC),
STRING_TO_ENUM(AUDIO_FORMAT_VORBIS),
+ STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1),
+ STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2),
+ STRING_TO_ENUM(AUDIO_FORMAT_OPUS),
+ STRING_TO_ENUM(AUDIO_FORMAT_AC3),
+ STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
};
const StringToEnum sOutChannelsNameToEnumTable[] = {