1761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman/* 2761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Copyright (C) 2011 The Android Open Source Project 3761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * 4761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Licensed under the Apache License, Version 2.0 (the "License"); 5761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * you may not use this file except in compliance with the License. 6761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * You may obtain a copy of the License at 7761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * 8761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * http://www.apache.org/licenses/LICENSE-2.0 9761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * 10761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * Unless required by applicable law or agreed to in writing, software 11761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * distributed under the License is distributed on an "AS IS" BASIS, 12761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * See the License for the specific language governing permissions and 14761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman * limitations under the License. 15761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman */ 16761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 17761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#ifndef __AAH_TX_SENDER_H__ 18761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#define __AAH_TX_SENDER_H__ 19761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 20761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/foundation/ALooper.h> 21761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <media/stagefright/foundation/AHandlerReflector.h> 22761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <utils/RefBase.h> 23761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <utils/threads.h> 24761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 25761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include "aah_tx_packet.h" 26761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include "pipe_event.h" 27761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 28761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmannamespace android { 29761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 30761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmantemplate <typename T> class CircularBuffer { 31761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman public: 32761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CircularBuffer(size_t capacity); 33761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ~CircularBuffer(); 34761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void push_back(const T& item);; 35761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void pop_front(); 36761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman size_t size() const; 37761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman bool isFull() const; 38761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman bool isEmpty() const; 39761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman const T& itemAt(size_t index) const; 40761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman const T& operator[](size_t index) const; 41761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 42761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman private: 43761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman T* mBuffer; 44761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman size_t mCapacity; 45761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman size_t mHead; 46761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman size_t mTail; 47761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman size_t mFillCount; 48761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 49761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman DISALLOW_EVIL_CONSTRUCTORS(CircularBuffer); 50761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman}; 51761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 52761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanclass AAH_TXSender : public virtual RefBase { 53761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman public: 54761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ~AAH_TXSender(); 55761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 56761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static sp<AAH_TXSender> GetInstance(); 57761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 58761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALooper::handler_id handlerID() { return mReflector->id(); } 59761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 60761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // an IP address and port 61761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman struct Endpoint { 62761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Endpoint(); 63761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Endpoint(uint32_t a, uint16_t p); 64761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman bool operator<(const Endpoint& other) const; 65761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 66761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t addr; 67761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t port; 68761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman }; 69761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 70761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t registerEndpoint(const Endpoint& endpoint); 71761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void unregisterEndpoint(const Endpoint& endpoint); 72761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 73761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman enum { 74761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman kWhatSendPacket, 75761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman kWhatTrimRetryBuffers, 76761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman kWhatSendHeartbeats, 77761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman }; 78761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 79761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // fields for SendPacket messages 80761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const char* kSendPacketIPAddr; 81761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const char* kSendPacketPort; 82761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const char* kSendPacketTRTPPacket; 83761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 84761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman private: 85761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AAH_TXSender(); 86761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 87761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static Mutex sLock; 88761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static wp<AAH_TXSender> sInstance; 89761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static uint32_t sNextEpoch; 90761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static bool sNextEpochValid; 91761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 92761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static uint32_t getNextEpoch(); 93761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 94761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman typedef CircularBuffer<sp<TRTPPacket> > RetryBuffer; 95761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 96761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // state maintained on a per-endpoint basis 97761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman struct EndpointState { 98761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman EndpointState(uint32_t epoch); 99761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman RetryBuffer retry; 100761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman int playerRefCount; 101761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t trtpSeqNumber; 102761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t nextProgramID; 103761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t epoch; 104761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman }; 105761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 106761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman friend class AHandlerReflector<AAH_TXSender>; 107761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void onMessageReceived(const sp<AMessage>& msg); 108761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void onSendPacket(const sp<AMessage>& msg); 109761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void doSendPacket_l(const sp<TRTPPacket>& packet, 110761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman const Endpoint& endpoint); 111761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void trimRetryBuffers(); 112761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void sendHeartbeats(); 113761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman bool shouldSendHeartbeats_l(); 114761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 115761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman sp<ALooper> mLooper; 116761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman sp<AHandlerReflector<AAH_TXSender> > mReflector; 117761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 118761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman int mSocket; 119761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman nsecs_t mLastSentPacketTime; 120761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 121761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman DefaultKeyedVector<Endpoint, EndpointState*> mEndpointMap; 122761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman Mutex mEndpointLock; 123761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 124761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const int kRetryTrimIntervalUs; 125761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const int kHeartbeatIntervalUs; 126761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const int kRetryBufferCapacity; 127761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const nsecs_t kHeartbeatTimeout; 128761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 129761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman class RetryReceiver : public Thread { 130761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman private: 131761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman friend class AAH_TXSender; 132761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 133761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman RetryReceiver(AAH_TXSender* sender); 134761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman virtual ~RetryReceiver(); 135761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman virtual bool threadLoop(); 136761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman void handleRetryRequest(); 137761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 138761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const int kMaxReceiverPacketLen; 139761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const uint32_t kRetryRequestID; 140761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const uint32_t kFastStartRequestID; 141761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman static const uint32_t kRetryNakID; 142761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 143761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AAH_TXSender* mSender; 144761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman PipeEvent mWakeupEvent; 145761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman }; 146761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 147761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman sp<RetryReceiver> mRetryReceiver; 148761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 149761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman DISALLOW_EVIL_CONSTRUCTORS(AAH_TXSender); 150761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman}; 151761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 152761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanstruct RetryPacket { 153761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t id; 154761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t endpointIP; 155761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t endpointPort; 156761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t seqStart; 157761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t seqEnd; 158761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} __attribute__((packed)); 159761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 160761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} // namespace android 161761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 162761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#endif // __AAH_TX_SENDER_H__ 163