ARTPSource.cpp revision cf7b9c7aae758ac0b99833915053c63c2ac46e09
1cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber/*
2cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
4cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * you may not use this file except in compliance with the License.
6cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * You may obtain a copy of the License at
7cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
8cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber *
10cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * See the License for the specific language governing permissions and
14cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber * limitations under the License.
15cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber */
16cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
17cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ARTPSource.h"
18cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
19cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "AAVCAssembler.h"
20cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "AMPEG4AudioAssembler.h"
21cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include "ASessionDescription.h"
22cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
23cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
24cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/ADebug.h>
25cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#include <media/stagefright/foundation/AMessage.h>
26cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
27cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#define VERBOSE         0
28cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
29cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubernamespace android {
30cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
31cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas HuberARTPSource::ARTPSource(
32cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        uint32_t id,
33cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<ASessionDescription> &sessionDesc, size_t index,
34cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        const sp<AMessage> &notify)
35cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    : mID(id),
36cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mHighestSeqNumber(0),
37cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mNumBuffersReceived(0),
38cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber      mNumTimes(0) {
39cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    unsigned long PT;
40cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString desc;
41cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString params;
42cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    sessionDesc->getFormatType(index, &PT, &desc, &params);
43cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
44cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (!strncmp(desc.c_str(), "H264/", 5)) {
45cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mAssembler = new AAVCAssembler(notify);
46cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else if (!strncmp(desc.c_str(), "MP4A-LATM", 9)) {
47cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mAssembler = new AMPEG4AudioAssembler(notify);
48cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
49cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        TRESPASS();
50cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
51cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
52cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
53cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberstatic uint32_t AbsDiff(uint32_t seq1, uint32_t seq2) {
54cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return seq1 > seq2 ? seq1 - seq2 : seq2 - seq1;
55cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
56cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
57cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPSource::processRTPPacket(const sp<ABuffer> &buffer) {
58cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (queuePacket(buffer) && mNumTimes == 2 && mAssembler != NULL) {
59cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mAssembler->onPacketReceived(this);
60cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
61cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
62cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    dump();
63cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
64cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
65cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPSource::timeUpdate(uint32_t rtpTime, uint64_t ntpTime) {
66cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#if VERBOSE
67cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    LOG(VERBOSE) << "timeUpdate";
68cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif
69cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
70cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mNumTimes == 2) {
71cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mNTPTime[0] = mNTPTime[1];
72cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mRTPTime[0] = mRTPTime[1];
73cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mNumTimes = 1;
74cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
75cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mNTPTime[mNumTimes] = ntpTime;
76cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mRTPTime[mNumTimes++] = rtpTime;
77cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
78cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mNumTimes == 2) {
79cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        for (List<sp<ABuffer> >::iterator it = mQueue.begin();
80cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber             it != mQueue.end(); ++it) {
81cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            sp<AMessage> meta = (*it)->meta();
82cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
83cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            uint32_t rtpTime;
84cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime));
85cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
86cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            meta->setInt64("ntp-time", RTP2NTP(rtpTime));
87cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
88cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
89cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
90cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
91cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberbool ARTPSource::queuePacket(const sp<ABuffer> &buffer) {
92cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t seqNum = (uint32_t)buffer->int32Data();
93cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
94cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mNumTimes == 2) {
95cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sp<AMessage> meta = buffer->meta();
96cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
97cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        uint32_t rtpTime;
98cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        CHECK(meta->findInt32("rtp-time", (int32_t *)&rtpTime));
99cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
100cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        meta->setInt64("ntp-time", RTP2NTP(rtpTime));
101cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
102cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
103cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mNumBuffersReceived++ == 0) {
104cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mHighestSeqNumber = seqNum;
105cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mQueue.push_back(buffer);
106cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return true;
107cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
108cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
109cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // Only the lower 16-bit of the sequence numbers are transmitted,
110cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // derive the high-order bits by choosing the candidate closest
111cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    // to the highest sequence number (extended to 32 bits) received so far.
112cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
113cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t seq1 = seqNum | (mHighestSeqNumber & 0xffff0000);
114cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t seq2 = seqNum | ((mHighestSeqNumber & 0xffff0000) + 0x10000);
115cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t seq3 = seqNum | ((mHighestSeqNumber & 0xffff0000) - 0x10000);
116cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t diff1 = AbsDiff(seq1, mHighestSeqNumber);
117cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t diff2 = AbsDiff(seq2, mHighestSeqNumber);
118cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    uint32_t diff3 = AbsDiff(seq3, mHighestSeqNumber);
119cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
120cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (diff1 < diff2) {
121cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (diff1 < diff3) {
122cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // diff1 < diff2 ^ diff1 < diff3
123cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            seqNum = seq1;
124cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        } else {
125cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            // diff3 <= diff1 < diff2
126cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            seqNum = seq3;
127cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
128cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else if (diff2 < diff3) {
129cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // diff2 <= diff1 ^ diff2 < diff3
130cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        seqNum = seq2;
131cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    } else {
132cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        // diff3 <= diff2 <= diff1
133cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        seqNum = seq3;
134cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
135cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
136cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (seqNum > mHighestSeqNumber) {
137cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        mHighestSeqNumber = seqNum;
138cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
139cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
140cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    buffer->setInt32Data(seqNum);
141cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
142cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    List<sp<ABuffer> >::iterator it = mQueue.begin();
143cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (it != mQueue.end() && (uint32_t)(*it)->int32Data() < seqNum) {
144cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++it;
145cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
146cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
147cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (it != mQueue.end() && (uint32_t)(*it)->int32Data() == seqNum) {
148cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        LOG(WARNING) << "Discarding duplicate buffer";
149cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return false;
150cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
151cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
152cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    mQueue.insert(it, buffer);
153cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
154cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return true;
155cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
156cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
157cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Hubervoid ARTPSource::dump() const {
158cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if ((mNumBuffersReceived % 128) != 0) {
159cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        return;
160cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
161cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
162cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#if 0
163cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    if (mAssembler == NULL) {
164cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        char tmp[20];
165cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        sprintf(tmp, "0x%08x", mID);
166cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
167cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        int32_t numMissing = 0;
168cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
169cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (!mQueue.empty()) {
170cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            List<sp<ABuffer> >::const_iterator it = mQueue.begin();
171cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            uint32_t expectedSeqNum = (uint32_t)(*it)->int32Data();
172cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++expectedSeqNum;
173cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++it;
174cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
175cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            for (; it != mQueue.end(); ++it) {
176cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                uint32_t seqNum = (uint32_t)(*it)->int32Data();
177cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                CHECK_GE(seqNum, expectedSeqNum);
178cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
179cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                if (seqNum != expectedSeqNum) {
180cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    numMissing += seqNum - expectedSeqNum;
181cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    expectedSeqNum = seqNum;
182cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                }
183cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
184cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                ++expectedSeqNum;
185cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
186cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
187cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
188cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        LOG(VERBOSE) << "[" << tmp << "] Missing " << numMissing
189cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber             << " / " << (mNumBuffersReceived + numMissing) << " packets. ("
190cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber             << (100.0 * numMissing / (mNumBuffersReceived + numMissing))
191cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber             << " %%)";
192cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
193cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif
194cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
195cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#if 0
196cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    AString out;
197cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
198cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    out.append(tmp);
199cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    out.append(" [");
200cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
201cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    List<sp<ABuffer> >::const_iterator it = mQueue.begin();
202cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    while (it != mQueue.end()) {
203cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        uint32_t start = (uint32_t)(*it)->int32Data();
204cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
205cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        out.append(start);
206cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
207cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        ++it;
208cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        uint32_t expected = start + 1;
209cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
210cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        while (it != mQueue.end()) {
211cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            uint32_t seqNum = (uint32_t)(*it)->int32Data();
212cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
213cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (seqNum != expected) {
214cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                if (expected > start + 1) {
215cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    out.append("-");
216cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                    out.append(expected - 1);
217cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                }
218cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                out.append(", ");
219cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                break;
220cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
221cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
222cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++it;
223cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            ++expected;
224cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
225cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
226cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        if (it == mQueue.end()) {
227cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            if (expected > start + 1) {
228cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                out.append("-");
229cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber                out.append(expected - 1);
230cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            }
231cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber        }
232cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    }
233cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
234cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    out.append("]");
235cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
236cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    LOG(VERBOSE) << out;
237cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber#endif
238cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
239cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
240cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huberuint64_t ARTPSource::RTP2NTP(uint32_t rtpTime) const {
241cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    CHECK_EQ(mNumTimes, 2u);
242cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
243cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber    return mNTPTime[0] + (double)(mNTPTime[1] - mNTPTime[0])
244cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            * ((double)rtpTime - (double)mRTPTime[0])
245cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber            / (double)(mRTPTime[1] - mRTPTime[0]);
246cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}
247cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
248cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber}  // namespace android
249cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
250cf7b9c7aae758ac0b99833915053c63c2ac46e09Andreas Huber
251