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

Commit 94be35bc authored by vivek mehta's avatar vivek mehta Committed by Linux Build Service Account
Browse files

audio: add support to enable Direct PCM output

This change squashes all changes done to enable
direct PCM output.

audio: use offload standby delay for direct pcm
Change-Id: Ifd0e39c5b3fe4a4af9f444dbbad21ef1e1a5edfa

AudioTrack: Set DIRECT track flag for direct pcm output
Change-Id: I13f840b5d67be56e03ec65d3bc7d44f1090b48c5

Direct_PCM: add support for effects
Change-Id: I2fbac63c623bf51a03e5e91828369739d33329f3

libmedia : audio: handle set playback rate when direct pcm used
Change-Id: I6df7c10b7115c77a19564e2f9fabc511d76a2410

audioflinger: Always process volume commands from a latest track
Change-Id: I9afbdd221db3a7311eb0ec8bb75852cf5409084e

Change-Id: I2ad7eacf11642a4ca9f892b61124293d0dc503a9
parent a10965dd
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1089,6 +1089,8 @@ protected:
    // For Device Selection API
    //  a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing.
    audio_port_handle_t     mSelectedDeviceId;
    bool                    mTrackOffloaded;
    bool                    mPlaybackRateSet;

private:
    class DeathNotifier : public IBinder::DeathRecipient {
+4 −3
Original line number Diff line number Diff line
@@ -43,9 +43,10 @@ class MediaRecorder;
struct AVMediaUtils {


    virtual size_t AudioTrackGetOffloadFrameCount(size_t frameCount) {
        return frameCount;
    }
    virtual size_t AudioTrackGetOffloadFrameCount(size_t frameCount);

    virtual bool AudioTrackIsTrackOffloaded(audio_io_handle_t /*output*/);

    // ----- NO TRESSPASSING BEYOND THIS LINE ------
    DECLARE_LOADABLE_SINGLETON(AVMediaUtils);
};
+8 −0
Original line number Diff line number Diff line
@@ -46,6 +46,14 @@

namespace android {

size_t AVMediaUtils::AudioTrackGetOffloadFrameCount(size_t frameCount) {
    return frameCount;
}

bool AVMediaUtils::AudioTrackIsTrackOffloaded(audio_io_handle_t output __unused) {
    return false;
}

// ----- NO TRESSPASSING BEYOND THIS LINE ------
AVMediaUtils::AVMediaUtils() {
}
+27 −4
Original line number Diff line number Diff line
@@ -177,7 +177,9 @@ AudioTrack::AudioTrack()
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0),
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
      mTrackOffloaded(false),
      mPlaybackRateSet(false)
{
    mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
    mAttributes.usage = AUDIO_USAGE_UNKNOWN;
@@ -208,7 +210,9 @@ AudioTrack::AudioTrack(
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0),
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
      mTrackOffloaded(false),
      mPlaybackRateSet(false)
{
    mStatus = set(streamType, sampleRate, format, channelMask,
            frameCount, flags, cbf, user, notificationFrames,
@@ -239,7 +243,9 @@ AudioTrack::AudioTrack(
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0),
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
      mTrackOffloaded(false),
      mPlaybackRateSet(false)
{
    mStatus = set(streamType, sampleRate, format, channelMask,
            0 /*frameCount*/, flags, cbf, user, notificationFrames,
@@ -905,6 +911,12 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate)
    //set effective rates
    mProxy->setPlaybackRate(playbackRateTemp);
    mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate

    // Playback Rate cannot be changed for direct tracks, hence fallback to deep buffer
    if (mTrackOffloaded) {
        mPlaybackRateSet = true;
        android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
    }
    return NO_ERROR;
}

@@ -1239,6 +1251,13 @@ status_t AudioTrack::createTrack_l()
    // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
    // After fast request is denied, we will request again if IAudioTrack is re-created.

    // Playback Rate is set, ensure we dont get a direct output
    audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
    if (mPlaybackRateSet == true && mOffloadInfo == NULL
        && audio_is_linear_pcm(mFormat)) {
        mOffloadInfo = &tOffloadInfo;
    }

    status_t status;
    status = AudioSystem::getOutputForAttr(attr, &output,
                                           mSessionId, &streamType, mClientUid,
@@ -1251,11 +1270,15 @@ status_t AudioTrack::createTrack_l()
              mSessionId, streamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);
        return BAD_VALUE;
    }
    //reset offload info if forced
    mOffloadInfo = (mOffloadInfo == &tOffloadInfo) ? NULL : mOffloadInfo;

    {
    // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
    // we must release it ourselves if anything goes wrong.

    // Not all of these values are needed under all conditions, but it is easier to get them all
    mTrackOffloaded = AVMediaUtils::get()->AudioTrackIsTrackOffloaded(output);
    status = AudioSystem::getLatency(output, &mAfLatency);
    if (status != NO_ERROR) {
        ALOGE("getLatency(%d) failed status %d", output, status);
@@ -1392,7 +1415,7 @@ status_t AudioTrack::createTrack_l()
        trackFlags |= IAudioFlinger::TRACK_OFFLOAD;
    }

    if (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
    if ((mFlags & AUDIO_OUTPUT_FLAG_DIRECT) || mTrackOffloaded) {
        trackFlags |= IAudioFlinger::TRACK_DIRECT;
    }

+5 −1
Original line number Diff line number Diff line
@@ -1892,6 +1892,10 @@ sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_
                || !isValidPcmSinkChannelMask(config->channel_mask)) {
            thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
            ALOGV("openOutput_l() created direct output: ID %d thread %p ", *output, thread);
            //Check if this is DirectPCM, if so
            if (flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
                thread->mIsDirectPcm = true;
            }
        } else {
            thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);
            ALOGV("openOutput_l() created mixer output: ID %d thread %p", *output, thread);
Loading