Home | History | Annotate | Download | only in rtsp
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "ARTPConnection"
     19 #include <utils/Log.h>
     20 
     21 #include "ARTPAssembler.h"
     22 #include "ARTPConnection.h"
     23 
     24 #include "ARTPSource.h"
     25 #include "ASessionDescription.h"
     26 
     27 #include <media/stagefright/foundation/ABuffer.h>
     28 #include <media/stagefright/foundation/ADebug.h>
     29 #include <media/stagefright/foundation/AMessage.h>
     30 #include <media/stagefright/foundation/AString.h>
     31 #include <media/stagefright/foundation/hexdump.h>
     32 
     33 #include <arpa/inet.h>
     34 #include <sys/socket.h>
     35 
     36 namespace android {
     37 
     38 static const size_t kMaxUDPSize = 1500;
     39 
     40 static uint16_t u16at(const uint8_t *data) {
     41     return data[0] << 8 | data[1];
     42 }
     43 
     44 static uint32_t u32at(const uint8_t *data) {
     45     return u16at(data) << 16 | u16at(&data[2]);
     46 }
     47 
     48 static uint64_t u64at(const uint8_t *data) {
     49     return (uint64_t)(u32at(data)) << 32 | u32at(&data[4]);
     50 }
     51 
     52 // static
     53 const int64_t ARTPConnection::kSelectTimeoutUs = 1000ll;
     54 
     55 struct ARTPConnection::StreamInfo {
     56     int mRTPSocket;
     57     int mRTCPSocket;
     58     sp<ASessionDescription> mSessionDesc;
     59     size_t mIndex;
     60     sp<AMessage> mNotifyMsg;
     61     KeyedVector<uint32_t, sp<ARTPSource> > mSources;
     62 
     63     int64_t mNumRTCPPacketsReceived;
     64     int64_t mNumRTPPacketsReceived;
     65     struct sockaddr_in mRemoteRTCPAddr;
     66 
     67     bool mIsInjected;
     68 };
     69 
     70 ARTPConnection::ARTPConnection(uint32_t flags)
     71     : mFlags(flags),
     72       mPollEventPending(false),
     73       mLastReceiverReportTimeUs(-1) {
     74 }
     75 
     76 ARTPConnection::~ARTPConnection() {
     77 }
     78 
     79 void ARTPConnection::addStream(
     80         int rtpSocket, int rtcpSocket,
     81         const sp<ASessionDescription> &sessionDesc,
     82         size_t index,
     83         const sp<AMessage> &notify,
     84         bool injected) {
     85     sp<AMessage> msg = new AMessage(kWhatAddStream, this);
     86     msg->setInt32("rtp-socket", rtpSocket);
     87     msg->setInt32("rtcp-socket", rtcpSocket);
     88     msg->setObject("session-desc", sessionDesc);
     89     msg->setSize("index", index);
     90     msg->setMessage("notify", notify);
     91     msg->setInt32("injected", injected);
     92     msg->post();
     93 }
     94 
     95 void ARTPConnection::removeStream(int rtpSocket, int rtcpSocket) {
     96     sp<AMessage> msg = new AMessage(kWhatRemoveStream, this);
     97     msg->setInt32("rtp-socket", rtpSocket);
     98     msg->setInt32("rtcp-socket", rtcpSocket);
     99     msg->post();
    100 }
    101 
    102 static void bumpSocketBufferSize(int s) {
    103     int size = 256 * 1024;
    104     CHECK_EQ(setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)), 0);
    105 }
    106 
    107 // static
    108 void ARTPConnection::MakePortPair(
    109         int *rtpSocket, int *rtcpSocket, unsigned *rtpPort) {
    110     *rtpSocket = socket(AF_INET, SOCK_DGRAM, 0);
    111     CHECK_GE(*rtpSocket, 0);
    112 
    113     bumpSocketBufferSize(*rtpSocket);
    114 
    115     *rtcpSocket = socket(AF_INET, SOCK_DGRAM, 0);
    116     CHECK_GE(*rtcpSocket, 0);
    117 
    118     bumpSocketBufferSize(*rtcpSocket);
    119 
    120     /* rand() * 1000 may overflow int type, use long long */
    121     unsigned start = (unsigned)((rand()* 1000ll)/RAND_MAX) + 15550;
    122     start &= ~1;
    123 
    124     for (unsigned port = start; port < 65536; port += 2) {
    125         struct sockaddr_in addr;
    126         memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
    127         addr.sin_family = AF_INET;
    128         addr.sin_addr.s_addr = htonl(INADDR_ANY);
    129         addr.sin_port = htons(port);
    130 
    131         if (bind(*rtpSocket,
    132                  (const struct sockaddr *)&addr, sizeof(addr)) < 0) {
    133             continue;
    134         }
    135 
    136         addr.sin_port = htons(port + 1);
    137 
    138         if (bind(*rtcpSocket,
    139                  (const struct sockaddr *)&addr, sizeof(addr)) == 0) {
    140             *rtpPort = port;
    141             return;
    142         }
    143     }
    144 
    145     TRESPASS();
    146 }
    147 
    148 void ARTPConnection::onMessageReceived(const sp<AMessage> &msg) {
    149     switch (msg->what()) {
    150         case kWhatAddStream:
    151         {
    152             onAddStream(msg);
    153             break;
    154         }
    155 
    156         case kWhatRemoveStream:
    157         {
    158             onRemoveStream(msg);
    159             break;
    160         }
    161 
    162         case kWhatPollStreams:
    163         {
    164             onPollStreams();
    165             break;
    166         }
    167 
    168         case kWhatInjectPacket:
    169         {
    170             onInjectPacket(msg);
    171             break;
    172         }
    173 
    174         default:
    175         {
    176             TRESPASS();
    177             break;
    178         }
    179     }
    180 }
    181 
    182 void ARTPConnection::onAddStream(const sp<AMessage> &msg) {
    183     mStreams.push_back(StreamInfo());
    184     StreamInfo *info = &*--mStreams.end();
    185 
    186     int32_t s;
    187     CHECK(msg->findInt32("rtp-socket", &s));
    188     info->mRTPSocket = s;
    189     CHECK(msg->findInt32("rtcp-socket", &s));
    190     info->mRTCPSocket = s;
    191 
    192     int32_t injected;
    193     CHECK(msg->findInt32("injected", &injected));
    194 
    195     info->mIsInjected = injected;
    196 
    197     sp<RefBase> obj;
    198     CHECK(msg->findObject("session-desc", &obj));
    199     info->mSessionDesc = static_cast<ASessionDescription *>(obj.get());
    200 
    201     CHECK(msg->findSize("index", &info->mIndex));
    202     CHECK(msg->findMessage("notify", &info->mNotifyMsg));
    203 
    204     info->mNumRTCPPacketsReceived = 0;
    205     info->mNumRTPPacketsReceived = 0;
    206     memset(&info->mRemoteRTCPAddr, 0, sizeof(info->mRemoteRTCPAddr));
    207 
    208     if (!injected) {
    209         postPollEvent();
    210     }
    211 }
    212 
    213 void ARTPConnection::onRemoveStream(const sp<AMessage> &msg) {
    214     int32_t rtpSocket, rtcpSocket;
    215     CHECK(msg->findInt32("rtp-socket", &rtpSocket));
    216     CHECK(msg->findInt32("rtcp-socket", &rtcpSocket));
    217 
    218     List<StreamInfo>::iterator it = mStreams.begin();
    219     while (it != mStreams.end()
    220            && (it->mRTPSocket != rtpSocket || it->mRTCPSocket != rtcpSocket)) {
    221         ++it;
    222     }
    223 
    224     if (it == mStreams.end()) {
    225         return;
    226     }
    227 
    228     mStreams.erase(it);
    229 }
    230 
    231 void ARTPConnection::postPollEvent() {
    232     if (mPollEventPending) {
    233         return;
    234     }
    235 
    236     sp<AMessage> msg = new AMessage(kWhatPollStreams, this);
    237     msg->post();
    238 
    239     mPollEventPending = true;
    240 }
    241 
    242 void ARTPConnection::onPollStreams() {
    243     mPollEventPending = false;
    244 
    245     if (mStreams.empty()) {
    246         return;
    247     }
    248 
    249     struct timeval tv;
    250     tv.tv_sec = 0;
    251     tv.tv_usec = kSelectTimeoutUs;
    252 
    253     fd_set rs;
    254     FD_ZERO(&rs);
    255 
    256     int maxSocket = -1;
    257     for (List<StreamInfo>::iterator it = mStreams.begin();
    258          it != mStreams.end(); ++it) {
    259         if ((*it).mIsInjected) {
    260             continue;
    261         }
    262 
    263         FD_SET(it->mRTPSocket, &rs);
    264         FD_SET(it->mRTCPSocket, &rs);
    265 
    266         if (it->mRTPSocket > maxSocket) {
    267             maxSocket = it->mRTPSocket;
    268         }
    269         if (it->mRTCPSocket > maxSocket) {
    270             maxSocket = it->mRTCPSocket;
    271         }
    272     }
    273 
    274     if (maxSocket == -1) {
    275         return;
    276     }
    277 
    278     int res = select(maxSocket + 1, &rs, NULL, NULL, &tv);
    279 
    280     if (res > 0) {
    281         List<StreamInfo>::iterator it = mStreams.begin();
    282         while (it != mStreams.end()) {
    283             if ((*it).mIsInjected) {
    284                 ++it;
    285                 continue;
    286             }
    287 
    288             status_t err = OK;
    289             if (FD_ISSET(it->mRTPSocket, &rs)) {
    290                 err = receive(&*it, true);
    291             }
    292             if (err == OK && FD_ISSET(it->mRTCPSocket, &rs)) {
    293                 err = receive(&*it, false);
    294             }
    295 
    296             if (err == -ECONNRESET) {
    297                 // socket failure, this stream is dead, Jim.
    298 
    299                 ALOGW("failed to receive RTP/RTCP datagram.");
    300                 it = mStreams.erase(it);
    301                 continue;
    302             }
    303 
    304             ++it;
    305         }
    306     }
    307 
    308     int64_t nowUs = ALooper::GetNowUs();
    309     if (mLastReceiverReportTimeUs <= 0
    310             || mLastReceiverReportTimeUs + 5000000ll <= nowUs) {
    311         sp<ABuffer> buffer = new ABuffer(kMaxUDPSize);
    312         List<StreamInfo>::iterator it = mStreams.begin();
    313         while (it != mStreams.end()) {
    314             StreamInfo *s = &*it;
    315 
    316             if (s->mIsInjected) {
    317                 ++it;
    318                 continue;
    319             }
    320 
    321             if (s->mNumRTCPPacketsReceived == 0) {
    322                 // We have never received any RTCP packets on this stream,
    323                 // we don't even know where to send a report.
    324                 ++it;
    325                 continue;
    326             }
    327 
    328             buffer->setRange(0, 0);
    329 
    330             for (size_t i = 0; i < s->mSources.size(); ++i) {
    331                 sp<ARTPSource> source = s->mSources.valueAt(i);
    332 
    333                 source->addReceiverReport(buffer);
    334 
    335                 if (mFlags & kRegularlyRequestFIR) {
    336                     source->addFIR(buffer);
    337                 }
    338             }
    339 
    340             if (buffer->size() > 0) {
    341                 ALOGV("Sending RR...");
    342 
    343                 ssize_t n;
    344                 do {
    345                     n = sendto(
    346                         s->mRTCPSocket, buffer->data(), buffer->size(), 0,
    347                         (const struct sockaddr *)&s->mRemoteRTCPAddr,
    348                         sizeof(s->mRemoteRTCPAddr));
    349                 } while (n < 0 && errno == EINTR);
    350 
    351                 if (n <= 0) {
    352                     ALOGW("failed to send RTCP receiver report (%s).",
    353                          n == 0 ? "connection gone" : strerror(errno));
    354 
    355                     it = mStreams.erase(it);
    356                     continue;
    357                 }
    358 
    359                 CHECK_EQ(n, (ssize_t)buffer->size());
    360 
    361                 mLastReceiverReportTimeUs = nowUs;
    362             }
    363 
    364             ++it;
    365         }
    366     }
    367 
    368     if (!mStreams.empty()) {
    369         postPollEvent();
    370     }
    371 }
    372 
    373 status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
    374     ALOGV("receiving %s", receiveRTP ? "RTP" : "RTCP");
    375 
    376     CHECK(!s->mIsInjected);
    377 
    378     sp<ABuffer> buffer = new ABuffer(65536);
    379 
    380     socklen_t remoteAddrLen =
    381         (!receiveRTP && s->mNumRTCPPacketsReceived == 0)
    382             ? sizeof(s->mRemoteRTCPAddr) : 0;
    383 
    384     ssize_t nbytes;
    385     do {
    386         nbytes = recvfrom(
    387             receiveRTP ? s->mRTPSocket : s->mRTCPSocket,
    388             buffer->data(),
    389             buffer->capacity(),
    390             0,
    391             remoteAddrLen > 0 ? (struct sockaddr *)&s->mRemoteRTCPAddr : NULL,
    392             remoteAddrLen > 0 ? &remoteAddrLen : NULL);
    393     } while (nbytes < 0 && errno == EINTR);
    394 
    395     if (nbytes <= 0) {
    396         return -ECONNRESET;
    397     }
    398 
    399     buffer->setRange(0, nbytes);
    400 
    401     // ALOGI("received %d bytes.", buffer->size());
    402 
    403     status_t err;
    404     if (receiveRTP) {
    405         err = parseRTP(s, buffer);
    406     } else {
    407         err = parseRTCP(s, buffer);
    408     }
    409 
    410     return err;
    411 }
    412 
    413 status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) {
    414     if (s->mNumRTPPacketsReceived++ == 0) {
    415         sp<AMessage> notify = s->mNotifyMsg->dup();
    416         notify->setInt32("first-rtp", true);
    417         notify->post();
    418     }
    419 
    420     size_t size = buffer->size();
    421 
    422     if (size < 12) {
    423         // Too short to be a valid RTP header.
    424         return -1;
    425     }
    426 
    427     const uint8_t *data = buffer->data();
    428 
    429     if ((data[0] >> 6) != 2) {
    430         // Unsupported version.
    431         return -1;
    432     }
    433 
    434     if (data[0] & 0x20) {
    435         // Padding present.
    436 
    437         size_t paddingLength = data[size - 1];
    438 
    439         if (paddingLength + 12 > size) {
    440             // If we removed this much padding we'd end up with something
    441             // that's too short to be a valid RTP header.
    442             return -1;
    443         }
    444 
    445         size -= paddingLength;
    446     }
    447 
    448     int numCSRCs = data[0] & 0x0f;
    449 
    450     size_t payloadOffset = 12 + 4 * numCSRCs;
    451 
    452     if (size < payloadOffset) {
    453         // Not enough data to fit the basic header and all the CSRC entries.
    454         return -1;
    455     }
    456 
    457     if (data[0] & 0x10) {
    458         // Header eXtension present.
    459 
    460         if (size < payloadOffset + 4) {
    461             // Not enough data to fit the basic header, all CSRC entries
    462             // and the first 4 bytes of the extension header.
    463 
    464             return -1;
    465         }
    466 
    467         const uint8_t *extensionData = &data[payloadOffset];
    468 
    469         size_t extensionLength =
    470             4 * (extensionData[2] << 8 | extensionData[3]);
    471 
    472         if (size < payloadOffset + 4 + extensionLength) {
    473             return -1;
    474         }
    475 
    476         payloadOffset += 4 + extensionLength;
    477     }
    478 
    479     uint32_t srcId = u32at(&data[8]);
    480 
    481     sp<ARTPSource> source = findSource(s, srcId);
    482 
    483     uint32_t rtpTime = u32at(&data[4]);
    484 
    485     sp<AMessage> meta = buffer->meta();
    486     meta->setInt32("ssrc", srcId);
    487     meta->setInt32("rtp-time", rtpTime);
    488     meta->setInt32("PT", data[1] & 0x7f);
    489     meta->setInt32("M", data[1] >> 7);
    490 
    491     buffer->setInt32Data(u16at(&data[2]));
    492     buffer->setRange(payloadOffset, size - payloadOffset);
    493 
    494     source->processRTPPacket(buffer);
    495 
    496     return OK;
    497 }
    498 
    499 status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
    500     if (s->mNumRTCPPacketsReceived++ == 0) {
    501         sp<AMessage> notify = s->mNotifyMsg->dup();
    502         notify->setInt32("first-rtcp", true);
    503         notify->post();
    504     }
    505 
    506     const uint8_t *data = buffer->data();
    507     size_t size = buffer->size();
    508 
    509     while (size > 0) {
    510         if (size < 8) {
    511             // Too short to be a valid RTCP header
    512             return -1;
    513         }
    514 
    515         if ((data[0] >> 6) != 2) {
    516             // Unsupported version.
    517             return -1;
    518         }
    519 
    520         if (data[0] & 0x20) {
    521             // Padding present.
    522 
    523             size_t paddingLength = data[size - 1];
    524 
    525             if (paddingLength + 12 > size) {
    526                 // If we removed this much padding we'd end up with something
    527                 // that's too short to be a valid RTP header.
    528                 return -1;
    529             }
    530 
    531             size -= paddingLength;
    532         }
    533 
    534         size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
    535 
    536         if (size < headerLength) {
    537             // Only received a partial packet?
    538             return -1;
    539         }
    540 
    541         switch (data[1]) {
    542             case 200:
    543             {
    544                 parseSR(s, data, headerLength);
    545                 break;
    546             }
    547 
    548             case 201:  // RR
    549             case 202:  // SDES
    550             case 204:  // APP
    551                 break;
    552 
    553             case 205:  // TSFB (transport layer specific feedback)
    554             case 206:  // PSFB (payload specific feedback)
    555                 // hexdump(data, headerLength);
    556                 break;
    557 
    558             case 203:
    559             {
    560                 parseBYE(s, data, headerLength);
    561                 break;
    562             }
    563 
    564             default:
    565             {
    566                 ALOGW("Unknown RTCP packet type %u of size %zu",
    567                      (unsigned)data[1], headerLength);
    568                 break;
    569             }
    570         }
    571 
    572         data += headerLength;
    573         size -= headerLength;
    574     }
    575 
    576     return OK;
    577 }
    578 
    579 status_t ARTPConnection::parseBYE(
    580         StreamInfo *s, const uint8_t *data, size_t size) {
    581     size_t SC = data[0] & 0x3f;
    582 
    583     if (SC == 0 || size < (4 + SC * 4)) {
    584         // Packet too short for the minimal BYE header.
    585         return -1;
    586     }
    587 
    588     uint32_t id = u32at(&data[4]);
    589 
    590     sp<ARTPSource> source = findSource(s, id);
    591 
    592     source->byeReceived();
    593 
    594     return OK;
    595 }
    596 
    597 status_t ARTPConnection::parseSR(
    598         StreamInfo *s, const uint8_t *data, size_t size) {
    599     size_t RC = data[0] & 0x1f;
    600 
    601     if (size < (7 + RC * 6) * 4) {
    602         // Packet too short for the minimal SR header.
    603         return -1;
    604     }
    605 
    606     uint32_t id = u32at(&data[4]);
    607     uint64_t ntpTime = u64at(&data[8]);
    608     uint32_t rtpTime = u32at(&data[16]);
    609 
    610 #if 0
    611     ALOGI("XXX timeUpdate: ssrc=0x%08x, rtpTime %u == ntpTime %.3f",
    612          id,
    613          rtpTime,
    614          (ntpTime >> 32) + (double)(ntpTime & 0xffffffff) / (1ll << 32));
    615 #endif
    616 
    617     sp<ARTPSource> source = findSource(s, id);
    618 
    619     source->timeUpdate(rtpTime, ntpTime);
    620 
    621     return 0;
    622 }
    623 
    624 sp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) {
    625     sp<ARTPSource> source;
    626     ssize_t index = info->mSources.indexOfKey(srcId);
    627     if (index < 0) {
    628         index = info->mSources.size();
    629 
    630         source = new ARTPSource(
    631                 srcId, info->mSessionDesc, info->mIndex, info->mNotifyMsg);
    632 
    633         info->mSources.add(srcId, source);
    634     } else {
    635         source = info->mSources.valueAt(index);
    636     }
    637 
    638     return source;
    639 }
    640 
    641 void ARTPConnection::injectPacket(int index, const sp<ABuffer> &buffer) {
    642     sp<AMessage> msg = new AMessage(kWhatInjectPacket, this);
    643     msg->setInt32("index", index);
    644     msg->setBuffer("buffer", buffer);
    645     msg->post();
    646 }
    647 
    648 void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
    649     int32_t index;
    650     CHECK(msg->findInt32("index", &index));
    651 
    652     sp<ABuffer> buffer;
    653     CHECK(msg->findBuffer("buffer", &buffer));
    654 
    655     List<StreamInfo>::iterator it = mStreams.begin();
    656     while (it != mStreams.end()
    657            && it->mRTPSocket != index && it->mRTCPSocket != index) {
    658         ++it;
    659     }
    660 
    661     if (it == mStreams.end()) {
    662         TRESPASS();
    663     }
    664 
    665     StreamInfo *s = &*it;
    666 
    667     if (it->mRTPSocket == index) {
    668         parseRTP(s, buffer);
    669     } else {
    670         parseRTCP(s, buffer);
    671     }
    672 }
    673 
    674 }  // namespace android
    675 
    676