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#define LOG_TAG "LibAAH_RTP" 18761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman//#define LOG_NDEBUG 0 19761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include <utils/Log.h> 20761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 21761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman#include "aah_rx_player.h" 22761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 23761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmannamespace android { 24761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 25761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_RXPlayer::RXRingBuffer::RXRingBuffer(uint32_t capacity) { 26761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman capacity_ = capacity; 27761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_ = wr_ = 0; 28761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_ = new PacketBuffer*[capacity]; 29761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman memset(ring_, 0, sizeof(PacketBuffer*) * capacity); 30761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman reset(); 31761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 32761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 33761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_RXPlayer::RXRingBuffer::~RXRingBuffer() { 34761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman reset(); 35761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman delete[] ring_; 36761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 37761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 38761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanvoid AAH_RXPlayer::RXRingBuffer::reset() { 39761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AutoMutex lock(&lock_); 40761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 41761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != ring_) { 42761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman while (rd_ != wr_) { 43761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(rd_ < capacity_); 44761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != ring_[rd_]) { 45761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman PacketBuffer::destroy(ring_[rd_]); 46761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_[rd_] = NULL; 47761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 48761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_ = (rd_ + 1) % capacity_; 49761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 50761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 51761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 52761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_ = wr_ = 0; 53761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_seq_known_ = false; 54761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman waiting_for_fast_start_ = true; 55761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman fetched_first_packet_ = false; 56761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rtp_activity_timeout_valid_ = false; 57761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 58761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 59761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanbool AAH_RXPlayer::RXRingBuffer::pushBuffer(PacketBuffer* buf, 60761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t seq) { 61761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AutoMutex lock(&lock_); 62761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL != ring_); 63761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL != buf); 64761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 65761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rtp_activity_timeout_valid_ = true; 66761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rtp_activity_timeout_ = monotonicUSecNow() + kRTPActivityTimeoutUSec; 67761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 68761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If the ring buffer is totally reset (we have never received a single 69761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // payload) then we don't know the rd sequence number and this should be 70761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // simple. We just store the payload, advance the wr pointer and record the 71761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // initial sequence number. 72761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!rd_seq_known_) { 73761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(rd_ == wr_); 74761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL == ring_[wr_]); 75761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(wr_ < capacity_); 76761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 77761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_[wr_] = buf; 78761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman wr_ = (wr_ + 1) % capacity_; 79761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_seq_ = seq; 80761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_seq_known_ = true; 81761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return true; 82761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 83761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 84761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Compute the seqence number of this payload and of the write pointer, 85761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // normalized around the read pointer. IOW - transform the payload seq no 86761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // and the wr pointer seq no into a space where the rd pointer seq no is 87761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // zero. This will define 4 cases we can consider... 88761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 89761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 1) norm_seq == norm_wr_seq 90761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // This payload is contiguous with the last. All is good. 91761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 92761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 2) ((norm_seq < norm_wr_seq) && (norm_seq >= norm_rd_seq) 93761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // aka ((norm_seq < norm_wr_seq) && (norm_seq >= 0) 94761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // This payload is in the past, in the unprocessed region of the ring 95761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // buffer. It is probably a retransmit intended to fill in a dropped 96761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // payload; it may be a duplicate. 97761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 98761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 3) ((norm_seq - norm_wr_seq) & 0x8000) != 0 99761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // This payload is in the past compared to the write pointer (or so very 100761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // far in the future that it has wrapped the seq no space), but not in 101761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // the unprocessed region of the ring buffer. This could be a duplicate 102761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // retransmit; we just drop these payloads unless we are waiting for our 103761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // first fast start packet. If we are waiting for fast start, than this 104761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // packet is probably the first packet of the fast start retransmission. 105761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If it will fit in the buffer, back up the read pointer to its position 106761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // and clear the fast start flag, otherwise just drop it. 107761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 108761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // 4) ((norm_seq - norm_wr_seq) & 0x8000) == 0 109761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // This payload which is ahead of the next write pointer. This indicates 110761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // that we have missed some payloads and need to request a retransmit. 111761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If norm_seq >= (capacity - 1), then the gap is so large that it would 112761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // overflow the ring buffer and we should probably start to panic. 113761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 114761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t norm_wr_seq = ((wr_ + capacity_ - rd_) % capacity_); 115761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t norm_seq = seq - rd_seq_; 116761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 117761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Check for overflow first. 118761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if ((!(norm_seq & 0x8000)) && (norm_seq >= (capacity_ - 1))) { 1194b77dc28097288cb062fce6bf5de0fb3394877a9John Grossman ALOGW("Ring buffer overflow; cap = %u, [rd, wr] = [%hu, %hu]," 1204b77dc28097288cb062fce6bf5de0fb3394877a9John Grossman " seq = %hu", capacity_, rd_seq_, norm_wr_seq + rd_seq_, seq); 121761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman PacketBuffer::destroy(buf); 122761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return false; 123761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 124761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 125761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Check for case #1 126761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (norm_seq == norm_wr_seq) { 127761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(wr_ < capacity_); 128761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL == ring_[wr_]); 129761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 130761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_[wr_] = buf; 131761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman wr_ = (wr_ + 1) % capacity_; 132761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 133761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(wr_ != rd_); 134761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return true; 135761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 136761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 137761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Check case #2 138761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t ring_pos = (rd_ + norm_seq) % capacity_; 139761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if ((norm_seq < norm_wr_seq) && (!(norm_seq & 0x8000))) { 140761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Do we already have a payload for this slot? If so, then this looks 141761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // like a duplicate retransmit. Just ignore it. 142761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != ring_[ring_pos]) { 143761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGD("RXed duplicate retransmit, seq = %hu", seq); 144761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman PacketBuffer::destroy(buf); 145761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 146761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Looks like we were missing this payload. Go ahead and store it. 147761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_[ring_pos] = buf; 148761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 149761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 150761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return true; 151761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 152761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 153761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Check case #3 154761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if ((norm_seq - norm_wr_seq) & 0x8000) { 155761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!waiting_for_fast_start_) { 156761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGD("RXed duplicate retransmit from before rd pointer, seq = %hu", 157761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman seq); 158761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman PacketBuffer::destroy(buf); 159761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 160761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Looks like a fast start fill-in. Go ahead and store it, assuming 161761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // that we can fit it in the buffer. 162761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t implied_ring_size = static_cast<uint32_t>(norm_wr_seq) 163761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman + (rd_seq_ - seq); 164761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 165761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (implied_ring_size >= (capacity_ - 1)) { 166761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGD("RXed what looks like a fast start packet (seq = %hu)," 167761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " but packet is too far in the past to fit into the ring" 168761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman " buffer. Dropping.", seq); 169761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman PacketBuffer::destroy(buf); 170761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } else { 171761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_pos = (rd_ + capacity_ + seq - rd_seq_) % capacity_; 172761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_seq_ = seq; 173761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_ = ring_pos; 174761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman waiting_for_fast_start_ = false; 175761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 176761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(ring_pos < capacity_); 177761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL == ring_[ring_pos]); 178761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_[ring_pos] = buf; 179761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 180761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 181761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 182761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return true; 183761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 184761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 185761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Must be in case #4 with no overflow. This packet fits in the current 186761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // ring buffer, but is discontiuguous. Advance the write pointer leaving a 187761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // gap behind. 188761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t gap_len = (ring_pos + capacity_ - wr_) % capacity_; 189761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ALOGD("Drop detected; %u packets, seq_range [%hu, %hu]", 190761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman gap_len, 191761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_seq_ + norm_wr_seq, 192761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_seq_ + norm_wr_seq + gap_len - 1); 193761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 194761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL == ring_[ring_pos]); 195761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_[ring_pos] = buf; 196761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman wr_ = (ring_pos + 1) % capacity_; 197761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(wr_ != rd_); 198761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 199761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return true; 200761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 201761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 202761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_RXPlayer::PacketBuffer* 203761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_RXPlayer::RXRingBuffer::fetchBuffer(bool* is_discon) { 204761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AutoMutex lock(&lock_); 205761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL != ring_); 206761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL != is_discon); 207761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 208761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If the read seqence number is not known, then this ring buffer has not 209761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // received a packet since being reset and there cannot be any packets to 210761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // return. If we are still waiting for the first fast start packet to show 211761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // up, we don't want to let any buffer be consumed yet because we expect to 212761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // see a packet before the initial read sequence number show up shortly. 213761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!rd_seq_known_ || waiting_for_fast_start_) { 214761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman *is_discon = false; 215761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return NULL; 216761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 217761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 218761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman PacketBuffer* ret = NULL; 219761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman *is_discon = !fetched_first_packet_; 220761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 221761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman while ((rd_ != wr_) && (NULL == ret)) { 222761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(rd_ < capacity_); 223761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 224761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If we hit a gap, stall and do not advance the read pointer. Let the 225761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // higher level code deal with requesting retries and/or deciding to 226761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // skip the current gap. 227761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ret = ring_[rd_]; 228761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL == ret) { 229761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman break; 230761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 231761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 232761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ring_[rd_] = NULL; 233761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_ = (rd_ + 1) % capacity_; 234761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ++rd_seq_; 235761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 236761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 237761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != ret) { 238761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman fetched_first_packet_ = true; 239761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 240761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 241761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return ret; 242761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 243761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 244761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_RXPlayer::GapStatus 245761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_RXPlayer::RXRingBuffer::fetchCurrentGap(SeqNoGap* gap) { 246761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AutoMutex lock(&lock_); 247761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL != ring_); 248761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL != gap); 249761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 250761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If the read seqence number is not known, then this ring buffer has not 251761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // received a packet since being reset and there cannot be any gaps. 252761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!rd_seq_known_) { 253761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return kGS_NoGap; 254761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 255761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 256761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If we are waiting for fast start, then the current gap is a fast start 257761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // gap and it includes all packets before the read sequence number. 258761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (waiting_for_fast_start_) { 259761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman gap->start_seq_ = 260761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman gap->end_seq_ = rd_seq_ - 1; 261761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return kGS_FastStartGap; 262761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 263761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 264761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If rd == wr, then the buffer is empty and there cannot be any gaps. 265761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (rd_ == wr_) { 266761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return kGS_NoGap; 267761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 268761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 269761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If rd_ is currently pointing at an unprocessed packet, then there is no 270761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // current gap. 271761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(rd_ < capacity_); 272761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != ring_[rd_]) { 273761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return kGS_NoGap; 274761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 275761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 276761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Looks like there must be a gap here. The start of the gap is the current 277761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // rd sequence number, all we need to do now is determine its length in 278761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // order to compute the end sequence number. 279761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman gap->start_seq_ = rd_seq_; 280761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t end = rd_seq_; 281761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t tmp = (rd_ + 1) % capacity_; 282761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman while ((tmp != wr_) && (NULL == ring_[tmp])) { 283761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ++end; 284761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman tmp = (tmp + 1) % capacity_; 285761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 286761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman gap->end_seq_ = end; 287761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 288761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return kGS_NormalGap; 289761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 290761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 291761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanvoid AAH_RXPlayer::RXRingBuffer::processNAK(const SeqNoGap* nak) { 292761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AutoMutex lock(&lock_); 293761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(NULL != ring_); 294761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 295761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If we were waiting for our first fast start fill-in packet, and we 296761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // received a NAK, then apparantly we are not getting our fast start. Just 297761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // clear the waiting flag and go back to normal behavior. 298761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (waiting_for_fast_start_) { 299761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman waiting_for_fast_start_ = false; 300761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 301761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 302761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If we have not received a packet since last reset, or there is no data in 303761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // the ring, then there is nothing to skip. 304761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if ((!rd_seq_known_) || (rd_ == wr_)) { 305761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return; 306761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 307761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 308761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // If rd_ is currently pointing at an unprocessed packet, then there is no 309761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // gap to skip. 310761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman CHECK(rd_ < capacity_); 311761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != ring_[rd_]) { 312761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return; 313761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 314761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 315761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // Looks like there must be a gap here. Advance rd until we have passed 316761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // over the portion of it indicated by nak (or all of the gap if nak is 317761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // NULL). Then reset fetched_first_packet_ so that the next read will show 318761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman // up as being discontiguous. 319761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint16_t seq_after_gap = (NULL == nak) ? 0 : nak->end_seq_ + 1; 320761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman while ((rd_ != wr_) && 321761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman (NULL == ring_[rd_]) && 322761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ((NULL == nak) || (seq_after_gap != rd_seq_))) { 323761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman rd_ = (rd_ + 1) % capacity_; 324761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ++rd_seq_; 325761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 326761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman fetched_first_packet_ = false; 327761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 328761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 329761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanint AAH_RXPlayer::RXRingBuffer::computeInactivityTimeout() { 330761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman AutoMutex lock(&lock_); 331761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 332761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (!rtp_activity_timeout_valid_) { 333761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return -1; 334761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 335761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 336761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint64_t now = monotonicUSecNow(); 337761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (rtp_activity_timeout_ <= now) { 338761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return 0; 339761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 340761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 341761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return (rtp_activity_timeout_ - now) / 1000; 342761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 343761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 344761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_RXPlayer::PacketBuffer* 345761defc341c5ce9019a42919c441f035f665ec0dJohn GrossmanAAH_RXPlayer::PacketBuffer::allocate(ssize_t length) { 346761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (length <= 0) { 347761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return NULL; 348761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 349761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 350761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint32_t alloc_len = sizeof(PacketBuffer) + length; 351761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman PacketBuffer* ret = reinterpret_cast<PacketBuffer*>( 352761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman new uint8_t[alloc_len]); 353761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 354761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman if (NULL != ret) { 355761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman ret->length_ = length; 356761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman } 357761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 358761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman return ret; 359761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 360761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 361761defc341c5ce9019a42919c441f035f665ec0dJohn Grossmanvoid AAH_RXPlayer::PacketBuffer::destroy(PacketBuffer* pb) { 362761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman uint8_t* kill_me = reinterpret_cast<uint8_t*>(pb); 363761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman delete[] kill_me; 364761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} 365761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman 366761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman} // namespace android 367