summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2012-03-19 13:38:30 -0700
committerGlenn Kasten <gkasten@google.com>2012-04-02 11:26:18 -0700
commit73d227557ba5192735356bacab9f77b44980793b (patch)
tree7c7f0e72f5ffa5ff5920c35c3ad03b6b821e831f /services
parent2d6486f9112a6f0d23f17eaaad94bac62e16caab (diff)
AudioFlinger track flags and server's fast policy
Change-Id: I72358c8e6829d173b3e60ced8a8babc089869fac
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp62
-rw-r--r--services/audioflinger/AudioFlinger.h10
2 files changed, 63 insertions, 9 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index fb5a7e17..ad386f6f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -504,7 +504,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(
bool isTimed = (flags & IAudioFlinger::TRACK_TIMED) != 0;
track = thread->createTrack_l(client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, lSessionId, isTimed, &lStatus);
+ channelMask, frameCount, sharedBuffer, lSessionId, flags, &lStatus);
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
@@ -1608,12 +1608,50 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
- bool isTimed,
+ IAudioFlinger::track_flags_t flags,
status_t *status)
{
sp<Track> track;
status_t lStatus;
+ bool isTimed = (flags & IAudioFlinger::TRACK_TIMED) != 0;
+
+ // client expresses a preference for FAST, but we get the final say
+ if ((flags & IAudioFlinger::TRACK_FAST) &&
+ !(
+ // not timed
+ (!isTimed) &&
+ // either of these use cases:
+ (
+ // use case 1: shared buffer with any frame count
+ (
+ (sharedBuffer != 0)
+ ) ||
+ // use case 2: callback handler and small power-of-2 frame count
+ (
+ // unfortunately we can't verify that there's a callback until start()
+ // FIXME supported frame counts should not be hard-coded
+ (
+ (frameCount == 128) ||
+ (frameCount == 256) ||
+ (frameCount == 512)
+ )
+ )
+ ) &&
+ // PCM data
+ audio_is_linear_pcm(format) &&
+ // mono or stereo
+ ( (channelMask == AUDIO_CHANNEL_OUT_MONO) ||
+ (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) &&
+ // hardware sample rate
+ (sampleRate == mSampleRate)
+ // FIXME test that MixerThread for this fast track has a capable output HAL
+ // FIXME add a permission test also?
+ ) ) {
+ ALOGW("AUDIO_POLICY_OUTPUT_FLAG_FAST denied");
+ flags &= ~IAudioFlinger::TRACK_FAST;
+ }
+
if (mType == DIRECT) {
if ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
if (sampleRate != mSampleRate || format != mFormat || channelMask != mChannelMask) {
@@ -1661,7 +1699,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
if (!isTimed) {
track = new Track(this, client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, sessionId);
+ channelMask, frameCount, sharedBuffer, sessionId, flags);
} else {
track = TimedTrack::create(this, client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, sessionId);
@@ -3550,7 +3588,8 @@ AudioFlinger::PlaybackThread::Track::Track(
uint32_t channelMask,
int frameCount,
const sp<IMemory>& sharedBuffer,
- int sessionId)
+ int sessionId,
+ IAudioFlinger::track_flags_t flags)
: TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer, sessionId),
mMute(false),
// mFillingUpStatus ?
@@ -3561,7 +3600,8 @@ AudioFlinger::PlaybackThread::Track::Track(
mMainBuffer(thread->mixBuffer()),
mAuxBuffer(NULL),
mAuxEffectId(0), mHasVolumeController(false),
- mPresentationCompleteFrames(0)
+ mPresentationCompleteFrames(0),
+ mFlags(flags)
{
if (mCblk != NULL) {
// NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
@@ -3707,6 +3747,13 @@ status_t AudioFlinger::PlaybackThread::Track::start(pid_t tid,
status_t status = NO_ERROR;
ALOGV("start(%d), calling pid %d session %d tid %d",
mName, IPCThreadState::self()->getCallingPid(), mSessionId, tid);
+ // check for use case 2 with missing callback
+ if (isFastTrack() && (mSharedBuffer == 0) && (tid == 0)) {
+ ALOGW("AUDIO_POLICY_OUTPUT_FLAG_FAST denied");
+ mFlags &= ~IAudioFlinger::TRACK_FAST;
+ // FIXME the track must be invalidated and moved to another thread or
+ // attached directly to the normal mixer now
+ }
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
Mutex::Autolock _l(thread->mLock);
@@ -3922,7 +3969,7 @@ AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
const sp<IMemory>& sharedBuffer,
int sessionId)
: Track(thread, client, streamType, sampleRate, format, channelMask,
- frameCount, sharedBuffer, sessionId),
+ frameCount, sharedBuffer, sessionId, IAudioFlinger::TRACK_TIMED),
mTimedSilenceBuffer(NULL),
mTimedSilenceBufferSize(0),
mTimedAudioOutputOnTime(false),
@@ -4400,7 +4447,8 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
audio_format_t format,
uint32_t channelMask,
int frameCount)
- : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount, NULL, 0),
+ : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
+ NULL, 0, IAudioFlinger::TRACK_DEFAULT),
mActive(false), mSourceThread(sourceThread)
{
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 3051514e..de59f6db 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -662,7 +662,8 @@ private:
uint32_t channelMask,
int frameCount,
const sp<IMemory>& sharedBuffer,
- int sessionId);
+ int sessionId,
+ IAudioFlinger::track_flags_t flags);
virtual ~Track();
void dump(char* buffer, size_t size);
@@ -689,6 +690,9 @@ private:
int16_t *mainBuffer() const { return mMainBuffer; }
int auxEffectId() const { return mAuxEffectId; }
+ bool isFastTrack() const
+ { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
+
protected:
// for numerous
friend class PlaybackThread;
@@ -742,6 +746,8 @@ private:
bool mHasVolumeController;
size_t mPresentationCompleteFrames; // number of frames written to the audio HAL
// when this track will be fully rendered
+ private:
+ IAudioFlinger::track_flags_t mFlags;
}; // end of Track
class TimedTrack : public Track {
@@ -913,7 +919,7 @@ public:
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
- bool isTimed,
+ IAudioFlinger::track_flags_t flags,
status_t *status);
AudioStreamOut* getOutput() const;