ARTPConnection.cpp revision e7d3e90d8761f52a6acfdcd926f0392aca8ebb52
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
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
3339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic const size_t kMaxUDPSize = 1500;
3439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint16_t u16at(const uint8_t *data) {
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return data[0] << 8 | data[1];
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint32_t u32at(const uint8_t *data) {
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return u16at(data) << 16 | u16at(&data[2]);
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint64_t u64at(const uint8_t *data) {
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return (uint64_t)(u32at(data)) << 32 | u32at(&data[4]);
45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static
48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberconst int64_t ARTPConnection::kSelectTimeoutUs = 1000ll;
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstruct ARTPConnection::StreamInfo {
51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int mRTPSocket;
52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int mRTCPSocket;
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ASessionDescription> mSessionDesc;
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t mIndex;
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<AMessage> mNotifyMsg;
5639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    KeyedVector<uint32_t, sp<ARTPSource> > mSources;
5739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
5839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    int32_t mNumRTCPPacketsReceived;
5939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    struct sockaddr_in mRemoteRTCPAddr;
600792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
610792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    bool mIsInjected;
62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber};
63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
64f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas HuberARTPConnection::ARTPConnection(uint32_t flags)
65f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    : mFlags(flags),
66f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber      mPollEventPending(false),
6739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mLastReceiverReportTimeUs(-1) {
68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPConnection::~ARTPConnection() {
71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::addStream(
74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int rtpSocket, int rtcpSocket,
75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ASessionDescription> &sessionDesc,
76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t index,
770792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        const sp<AMessage> &notify,
780792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        bool injected) {
79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<AMessage> msg = new AMessage(kWhatAddStream, id());
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->setInt32("rtp-socket", rtpSocket);
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->setInt32("rtcp-socket", rtcpSocket);
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->setObject("session-desc", sessionDesc);
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->setSize("index", index);
84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->setMessage("notify", notify);
850792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    msg->setInt32("injected", injected);
86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->post();
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::removeStream(int rtpSocket, int rtcpSocket) {
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<AMessage> msg = new AMessage(kWhatRemoveStream, id());
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->setInt32("rtp-socket", rtpSocket);
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->setInt32("rtcp-socket", rtcpSocket);
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->post();
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic void bumpSocketBufferSize(int s) {
97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int size = 256 * 1024;
98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(setsockopt(s, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)), 0);
99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber// static
102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::MakePortPair(
103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int *rtpSocket, int *rtcpSocket, unsigned *rtpPort) {
104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *rtpSocket = socket(AF_INET, SOCK_DGRAM, 0);
105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(*rtpSocket, 0);
106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    bumpSocketBufferSize(*rtpSocket);
108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    *rtcpSocket = socket(AF_INET, SOCK_DGRAM, 0);
110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(*rtcpSocket, 0);
111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    bumpSocketBufferSize(*rtcpSocket);
113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned start = (rand() * 1000)/ RAND_MAX + 15550;
115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    start &= ~1;
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (unsigned port = start; port < 65536; port += 2) {
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        struct sockaddr_in addr;
119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        addr.sin_family = AF_INET;
121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        addr.sin_addr.s_addr = INADDR_ANY;
122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        addr.sin_port = htons(port);
123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
124cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (bind(*rtpSocket,
125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                 (const struct sockaddr *)&addr, sizeof(addr)) < 0) {
126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            continue;
127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        addr.sin_port = htons(port + 1);
130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (bind(*rtcpSocket,
132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                 (const struct sockaddr *)&addr, sizeof(addr)) == 0) {
133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            *rtpPort = port;
134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return;
135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    TRESPASS();
139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onMessageReceived(const sp<AMessage> &msg) {
142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    switch (msg->what()) {
143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        case kWhatAddStream:
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        {
145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            onAddStream(msg);
146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        case kWhatRemoveStream:
150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        {
151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            onRemoveStream(msg);
152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        case kWhatPollStreams:
156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        {
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            onPollStreams();
158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
1610792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        case kWhatInjectPacket:
1620792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        {
1630792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber            onInjectPacket(msg);
1640792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber            break;
1650792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        }
1660792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        default:
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        {
169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            TRESPASS();
170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            break;
171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onAddStream(const sp<AMessage> &msg) {
176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mStreams.push_back(StreamInfo());
177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    StreamInfo *info = &*--mStreams.end();
178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int32_t s;
180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(msg->findInt32("rtp-socket", &s));
181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    info->mRTPSocket = s;
182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(msg->findInt32("rtcp-socket", &s));
183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    info->mRTCPSocket = s;
184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
1850792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    int32_t injected;
1860792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    CHECK(msg->findInt32("injected", &injected));
1870792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
1880792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    info->mIsInjected = injected;
1890792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<RefBase> obj;
191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(msg->findObject("session-desc", &obj));
192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    info->mSessionDesc = static_cast<ASessionDescription *>(obj.get());
193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(msg->findSize("index", &info->mIndex));
195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(msg->findMessage("notify", &info->mNotifyMsg));
196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
19739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    info->mNumRTCPPacketsReceived = 0;
19839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    memset(&info->mRemoteRTCPAddr, 0, sizeof(info->mRemoteRTCPAddr));
19939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2000792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    if (!injected) {
2010792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        postPollEvent();
2020792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    }
203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onRemoveStream(const sp<AMessage> &msg) {
206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int32_t rtpSocket, rtcpSocket;
207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(msg->findInt32("rtp-socket", &rtpSocket));
208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK(msg->findInt32("rtcp-socket", &rtcpSocket));
209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    List<StreamInfo>::iterator it = mStreams.begin();
211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (it != mStreams.end()
212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber           && (it->mRTPSocket != rtpSocket || it->mRTCPSocket != rtcpSocket)) {
213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++it;
214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (it == mStreams.end()) {
217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        TRESPASS();
218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mStreams.erase(it);
221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::postPollEvent() {
224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mPollEventPending) {
225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return;
226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPollStreams, id());
229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    msg->post();
230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mPollEventPending = true;
232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPConnection::onPollStreams() {
235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mPollEventPending = false;
236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mStreams.empty()) {
238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return;
239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    struct timeval tv;
242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    tv.tv_sec = 0;
243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    tv.tv_usec = kSelectTimeoutUs;
244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    fd_set rs;
246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    FD_ZERO(&rs);
247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int maxSocket = -1;
249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    for (List<StreamInfo>::iterator it = mStreams.begin();
250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber         it != mStreams.end(); ++it) {
2510792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        if ((*it).mIsInjected) {
2520792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber            continue;
2530792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        }
2540792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
255cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        FD_SET(it->mRTPSocket, &rs);
256cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        FD_SET(it->mRTCPSocket, &rs);
257cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
258cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (it->mRTPSocket > maxSocket) {
259cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            maxSocket = it->mRTPSocket;
260cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
261cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (it->mRTCPSocket > maxSocket) {
262cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            maxSocket = it->mRTCPSocket;
263cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
264cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
265cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
2667aef03379179c109c2547c33c410bfc93c8db576Andreas Huber    if (maxSocket == -1) {
2677aef03379179c109c2547c33c410bfc93c8db576Andreas Huber        return;
2687aef03379179c109c2547c33c410bfc93c8db576Andreas Huber    }
2697aef03379179c109c2547c33c410bfc93c8db576Andreas Huber
270cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int res = select(maxSocket + 1, &rs, NULL, NULL, &tv);
271cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_GE(res, 0);
272cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
273cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (res > 0) {
274cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        for (List<StreamInfo>::iterator it = mStreams.begin();
275cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber             it != mStreams.end(); ++it) {
2760792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber            if ((*it).mIsInjected) {
2770792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber                continue;
2780792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber            }
2790792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
280cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (FD_ISSET(it->mRTPSocket, &rs)) {
281cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                receive(&*it, true);
282cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
283cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (FD_ISSET(it->mRTCPSocket, &rs)) {
284cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                receive(&*it, false);
285cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
286cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
287cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
288cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
289cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    postPollEvent();
29039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
29139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    int64_t nowUs = ALooper::GetNowUs();
29239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mLastReceiverReportTimeUs <= 0
29339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            || mLastReceiverReportTimeUs + 5000000ll <= nowUs) {
29439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        sp<ABuffer> buffer = new ABuffer(kMaxUDPSize);
29539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        for (List<StreamInfo>::iterator it = mStreams.begin();
29639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber             it != mStreams.end(); ++it) {
29739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            StreamInfo *s = &*it;
29839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2997aef03379179c109c2547c33c410bfc93c8db576Andreas Huber            if (s->mIsInjected) {
3007aef03379179c109c2547c33c410bfc93c8db576Andreas Huber                continue;
3017aef03379179c109c2547c33c410bfc93c8db576Andreas Huber            }
3027aef03379179c109c2547c33c410bfc93c8db576Andreas Huber
30339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            if (s->mNumRTCPPacketsReceived == 0) {
30439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                // We have never received any RTCP packets on this stream,
30539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                // we don't even know where to send a report.
30639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                continue;
30739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            }
30839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
30939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            buffer->setRange(0, 0);
31039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
31139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            for (size_t i = 0; i < s->mSources.size(); ++i) {
31239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                sp<ARTPSource> source = s->mSources.valueAt(i);
31339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
31439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                source->addReceiverReport(buffer);
315f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber
316f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber                if (mFlags & kRegularlyRequestFIR) {
317f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber                    source->addFIR(buffer);
318f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber                }
31939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            }
32039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
32139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            if (buffer->size() > 0) {
32239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                LOG(VERBOSE) << "Sending RR...";
32339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
32439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                ssize_t n = sendto(
32539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                        s->mRTCPSocket, buffer->data(), buffer->size(), 0,
32639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                        (const struct sockaddr *)&s->mRemoteRTCPAddr,
32739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                        sizeof(s->mRemoteRTCPAddr));
32839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                CHECK_EQ(n, (ssize_t)buffer->size());
32939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
33039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                mLastReceiverReportTimeUs = nowUs;
33139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            }
33239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
33339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
334cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
335cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
336cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
3370792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    CHECK(!s->mIsInjected);
3380792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
339cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ABuffer> buffer = new ABuffer(65536);
340cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
34139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    socklen_t remoteAddrLen =
34239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        (!receiveRTP && s->mNumRTCPPacketsReceived == 0)
34339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            ? sizeof(s->mRemoteRTCPAddr) : 0;
344cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
345cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    ssize_t nbytes = recvfrom(
346cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            receiveRTP ? s->mRTPSocket : s->mRTCPSocket,
347cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            buffer->data(),
348cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            buffer->capacity(),
349cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            0,
35039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            remoteAddrLen > 0 ? (struct sockaddr *)&s->mRemoteRTCPAddr : NULL,
35139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            remoteAddrLen > 0 ? &remoteAddrLen : NULL);
352cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
353cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (nbytes < 0) {
354cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return -1;
355cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
356cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
357cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    buffer->setRange(0, nbytes);
358cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
35962cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber    // LOG(INFO) << "received " << buffer->size() << " bytes.";
36062cb04d23642a2ea7c005f050494c8ef3c370dd3Andreas Huber
361cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    status_t err;
362cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (receiveRTP) {
363cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        err = parseRTP(s, buffer);
364cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
365cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        err = parseRTCP(s, buffer);
366cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
367cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
368cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return err;
369cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
370cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
371cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) {
372cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t size = buffer->size();
373cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
374cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (size < 12) {
375cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Too short to be a valid RTP header.
376cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return -1;
377cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
378cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
379cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const uint8_t *data = buffer->data();
380cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
381cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if ((data[0] >> 6) != 2) {
382cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Unsupported version.
383cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return -1;
384cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
385cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
386cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (data[0] & 0x20) {
387cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Padding present.
388cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
389cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t paddingLength = data[size - 1];
390cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
391cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (paddingLength + 12 > size) {
392cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // If we removed this much padding we'd end up with something
393cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // that's too short to be a valid RTP header.
394cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return -1;
395cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
396cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
397cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size -= paddingLength;
398cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
399cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
400cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    int numCSRCs = data[0] & 0x0f;
401cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
402cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t payloadOffset = 12 + 4 * numCSRCs;
403cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
404cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (size < payloadOffset) {
405cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Not enough data to fit the basic header and all the CSRC entries.
406cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return -1;
407cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
408cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
409cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (data[0] & 0x10) {
410cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Header eXtension present.
411cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
412cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (size < payloadOffset + 4) {
413cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // Not enough data to fit the basic header, all CSRC entries
414cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // and the first 4 bytes of the extension header.
415cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
416cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return -1;
417cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
418cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
419cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const uint8_t *extensionData = &data[payloadOffset];
420cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
421cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t extensionLength =
422cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            4 * (extensionData[2] << 8 | extensionData[3]);
423cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
424cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (size < payloadOffset + 4 + extensionLength) {
425cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return -1;
426cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
427cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
428cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        payloadOffset += 4 + extensionLength;
429cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
430cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
431cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t srcId = u32at(&data[8]);
432cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
43339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<ARTPSource> source = findSource(s, srcId);
434cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
435cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t rtpTime = u32at(&data[4]);
436cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
437cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<AMessage> meta = buffer->meta();
438cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    meta->setInt32("ssrc", srcId);
439cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    meta->setInt32("rtp-time", rtpTime);
440cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    meta->setInt32("PT", data[1] & 0x7f);
441cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    meta->setInt32("M", data[1] >> 7);
442cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
443cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    buffer->setInt32Data(u16at(&data[2]));
444cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    buffer->setRange(payloadOffset, size - payloadOffset);
445cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
446f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    if ((mFlags & kFakeTimestamps) && !source->timeEstablished()) {
447ff53123821a3ec2e71fdb1a971ea2cbae3119826Andreas Huber        source->timeUpdate(rtpTime, 0);
448f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        source->timeUpdate(rtpTime + 90000, 0x100000000ll);
449ff53123821a3ec2e71fdb1a971ea2cbae3119826Andreas Huber        CHECK(source->timeEstablished());
450ff53123821a3ec2e71fdb1a971ea2cbae3119826Andreas Huber    }
451ff53123821a3ec2e71fdb1a971ea2cbae3119826Andreas Huber
452cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    source->processRTPPacket(buffer);
453cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
454cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
455cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
456cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
457cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
458e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber    if (s->mNumRTCPPacketsReceived++ == 0) {
459e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber        sp<AMessage> notify = s->mNotifyMsg->dup();
460e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber        notify->setInt32("first-rtcp", true);
461e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber        notify->post();
462e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber    }
463e7d3e90d8761f52a6acfdcd926f0392aca8ebb52Andreas Huber
464cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    const uint8_t *data = buffer->data();
465cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t size = buffer->size();
466cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
467cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (size > 0) {
468cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (size < 8) {
469cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // Too short to be a valid RTCP header
470cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return -1;
471cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
472cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
473cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if ((data[0] >> 6) != 2) {
474cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // Unsupported version.
475cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return -1;
476cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
477cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
478cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (data[0] & 0x20) {
479cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // Padding present.
480cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
481cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            size_t paddingLength = data[size - 1];
482cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
483cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (paddingLength + 12 > size) {
484cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                // If we removed this much padding we'd end up with something
485cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                // that's too short to be a valid RTP header.
486cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                return -1;
487cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
488cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
489cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            size -= paddingLength;
490cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
491cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
492cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
493cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
494cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (size < headerLength) {
495cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // Only received a partial packet?
496cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            return -1;
497cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
498cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
499cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        switch (data[1]) {
500cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            case 200:
501cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            {
502cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                parseSR(s, data, headerLength);
503cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
504cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
505cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
50639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            case 201:  // RR
50739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            case 202:  // SDES
50839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            case 204:  // APP
50939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                break;
51039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
51139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            case 205:  // TSFB (transport layer specific feedback)
51239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            case 206:  // PSFB (payload specific feedback)
51339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                // hexdump(data, headerLength);
51439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                break;
51539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
51639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            case 203:
517cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            {
51839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                parseBYE(s, data, headerLength);
51939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                break;
52039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            }
521cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
52239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            default:
52339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            {
52439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                LOG(WARNING) << "Unknown RTCP packet type "
52539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                             << (unsigned)data[1]
52639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                             << " of size " << headerLength;
527cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
528cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
529cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
530cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
531cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        data += headerLength;
532cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        size -= headerLength;
533cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
534cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
535cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return OK;
536cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
537cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
53839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatus_t ARTPConnection::parseBYE(
53939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        StreamInfo *s, const uint8_t *data, size_t size) {
54039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    size_t SC = data[0] & 0x3f;
54139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
54239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (SC == 0 || size < (4 + SC * 4)) {
54339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        // Packet too short for the minimal BYE header.
54439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return -1;
54539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
54639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
54739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    uint32_t id = u32at(&data[4]);
54839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
54939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<ARTPSource> source = findSource(s, id);
55039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
55139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    source->byeReceived();
55239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
55339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return OK;
55439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
55539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
556cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatus_t ARTPConnection::parseSR(
557cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        StreamInfo *s, const uint8_t *data, size_t size) {
558cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    size_t RC = data[0] & 0x1f;
559cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
560cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (size < (7 + RC * 6) * 4) {
561cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // Packet too short for the minimal SR header.
562cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return -1;
563cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
564cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
565cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t id = u32at(&data[4]);
566cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint64_t ntpTime = u64at(&data[8]);
567cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t rtpTime = u32at(&data[16]);
568cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
56939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if 0
57039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    LOG(INFO) << StringPrintf(
57139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            "XXX timeUpdate: ssrc=0x%08x, rtpTime %u == ntpTime %.3f",
57239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            id,
57339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            rtpTime, (ntpTime >> 32) + (double)(ntpTime & 0xffffffff) / (1ll << 32));
57439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif
57539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
57639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<ARTPSource> source = findSource(s, id);
57739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
578f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    if ((mFlags & kFakeTimestamps) == 0) {
579f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber        source->timeUpdate(rtpTime, ntpTime);
580f8ca90452ff3e252f20de38f1c3eee524c808c3eAndreas Huber    }
581cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
58239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return 0;
58339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
58439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
58539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubersp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) {
586cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sp<ARTPSource> source;
58739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    ssize_t index = info->mSources.indexOfKey(srcId);
588cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (index < 0) {
58939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        index = info->mSources.size();
590cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
591cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        source = new ARTPSource(
59239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                srcId, info->mSessionDesc, info->mIndex, info->mNotifyMsg);
59339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
59439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        info->mSources.add(srcId, source);
595cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
59639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        source = info->mSources.valueAt(index);
597cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
598cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
59939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return source;
600cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
601cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
6020792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Hubervoid ARTPConnection::injectPacket(int index, const sp<ABuffer> &buffer) {
6030792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    sp<AMessage> msg = new AMessage(kWhatInjectPacket, id());
6040792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    msg->setInt32("index", index);
6050792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    msg->setObject("buffer", buffer);
6060792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    msg->post();
6070792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber}
6080792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
6090792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Hubervoid ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
6100792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    int32_t index;
6110792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    CHECK(msg->findInt32("index", &index));
6120792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
6130792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    sp<RefBase> obj;
6140792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    CHECK(msg->findObject("buffer", &obj));
6150792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
6160792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
6170792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
6180792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    List<StreamInfo>::iterator it = mStreams.begin();
6190792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    while (it != mStreams.end()
6200792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber           && it->mRTPSocket != index && it->mRTCPSocket != index) {
6210792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        ++it;
6220792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    }
6230792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
6240792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    if (it == mStreams.end()) {
6250792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        TRESPASS();
6260792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    }
6270792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
6280792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    StreamInfo *s = &*it;
6290792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
6300792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    status_t err;
6310792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    if (it->mRTPSocket == index) {
6320792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        err = parseRTP(s, buffer);
6330792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    } else {
6340792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber        err = parseRTCP(s, buffer);
6350792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber    }
6360792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber}
6370792ce7e0924ebb0dbe7b7cfcd79d12cbdb03ed2Andreas Huber
638cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
639cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
640