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

Commit 83266677 authored by Lajos Molnar's avatar Lajos Molnar Committed by Android (Google) Code Review
Browse files

Merge "NuPlayer: use getTimestamp instead of getPosition" into lmp-dev

parents a87be62b 06ad1528
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include <media/mediaplayer.h>
#include <media/AudioSystem.h>
#include <media/AudioTimestamp.h>
#include <media/Metadata.h>

// Fwd decl to make sure everyone agrees that the scope of struct sockaddr_in is
@@ -97,6 +98,7 @@ public:
        virtual uint32_t    latency() const = 0;
        virtual float       msecsPerFrame() const = 0;
        virtual status_t    getPosition(uint32_t *position) const = 0;
        virtual status_t    getTimestamp(AudioTimestamp &ts) const = 0;
        virtual status_t    getFramesWritten(uint32_t *frameswritten) const = 0;
        virtual int         getSessionId() const = 0;
        virtual audio_stream_type_t getAudioStreamType() const = 0;
+16 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <utils/Errors.h>  // for status_t
#include <utils/String8.h>
#include <utils/SystemClock.h>
#include <utils/Timers.h>
#include <utils/Vector.h>

#include <media/IMediaHTTPService.h>
@@ -1496,6 +1497,12 @@ status_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) const
    return mTrack->getPosition(position);
}

status_t MediaPlayerService::AudioOutput::getTimestamp(AudioTimestamp &ts) const
{
    if (mTrack == 0) return NO_INIT;
    return mTrack->getTimestamp(ts);
}

status_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritten) const
{
    if (mTrack == 0) return NO_INIT;
@@ -1971,6 +1978,15 @@ status_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) const
    return NO_ERROR;
}

status_t MediaPlayerService::AudioCache::getTimestamp(AudioTimestamp &ts) const
{
    ts.mPosition = mSize / mFrameSize;
    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    ts.mTime.tv_sec = now / 1000000000LL;
    ts.mTime.tv_nsec = now - (1000000000LL * ts.mTime.tv_sec);
    return NO_ERROR;
}

status_t MediaPlayerService::AudioCache::getFramesWritten(uint32_t *written) const
{
    if (written == 0) return BAD_VALUE;
+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ class MediaPlayerService : public BnMediaPlayerService
        virtual uint32_t        latency() const;
        virtual float           msecsPerFrame() const;
        virtual status_t        getPosition(uint32_t *position) const;
        virtual status_t        getTimestamp(AudioTimestamp &ts) const;
        virtual status_t        getFramesWritten(uint32_t *frameswritten) const;
        virtual int             getSessionId() const;
        virtual uint32_t        getSampleRate() const;
@@ -198,6 +199,7 @@ class MediaPlayerService : public BnMediaPlayerService
        virtual uint32_t        latency() const;
        virtual float           msecsPerFrame() const;
        virtual status_t        getPosition(uint32_t *position) const;
        virtual status_t        getTimestamp(AudioTimestamp &ts) const;
        virtual status_t        getFramesWritten(uint32_t *frameswritten) const;
        virtual int             getSessionId() const;
        virtual uint32_t        getSampleRate() const;
+38 −22
Original line number Diff line number Diff line
@@ -343,15 +343,13 @@ size_t NuPlayer::Renderer::fillAudioBuffer(void *buffer, size_t size) {
                mFirstAudioTimeUs = mediaTimeUs;
            }

            uint32_t numFramesPlayed;
            CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);

            // TODO: figure out how to calculate initial latency.
            // Otherwise, the initial time is not correct till the first sample
            // is played.
            mAnchorTimeMediaUs = mFirstAudioTimeUs
                    + (numFramesPlayed * mAudioSink->msecsPerFrame()) * 1000ll;
            mAnchorTimeRealUs = ALooper::GetNowUs();
            // TODO: figure out how to calculate initial latency if
            // getTimestamp is not available. Otherwise, the initial time
            // is not correct till the first sample is played.
            int64_t nowUs = ALooper::GetNowUs();
            mAnchorTimeMediaUs =
                mFirstAudioTimeUs + getPlayedOutAudioDurationUs(nowUs);
            mAnchorTimeRealUs = nowUs;
        }

        size_t copy = entry->mBuffer->size() - entry->mOffset;
