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);
}
}