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

Commit 4a8b9a23 authored by Andreas Huber's avatar Andreas Huber
Browse files

Now back to 30fps, suspend updates if surface flinger didn't send us

any new frames for one second or longer.

Change-Id: I1c2ec349b0a4b7c4eb9dcdde483362ec87dd69fa
related-to-bug: 7248248
parent 887070db
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ status_t Converter::initEncoder() {
        mOutputFormat->setInt32("bitrate", audioBitrate);
    } else {
        mOutputFormat->setInt32("bitrate", videoBitrate);
        mOutputFormat->setInt32("frame-rate", 60);
        mOutputFormat->setInt32("frame-rate", 30);
        mOutputFormat->setInt32("i-frame-interval", 1);  // Iframes every 1 secs
        mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1);
    }
+42 −4
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ struct WifiDisplaySource::PlaybackSession::Track : public AHandler {
          const sp<MediaPuller> &mediaPuller,
          const sp<Converter> &converter);

    void setRepeaterSource(const sp<RepeaterSource> &source);

    sp<AMessage> getFormat();
    bool isAudio() const;

@@ -78,6 +80,8 @@ struct WifiDisplaySource::PlaybackSession::Track : public AHandler {
    void queueAccessUnit(const sp<ABuffer> &accessUnit);
    sp<ABuffer> dequeueAccessUnit();

    void requestIDRFrame();

protected:
    virtual void onMessageReceived(const sp<AMessage> &msg);
    virtual ~Track();
@@ -96,6 +100,7 @@ private:
    ssize_t mPacketizerTrackIndex;
    bool mIsAudio;
    List<sp<ABuffer> > mQueuedAccessUnits;
    sp<RepeaterSource> mRepeaterSource;

    static bool IsAudioFormat(const sp<AMessage> &format);

@@ -178,6 +183,11 @@ void WifiDisplaySource::PlaybackSession::Track::stopAsync() {
    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());

    if (mStarted && mMediaPuller != NULL) {
        if (mRepeaterSource != NULL) {
            // Let's unblock MediaPuller's MediaSource::read().
            mRepeaterSource->wakeUp();
        }

        mMediaPuller->stopAsync(msg);
    } else {
        msg->post();
@@ -224,6 +234,23 @@ sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
    return accessUnit;
}

void WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
        const sp<RepeaterSource> &source) {
    mRepeaterSource = source;
}

void WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
    if (mIsAudio) {
        return;
    }

    if (mRepeaterSource != NULL) {
        mRepeaterSource->wakeUp();
    }

    mConverter->requestIDRFrame();
}

////////////////////////////////////////////////////////////////////////////////

WifiDisplaySource::PlaybackSession::PlaybackSession(
@@ -809,7 +836,8 @@ status_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
}

