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

Commit e7e676fd authored by Andy Hung's avatar Andy Hung
Browse files

Convert AudioFlinger mSinkBuffer to flexible format



Change-Id: I618d9c99a5f6f8c8d6a9f4b2d19e82c9ddc3b06e
Signed-off-by: default avatarAndy Hung <hunga@google.com>
parent 98ef978d
Loading
Loading
Loading
Loading
+35 −19
Original line number Diff line number Diff line
@@ -1145,7 +1145,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
AudioFlinger::PlaybackThread::~PlaybackThread()
{
    mAudioFlinger->unregisterWriter(mNBLogWriter);
    delete[] mSinkBuffer;
    free(mSinkBuffer);
    free(mMixerBuffer);
    free(mEffectBuffer);
}
@@ -1782,11 +1782,13 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l()
    ALOGI("HAL output buffer size %u frames, normal sink buffer size %u frames", mFrameCount,
            mNormalFrameCount);

    delete[] mSinkBuffer;
    size_t normalBufferSize = mNormalFrameCount * mFrameSize;
    // For historical reasons mSinkBuffer is int16_t[], but mFrameSize can be odd (such as 1)
    mSinkBuffer = new int16_t[(normalBufferSize + 1) >> 1];
    memset(mSinkBuffer, 0, normalBufferSize);
    // mSinkBuffer is the sink buffer.  Size is always multiple-of-16 frames.
    // Originally this was int16_t[] array, need to remove legacy implications.
    free(mSinkBuffer);
    mSinkBuffer = NULL;
    const size_t sinkBufferSize = mNormalFrameCount * mChannelCount
            * audio_bytes_per_sample(mFormat);
    (void)posix_memalign(&mSinkBuffer, 32, sinkBufferSize);

    // We resize the mMixerBuffer according to the requirements of the sink buffer which
    // drives the output.
@@ -1984,12 +1986,12 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
    mLastWriteTime = systemTime();
    mInWrite = true;
    ssize_t bytesWritten;
    const size_t offset = mCurrentWriteLength - mBytesRemaining;

    // If an NBAIO sink is present, use it to write the normal mixer's submix
    if (mNormalSink != 0) {
#define mBitShift 2 // FIXME
        size_t count = mBytesRemaining >> mBitShift;
        size_t offset = (mCurrentWriteLength - mBytesRemaining) >> 1;
        const size_t count = mBytesRemaining / mFrameSize;

        ATRACE_BEGIN("write");
        // update the setpoint when AudioFlinger::mScreenState changes
        uint32_t screenState = AudioFlinger::mScreenState;
@@ -2001,10 +2003,10 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
                        (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
            }
        }
        ssize_t framesWritten = mNormalSink->write(mSinkBuffer + offset, count);
        ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);
        ATRACE_END();
        if (framesWritten > 0) {
            bytesWritten = framesWritten << mBitShift;
            bytesWritten = framesWritten * mFrameSize;
        } else {
            bytesWritten = framesWritten;
        }
