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