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> ¬ify) 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