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

Commit 3acc9b1b authored by guonaichao's avatar guonaichao Committed by 郭奶超
Browse files

AudioPlaybackCapture: solve second output data consumed low issue



PatchRecord is in the output thread of audiohal. Every time the track
is consumed by the mixer and the ReleaseBuffer is executed, the data
obtainBuffer is written into the PatchBuffer. When a third-party application
uses AudioTrack::setPlaybackRate to timestretch the audio data, PatchRecord
and PatchTrack need to update framecount and speed at the same time. And the
remotesubmix thread where PatchTrack is located needs to perform timestretch
processing synchronously to solve the problem of Track::interceptBuffer
dropping frames.

Test: atest AudioPlaybackCaptureTest
Bug: 345666452

Change-Id: I39962c754426485d5bd60be21eceba11a171abd6
Signed-off-by: default avatarguonaichao <guonaichao@xiaomi.com>
parent 0ab78043
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3922,7 +3922,8 @@ void AudioFlinger::updateSecondaryOutputsForTrack_l(
                                                       patchRecord->bufferSize(),
                                                       outputFlags,
                                                       0ns /* timeout */,
                                                       frameCountToBeReady);
                                                       frameCountToBeReady,
                                                       track->getSpeed());
        status = patchTrack->initCheck();
        if (status != NO_ERROR) {
            ALOGE("Secondary output patchTrack init failed: %d", status);
+3 −2
Original line number Diff line number Diff line
@@ -571,10 +571,11 @@ public:
            size_t bufferSize,
            audio_output_flags_t flags,
            const Timeout& timeout = {},
            size_t frameCountToBeReady = 1 /** Default behaviour is to start
            size_t frameCountToBeReady = 1, /** Default behaviour is to start
                                             *  as soon as possible to have
                                             *  the lowest possible latency
                                             *  even if it might glitch. */);
                                             *  even if it might glitch. */
            float speed = 1.0f);
};

class IAfPatchRecord : public virtual IAfRecordTrack, public virtual IAfPatchTrackBase {
+2 −1
Original line number Diff line number Diff line
@@ -646,7 +646,8 @@ status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel)
                                           tempRecordTrack->bufferSize(),
                                           outputFlags,
                                           {} /*timeout*/,
                                           frameCountToBeReady);
                                           frameCountToBeReady,
                                           1.0f);
    status = mPlayback.checkTrack(tempPatchTrack.get());
    if (status != NO_ERROR) {
        return status;
+3 −2
Original line number Diff line number Diff line
@@ -490,10 +490,11 @@ public:
                                   size_t bufferSize,
                                   audio_output_flags_t flags,
                                   const Timeout& timeout = {},
                                   size_t frameCountToBeReady = 1 /** Default behaviour is to start
                                   size_t frameCountToBeReady = 1, /** Default behaviour is to start
                                                                    *  as soon as possible to have
                                                                    *  the lowest possible latency
                                                                    *  even if it might glitch. */);
                                                                    *  even if it might glitch. */
                                   float speed = 1.0f);
    ~PatchTrack() override;

    size_t framesReady() const final;
+18 −7
Original line number Diff line number Diff line
@@ -2441,10 +2441,11 @@ sp<IAfPatchTrack> IAfPatchTrack::create(
        size_t bufferSize,
        audio_output_flags_t flags,
        const Timeout& timeout,
        size_t frameCountToBeReady /** Default behaviour is to start
        size_t frameCountToBeReady, /** Default behaviour is to start
                                         *  as soon as possible to have
                                         *  the lowest possible latency
                                         *  even if it might glitch. */)
                                         *  even if it might glitch. */
        float speed)
{
    return sp<PatchTrack>::make(
            playbackThread,
@@ -2457,7 +2458,8 @@ sp<IAfPatchTrack> IAfPatchTrack::create(
            bufferSize,
            flags,
            timeout,
            frameCountToBeReady);
            frameCountToBeReady,
            speed);
}

PatchTrack::PatchTrack(IAfPlaybackThread* playbackThread,
@@ -2470,17 +2472,26 @@ PatchTrack::PatchTrack(IAfPlaybackThread* playbackThread,
                                                     size_t bufferSize,
                                                     audio_output_flags_t flags,
                                                     const Timeout& timeout,
                                                     size_t frameCountToBeReady)
                                                     size_t frameCountToBeReady,
                                                     float speed)
    :   Track(playbackThread, NULL, streamType,
              audio_attributes_t{} /* currently unused for patch track */,
              sampleRate, format, channelMask, frameCount,
              buffer, bufferSize, nullptr /* sharedBuffer */,
              AUDIO_SESSION_NONE, getpid(), audioServerAttributionSource(getpid()), flags,
              TYPE_PATCH, AUDIO_PORT_HANDLE_NONE, frameCountToBeReady),
        PatchTrackBase(mCblk ? new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true)
                        : nullptr,
              TYPE_PATCH, AUDIO_PORT_HANDLE_NONE, frameCountToBeReady, speed),
        PatchTrackBase(mCblk ? new AudioTrackClientProxy(mCblk, mBuffer, frameCount, mFrameSize,
                        true /*clientInServer*/) : nullptr,
                       playbackThread, timeout)
{
    if (mProxy != nullptr) {
        sp<AudioTrackClientProxy>::cast(mProxy)->setPlaybackRate({
                /* .mSpeed = */ speed,
                /* .mPitch = */ AUDIO_TIMESTRETCH_PITCH_NORMAL,
                /* .mStretchMode = */ AUDIO_TIMESTRETCH_STRETCH_DEFAULT,
                /* .mFallbackMode = */ AUDIO_TIMESTRETCH_FALLBACK_FAIL
        });
    }
    ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
                                      __func__, mId, sampleRate,
                                      (int)mPeerTimeout.tv_sec,