ARTPConnection.cpp revision 39ddf8e0f18766f7ba1e3246b774aa6ebd93eea8
1cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/* 2cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * 4cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * you may not use this file except in compliance with the License. 6cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * You may obtain a copy of the License at 7cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * 8cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * 10cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Unless required by applicable law or agreed to in writing, software 11cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * See the License for the specific language governing permissions and 14cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * limitations under the License. 15cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */ 16cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 17cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ARTPConnection.h" 18cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 19cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ARTPSource.h" 20cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h" 21cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 23cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h> 24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h> 25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h> 2639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/hexdump.h> 27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <arpa/inet.h> 29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <sys/socket.h> 30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 3139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#define IGNORE_RTCP_TIME 0 32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android { 34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 3539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic const size_t kMaxUDPSize = 1500; 3639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint16_t u16at(const uint8_t *data) { 38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return data[0] << 8 | data[1]; 39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint32_t u32at(const uint8_t *data) { 42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return u16at(data) << 16 | u16at(&data[2]); 43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint64_t u64at(const uint8_t *data) { 46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return (uint64_t)(u32at(data)) << 32 | u32at(&data[4]); 47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static 50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberconst int64_t ARTPConnection::kSelectTimeoutUs = 1000ll; 51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstruct ARTPConnection::StreamInfo { 53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int mRTPSocket; 54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int mRTCPSocket; 55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ASessionDescription> mSessionDesc; 56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t mIndex; 57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> mNotifyMsg; 5839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber KeyedVector<uint32_t, sp<ARTPSource> > mSources; 5939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 6039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int32_t mNumRTCPPacketsReceived; 6139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber struct sockaddr_in mRemoteRTCPAddr; 62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}; 63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPConnection::ARTPConnection() 6539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber : mPollEventPending(false), 6639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastReceiverReportTimeUs(-1) { 67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPConnection::~ARTPConnection() { 70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::addStream( 73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int rtpSocket, int rtcpSocket, 74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ASessionDescription> &sessionDesc, 75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t index, 76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<AMessage> ¬ify) { 77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatAddStream, id()); 78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtp-socket", rtpSocket); 79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtcp-socket", rtcpSocket); 80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setObject("session-desc", sessionDesc); 81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setSize("index", index); 82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setMessage("notify", notify); 83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::removeStream(int rtpSocket, int rtcpSocket) { 87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatRemoveStream, id()); 88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtp-socket", rtpSocket); 89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtcp-socket", rtcpSocket); 90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic void bumpSocketBufferSize(int s) { 94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int size = 256 * 1024; 95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ(setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)), 0); 96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static 99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::MakePortPair( 100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int *rtpSocket, int *rtcpSocket, unsigned *rtpPort) { 101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtpSocket = socket(AF_INET, SOCK_DGRAM, 0); 102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(*rtpSocket, 0); 103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber bumpSocketBufferSize(*rtpSocket); 105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtcpSocket = socket(AF_INET, SOCK_DGRAM, 0); 107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(*rtcpSocket, 0); 108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber bumpSocketBufferSize(*rtcpSocket); 110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned start = (rand() * 1000)/ RAND_MAX + 15550; 112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber start &= ~1; 113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (unsigned port = start; port < 65536; port += 2) { 115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber struct sockaddr_in addr; 116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); 117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_family = AF_INET; 118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_addr.s_addr = INADDR_ANY; 119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_port = htons(port); 120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (bind(*rtpSocket, 122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (const struct sockaddr *)&addr, sizeof(addr)) < 0) { 123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber continue; 124cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_port = htons(port + 1); 127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (bind(*rtcpSocket, 129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (const struct sockaddr *)&addr, sizeof(addr)) == 0) { 130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtpPort = port; 131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onMessageReceived(const sp<AMessage> &msg) { 139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber switch (msg->what()) { 140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatAddStream: 141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onAddStream(msg); 143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatRemoveStream: 147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onRemoveStream(msg); 149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatPollStreams: 153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onPollStreams(); 155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber default: 159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onAddStream(const sp<AMessage> &msg) { 167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mStreams.push_back(StreamInfo()); 168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber StreamInfo *info = &*--mStreams.end(); 169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t s; 171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtp-socket", &s)); 172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mRTPSocket = s; 173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtcp-socket", &s)); 174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mRTCPSocket = s; 175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<RefBase> obj; 177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findObject("session-desc", &obj)); 178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mSessionDesc = static_cast<ASessionDescription *>(obj.get()); 179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findSize("index", &info->mIndex)); 181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findMessage("notify", &info->mNotifyMsg)); 182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 18339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber info->mNumRTCPPacketsReceived = 0; 18439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memset(&info->mRemoteRTCPAddr, 0, sizeof(info->mRemoteRTCPAddr)); 18539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber postPollEvent(); 187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onRemoveStream(const sp<AMessage> &msg) { 190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t rtpSocket, rtcpSocket; 191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtp-socket", &rtpSocket)); 192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtcp-socket", &rtcpSocket)); 193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber List<StreamInfo>::iterator it = mStreams.begin(); 195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (it != mStreams.end() 196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber && (it->mRTPSocket != rtpSocket || it->mRTCPSocket != rtcpSocket)) { 197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++it; 198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it == mStreams.end()) { 201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mStreams.erase(it); 205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::postPollEvent() { 208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (mPollEventPending) { 209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatPollStreams, id()); 213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mPollEventPending = true; 216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onPollStreams() { 219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mPollEventPending = false; 220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (mStreams.empty()) { 222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber struct timeval tv; 226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber tv.tv_sec = 0; 227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber tv.tv_usec = kSelectTimeoutUs; 228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber fd_set rs; 230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_ZERO(&rs); 231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int maxSocket = -1; 233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (List<StreamInfo>::iterator it = mStreams.begin(); 234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber it != mStreams.end(); ++it) { 235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_SET(it->mRTPSocket, &rs); 236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_SET(it->mRTCPSocket, &rs); 237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it->mRTPSocket > maxSocket) { 239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber maxSocket = it->mRTPSocket; 240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it->mRTCPSocket > maxSocket) { 242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber maxSocket = it->mRTCPSocket; 243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int res = select(maxSocket + 1, &rs, NULL, NULL, &tv); 247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(res, 0); 248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (res > 0) { 250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (List<StreamInfo>::iterator it = mStreams.begin(); 251cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber it != mStreams.end(); ++it) { 252cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (FD_ISSET(it->mRTPSocket, &rs)) { 253cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber receive(&*it, true); 254cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 255cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (FD_ISSET(it->mRTCPSocket, &rs)) { 256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber receive(&*it, false); 257cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 258cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 259cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 260cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber postPollEvent(); 26239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 26339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 26439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mLastReceiverReportTimeUs <= 0 26539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber || mLastReceiverReportTimeUs + 5000000ll <= nowUs) { 26639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ABuffer> buffer = new ABuffer(kMaxUDPSize); 26739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber for (List<StreamInfo>::iterator it = mStreams.begin(); 26839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber it != mStreams.end(); ++it) { 26939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber StreamInfo *s = &*it; 27039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 27139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (s->mNumRTCPPacketsReceived == 0) { 27239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // We have never received any RTCP packets on this stream, 27339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // we don't even know where to send a report. 27439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber continue; 27539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 27639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 27739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(0, 0); 27839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 27939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber for (size_t i = 0; i < s->mSources.size(); ++i) { 28039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ARTPSource> source = s->mSources.valueAt(i); 28139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 28239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source->addReceiverReport(buffer); 28339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source->addFIR(buffer); 28439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 28539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 28639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (buffer->size() > 0) { 28739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber LOG(VERBOSE) << "Sending RR..."; 28839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 28939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ssize_t n = sendto( 29039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber s->mRTCPSocket, buffer->data(), buffer->size(), 0, 29139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (const struct sockaddr *)&s->mRemoteRTCPAddr, 29239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sizeof(s->mRemoteRTCPAddr)); 29339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(n, (ssize_t)buffer->size()); 29439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 29539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastReceiverReportTimeUs = nowUs; 29639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 29739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 29839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 299cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 300cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 301cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { 302cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> buffer = new ABuffer(65536); 303cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 30439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber socklen_t remoteAddrLen = 30539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (!receiveRTP && s->mNumRTCPPacketsReceived == 0) 30639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ? sizeof(s->mRemoteRTCPAddr) : 0; 307cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 308cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ssize_t nbytes = recvfrom( 309cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber receiveRTP ? s->mRTPSocket : s->mRTCPSocket, 310cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->data(), 311cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->capacity(), 312cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0, 31339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber remoteAddrLen > 0 ? (struct sockaddr *)&s->mRemoteRTCPAddr : NULL, 31439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber remoteAddrLen > 0 ? &remoteAddrLen : NULL); 315cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 316cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (nbytes < 0) { 317cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 318cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 319cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 320cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setRange(0, nbytes); 321cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 322cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber status_t err; 323cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (receiveRTP) { 324cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber err = parseRTP(s, buffer); 325cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 32639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ++s->mNumRTCPPacketsReceived; 327cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber err = parseRTCP(s, buffer); 328cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 329cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 330cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return err; 331cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 332cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 333cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) { 334cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t size = buffer->size(); 335cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 336cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < 12) { 337cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Too short to be a valid RTP header. 338cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 339cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 340cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 341cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = buffer->data(); 342cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 343cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((data[0] >> 6) != 2) { 344cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Unsupported version. 345cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 346cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 347cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 348cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x20) { 349cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Padding present. 350cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 351cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t paddingLength = data[size - 1]; 352cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 353cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (paddingLength + 12 > size) { 354cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // If we removed this much padding we'd end up with something 355cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // that's too short to be a valid RTP header. 356cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 357cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 358cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 359cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= paddingLength; 360cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 361cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 362cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int numCSRCs = data[0] & 0x0f; 363cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 364cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t payloadOffset = 12 + 4 * numCSRCs; 365cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 366cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset) { 367cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Not enough data to fit the basic header and all the CSRC entries. 368cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 369cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 370cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 371cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x10) { 372cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Header eXtension present. 373cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 374cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset + 4) { 375cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Not enough data to fit the basic header, all CSRC entries 376cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // and the first 4 bytes of the extension header. 377cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 378cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 379cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 380cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 381cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *extensionData = &data[payloadOffset]; 382cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 383cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t extensionLength = 384cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 4 * (extensionData[2] << 8 | extensionData[3]); 385cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 386cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset + 4 + extensionLength) { 387cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 388cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 389cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 390cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber payloadOffset += 4 + extensionLength; 391cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 392cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 393cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t srcId = u32at(&data[8]); 394cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 39539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ARTPSource> source = findSource(s, srcId); 396cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 397cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t rtpTime = u32at(&data[4]); 398cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 399cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> meta = buffer->meta(); 400cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("ssrc", srcId); 401cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("rtp-time", rtpTime); 402cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("PT", data[1] & 0x7f); 403cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("M", data[1] >> 7); 404cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 405cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setInt32Data(u16at(&data[2])); 406cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setRange(payloadOffset, size - payloadOffset); 407cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 408cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source->processRTPPacket(buffer); 409cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 410cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 411cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 412cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 413cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) { 414cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = buffer->data(); 415cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t size = buffer->size(); 416cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 417cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (size > 0) { 418cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < 8) { 419cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Too short to be a valid RTCP header 420cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 421cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 422cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 423cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((data[0] >> 6) != 2) { 424cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Unsupported version. 425cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 426cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 427cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 428cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x20) { 429cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Padding present. 430cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 431cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t paddingLength = data[size - 1]; 432cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 433cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (paddingLength + 12 > size) { 434cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // If we removed this much padding we'd end up with something 435cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // that's too short to be a valid RTP header. 436cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 437cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 438cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 439cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= paddingLength; 440cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 441cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 442cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4; 443cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 444cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < headerLength) { 445cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Only received a partial packet? 446cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 447cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 448cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 449cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber switch (data[1]) { 450cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case 200: 451cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 452cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber parseSR(s, data, headerLength); 453cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 454cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 455cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 45639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 201: // RR 45739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 202: // SDES 45839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 204: // APP 45939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 46039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 46139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 205: // TSFB (transport layer specific feedback) 46239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 206: // PSFB (payload specific feedback) 46339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // hexdump(data, headerLength); 46439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 46539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 46639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 203: 467cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 46839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber parseBYE(s, data, headerLength); 46939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 47039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 471cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 47239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber default: 47339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 47439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber LOG(WARNING) << "Unknown RTCP packet type " 47539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber << (unsigned)data[1] 47639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber << " of size " << headerLength; 477cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 478cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 479cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 480cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 481cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber data += headerLength; 482cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= headerLength; 483cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 484cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 485cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 486cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 487cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 48839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t ARTPConnection::parseBYE( 48939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber StreamInfo *s, const uint8_t *data, size_t size) { 49039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t SC = data[0] & 0x3f; 49139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 49239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (SC == 0 || size < (4 + SC * 4)) { 49339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // Packet too short for the minimal BYE header. 49439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return -1; 49539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 49639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 49739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t id = u32at(&data[4]); 49839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 49939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ARTPSource> source = findSource(s, id); 50039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 50139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source->byeReceived(); 50239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 50339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return OK; 50439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 50539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 506cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseSR( 507cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber StreamInfo *s, const uint8_t *data, size_t size) { 508cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t RC = data[0] & 0x1f; 509cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 510cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < (7 + RC * 6) * 4) { 511cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Packet too short for the minimal SR header. 512cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 513cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 514cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 515cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t id = u32at(&data[4]); 516cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint64_t ntpTime = u64at(&data[8]); 517cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t rtpTime = u32at(&data[16]); 518cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 51939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if 0 52039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber LOG(INFO) << StringPrintf( 52139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber "XXX timeUpdate: ssrc=0x%08x, rtpTime %u == ntpTime %.3f", 52239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber id, 52339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber rtpTime, (ntpTime >> 32) + (double)(ntpTime & 0xffffffff) / (1ll << 32)); 52439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif 52539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 52639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ARTPSource> source = findSource(s, id); 52739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 52839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if !IGNORE_RTCP_TIME 52939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source->timeUpdate(rtpTime, ntpTime); 530cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif 531cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 53239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return 0; 53339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 53439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 53539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubersp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) { 536cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ARTPSource> source; 53739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ssize_t index = info->mSources.indexOfKey(srcId); 538cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (index < 0) { 53939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber index = info->mSources.size(); 540cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 541cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source = new ARTPSource( 54239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber srcId, info->mSessionDesc, info->mIndex, info->mNotifyMsg); 54339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 54439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if IGNORE_RTCP_TIME 54539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // For H.263 gtalk to work... 54639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source->timeUpdate(0, 0); 54739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source->timeUpdate(30, 0x100000000ll); 54839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif 549cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 55039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber info->mSources.add(srcId, source); 551cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 55239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source = info->mSources.valueAt(index); 553cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 554cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 55539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return source; 556cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 557cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 558cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} // namespace android 559cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 560