status_t WifiDisplaySource::PlaybackSession::addSource(
        bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) {
        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
        size_t *numInputBuffers) {
    sp<ALooper> pullLooper = new ALooper;
    pullLooper->setName("pull_looper");

@@ -871,6 +899,10 @@ status_t WifiDisplaySource::PlaybackSession::addSource(
    sp<Track> track = new Track(
            notify, pullLooper, codecLooper, puller, converter);

    if (isRepeaterSource) {
        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
    }

    looper()->registerHandler(track);

    mTracks.add(trackIndex, track);
@@ -887,8 +919,13 @@ status_t WifiDisplaySource::PlaybackSession::addVideoSource() {

    source->setUseAbsoluteTimestamps();

    sp<RepeaterSource> videoSource =
        new RepeaterSource(source, 30.0 /* rateHz */);

    size_t numInputBuffers;
    status_t err = addSource(true /* isVideo */, source, &numInputBuffers);
    status_t err = addSource(
            true /* isVideo */, videoSource, true /* isRepeaterSource */,
            &numInputBuffers);

    if (err != OK) {
        return err;
@@ -910,7 +947,8 @@ status_t WifiDisplaySource::PlaybackSession::addAudioSource() {

    if (audioSource->initCheck() == OK) {
        return addSource(
                false /* isVideo */, audioSource, NULL /* numInputBuffers */);
                false /* isVideo */, audioSource, false /* isRepeaterSource */,
                NULL /* numInputBuffers */);
    }

    ALOGW("Unable to instantiate audio source");
@@ -1300,7 +1338,7 @@ void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
    for (size_t i = 0; i < mTracks.size(); ++i) {
        const sp<Track> &track = mTracks.valueAt(i);

        track->converter()->requestIDRFrame();
        track->requestIDRFrame();
    }
}

+1 −0
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ private:
    status_t addSource(
            bool isVideo,
            const sp<MediaSource> &source,
            bool isRepeaterSource,
            size_t *numInputBuffers);

    status_t addVideoSource();
+56 −24
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ RepeaterSource::RepeaterSource(const sp<MediaSource> &source, double rateHz)
      mRateHz(rateHz),
      mBuffer(NULL),
      mResult(OK),
      mLastBufferUpdateUs(-1ll),
      mStartTimeUs(-1ll),
      mFrameCount(0) {
}
@@ -91,14 +92,17 @@ status_t RepeaterSource::read(
    ReadOptions::SeekMode seekMode;
    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &seekMode));

    for (;;) {
        int64_t bufferTimeUs = -1ll;

        if (mStartTimeUs < 0ll) {
            Mutex::Autolock autoLock(mLock);
        while (mBuffer == NULL && mResult == OK) {
            while ((mLastBufferUpdateUs < 0ll || mBuffer == NULL)
                    && mResult == OK) {
                mCondition.wait(mLock);
            }

            ALOGV("now resuming.");
            mStartTimeUs = ALooper::GetNowUs();
            bufferTimeUs = mStartTimeUs;
        } else {
@@ -112,17 +116,35 @@ status_t RepeaterSource::read(
            }
        }

        bool stale = false;

        {
            Mutex::Autolock autoLock(mLock);
            if (mResult != OK) {
                CHECK(mBuffer == NULL);
                return mResult;
            }

            int64_t nowUs = ALooper::GetNowUs();
            if (nowUs - mLastBufferUpdateUs > 1000000ll) {
                mLastBufferUpdateUs = -1ll;
                stale = true;
            } else {
                mBuffer->add_ref();
                *buffer = mBuffer;
                (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs);

                ++mFrameCount;
            }
        }

        if (!stale) {
            break;
        }

        mStartTimeUs = -1ll;
        mFrameCount = 0;
        ALOGV("now dormant");
    }

    return OK;
}
@@ -147,6 +169,7 @@ void RepeaterSource::onMessageReceived(const sp<AMessage> &msg) {
            }
            mBuffer = buffer;
            mResult = err;
            mLastBufferUpdateUs = ALooper::GetNowUs();

            mCondition.broadcast();

@@ -161,4 +184,13 @@ void RepeaterSource::onMessageReceived(const sp<AMessage> &msg) {
    }
}

void RepeaterSource::wakeUp() {
    ALOGV("wakeUp");
    Mutex::Autolock autoLock(mLock);
    if (mLastBufferUpdateUs < 0ll && mBuffer != NULL) {
        mLastBufferUpdateUs = ALooper::GetNowUs();
        mCondition.broadcast();
    }
}

}  // namespace android
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ struct RepeaterSource : public MediaSource {

    void onMessageReceived(const sp<AMessage> &msg);

    // If RepeaterSource is currently dormant, because SurfaceFlinger didn't
    // send updates in a while, this is its wakeup call.
    void wakeUp();

protected:
    virtual ~RepeaterSource();

@@ -43,6 +47,7 @@ private:

    MediaBuffer *mBuffer;
    status_t mResult;
    int64_t mLastBufferUpdateUs;

    int64_t mStartTimeUs;
    int32_t mFrameCount;
Loading