Merge changes I426dc1f7,I7502f09f am: ec895dd834

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1591128

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I17e8647885e257617ed8f6f30dc40332a0de9ad8
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index ac86f72..154988d 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -66,6 +66,7 @@
     ENABLE_AUDIO_DEVICE_CALLBACK,
     GET_ACTIVE_MICROPHONES,
     GET_PORT_ID,
+    GET_RTP_DATA_USAGE,
     SET_PREFERRED_MICROPHONE_DIRECTION,
     SET_PREFERRED_MICROPHONE_FIELD_DIMENSION,
     SET_PRIVACY_SENSITIVE,
@@ -476,6 +477,23 @@
         *portId = (audio_port_handle_t)reply.readInt32();
         return NO_ERROR;
     }
+
+    status_t getRtpDataUsage(uint64_t *bytes)
+    {
+        ALOGV("getRtpDataUsage");
+        if (bytes == nullptr) {
+            return BAD_VALUE;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+        status_t status = remote()->transact(GET_RTP_DATA_USAGE, data, &reply);
+        if (status != OK
+                || (status = (status_t)reply.readInt32()) != NO_ERROR) {
+            *bytes = 0;
+            return status;
+        }
+        return reply.readUint64(bytes);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder");
@@ -759,6 +777,17 @@
             }
             return NO_ERROR;
         }
+        case GET_RTP_DATA_USAGE: {
+            ALOGV("GET_RTP_DATA_USAGE");
+            CHECK_INTERFACE(IMediaRecorder, data, reply);
+            uint64_t bytes;
+            status_t status = getRtpDataUsage(&bytes);
+            reply->writeInt32(status);
+            if (status == NO_ERROR) {
+                reply->writeUint64(bytes);
+            }
+            return NO_ERROR;
+        }
         case SET_PREFERRED_MICROPHONE_DIRECTION: {
             ALOGV("SET_PREFERRED_MICROPHONE_DIRECTION");
             CHECK_INTERFACE(IMediaRecorder, data, reply);
diff --git a/media/libmedia/include/media/IMediaRecorder.h b/media/libmedia/include/media/IMediaRecorder.h
index 651bd5e..6e69782 100644
--- a/media/libmedia/include/media/IMediaRecorder.h
+++ b/media/libmedia/include/media/IMediaRecorder.h
@@ -78,6 +78,7 @@
     virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
     virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
     virtual status_t getPortId(audio_port_handle_t *portId) = 0;
+    virtual status_t getRtpDataUsage(uint64_t *bytes) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/media/libmedia/include/media/MediaRecorderBase.h b/media/libmedia/include/media/MediaRecorderBase.h
index 8493f64..d9a7efb 100644
--- a/media/libmedia/include/media/MediaRecorderBase.h
+++ b/media/libmedia/include/media/MediaRecorderBase.h
@@ -77,6 +77,7 @@
     virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
     virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
     virtual status_t getPortId(audio_port_handle_t *portId) const = 0;
+    virtual status_t getRtpDataUsage(uint64_t *bytes) = 0;
 
 
 
diff --git a/media/libmedia/include/media/mediarecorder.h b/media/libmedia/include/media/mediarecorder.h
index fbcdb28..84c92f6 100644
--- a/media/libmedia/include/media/mediarecorder.h
+++ b/media/libmedia/include/media/mediarecorder.h
@@ -270,6 +270,7 @@
     status_t    setPreferredMicrophoneFieldDimension(float zoom);
 
     status_t    getPortId(audio_port_handle_t *portId) const;
+    status_t    getRtpDataUsage(uint64_t *bytes);
 
 private:
     void                    doCleanUp();
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index d9d1f25..e3cd9d8 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -913,4 +913,14 @@
     return mMediaRecorder->getPortId(portId);
 }
 
+status_t MediaRecorder::getRtpDataUsage(uint64_t *bytes)
+{
+    ALOGV("getRtpDataUsage");
+
+    if (mMediaRecorder == NULL) {
+        ALOGE("media recorder is not initialized yet");
+        return INVALID_OPERATION;
+    }
+    return mMediaRecorder->getRtpDataUsage(bytes);
+}
 } // namespace android
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 1cc255d..9f16a22 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -591,4 +591,13 @@
     }
     return NO_INIT;
 }
