VT: Refine codes in AAVCAssembler.
- Fixed a crash problem by overflow when rtp time hits 2^31
- Code clean up for jitter buffer's logging.
Bug: 165061754
Merged-in: I1c9f39d8857870e1590d1f320f0385e0a500c7e6
Change-Id: I1c9f39d8857870e1590d1f320f0385e0a500c7e6
Signed-off-by: Kim Sungyeon <sy85.kim@samsung.com>
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index facff09..9d75828 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -109,35 +109,28 @@
}
sp<ABuffer> buffer = *queue->begin();
- int32_t rtpTime;
- CHECK(buffer->meta()->findInt32("rtp-time", &rtpTime));
+ uint32_t rtpTime;
+ CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
int64_t startTime = source->mFirstSysTime / 1000;
int64_t nowTime = ALooper::GetNowUs() / 1000;
int64_t playedTime = nowTime - startTime;
- int32_t playedTimeRtp = source->mFirstRtpTime +
+ int64_t playedTimeRtp = source->mFirstRtpTime +
(((uint32_t)playedTime) * (source->mClockRate / 1000));
- const int32_t jitterTime = (int32_t)(source->mClockRate / ((float)1000 / (source->mJbTime)));
- int32_t expiredTimeInJb = rtpTime + jitterTime;
+ const uint32_t jitterTime = (uint32_t)(source->mClockRate / ((float)1000 / (source->mJbTime)));
+ uint32_t expiredTimeInJb = rtpTime + jitterTime;
bool isExpired = expiredTimeInJb <= (playedTimeRtp);
bool isTooLate200 = expiredTimeInJb < (playedTimeRtp - jitterTime);
bool isTooLate300 = expiredTimeInJb < (playedTimeRtp - (jitterTime * 3 / 2));
if (mShowQueue && mShowQueueCnt < 20) {
showCurrentQueue(queue);
- ALOGD("start=%lld, now=%lld, played=%lld", (long long)startTime,
- (long long)nowTime, (long long)playedTime);
- ALOGD("rtp-time(JB)=%d, played-rtp-time(JB)=%d, expired-rtp-time(JB)=%d isExpired=%d",
- rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
+ printNowTimeUs(startTime, nowTime, playedTime);
+ printRTPTime(rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
mShowQueueCnt++;
}
AAVCAssembler::addNack(source);
- ALOGV("start=%lld, now=%lld, played=%lld", (long long)startTime,
- (long long)nowTime, (long long)playedTime);
- ALOGV("rtp-time(JB)=%d, played-rtp-time(JB)=%d, expired-rtp-time(JB)=%d isExpired=%d",
- rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
-
if (!isExpired) {
ALOGV("buffering in jitter buffer.");
return NOT_ENOUGH_DATA;
@@ -147,42 +140,21 @@
ALOGW("=== WARNING === buffer arrived 200ms late. === WARNING === ");
if (isTooLate300) {
- ALOGW("buffer arrived too late. 300ms..");
- ALOGW("start=%lld, now=%lld, played=%lld", (long long)startTime,
- (long long)nowTime, (long long)playedTime);
- ALOGW("rtp-time(JB)=%d, plyed-rtp-time(JB)=%d, exp-rtp-time(JB)=%d diff=%lld isExpired=%d",
- rtpTime, playedTimeRtp, expiredTimeInJb,
- ((long long)playedTimeRtp) - expiredTimeInJb, isExpired);
- ALOGW("expected Seq. NO =%d", buffer->int32Data());
+ ALOGW("buffer arrived after 300ms ... \t Diff in Jb=%lld \t Seq# %d",
+ ((long long)playedTimeRtp) - expiredTimeInJb, buffer->int32Data());
+ printNowTimeUs(startTime, nowTime, playedTime);
+ printRTPTime(rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
- List<sp<ABuffer> >::iterator it = queue->begin();
- while (it != queue->end()) {
- CHECK((*it)->meta()->findInt32("rtp-time", &rtpTime));
- if (rtpTime + jitterTime >= playedTimeRtp) {
- mNextExpectedSeqNo = (*it)->int32Data();
- break;
- }
- it++;
- }
- source->noticeAbandonBuffer();
+ mNextExpectedSeqNo = pickProperSeq(queue, jitterTime, playedTimeRtp);
}
if (mNextExpectedSeqNoValid) {
int32_t size = queue->size();
- int32_t cnt = 0;
- List<sp<ABuffer> >::iterator it = queue->begin();
- while (it != queue->end()) {
- if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
- break;
- }
+ int32_t cntRemove = deleteUnitUnderSeq(queue, mNextExpectedSeqNo);
- it = queue->erase(it);
- cnt++;
- }
-
- if (cnt > 0) {
- source->noticeAbandonBuffer(cnt);
- ALOGW("delete %d of %d buffers", cnt, size);
+ if (cntRemove > 0) {
+ source->noticeAbandonBuffer(cntRemove);
+ ALOGW("delete %d of %d buffers", cntRemove, size);
}
if (queue->empty()) {
return NOT_ENOUGH_DATA;
@@ -339,8 +311,8 @@
size_t totalCount = 1;
bool complete = false;
- int32_t rtpTimeStartAt;
- CHECK(buffer->meta()->findInt32("rtp-time", &rtpTimeStartAt));
+ uint32_t rtpTimeStartAt;
+ CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTimeStartAt));
uint32_t startSeqNo = buffer->int32Data();
bool pFrame = nalType == 0x1;
@@ -368,8 +340,8 @@
return WRONG_SEQUENCE_NUMBER;
}
- int32_t rtpTime;
- CHECK(buffer->meta()->findInt32("rtp-time", &rtpTime));
+ uint32_t rtpTime;
+ CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
if (size < 2
|| data[0] != indicator
|| (data[1] & 0x1f) != nalType
@@ -379,12 +351,8 @@
// Delete the whole start of the FU.
- it = queue->begin();
- for (size_t i = 0; i <= totalCount; ++i) {
- it = queue->erase(it);
- }
-
mNextExpectedSeqNo = expectedSeqNo + 1;
+ deleteUnitUnderSeq(queue, mNextExpectedSeqNo);
return MALFORMED_PACKET;
}
@@ -395,22 +363,11 @@
expectedSeqNo = buffer->int32Data() + 1;
if (data[1] & 0x40) {
- if (pFrame) {
- ALOGV("checking p-frame losses.. recvBufs %d diff %d drop? %d",
- (uint32_t)totalCount, expectedSeqNo - startSeqNo,
- totalCount < ((expectedSeqNo - startSeqNo) / 2));
- if (totalCount < ((expectedSeqNo - startSeqNo) / 2)) {
- ALOGI("drop p-frame. recvBufs %d lastSeq %d startSeq %d",
- (uint32_t)totalCount, expectedSeqNo - 1, startSeqNo);
-
- it = queue->begin();
- for (size_t i = 0; i <= totalCount; ++i) {
- it = queue->erase(it);
- }
+ if (pFrame && !recycleUnit(startSeqNo, expectedSeqNo, totalCount, 0.5f)) {
mNextExpectedSeqNo = expectedSeqNo;
+ deleteUnitUnderSeq(queue, mNextExpectedSeqNo);
return MALFORMED_PACKET;
- }
}
// This is the last fragment.
complete = true;
@@ -518,6 +475,58 @@
msg->post();
}
+int32_t AAVCAssembler::pickProperSeq(const Q *q, uint32_t jit, int64_t play) {
+ sp<ABuffer> buffer = *(q->begin());
+ uint32_t rtpTime;
+ int32_t nextSeqNo = buffer->int32Data();
+
+ Q::const_iterator it = q->begin();
+ while (it != q->end()) {
+ CHECK((*it)->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
+ // if pkt in time exists, that should be the next pivot
+ if (rtpTime + jit >= play) {
+ nextSeqNo = (*it)->int32Data();
+ break;
+ }
+ it++;
+ }
+ return nextSeqNo;
+}
+
+bool AAVCAssembler::recycleUnit(uint32_t start, uint32_t end, size_t avail, float goodRatio) {
+ float total = end - start;
+ float exist = avail;
+ bool isRecycle = (exist / total) >= goodRatio;
+
+ ALOGV("checking p-frame losses.. recvBufs %f diff %f recycle? %d",
+ exist, total, isRecycle);
+
+ return isRecycle;
+}
+
+int32_t AAVCAssembler::deleteUnitUnderSeq(Q *q, uint32_t seq) {
+ int32_t initSize = q->size();
+ Q::iterator it = q->begin();
+ while (it != q->end()) {
+ if ((uint32_t)(*it)->int32Data() >= seq) {
+ break;
+ }
+ it++;
+ }
+ q->erase(q->begin(), it);
+ return initSize - q->size();
+}
+
+inline void AAVCAssembler::printNowTimeUs(int64_t start, int64_t now, int64_t play) {
+ ALOGD("start=%lld, now=%lld, played=%lld",
+ (long long)start, (long long)now, (long long)play);
+}
+
+inline void AAVCAssembler::printRTPTime(uint32_t rtp, int64_t play, uint32_t exp, bool isExp) {
+ ALOGD("rtp-time(JB)=%u, played-rtp-time(JB)=%lld, expired-rtp-time(JB)=%u isExpired=%d",
+ rtp, (long long)play, exp, isExp);
+}
+
ARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore(
const sp<ARTPSource> &source) {
AssemblyStatus status = addNALUnit(source);
diff --git a/media/libstagefright/rtsp/AAVCAssembler.h b/media/libstagefright/rtsp/AAVCAssembler.h
index 11ba08c..b9add64 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.h
+++ b/media/libstagefright/rtsp/AAVCAssembler.h
@@ -25,6 +25,8 @@
namespace android {
+using Q = List<sp<ABuffer> >;
+
struct ABuffer;
struct AMessage;
@@ -55,6 +57,12 @@
void submitAccessUnit();
+ int32_t pickProperSeq(const Q *q, uint32_t jit, int64_t play);
+ bool recycleUnit(uint32_t start, uint32_t end, size_t avail, float goodRatio);
+ int32_t deleteUnitUnderSeq(Q *q, uint32_t seq);
+ void printNowTimeUs(int64_t start, int64_t now, int64_t play);
+ void printRTPTime(uint32_t rtp, int64_t play, uint32_t exp, bool isExp);
+
DISALLOW_EVIL_CONSTRUCTORS(AAVCAssembler);
};
diff --git a/media/libstagefright/rtsp/AHEVCAssembler.cpp b/media/libstagefright/rtsp/AHEVCAssembler.cpp
index 7b9ccc1..2514c6b 100644
--- a/media/libstagefright/rtsp/AHEVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AHEVCAssembler.cpp
@@ -63,19 +63,19 @@
}
sp<ABuffer> buffer = *queue->begin();
- int32_t rtpTime;
- CHECK(buffer->meta()->findInt32("rtp-time", &rtpTime));
+ uint32_t rtpTime;
+ CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
int64_t startTime = source->mFirstSysTime / 1000;
int64_t nowTime = ALooper::GetNowUs() / 1000;
int64_t playedTime = nowTime - startTime;
- int32_t playedTimeRtp = source->mFirstRtpTime +
+ int64_t playedTimeRtp = source->mFirstRtpTime +
(((uint32_t)playedTime) * (source->mClockRate / 1000));
- int32_t expiredTimeInJb = rtpTime + (source->mClockRate / 5);
+ const uint32_t expiredTimeInJb = rtpTime + (source->mClockRate / 5);
bool isExpired = expiredTimeInJb <= (playedTimeRtp);
ALOGV("start=%lld, now=%lld, played=%lld", (long long)startTime,
(long long)nowTime, (long long)playedTime);
- ALOGV("rtp-time(JB)=%d, played-rtp-time(JB)=%d, expired-rtp-time(JB)=%d isExpired=%d",
- rtpTime, playedTimeRtp, expiredTimeInJb, isExpired);
+ ALOGV("rtp-time(JB)=%u, played-rtp-time(JB)=%lld, expired-rtp-time(JB)=%u isExpired=%d",
+ rtpTime, (long long)playedTimeRtp, expiredTimeInJb, isExpired);
if (!isExpired) {
ALOGV("buffering in jitter buffer.");
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 9ae00ac..5c8c71e 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -129,8 +129,8 @@
buffer->meta()->findInt32("ssrc", &ssrc);
if (mNumBuffersReceived++ == 0 && mFirstSysTime == 0) {
- int32_t firstRtpTime;
- CHECK(buffer->meta()->findInt32("rtp-time", &firstRtpTime));
+ uint32_t firstRtpTime;
+ CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&firstRtpTime));
mFirstSysTime = ALooper::GetNowUs();
mHighestSeqNumber = seqNum;
mBaseSeqNumber = seqNum;
diff --git a/media/libstagefright/rtsp/ARTPSource.h b/media/libstagefright/rtsp/ARTPSource.h
index 9f5c4b3..a68740e 100644
--- a/media/libstagefright/rtsp/ARTPSource.h
+++ b/media/libstagefright/rtsp/ARTPSource.h
@@ -59,7 +59,7 @@
void noticeAbandonBuffer(int cnt=1);
int32_t mFirstSeqNumber;
- int32_t mFirstRtpTime;
+ uint32_t mFirstRtpTime;
int64_t mFirstSysTime;
int32_t mClockRate;