1a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber/*
2a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Copyright 2013, The Android Open Source Project
3a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber *
4a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * you may not use this file except in compliance with the License.
6a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * You may obtain a copy of the License at
7a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber *
8a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
9a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber *
10a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Unless required by applicable law or agreed to in writing, software
11a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * See the License for the specific language governing permissions and
14a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * limitations under the License.
15a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber */
16a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
17a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber//#define LOG_NDEBUG 0
18a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#define LOG_TAG "RTPSender"
19a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <utils/Log.h>
20a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
21a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "RTPSender.h"
22a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
23a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
24a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/ADebug.h>
25a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/AMessage.h>
268060060217ff16cd67c8f6a15c649f44c343acf0Andreas Huber#include <media/stagefright/foundation/ANetworkSession.h>
27a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/hexdump.h>
28a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/MediaErrors.h>
29a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/Utils.h>
30a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
31a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "include/avc_utils.h"
32a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
33a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubernamespace android {
34a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
35a556c4822fc205db0d27834ba5b637c351d73ffaAndreas HuberRTPSender::RTPSender(
36a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const sp<ANetworkSession> &netSession,
37a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const sp<AMessage> &notify)
38a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    : mNetSession(netSession),
39a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mNotify(notify),
406e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber      mRTPMode(TRANSPORT_UNDEFINED),
416e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber      mRTCPMode(TRANSPORT_UNDEFINED),
42a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mRTPSessionID(0),
43a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mRTCPSessionID(0),
44a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mRTPConnected(false),
45a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mRTCPConnected(false),
46a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mLastNTPTime(0),
47a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mLastRTPTime(0),
48a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mNumRTPSent(0),
49a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mNumRTPOctetsSent(0),
50a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mNumSRsSent(0),
51a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mRTPSeqNo(0),
52a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mHistorySize(0) {
53a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
54a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
55a556c4822fc205db0d27834ba5b637c351d73ffaAndreas HuberRTPSender::~RTPSender() {
56a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mRTCPSessionID != 0) {
57a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mNetSession->destroySession(mRTCPSessionID);
58a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mRTCPSessionID = 0;
59a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
60a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
61a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mRTPSessionID != 0) {
62a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mNetSession->destroySession(mRTPSessionID);
63a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mRTPSessionID = 0;
64a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
65a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
66a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
67a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber// static
68a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberint32_t RTPBase::PickRandomRTPPort() {
69a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    // Pick an even integer in range [1024, 65534)
70a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
71a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    static const size_t kRange = (65534 - 1024) / 2;
72a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
73a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return (int32_t)(((float)(kRange + 1) * rand()) / RAND_MAX) * 2 + 1024;
74a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
75a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
76a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t RTPSender::initAsync(
77a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const char *remoteHost,
78a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        int32_t remoteRTPPort,
796e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber        TransportMode rtpMode,
80a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        int32_t remoteRTCPPort,
816e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber        TransportMode rtcpMode,
82a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        int32_t *outLocalRTPPort) {
836e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    if (mRTPMode != TRANSPORT_UNDEFINED
846e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber            || rtpMode == TRANSPORT_UNDEFINED
856e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber            || rtpMode == TRANSPORT_NONE
866e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber            || rtcpMode == TRANSPORT_UNDEFINED) {
87a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return INVALID_OPERATION;
88a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
89a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
906e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    CHECK_NE(rtpMode, TRANSPORT_TCP_INTERLEAVED);
916e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    CHECK_NE(rtcpMode, TRANSPORT_TCP_INTERLEAVED);
92a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
932aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber    if ((rtcpMode == TRANSPORT_NONE && remoteRTCPPort >= 0)
942aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber            || (rtcpMode != TRANSPORT_NONE && remoteRTCPPort < 0)) {
95a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return INVALID_OPERATION;
96a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
97a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
98a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
99a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
100a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<AMessage> rtcpNotify;
101a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (remoteRTCPPort >= 0) {
102a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtcpNotify = new AMessage(kWhatRTCPNotify, id());
103a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
104a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
105a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK_EQ(mRTPSessionID, 0);
106a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK_EQ(mRTCPSessionID, 0);
107a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
108a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    int32_t localRTPPort;
109a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
110a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    for (;;) {
111a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        localRTPPort = PickRandomRTPPort();
112a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
113a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        status_t err;
1146e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber        if (rtpMode == TRANSPORT_UDP) {
115a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            err = mNetSession->createUDPSession(
116a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    localRTPPort,
117a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteHost,
118a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteRTPPort,
119a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    rtpNotify,
120a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    &mRTPSessionID);
121a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        } else {
1226e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber            CHECK_EQ(rtpMode, TRANSPORT_TCP);
123a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            err = mNetSession->createTCPDatagramSession(
124a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    localRTPPort,
125a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteHost,
126a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteRTPPort,
127a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    rtpNotify,
128a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    &mRTPSessionID);
129a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
130a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
131a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (err != OK) {
132a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            continue;
133a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
134a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
135a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (remoteRTCPPort < 0) {
136a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
137a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
138a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
1396e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber        if (rtcpMode == TRANSPORT_UDP) {
140a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            err = mNetSession->createUDPSession(
141a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    localRTPPort + 1,
142a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteHost,
143a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteRTCPPort,
144a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    rtcpNotify,
145a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    &mRTCPSessionID);
146a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        } else {
1476e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber            CHECK_EQ(rtcpMode, TRANSPORT_TCP);
148a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            err = mNetSession->createTCPDatagramSession(
149a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    localRTPPort + 1,
150a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteHost,
151a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteRTCPPort,
152a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    rtcpNotify,
153a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    &mRTCPSessionID);
154a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
155a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
156a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (err == OK) {
157a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
158a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
159a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
160a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mNetSession->destroySession(mRTPSessionID);
161a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mRTPSessionID = 0;
162a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
163a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
1646e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    if (rtpMode == TRANSPORT_UDP) {
165a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mRTPConnected = true;
1666e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    }
1676e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber
1686e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    if (rtcpMode == TRANSPORT_UDP) {
169a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mRTCPConnected = true;
170a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
171a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
1726e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    mRTPMode = rtpMode;
1736e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    mRTCPMode = rtcpMode;
174a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    *outLocalRTPPort = localRTPPort;
175a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
1766e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber    if (mRTPMode == TRANSPORT_UDP
1776e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber            && (mRTCPMode == TRANSPORT_UDP || mRTCPMode == TRANSPORT_NONE)) {
178a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        notifyInitDone(OK);
179a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
180a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
181a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
182a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
183a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
184a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t RTPSender::queueBuffer(
185a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const sp<ABuffer> &buffer, uint8_t packetType, PacketizationMode mode) {
186a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    status_t err;
187a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
188a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    switch (mode) {
1898f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber        case PACKETIZATION_NONE:
1908f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber            err = queueRawPacket(buffer, packetType);
1918f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber            break;
1928f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
193a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case PACKETIZATION_TRANSPORT_STREAM:
194a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            err = queueTSPackets(buffer, packetType);
195a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
196a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
197a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case PACKETIZATION_H264:
198a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            err  = queueAVCBuffer(buffer, packetType);
199a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
200a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
201a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        default:
202a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            TRESPASS();
203a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
204a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
205a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return err;
206a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
207a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
2088f1f6a4814403dd78539250c845f8326f6137a61Andreas Huberstatus_t RTPSender::queueRawPacket(
2098f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber        const sp<ABuffer> &packet, uint8_t packetType) {
2108f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    CHECK_LE(packet->size(), kMaxUDPPacketSize - 12);
2118f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2128f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    int64_t timeUs;
2138f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    CHECK(packet->meta()->findInt64("timeUs", &timeUs));
2148f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2158f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    sp<ABuffer> udpPacket = new ABuffer(12 + packet->size());
2168f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2178f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    udpPacket->setInt32Data(mRTPSeqNo);
2188f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2198f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    uint8_t *rtp = udpPacket->data();
2208f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[0] = 0x80;
2218f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[1] = packetType;
2228f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2238f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[2] = (mRTPSeqNo >> 8) & 0xff;
2248f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[3] = mRTPSeqNo & 0xff;
2258f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    ++mRTPSeqNo;
2268f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2278f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    uint32_t rtpTime = (timeUs * 9) / 100ll;
2288f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2298f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[4] = rtpTime >> 24;
2308f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[5] = (rtpTime >> 16) & 0xff;
2318f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[6] = (rtpTime >> 8) & 0xff;
2328f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[7] = rtpTime & 0xff;
2338f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2348f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[8] = kSourceID >> 24;
2358f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[9] = (kSourceID >> 16) & 0xff;
2368f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[10] = (kSourceID >> 8) & 0xff;
2378f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    rtp[11] = kSourceID & 0xff;
2388f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2398f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    memcpy(&rtp[12], packet->data(), packet->size());
2408f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
2418f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber    return sendRTPPacket(
2428f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber            udpPacket,
2438f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber            true /* storeInHistory */,
2448f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber            true /* timeValid */,
2454eac4e624f6930966d208d8e1ee99eefee077b50Andreas Huber            ALooper::GetNowUs());
2468f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber}
2478f1f6a4814403dd78539250c845f8326f6137a61Andreas Huber
248a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t RTPSender::queueTSPackets(
249a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const sp<ABuffer> &tsPackets, uint8_t packetType) {
250a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK_EQ(0, tsPackets->size() % 188);
251a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
252a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber    int64_t timeUs;
253a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber    CHECK(tsPackets->meta()->findInt64("timeUs", &timeUs));
254a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber
255a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    const size_t numTSPackets = tsPackets->size() / 188;
256a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
257a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    size_t srcOffset = 0;
258a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    while (srcOffset < tsPackets->size()) {
259a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        sp<ABuffer> udpPacket =
260a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
261a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
262a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        udpPacket->setInt32Data(mRTPSeqNo);
263a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
264a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        uint8_t *rtp = udpPacket->data();
265a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[0] = 0x80;
266a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[1] = packetType;
267a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
268a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
269a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[3] = mRTPSeqNo & 0xff;
270a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        ++mRTPSeqNo;
271a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
272a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        int64_t nowUs = ALooper::GetNowUs();
273a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        uint32_t rtpTime = (nowUs * 9) / 100ll;
274a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
275a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[4] = rtpTime >> 24;
276a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[5] = (rtpTime >> 16) & 0xff;
277a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[6] = (rtpTime >> 8) & 0xff;
278a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[7] = rtpTime & 0xff;
279a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
280a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[8] = kSourceID >> 24;
281a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[9] = (kSourceID >> 16) & 0xff;
282a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[10] = (kSourceID >> 8) & 0xff;
283a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        rtp[11] = kSourceID & 0xff;
284a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
285a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size_t numTSPackets = (tsPackets->size() - srcOffset) / 188;
286a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (numTSPackets > kMaxNumTSPacketsPerRTPPacket) {
287a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            numTSPackets = kMaxNumTSPacketsPerRTPPacket;
288a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
289a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
290a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        memcpy(&rtp[12], tsPackets->data() + srcOffset, numTSPackets * 188);
291a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
292a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        udpPacket->setRange(0, 12 + numTSPackets * 188);
293a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber
294a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber        srcOffset += numTSPackets * 188;
295a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber        bool isLastPacket = (srcOffset == tsPackets->size());
296a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber
297a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber        status_t err = sendRTPPacket(
298a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber                udpPacket,
299a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber                true /* storeInHistory */,
300a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber                isLastPacket /* timeValid */,
301a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber                timeUs);
302a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
303a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (err != OK) {
304a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            return err;
305a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
306a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
307a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
308a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
309a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
310a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
311a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t RTPSender::queueAVCBuffer(
312a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const sp<ABuffer> &accessUnit, uint8_t packetType) {
313a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    int64_t timeUs;
314a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
315a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
316a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint32_t rtpTime = (timeUs * 9 / 100ll);
317a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
318a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    List<sp<ABuffer> > packets;
319a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
320a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<ABuffer> out = new ABuffer(kMaxUDPPacketSize);
321a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    size_t outBytesUsed = 12;  // Placeholder for RTP header.
322a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
323a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    const uint8_t *data = accessUnit->data();
324a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    size_t size = accessUnit->size();
325a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    const uint8_t *nalStart;
326a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    size_t nalSize;
327a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    while (getNextNALUnit(
328a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                &data, &size, &nalStart, &nalSize,
329a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                true /* startCodeFollows */) == OK) {
330a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size_t bytesNeeded = nalSize + 2;
331a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (outBytesUsed == 12) {
332a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ++bytesNeeded;
333a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
334a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
335a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (outBytesUsed + bytesNeeded > out->capacity()) {
336a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            bool emitSingleNALPacket = false;
337a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
338a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (outBytesUsed == 12
339a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    && outBytesUsed + nalSize <= out->capacity()) {
340a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                // We haven't emitted anything into the current packet yet and
341a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                // this NAL unit fits into a single-NAL-unit-packet while
342a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                // it wouldn't have fit as part of a STAP-A packet.
343a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
344a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                memcpy(out->data() + outBytesUsed, nalStart, nalSize);
345a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                outBytesUsed += nalSize;
346a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
347a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                emitSingleNALPacket = true;
348a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
349a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
350a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (outBytesUsed > 12) {
351a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                out->setRange(0, outBytesUsed);
352a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                packets.push_back(out);
353a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                out = new ABuffer(kMaxUDPPacketSize);
354a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                outBytesUsed = 12;  // Placeholder for RTP header
355a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
356a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
357a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (emitSingleNALPacket) {
358a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                continue;
359a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
360a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
361a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
362a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (outBytesUsed + bytesNeeded <= out->capacity()) {
363a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            uint8_t *dst = out->data() + outBytesUsed;
364a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
365a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (outBytesUsed == 12) {
366a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                *dst++ = 24;  // STAP-A header
367a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
368a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
369a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            *dst++ = (nalSize >> 8) & 0xff;
370a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            *dst++ = nalSize & 0xff;
371a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            memcpy(dst, nalStart, nalSize);
372a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
373a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            outBytesUsed += bytesNeeded;
374a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            continue;
375a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
376a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
377a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        // This single NAL unit does not fit into a single RTP packet,
378a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        // we need to emit an FU-A.
379a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
380a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        CHECK_EQ(outBytesUsed, 12u);
381a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
382a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        uint8_t nalType = nalStart[0] & 0x1f;
383a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        uint8_t nri = (nalStart[0] >> 5) & 3;
384a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
385a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size_t srcOffset = 1;
386a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        while (srcOffset < nalSize) {
387a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            size_t copy = out->capacity() - outBytesUsed - 2;
388a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (copy > nalSize - srcOffset) {
389a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                copy = nalSize - srcOffset;
390a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
391a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
392a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            uint8_t *dst = out->data() + outBytesUsed;
393a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            dst[0] = (nri << 5) | 28;
394a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
395a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            dst[1] = nalType;
396a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
397a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (srcOffset == 1) {
398a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                dst[1] |= 0x80;
399a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
400a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
401a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (srcOffset + copy == nalSize) {
402a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                dst[1] |= 0x40;
403a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
404a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
405a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            memcpy(&dst[2], nalStart + srcOffset, copy);
406a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            srcOffset += copy;
407a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
408a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            out->setRange(0, outBytesUsed + copy + 2);
409a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
410a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            packets.push_back(out);
411a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            out = new ABuffer(kMaxUDPPacketSize);
412a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            outBytesUsed = 12;  // Placeholder for RTP header
413a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
414a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
415a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
416a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (outBytesUsed > 12) {
417a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        out->setRange(0, outBytesUsed);
418a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        packets.push_back(out);
419a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
420a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
421a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    while (!packets.empty()) {
422a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        sp<ABuffer> out = *packets.begin();
423a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        packets.erase(packets.begin());
424a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
425a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        out->setInt32Data(mRTPSeqNo);
426a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
427a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        bool last = packets.empty();
428a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
429a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        uint8_t *dst = out->data();
430a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
431a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[0] = 0x80;
432a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
433a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[1] = packetType;
434a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (last) {
435a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            dst[1] |= 1 << 7;  // M-bit
436a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
437a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
438a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[2] = (mRTPSeqNo >> 8) & 0xff;
439a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[3] = mRTPSeqNo & 0xff;
440a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        ++mRTPSeqNo;
441a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
442a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[4] = rtpTime >> 24;
443a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[5] = (rtpTime >> 16) & 0xff;
444a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[6] = (rtpTime >> 8) & 0xff;
445a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[7] = rtpTime & 0xff;
446a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[8] = kSourceID >> 24;
447a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[9] = (kSourceID >> 16) & 0xff;
448a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[10] = (kSourceID >> 8) & 0xff;
449a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        dst[11] = kSourceID & 0xff;
450a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
451a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        status_t err = sendRTPPacket(out, true /* storeInHistory */);
452a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
453a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (err != OK) {
454a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            return err;
455a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
456a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
457a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
458a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
459a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
460a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
461a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t RTPSender::sendRTPPacket(
462a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber        const sp<ABuffer> &buffer, bool storeInHistory,
463a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber        bool timeValid, int64_t timeUs) {
464a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK(mRTPConnected);
465a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
466a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    status_t err = mNetSession->sendRequest(
467a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber            mRTPSessionID, buffer->data(), buffer->size(),
468a239dd722e760fe4fd7379b454d7722e1f312928Andreas Huber            timeValid, timeUs);
469a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
470a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (err != OK) {
471a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return err;
472a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
473a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
474a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mLastNTPTime = GetNowNTP();
475a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mLastRTPTime = U32_AT(buffer->data() + 4);
476a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
477a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    ++mNumRTPSent;
478a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mNumRTPOctetsSent += buffer->size() - 12;
479a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
480a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (storeInHistory) {
481a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (mHistorySize == kMaxHistorySize) {
482a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            mHistory.erase(mHistory.begin());
483a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        } else {
484a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ++mHistorySize;
485a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
486a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mHistory.push_back(buffer);
487a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
488a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
489a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
490a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
491a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
492a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber// static
493a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberuint64_t RTPSender::GetNowNTP() {
494a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    struct timeval tv;
495a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    gettimeofday(&tv, NULL /* timezone */);
496a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
497a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint64_t nowUs = tv.tv_sec * 1000000ll + tv.tv_usec;
498a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
499a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
500a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
501a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint64_t hi = nowUs / 1000000ll;
502a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
503a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
504a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return (hi << 32) | lo;
505a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
506a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
507a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid RTPSender::onMessageReceived(const sp<AMessage> &msg) {
508a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    switch (msg->what()) {
509a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case kWhatRTPNotify:
510a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case kWhatRTCPNotify:
511a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            onNetNotify(msg->what() == kWhatRTPNotify, msg);
512a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
513a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
514a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        default:
515a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            TRESPASS();
516a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
517a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
518a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
519a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid RTPSender::onNetNotify(bool isRTP, const sp<AMessage> &msg) {
520a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    int32_t reason;
521a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK(msg->findInt32("reason", &reason));
522a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
523a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    switch (reason) {
524a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case ANetworkSession::kWhatError:
525a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        {
526a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            int32_t sessionID;
527a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findInt32("sessionID", &sessionID));
528a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
529a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            int32_t err;
530a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findInt32("err", &err));
531a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
532a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            int32_t errorOccuredDuringSend;
533a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findInt32("send", &errorOccuredDuringSend));
534a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
535a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            AString detail;
536a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findString("detail", &detail));
537a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
538a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ALOGE("An error occurred during %s in session %d "
539a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  "(%d, '%s' (%s)).",
540a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  errorOccuredDuringSend ? "send" : "receive",
541a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  sessionID,
542a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  err,
543a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  detail.c_str(),
544a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  strerror(-err));
545a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
546a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            mNetSession->destroySession(sessionID);
547a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
548a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (sessionID == mRTPSessionID) {
549a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                mRTPSessionID = 0;
550a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            } else if (sessionID == mRTCPSessionID) {
551a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                mRTCPSessionID = 0;
552a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
553a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
5546e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber            if (!mRTPConnected
5556e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber                    || (mRTPMode != TRANSPORT_NONE && !mRTCPConnected)) {
5566e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber                // We haven't completed initialization, attach the error
5576e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber                // to the notification instead.
5586e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber                notifyInitDone(err);
5596e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber                break;
560a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
561a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
562a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            notifyError(err);
563a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
564a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
565a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
566a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case ANetworkSession::kWhatDatagram:
567a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        {
568a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            sp<ABuffer> data;
569a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findBuffer("data", &data));
570a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
571a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (isRTP) {
572a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                ALOGW("Huh? Received data on RTP connection...");
573a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            } else {
574a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                onRTCPData(data);
575a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
576a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
577a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
578a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
579a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case ANetworkSession::kWhatConnected:
580a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        {
581a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            int32_t sessionID;
582a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findInt32("sessionID", &sessionID));
583a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
584a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if  (isRTP) {
5856e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber                CHECK_EQ(mRTPMode, TRANSPORT_TCP);
586a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                CHECK_EQ(sessionID, mRTPSessionID);
587a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                mRTPConnected = true;
588a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            } else {
5896e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber                CHECK_EQ(mRTCPMode, TRANSPORT_TCP);
590a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                CHECK_EQ(sessionID, mRTCPSessionID);
591a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                mRTCPConnected = true;
592a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
593a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
5946e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber            if (mRTPConnected
5956e98aba4d23d00cab236d993d895f57ea76ea0e5Andreas Huber                    && (mRTCPMode == TRANSPORT_NONE || mRTCPConnected)) {
596a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                notifyInitDone(OK);
597a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
598a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
599a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
600126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
601126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber        case ANetworkSession::kWhatNetworkStall:
602126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber        {
603126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            size_t numBytesQueued;
604126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            CHECK(msg->findSize("numBytesQueued", &numBytesQueued));
605126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
606126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            notifyNetworkStall(numBytesQueued);
607126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            break;
608126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber        }
609126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
610126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber        default:
611126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            TRESPASS();
612a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
613a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
614a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
615a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t RTPSender::onRTCPData(const sp<ABuffer> &buffer) {
616a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    const uint8_t *data = buffer->data();
617a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    size_t size = buffer->size();
618a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
619a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    while (size > 0) {
620a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (size < 8) {
621a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            // Too short to be a valid RTCP header
622a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            return ERROR_MALFORMED;
623a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
624a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
625a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if ((data[0] >> 6) != 2) {
626a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            // Unsupported version.
627a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            return ERROR_UNSUPPORTED;
628a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
629a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
630a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (data[0] & 0x20) {
631a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            // Padding present.
632a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
633a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            size_t paddingLength = data[size - 1];
634a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
635a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (paddingLength + 12 > size) {
636a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                // If we removed this much padding we'd end up with something
637a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                // that's too short to be a valid RTP header.
638a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                return ERROR_MALFORMED;
639a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
640a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
641a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            size -= paddingLength;
642a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
643a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
644a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
645a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
646a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (size < headerLength) {
647a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            // Only received a partial packet?
648a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            return ERROR_MALFORMED;
649a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
650a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
651a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        switch (data[1]) {
652a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            case 200:
653a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            case 201:  // RR
654a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                parseReceiverReport(data, headerLength);
655a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                break;
656a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
657a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            case 202:  // SDES
658a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            case 203:
659d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber                break;
660d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
661a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            case 204:  // APP
6622aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber                parseAPP(data, headerLength);
663a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                break;
664a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
665a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            case 205:  // TSFB (transport layer specific feedback)
666a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                parseTSFB(data, headerLength);
667a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                break;
668a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
669a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            case 206:  // PSFB (payload specific feedback)
670a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                // hexdump(data, headerLength);
671a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                break;
672a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
673a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            default:
674a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            {
675a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                ALOGW("Unknown RTCP packet type %u of size %d",
676a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                     (unsigned)data[1], headerLength);
677a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                break;
678a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
679a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
680a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
681a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        data += headerLength;
682a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size -= headerLength;
683a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
684a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
685a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
686a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
687a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
688a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t RTPSender::parseReceiverReport(const uint8_t *data, size_t size) {
689a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    // hexdump(data, size);
690a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
691a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    float fractionLost = data[12] / 256.0f;
692a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
693a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    ALOGI("lost %.2f %% of packets during report interval.",
694a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber          100.0f * fractionLost);
695a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
696a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
697a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
698a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
699a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t RTPSender::parseTSFB(const uint8_t *data, size_t size) {
700a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if ((data[0] & 0x1f) != 1) {
701a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return ERROR_UNSUPPORTED;  // We only support NACK for now.
702a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
703a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
704a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint32_t srcId = U32_AT(&data[8]);
705a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (srcId != kSourceID) {
706a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return ERROR_MALFORMED;
707a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
708a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
709a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    for (size_t i = 12; i < size; i += 4) {
710a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        uint16_t seqNo = U16_AT(&data[i]);
711a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        uint16_t blp = U16_AT(&data[i + 2]);
712a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
713a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        List<sp<ABuffer> >::iterator it = mHistory.begin();
714a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        bool foundSeqNo = false;
715a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        while (it != mHistory.end()) {
716a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            const sp<ABuffer> &buffer = *it;
717a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
718a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
719a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
720a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            bool retransmit = false;
721a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (bufferSeqNo == seqNo) {
722a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                retransmit = true;
723a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            } else if (blp != 0) {
724a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                for (size_t i = 0; i < 16; ++i) {
725a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    if ((blp & (1 << i))
726a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
727a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        blp &= ~(1 << i);
728a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        retransmit = true;
729a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    }
730a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
731a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
732a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
733a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (retransmit) {
734a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                ALOGV("retransmitting seqNo %d", bufferSeqNo);
735a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
736a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                CHECK_EQ((status_t)OK,
737a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                         sendRTPPacket(buffer, false /* storeInHistory */));
738a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
739a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                if (bufferSeqNo == seqNo) {
740a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    foundSeqNo = true;
741a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
742a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
743a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                if (foundSeqNo && blp == 0) {
744a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    break;
745a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
746a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
747a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
748a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ++it;
749a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
750a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
751a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (!foundSeqNo || blp != 0) {
752a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ALOGI("Some sequence numbers were no longer available for "
753a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  "retransmission (seqNo = %d, foundSeqNo = %d, blp = 0x%04x)",
754a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  seqNo, foundSeqNo, blp);
755a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
756a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (!mHistory.empty()) {
757a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                int32_t earliest = (*mHistory.begin())->int32Data() & 0xffff;
758a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                int32_t latest = (*--mHistory.end())->int32Data() & 0xffff;
759a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
760a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                ALOGI("have seq numbers from %d - %d", earliest, latest);
761a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
762a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
763a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
764a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
765a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
766a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
767a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
7682aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huberstatus_t RTPSender::parseAPP(const uint8_t *data, size_t size) {
769c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    if (!memcmp("late", &data[8], 4)) {
770c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        int64_t avgLatencyUs = (int64_t)U64_AT(&data[12]);
771c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        int64_t maxLatencyUs = (int64_t)U64_AT(&data[20]);
772c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
773c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        sp<AMessage> notify = mNotify->dup();
774c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        notify->setInt32("what", kWhatInformSender);
775c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        notify->setInt64("avgLatencyUs", avgLatencyUs);
776c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        notify->setInt64("maxLatencyUs", maxLatencyUs);
777c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        notify->post();
778c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    }
779c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
7802aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber    return OK;
7812aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber}
7822aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber
783a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid RTPSender::notifyInitDone(status_t err) {
784a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<AMessage> notify = mNotify->dup();
785a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("what", kWhatInitDone);
786a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("err", err);
787a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->post();
788a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
789a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
790a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid RTPSender::notifyError(status_t err) {
791a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<AMessage> notify = mNotify->dup();
792a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("what", kWhatError);
793a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("err", err);
794a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->post();
795a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
796a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
797126568c7aeeb5570789e70a310477f44dbdbd885Andreas Hubervoid RTPSender::notifyNetworkStall(size_t numBytesQueued) {
798126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber    sp<AMessage> notify = mNotify->dup();
799126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber    notify->setInt32("what", kWhatNetworkStall);
800126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber    notify->setSize("numBytesQueued", numBytesQueued);
801126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber    notify->post();
802126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber}
803126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
804a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}  // namespace android
805a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
806