+
+status_t MediaRecorderClient::getRtpDataUsage(uint64_t *bytes) {
+    ALOGV("getRtpDataUsage");
+    Mutex::Autolock lock(mLock);
+    if (mRecorder != NULL) {
+        return mRecorder->getRtpDataUsage(bytes);
+    }
+    return NO_INIT;
+}
 }; // namespace android
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index 12257e5..e041855 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -86,6 +86,7 @@
     virtual     status_t   setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
     virtual     status_t   setPreferredMicrophoneFieldDimension(float zoom);
                 status_t   getPortId(audio_port_handle_t *portId) override;
+    virtual     status_t   getRtpDataUsage(uint64_t *bytes);
 
 private:
     friend class           MediaPlayerService;  // for accessing private constructor
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index b2f6407..ecbdf61 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -2568,6 +2568,14 @@
     return NO_INIT;
 }
 
+status_t StagefrightRecorder::getRtpDataUsage(uint64_t *bytes) {
+    if (mWriter != 0) {
+        *bytes = mWriter->getAccumulativeBytes();
+        return OK;
+    }
+    return NO_INIT;
+}
+
 status_t StagefrightRecorder::dump(
         int fd, const Vector<String16>& args) const {
     ALOGV("dump");
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 0362edd..4bba869 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -82,6 +82,7 @@
     virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
     virtual status_t setPreferredMicrophoneFieldDimension(float zoom);
             status_t getPortId(audio_port_handle_t *portId) const override;
+    virtual status_t getRtpDataUsage(uint64_t *bytes);
 
 private:
 
diff --git a/media/libstagefright/include/media/stagefright/MediaWriter.h b/media/libstagefright/include/media/stagefright/MediaWriter.h
index 17b1abf..9f20185 100644
--- a/media/libstagefright/include/media/stagefright/MediaWriter.h
+++ b/media/libstagefright/include/media/stagefright/MediaWriter.h
@@ -58,6 +58,7 @@
     virtual void updatePayloadType(int32_t /*payloadType*/) {}
     virtual void updateSocketNetwork(int64_t /*socketNetwork*/) {}
     virtual uint32_t getSequenceNum() { return 0; }
+    virtual uint64_t getAccumulativeBytes() { return 0; }
 
 protected:
     virtual ~MediaWriter() {}
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 73c94e8..61c06d1 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -876,6 +876,12 @@
 
     sp<ARTPSource> source = findSource(s, id);
 
+    // Report a final stastics to be used for rtp data usage.
+    int64_t nowUs = ALooper::GetNowUs();
+    int32_t timeDiff = (nowUs - mLastBitrateReportTimeUs) / 1000000ll;
+    int32_t bitrate = mCumulativeBytes * 8 / timeDiff;
+    source->notifyPktInfo(bitrate, true /* isRegular */);
+
     source->byeReceived();
 
     return OK;
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index dc0ddb9..c8f6985 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -46,10 +46,12 @@
 #define H265_NALU_SPS 0x21
 #define H265_NALU_PPS 0x22
 
-#define LINK_HEADER_SIZE 14
-#define IP_HEADER_SIZE 20
+#define IPV4_HEADER_SIZE 20
+#define IPV6_HEADER_SIZE 40
 #define UDP_HEADER_SIZE 8
-#define TCPIP_HEADER_SIZE (LINK_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE)
+#define TCPIPV4_HEADER_SIZE (IPV4_HEADER_SIZE + UDP_HEADER_SIZE)
+#define TCPIPV6_HEADER_SIZE (IPV6_HEADER_SIZE + UDP_HEADER_SIZE)
+#define TCPIP_HEADER_SIZE TCPIPV4_HEADER_SIZE
 #define RTP_HEADER_SIZE 12
 #define RTP_HEADER_EXT_SIZE 8
 #define RTP_FU_HEADER_SIZE 2
@@ -62,6 +64,9 @@
 static const size_t kMaxPacketSize = 1280;
 static char kCNAME[255] = "someone@somewhere";
 
+static const size_t kTrafficRecorderMaxEntries = 128;
+static const size_t kTrafficRecorderMaxTimeSpanMs = 2000;
+
 static int UniformRand(int limit) {
     return ((double)rand() * limit) / RAND_MAX;
 }
@@ -71,7 +76,8 @@
       mFd(dup(fd)),
       mLooper(new ALooper),
       mReflector(new AHandlerReflector<ARTPWriter>(this)),
-      mTrafficRec(new TrafficRecorder<uint32_t, size_t>(128)) {
+      mTrafficRec(new TrafficRecorder<uint32_t /* Time */, Bytes>(
+              kTrafficRecorderMaxEntries, kTrafficRecorderMaxTimeSpanMs)) {
     CHECK_GE(fd, 0);
     mIsIPv6 = false;
 
@@ -122,7 +128,8 @@
       mFd(dup(fd)),
       mLooper(new ALooper),
       mReflector(new AHandlerReflector<ARTPWriter>(this)),
-      mTrafficRec(new TrafficRecorder<uint32_t, size_t>(128)) {
+      mTrafficRec(new TrafficRecorder<uint32_t /* Time */, Bytes>(
+              kTrafficRecorderMaxEntries, kTrafficRecorderMaxTimeSpanMs)) {
     CHECK_GE(fd, 0);
     mIsIPv6 = false;
 
@@ -609,7 +616,8 @@
         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->writeBytes(buffer->size() +
+                (mIsIPv6 ? TCPIPV6_HEADER_SIZE : TCPIPV4_HEADER_SIZE));
         mTrafficRec->printAccuBitsForLastPeriod(1000, 1000);
     }
 
@@ -1371,6 +1379,10 @@
     return mSeqNo;
 }
 
+uint64_t ARTPWriter::getAccumulativeBytes() {
+    return mTrafficRec->readBytesForTotal();
+}
+
 static size_t getFrameSize(bool isWide, unsigned FT) {
     static const size_t kFrameSizeNB[8] = {
         95, 103, 118, 134, 148, 159, 204, 244
diff --git a/media/libstagefright/rtsp/ARTPWriter.h b/media/libstagefright/rtsp/ARTPWriter.h
index 69f560b..28d6ec5 100644
--- a/media/libstagefright/rtsp/ARTPWriter.h
+++ b/media/libstagefright/rtsp/ARTPWriter.h
@@ -53,6 +53,7 @@
     void updateSocketDscp(int32_t dscp);
     void updateSocketNetwork(int64_t socketNetwork);
     uint32_t getSequenceNum();
+    virtual uint64_t getAccumulativeBytes() override;
 
     virtual void onMessageReceived(const sp<AMessage> &msg);
     virtual void setTMMBNInfo(uint32_t opponentID, uint32_t bitrate);
@@ -118,7 +119,8 @@
 
     uint32_t mOpponentID;
     uint32_t mBitrate;
-    sp<TrafficRecorder<uint32_t, size_t> > mTrafficRec;
+    typedef uint64_t Bytes;
+    sp<TrafficRecorder<uint32_t /* Time */, Bytes> > mTrafficRec;
 
     int32_t mNumSRsSent;
     int32_t mRTPCVOExtMap;
diff --git a/media/libstagefright/rtsp/TrafficRecorder.h b/media/libstagefright/rtsp/TrafficRecorder.h
index f8e7c03..8ba8f90 100644
--- a/media/libstagefright/rtsp/TrafficRecorder.h
+++ b/media/libstagefright/rtsp/TrafficRecorder.h
@@ -27,44 +27,49 @@
 template <class Time, class Bytes>
 class TrafficRecorder : public RefBase {
 private:
+    constexpr static size_t kMinNumEntries = 4;
+    constexpr static size_t kMaxNumEntries = 1024;
+
     size_t mSize;
     size_t mSizeMask;
     Time *mTimeArray = NULL;
     Bytes *mBytesArray = NULL;
-    size_t mHeadIdx = 0;
-    size_t mTailIdx = 0;
+    size_t mHeadIdx;
+    size_t mTailIdx;
 
-    Time mClock = 0;
-    Time mLastTimeOfPrint = 0;
-    Bytes mAccuBytesOfPrint = 0;
+    int mLastReadIdx;
+
+    const Time mRecordLimit;
+    Time mClock;
+    Time mLastTimeOfPrint;
+    Bytes mAccuBytes;
+
 public:
-    TrafficRecorder();
-    TrafficRecorder(size_t size);
+    TrafficRecorder(size_t size, Time accuTimeLimit);
     virtual ~TrafficRecorder();
 
     void init();
-
     void updateClock(Time now);
-
+    Bytes readBytesForTotal();
     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) {
-    size_t exp;
-    for (exp = 0; exp < 32; exp++) {
-        if (size <= (1ul << exp)) {
-            break;
-        }
+TrafficRecorder<Time, Bytes>::TrafficRecorder(size_t size, Time recordLimit)
+    : mRecordLimit(recordLimit) {
+    if (size > kMaxNumEntries) {
+        LOG(VERBOSE) << "Limiting TrafficRecorder size to " << kMaxNumEntries;
+        size = kMaxNumEntries;
+    } else if (size < kMinNumEntries) {
+        LOG(VERBOSE) << "Limiting TrafficRecorder size to " << kMaxNumEntries;
+        size = kMinNumEntries;
     }
+
+    size_t exp = ((sizeof(size_t) == 8) ?
+                  64 - __builtin_clzl(size - 1) :
+                  32 - __builtin_clz(size - 1));
     mSize = (1ul << exp);         // size = 2^exp
     mSizeMask = mSize - 1;
 
@@ -84,9 +89,15 @@
 template <class Time, class Bytes>
 void TrafficRecorder<Time, Bytes>::init() {
     mHeadIdx = 0;
-    mTailIdx = 0;
-    mTimeArray[0] = 0;
-    mBytesArray[0] = 0;
+    mTailIdx = mSizeMask;
+    for (int i = 0 ; i < mSize ; i++) {
+        mTimeArray[i] = 0;
+        mBytesArray[i] = 0;
+    }
+    mClock = 0;
+    mLastReadIdx = 0;
+    mLastTimeOfPrint = 0;
+    mAccuBytes = 0;
 }
 
 template <class Time, class Bytes>
@@ -95,54 +106,71 @@
 }
 
 template <class Time, class Bytes>
-Bytes TrafficRecorder<Time, Bytes>::readBytesForLastPeriod(Time period) {
-    Bytes bytes = 0;
+Bytes TrafficRecorder<Time, Bytes>::readBytesForTotal() {
+    return mAccuBytes;
+}
 
-    size_t i = mTailIdx;
-    while (i != mHeadIdx) {
-        LOG(VERBOSE) << "READ " << i << " time " << mTimeArray[i] << " \t EndOfPeriod " << mClock - period;
+template <class Time, class Bytes>
+Bytes TrafficRecorder<Time, Bytes>::readBytesForLastPeriod(Time period) {
+    // Not enough data
+    if (period > mClock)
+        return 0;
+
+    Bytes bytes = 0;
+    int i = mHeadIdx;
+    while (i != mTailIdx) {
+        LOG(VERBOSE) << "READ " << i << " time " << mTimeArray[i]
+                << " \t EndOfPeriod " << mClock - period
+                << "\t\t Bytes:" << mBytesArray[i] << "\t\t Accu: " << bytes;
         if (mTimeArray[i] < mClock - period) {
             break;
         }
         bytes += mBytesArray[i];
-        i = (i + mSize - 1) & mSizeMask;
+        i = (i - 1) & mSizeMask;
     }
-    mHeadIdx = i;
+    mLastReadIdx = (i + 1) & mSizeMask;
+
     return bytes;
 }
 
 template <class Time, class Bytes>
 void TrafficRecorder<Time, Bytes>::writeBytes(Bytes bytes) {
-    size_t writeIdx;
-    if (mClock == mTimeArray[mTailIdx]) {
-        writeIdx = mTailIdx;
+    int writeIdx;
+    if (mClock == mTimeArray[mHeadIdx]) {
+        writeIdx = mHeadIdx;
         mBytesArray[writeIdx] += bytes;
     } else {
-        writeIdx = (mTailIdx + 1) % mSize;
+        writeIdx = (mHeadIdx + 1) & mSizeMask;
         mTimeArray[writeIdx] = mClock;
         mBytesArray[writeIdx] = bytes;
     }
 
     LOG(VERBOSE) << "WRITE " << writeIdx << " time " << mClock;
-    if (writeIdx == mHeadIdx) {
-        LOG(WARNING) << "Traffic recorder size exceeded at " << mHeadIdx;
-        mHeadIdx = (mHeadIdx + 1) & mSizeMask;
+    if (writeIdx == mTailIdx) {
+        mTailIdx = (mTailIdx + 1) & mSizeMask;
     }
 
-    mTailIdx = writeIdx;
-    mAccuBytesOfPrint += bytes;
+    mHeadIdx = writeIdx;
+    mAccuBytes += 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();
+    Time timeSinceLastPrint = mClock - mLastTimeOfPrint;
+    if (timeSinceLastPrint < period)
+        return;
+
+    Bytes sum = readBytesForLastPeriod(period);
+    Time readPeriod = mClock - mTimeArray[mLastReadIdx];
+
+    float numOfUnit = (float)(readPeriod) / (unit + FLT_MIN);
+    ALOGD("Actual Tx period %.3f unit \t %.0f bytes (%.0f Kbits)/Unit",
+          numOfUnit, sum / numOfUnit, sum * 8.f / numOfUnit / 1000.f);
+    mLastTimeOfPrint = mClock;
+
+    if (mClock - mTimeArray[mTailIdx] < mRecordLimit) {
+        // Size is not enough to record bytes for mRecordLimit period
+        ALOGW("Traffic recorder size is not enough. mRecordLimit %d", mRecordLimit);
     }
 }