Loading media/libmediaplayerservice/nuplayer/RTPSource.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ NuPlayer::RTPSource::RTPSource( mFinalResult(OK), mBuffering(false), mInPreparationPhase(true), mRTPConn(new ARTPConnection), mRTPConn(new ARTPConnection(ARTPConnection::kViLTEConnection)), mEOSTimeoutAudio(0), mEOSTimeoutVideo(0), mLastCVOUpdated(-1) { Loading Loading @@ -111,7 +111,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); mRTPConn->setMinMaxBitrate(videoMinBitrate, info->mAS * 1000); info->mRTPSocket = sockRtp; info->mRTCPSocket = sockRtcp; Loading media/libstagefright/rtsp/ARTPConnection.cpp +81 −23 Original line number Diff line number Diff line Loading @@ -427,7 +427,8 @@ void ARTPConnection::onPollStreams() { } int64_t nowUs = ALooper::GetNowUs(); showRxBitrate(nowUs); checkRxBitrate(nowUs); if (mLastReceiverReportTimeUs <= 0 || mLastReceiverReportTimeUs + 5000000LL <= nowUs) { sp<ABuffer> buffer = new ABuffer(kMaxUDPSize); Loading @@ -452,10 +453,7 @@ 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); Loading @@ -465,22 +463,7 @@ void ARTPConnection::onPollStreams() { if (buffer->size() > 0) { ALOGV("Sending RR..."); struct sockaddr* pRemoteRTCPAddr; int sizeSockSt; if (s->isIPv6) { pRemoteRTCPAddr = (struct sockaddr *)&s->mRemoteRTCPAddr6; sizeSockSt = sizeof(struct sockaddr_in6); } else { pRemoteRTCPAddr = (struct sockaddr *)&s->mRemoteRTCPAddr; sizeSockSt = sizeof(struct sockaddr_in); } ssize_t n; do { n = sendto( s->mRTCPSocket, buffer->data(), buffer->size(), 0, pRemoteRTCPAddr, sizeSockSt); } while (n < 0 && errno == EINTR); ssize_t n = send(s, buffer); if (n <= 0) { ALOGW("failed to send RTCP receiver report (%s).", Loading Loading @@ -524,6 +507,9 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { (!receiveRTP && s->mNumRTCPPacketsReceived == 0) ? sizeSockSt : 0; if (mFlags & kViLTEConnection) remoteAddrLen = 0; ssize_t nbytes; do { nbytes = recvfrom( Loading Loading @@ -554,6 +540,36 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { return err; } ssize_t ARTPConnection::send(const StreamInfo *info, const sp<ABuffer> buffer) { struct sockaddr* pRemoteRTCPAddr; int sizeSockSt; /* It seems this isIPv6 variable is useless. * We should remove it to prevent confusion */ if (info->isIPv6) { pRemoteRTCPAddr = (struct sockaddr *)&info->mRemoteRTCPAddr6; sizeSockSt = sizeof(struct sockaddr_in6); } else { pRemoteRTCPAddr = (struct sockaddr *)&info->mRemoteRTCPAddr; sizeSockSt = sizeof(struct sockaddr_in); } if (mFlags & kViLTEConnection) { ALOGV("ViLTE RTCP"); pRemoteRTCPAddr = NULL; sizeSockSt = 0; } ssize_t n; do { n = sendto( info->mRTCPSocket, buffer->data(), buffer->size(), 0, pRemoteRTCPAddr, sizeSockSt); } while (n < 0 && errno == EINTR); return n; } status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) { if (s->mNumRTPPacketsReceived++ == 0) { sp<AMessage> notify = s->mNotifyMsg->dup(); Loading Loading @@ -970,14 +986,56 @@ void ARTPConnection::setMinMaxBitrate(int32_t min, int32_t max) { mMaxBitrate = max; } void ARTPConnection::showRxBitrate(int64_t nowUs) { void ARTPConnection::checkRxBitrate(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); int32_t bitrate = mCumulativeBytes * 8 / timeDiff; ALOGI("Actual Rx bitrate : %d bits/sec", bitrate); sp<ABuffer> buffer = new ABuffer(kMaxUDPSize); List<StreamInfo>::iterator it = mStreams.begin(); while (it != mStreams.end()) { StreamInfo *s = &*it; if (s->mIsInjected) { ++it; continue; } if (s->mNumRTCPPacketsReceived == 0) { // We have never received any RTCP packets on this stream, // we don't even know where to send a report. ++it; continue; } buffer->setRange(0, 0); for (size_t i = 0; i < s->mSources.size(); ++i) { sp<ARTPSource> source = s->mSources.valueAt(i); source->setTargetBitrate(); source->addTMMBR(buffer); } if (buffer->size() > 0) { ALOGV("Sending TMMBR..."); ssize_t n = send(s, buffer); if (n <= 0) { ALOGW("failed to send RTCP TMMBR (%s).", n == 0 ? "connection gone" : strerror(errno)); it = mStreams.erase(it); continue; } CHECK_EQ(n, (ssize_t)buffer->size()); } ++it; } mCumulativeBytes = 0; mLastBitrateReportTimeUs = nowUs; } Loading media/libstagefright/rtsp/ARTPConnection.h +3 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ struct ASessionDescription; struct ARTPConnection : public AHandler { enum Flags { kRegularlyRequestFIR = 2, kViLTEConnection = 4, }; explicit ARTPConnection(uint32_t flags = 0); Loading Loading @@ -94,9 +95,10 @@ private: void onPollStreams(); void onInjectPacket(const sp<AMessage> &msg); void onSendReceiverReports(); void showRxBitrate(int64_t nowUs); void checkRxBitrate(int64_t nowUs); status_t receive(StreamInfo *info, bool receiveRTP); ssize_t send(const StreamInfo *info, const sp<ABuffer> buffer); status_t parseRTP(StreamInfo *info, const sp<ABuffer> &buffer); status_t parseRTPExt(StreamInfo *s, const uint8_t *extData, size_t extLen, int32_t *cvoDegrees); Loading media/libstagefright/rtsp/ARTPSource.cpp +25 −4 Original line number Diff line number Diff line Loading @@ -263,8 +263,6 @@ 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; Loading Loading @@ -330,7 +328,9 @@ void ARTPSource::addTMMBR(const sp<ABuffer> &buffer) { ALOGW("RTCP buffer too small to accomodate RR."); return; } if (mQualManager.mTargetBitrate <= 0) int32_t targetBitrate = mQualManager.getTargetBitrate(); if (targetBitrate <= 0) return; uint8_t *data = buffer->data() + buffer->size(); Loading @@ -351,7 +351,6 @@ void ARTPSource::addTMMBR(const sp<ABuffer> &buffer) { 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 Loading @@ -369,6 +368,9 @@ void ARTPSource::addTMMBR(const sp<ABuffer> &buffer) { buffer->setRange(buffer->offset(), buffer->size() + 20); } uint32_t ARTPSource::getSelfID() { return kSourceID; } void ARTPSource::setSelfID(const uint32_t selfID) { kSourceID = selfID; } Loading @@ -377,6 +379,25 @@ void ARTPSource::setMinMaxBitrate(int32_t min, int32_t max) { mQualManager.setMinMaxBitrate(min, max); } void ARTPSource::setTargetBitrate() { uint8_t fraction = 0; // According to appendix A.3 in RFC 3550 uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1; int64_t intervalExpected = expected - mPrevExpected; int64_t intervalReceived = mNumBuffersReceived - mPrevNumBuffersReceived; int64_t intervalPacketLost = intervalExpected - intervalReceived; if (intervalPacketLost < 0) fraction = 0; else if (intervalExpected <= intervalPacketLost || intervalExpected == 0) fraction = 255; else fraction = (intervalPacketLost << 8) / intervalExpected; mQualManager.setTargetBitrate(fraction, ALooper::GetNowUs()); } bool ARTPSource::isNeedToReport() { int64_t intervalReceived = mNumBuffersReceived - mPrevNumBuffersReceived; return (intervalReceived > 0) ? true : false; Loading media/libstagefright/rtsp/ARTPSource.h +5 −29 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <media/stagefright/foundation/ABase.h> #include <utils/List.h> #include <utils/RefBase.h> #include <QualManager.h> namespace android { Loading @@ -46,8 +47,10 @@ struct ARTPSource : public RefBase { void addReceiverReport(const sp<ABuffer> &buffer); void addFIR(const sp<ABuffer> &buffer); void addTMMBR(const sp<ABuffer> &buffer); uint32_t getSelfID(); void setSelfID(const uint32_t selfID); void setMinMaxBitrate(int32_t min, int32_t max); void setTargetBitrate(); bool isNeedToReport(); Loading @@ -59,35 +62,6 @@ struct ARTPSource : public RefBase { int32_t mClockRate; private: struct QualManager { QualManager() : mMinBitrate(-1), mMaxBitrate(-1), mTargetBitrate(-1) {}; int32_t mMinBitrate; int32_t mMaxBitrate; int32_t mBitrateStep; int32_t mTargetBitrate; void setTargetBitrate(uint8_t fraction) { if (fraction <= (256 * 2 /100)) { // loss less than 2% mTargetBitrate += mBitrateStep; } else if (fraction > (256 * 5 / 100)) { // loss more than 5% mTargetBitrate -= mBitrateStep; } if (mTargetBitrate > mMaxBitrate) mTargetBitrate = mMaxBitrate; else if (mTargetBitrate < mMinBitrate) mTargetBitrate = mMinBitrate; }; void setMinMaxBitrate(int32_t min, int32_t max) { mMinBitrate = min; mMaxBitrate = max; mBitrateStep = (max - min) / 8; mTargetBitrate = min; }; } mQualManager; uint32_t mID; uint32_t mHighestSeqNumber; Loading @@ -108,6 +82,8 @@ private: sp<AMessage> mNotify; QualManager mQualManager; bool queuePacket(const sp<ABuffer> &buffer); DISALLOW_EVIL_CONSTRUCTORS(ARTPSource); Loading Loading
media/libmediaplayerservice/nuplayer/RTPSource.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ NuPlayer::RTPSource::RTPSource( mFinalResult(OK), mBuffering(false), mInPreparationPhase(true), mRTPConn(new ARTPConnection), mRTPConn(new ARTPConnection(ARTPConnection::kViLTEConnection)), mEOSTimeoutAudio(0), mEOSTimeoutVideo(0), mLastCVOUpdated(-1) { Loading Loading @@ -111,7 +111,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); mRTPConn->setMinMaxBitrate(videoMinBitrate, info->mAS * 1000); info->mRTPSocket = sockRtp; info->mRTCPSocket = sockRtcp; Loading
media/libstagefright/rtsp/ARTPConnection.cpp +81 −23 Original line number Diff line number Diff line Loading @@ -427,7 +427,8 @@ void ARTPConnection::onPollStreams() { } int64_t nowUs = ALooper::GetNowUs(); showRxBitrate(nowUs); checkRxBitrate(nowUs); if (mLastReceiverReportTimeUs <= 0 || mLastReceiverReportTimeUs + 5000000LL <= nowUs) { sp<ABuffer> buffer = new ABuffer(kMaxUDPSize); Loading @@ -452,10 +453,7 @@ 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); Loading @@ -465,22 +463,7 @@ void ARTPConnection::onPollStreams() { if (buffer->size() > 0) { ALOGV("Sending RR..."); struct sockaddr* pRemoteRTCPAddr; int sizeSockSt; if (s->isIPv6) { pRemoteRTCPAddr = (struct sockaddr *)&s->mRemoteRTCPAddr6; sizeSockSt = sizeof(struct sockaddr_in6); } else { pRemoteRTCPAddr = (struct sockaddr *)&s->mRemoteRTCPAddr; sizeSockSt = sizeof(struct sockaddr_in); } ssize_t n; do { n = sendto( s->mRTCPSocket, buffer->data(), buffer->size(), 0, pRemoteRTCPAddr, sizeSockSt); } while (n < 0 && errno == EINTR); ssize_t n = send(s, buffer); if (n <= 0) { ALOGW("failed to send RTCP receiver report (%s).", Loading Loading @@ -524,6 +507,9 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { (!receiveRTP && s->mNumRTCPPacketsReceived == 0) ? sizeSockSt : 0; if (mFlags & kViLTEConnection) remoteAddrLen = 0; ssize_t nbytes; do { nbytes = recvfrom( Loading Loading @@ -554,6 +540,36 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { return err; } ssize_t ARTPConnection::send(const StreamInfo *info, const sp<ABuffer> buffer) { struct sockaddr* pRemoteRTCPAddr; int sizeSockSt; /* It seems this isIPv6 variable is useless. * We should remove it to prevent confusion */ if (info->isIPv6) { pRemoteRTCPAddr = (struct sockaddr *)&info->mRemoteRTCPAddr6; sizeSockSt = sizeof(struct sockaddr_in6); } else { pRemoteRTCPAddr = (struct sockaddr *)&info->mRemoteRTCPAddr; sizeSockSt = sizeof(struct sockaddr_in); } if (mFlags & kViLTEConnection) { ALOGV("ViLTE RTCP"); pRemoteRTCPAddr = NULL; sizeSockSt = 0; } ssize_t n; do { n = sendto( info->mRTCPSocket, buffer->data(), buffer->size(), 0, pRemoteRTCPAddr, sizeSockSt); } while (n < 0 && errno == EINTR); return n; } status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) { if (s->mNumRTPPacketsReceived++ == 0) { sp<AMessage> notify = s->mNotifyMsg->dup(); Loading Loading @@ -970,14 +986,56 @@ void ARTPConnection::setMinMaxBitrate(int32_t min, int32_t max) { mMaxBitrate = max; } void ARTPConnection::showRxBitrate(int64_t nowUs) { void ARTPConnection::checkRxBitrate(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); int32_t bitrate = mCumulativeBytes * 8 / timeDiff; ALOGI("Actual Rx bitrate : %d bits/sec", bitrate); sp<ABuffer> buffer = new ABuffer(kMaxUDPSize); List<StreamInfo>::iterator it = mStreams.begin(); while (it != mStreams.end()) { StreamInfo *s = &*it; if (s->mIsInjected) { ++it; continue; } if (s->mNumRTCPPacketsReceived == 0) { // We have never received any RTCP packets on this stream, // we don't even know where to send a report. ++it; continue; } buffer->setRange(0, 0); for (size_t i = 0; i < s->mSources.size(); ++i) { sp<ARTPSource> source = s->mSources.valueAt(i); source->setTargetBitrate(); source->addTMMBR(buffer); } if (buffer->size() > 0) { ALOGV("Sending TMMBR..."); ssize_t n = send(s, buffer); if (n <= 0) { ALOGW("failed to send RTCP TMMBR (%s).", n == 0 ? "connection gone" : strerror(errno)); it = mStreams.erase(it); continue; } CHECK_EQ(n, (ssize_t)buffer->size()); } ++it; } mCumulativeBytes = 0; mLastBitrateReportTimeUs = nowUs; } Loading
media/libstagefright/rtsp/ARTPConnection.h +3 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ struct ASessionDescription; struct ARTPConnection : public AHandler { enum Flags { kRegularlyRequestFIR = 2, kViLTEConnection = 4, }; explicit ARTPConnection(uint32_t flags = 0); Loading Loading @@ -94,9 +95,10 @@ private: void onPollStreams(); void onInjectPacket(const sp<AMessage> &msg); void onSendReceiverReports(); void showRxBitrate(int64_t nowUs); void checkRxBitrate(int64_t nowUs); status_t receive(StreamInfo *info, bool receiveRTP); ssize_t send(const StreamInfo *info, const sp<ABuffer> buffer); status_t parseRTP(StreamInfo *info, const sp<ABuffer> &buffer); status_t parseRTPExt(StreamInfo *s, const uint8_t *extData, size_t extLen, int32_t *cvoDegrees); Loading
media/libstagefright/rtsp/ARTPSource.cpp +25 −4 Original line number Diff line number Diff line Loading @@ -263,8 +263,6 @@ 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; Loading Loading @@ -330,7 +328,9 @@ void ARTPSource::addTMMBR(const sp<ABuffer> &buffer) { ALOGW("RTCP buffer too small to accomodate RR."); return; } if (mQualManager.mTargetBitrate <= 0) int32_t targetBitrate = mQualManager.getTargetBitrate(); if (targetBitrate <= 0) return; uint8_t *data = buffer->data() + buffer->size(); Loading @@ -351,7 +351,6 @@ void ARTPSource::addTMMBR(const sp<ABuffer> &buffer) { 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 Loading @@ -369,6 +368,9 @@ void ARTPSource::addTMMBR(const sp<ABuffer> &buffer) { buffer->setRange(buffer->offset(), buffer->size() + 20); } uint32_t ARTPSource::getSelfID() { return kSourceID; } void ARTPSource::setSelfID(const uint32_t selfID) { kSourceID = selfID; } Loading @@ -377,6 +379,25 @@ void ARTPSource::setMinMaxBitrate(int32_t min, int32_t max) { mQualManager.setMinMaxBitrate(min, max); } void ARTPSource::setTargetBitrate() { uint8_t fraction = 0; // According to appendix A.3 in RFC 3550 uint32_t expected = mHighestSeqNumber - mBaseSeqNumber + 1; int64_t intervalExpected = expected - mPrevExpected; int64_t intervalReceived = mNumBuffersReceived - mPrevNumBuffersReceived; int64_t intervalPacketLost = intervalExpected - intervalReceived; if (intervalPacketLost < 0) fraction = 0; else if (intervalExpected <= intervalPacketLost || intervalExpected == 0) fraction = 255; else fraction = (intervalPacketLost << 8) / intervalExpected; mQualManager.setTargetBitrate(fraction, ALooper::GetNowUs()); } bool ARTPSource::isNeedToReport() { int64_t intervalReceived = mNumBuffersReceived - mPrevNumBuffersReceived; return (intervalReceived > 0) ? true : false; Loading
media/libstagefright/rtsp/ARTPSource.h +5 −29 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <media/stagefright/foundation/ABase.h> #include <utils/List.h> #include <utils/RefBase.h> #include <QualManager.h> namespace android { Loading @@ -46,8 +47,10 @@ struct ARTPSource : public RefBase { void addReceiverReport(const sp<ABuffer> &buffer); void addFIR(const sp<ABuffer> &buffer); void addTMMBR(const sp<ABuffer> &buffer); uint32_t getSelfID(); void setSelfID(const uint32_t selfID); void setMinMaxBitrate(int32_t min, int32_t max); void setTargetBitrate(); bool isNeedToReport(); Loading @@ -59,35 +62,6 @@ struct ARTPSource : public RefBase { int32_t mClockRate; private: struct QualManager { QualManager() : mMinBitrate(-1), mMaxBitrate(-1), mTargetBitrate(-1) {}; int32_t mMinBitrate; int32_t mMaxBitrate; int32_t mBitrateStep; int32_t mTargetBitrate; void setTargetBitrate(uint8_t fraction) { if (fraction <= (256 * 2 /100)) { // loss less than 2% mTargetBitrate += mBitrateStep; } else if (fraction > (256 * 5 / 100)) { // loss more than 5% mTargetBitrate -= mBitrateStep; } if (mTargetBitrate > mMaxBitrate) mTargetBitrate = mMaxBitrate; else if (mTargetBitrate < mMinBitrate) mTargetBitrate = mMinBitrate; }; void setMinMaxBitrate(int32_t min, int32_t max) { mMinBitrate = min; mMaxBitrate = max; mBitrateStep = (max - min) / 8; mTargetBitrate = min; }; } mQualManager; uint32_t mID; uint32_t mHighestSeqNumber; Loading @@ -108,6 +82,8 @@ private: sp<AMessage> mNotify; QualManager mQualManager; bool queuePacket(const sp<ABuffer> &buffer); DISALLOW_EVIL_CONSTRUCTORS(ARTPSource); Loading