@@ -2019,7 +2021,7 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
    // otherwise use the HAL / AudioStreamOut directly
    } else {
        // Direct output and offload threads
        size_t offset = (mCurrentWriteLength - mBytesRemaining);

        if (mUseAsyncWrite) {
            ALOGW_IF(mWriteAckSequence & 1, "threadLoop_write(): out of sequence write request");
            mWriteAckSequence += 2;
@@ -2111,8 +2113,8 @@ void AudioFlinger::PlaybackThread::invalidateTracks(audio_stream_type_t streamTy
status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& chain)
{
    int session = chain->sessionId();
    int16_t *buffer = mEffectBufferEnabled
            ? reinterpret_cast<int16_t*>(mEffectBuffer) : mSinkBuffer;
    int16_t* buffer = reinterpret_cast<int16_t*>(mEffectBufferEnabled
            ? mEffectBuffer : mSinkBuffer);
    bool ownsBuffer = false;

    ALOGV("addEffectChain_l() %p on thread %p for session %d", chain.get(), this, session);
@@ -2152,8 +2154,8 @@ status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& c
    }

    chain->setInBuffer(buffer, ownsBuffer);
    chain->setOutBuffer(mEffectBufferEnabled
            ? reinterpret_cast<int16_t*>(mEffectBuffer) : mSinkBuffer);
    chain->setOutBuffer(reinterpret_cast<int16_t*>(mEffectBufferEnabled
            ? mEffectBuffer : mSinkBuffer));
    // Effect chain for session AUDIO_SESSION_OUTPUT_STAGE is inserted at end of effect
    // chains list in order to be processed last as it contains output stage effects
    // Effect chain for session AUDIO_SESSION_OUTPUT_MIX is inserted before
@@ -2203,7 +2205,7 @@ size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>&
            for (size_t i = 0; i < mTracks.size(); ++i) {
                sp<Track> track = mTracks[i];
                if (session == track->sessionId()) {
                    track->setMainBuffer(mSinkBuffer);
                    track->setMainBuffer(reinterpret_cast<int16_t*>(mSinkBuffer));
                    chain->decTrackCnt();
                }
            }
@@ -4471,7 +4473,15 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()
ssize_t AudioFlinger::DuplicatingThread::threadLoop_write()
{
    for (size_t i = 0; i < outputTracks.size(); i++) {
        outputTracks[i]->write(mSinkBuffer, writeFrames);
        // We convert the duplicating thread format to AUDIO_FORMAT_PCM_16_BIT
        // for delivery downstream as needed. This in-place conversion is safe as
        // AUDIO_FORMAT_PCM_16_BIT is smaller than any other supported format
        // (AUDIO_FORMAT_PCM_8_BIT is not allowed here).
        if (mFormat != AUDIO_FORMAT_PCM_16_BIT) {
            memcpy_by_audio_format(mSinkBuffer, AUDIO_FORMAT_PCM_16_BIT,
                    mSinkBuffer, mFormat, writeFrames * mChannelCount);
        }
        outputTracks[i]->write(reinterpret_cast<int16_t*>(mSinkBuffer), writeFrames);
    }
    mStandby = false;
    return (ssize_t)mSinkBufferSize;
@@ -4500,10 +4510,16 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
    Mutex::Autolock _l(mLock);
    // FIXME explain this formula
    size_t frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate();
    // OutputTrack is forced to AUDIO_FORMAT_PCM_16_BIT regardless of mFormat
    // due to current usage case and restrictions on the AudioBufferProvider.
    // Actual buffer conversion is done in threadLoop_write().
    //
    // TODO: This may change in the future, depending on multichannel
    // (and non int16_t*) support on AF::PlaybackThread::OutputTrack
    OutputTrack *outputTrack = new OutputTrack(thread,
                                            this,
                                            mSampleRate,
                                            mFormat,
                                            AUDIO_FORMAT_PCM_16_BIT,
                                            mChannelMask,
                                            frameCount,
                                            IPCThreadState::self()->getCallingUid());
+6 −3
Original line number Diff line number Diff line
@@ -450,8 +450,11 @@ public:
    virtual     String8     getParameters(const String8& keys);
    virtual     void        audioConfigChanged_l(int event, int param = 0);
                status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
                // TODO: rename mixBuffer() to sinkBuffer() or try to remove external use.
                int16_t     *mixBuffer() const { return mSinkBuffer; };
                // FIXME rename mixBuffer() to sinkBuffer() and remove int16_t* dependency.
                // Consider also removing and passing an explicit mMainBuffer initialization
                // parameter to AF::PlaybackThread::Track::Track().
                int16_t     *mixBuffer() const {
                    return reinterpret_cast<int16_t *>(mSinkBuffer); };

    virtual     void detachAuxEffect_l(int effectId);
                status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track,
@@ -482,7 +485,7 @@ protected:
    // updated by readOutputParameters_l()
    size_t                          mNormalFrameCount;  // normal mixer and effects

    int16_t*                        mSinkBuffer;         // frame size aligned sink buffer
    void*                           mSinkBuffer;         // frame size aligned sink buffer

    // TODO:
    // Rearrange the buffer info into a struct/class with