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

Commit b7d8c5aa authored by jiabin's avatar jiabin Committed by Jiabin Huang
Browse files

Add getExternalPosition in MMapStreamInterface.

GetExternalPosition will return a recent count of the number of
audio frames presented/received to/from an external observer. Using
the new API can return a precise timestamp to client, which can
help on A/V sync.

Test: atest AAudioTests
Bug: 158609200
Change-Id: If74e1d859a2bb2b4dba6af0e4e9164f05d19d962
parent 8dbd241e
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include <utils/Errors.h>
#include <utils/RefBase.h>

#include <time.h>

namespace android {

class MmapStreamCallback;
@@ -102,6 +104,19 @@ class MmapStreamInterface : public virtual RefBase
     */
    virtual status_t getMmapPosition(struct audio_mmap_position *position) = 0;

    /**
     * Get a recent count of the number of audio frames presented/received to/from an
     * external observer.
     *
     * \param[out] position count of presented audio frames
     * \param[out] timeNanos associated clock time
     *
     * \return OK if the external position is set correctly.
     *         NO_INIT in case of initialization error
     *         INVALID_OPERATION if the interface is not implemented
     */
    virtual status_t getExternalPosition(uint64_t* position, int64_t* timeNanos) = 0;

    /**
     * Start a stream operating in mmap mode.
     * createMmapBuffer() must be called before calling start()
+1 −0
Original line number Diff line number Diff line
@@ -684,6 +684,7 @@ using effect_buffer_t = int16_t;
        virtual status_t createMmapBuffer(int32_t minSizeFrames,
                                          struct audio_mmap_buffer_info *info);
        virtual status_t getMmapPosition(struct audio_mmap_position *position);
        virtual status_t getExternalPosition(uint64_t *position, int64_t *timeNanos);
        virtual status_t start(const AudioClient& client,
                               const audio_attributes_t *attr,
                               audio_port_handle_t *handle);
+28 −0
Original line number Diff line number Diff line
@@ -8742,6 +8742,11 @@ status_t AudioFlinger::MmapThreadHandle::getMmapPosition(struct audio_mmap_posit
    return mThread->getMmapPosition(position);
}

status_t AudioFlinger::MmapThreadHandle::getExternalPosition(uint64_t *position,
                                                             int64_t *timeNanos) {
    return mThread->getExternalPosition(position, timeNanos);
}

status_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client,
        const audio_attributes_t *attr, audio_port_handle_t *handle)

@@ -9696,6 +9701,20 @@ void AudioFlinger::MmapPlaybackThread::toAudioPortConfig(struct audio_port_confi
    }
}

status_t AudioFlinger::MmapPlaybackThread::getExternalPosition(uint64_t *position,
                                                               int64_t *timeNanos)
{
    if (mOutput == nullptr) {
        return NO_INIT;
    }
    struct timespec timestamp;
    status_t status = mOutput->getPresentationPosition(position, &timestamp);
    if (status == NO_ERROR) {
        *timeNanos = timestamp.tv_sec * NANOS_PER_SECOND + timestamp.tv_nsec;
    }
    return status;
}

void AudioFlinger::MmapPlaybackThread::dumpInternals_l(int fd, const Vector<String16>& args)
{
    MmapThread::dumpInternals_l(fd, args);
@@ -9800,4 +9819,13 @@ void AudioFlinger::MmapCaptureThread::toAudioPortConfig(struct audio_port_config
    }
}

status_t AudioFlinger::MmapCaptureThread::getExternalPosition(
        uint64_t *position, int64_t *timeNanos)
{
    if (mInput == nullptr) {
        return NO_INIT;
    }
    return mInput->getCapturePosition((int64_t*)position, timeNanos);
}

} // namespace android
+5 −0
Original line number Diff line number Diff line
@@ -1824,6 +1824,7 @@ class MmapThread : public ThreadBase
                   audio_port_handle_t *handle);
    status_t stop(audio_port_handle_t handle);
    status_t standby();
    virtual status_t getExternalPosition(uint64_t *position, int64_t *timeNaos) = 0;

    // RefBase
    virtual     void        onFirstRef();
@@ -1935,6 +1936,8 @@ public:

    virtual     void        toAudioPortConfig(struct audio_port_config *config);

                status_t    getExternalPosition(uint64_t *position, int64_t *timeNanos) override;

protected:
                void        dumpInternals_l(int fd, const Vector<String16>& args) override;

@@ -1965,6 +1968,8 @@ public:

    virtual     void           toAudioPortConfig(struct audio_port_config *config);

                status_t       getExternalPosition(uint64_t *position, int64_t *timeNanos) override;

protected:

                AudioStreamIn*  mInput;
+15 −0
Original line number Diff line number Diff line
@@ -378,3 +378,18 @@ aaudio_result_t AAudioServiceEndpointMMAP::getDownDataDescription(AudioEndpointP
    parcelable.mDownDataQueueParcelable.setCapacityInFrames(getBufferCapacity());
    return AAUDIO_OK;
}

aaudio_result_t AAudioServiceEndpointMMAP::getExternalPosition(uint64_t *positionFrames,
                                                               int64_t *timeNanos)
{
    if (!mExternalPositionSupported) {
        return AAUDIO_ERROR_INVALID_STATE;
    }
    status_t status = mMmapStream->getExternalPosition(positionFrames, timeNanos);
    if (status == INVALID_OPERATION) {
        // getExternalPosition is not supported. Set mExternalPositionSupported as false
        // so that the call will not go to the HAL next time.
        mExternalPositionSupported = false;
    }
    return AAudioConvert_androidToAAudioResult(status);
}
Loading