@@ -413,7 +411,7 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
            // EOS
            int64_t postEOSDelayUs = 0;
            if (mAudioSink->needsTrailingPadding()) {
                postEOSDelayUs = getAudioPendingPlayoutUs() + 1000 * mAudioSink->latency();
                postEOSDelayUs = getPendingAudioPlayoutDurationUs(ALooper::GetNowUs());
            }
            notifyEOS(true /* audio */, entry->mFinalResult, postEOSDelayUs);

@@ -428,8 +426,8 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
            ALOGV("rendering audio at media time %.2f secs", mediaTimeUs / 1E6);
            mAnchorTimeMediaUs = mediaTimeUs;

            mAnchorTimeRealUs = ALooper::GetNowUs()
                    + getAudioPendingPlayoutUs() + 1000 * mAudioSink->latency() / 2;
            int64_t nowUs = ALooper::GetNowUs();
            mAnchorTimeRealUs = nowUs + getPendingAudioPlayoutDurationUs(nowUs);
        }

        size_t copy = entry->mBuffer->size() - entry->mOffset;
@@ -483,12 +481,10 @@ bool NuPlayer::Renderer::onDrainAudioQueue() {
    return !mAudioQueue.empty();
}

int64_t NuPlayer::Renderer::getAudioPendingPlayoutUs() {
    uint32_t numFramesPlayed;
    CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);

    uint32_t numFramesPendingPlayout = mNumFramesWritten - numFramesPlayed;
    return numFramesPendingPlayout * mAudioSink->msecsPerFrame() * 1000;
int64_t NuPlayer::Renderer::getPendingAudioPlayoutDurationUs(int64_t nowUs) {
    int64_t writtenAudioDurationUs =
        mNumFramesWritten * 1000LL * mAudioSink->msecsPerFrame();
    return writtenAudioDurationUs - getPlayedOutAudioDurationUs(nowUs);
}

void NuPlayer::Renderer::postDrainVideoQueue() {
@@ -937,17 +933,37 @@ void NuPlayer::Renderer::onResume() {
    }
}

void NuPlayer::Renderer::onAudioOffloadTearDown() {
int64_t NuPlayer::Renderer::getPlayedOutAudioDurationUs(int64_t nowUs) {
    // FIXME: getTimestamp sometimes returns negative frame count.
    // Since we do not handle the rollover at this point (which can
    // happen every 14 hours), simply treat the timestamp as signed.
    uint32_t numFramesPlayed;
    CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
    int64_t numFramesPlayedAt;
    AudioTimestamp ts;
    status_t res = mAudioSink->getTimestamp(ts);
    if (res == OK) {
        numFramesPlayed = ts.mPosition;
        numFramesPlayedAt =
            ts.mTime.tv_sec * 1000000LL + ts.mTime.tv_nsec / 1000;
    } else {
        res = mAudioSink->getPosition(&numFramesPlayed);
        CHECK_EQ(res, (status_t)OK);
        numFramesPlayedAt = nowUs;
        numFramesPlayedAt += 1000LL * mAudioSink->latency() / 2; /* XXX */
    }
    return (int32_t)numFramesPlayed * 1000LL * mAudioSink->msecsPerFrame()
            + nowUs - numFramesPlayedAt;
}

void NuPlayer::Renderer::onAudioOffloadTearDown() {
    int64_t firstAudioTimeUs;
    {
        Mutex::Autolock autoLock(mLock);
        firstAudioTimeUs = mFirstAudioTimeUs;
    }
    int64_t currentPositionUs = firstAudioTimeUs
            + (numFramesPlayed * mAudioSink->msecsPerFrame()) * 1000ll;

    int64_t currentPositionUs =
        firstAudioTimeUs + getPlayedOutAudioDurationUs(ALooper::GetNowUs());

    mAudioSink->stop();
    mAudioSink->flush();
+2 −1
Original line number Diff line number Diff line
@@ -130,7 +130,8 @@ private:
    size_t fillAudioBuffer(void *buffer, size_t size);

    bool onDrainAudioQueue();
    int64_t getAudioPendingPlayoutUs();
    int64_t getPendingAudioPlayoutDurationUs(int64_t nowUs);
    int64_t getPlayedOutAudioDurationUs(int64_t nowUs);
    void postDrainAudioQueue_l(int64_t delayUs = 0);

    void onDrainVideoQueue();