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

Commit 9e7a6fc1 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Various improvements to nuplayer playback"

parents d6790989 115cac81
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -299,7 +299,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                         sampleRate, numChannels);

                    mAudioSink->close();
                    CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
                    CHECK_EQ(mAudioSink->open(
                                sampleRate,
                                numChannels,
                                AUDIO_FORMAT_PCM_16_BIT,
                                8 /* bufferCount */),
                             (status_t)OK);
                    mAudioSink->start();

                    mRenderer->signalAudioSinkChanged();
+13 −13
Original line number Diff line number Diff line
@@ -70,19 +70,19 @@ private:
    struct StreamingSource;

    enum {
        kWhatSetDataSource,
        kWhatSetVideoNativeWindow,
        kWhatSetAudioSink,
        kWhatMoreDataQueued,
        kWhatStart,
        kWhatScanSources,
        kWhatVideoNotify,
        kWhatAudioNotify,
        kWhatRendererNotify,
        kWhatReset,
        kWhatSeek,
        kWhatPause,
        kWhatResume,
        kWhatSetDataSource              = '=DaS',
        kWhatSetVideoNativeWindow       = '=NaW',
        kWhatSetAudioSink               = '=AuS',
        kWhatMoreDataQueued             = 'more',
        kWhatStart                      = 'strt',
        kWhatScanSources                = 'scan',
        kWhatVideoNotify                = 'vidN',
        kWhatAudioNotify                = 'audN',
        kWhatRendererNotify             = 'renN',
        kWhatReset                      = 'rset',
        kWhatSeek                       = 'seek',
        kWhatPause                      = 'paus',
        kWhatResume                     = 'rsme',
    };

    wp<NuPlayerDriver> mDriver;
+14 −1
Original line number Diff line number Diff line
@@ -59,8 +59,21 @@ void NuPlayer::Decoder::configure(const sp<MetaData> &meta) {
        format->setObject("native-window", mNativeWindow);
    }

    // Current video decoders do not return from OMX_FillThisBuffer
    // quickly, violating the OpenMAX specs, until that is remedied
    // we need to invest in an extra looper to free the main event
    // queue.
    bool needDedicatedLooper = !strncasecmp(mime, "video/", 6);

    mCodec = new ACodec;
    looper()->registerHandler(mCodec);

    if (needDedicatedLooper && mCodecLooper == NULL) {
        mCodecLooper = new ALooper;
        mCodecLooper->setName("NuPlayerDecoder");
        mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
    }

    (needDedicatedLooper ? mCodecLooper : looper())->registerHandler(mCodec);

    mCodec->setNotificationMessage(notifyMsg);
    mCodec->initiateSetup(format);
+2 −1
Original line number Diff line number Diff line
@@ -43,13 +43,14 @@ protected:

private:
    enum {
        kWhatCodecNotify,
        kWhatCodecNotify        = 'cdcN',
    };

    sp<AMessage> mNotify;
    sp<NativeWindowWrapper> mNativeWindow;

    sp<ACodec> mCodec;
    sp<ALooper> mCodecLooper;

    Vector<sp<ABuffer> > mCSD;
    size_t mCSDIndex;
+53 −26
Original line number Diff line number Diff line
@@ -118,9 +118,24 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {

            mDrainAudioQueuePending = false;

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

            postDrainAudioQueue();
                uint32_t numFramesPendingPlayout =
                    mNumFramesWritten - numFramesPlayed;

                // This is how long the audio sink will have data to
                // play back.
                int64_t delayUs =
                    mAudioSink->msecsPerFrame()
                        * numFramesPendingPlayout * 1000ll;

                // Let's give it more data after about half that time
                // has elapsed.
                postDrainAudioQueue(delayUs / 2);
            }
            break;
        }

@@ -182,7 +197,7 @@ void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
    }
}

void NuPlayer::Renderer::postDrainAudioQueue() {
void NuPlayer::Renderer::postDrainAudioQueue(int64_t delayUs) {
    if (mDrainAudioQueuePending || mSyncQueues || mPaused) {
        return;
    }
@@ -194,19 +209,33 @@ void NuPlayer::Renderer::postDrainAudioQueue() {
    mDrainAudioQueuePending = true;
    sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id());
    msg->setInt32("generation", mAudioQueueGeneration);
    msg->post();
    msg->post(delayUs);
}

void NuPlayer::Renderer::signalAudioSinkChanged() {
    (new AMessage(kWhatAudioSinkChanged, id()))->post();
}

void NuPlayer::Renderer::onDrainAudioQueue() {
    for (;;) {
        if (mAudioQueue.empty()) {
            break;
bool NuPlayer::Renderer::onDrainAudioQueue() {
    uint32_t numFramesPlayed;
    CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);

    ssize_t numFramesAvailableToWrite =
        mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);

#if 0
    if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
        LOGI("audio sink underrun");
    } else {
        LOGV("audio queue has %d frames left to play",
             mAudioSink->frameCount() - numFramesAvailableToWrite);
    }
#endif

    size_t numBytesAvailableToWrite =
        numFramesAvailableToWrite * mAudioSink->frameSize();

    while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) {
        QueueEntry *entry = &*mAudioQueue.begin();

        if (entry->mBuffer == NULL) {
@@ -216,20 +245,7 @@ void NuPlayer::Renderer::onDrainAudioQueue() {

            mAudioQueue.erase(mAudioQueue.begin());
            entry = NULL;
            return;
        }

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

        ssize_t numFramesAvailableToWrite =
            mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);

        size_t numBytesAvailableToWrite =
            numFramesAvailableToWrite * mAudioSink->frameSize();

        if (numBytesAvailableToWrite == 0) {
            break;
            return false;
        }

        if (entry->mOffset == 0) {
@@ -274,10 +290,14 @@ void NuPlayer::Renderer::onDrainAudioQueue() {
            entry = NULL;
        }

        mNumFramesWritten += copy / mAudioSink->frameSize();
        numBytesAvailableToWrite -= copy;
        size_t copiedFrames = copy / mAudioSink->frameSize();
        mNumFramesWritten += copiedFrames;
    }

    notifyPosition();

    return !mAudioQueue.empty();
}

void NuPlayer::Renderer::postDrainVideoQueue() {
@@ -344,7 +364,14 @@ void NuPlayer::Renderer::onDrainVideoQueue() {
    int64_t mediaTimeUs;
    CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));

    LOGI("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
    int64_t realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs;
    int64_t lateByUs = ALooper::GetNowUs() - realTimeUs;

    if (lateByUs > 40000) {
        LOGI("video late by %lld us (%.2f secs)", lateByUs, lateByUs / 1E6);
    } else {
        LOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
    }
#endif

    entry->mNotifyConsumed->setInt32("render", true);
Loading