ARTPConnection.cpp revision 5ff1dd576bb93c45b44088a51544a18fc43ebf58
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 176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0 186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "ARTPConnection" 196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h> 206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber 21cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ARTPConnection.h" 22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 23cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ARTPSource.h" 24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h" 25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h> 28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h> 29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AString.h> 3039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/hexdump.h> 31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <arpa/inet.h> 33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <sys/socket.h> 34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android { 36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 3739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic const size_t kMaxUDPSize = 1500; 3839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint16_t u16at(const uint8_t *data) { 40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return data[0] << 8 | data[1]; 41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint32_t u32at(const uint8_t *data) { 44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return u16at(data) << 16 | u16at(&data[2]); 45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint64_t u64at(const uint8_t *data) { 48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return (uint64_t)(u32at(data)) << 32 | u32at(&data[4]); 49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static 52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberconst int64_t ARTPConnection::kSelectTimeoutUs = 1000ll; 53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstruct ARTPConnection::StreamInfo { 55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int mRTPSocket; 56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int mRTCPSocket; 57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ASessionDescription> mSessionDesc; 58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t mIndex; 59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> mNotifyMsg; 6039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber KeyedVector<uint32_t, sp<ARTPSource> > mSources; 6139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 62f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber int64_t mNumRTCPPacketsReceived; 63f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber int64_t mNumRTPPacketsReceived; 6439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber struct sockaddr_in mRemoteRTCPAddr; 650792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 660792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber bool mIsInjected; 67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}; 68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 69f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas HuberARTPConnection::ARTPConnection(uint32_t flags) 70f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber : mFlags(flags), 71f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber mPollEventPending(false), 7239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastReceiverReportTimeUs(-1) { 73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPConnection::~ARTPConnection() { 76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::addStream( 79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int rtpSocket, int rtcpSocket, 80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ASessionDescription> &sessionDesc, 81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t index, 820792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber const sp<AMessage> ¬ify, 830792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber bool injected) { 84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatAddStream, id()); 85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtp-socket", rtpSocket); 86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtcp-socket", rtcpSocket); 87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setObject("session-desc", sessionDesc); 88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setSize("index", index); 89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setMessage("notify", notify); 900792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber msg->setInt32("injected", injected); 91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::removeStream(int rtpSocket, int rtcpSocket) { 95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatRemoveStream, id()); 96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtp-socket", rtpSocket); 97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtcp-socket", rtcpSocket); 98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic void bumpSocketBufferSize(int s) { 102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int size = 256 * 1024; 103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ(setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)), 0); 104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static 107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::MakePortPair( 108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int *rtpSocket, int *rtcpSocket, unsigned *rtpPort) { 109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtpSocket = socket(AF_INET, SOCK_DGRAM, 0); 110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(*rtpSocket, 0); 111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber bumpSocketBufferSize(*rtpSocket); 113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtcpSocket = socket(AF_INET, SOCK_DGRAM, 0); 115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(*rtcpSocket, 0); 116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber bumpSocketBufferSize(*rtcpSocket); 118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned start = (rand() * 1000)/ RAND_MAX + 15550; 120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber start &= ~1; 121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (unsigned port = start; port < 65536; port += 2) { 123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber struct sockaddr_in addr; 124cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); 125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_family = AF_INET; 126dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber addr.sin_addr.s_addr = htonl(INADDR_ANY); 127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_port = htons(port); 128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (bind(*rtpSocket, 130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (const struct sockaddr *)&addr, sizeof(addr)) < 0) { 131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber continue; 132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_port = htons(port + 1); 135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (bind(*rtcpSocket, 137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (const struct sockaddr *)&addr, sizeof(addr)) == 0) { 138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtpPort = port; 139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onMessageReceived(const sp<AMessage> &msg) { 147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber switch (msg->what()) { 148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatAddStream: 149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onAddStream(msg); 151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatRemoveStream: 155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onRemoveStream(msg); 157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatPollStreams: 161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onPollStreams(); 163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 1660792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber case kWhatInjectPacket: 1670792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber { 1680792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber onInjectPacket(msg); 1690792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber break; 1700792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } 1710792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber default: 173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onAddStream(const sp<AMessage> &msg) { 181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mStreams.push_back(StreamInfo()); 182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber StreamInfo *info = &*--mStreams.end(); 183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t s; 185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtp-socket", &s)); 186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mRTPSocket = s; 187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtcp-socket", &s)); 188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mRTCPSocket = s; 189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 1900792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber int32_t injected; 1910792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber CHECK(msg->findInt32("injected", &injected)); 1920792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 1930792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber info->mIsInjected = injected; 1940792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<RefBase> obj; 196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findObject("session-desc", &obj)); 197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mSessionDesc = static_cast<ASessionDescription *>(obj.get()); 198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findSize("index", &info->mIndex)); 200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findMessage("notify", &info->mNotifyMsg)); 201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 20239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber info->mNumRTCPPacketsReceived = 0; 203f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber info->mNumRTPPacketsReceived = 0; 20439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber memset(&info->mRemoteRTCPAddr, 0, sizeof(info->mRemoteRTCPAddr)); 20539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 2060792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber if (!injected) { 2070792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber postPollEvent(); 2080792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } 209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onRemoveStream(const sp<AMessage> &msg) { 212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t rtpSocket, rtcpSocket; 213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtp-socket", &rtpSocket)); 214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtcp-socket", &rtcpSocket)); 215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber List<StreamInfo>::iterator it = mStreams.begin(); 217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (it != mStreams.end() 218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber && (it->mRTPSocket != rtpSocket || it->mRTCPSocket != rtcpSocket)) { 219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++it; 220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it == mStreams.end()) { 2238c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber return; 224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mStreams.erase(it); 227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::postPollEvent() { 230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (mPollEventPending) { 231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatPollStreams, id()); 235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mPollEventPending = true; 238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onPollStreams() { 241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mPollEventPending = false; 242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (mStreams.empty()) { 244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber struct timeval tv; 248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber tv.tv_sec = 0; 249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber tv.tv_usec = kSelectTimeoutUs; 250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 251cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber fd_set rs; 252cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_ZERO(&rs); 253cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 254cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int maxSocket = -1; 255cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (List<StreamInfo>::iterator it = mStreams.begin(); 256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber it != mStreams.end(); ++it) { 2570792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber if ((*it).mIsInjected) { 2580792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber continue; 2590792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } 2600792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_SET(it->mRTPSocket, &rs); 262cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_SET(it->mRTCPSocket, &rs); 263cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 264cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it->mRTPSocket > maxSocket) { 265cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber maxSocket = it->mRTPSocket; 266cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 267cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it->mRTCPSocket > maxSocket) { 268cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber maxSocket = it->mRTCPSocket; 269cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 270cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 271cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 2727aef03379179c109c2547c33c410bfc93c8db576Andreas Huber if (maxSocket == -1) { 2737aef03379179c109c2547c33c410bfc93c8db576Andreas Huber return; 2747aef03379179c109c2547c33c410bfc93c8db576Andreas Huber } 2757aef03379179c109c2547c33c410bfc93c8db576Andreas Huber 276cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int res = select(maxSocket + 1, &rs, NULL, NULL, &tv); 277cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 278cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (res > 0) { 2798c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber List<StreamInfo>::iterator it = mStreams.begin(); 2808c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber while (it != mStreams.end()) { 2810792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber if ((*it).mIsInjected) { 2828c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber ++it; 2830792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber continue; 2840792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } 2850792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 2868c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber status_t err = OK; 287cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (FD_ISSET(it->mRTPSocket, &rs)) { 2888c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber err = receive(&*it, true); 2898c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber } 2908c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber if (err == OK && FD_ISSET(it->mRTCPSocket, &rs)) { 2918c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber err = receive(&*it, false); 292cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 2938c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber 2948c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber if (err == -ECONNRESET) { 2958c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber // socket failure, this stream is dead, Jim. 2968c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber 2975ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("failed to receive RTP/RTCP datagram."); 2988c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber it = mStreams.erase(it); 2998c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber continue; 300cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 3018c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber 3028c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber ++it; 303cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 304cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 305cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 30639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 30739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (mLastReceiverReportTimeUs <= 0 30839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber || mLastReceiverReportTimeUs + 5000000ll <= nowUs) { 30939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ABuffer> buffer = new ABuffer(kMaxUDPSize); 3108c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber List<StreamInfo>::iterator it = mStreams.begin(); 3118c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber while (it != mStreams.end()) { 31239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber StreamInfo *s = &*it; 31339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 3147aef03379179c109c2547c33c410bfc93c8db576Andreas Huber if (s->mIsInjected) { 3158c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber ++it; 3167aef03379179c109c2547c33c410bfc93c8db576Andreas Huber continue; 3177aef03379179c109c2547c33c410bfc93c8db576Andreas Huber } 3187aef03379179c109c2547c33c410bfc93c8db576Andreas Huber 31939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (s->mNumRTCPPacketsReceived == 0) { 32039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // We have never received any RTCP packets on this stream, 32139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // we don't even know where to send a report. 3228c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber ++it; 32339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber continue; 32439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 32539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 32639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber buffer->setRange(0, 0); 32739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 32839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber for (size_t i = 0; i < s->mSources.size(); ++i) { 32939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ARTPSource> source = s->mSources.valueAt(i); 33039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 33139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source->addReceiverReport(buffer); 332f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber 333f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber if (mFlags & kRegularlyRequestFIR) { 334f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber source->addFIR(buffer); 335f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber } 33639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 33739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 33839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (buffer->size() > 0) { 3393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Sending RR..."); 34039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 3418c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber ssize_t n; 3428c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber do { 3438c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber n = sendto( 34439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber s->mRTCPSocket, buffer->data(), buffer->size(), 0, 34539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (const struct sockaddr *)&s->mRemoteRTCPAddr, 34639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sizeof(s->mRemoteRTCPAddr)); 3478c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber } while (n < 0 && errno == EINTR); 3488c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber 3498c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber if (n <= 0) { 3505ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("failed to send RTCP receiver report (%s).", 3518c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber n == 0 ? "connection gone" : strerror(errno)); 3528c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber 3538c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber it = mStreams.erase(it); 3548c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber continue; 3558c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber } 3568c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber 35739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber CHECK_EQ(n, (ssize_t)buffer->size()); 35839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 35939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber mLastReceiverReportTimeUs = nowUs; 36039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 3618c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber 3628c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber ++it; 36339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 36439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 3658c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber 3668c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber if (!mStreams.empty()) { 3678c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber postPollEvent(); 3688c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber } 369cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 370cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 371cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { 3723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("receiving %s", receiveRTP ? "RTP" : "RTCP"); 373dc468c5f9d72ce54de0070493e9a23efb8907e06Andreas Huber 3740792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber CHECK(!s->mIsInjected); 3750792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 376cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> buffer = new ABuffer(65536); 377cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 37839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber socklen_t remoteAddrLen = 37939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber (!receiveRTP && s->mNumRTCPPacketsReceived == 0) 38039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ? sizeof(s->mRemoteRTCPAddr) : 0; 381cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 3828c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber ssize_t nbytes; 3838c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber do { 3848c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber nbytes = recvfrom( 385cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber receiveRTP ? s->mRTPSocket : s->mRTCPSocket, 386cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->data(), 387cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->capacity(), 388cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0, 38939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber remoteAddrLen > 0 ? (struct sockaddr *)&s->mRemoteRTCPAddr : NULL, 39039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber remoteAddrLen > 0 ? &remoteAddrLen : NULL); 3918c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber } while (nbytes < 0 && errno == EINTR); 392cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 3938c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber if (nbytes <= 0) { 3948c308ffd781132c8417cebc3bf77c2e56a464e0bAndreas Huber return -ECONNRESET; 395cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 396cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 397cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setRange(0, nbytes); 398cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 399df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block // ALOGI("received %d bytes.", buffer->size()); 40062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber 401cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber status_t err; 402cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (receiveRTP) { 403cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber err = parseRTP(s, buffer); 404cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 405cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber err = parseRTCP(s, buffer); 406cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 407cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 408cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return err; 409cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 410cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 411cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) { 412f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber if (s->mNumRTPPacketsReceived++ == 0) { 413f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber sp<AMessage> notify = s->mNotifyMsg->dup(); 414f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber notify->setInt32("first-rtp", true); 415f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber notify->post(); 416f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber } 417f61551f4fc79e7da879802e3974afa9b03ffb5d0Andreas Huber 418cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t size = buffer->size(); 419cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 420cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < 12) { 421cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Too short to be a valid RTP header. 422cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 423cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 424cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 425cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = buffer->data(); 426cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 427cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((data[0] >> 6) != 2) { 428cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Unsupported version. 429cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 430cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 431cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 432cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x20) { 433cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Padding present. 434cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 435cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t paddingLength = data[size - 1]; 436cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 437cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (paddingLength + 12 > size) { 438cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // If we removed this much padding we'd end up with something 439cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // that's too short to be a valid RTP header. 440cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 441cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 442cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 443cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= paddingLength; 444cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 445cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 446cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int numCSRCs = data[0] & 0x0f; 447cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 448cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t payloadOffset = 12 + 4 * numCSRCs; 449cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 450cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset) { 451cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Not enough data to fit the basic header and all the CSRC entries. 452cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 453cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 454cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 455cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x10) { 456cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Header eXtension present. 457cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 458cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset + 4) { 459cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Not enough data to fit the basic header, all CSRC entries 460cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // and the first 4 bytes of the extension header. 461cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 462cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 463cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 464cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 465cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *extensionData = &data[payloadOffset]; 466cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 467cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t extensionLength = 468cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 4 * (extensionData[2] << 8 | extensionData[3]); 469cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 470cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset + 4 + extensionLength) { 471cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 472cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 473cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 474cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber payloadOffset += 4 + extensionLength; 475cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 476cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 477cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t srcId = u32at(&data[8]); 478cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 47939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ARTPSource> source = findSource(s, srcId); 480cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 481cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t rtpTime = u32at(&data[4]); 482cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 483cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> meta = buffer->meta(); 484cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("ssrc", srcId); 485cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("rtp-time", rtpTime); 486cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("PT", data[1] & 0x7f); 487cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("M", data[1] >> 7); 488cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 489cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setInt32Data(u16at(&data[2])); 490cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setRange(payloadOffset, size - payloadOffset); 491cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 492cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source->processRTPPacket(buffer); 493cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 494cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 495cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 496cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 497cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) { 498e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber if (s->mNumRTCPPacketsReceived++ == 0) { 499e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber sp<AMessage> notify = s->mNotifyMsg->dup(); 500e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber notify->setInt32("first-rtcp", true); 501e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber notify->post(); 502e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber } 503e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber 504cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = buffer->data(); 505cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t size = buffer->size(); 506cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 507cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (size > 0) { 508cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < 8) { 509cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Too short to be a valid RTCP header 510cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 511cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 512cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 513cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((data[0] >> 6) != 2) { 514cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Unsupported version. 515cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 516cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 517cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 518cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x20) { 519cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Padding present. 520cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 521cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t paddingLength = data[size - 1]; 522cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 523cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (paddingLength + 12 > size) { 524cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // If we removed this much padding we'd end up with something 525cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // that's too short to be a valid RTP header. 526cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 527cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 528cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 529cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= paddingLength; 530cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 531cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 532cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4; 533cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 534cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < headerLength) { 535cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Only received a partial packet? 536cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 537cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 538cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 539cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber switch (data[1]) { 540cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case 200: 541cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 542cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber parseSR(s, data, headerLength); 543cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 544cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 545cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 54639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 201: // RR 54739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 202: // SDES 54839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 204: // APP 54939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 55039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 55139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 205: // TSFB (transport layer specific feedback) 55239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 206: // PSFB (payload specific feedback) 55339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // hexdump(data, headerLength); 55439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 55539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 55639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber case 203: 557cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 55839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber parseBYE(s, data, headerLength); 55939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber break; 56039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 561cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 56239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber default: 56339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber { 5645ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Unknown RTCP packet type %u of size %d", 5656e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber (unsigned)data[1], headerLength); 566cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 567cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 568cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 569cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 570cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber data += headerLength; 571cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= headerLength; 572cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 573cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 574cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 575cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 576cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 57739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t ARTPConnection::parseBYE( 57839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber StreamInfo *s, const uint8_t *data, size_t size) { 57939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber size_t SC = data[0] & 0x3f; 58039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 58139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber if (SC == 0 || size < (4 + SC * 4)) { 58239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber // Packet too short for the minimal BYE header. 58339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return -1; 58439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber } 58539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 58639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber uint32_t id = u32at(&data[4]); 58739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 58839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ARTPSource> source = findSource(s, id); 58939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 59039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source->byeReceived(); 59139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 59239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return OK; 59339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 59439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 595cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseSR( 596cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber StreamInfo *s, const uint8_t *data, size_t size) { 597cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t RC = data[0] & 0x1f; 598cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 599cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < (7 + RC * 6) * 4) { 600cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Packet too short for the minimal SR header. 601cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 602cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 603cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 604cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t id = u32at(&data[4]); 605cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint64_t ntpTime = u64at(&data[8]); 606cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t rtpTime = u32at(&data[16]); 607cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 60839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if 0 609df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("XXX timeUpdate: ssrc=0x%08x, rtpTime %u == ntpTime %.3f", 6106e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber id, 6116e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber rtpTime, 6126e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber (ntpTime >> 32) + (double)(ntpTime & 0xffffffff) / (1ll << 32)); 61339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif 61439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 61539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber sp<ARTPSource> source = findSource(s, id); 61639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 617100a4408968b90e314526185d572c72ea4cc784aAndreas Huber source->timeUpdate(rtpTime, ntpTime); 618cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 61939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return 0; 62039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber} 62139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 62239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubersp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) { 623cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ARTPSource> source; 62439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber ssize_t index = info->mSources.indexOfKey(srcId); 625cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (index < 0) { 62639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber index = info->mSources.size(); 627cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 628cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source = new ARTPSource( 62939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber srcId, info->mSessionDesc, info->mIndex, info->mNotifyMsg); 63039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber 63139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber info->mSources.add(srcId, source); 632cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 63339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber source = info->mSources.valueAt(index); 634cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 635cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 63639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber return source; 637cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 638cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 6390792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Hubervoid ARTPConnection::injectPacket(int index, const sp<ABuffer> &buffer) { 6400792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber sp<AMessage> msg = new AMessage(kWhatInjectPacket, id()); 6410792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber msg->setInt32("index", index); 6420792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber msg->setObject("buffer", buffer); 6430792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber msg->post(); 6440792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber} 6450792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 6460792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Hubervoid ARTPConnection::onInjectPacket(const sp<AMessage> &msg) { 6470792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber int32_t index; 6480792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber CHECK(msg->findInt32("index", &index)); 6490792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 6500792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber sp<RefBase> obj; 6510792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber CHECK(msg->findObject("buffer", &obj)); 6520792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 6530792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get()); 6540792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 6550792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber List<StreamInfo>::iterator it = mStreams.begin(); 6560792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber while (it != mStreams.end() 6570792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber && it->mRTPSocket != index && it->mRTCPSocket != index) { 6580792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber ++it; 6590792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } 6600792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 6610792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber if (it == mStreams.end()) { 6620792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber TRESPASS(); 6630792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } 6640792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 6650792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber StreamInfo *s = &*it; 6660792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 6670792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber status_t err; 6680792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber if (it->mRTPSocket == index) { 6690792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber err = parseRTP(s, buffer); 6700792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } else { 6710792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber err = parseRTCP(s, buffer); 6720792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber } 6730792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber} 6740792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber 675cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} // namespace android 676cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 677