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

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

AudioFlinger: Add timestamp correction to MSD BUS Threads

Test: MSD YouTube playback
Bug: 112431914
Change-Id: Ic15ace24d6ab3613be08978b925fd7b9dc7aef38
parent 30282562
Loading
Loading
Loading
Loading
+55 −5
Original line number Diff line number Diff line
@@ -863,6 +863,7 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args __u
            || mType == DIRECT
            || mType == OFFLOAD) {
        dprintf(fd, "  Timestamp stats: %s\n", mTimestampVerifier.toString().c_str());
        dprintf(fd, "  Timestamp corrected: %s\n", isTimestampCorrectionEnabled() ? "yes" : "no");
    }

    if (locked) {
@@ -1732,10 +1733,21 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
        if (mOutput->audioHwDev->canSetMasterMute()) {
            mMasterMute = false;
        }
        mIsMsdDevice = strcmp(
                mOutput->audioHwDev->moduleName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0;
    }

    readOutputParameters_l();

    // TODO: We may also match on address as well as device type for
    // AUDIO_DEVICE_OUT_BUS, AUDIO_DEVICE_OUT_ALL_A2DP, AUDIO_DEVICE_OUT_REMOTE_SUBMIX
    if (type == MIXER || type == DIRECT) {
        mTimestampCorrectedDevices = (audio_devices_t)property_get_int64(
                "audio.timestamp.corrected_output_devices",
                (int64_t)(mIsMsdDevice ? AUDIO_DEVICE_OUT_BUS // turn on by default for MSD
                                       : AUDIO_DEVICE_NONE));
    }

    // ++ operator does not compile
    for (audio_stream_type_t stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_FOR_POLICY_CNT;
            stream = (audio_stream_type_t) (stream + 1)) {
@@ -3248,6 +3260,21 @@ bool AudioFlinger::PlaybackThread::threadLoop()
                mTimestampVerifier.add(timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL],
                        timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
                        mSampleRate);

                if (isTimestampCorrectionEnabled()) {
                    ALOGV("TS_BEFORE: %d %lld %lld", id(),
                            (long long)timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
                            (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]);
                    auto correctedTimestamp = mTimestampVerifier.getLastCorrectedTimestamp();
                    timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]
                            = correctedTimestamp.mFrames;
                    timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]
                            = correctedTimestamp.mTimeNs;
                    ALOGV("TS_AFTER: %d %lld %lld", id(),
                            (long long)timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
                            (long long)timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]);
                }

                // We always fetch the timestamp here because often the downstream
                // sink will block while writing.

@@ -6368,8 +6395,20 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
    snprintf(mThreadName, kThreadNameLength, "AudioIn_%X", id);
    mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);

    if (mInput != nullptr && mInput->audioHwDev != nullptr) {
        mIsMsdDevice = strcmp(
                mInput->audioHwDev->moduleName(), AUDIO_HARDWARE_MODULE_ID_MSD) == 0;
    }

    readInputParameters_l();

    // TODO: We may also match on address as well as device type for
    // AUDIO_DEVICE_IN_BUS, AUDIO_DEVICE_IN_BLUETOOTH_A2DP, AUDIO_DEVICE_IN_REMOTE_SUBMIX
    mTimestampCorrectedDevices = (audio_devices_t)property_get_int64(
            "audio.timestamp.corrected_input_devices",
            (int64_t)(mIsMsdDevice ? AUDIO_DEVICE_IN_BUS // turn on by default for MSD
                                   : AUDIO_DEVICE_NONE));

    // create an NBAIO source for the HAL input stream, and negotiate
    mInputSource = new AudioStreamInSource(input->stream);
    size_t numCounterOffers = 0;
@@ -6804,7 +6843,22 @@ reacquire_wakelock:
            int64_t position, time;
            if (mStandby) {
                mTimestampVerifier.discontinuity();
            } else if (mInput->stream->getCapturePosition(&position, &time) == NO_ERROR) {
            } else if (mInput->stream->getCapturePosition(&position, &time) == NO_ERROR
                    && time > mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]) {

                mTimestampVerifier.add(position, time, mSampleRate);

                // Correct timestamps
                if (isTimestampCorrectionEnabled()) {
                    ALOGV("TS_BEFORE: %d %lld %lld",
                            id(), (long long)time, (long long)position);
                    auto correctedTimestamp = mTimestampVerifier.getLastCorrectedTimestamp();
                    position = correctedTimestamp.mFrames;
                    time = correctedTimestamp.mTimeNs;
                    ALOGV("TS_AFTER: %d %lld %lld",
                            id(), (long long)time, (long long)position);
                }

                mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = position;
                mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = time;
                // Note: In general record buffers should tend to be empty in
@@ -6812,10 +6866,6 @@ reacquire_wakelock:
                //
                // Also, it is not advantageous to call get_presentation_position during the read
                // as the read obtains a lock, preventing the timestamp call from executing.

                mTimestampVerifier.add(mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL],
                        mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL],
                        mSampleRate);
            } else {
                mTimestampVerifier.error();
            }
+16 −1
Original line number Diff line number Diff line
@@ -393,6 +393,10 @@ public:

                        void        broadcast_l();

                virtual bool        isTimestampCorrectionEnabled() const { return false; }

                bool                isMsdDevice() const { return mIsMsdDevice; }

    mutable     Mutex                   mLock;

protected:
@@ -501,7 +505,8 @@ protected:
                ExtendedTimestamp       mTimestamp;
                TimestampVerifier< // For timestamp statistics.
                        int64_t /* frame count */, int64_t /* time ns */> mTimestampVerifier;

                audio_devices_t         mTimestampCorrectedDevices = AUDIO_DEVICE_NONE;
                bool                    mIsMsdDevice = false;
                // A condition that must be evaluated by the thread loop has changed and
                // we must not wait for async write callback in the thread loop before evaluating it
                bool                    mSignalPending;
@@ -816,6 +821,11 @@ public:
                                       && mTracks.size() < PlaybackThread::kMaxTracks;
                            }

                bool        isTimestampCorrectionEnabled() const override {
                                const audio_devices_t device =
                                        mOutDevice & mTimestampCorrectedDevices;
                                return audio_is_output_devices(device) && popcount(device) > 0;
                            }
protected:
    // updated by readOutputParameters_l()
    size_t                          mNormalFrameCount;  // normal mixer and effects
@@ -1532,6 +1542,11 @@ public:

            bool        fastTrackAvailable() const { return mFastTrackAvail; }

            bool        isTimestampCorrectionEnabled() const override {
                            // checks popcount for exactly one device.
                            return audio_is_input_device(
                                    mInDevice & mTimestampCorrectedDevices);
                        }
private:
            // Enter standby if not already in standby, and set mStandby flag
            void    standbyIfNotAlreadyInStandby();