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

Commit 71a9abf6 authored by Kim Sungyeon's avatar Kim Sungyeon Committed by Lajos Molnar
Browse files

VT: ARTPWriter: Add traffic recorder



Introduce TrafficRecorder class
  - Record amount of bytes that has sent in a same sendAVCData() loop.
    This can be used for another sendXXXData() loop.
  - Record amount of bytes until a new request of Bps printing.

Bug: 165061754
Merged-in: I935ec1f5ba2c1fda94f3f89ebfab60c8b5d91cf4
Change-Id: I935ec1f5ba2c1fda94f3f89ebfab60c8b5d91cf4
Signed-off-by: default avatarKim Sungyeon <sy85.kim@samsung.com>
parent 6ad0a2f1
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -70,7 +70,8 @@ ARTPWriter::ARTPWriter(int fd)
    : mFlags(0),
      mFd(dup(fd)),
      mLooper(new ALooper),
      mReflector(new AHandlerReflector<ARTPWriter>(this)) {
      mReflector(new AHandlerReflector<ARTPWriter>(this)),
      mTrafficRec(new TrafficRecorder<uint32_t, size_t>(128)) {
    CHECK_GE(fd, 0);
    mIsIPv6 = false;

@@ -120,7 +121,8 @@ ARTPWriter::ARTPWriter(int fd, String8& localIp, int localPort, String8& remoteI
    : mFlags(0),
      mFd(dup(fd)),
      mLooper(new ALooper),
      mReflector(new AHandlerReflector<ARTPWriter>(this)) {
      mReflector(new AHandlerReflector<ARTPWriter>(this)),
      mTrafficRec(new TrafficRecorder<uint32_t, size_t>(128)) {
    CHECK_GE(fd, 0);
    mIsIPv6 = false;

@@ -573,6 +575,10 @@ void ARTPWriter::send(const sp<ABuffer> &buffer, bool isRTCP) {

    if (n != (ssize_t)buffer->size()) {
        ALOGW("packets can not be sent. ret=%d, buf=%d", (int)n, (int)buffer->size());
    } else {
        // Record current traffic & Print bits while last 1sec (1000ms)
        mTrafficRec->writeBytes(buffer->size());
        mTrafficRec->printAccuBitsForLastPeriod(1000, 1000);
    }

#if LOG_TO_FILES
@@ -1073,6 +1079,7 @@ void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) {
        isSpsPps = true;
    }

    mTrafficRec->updateClock(ALooper::GetNowUs() / 1000);
    sp<ABuffer> buffer = new ABuffer(kMaxPacketSize);
    if (mediaBuf->range_length() + TCPIP_HEADER_SIZE + RTP_HEADER_SIZE + RTP_HEADER_EXT_SIZE
            + RTP_PAYLOAD_ROOM_SIZE <= buffer->capacity()) {
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <sys/socket.h>

#include <android/multinetwork.h>
#include "TrafficRecorder.h"

#define LOG_TO_FILES    0

@@ -117,6 +118,7 @@ private:

    uint32_t mOpponentID;
    uint32_t mBitrate;
    sp<TrafficRecorder<uint32_t, size_t> > mTrafficRec;

    int32_t mNumSRsSent;
    int32_t mRTPCVOExtMap;
+153 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef A_TRAFFIC_RECORDER_H_

#define A_TRAFFIC_RECORDER_H_

#include <utils/Log.h>
#include <utils/RefBase.h>

namespace android {

// Circular array to save recent amount of bytes
template <class Time, class Bytes>
class TrafficRecorder : public RefBase {
private:
    int mSize;
    int mSizeMask;
    Time* mTimeArray = NULL;
    Bytes* mBytesArray = NULL;
    int mHeadIdx = 0;
    int mTailIdx = 0;

    Time mClock = 0;
    Time mLastTimeOfPrint = 0;
    Bytes mAccuBytesOfPrint = 0;
public:
    TrafficRecorder();
    TrafficRecorder(size_t size);
    virtual ~TrafficRecorder();

    void init();

    void updateClock(Time now);

    Bytes readBytesForLastPeriod(Time period);
    void writeBytes(Bytes bytes);

    void printAccuBitsForLastPeriod(Time period, Time unit);
};

template <class Time, class Bytes>
TrafficRecorder<Time, Bytes>::TrafficRecorder() {
    TrafficRecorder(128);
}

template <class Time, class Bytes>
TrafficRecorder<Time, Bytes>::TrafficRecorder(size_t size) {
    int exp;
    for (exp = 0 ; exp < 32 ; exp++) {
        if (size <= (1 << exp))
            break;
    }
    mSize = (1 << exp);         // size = 2^exp
    mSizeMask = mSize - 1;

    ALOGV("TrafficRecorder Init size %u", mSize);
    if (mTimeArray != NULL)
        free(mTimeArray);
    if (mBytesArray != NULL)
        free(mBytesArray);
    mTimeArray = (Time*)malloc(sizeof(Time) * mSize);
    mBytesArray = (Bytes*)malloc(sizeof(Bytes) * mSize);

    init();
}

template <class Time, class Bytes>
TrafficRecorder<Time, Bytes>::~TrafficRecorder() {
    free(mTimeArray);
    free(mBytesArray);
}

template <class Time, class Bytes>
void TrafficRecorder<Time, Bytes>::init() {
    mHeadIdx = 0;
    mTailIdx = 0;
    mTimeArray[0] = 0;
    mBytesArray[0] = 0;
}

template <class Time, class Bytes>
void TrafficRecorder<Time, Bytes>::updateClock(Time now) {
    mClock = now;
}

template <class Time, class Bytes>
Bytes TrafficRecorder<Time, Bytes>::readBytesForLastPeriod(Time period) {
    Bytes bytes = 0;

    int i = mTailIdx;
    while(i != mHeadIdx) {
        ALOGV("READ %d time %d \t EndOfPeriod %d", i, mTimeArray[i], mClock - period);
        if (mTimeArray[i] < mClock - period) {
            break;
        }
        bytes += mBytesArray[i];
        i = (i - 1 + mSize) & mSizeMask;
    }
    mHeadIdx = i;
    return bytes;
}

template <class Time, class Bytes>
void TrafficRecorder<Time, Bytes>::writeBytes(Bytes bytes) {
    int writeIdx;
    if(mClock == mTimeArray[mTailIdx]) {
        writeIdx = mTailIdx;
        mBytesArray[writeIdx] += bytes;
    } else {
        writeIdx = (mTailIdx + 1) % mSize;
        mTimeArray[writeIdx] = mClock;
        mBytesArray[writeIdx] = bytes;
    }

    ALOGV("WRITE %d time %d", writeIdx, mClock);
    if (writeIdx == mHeadIdx) {
        ALOGW("Traffic recorder size exceeded at %d", mHeadIdx);
        mHeadIdx = (mHeadIdx + 1) & mSizeMask;
    }

    mTailIdx = writeIdx;
    mAccuBytesOfPrint += bytes;
}

template <class Time, class Bytes>
void TrafficRecorder<Time, Bytes>::printAccuBitsForLastPeriod(Time period, Time unit) {
    Time duration = mClock - mLastTimeOfPrint;
    float numOfUnit = (float)duration / unit;
    if(duration > period) {
        ALOGD("Actual Tx period %.0f ms \t %.0f Bits/Unit",
              numOfUnit * 1000.f, mAccuBytesOfPrint * 8.f / numOfUnit);
        mLastTimeOfPrint = mClock;
        mAccuBytesOfPrint = 0;
        init();
    }
}
}  // namespace android

#endif  // A_TRAFFIC_RECORDER_H_