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

Commit 703a7fb7 authored by Phil Burk's avatar Phil Burk Committed by Android Git Automerger
Browse files

am b9f72ab0: Merge "AudioFlinger: fix repeated underruns for compressed audio" into mnc-dev

* commit 'b9f72ab0':
  AudioFlinger: fix repeated underruns for compressed audio
parents 2d941323 b9f72ab0
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -143,9 +143,19 @@ status_t AudioStreamOut::open(
    return status;
}

size_t AudioStreamOut::getFrameSize()
audio_format_t AudioStreamOut::getFormat() const
{
    return mHalFrameSize;
    return stream->common.get_format(&stream->common);
}

uint32_t AudioStreamOut::getSampleRate() const
{
    return stream->common.get_sample_rate(&stream->common);
}

audio_channel_mask_t AudioStreamOut::getChannelMask() const
{
    return stream->common.get_channels(&stream->common);
}

int AudioStreamOut::flush()
@@ -165,7 +175,6 @@ int AudioStreamOut::standby()
    ALOG_ASSERT(stream != NULL);
    mRenderPosition = 0;
    mFramesWrittenAtStandby = mFramesWritten;
    ALOGI("AudioStreamOut::standby(), mFramesWrittenAtStandby = %llu", mFramesWrittenAtStandby);
    return stream->common.standby(&stream->common);
}

+22 −1
Original line number Diff line number Diff line
@@ -75,7 +75,28 @@ public:
    */
    virtual ssize_t write(const void *buffer, size_t bytes);

    virtual size_t getFrameSize();
    /**
     * @return frame size from the perspective of the application and the AudioFlinger.
     */
    virtual size_t getFrameSize() const { return mHalFrameSize; }

    /**
     * @return format from the perspective of the application and the AudioFlinger.
     */
    virtual audio_format_t getFormat() const;

    /**
     * The HAL may be running at a higher sample rate if, for example, playing wrapped EAC3.
     * @return sample rate from the perspective of the application and the AudioFlinger.
     */
    virtual uint32_t getSampleRate() const;

    /**
     * The HAL is in stereo mode when playing multi-channel compressed audio over HDMI.
     * @return channel mask from the perspective of the application and the AudioFlinger.
     */
    virtual audio_channel_mask_t getChannelMask() const;


    virtual status_t flush();
    virtual status_t standby();
+9 −7
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@ SpdifStreamOut::SpdifStreamOut(AudioHwDevice *dev,
            audio_format_t format)
        : AudioStreamOut(dev,flags)
        , mSpdifEncoder(this, format)
        , mApplicationFormat(AUDIO_FORMAT_DEFAULT)
        , mApplicationSampleRate(0)
        , mApplicationChannelMask(0)
{
}

