Sender.cpp revision 90a92053219ae50ddf4bb54e3d54db2d309e2b8d
190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber/*
290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * Copyright 2012, The Android Open Source Project
390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *
490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * you may not use this file except in compliance with the License.
690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * You may obtain a copy of the License at
790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *
890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *
1090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * Unless required by applicable law or agreed to in writing, software
1190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * See the License for the specific language governing permissions and
1490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber * limitations under the License.
1590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber */
1690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
1790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber//#define LOG_NDEBUG 0
1890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#define LOG_TAG "Sender"
1990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <utils/Log.h>
2090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
2190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include "Sender.h"
2290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
2390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include "ANetworkSession.h"
2490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
2590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
2690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <media/stagefright/foundation/ADebug.h>
2790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <media/stagefright/foundation/AMessage.h>
2890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <media/stagefright/foundation/hexdump.h>
2990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <media/stagefright/MediaErrors.h>
3090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <media/stagefright/Utils.h>
3190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
3290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include <math.h>
3390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
3490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#define DEBUG_JITTER    0
3590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
3690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubernamespace android {
3790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
3890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber////////////////////////////////////////////////////////////////////////////////
3990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
4090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if DEBUG_JITTER
4190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberstruct TimeSeries {
4290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    TimeSeries();
4390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
4490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    void add(double val);
4590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
4690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    double mean() const;
4790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    double sdev() const;
4890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
4990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberprivate:
5090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    enum {
5190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        kHistorySize = 20
5290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    };
5390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    double mValues[kHistorySize];
5490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
5590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t mCount;
5690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    double mSum;
5790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber};
5890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
5990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas HuberTimeSeries::TimeSeries()
6090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    : mCount(0),
6190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mSum(0.0) {
6290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
6390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
6490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid TimeSeries::add(double val) {
6590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mCount < kHistorySize) {
6690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mValues[mCount++] = val;
6790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mSum += val;
6890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    } else {
6990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mSum -= mValues[0];
7090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        memmove(&mValues[0], &mValues[1], (kHistorySize - 1) * sizeof(double));
7190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mValues[kHistorySize - 1] = val;
7290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mSum += val;
7390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
7490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
7590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
7690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberdouble TimeSeries::mean() const {
7790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mCount < 1) {
7890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return 0.0;
7990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
8090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
8190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return mSum / mCount;
8290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
8390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
8490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberdouble TimeSeries::sdev() const {
8590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mCount < 1) {
8690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return 0.0;
8790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
8890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
8990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    double m = mean();
9090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
9190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    double sum = 0.0;
9290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    for (size_t i = 0; i < mCount; ++i) {
9390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        double tmp = mValues[i] - m;
9490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        tmp *= tmp;
9590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
9690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        sum += tmp;
9790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
9890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
9990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return sqrt(sum / mCount);
10090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
10190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif  // DEBUG_JITTER
10290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
10390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber////////////////////////////////////////////////////////////////////////////////
10490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
10590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberstatic size_t kMaxRTPPacketSize = 1500;
10690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberstatic size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188;
10790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
10890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas HuberSender::Sender(
10990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const sp<ANetworkSession> &netSession,
11090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const sp<AMessage> &notify)
11190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    : mNetSession(netSession),
11290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mNotify(notify),
11390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
11490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mTransportMode(TRANSPORT_UDP),
11590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTPChannel(0),
11690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTCPChannel(0),
11790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTPPort(0),
11890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTPSessionID(0),
11990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTCPSessionID(0),
12090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
12190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTPRetransmissionSessionID(0),
12290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTCPRetransmissionSessionID(0),
12390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
12490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mClientRTPPort(0),
12590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mClientRTCPPort(0),
12690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTPConnected(false),
12790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTCPConnected(false),
12890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mFirstOutputBufferReadyTimeUs(-1ll),
12990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mFirstOutputBufferSentTimeUs(-1ll),
13090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTPSeqNo(0),
13190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
13290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mRTPRetransmissionSeqNo(0),
13390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
13490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mLastNTPTime(0),
13590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mLastRTPTime(0),
13690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mNumRTPSent(0),
13790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mNumRTPOctetsSent(0),
13890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mNumSRsSent(0),
13990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mSendSRPending(false)
14090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
14190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      ,mHistoryLength(0)
14290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
14390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if TRACK_BANDWIDTH
14490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      ,mFirstPacketTimeUs(-1ll)
14590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      ,mTotalBytesSent(0ll)
14690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
14790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if LOG_TRANSPORT_STREAM
14890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    ,mLogFile(NULL)
14990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
15090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber{
15190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mTSQueue->setRange(0, 12);
15290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
15390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if LOG_TRANSPORT_STREAM
15490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mLogFile = fopen("/system/etc/log.ts", "wb");
15590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
15690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
15790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
15890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas HuberSender::~Sender() {
15990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
16090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mRTCPRetransmissionSessionID != 0) {
16190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mNetSession->destroySession(mRTCPRetransmissionSessionID);
16290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
16390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
16490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mRTPRetransmissionSessionID != 0) {
16590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mNetSession->destroySession(mRTPRetransmissionSessionID);
16690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
16790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
16890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
16990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mRTCPSessionID != 0) {
17090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mNetSession->destroySession(mRTCPSessionID);
17190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
17290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
17390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mRTPSessionID != 0) {
17490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mNetSession->destroySession(mRTPSessionID);
17590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
17690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
17790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if LOG_TRANSPORT_STREAM
17890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mLogFile != NULL) {
17990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        fclose(mLogFile);
18090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mLogFile = NULL;
18190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
18290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
18390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
18490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
18590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberstatus_t Sender::init(
18690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
18790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        TransportMode transportMode) {
18890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mClientIP = clientIP;
18990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mTransportMode = transportMode;
19090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
19190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (transportMode == TRANSPORT_TCP_INTERLEAVED) {
19290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTPChannel = clientRtp;
19390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTCPChannel = clientRtcp;
19490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTPPort = 0;
19590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTPSessionID = 0;
19690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTCPSessionID = 0;
19790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return OK;
19890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
19990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
20090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mRTPChannel = 0;
20190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mRTCPChannel = 0;
20290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
20390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mTransportMode == TRANSPORT_TCP) {
20490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // XXX This is wrong, we need to allocate sockets here, we only
20590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // need to do this because the dongles are not establishing their
20690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // end until after PLAY instead of before SETUP.
20790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTPPort = 20000;
20890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTPSessionID = 0;
20990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTCPSessionID = 0;
21090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mClientRTPPort = clientRtp;
21190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mClientRTCPPort = clientRtcp;
21290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return OK;
21390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
21490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
21590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int serverRtp;
21690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
21790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
21890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
21990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
22090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
22190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> rtpRetransmissionNotify =
22290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        new AMessage(kWhatRTPRetransmissionNotify, id());
22390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
22490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> rtcpRetransmissionNotify =
22590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        new AMessage(kWhatRTCPRetransmissionNotify, id());
22690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
22790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
22890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    status_t err;
22990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    for (serverRtp = 15550;; serverRtp += 2) {
23090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int32_t rtpSession;
23190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (mTransportMode == TRANSPORT_UDP) {
23290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            err = mNetSession->createUDPSession(
23390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        serverRtp, clientIP, clientRtp,
23490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        rtpNotify, &rtpSession);
23590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        } else {
23690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            err = mNetSession->createTCPDatagramSession(
23790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        serverRtp, clientIP, clientRtp,
23890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        rtpNotify, &rtpSession);
23990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
24090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
24190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (err != OK) {
24290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            ALOGI("failed to create RTP socket on port %d", serverRtp);
24390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            continue;
24490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
24590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
24690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int32_t rtcpSession = 0;
24790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
24890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (clientRtcp >= 0) {
24990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (mTransportMode == TRANSPORT_UDP) {
25090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                err = mNetSession->createUDPSession(
25190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        serverRtp + 1, clientIP, clientRtcp,
25290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        rtcpNotify, &rtcpSession);
25390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            } else {
25490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                err = mNetSession->createTCPDatagramSession(
25590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        serverRtp + 1, clientIP, clientRtcp,
25690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        rtcpNotify, &rtcpSession);
25790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
25890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
25990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (err != OK) {
26090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                ALOGI("failed to create RTCP socket on port %d", serverRtp + 1);
26190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
26290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mNetSession->destroySession(rtpSession);
26390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                continue;
26490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
26590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
26690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
26790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
26890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (mTransportMode == TRANSPORT_UDP) {
26990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            int32_t rtpRetransmissionSession;
27090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
27190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            err = mNetSession->createUDPSession(
27290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        serverRtp + kRetransmissionPortOffset,
27390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        clientIP,
27490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        clientRtp + kRetransmissionPortOffset,
27590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        rtpRetransmissionNotify,
27690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        &rtpRetransmissionSession);
27790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
27890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (err != OK) {
27990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mNetSession->destroySession(rtcpSession);
28090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mNetSession->destroySession(rtpSession);
28190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                continue;
28290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
28390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
28490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            CHECK_GE(clientRtcp, 0);
28590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
28690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            int32_t rtcpRetransmissionSession;
28790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            err = mNetSession->createUDPSession(
28890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        serverRtp + 1 + kRetransmissionPortOffset,
28990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        clientIP,
29090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        clientRtp + 1 + kRetransmissionPortOffset,
29190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        rtcpRetransmissionNotify,
29290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        &rtcpRetransmissionSession);
29390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
29490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (err != OK) {
29590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mNetSession->destroySession(rtpRetransmissionSession);
29690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mNetSession->destroySession(rtcpSession);
29790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mNetSession->destroySession(rtpSession);
29890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                continue;
29990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
30090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mRTPRetransmissionSessionID = rtpRetransmissionSession;
30290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mRTCPRetransmissionSessionID = rtcpRetransmissionSession;
30390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            ALOGI("rtpRetransmissionSessionID = %d, "
30590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                  "rtcpRetransmissionSessionID = %d",
30690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                  rtpRetransmissionSession, rtcpRetransmissionSession);
30790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
30890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
30990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
31090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTPPort = serverRtp;
31190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTPSessionID = rtpSession;
31290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mRTCPSessionID = rtcpSession;
31390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
31490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession);
31590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        break;
31690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
31790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
31890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mRTPPort == 0) {
31990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return UNKNOWN_ERROR;
32090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
32190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
32290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return OK;
32390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
32490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
32590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberstatus_t Sender::finishInit() {
32690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mTransportMode != TRANSPORT_TCP) {
32790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        notifyInitDone();
32890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return OK;
32990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
33090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
33190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
33290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
33390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    status_t err = mNetSession->createTCPDatagramSession(
33490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mRTPPort, mClientIP.c_str(), mClientRTPPort,
33590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                rtpNotify, &mRTPSessionID);
33690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
33790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (err != OK) {
33890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return err;
33990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
34090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
34190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mClientRTCPPort >= 0) {
34290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
34390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
34490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        err = mNetSession->createTCPDatagramSession(
34590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort,
34690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                rtcpNotify, &mRTCPSessionID);
34790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
34890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (err != OK) {
34990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            return err;
35090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
35190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
35290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
35390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return OK;
35490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
35590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
35690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberint32_t Sender::getRTPPort() const {
35790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return mRTPPort;
35890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
35990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
36090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::queuePackets(
36190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int64_t timeUs, const sp<ABuffer> &packets) {
36290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bool isVideo = false;
36390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
36490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int32_t dummy;
36590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (packets->meta()->findInt32("isVideo", &dummy)) {
36690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        isVideo = true;
36790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
36890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
36990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t delayUs;
37090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t whenUs;
37190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
37290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mFirstOutputBufferReadyTimeUs < 0ll) {
37390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mFirstOutputBufferReadyTimeUs = timeUs;
37490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mFirstOutputBufferSentTimeUs = whenUs = ALooper::GetNowUs();
37590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        delayUs = 0ll;
37690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    } else {
37790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int64_t nowUs = ALooper::GetNowUs();
37890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
37990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        whenUs = (timeUs - mFirstOutputBufferReadyTimeUs)
38090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                + mFirstOutputBufferSentTimeUs;
38190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
38290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        delayUs = whenUs - nowUs;
38390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
38490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
38590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatQueuePackets, id());
38690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    msg->setBuffer("packets", packets);
38790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
38890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    packets->meta()->setInt64("timeUs", timeUs);
38990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    packets->meta()->setInt64("whenUs", whenUs);
39090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    packets->meta()->setInt64("delayUs", delayUs);
39190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    msg->post(delayUs > 0 ? delayUs : 0);
39290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
39390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
39490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::onMessageReceived(const sp<AMessage> &msg) {
39590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    switch (msg->what()) {
39690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case kWhatRTPNotify:
39790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case kWhatRTCPNotify:
39890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
39990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case kWhatRTPRetransmissionNotify:
40090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case kWhatRTCPRetransmissionNotify:
40190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
40290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        {
40390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            int32_t reason;
40490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            CHECK(msg->findInt32("reason", &reason));
40590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
40690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            switch (reason) {
40790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                case ANetworkSession::kWhatError:
40890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                {
40990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    int32_t sessionID;
41090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
41190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
41290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    int32_t err;
41390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    CHECK(msg->findInt32("err", &err));
41490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
41590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    int32_t errorOccuredDuringSend;
41690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    CHECK(msg->findInt32("send", &errorOccuredDuringSend));
41790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
41890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    AString detail;
41990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    CHECK(msg->findString("detail", &detail));
42090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
42190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    if ((msg->what() == kWhatRTPNotify
42290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
42390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                            || msg->what() == kWhatRTPRetransmissionNotify
42490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
42590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        ) && !errorOccuredDuringSend) {
42690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        // This is ok, we don't expect to receive anything on
42790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        // the RTP socket.
42890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        break;
42990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    }
43090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
43190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    ALOGE("An error occurred during %s in session %d "
43290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                          "(%d, '%s' (%s)).",
43390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                          errorOccuredDuringSend ? "send" : "receive",
43490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                          sessionID,
43590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                          err,
43690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                          detail.c_str(),
43790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                          strerror(-err));
43890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
43990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    mNetSession->destroySession(sessionID);
44090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
44190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    if (sessionID == mRTPSessionID) {
44290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        mRTPSessionID = 0;
44390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    } else if (sessionID == mRTCPSessionID) {
44490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        mRTCPSessionID = 0;
44590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    }
44690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
44790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    else if (sessionID == mRTPRetransmissionSessionID) {
44890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        mRTPRetransmissionSessionID = 0;
44990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    } else if (sessionID == mRTCPRetransmissionSessionID) {
45090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        mRTCPRetransmissionSessionID = 0;
45190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    }
45290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
45390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
45490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    notifySessionDead();
45590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    break;
45690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                }
45790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
45890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                case ANetworkSession::kWhatDatagram:
45990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                {
46090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    int32_t sessionID;
46190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
46290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
46390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    sp<ABuffer> data;
46490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    CHECK(msg->findBuffer("data", &data));
46590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
46690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    status_t err;
46790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    if (msg->what() == kWhatRTCPNotify
46890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
46990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                            || msg->what() == kWhatRTCPRetransmissionNotify
47090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
47190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                       )
47290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    {
47390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        err = parseRTCP(data);
47490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    }
47590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    break;
47690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                }
47790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
47890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                case ANetworkSession::kWhatConnected:
47990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                {
48090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    CHECK_EQ(mTransportMode, TRANSPORT_TCP);
48190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
48290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    int32_t sessionID;
48390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
48490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
48590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    if (sessionID == mRTPSessionID) {
48690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        CHECK(!mRTPConnected);
48790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        mRTPConnected = true;
48890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        ALOGI("RTP Session now connected.");
48990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    } else if (sessionID == mRTCPSessionID) {
49090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        CHECK(!mRTCPConnected);
49190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        mRTCPConnected = true;
49290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        ALOGI("RTCP Session now connected.");
49390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    } else {
49490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        TRESPASS();
49590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    }
49690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
49790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    if (mRTPConnected
49890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                            && (mClientRTCPPort < 0 || mRTCPConnected)) {
49990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        notifyInitDone();
50090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    }
50190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    break;
50290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                }
50390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
50490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                default:
50590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    TRESPASS();
50690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
50790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            break;
50890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
50990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
51090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case kWhatQueuePackets:
51190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        {
51290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            sp<ABuffer> packets;
51390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            CHECK(msg->findBuffer("packets", &packets));
51490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
51590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            onQueuePackets(packets);
51690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            break;
51790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
51890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
51990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case kWhatSendSR:
52090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        {
52190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mSendSRPending = false;
52290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
52390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (mRTCPSessionID == 0) {
52490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                break;
52590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
52690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
52790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            onSendSR();
52890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
52990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            scheduleSendSR();
53090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            break;
53190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
53290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
53390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
53490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
53590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::onQueuePackets(const sp<ABuffer> &packets) {
53690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if DEBUG_JITTER
53790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int32_t dummy;
53890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (packets->meta()->findInt32("isVideo", &dummy)) {
53990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        static int64_t lastTimeUs = 0ll;
54090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int64_t nowUs = ALooper::GetNowUs();
54190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
54290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        static TimeSeries series;
54390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        series.add((double)(nowUs - lastTimeUs));
54490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
54590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        ALOGI("deltaTimeUs = %lld us, mean %.2f, sdev %.2f",
54690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber              nowUs - lastTimeUs, series.mean(), series.sdev());
54790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
54890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        lastTimeUs = nowUs;
54990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
55090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
55190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
55290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t startTimeUs = ALooper::GetNowUs();
55390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
55490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    for (size_t offset = 0;
55590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            offset < packets->size(); offset += 188) {
55690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        bool lastTSPacket = (offset + 188 >= packets->size());
55790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
55890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        appendTSData(
55990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                packets->data() + offset,
56090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                188,
56190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                true /* timeDiscontinuity */,
56290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                lastTSPacket /* flush */);
56390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
56490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
56590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if 0
56690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t netTimeUs = ALooper::GetNowUs() - startTimeUs;
56790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
56890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t whenUs;
56990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK(packets->meta()->findInt64("whenUs", &whenUs));
57090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
57190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t delayUs;
57290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK(packets->meta()->findInt64("delayUs", &delayUs));
57390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
57490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bool isVideo = false;
57590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int32_t dummy;
57690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (packets->meta()->findInt32("isVideo", &dummy)) {
57790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        isVideo = true;
57890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
57990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
58090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t nowUs = ALooper::GetNowUs();
58190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
58290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (nowUs - whenUs > 2000) {
58390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        ALOGI("[%s] delayUs = %lld us, delta = %lld us",
58490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber              isVideo ? "video" : "audio", delayUs, nowUs - netTimeUs - whenUs);
58590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
58690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
58790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
58890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if LOG_TRANSPORT_STREAM
58990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mLogFile != NULL) {
59090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        fwrite(packets->data(), 1, packets->size(), mLogFile);
59190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
59290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
59390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
59490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
59590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberssize_t Sender::appendTSData(
59690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
59790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK_EQ(size, 188);
59890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
59990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
60090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
60190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
60290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mTSQueue->setRange(0, mTSQueue->size() + size);
60390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
60490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
60590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // flush
60690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
60790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int64_t nowUs = ALooper::GetNowUs();
60890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
60990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if TRACK_BANDWIDTH
61090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (mFirstPacketTimeUs < 0ll) {
61190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mFirstPacketTimeUs = nowUs;
61290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
61390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
61490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
61590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // 90kHz time scale
61690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        uint32_t rtpTime = (nowUs * 9ll) / 100ll;
61790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
61890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        uint8_t *rtp = mTSQueue->data();
61990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[0] = 0x80;
62090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
62190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
62290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[3] = mRTPSeqNo & 0xff;
62390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[4] = rtpTime >> 24;
62490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[5] = (rtpTime >> 16) & 0xff;
62590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[6] = (rtpTime >> 8) & 0xff;
62690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[7] = rtpTime & 0xff;
62790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[8] = kSourceID >> 24;
62890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[9] = (kSourceID >> 16) & 0xff;
62990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[10] = (kSourceID >> 8) & 0xff;
63090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        rtp[11] = kSourceID & 0xff;
63190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
63290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        ++mRTPSeqNo;
63390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        ++mNumRTPSent;
63490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mNumRTPOctetsSent += mTSQueue->size() - 12;
63590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
63690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mLastRTPTime = rtpTime;
63790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mLastNTPTime = GetNowNTP();
63890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
63990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
64090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            sp<AMessage> notify = mNotify->dup();
64190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            notify->setInt32("what", kWhatBinaryData);
64290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
64390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            sp<ABuffer> data = new ABuffer(mTSQueue->size());
64490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            memcpy(data->data(), rtp, mTSQueue->size());
64590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
64690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            notify->setInt32("channel", mRTPChannel);
64790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            notify->setBuffer("data", data);
64890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            notify->post();
64990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        } else {
65090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            sendPacket(mRTPSessionID, rtp, mTSQueue->size());
65190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
65290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if TRACK_BANDWIDTH
65390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mTotalBytesSent += mTSQueue->size();
65490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs;
65590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
65690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (delayUs > 0ll) {
65790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                ALOGI("approx. net bandwidth used: %.2f Mbit/sec",
65890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        mTotalBytesSent * 8.0 / delayUs);
65990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
66090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
66190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
66290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
66390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
66490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mTSQueue->setInt32Data(mRTPSeqNo - 1);
66590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
66690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mHistory.push_back(mTSQueue);
66790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        ++mHistoryLength;
66890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
66990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (mHistoryLength > kMaxHistoryLength) {
67090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mTSQueue = *mHistory.begin();
67190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mHistory.erase(mHistory.begin());
67290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
67390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            --mHistoryLength;
67490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        } else {
67590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
67690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
67790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
67890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
67990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        mTSQueue->setRange(0, 12);
68090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
68190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
68290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return size;
68390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
68490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
68590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::scheduleSendSR() {
68690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mSendSRPending || mRTCPSessionID == 0) {
68790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return;
68890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
68990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
69090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mSendSRPending = true;
69190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
69290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
69390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
69490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::addSR(const sp<ABuffer> &buffer) {
69590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    uint8_t *data = buffer->data() + buffer->size();
69690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
69790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    // TODO: Use macros/utility functions to clean up all the bitshifts below.
69890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
69990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[0] = 0x80 | 0;
70090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[1] = 200;  // SR
70190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[2] = 0;
70290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[3] = 6;
70390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[4] = kSourceID >> 24;
70490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[5] = (kSourceID >> 16) & 0xff;
70590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[6] = (kSourceID >> 8) & 0xff;
70690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[7] = kSourceID & 0xff;
70790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
70890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[8] = mLastNTPTime >> (64 - 8);
70990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
71090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
71190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[11] = (mLastNTPTime >> 32) & 0xff;
71290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[12] = (mLastNTPTime >> 24) & 0xff;
71390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[13] = (mLastNTPTime >> 16) & 0xff;
71490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[14] = (mLastNTPTime >> 8) & 0xff;
71590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[15] = mLastNTPTime & 0xff;
71690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
71790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[16] = (mLastRTPTime >> 24) & 0xff;
71890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[17] = (mLastRTPTime >> 16) & 0xff;
71990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[18] = (mLastRTPTime >> 8) & 0xff;
72090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[19] = mLastRTPTime & 0xff;
72190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
72290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[20] = mNumRTPSent >> 24;
72390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[21] = (mNumRTPSent >> 16) & 0xff;
72490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[22] = (mNumRTPSent >> 8) & 0xff;
72590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[23] = mNumRTPSent & 0xff;
72690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
72790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[24] = mNumRTPOctetsSent >> 24;
72890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
72990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
73090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[27] = mNumRTPOctetsSent & 0xff;
73190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
73290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 28);
73390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
73490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
73590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::addSDES(const sp<ABuffer> &buffer) {
73690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    uint8_t *data = buffer->data() + buffer->size();
73790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[0] = 0x80 | 1;
73890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[1] = 202;  // SDES
73990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[4] = kSourceID >> 24;
74090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[5] = (kSourceID >> 16) & 0xff;
74190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[6] = (kSourceID >> 8) & 0xff;
74290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[7] = kSourceID & 0xff;
74390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
74490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t offset = 8;
74590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
74690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[offset++] = 1;  // CNAME
74790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
74890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    static const char *kCNAME = "someone@somewhere";
74990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[offset++] = strlen(kCNAME);
75090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
75190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    memcpy(&data[offset], kCNAME, strlen(kCNAME));
75290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    offset += strlen(kCNAME);
75390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
75490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[offset++] = 7;  // NOTE
75590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
75690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    static const char *kNOTE = "Hell's frozen over.";
75790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[offset++] = strlen(kNOTE);
75890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
75990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    memcpy(&data[offset], kNOTE, strlen(kNOTE));
76090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    offset += strlen(kNOTE);
76190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
76290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[offset++] = 0;
76390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
76490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if ((offset % 4) > 0) {
76590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        size_t count = 4 - (offset % 4);
76690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        switch (count) {
76790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 3:
76890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                data[offset++] = 0;
76990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 2:
77090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                data[offset++] = 0;
77190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 1:
77290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                data[offset++] = 0;
77390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
77490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
77590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
77690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t numWords = (offset / 4) - 1;
77790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[2] = numWords >> 8;
77890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    data[3] = numWords & 0xff;
77990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
78090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    buffer->setRange(buffer->offset(), buffer->size() + offset);
78190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
78290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
78390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber// static
78490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberuint64_t Sender::GetNowNTP() {
78590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    uint64_t nowUs = ALooper::GetNowUs();
78690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
78790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
78890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
78990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    uint64_t hi = nowUs / 1000000ll;
79090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
79190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
79290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return (hi << 32) | lo;
79390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
79490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
79590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::onSendSR() {
79690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> buffer = new ABuffer(1500);
79790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    buffer->setRange(0, 0);
79890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
79990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    addSR(buffer);
80090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    addSDES(buffer);
80190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
80290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
80390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        sp<AMessage> notify = mNotify->dup();
80490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        notify->setInt32("what", kWhatBinaryData);
80590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        notify->setInt32("channel", mRTCPChannel);
80690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        notify->setBuffer("data", buffer);
80790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        notify->post();
80890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    } else {
80990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        sendPacket(mRTCPSessionID, buffer->data(), buffer->size());
81090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
81190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
81290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    ++mNumSRsSent;
81390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
81490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
81590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
81690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberstatus_t Sender::parseTSFB(
81790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const uint8_t *data, size_t size) {
81890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if ((data[0] & 0x1f) != 1) {
81990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return ERROR_UNSUPPORTED;  // We only support NACK for now.
82090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
82190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
82290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    uint32_t srcId = U32_AT(&data[8]);
82390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (srcId != kSourceID) {
82490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return ERROR_MALFORMED;
82590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
82690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
82790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    for (size_t i = 12; i < size; i += 4) {
82890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        uint16_t seqNo = U16_AT(&data[i]);
82990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        uint16_t blp = U16_AT(&data[i + 2]);
83090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
83190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        List<sp<ABuffer> >::iterator it = mHistory.begin();
83290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        bool foundSeqNo = false;
83390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        while (it != mHistory.end()) {
83490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            const sp<ABuffer> &buffer = *it;
83590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
83690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
83790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
83890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            bool retransmit = false;
83990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (bufferSeqNo == seqNo) {
84090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                retransmit = true;
84190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            } else if (blp != 0) {
84290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                for (size_t i = 0; i < 16; ++i) {
84390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    if ((blp & (1 << i))
84490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
84590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        blp &= ~(1 << i);
84690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        retransmit = true;
84790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    }
84890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                }
84990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
85090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
85190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (retransmit) {
85290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                ALOGI("retransmitting seqNo %d", bufferSeqNo);
85390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
85490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size());
85590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                uint8_t *rtp = retransRTP->data();
85690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                memcpy(rtp, buffer->data(), 12);
85790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff;
85890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                rtp[3] = mRTPRetransmissionSeqNo & 0xff;
85990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                rtp[12] = (bufferSeqNo >> 8) & 0xff;
86090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                rtp[13] = bufferSeqNo & 0xff;
86190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12);
86290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
86390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                ++mRTPRetransmissionSeqNo;
86490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
86590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                sendPacket(
86690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        mRTPRetransmissionSessionID,
86790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                        retransRTP->data(), retransRTP->size());
86890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
86990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                if (bufferSeqNo == seqNo) {
87090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    foundSeqNo = true;
87190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                }
87290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
87390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                if (foundSeqNo && blp == 0) {
87490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                    break;
87590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                }
87690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
87790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
87890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            ++it;
87990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
88090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
88190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (!foundSeqNo || blp != 0) {
88290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            ALOGI("Some sequence numbers were no longer available for "
88390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                  "retransmission");
88490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
88590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
88690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
88790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return OK;
88890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
88990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
89090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
89190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberstatus_t Sender::parseRTCP(
89290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const sp<ABuffer> &buffer) {
89390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    const uint8_t *data = buffer->data();
89490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t size = buffer->size();
89590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
89690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    while (size > 0) {
89790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (size < 8) {
89890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            // Too short to be a valid RTCP header
89990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            return ERROR_MALFORMED;
90090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
90190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
90290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if ((data[0] >> 6) != 2) {
90390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            // Unsupported version.
90490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            return ERROR_UNSUPPORTED;
90590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
90690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
90790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (data[0] & 0x20) {
90890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            // Padding present.
90990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
91090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            size_t paddingLength = data[size - 1];
91190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
91290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (paddingLength + 12 > size) {
91390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                // If we removed this much padding we'd end up with something
91490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                // that's too short to be a valid RTP header.
91590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                return ERROR_MALFORMED;
91690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
91790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
91890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            size -= paddingLength;
91990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
92090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
92190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
92290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
92390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (size < headerLength) {
92490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            // Only received a partial packet?
92590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            return ERROR_MALFORMED;
92690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
92790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
92890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        switch (data[1]) {
92990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 200:
93090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 201:  // RR
93190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 202:  // SDES
93290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 203:
93390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 204:  // APP
93490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                break;
93590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
93690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if ENABLE_RETRANSMISSION
93790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 205:  // TSFB (transport layer specific feedback)
93890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                parseTSFB(data, headerLength);
93990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                break;
94090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
94190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
94290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            case 206:  // PSFB (payload specific feedback)
94390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                hexdump(data, headerLength);
94490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                break;
94590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
94690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            default:
94790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            {
94890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                ALOGW("Unknown RTCP packet type %u of size %d",
94990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                     (unsigned)data[1], headerLength);
95090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                break;
95190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
95290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
95390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
95490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        data += headerLength;
95590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        size -= headerLength;
95690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
95790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
95890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return OK;
95990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
96090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
96190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberstatus_t Sender::sendPacket(
96290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int32_t sessionID, const void *data, size_t size) {
96390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return mNetSession->sendRequest(sessionID, data, size);
96490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
96590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
96690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::notifyInitDone() {
96790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> notify = mNotify->dup();
96890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    notify->setInt32("what", kWhatInitDone);
96990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    notify->post();
97090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
97190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
97290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid Sender::notifySessionDead() {
97390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> notify = mNotify->dup();
97490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    notify->setInt32("what", kWhatSessionDead);
97590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    notify->post();
97690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
97790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
97890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}  // namespace android
97990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
980