summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/wifi-display/rtp/RTPReceiver.cpp')
-rw-r--r--media/libstagefright/wifi-display/rtp/RTPReceiver.cpp1153
1 files changed, 0 insertions, 1153 deletions
diff --git a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp b/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
deleted file mode 100644
index 8fa1dae..0000000
--- a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp
+++ /dev/null
@@ -1,1153 +0,0 @@
-/*
- * Copyright 2013, 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "RTPReceiver"
-#include <utils/Log.h>
-
-#include "RTPAssembler.h"
-#include "RTPReceiver.h"
-
-#include "ANetworkSession.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/Utils.h>
-
-#define TRACK_PACKET_LOSS 0
-
-namespace android {
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct RTPReceiver::Source : public AHandler {
- Source(RTPReceiver *receiver, uint32_t ssrc);
-
- void onPacketReceived(uint16_t seq, const sp<ABuffer> &buffer);
-
- void addReportBlock(uint32_t ssrc, const sp<ABuffer> &buf);
-
-protected:
- virtual ~Source();
-
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- enum {
- kWhatRetransmit,
- kWhatDeclareLost,
- };
-
- static const uint32_t kMinSequential = 2;
- static const uint32_t kMaxDropout = 3000;
- static const uint32_t kMaxMisorder = 100;
- static const uint32_t kRTPSeqMod = 1u << 16;
- static const int64_t kReportIntervalUs = 10000000ll;
-
- RTPReceiver *mReceiver;
- uint32_t mSSRC;
- bool mFirst;
- uint16_t mMaxSeq;
- uint32_t mCycles;
- uint32_t mBaseSeq;
- uint32_t mReceived;
- uint32_t mExpectedPrior;
- uint32_t mReceivedPrior;
-
- int64_t mFirstArrivalTimeUs;
- int64_t mFirstRTPTimeUs;
-
- // Ordered by extended seq number.
- List<sp<ABuffer> > mPackets;
-
- enum StatusBits {
- STATUS_DECLARED_LOST = 1,
- STATUS_REQUESTED_RETRANSMISSION = 2,
- STATUS_ARRIVED_LATE = 4,
- };
-#if TRACK_PACKET_LOSS
- KeyedVector<int32_t, uint32_t> mLostPackets;
-#endif
-
- void modifyPacketStatus(int32_t extSeqNo, uint32_t mask);
-
- int32_t mAwaitingExtSeqNo;
- bool mRequestedRetransmission;
-
- int32_t mActivePacketType;
- sp<Assembler> mActiveAssembler;
-
- int64_t mNextReportTimeUs;
-
- int32_t mNumDeclaredLost;
- int32_t mNumDeclaredLostPrior;
-
- int32_t mRetransmitGeneration;
- int32_t mDeclareLostGeneration;
- bool mDeclareLostTimerPending;
-
- void queuePacket(const sp<ABuffer> &packet);
- void dequeueMore();
-
- sp<ABuffer> getNextPacket();
- void resync();
-
- void postRetransmitTimer(int64_t delayUs);
- void postDeclareLostTimer(int64_t delayUs);
- void cancelTimers();
-
- DISALLOW_EVIL_CONSTRUCTORS(Source);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-RTPReceiver::Source::Source(RTPReceiver *receiver, uint32_t ssrc)
- : mReceiver(receiver),
- mSSRC(ssrc),
- mFirst(true),
- mMaxSeq(0),
- mCycles(0),
- mBaseSeq(0),
- mReceived(0),
- mExpectedPrior(0),
- mReceivedPrior(0),
- mFirstArrivalTimeUs(-1ll),
- mFirstRTPTimeUs(-1ll),
- mAwaitingExtSeqNo(-1),
- mRequestedRetransmission(false),
- mActivePacketType(-1),
- mNextReportTimeUs(-1ll),
- mNumDeclaredLost(0),
- mNumDeclaredLostPrior(0),
- mRetransmitGeneration(0),
- mDeclareLostGeneration(0),
- mDeclareLostTimerPending(false) {
-}
-
-RTPReceiver::Source::~Source() {
-}
-
-void RTPReceiver::Source::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatRetransmit:
- {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
-
- if (generation != mRetransmitGeneration) {
- break;
- }
-
- mRequestedRetransmission = true;
- mReceiver->requestRetransmission(mSSRC, mAwaitingExtSeqNo);
-
- modifyPacketStatus(
- mAwaitingExtSeqNo, STATUS_REQUESTED_RETRANSMISSION);
- break;
- }
-
- case kWhatDeclareLost:
- {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
-
- if (generation != mDeclareLostGeneration) {
- break;
- }
-
- cancelTimers();
-
- ALOGV("Lost packet extSeqNo %d %s",
- mAwaitingExtSeqNo,
- mRequestedRetransmission ? "*" : "");
-
- mRequestedRetransmission = false;
- if (mActiveAssembler != NULL) {
- mActiveAssembler->signalDiscontinuity();
- }
-
- modifyPacketStatus(mAwaitingExtSeqNo, STATUS_DECLARED_LOST);
-
- // resync();
- ++mAwaitingExtSeqNo;
- ++mNumDeclaredLost;
-
- mReceiver->notifyPacketLost();
-
- dequeueMore();
- break;
- }
-
- default:
- TRESPASS();
- }
-}
-
-void RTPReceiver::Source::onPacketReceived(
- uint16_t seq, const sp<ABuffer> &buffer) {
- if (mFirst) {
- buffer->setInt32Data(mCycles | seq);
- queuePacket(buffer);
-
- mFirst = false;
- mBaseSeq = seq;
- mMaxSeq = seq;
- ++mReceived;
- return;
- }
-
- uint16_t udelta = seq - mMaxSeq;
-
- if (udelta < kMaxDropout) {
- // In order, with permissible gap.
-
- if (seq < mMaxSeq) {
- // Sequence number wrapped - count another 64K cycle
- mCycles += kRTPSeqMod;
- }
-
- mMaxSeq = seq;
-
- ++mReceived;
- } else if (udelta <= kRTPSeqMod - kMaxMisorder) {
- // The sequence number made a very large jump
- return;
- } else {
- // Duplicate or reordered packet.
- }
-
- buffer->setInt32Data(mCycles | seq);
- queuePacket(buffer);
-}
-
-void RTPReceiver::Source::queuePacket(const sp<ABuffer> &packet) {
- int32_t newExtendedSeqNo = packet->int32Data();
-
- if (mFirstArrivalTimeUs < 0ll) {
- mFirstArrivalTimeUs = ALooper::GetNowUs();
-
- uint32_t rtpTime;
- CHECK(packet->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
-
- mFirstRTPTimeUs = (rtpTime * 100ll) / 9ll;
- }
-
- if (mAwaitingExtSeqNo >= 0 && newExtendedSeqNo < mAwaitingExtSeqNo) {
- // We're no longer interested in these. They're old.
- ALOGV("dropping stale extSeqNo %d", newExtendedSeqNo);
-
- modifyPacketStatus(newExtendedSeqNo, STATUS_ARRIVED_LATE);
- return;
- }
-
- if (mPackets.empty()) {
- mPackets.push_back(packet);
- dequeueMore();
- return;
- }
-
- List<sp<ABuffer> >::iterator firstIt = mPackets.begin();
- List<sp<ABuffer> >::iterator it = --mPackets.end();
- for (;;) {
- int32_t extendedSeqNo = (*it)->int32Data();
-
- if (extendedSeqNo == newExtendedSeqNo) {
- // Duplicate packet.
- return;
- }
-
- if (extendedSeqNo < newExtendedSeqNo) {
- // Insert new packet after the one at "it".
- mPackets.insert(++it, packet);
- break;
- }
-
- if (it == firstIt) {
- // Insert new packet before the first existing one.
- mPackets.insert(it, packet);
- break;
- }
-
- --it;
- }
-
- dequeueMore();
-}
-
-void RTPReceiver::Source::dequeueMore() {
- int64_t nowUs = ALooper::GetNowUs();
- if (mNextReportTimeUs < 0ll || nowUs >= mNextReportTimeUs) {
- if (mNextReportTimeUs >= 0ll) {
- uint32_t expected = (mMaxSeq | mCycles) - mBaseSeq + 1;
-
- uint32_t expectedInterval = expected - mExpectedPrior;
- mExpectedPrior = expected;
-
- uint32_t receivedInterval = mReceived - mReceivedPrior;
- mReceivedPrior = mReceived;
-
- int64_t lostInterval =
- (int64_t)expectedInterval - (int64_t)receivedInterval;
-
- int32_t declaredLostInterval =
- mNumDeclaredLost - mNumDeclaredLostPrior;
-
- mNumDeclaredLostPrior = mNumDeclaredLost;
-
- if (declaredLostInterval > 0) {
- ALOGI("lost %lld packets (%.2f %%), declared %d lost\n",
- lostInterval,
- 100.0f * lostInterval / expectedInterval,
- declaredLostInterval);
- }
- }
-
- mNextReportTimeUs = nowUs + kReportIntervalUs;
-
-#if TRACK_PACKET_LOSS
- for (size_t i = 0; i < mLostPackets.size(); ++i) {
- int32_t key = mLostPackets.keyAt(i);
- uint32_t value = mLostPackets.valueAt(i);
-
- AString status;
- if (value & STATUS_REQUESTED_RETRANSMISSION) {
- status.append("retrans ");
- }
- if (value & STATUS_ARRIVED_LATE) {
- status.append("arrived-late ");
- }
- ALOGI("Packet %d declared lost %s", key, status.c_str());
- }
-#endif
- }
-
- sp<ABuffer> packet;
- while ((packet = getNextPacket()) != NULL) {
- if (mDeclareLostTimerPending) {
- cancelTimers();
- }
-
- CHECK_GE(mAwaitingExtSeqNo, 0);
-#if TRACK_PACKET_LOSS
- mLostPackets.removeItem(mAwaitingExtSeqNo);
-#endif
-
- int32_t packetType;
- CHECK(packet->meta()->findInt32("PT", &packetType));
-
- if (packetType != mActivePacketType) {
- mActiveAssembler = mReceiver->makeAssembler(packetType);
- mActivePacketType = packetType;
- }
-
- if (mActiveAssembler != NULL) {
- status_t err = mActiveAssembler->processPacket(packet);
- if (err != OK) {
- ALOGV("assembler returned error %d", err);
- }
- }
-
- ++mAwaitingExtSeqNo;
- }
-
- if (mDeclareLostTimerPending) {
- return;
- }
-
- if (mPackets.empty()) {
- return;
- }
-
- CHECK_GE(mAwaitingExtSeqNo, 0);
-
- const sp<ABuffer> &firstPacket = *mPackets.begin();
-
- uint32_t rtpTime;
- CHECK(firstPacket->meta()->findInt32(
- "rtp-time", (int32_t *)&rtpTime));
-
-
- int64_t rtpUs = (rtpTime * 100ll) / 9ll;
-
- int64_t maxArrivalTimeUs =
- mFirstArrivalTimeUs + rtpUs - mFirstRTPTimeUs;
-
- nowUs = ALooper::GetNowUs();
-
- CHECK_LT(mAwaitingExtSeqNo, firstPacket->int32Data());
-
- ALOGV("waiting for %d, comparing against %d, %lld us left",
- mAwaitingExtSeqNo,
- firstPacket->int32Data(),
- maxArrivalTimeUs - nowUs);
-
- postDeclareLostTimer(maxArrivalTimeUs + kPacketLostAfterUs);
-
- if (kRequestRetransmissionAfterUs > 0ll) {
- postRetransmitTimer(
- maxArrivalTimeUs + kRequestRetransmissionAfterUs);
- }
-}
-
-sp<ABuffer> RTPReceiver::Source::getNextPacket() {
- if (mPackets.empty()) {
- return NULL;
- }
-
- int32_t extSeqNo = (*mPackets.begin())->int32Data();
-
- if (mAwaitingExtSeqNo < 0) {
- mAwaitingExtSeqNo = extSeqNo;
- } else if (extSeqNo != mAwaitingExtSeqNo) {
- return NULL;
- }
-
- sp<ABuffer> packet = *mPackets.begin();
- mPackets.erase(mPackets.begin());
-
- return packet;
-}
-
-void RTPReceiver::Source::resync() {
- mAwaitingExtSeqNo = -1;
-}
-
-void RTPReceiver::Source::addReportBlock(
- uint32_t ssrc, const sp<ABuffer> &buf) {
- uint32_t extMaxSeq = mMaxSeq | mCycles;
- uint32_t expected = extMaxSeq - mBaseSeq + 1;
-
- int64_t lost = (int64_t)expected - (int64_t)mReceived;
- if (lost > 0x7fffff) {
- lost = 0x7fffff;
- } else if (lost < -0x800000) {
- lost = -0x800000;
- }
-
- uint32_t expectedInterval = expected - mExpectedPrior;
- mExpectedPrior = expected;
-
- uint32_t receivedInterval = mReceived - mReceivedPrior;
- mReceivedPrior = mReceived;
-
- int64_t lostInterval = expectedInterval - receivedInterval;
-
- uint8_t fractionLost;
- if (expectedInterval == 0 || lostInterval <=0) {
- fractionLost = 0;
- } else {
- fractionLost = (lostInterval << 8) / expectedInterval;
- }
-
- uint8_t *ptr = buf->data() + buf->size();
-
- ptr[0] = ssrc >> 24;
- ptr[1] = (ssrc >> 16) & 0xff;
- ptr[2] = (ssrc >> 8) & 0xff;
- ptr[3] = ssrc & 0xff;
-
- ptr[4] = fractionLost;
-
- ptr[5] = (lost >> 16) & 0xff;
- ptr[6] = (lost >> 8) & 0xff;
- ptr[7] = lost & 0xff;
-
- ptr[8] = extMaxSeq >> 24;
- ptr[9] = (extMaxSeq >> 16) & 0xff;
- ptr[10] = (extMaxSeq >> 8) & 0xff;
- ptr[11] = extMaxSeq & 0xff;
-
- // XXX TODO:
-
- ptr[12] = 0x00; // interarrival jitter
- ptr[13] = 0x00;
- ptr[14] = 0x00;
- ptr[15] = 0x00;
-
- ptr[16] = 0x00; // last SR
- ptr[17] = 0x00;
- ptr[18] = 0x00;
- ptr[19] = 0x00;
-
- ptr[20] = 0x00; // delay since last SR
- ptr[21] = 0x00;
- ptr[22] = 0x00;
- ptr[23] = 0x00;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-RTPReceiver::RTPReceiver(
- const sp<ANetworkSession> &netSession,
- const sp<AMessage> &notify,
- uint32_t flags)
- : mNetSession(netSession),
- mNotify(notify),
- mFlags(flags),
- mRTPMode(TRANSPORT_UNDEFINED),
- mRTCPMode(TRANSPORT_UNDEFINED),
- mRTPSessionID(0),
- mRTCPSessionID(0),
- mRTPConnected(false),
- mRTCPConnected(false),
- mRTPClientSessionID(0),
- mRTCPClientSessionID(0) {
-}
-
-RTPReceiver::~RTPReceiver() {
- if (mRTCPClientSessionID != 0) {
- mNetSession->destroySession(mRTCPClientSessionID);
- mRTCPClientSessionID = 0;
- }
-
- if (mRTPClientSessionID != 0) {
- mNetSession->destroySession(mRTPClientSessionID);
- mRTPClientSessionID = 0;
- }
-
- if (mRTCPSessionID != 0) {
- mNetSession->destroySession(mRTCPSessionID);
- mRTCPSessionID = 0;
- }
-
- if (mRTPSessionID != 0) {
- mNetSession->destroySession(mRTPSessionID);
- mRTPSessionID = 0;
- }
-}
-
-status_t RTPReceiver::initAsync(
- TransportMode rtpMode,
- TransportMode rtcpMode,
- int32_t *outLocalRTPPort) {
- if (mRTPMode != TRANSPORT_UNDEFINED
- || rtpMode == TRANSPORT_UNDEFINED
- || rtpMode == TRANSPORT_NONE
- || rtcpMode == TRANSPORT_UNDEFINED) {
- return INVALID_OPERATION;
- }
-
- CHECK_NE(rtpMode, TRANSPORT_TCP_INTERLEAVED);
- CHECK_NE(rtcpMode, TRANSPORT_TCP_INTERLEAVED);
-
- sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
-
- sp<AMessage> rtcpNotify;
- if (rtcpMode != TRANSPORT_NONE) {
- rtcpNotify = new AMessage(kWhatRTCPNotify, id());
- }
-
- CHECK_EQ(mRTPSessionID, 0);
- CHECK_EQ(mRTCPSessionID, 0);
-
- int32_t localRTPPort;
-
- struct in_addr ifaceAddr;
- ifaceAddr.s_addr = INADDR_ANY;
-
- for (;;) {
- localRTPPort = PickRandomRTPPort();
-
- status_t err;
- if (rtpMode == TRANSPORT_UDP) {
- err = mNetSession->createUDPSession(
- localRTPPort,
- rtpNotify,
- &mRTPSessionID);
- } else {
- CHECK_EQ(rtpMode, TRANSPORT_TCP);
- err = mNetSession->createTCPDatagramSession(
- ifaceAddr,
- localRTPPort,
- rtpNotify,
- &mRTPSessionID);
- }
-
- if (err != OK) {
- continue;
- }
-
- if (rtcpMode == TRANSPORT_NONE) {
- break;
- } else if (rtcpMode == TRANSPORT_UDP) {
- err = mNetSession->createUDPSession(
- localRTPPort + 1,
- rtcpNotify,
- &mRTCPSessionID);
- } else {
- CHECK_EQ(rtpMode, TRANSPORT_TCP);
- err = mNetSession->createTCPDatagramSession(
- ifaceAddr,
- localRTPPort + 1,
- rtcpNotify,
- &mRTCPSessionID);
- }
-
- if (err == OK) {
- break;
- }
-
- mNetSession->destroySession(mRTPSessionID);
- mRTPSessionID = 0;
- }
-
- mRTPMode = rtpMode;
- mRTCPMode = rtcpMode;
- *outLocalRTPPort = localRTPPort;
-
- return OK;
-}
-
-status_t RTPReceiver::connect(
- const char *remoteHost, int32_t remoteRTPPort, int32_t remoteRTCPPort) {
- status_t err;
-
- if (mRTPMode == TRANSPORT_UDP) {
- CHECK(!mRTPConnected);
-
- err = mNetSession->connectUDPSession(
- mRTPSessionID, remoteHost, remoteRTPPort);
-
- if (err != OK) {
- notifyInitDone(err);
- return err;
- }
-
- ALOGI("connectUDPSession RTP successful.");
-
- mRTPConnected = true;
- }
-
- if (mRTCPMode == TRANSPORT_UDP) {
- CHECK(!mRTCPConnected);
-
- err = mNetSession->connectUDPSession(
- mRTCPSessionID, remoteHost, remoteRTCPPort);
-
- if (err != OK) {
- notifyInitDone(err);
- return err;
- }
-
- scheduleSendRR();
-
- ALOGI("connectUDPSession RTCP successful.");
-
- mRTCPConnected = true;
- }
-
- if (mRTPConnected
- && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) {
- notifyInitDone(OK);
- }
-
- return OK;
-}
-
-status_t RTPReceiver::informSender(const sp<AMessage> &params) {
- if (!mRTCPConnected) {
- return INVALID_OPERATION;
- }
-
- int64_t avgLatencyUs;
- CHECK(params->findInt64("avgLatencyUs", &avgLatencyUs));
-
- int64_t maxLatencyUs;
- CHECK(params->findInt64("maxLatencyUs", &maxLatencyUs));
-
- sp<ABuffer> buf = new ABuffer(28);
-
- uint8_t *ptr = buf->data();
- ptr[0] = 0x80 | 0;
- ptr[1] = 204; // APP
- ptr[2] = 0;
-
- CHECK((buf->size() % 4) == 0u);
- ptr[3] = (buf->size() / 4) - 1;
-
- ptr[4] = kSourceID >> 24; // SSRC
- ptr[5] = (kSourceID >> 16) & 0xff;
- ptr[6] = (kSourceID >> 8) & 0xff;
- ptr[7] = kSourceID & 0xff;
- ptr[8] = 'l';
- ptr[9] = 'a';
- ptr[10] = 't';
- ptr[11] = 'e';
-
- ptr[12] = avgLatencyUs >> 56;
- ptr[13] = (avgLatencyUs >> 48) & 0xff;
- ptr[14] = (avgLatencyUs >> 40) & 0xff;
- ptr[15] = (avgLatencyUs >> 32) & 0xff;
- ptr[16] = (avgLatencyUs >> 24) & 0xff;
- ptr[17] = (avgLatencyUs >> 16) & 0xff;
- ptr[18] = (avgLatencyUs >> 8) & 0xff;
- ptr[19] = avgLatencyUs & 0xff;
-
- ptr[20] = maxLatencyUs >> 56;
- ptr[21] = (maxLatencyUs >> 48) & 0xff;
- ptr[22] = (maxLatencyUs >> 40) & 0xff;
- ptr[23] = (maxLatencyUs >> 32) & 0xff;
- ptr[24] = (maxLatencyUs >> 24) & 0xff;
- ptr[25] = (maxLatencyUs >> 16) & 0xff;
- ptr[26] = (maxLatencyUs >> 8) & 0xff;
- ptr[27] = maxLatencyUs & 0xff;
-
- mNetSession->sendRequest(mRTCPSessionID, buf->data(), buf->size());
-
- return OK;
-}
-
-void RTPReceiver::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatRTPNotify:
- case kWhatRTCPNotify:
- onNetNotify(msg->what() == kWhatRTPNotify, msg);
- break;
-
- case kWhatSendRR:
- {
- onSendRR();
- break;
- }
-
- default:
- TRESPASS();
- }
-}
-
-void RTPReceiver::onNetNotify(bool isRTP, const sp<AMessage> &msg) {
- int32_t reason;
- CHECK(msg->findInt32("reason", &reason));
-
- switch (reason) {
- case ANetworkSession::kWhatError:
- {
- int32_t sessionID;
- CHECK(msg->findInt32("sessionID", &sessionID));
-
- int32_t err;
- CHECK(msg->findInt32("err", &err));
-
- int32_t errorOccuredDuringSend;
- CHECK(msg->findInt32("send", &errorOccuredDuringSend));
-
- AString detail;
- CHECK(msg->findString("detail", &detail));
-
- ALOGE("An error occurred during %s in session %d "
- "(%d, '%s' (%s)).",
- errorOccuredDuringSend ? "send" : "receive",
- sessionID,
- err,
- detail.c_str(),
- strerror(-err));
-
- mNetSession->destroySession(sessionID);
-
- if (sessionID == mRTPSessionID) {
- mRTPSessionID = 0;
- } else if (sessionID == mRTCPSessionID) {
- mRTCPSessionID = 0;
- } else if (sessionID == mRTPClientSessionID) {
- mRTPClientSessionID = 0;
- } else if (sessionID == mRTCPClientSessionID) {
- mRTCPClientSessionID = 0;
- }
-
- if (!mRTPConnected
- || (mRTCPMode != TRANSPORT_NONE && !mRTCPConnected)) {
- notifyInitDone(err);
- break;
- }
-
- notifyError(err);
- break;
- }
-
- case ANetworkSession::kWhatDatagram:
- {
- sp<ABuffer> data;
- CHECK(msg->findBuffer("data", &data));
-
- if (isRTP) {
- if (mFlags & FLAG_AUTO_CONNECT) {
- AString fromAddr;
- CHECK(msg->findString("fromAddr", &fromAddr));
-
- int32_t fromPort;
- CHECK(msg->findInt32("fromPort", &fromPort));
-
- CHECK_EQ((status_t)OK,
- connect(
- fromAddr.c_str(), fromPort, fromPort + 1));
-
- mFlags &= ~FLAG_AUTO_CONNECT;
- }
-
- onRTPData(data);
- } else {
- onRTCPData(data);
- }
- break;
- }
-
- case ANetworkSession::kWhatClientConnected:
- {
- int32_t sessionID;
- CHECK(msg->findInt32("sessionID", &sessionID));
-
- if (isRTP) {
- CHECK_EQ(mRTPMode, TRANSPORT_TCP);
-
- if (mRTPClientSessionID != 0) {
- // We only allow a single client connection.
- mNetSession->destroySession(sessionID);
- sessionID = 0;
- break;
- }
-
- mRTPClientSessionID = sessionID;
- mRTPConnected = true;
- } else {
- CHECK_EQ(mRTCPMode, TRANSPORT_TCP);
-
- if (mRTCPClientSessionID != 0) {
- // We only allow a single client connection.
- mNetSession->destroySession(sessionID);
- sessionID = 0;
- break;
- }
-
- mRTCPClientSessionID = sessionID;
- mRTCPConnected = true;
- }
-
- if (mRTPConnected
- && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) {
- notifyInitDone(OK);
- }
- break;
- }
- }
-}
-
-void RTPReceiver::notifyInitDone(status_t err) {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatInitDone);
- notify->setInt32("err", err);
- notify->post();
-}
-
-void RTPReceiver::notifyError(status_t err) {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatError);
- notify->setInt32("err", err);
- notify->post();
-}
-
-void RTPReceiver::notifyPacketLost() {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatPacketLost);
- notify->post();
-}
-
-status_t RTPReceiver::onRTPData(const sp<ABuffer> &buffer) {
- size_t size = buffer->size();
- if (size < 12) {
- // Too short to be a valid RTP header.
- return ERROR_MALFORMED;
- }
-
- const uint8_t *data = buffer->data();
-
- if ((data[0] >> 6) != 2) {
- // Unsupported version.
- return ERROR_UNSUPPORTED;
- }
-
- if (data[0] & 0x20) {
- // Padding present.
-
- size_t paddingLength = data[size - 1];
-
- if (paddingLength + 12 > size) {
- // If we removed this much padding we'd end up with something
- // that's too short to be a valid RTP header.
- return ERROR_MALFORMED;
- }
-
- size -= paddingLength;
- }
-
- int numCSRCs = data[0] & 0x0f;
-
- size_t payloadOffset = 12 + 4 * numCSRCs;
-
- if (size < payloadOffset) {
- // Not enough data to fit the basic header and all the CSRC entries.
- return ERROR_MALFORMED;
- }
-
- if (data[0] & 0x10) {
- // Header eXtension present.
-
- if (size < payloadOffset + 4) {
- // Not enough data to fit the basic header, all CSRC entries
- // and the first 4 bytes of the extension header.
-
- return ERROR_MALFORMED;
- }
-
- const uint8_t *extensionData = &data[payloadOffset];
-
- size_t extensionLength =
- 4 * (extensionData[2] << 8 | extensionData[3]);
-
- if (size < payloadOffset + 4 + extensionLength) {
- return ERROR_MALFORMED;
- }
-
- payloadOffset += 4 + extensionLength;
- }
-
- uint32_t srcId = U32_AT(&data[8]);
- uint32_t rtpTime = U32_AT(&data[4]);
- uint16_t seqNo = U16_AT(&data[2]);
-
- sp<AMessage> meta = buffer->meta();
- meta->setInt32("ssrc", srcId);
- meta->setInt32("rtp-time", rtpTime);
- meta->setInt32("PT", data[1] & 0x7f);
- meta->setInt32("M", data[1] >> 7);
-
- buffer->setRange(payloadOffset, size - payloadOffset);
-
- ssize_t index = mSources.indexOfKey(srcId);
- sp<Source> source;
- if (index < 0) {
- source = new Source(this, srcId);
- looper()->registerHandler(source);
-
- mSources.add(srcId, source);
- } else {
- source = mSources.valueAt(index);
- }
-
- source->onPacketReceived(seqNo, buffer);
-
- return OK;
-}
-
-status_t RTPReceiver::onRTCPData(const sp<ABuffer> &data) {
- ALOGI("onRTCPData");
- return OK;
-}
-
-void RTPReceiver::addSDES(const sp<ABuffer> &buffer) {
- uint8_t *data = buffer->data() + buffer->size();
- data[0] = 0x80 | 1;
- data[1] = 202; // SDES
- data[4] = kSourceID >> 24; // SSRC
- data[5] = (kSourceID >> 16) & 0xff;
- data[6] = (kSourceID >> 8) & 0xff;
- data[7] = kSourceID & 0xff;
-
- size_t offset = 8;
-
- data[offset++] = 1; // CNAME
-
- AString cname = "stagefright@somewhere";
- data[offset++] = cname.size();
-
- memcpy(&data[offset], cname.c_str(), cname.size());
- offset += cname.size();
-
- data[offset++] = 6; // TOOL
-
- AString tool = "stagefright/1.0";
- data[offset++] = tool.size();
-
- memcpy(&data[offset], tool.c_str(), tool.size());
- offset += tool.size();
-
- data[offset++] = 0;
-
- if ((offset % 4) > 0) {
- size_t count = 4 - (offset % 4);
- switch (count) {
- case 3:
- data[offset++] = 0;
- case 2:
- data[offset++] = 0;
- case 1:
- data[offset++] = 0;
- }
- }
-
- size_t numWords = (offset / 4) - 1;
- data[2] = numWords >> 8;
- data[3] = numWords & 0xff;
-
- buffer->setRange(buffer->offset(), buffer->size() + offset);
-}
-
-void RTPReceiver::scheduleSendRR() {
- (new AMessage(kWhatSendRR, id()))->post(5000000ll);
-}
-
-void RTPReceiver::onSendRR() {
-#if 0
- sp<ABuffer> buf = new ABuffer(kMaxUDPPacketSize);
- buf->setRange(0, 0);
-
- uint8_t *ptr = buf->data();
- ptr[0] = 0x80 | 0;
- ptr[1] = 201; // RR
- ptr[2] = 0;
- ptr[3] = 1;
- ptr[4] = kSourceID >> 24; // SSRC
- ptr[5] = (kSourceID >> 16) & 0xff;
- ptr[6] = (kSourceID >> 8) & 0xff;
- ptr[7] = kSourceID & 0xff;
-
- buf->setRange(0, 8);
-
- size_t numReportBlocks = 0;
- for (size_t i = 0; i < mSources.size(); ++i) {
- uint32_t ssrc = mSources.keyAt(i);
- sp<Source> source = mSources.valueAt(i);
-
- if (numReportBlocks > 31 || buf->size() + 24 > buf->capacity()) {
- // Cannot fit another report block.
- break;
- }
-
- source->addReportBlock(ssrc, buf);
- ++numReportBlocks;
- }
-
- ptr[0] |= numReportBlocks; // 5 bit
-
- size_t sizeInWordsMinus1 = 1 + 6 * numReportBlocks;
- ptr[2] = sizeInWordsMinus1 >> 8;
- ptr[3] = sizeInWordsMinus1 & 0xff;
-
- buf->setRange(0, (sizeInWordsMinus1 + 1) * 4);
-
- addSDES(buf);
-
- mNetSession->sendRequest(mRTCPSessionID, buf->data(), buf->size());
-#endif
-
- scheduleSendRR();
-}
-
-status_t RTPReceiver::registerPacketType(
- uint8_t packetType, PacketizationMode mode) {
- mPacketTypes.add(packetType, mode);
-
- return OK;
-}
-
-sp<RTPReceiver::Assembler> RTPReceiver::makeAssembler(uint8_t packetType) {
- ssize_t index = mPacketTypes.indexOfKey(packetType);
- if (index < 0) {
- return NULL;
- }
-
- PacketizationMode mode = mPacketTypes.valueAt(index);
-
- switch (mode) {
- case PACKETIZATION_NONE:
- case PACKETIZATION_TRANSPORT_STREAM:
- return new TSAssembler(mNotify);
-
- case PACKETIZATION_H264:
- return new H264Assembler(mNotify);
-
- default:
- return NULL;
- }
-}
-
-void RTPReceiver::requestRetransmission(uint32_t senderSSRC, int32_t extSeqNo) {
- int32_t blp = 0;
-
- sp<ABuffer> buf = new ABuffer(16);
- buf->setRange(0, 0);
-
- uint8_t *ptr = buf->data();
- ptr[0] = 0x80 | 1; // generic NACK
- ptr[1] = 205; // TSFB
- ptr[2] = 0;
- ptr[3] = 3;
- ptr[8] = (senderSSRC >> 24) & 0xff;
- ptr[9] = (senderSSRC >> 16) & 0xff;
- ptr[10] = (senderSSRC >> 8) & 0xff;
- ptr[11] = (senderSSRC & 0xff);
- ptr[8] = (kSourceID >> 24) & 0xff;
- ptr[9] = (kSourceID >> 16) & 0xff;
- ptr[10] = (kSourceID >> 8) & 0xff;
- ptr[11] = (kSourceID & 0xff);
- ptr[12] = (extSeqNo >> 8) & 0xff;
- ptr[13] = (extSeqNo & 0xff);
- ptr[14] = (blp >> 8) & 0xff;
- ptr[15] = (blp & 0xff);
-
- buf->setRange(0, 16);
-
- mNetSession->sendRequest(mRTCPSessionID, buf->data(), buf->size());
-}
-
-void RTPReceiver::Source::modifyPacketStatus(int32_t extSeqNo, uint32_t mask) {
-#if TRACK_PACKET_LOSS
- ssize_t index = mLostPackets.indexOfKey(extSeqNo);
- if (index < 0) {
- mLostPackets.add(extSeqNo, mask);
- } else {
- mLostPackets.editValueAt(index) |= mask;
- }
-#endif
-}
-
-void RTPReceiver::Source::postRetransmitTimer(int64_t timeUs) {
- int64_t delayUs = timeUs - ALooper::GetNowUs();
- sp<AMessage> msg = new AMessage(kWhatRetransmit, id());
- msg->setInt32("generation", mRetransmitGeneration);
- msg->post(delayUs);
-}
-
-void RTPReceiver::Source::postDeclareLostTimer(int64_t timeUs) {
- CHECK(!mDeclareLostTimerPending);
- mDeclareLostTimerPending = true;
-
- int64_t delayUs = timeUs - ALooper::GetNowUs();
- sp<AMessage> msg = new AMessage(kWhatDeclareLost, id());
- msg->setInt32("generation", mDeclareLostGeneration);
- msg->post(delayUs);
-}
-
-void RTPReceiver::Source::cancelTimers() {
- ++mRetransmitGeneration;
- ++mDeclareLostGeneration;
- mDeclareLostTimerPending = false;
-}
-
-} // namespace android
-