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

Commit cea17f26 authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "Convert AudioFlinger mSinkBuffer to flexible format"

parents c644345b e7e676fd
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