@@ -48,6 +51,10 @@ status_t SpdifStreamOut::open(
{
    struct audio_config customConfig = *config;

    mApplicationFormat = config->format;
    mApplicationSampleRate = config->sample_rate;
    mApplicationChannelMask = config->channel_mask;

    // Some data bursts run at a higher sample rate.
    // TODO Move this into the audio_utils as a static method.
    switch(config->format) {
@@ -106,20 +113,15 @@ int SpdifStreamOut::standby()
    return AudioStreamOut::standby();
}

size_t SpdifStreamOut::getFrameSize()
{
    return sizeof(int8_t);
}

ssize_t SpdifStreamOut::writeDataBurst(const void* buffer, size_t bytes)
{
    return AudioStreamOut::write(buffer, bytes);
}

ssize_t SpdifStreamOut::write(const void* buffer, size_t bytes)
ssize_t SpdifStreamOut::write(const void* buffer, size_t numBytes)
{
    // Write to SPDIF wrapper. It will call back to writeDataBurst().
    return mSpdifEncoder.write(buffer, bytes);
    return mSpdifEncoder.write(buffer, numBytes);
}

} // namespace android
+24 −1
Original line number Diff line number Diff line
@@ -64,7 +64,27 @@ public:
    */
    virtual ssize_t write(const void* buffer, size_t bytes);

    virtual size_t getFrameSize();
    /**
     * @return frame size from the perspective of the application and the AudioFlinger.
     */
    virtual size_t getFrameSize() const { return sizeof(int8_t); }

    /**
     * @return format from the perspective of the application and the AudioFlinger.
     */
    virtual audio_format_t getFormat() const { return mApplicationFormat; }

    /**
     * The HAL may be running at a higher sample rate if, for example, playing wrapped EAC3.
     * @return sample rate from the perspective of the application and the AudioFlinger.
     */
    virtual uint32_t getSampleRate() const { return mApplicationSampleRate; }

    /**
     * The HAL is in stereo mode when playing multi-channel compressed audio over HDMI.
     * @return channel mask from the perspective of the application and the AudioFlinger.
     */
    virtual audio_channel_mask_t getChannelMask() const { return mApplicationChannelMask; }

    virtual status_t flush();
    virtual status_t standby();
@@ -89,6 +109,9 @@ private:
    };

    MySPDIFEncoder       mSpdifEncoder;
    audio_format_t       mApplicationFormat;
    uint32_t             mApplicationSampleRate;
    audio_channel_mask_t mApplicationChannelMask;

    ssize_t  writeDataBurst(const void* data, size_t bytes);
    ssize_t  writeInternal(const void* buffer, size_t bytes);
+12 −4
Original line number Diff line number Diff line
@@ -2081,8 +2081,8 @@ int AudioFlinger::PlaybackThread::asyncCallback(stream_callback_event_t event,
void AudioFlinger::PlaybackThread::readOutputParameters_l()
{
    // unfortunately we have no way of recovering from errors here, hence the LOG_ALWAYS_FATAL
    mSampleRate = mOutput->stream->common.get_sample_rate(&mOutput->stream->common);
    mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common);
    mSampleRate = mOutput->getSampleRate();
    mChannelMask = mOutput->getChannelMask();
    if (!audio_is_output_channel(mChannelMask)) {
        LOG_ALWAYS_FATAL("HAL channel mask %#x not valid for output", mChannelMask);
    }
@@ -2092,8 +2092,12 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l()
                mChannelMask);
    }
    mChannelCount = audio_channel_count_from_out_mask(mChannelMask);

    // Get actual HAL format.
    mHALFormat = mOutput->stream->common.get_format(&mOutput->stream->common);
    mFormat = mHALFormat;
    // Get format from the shim, which will be different than the HAL format
    // if playing compressed audio over HDMI passthrough.
    mFormat = mOutput->getFormat();
    if (!audio_is_valid_format(mFormat)) {
        LOG_ALWAYS_FATAL("HAL format %#x not valid for output", mFormat);
    }
@@ -4559,9 +4563,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
        // app does not call stop() and relies on underrun to stop:
        // hence the test on (track->mRetryCount > 1).
        // If retryCount<=1 then track is about to underrun and be removed.
        // Do not use a high threshold for compressed audio.
        uint32_t minFrames;
        if ((track->sharedBuffer() == 0) && !track->isStopping_1() && !track->isPausing()
            && (track->mRetryCount > 1)) {
            && (track->mRetryCount > 1) && audio_is_linear_pcm(mFormat)) {
            minFrames = mNormalFrameCount;
        } else {
            minFrames = 1;
@@ -4650,6 +4655,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
                    // it will then automatically call start() when data is available
                    android_atomic_or(CBLK_DISABLED, &cblk->mFlags);
                } else if (last) {
                    ALOGW("pause because of UNDERRUN, framesReady = %zu,"
                            "minFrames = %u, mFormat = %#x",
                            track->framesReady(), minFrames, mFormat);
                    mixerStatus = MIXER_TRACKS_ENABLED;
                    if (mHwSupportsPause && !mHwPaused && !mStandby) {
                        doHwPause = true;