summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorJohn Grossman <johngro@google.com>2012-02-08 16:37:41 -0800
committerJohn Grossman <johngro@google.com>2012-02-16 13:45:11 -0800
commit4ff14bae91075eb274eb1c2975982358946e7e63 (patch)
treee9e54fddb9832d30b69c2a11c9ed2884397f2f95 /media
parent951bd8d1ad9581a414e171ad8605a9515d0ad667 (diff)
downloadframeworks_av-4ff14bae91075eb274eb1c2975982358946e7e63.zip
frameworks_av-4ff14bae91075eb274eb1c2975982358946e7e63.tar.gz
frameworks_av-4ff14bae91075eb274eb1c2975982358946e7e63.tar.bz2
Upintegrate Audio Flinger changes from ICS_AAH
Bring in changes to audio flinger made to support timed audio tracks and HW master volume control. Change-Id: Ide52d48809bdbed13acf35fd59b24637e35064ae Signed-off-by: John Grossman <johngro@google.com>
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/AudioTrack.cpp81
-rw-r--r--media/libmedia/IAudioFlinger.cpp5
-rw-r--r--media/libmedia/IAudioTrack.cpp81
3 files changed, 161 insertions, 6 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index aead9a1..74c97ed 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -80,7 +80,9 @@ status_t AudioTrack::getMinFrameCount(
AudioTrack::AudioTrack()
: mStatus(NO_INIT),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
+ mIsTimed(false),
+ mPreviousPriority(ANDROID_PRIORITY_NORMAL),
+ mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
{
}
@@ -96,7 +98,9 @@ AudioTrack::AudioTrack(
int notificationFrames,
int sessionId)
: mStatus(NO_INIT),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
+ mIsTimed(false),
+ mPreviousPriority(ANDROID_PRIORITY_NORMAL),
+ mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
@@ -134,7 +138,9 @@ AudioTrack::AudioTrack(
int notificationFrames,
int sessionId)
: mStatus(NO_INIT),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
+ mIsTimed(false),
+ mPreviousPriority(ANDROID_PRIORITY_NORMAL),
+ mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
{
mStatus = set(streamType, sampleRate, format, channelMask,
0, flags, cbf, user, notificationFrames,
@@ -540,6 +546,10 @@ status_t AudioTrack::setSampleRate(int rate)
{
int afSamplingRate;
+ if (mIsTimed) {
+ return INVALID_OPERATION;
+ }
+
if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {
return NO_INIT;
}
@@ -553,6 +563,10 @@ status_t AudioTrack::setSampleRate(int rate)
uint32_t AudioTrack::getSampleRate() const
{
+ if (mIsTimed) {
+ return INVALID_OPERATION;
+ }
+
AutoMutex lock(mLock);
return mCblk->sampleRate;
}
@@ -578,6 +592,10 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou
return NO_ERROR;
}
+ if (mIsTimed) {
+ return INVALID_OPERATION;
+ }
+
if (loopStart >= loopEnd ||
loopEnd - loopStart > cblk->frameCount ||
cblk->server > loopStart) {
@@ -641,6 +659,8 @@ status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) const
status_t AudioTrack::setPosition(uint32_t position)
{
+ if (mIsTimed) return INVALID_OPERATION;
+
AutoMutex lock(mLock);
if (!stopped_l()) return INVALID_OPERATION;
@@ -791,6 +811,7 @@ status_t AudioTrack::createTrack_l(
((uint16_t)flags) << 16,
sharedBuffer,
output,
+ mIsTimed,
&mSessionId,
&status);
@@ -957,6 +978,7 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
{
if (mSharedBuffer != 0) return INVALID_OPERATION;
+ if (mIsTimed) return INVALID_OPERATION;
if (ssize_t(userSize) < 0) {
// Sanity-check: user is most-likely passing an error code, and it would
@@ -1013,6 +1035,59 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
// -------------------------------------------------------------------------
+TimedAudioTrack::TimedAudioTrack() {
+ mIsTimed = true;
+}
+
+status_t TimedAudioTrack::allocateTimedBuffer(size_t size, sp<IMemory>* buffer)
+{
+ status_t result = UNKNOWN_ERROR;
+
+ // If the track is not invalid already, try to allocate a buffer. alloc
+ // fails indicating that the server is dead, flag the track as invalid so
+ // we can attempt to restore in in just a bit.
+ if (!(mCblk->flags & CBLK_INVALID_MSK)) {
+ result = mAudioTrack->allocateTimedBuffer(size, buffer);
+ if (result == DEAD_OBJECT) {
+ android_atomic_or(CBLK_INVALID_ON, &mCblk->flags);
+ }
+ }
+
+ // If the track is invalid at this point, attempt to restore it. and try the
+ // allocation one more time.
+ if (mCblk->flags & CBLK_INVALID_MSK) {
+ mCblk->lock.lock();
+ result = restoreTrack_l(mCblk, false);
+ mCblk->lock.unlock();
+
+ if (result == OK)
+ result = mAudioTrack->allocateTimedBuffer(size, buffer);
+ }
+
+ return result;
+}
+
+status_t TimedAudioTrack::queueTimedBuffer(const sp<IMemory>& buffer,
+ int64_t pts)
+{
+ // restart track if it was disabled by audioflinger due to previous underrun
+ if (mActive && (mCblk->flags & CBLK_DISABLED_MSK)) {
+ android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
+ ALOGW("queueTimedBuffer() track %p disabled, restarting", this);
+ mAudioTrack->start(0);
+ }
+
+ return mAudioTrack->queueTimedBuffer(buffer, pts);
+}
+
+status_t TimedAudioTrack::setMediaTimeTransform(const LinearTransform& xform,
+ TargetTimeline target)
+{
+ return mAudioTrack->setMediaTimeTransform(xform, target);
+}
+
+// -------------------------------------------------------------------------
+
bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
{
Buffer audioBuffer;
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 4507e5d..ebadbfa 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -90,6 +90,7 @@ public:
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
+ bool isTimed,
int *sessionId,
status_t *status)
{
@@ -105,6 +106,7 @@ public:
data.writeInt32(flags);
data.writeStrongBinder(sharedBuffer->asBinder());
data.writeInt32((int32_t) output);
+ data.writeInt32(isTimed);
int lSessionId = 0;
if (sessionId != NULL) {
lSessionId = *sessionId;
@@ -689,11 +691,12 @@ status_t BnAudioFlinger::onTransact(
uint32_t flags = data.readInt32();
sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
+ bool isTimed = data.readInt32();
int sessionId = data.readInt32();
status_t status;
sp<IAudioTrack> track = createTrack(pid,
(audio_stream_type_t) streamType, sampleRate, format,
- channelCount, bufferCount, flags, buffer, output, &sessionId, &status);
+ channelCount, bufferCount, flags, buffer, output, isTimed, &sessionId, &status);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(track->asBinder());
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp
index a7958de..28ebbbf 100644
--- a/media/libmedia/IAudioTrack.cpp
+++ b/media/libmedia/IAudioTrack.cpp
@@ -35,7 +35,10 @@ enum {
FLUSH,
MUTE,
PAUSE,
- ATTACH_AUX_EFFECT
+ ATTACH_AUX_EFFECT,
+ ALLOCATE_TIMED_BUFFER,
+ QUEUE_TIMED_BUFFER,
+ SET_MEDIA_TIME_TRANSFORM,
};
class BpAudioTrack : public BpInterface<IAudioTrack>
@@ -114,6 +117,52 @@ public:
}
return status;
}
+
+ virtual status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ data.writeInt32(size);
+ status_t status = remote()->transact(ALLOCATE_TIMED_BUFFER,
+ data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ if (status == NO_ERROR) {
+ *buffer = interface_cast<IMemory>(reply.readStrongBinder());
+ }
+ }
+ return status;
+ }
+
+ virtual status_t queueTimedBuffer(const sp<IMemory>& buffer,
+ int64_t pts) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ data.writeStrongBinder(buffer->asBinder());
+ data.writeInt64(pts);
+ status_t status = remote()->transact(QUEUE_TIMED_BUFFER,
+ data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ }
+ return status;
+ }
+
+ virtual status_t setMediaTimeTransform(const LinearTransform& xform,
+ int target) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ data.writeInt64(xform.a_zero);
+ data.writeInt64(xform.b_zero);
+ data.writeInt32(xform.a_to_b_numer);
+ data.writeInt32(xform.a_to_b_denom);
+ data.writeInt32(target);
+ status_t status = remote()->transact(SET_MEDIA_TIME_TRANSFORM,
+ data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
@@ -159,10 +208,38 @@ status_t BnAudioTrack::onTransact(
reply->writeInt32(attachAuxEffect(data.readInt32()));
return NO_ERROR;
} break;
+ case ALLOCATE_TIMED_BUFFER: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ sp<IMemory> buffer;
+ status_t status = allocateTimedBuffer(data.readInt32(), &buffer);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeStrongBinder(buffer->asBinder());
+ }
+ return NO_ERROR;
+ } break;
+ case QUEUE_TIMED_BUFFER: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ sp<IMemory> buffer = interface_cast<IMemory>(
+ data.readStrongBinder());
+ uint64_t pts = data.readInt64();
+ reply->writeInt32(queueTimedBuffer(buffer, pts));
+ return NO_ERROR;
+ } break;
+ case SET_MEDIA_TIME_TRANSFORM: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ LinearTransform xform;
+ xform.a_zero = data.readInt64();
+ xform.b_zero = data.readInt64();
+ xform.a_to_b_numer = data.readInt32();
+ xform.a_to_b_denom = data.readInt32();
+ int target = data.readInt32();
+ reply->writeInt32(setMediaTimeTransform(xform, target));
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
}; // namespace android
-