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

Commit 7c5b5c0c authored by Kim Sungyeon's avatar Kim Sungyeon Committed by Lajos Molnar
Browse files

VT: Add TMMBR function on Rx



Now Player(Rx) can measure and check Rx status(bitrate & loss)
And send TMMBR base on the status

Merged-in: I203ff5022ca95859c8acc662ba6cedff256a6995
Change-Id: I203ff5022ca95859c8acc662ba6cedff256a6995
Signed-off-by: default avatarKim Sungyeon <sy85.kim@samsung.com>
parent 0175f4e1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ void NuPlayer::RTPSource::prepareAsync() {
        // index(i) should be started from 1. 0 is reserved for [root]
        mRTPConn->addStream(sockRtp, sockRtcp, desc, i + 1, notify, false);
        mRTPConn->setSelfID(info->mSelfID);
        mRTPConn->setMinMaxBitrate(videoMinBitrate, 512000);

        info->mRTPSocket = sockRtp;
        info->mRTCPSocket = sockRtcp;
+2 −0
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ namespace android {
struct ALooper;
struct AnotherPacketSource;

const int32_t videoMinBitrate = 192000;

struct NuPlayer::RTPSource : public NuPlayer::Source {
    RTPSource(
            const sp<AMessage> &notify,
+26 −2
Original line number Diff line number Diff line
@@ -72,7 +72,8 @@ struct ARTPConnection::StreamInfo {
ARTPConnection::ARTPConnection(uint32_t flags)
    : mFlags(flags),
      mPollEventPending(false),
      mLastReceiverReportTimeUs(-1) {
      mLastReceiverReportTimeUs(-1),
      mLastBitrateReportTimeUs(-1) {
}

ARTPConnection::~ARTPConnection() {
@@ -411,6 +412,7 @@ void ARTPConnection::onPollStreams() {
    }

    int64_t nowUs = ALooper::GetNowUs();
    showRxBitrate(nowUs);
    if (mLastReceiverReportTimeUs <= 0
            || mLastReceiverReportTimeUs + 5000000LL <= nowUs) {
        sp<ABuffer> buffer = new ABuffer(kMaxUDPSize);
@@ -435,7 +437,10 @@ void ARTPConnection::onPollStreams() {
            for (size_t i = 0; i < s->mSources.size(); ++i) {
                sp<ARTPSource> source = s->mSources.valueAt(i);

                if (source->isNeedToReport()) {
                    source->addReceiverReport(buffer);
                    source->addTMMBR(buffer);
                }

                if (mFlags & kRegularlyRequestFIR) {
                    source->addFIR(buffer);
@@ -513,6 +518,7 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
            0,
            remoteAddrLen > 0 ? pRemoteRTCPAddr : NULL,
            remoteAddrLen > 0 ? &remoteAddrLen : NULL);
        mCumulativeBytes += nbytes;
    } while (nbytes < 0 && errno == EINTR);

    if (nbytes <= 0) {
@@ -875,6 +881,7 @@ sp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) {
                srcId, info->mSessionDesc, info->mIndex, info->mNotifyMsg);

        source->setSelfID(mSelfID);
        source->setMinMaxBitrate(mMinBitrate, mMaxBitrate);
        info->mSources.add(srcId, source);
    } else {
        source = info->mSources.valueAt(index);
@@ -894,6 +901,23 @@ void ARTPConnection::setSelfID(const uint32_t selfID) {
    mSelfID = selfID;
}

void ARTPConnection::setMinMaxBitrate(int32_t min, int32_t max) {
    mMinBitrate = min;
    mMaxBitrate = max;
}

void ARTPConnection::showRxBitrate(int64_t nowUs) {
    if (mLastBitrateReportTimeUs <= 0) {
        mCumulativeBytes = 0;
        mLastBitrateReportTimeUs = nowUs;
    }
    else if (mLastBitrateReportTimeUs + 1000000ll <= nowUs) {
        int32_t timeDiff = (nowUs - mLastBitrateReportTimeUs) / 1000000ll;
        ALOGI("Actual Rx bitrate : %d bits/sec", mCumulativeBytes * 8 / timeDiff);
        mCumulativeBytes = 0;
        mLastBitrateReportTimeUs = nowUs;
    }
}
void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
    int32_t index;
    CHECK(msg->findInt32("index", &index));
+7 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ struct ARTPConnection : public AHandler {
    void injectPacket(int index, const sp<ABuffer> &buffer);

    void setSelfID(const uint32_t selfID);
    void setMinMaxBitrate(int32_t min, int32_t max);

    // Creates a pair of UDP datagram sockets bound to adjacent ports
    // (the rtpSocket is bound to an even port, the rtcpSocket to the
@@ -80,14 +81,20 @@ private:

    bool mPollEventPending;
    int64_t mLastReceiverReportTimeUs;
    int64_t mLastBitrateReportTimeUs;

    int32_t mSelfID;

    int32_t mMinBitrate;
    int32_t mMaxBitrate;
    int32_t mCumulativeBytes;

    void onAddStream(const sp<AMessage> &msg);
    void onRemoveStream(const sp<AMessage> &msg);
    void onPollStreams();
    void onInjectPacket(const sp<AMessage> &msg);
    void onSendReceiverReports();
    void showRxBitrate(int64_t nowUs);

    status_t receive(StreamInfo *info, bool receiveRTP);

+57 −0
Original line number Diff line number Diff line
@@ -263,10 +263,14 @@ void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
        fraction = (intervalPacketLost << 8) / intervalExpected;
    }

    mQualManager.setTargetBitrate(fraction);

    mPrevExpected = expected;
    mPrevNumBuffersReceived = mNumBuffersReceived;
    int32_t cumulativePacketLost = (int32_t)expected - mNumBuffersReceived;

    ALOGI("UID %p expectedPkts %lld lostPkts %lld", this, (long long)intervalExpected, (long long)intervalPacketLost);

    uint8_t *data = buffer->data() + buffer->size();

    data[0] = 0x80 | 1;
@@ -321,10 +325,63 @@ void ARTPSource::addReceiverReport(const sp<ABuffer> &buffer) {
    buffer->setRange(buffer->offset(), buffer->size() + 32);
}

void ARTPSource::addTMMBR(const sp<ABuffer> &buffer) {
    if (buffer->size() + 32 > buffer->capacity()) {
        ALOGW("RTCP buffer too small to accomodate RR.");
        return;
    }
    if (mQualManager.mTargetBitrate <= 0)
        return;

    uint8_t *data = buffer->data() + buffer->size();

    data[0] = 0x80 | 3; // TMMBR
    data[1] = 205;      // TSFB
    data[2] = 0;
    data[3] = 4;        // total (4+1) * sizeof(int32_t) = 20 bytes
    data[4] = kSourceID >> 24;
    data[5] = (kSourceID >> 16) & 0xff;
    data[6] = (kSourceID >> 8) & 0xff;
    data[7] = kSourceID & 0xff;

    *(int32_t*)(&data[8]) = 0;  // 4 bytes blank

    data[12] = mID >> 24;
    data[13] = (mID >> 16) & 0xff;
    data[14] = (mID >> 8) & 0xff;
    data[15] = mID & 0xff;

    int32_t targetBitrate = mQualManager.mTargetBitrate;
    int32_t exp, mantissa;

    // Round off to the nearest 2^4th
    ALOGI("UE -> Op Req Rx bitrate : %d ", targetBitrate & 0xfffffff0);
    for (exp=4 ; exp < 32 ; exp++)
        if (((targetBitrate >> exp) & 0x01) != 0)
            break;
    mantissa = targetBitrate >> exp;

    data[16] = ((exp << 2) & 0xfc) | ((mantissa & 0x18000) >> 15);
    data[17] =                        (mantissa & 0x07f80) >> 7;
    data[18] =                        (mantissa & 0x0007f) << 1;
    data[19] = 40;              // 40 bytes overhead;

    buffer->setRange(buffer->offset(), buffer->size() + 20);
}

void ARTPSource::setSelfID(const uint32_t selfID) {
    kSourceID = selfID;
}

void ARTPSource::setMinMaxBitrate(int32_t min, int32_t max) {
    mQualManager.setMinMaxBitrate(min, max);
}

bool ARTPSource::isNeedToReport() {
    int64_t intervalReceived = mNumBuffersReceived - mPrevNumBuffersReceived;
    return (intervalReceived > 0) ? true : false;
}

void ARTPSource::noticeAbandonBuffer(int cnt) {
    mNumBuffersReceived -= cnt;
}
Loading