Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8cf2960 authored by John Grossman's avatar John Grossman
Browse files

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: default avatarJohn Grossman <johngro@google.com>
parent c157673a
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -446,7 +446,7 @@ public:
     */
            status_t dump(int fd, const Vector<String16>& args) const;

private:
protected:
    /* copying audio tracks is not allowed */
                        AudioTrack(const AudioTrack& other);
            AudioTrack& operator = (const AudioTrack& other);
@@ -518,10 +518,33 @@ private:
    int                     mAuxEffectId;
    mutable Mutex           mLock;
    status_t                mRestoreStatus;
    bool                    mIsTimed;
    int                     mPreviousPriority;          // before start()
    int                     mPreviousSchedulingGroup;
};

class TimedAudioTrack : public AudioTrack
{
public:
    TimedAudioTrack();

    /* allocate a shared memory buffer that can be passed to queueTimedBuffer */
    status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer);

    /* queue a buffer obtained via allocateTimedBuffer for playback at the
       given timestamp.  PTS units a microseconds on the media time timeline.
       The media time transform (set with setMediaTimeTransform) set by the
       audio producer will handle converting from media time to local time
       (perhaps going through the common time timeline in the case of
       synchronized multiroom audio case) */
    status_t queueTimedBuffer(const sp<IMemory>& buffer, int64_t pts);

    /* define a transform between media time and either common time or
       local time */
    enum TargetTimeline {LOCAL_TIME, COMMON_TIME};
    status_t setMediaTimeTransform(const LinearTransform& xform,
                                   TargetTimeline target);
};

}; // namespace android

+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ public:
                                uint32_t flags,
                                const sp<IMemory>& sharedBuffer,
                                audio_io_handle_t output,
                                bool isTimed,
                                int *sessionId,
                                status_t *status) = 0;

+18 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
#include <utils/Errors.h>
#include <binder/IInterface.h>
#include <binder/IMemory.h>

#include <utils/LinearTransform.h>

namespace android {

@@ -71,6 +71,23 @@ public:
     */
    virtual status_t    attachAuxEffect(int effectId) = 0;


    /* Allocate a shared memory buffer suitable for holding timed audio
       samples */
    virtual status_t    allocateTimedBuffer(size_t size,
                                            sp<IMemory>* buffer) = 0;

    /* Queue a buffer obtained via allocateTimedBuffer for playback at the given
       timestamp */
    virtual status_t    queueTimedBuffer(const sp<IMemory>& buffer,
                                         int64_t pts) = 0;

    /* Define the linear transform that will be applied to the timestamps
       given to queueTimedBuffer (which are expressed in media time).
       Target specifies whether this transform converts media time to local time
       or Tungsten time. The values for target are defined in AudioTrack.h */
    virtual status_t    setMediaTimeTransform(const LinearTransform& xform,
                                              int target) = 0;
};

// ----------------------------------------------------------------------------
+78 −3
Original line number Diff line number Diff line
@@ -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;
+4 −1
Original line number Diff line number Diff line
@@ -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());
Loading