ARTPConnection.cpp revision cf7b9c7aae758ac0b99833915053c63c2ac46e09
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> 26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <arpa/inet.h> 28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <sys/socket.h> 29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#define VERBOSE 0 31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#if VERBOSE 33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "hexdump.h" 34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif 35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android { 37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint16_t u16at(const uint8_t *data) { 39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return data[0] << 8 | data[1]; 40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint32_t u32at(const uint8_t *data) { 43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return u16at(data) << 16 | u16at(&data[2]); 44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint64_t u64at(const uint8_t *data) { 47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return (uint64_t)(u32at(data)) << 32 | u32at(&data[4]); 48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static 51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberconst int64_t ARTPConnection::kSelectTimeoutUs = 1000ll; 52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstruct ARTPConnection::StreamInfo { 54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int mRTPSocket; 55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int mRTCPSocket; 56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ASessionDescription> mSessionDesc; 57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t mIndex; 58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> mNotifyMsg; 59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}; 60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPConnection::ARTPConnection() 62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber : mPollEventPending(false) { 63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPConnection::~ARTPConnection() { 66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::addStream( 69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int rtpSocket, int rtcpSocket, 70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<ASessionDescription> &sessionDesc, 71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t index, 72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const sp<AMessage> ¬ify) { 73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatAddStream, id()); 74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtp-socket", rtpSocket); 75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtcp-socket", rtcpSocket); 76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setObject("session-desc", sessionDesc); 77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setSize("index", index); 78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setMessage("notify", notify); 79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::removeStream(int rtpSocket, int rtcpSocket) { 83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatRemoveStream, id()); 84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtp-socket", rtpSocket); 85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->setInt32("rtcp-socket", rtcpSocket); 86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic void bumpSocketBufferSize(int s) { 90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int size = 256 * 1024; 91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_EQ(setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)), 0); 92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static 95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::MakePortPair( 96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int *rtpSocket, int *rtcpSocket, unsigned *rtpPort) { 97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtpSocket = socket(AF_INET, SOCK_DGRAM, 0); 98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(*rtpSocket, 0); 99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber bumpSocketBufferSize(*rtpSocket); 101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtcpSocket = socket(AF_INET, SOCK_DGRAM, 0); 103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(*rtcpSocket, 0); 104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber bumpSocketBufferSize(*rtcpSocket); 106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber unsigned start = (rand() * 1000)/ RAND_MAX + 15550; 108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber start &= ~1; 109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (unsigned port = start; port < 65536; port += 2) { 111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber struct sockaddr_in addr; 112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); 113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_family = AF_INET; 114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_addr.s_addr = INADDR_ANY; 115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_port = htons(port); 116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (bind(*rtpSocket, 118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (const struct sockaddr *)&addr, sizeof(addr)) < 0) { 119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber continue; 120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber addr.sin_port = htons(port + 1); 123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 124cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (bind(*rtcpSocket, 125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (const struct sockaddr *)&addr, sizeof(addr)) == 0) { 126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *rtpPort = port; 127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onMessageReceived(const sp<AMessage> &msg) { 135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber switch (msg->what()) { 136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatAddStream: 137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onAddStream(msg); 139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatRemoveStream: 143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onRemoveStream(msg); 145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case kWhatPollStreams: 149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber onPollStreams(); 151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber default: 155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onAddStream(const sp<AMessage> &msg) { 163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mStreams.push_back(StreamInfo()); 164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber StreamInfo *info = &*--mStreams.end(); 165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t s; 167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtp-socket", &s)); 168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mRTPSocket = s; 169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtcp-socket", &s)); 170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mRTCPSocket = s; 171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<RefBase> obj; 173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findObject("session-desc", &obj)); 174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber info->mSessionDesc = static_cast<ASessionDescription *>(obj.get()); 175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findSize("index", &info->mIndex)); 177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findMessage("notify", &info->mNotifyMsg)); 178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber postPollEvent(); 180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onRemoveStream(const sp<AMessage> &msg) { 183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int32_t rtpSocket, rtcpSocket; 184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtp-socket", &rtpSocket)); 185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK(msg->findInt32("rtcp-socket", &rtcpSocket)); 186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber List<StreamInfo>::iterator it = mStreams.begin(); 188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (it != mStreams.end() 189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber && (it->mRTPSocket != rtpSocket || it->mRTCPSocket != rtcpSocket)) { 190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ++it; 191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it == mStreams.end()) { 194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber TRESPASS(); 195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mStreams.erase(it); 198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::postPollEvent() { 201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (mPollEventPending) { 202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> msg = new AMessage(kWhatPollStreams, id()); 206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber msg->post(); 207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mPollEventPending = true; 209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onPollStreams() { 212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mPollEventPending = false; 213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (mStreams.empty()) { 215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return; 216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber struct timeval tv; 219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber tv.tv_sec = 0; 220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber tv.tv_usec = kSelectTimeoutUs; 221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber fd_set rs; 223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_ZERO(&rs); 224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int maxSocket = -1; 226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (List<StreamInfo>::iterator it = mStreams.begin(); 227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber it != mStreams.end(); ++it) { 228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_SET(it->mRTPSocket, &rs); 229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber FD_SET(it->mRTCPSocket, &rs); 230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it->mRTPSocket > maxSocket) { 232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber maxSocket = it->mRTPSocket; 233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (it->mRTCPSocket > maxSocket) { 235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber maxSocket = it->mRTCPSocket; 236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int res = select(maxSocket + 1, &rs, NULL, NULL, &tv); 240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber CHECK_GE(res, 0); 241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (res > 0) { 243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber for (List<StreamInfo>::iterator it = mStreams.begin(); 244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber it != mStreams.end(); ++it) { 245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (FD_ISSET(it->mRTPSocket, &rs)) { 246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber receive(&*it, true); 247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (FD_ISSET(it->mRTCPSocket, &rs)) { 249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber receive(&*it, false); 250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 251cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 252cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 253cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 254cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber postPollEvent(); 255cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 257cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) { 258cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ABuffer> buffer = new ABuffer(65536); 259cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 260cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber struct sockaddr_in from; 261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber socklen_t fromSize = sizeof(from); 262cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 263cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ssize_t nbytes = recvfrom( 264cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber receiveRTP ? s->mRTPSocket : s->mRTCPSocket, 265cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->data(), 266cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->capacity(), 267cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 0, 268cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber (struct sockaddr *)&from, 269cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber &fromSize); 270cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 271cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (nbytes < 0) { 272cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 273cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 274cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 275cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setRange(0, nbytes); 276cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 277cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber status_t err; 278cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (receiveRTP) { 279cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber err = parseRTP(s, buffer); 280cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 281cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber err = parseRTCP(s, buffer); 282cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 283cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 284cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return err; 285cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 286cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 287cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) { 288cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t size = buffer->size(); 289cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 290cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < 12) { 291cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Too short to be a valid RTP header. 292cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 293cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 294cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 295cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = buffer->data(); 296cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 297cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((data[0] >> 6) != 2) { 298cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Unsupported version. 299cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 300cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 301cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 302cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x20) { 303cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Padding present. 304cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 305cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t paddingLength = data[size - 1]; 306cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 307cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (paddingLength + 12 > size) { 308cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // If we removed this much padding we'd end up with something 309cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // that's too short to be a valid RTP header. 310cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 311cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 312cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 313cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= paddingLength; 314cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 315cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 316cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber int numCSRCs = data[0] & 0x0f; 317cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 318cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t payloadOffset = 12 + 4 * numCSRCs; 319cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 320cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset) { 321cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Not enough data to fit the basic header and all the CSRC entries. 322cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 323cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 324cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 325cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x10) { 326cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Header eXtension present. 327cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 328cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset + 4) { 329cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Not enough data to fit the basic header, all CSRC entries 330cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // and the first 4 bytes of the extension header. 331cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 332cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 333cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 334cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 335cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *extensionData = &data[payloadOffset]; 336cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 337cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t extensionLength = 338cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 4 * (extensionData[2] << 8 | extensionData[3]); 339cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 340cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < payloadOffset + 4 + extensionLength) { 341cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 342cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 343cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 344cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber payloadOffset += 4 + extensionLength; 345cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 346cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 347cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t srcId = u32at(&data[8]); 348cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 349cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ARTPSource> source; 350cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ssize_t index = mSources.indexOfKey(srcId); 351cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (index < 0) { 352cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber index = mSources.size(); 353cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 354cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source = new ARTPSource( 355cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber srcId, s->mSessionDesc, s->mIndex, s->mNotifyMsg); 356cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 357cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mSources.add(srcId, source); 358cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 359cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source = mSources.valueAt(index); 360cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 361cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 362cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t rtpTime = u32at(&data[4]); 363cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 364cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<AMessage> meta = buffer->meta(); 365cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("ssrc", srcId); 366cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("rtp-time", rtpTime); 367cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("PT", data[1] & 0x7f); 368cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber meta->setInt32("M", data[1] >> 7); 369cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 370cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setInt32Data(u16at(&data[2])); 371cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 372cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#if VERBOSE 373cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("RTP = {\n" 374cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " PT: %d\n" 375cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " sequence number: %d\n" 376cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " RTP-time: 0x%08x\n" 377cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " M: %d\n" 378cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " SSRC: 0x%08x\n" 379cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber "}\n", 380cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber data[1] & 0x7f, 381cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber u16at(&data[2]), 382cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber rtpTime, 383cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber data[1] >> 7, 384cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber srcId); 385cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 386cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // hexdump(&data[payloadOffset], size - payloadOffset); 387cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif 388cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 389cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber buffer->setRange(payloadOffset, size - payloadOffset); 390cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 391cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source->processRTPPacket(buffer); 392cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 393cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 394cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 395cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 396cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) { 397cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber const uint8_t *data = buffer->data(); 398cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t size = buffer->size(); 399cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 400cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber while (size > 0) { 401cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < 8) { 402cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Too short to be a valid RTCP header 403cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 404cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 405cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 406cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if ((data[0] >> 6) != 2) { 407cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Unsupported version. 408cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 409cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 410cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 411cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (data[0] & 0x20) { 412cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Padding present. 413cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 414cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t paddingLength = data[size - 1]; 415cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 416cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (paddingLength + 12 > size) { 417cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // If we removed this much padding we'd end up with something 418cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // that's too short to be a valid RTP header. 419cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 420cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 421cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 422cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= paddingLength; 423cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 424cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 425cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4; 426cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 427cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < headerLength) { 428cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Only received a partial packet? 429cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 430cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 431cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 432cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber switch (data[1]) { 433cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber case 200: 434cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 435cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber parseSR(s, data, headerLength); 436cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 437cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 438cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 439cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber default: 440cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber { 441cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#if VERBOSE 442cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("Unknown RTCP packet type %d of size %ld\n", 443cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber data[1], headerLength); 444cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 445cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber hexdump(data, headerLength); 446cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif 447cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber break; 448cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 449cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 450cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 451cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber data += headerLength; 452cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size -= headerLength; 453cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 454cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 455cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return OK; 456cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 457cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 458cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseSR( 459cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber StreamInfo *s, const uint8_t *data, size_t size) { 460cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber size_t RC = data[0] & 0x1f; 461cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 462cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (size < (7 + RC * 6) * 4) { 463cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber // Packet too short for the minimal SR header. 464cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return -1; 465cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 466cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 467cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t id = u32at(&data[4]); 468cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint64_t ntpTime = u64at(&data[8]); 469cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber uint32_t rtpTime = u32at(&data[16]); 470cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 471cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#if VERBOSE 472cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber printf("SR = {\n" 473cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " SSRC: 0x%08x\n" 474cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " NTP-time: 0x%016llx\n" 475cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber " RTP-time: 0x%08x\n" 476cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber "}\n", 477cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber id, ntpTime, rtpTime); 478cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif 479cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 480cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber sp<ARTPSource> source; 481cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber ssize_t index = mSources.indexOfKey(id); 482cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber if (index < 0) { 483cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber index = mSources.size(); 484cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 485cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source = new ARTPSource( 486cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber id, s->mSessionDesc, s->mIndex, s->mNotifyMsg); 487cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 488cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber mSources.add(id, source); 489cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } else { 490cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source = mSources.valueAt(index); 491cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber } 492cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 493cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber source->timeUpdate(rtpTime, ntpTime); 494cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 495cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber return 0; 496cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} 497cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 498cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber} // namespace android 499cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber 500