RTSPSource.cpp revision 3f27436a9346f043f52265da1e6a74cde2bffd4d
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "RTSPSource"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <utils/Log.h>
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "RTSPSource.h"
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "AnotherPacketSource.h"
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "MyHandler.h"
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "SDPLoader.h"
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/IMediaHTTPService.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/MetaData.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huberconst int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::RTSPSource::RTSPSource(
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        const sp<AMessage> &notify,
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        const sp<IMediaHTTPService> &httpService,
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *url,
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const KeyedVector<String8, String8> *headers,
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        bool uidValid,
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        uid_t uid,
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isSDP)
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : Source(notify),
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mHTTPService(httpService),
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mURL(url),
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mUIDValid(uidValid),
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mUID(uid),
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFlags(0),
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mIsSDP(isSDP),
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mState(DISCONNECTED),
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mFinalResult(OK),
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mDisconnectReplyID(0),
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mBuffering(false),
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mSeekGeneration(0),
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mEOSTimeoutAudio(0),
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mEOSTimeoutVideo(0) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (headers) {
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mExtraHeaders = *headers;
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t index =
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (index >= 0) {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mFlags |= kFlagIncognito;
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mExtraHeaders.removeItemsAt(index);
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71f933441648ef6a71dee783d733aac17b9508b452Andreas HuberNuPlayer::RTSPSource::~RTSPSource() {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mLooper != NULL) {
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper->unregisterHandler(id());
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper->stop();
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::prepareAsync() {
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mLooper == NULL) {
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper = new ALooper;
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper->setName("rtsp");
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper->start();
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper->registerHandler(this);
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mHandler == NULL);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mSDPLoader == NULL);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = new AMessage(kWhatNotify, this);
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mState, (int)DISCONNECTED);
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mState = CONNECTING;
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mIsSDP) {
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mSDPLoader = new SDPLoader(notify,
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0,
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mHTTPService);
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mSDPLoader->load(
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mLooper->registerHandler(mHandler);
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mHandler->connect();
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    startBufferingIfNecessary();
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::start() {
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::stop() {
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mLooper == NULL) {
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> dummy;
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->postAndAwaitResponse(&dummy);
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
125f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::pause() {
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mediaDurationUs = 0;
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    getDuration(&mediaDurationUs);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t index = 0; index < mTracks.size(); index++) {
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        TrackInfo *info = &mTracks.editItemAt(index);
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AnotherPacketSource> source = info->mSource;
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Check if EOS or ERROR is received
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (source != NULL && source->isFinished(mediaDurationUs)) {
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mHandler->pause();
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::resume() {
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mHandler->resume();
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    Mutex::Autolock _l(mBufferingLock);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mFinalResult;
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) {
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AnotherPacketSource> source = getSource(audio);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (source == NULL) {
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return NULL;
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return source->getFormat();
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // We're going to buffer at least 2 secs worth data on all tracks before
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // starting playback (both at startup and after a seek).
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const int64_t kMinDurationUs = 2000000ll;
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t mediaDurationUs = 0;
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    getDuration(&mediaDurationUs);
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
169ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        return true;
170ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    status_t err;
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    int64_t durationUs;
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mAudioTrack != NULL
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber                    < kMinDurationUs
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            && err == OK) {
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber              durationUs / 1E6);
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        return false;
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mVideoTrack != NULL
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber                    < kMinDurationUs
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            && err == OK) {
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber              durationUs / 1E6);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool audio, sp<ABuffer> *accessUnit) {
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!stopBufferingIfNecessary()) {
198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        return -EWOULDBLOCK;
199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AnotherPacketSource> source = getSource(audio);
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (source == NULL) {
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return -EWOULDBLOCK;
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    status_t finalResult;
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        if (finalResult == OK) {
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int64_t mediaDurationUs = 0;
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            getDuration(&mediaDurationUs);
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AnotherPacketSource> otherSource = getSource(!audio);
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            status_t otherFinalResult;
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            // If other source already signaled EOS, this source should also signal EOS
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (otherSource != NULL &&
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    !otherSource->hasBufferAvailable(&otherFinalResult) &&
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    otherFinalResult == ERROR_END_OF_STREAM) {
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                source->signalEOS(ERROR_END_OF_STREAM);
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                return ERROR_END_OF_STREAM;
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            // If this source has detected near end, give it some time to retrieve more
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            // data before signaling EOS
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (source->isFinished(mediaDurationUs)) {
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (eosTimeout == 0) {
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    setEOSTimeout(audio, ALooper::GetNowUs());
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    setEOSTimeout(audio, 0);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    source->signalEOS(ERROR_END_OF_STREAM);
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    return ERROR_END_OF_STREAM;
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return -EWOULDBLOCK;
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) {
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We should not enter buffering mode
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // if any of the sources already have detected EOS.
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                startBufferingIfNecessary();
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return -EWOULDBLOCK;
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return finalResult;
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    setEOSTimeout(audio, 0);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return source->dequeueAccessUnit(accessUnit);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mTSParser != NULL) {
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<MediaSource> source = mTSParser->getSource(
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return static_cast<AnotherPacketSource *>(source.get());
259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return audio ? mAudioTrack : mVideoTrack;
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) {
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (audio) {
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        mEOSTimeoutAudio = timeout;
267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    } else {
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        mEOSTimeoutVideo = timeout;
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    *durationUs = 0ll;
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t audioDurationUs;
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mAudioTrack != NULL
277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            && mAudioTrack->getFormat()->findInt64(
278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                kKeyDuration, &audioDurationUs)
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && audioDurationUs > *durationUs) {
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *durationUs = audioDurationUs;
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int64_t videoDurationUs;
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mVideoTrack != NULL
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mVideoTrack->getFormat()->findInt64(
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                kKeyDuration, &videoDurationUs)
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && videoDurationUs > *durationUs) {
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        *durationUs = videoDurationUs;
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post(200000ll);
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mState != CONNECTED) {
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mState = SEEKING;
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mHandler->seek(seekTimeUs);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->what() == kWhatDisconnect) {
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AReplyToken> replyID;
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mDisconnectReplyID = replyID;
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        finishDisconnectIfPossible();
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t generation;
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("generation", &generation));
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (generation != mSeekGeneration) {
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // obsolete.
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t seekTimeUs;
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        performSeek(seekTimeUs);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t what;
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("what", &what));
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (what) {
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case MyHandler::kWhatConnected:
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onConnected();
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notifyVideoSizeChanged();
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            uint32_t flags = 0;
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mHandler->isSeekable()) {
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                flags = FLAG_CAN_PAUSE
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        | FLAG_CAN_SEEK
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        | FLAG_CAN_SEEK_BACKWARD
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        | FLAG_CAN_SEEK_FORWARD;
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notifyFlagsChanged(flags);
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notifyPrepared();
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case MyHandler::kWhatDisconnected:
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            onDisconnected(msg);
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber            break;
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber        }
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber        case MyHandler::kWhatSeekDone:
369054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        {
370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mState = CONNECTED;
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            break;
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case MyHandler::kWhatAccessUnit:
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t trackIndex;
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mTSParser == NULL) {
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_LT(trackIndex, mTracks.size());
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(trackIndex, 0u);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<ABuffer> accessUnit;
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
387dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t damaged;
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && damaged) {
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                ALOGI("dropping damaged access unit.");
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mTSParser != NULL) {
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                size_t offset = 0;
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                status_t err = OK;
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                while (offset + 188 <= accessUnit->size()) {
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    err = mTSParser->feedTSPacket(
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            accessUnit->data() + offset, 188);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    if (err != OK) {
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        break;
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                    offset += 188;
406a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                }
407a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                if (offset < accessUnit->size()) {
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                    err = ERROR_MALFORMED;
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                }
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (err != OK) {
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    sp<AnotherPacketSource> source = getSource(false /* audio */);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (source != NULL) {
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        source->signalEOS(err);
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    source = getSource(true /* audio */);
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (source != NULL) {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        source->signalEOS(err);
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            sp<AnotherPacketSource> source = info->mSource;
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (source != NULL) {
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                uint32_t rtpTime;
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!info->mNPTMappingValid) {
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // This is a live stream, we didn't receive any normal
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // playtime mapping. We won't map to npt time.
4367a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong                    source->queueAccessUnit(accessUnit);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    break;
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t nptUs =
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        / info->mTimeScale
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        * 1000000ll
444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        + info->mNormalPlaytimeUs;
445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                source->queueAccessUnit(accessUnit);
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
450496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case MyHandler::kWhatEOS:
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t finalResult;
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_NE(finalResult, (status_t)OK);
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mTSParser != NULL) {
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AnotherPacketSource> source = getSource(false /* audio */);
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (source != NULL) {
462054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    source->signalEOS(finalResult);
463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                source = getSource(true /* audio */);
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (source != NULL) {
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    source->signalEOS(finalResult);
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                return;
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t trackIndex;
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (source != NULL) {
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                source->signalEOS(finalResult);
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
488ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            size_t trackIndex;
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_LT(trackIndex, mTracks.size());
491afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            if (source != NULL) {
4951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber                source->queueDiscontinuity(
496308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        ATSParser::DISCONTINUITY_TIME,
497308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        NULL,
498ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        true /* discard */);
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            break;
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
505308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        {
506308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            size_t trackIndex;
507308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            CHECK(msg->findSize("trackIndex", &trackIndex));
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            CHECK_LT(trackIndex, mTracks.size());
509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t rtpTime;
511ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            int64_t nptUs;
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            info->mRTPTime = rtpTime;
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNormalPlaytimeUs = nptUs;
5191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            info->mNPTMappingValid = true;
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
5211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case SDPLoader::kWhatSDPLoaded:
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onSDPLoaded(msg);
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
533eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
534eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
535eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    CHECK(mAudioTrack == NULL);
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mVideoTrack == NULL);
537eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t numTracks = mHandler->countTracks();
539eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t timeScale;
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
542eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime;
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Very special case for MPEG2 Transport Streams.
548054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            CHECK_EQ(numTracks, 1u);
549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
550054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mTSParser = new ATSParser;
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        TrackInfo info;
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info.mTimeScale = timeScale;
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info.mRTPTime = 0;
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info.mNormalPlaytimeUs = 0ll;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info.mNPTMappingValid = false;
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if ((isAudio && mAudioTrack == NULL)
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                || (isVideo && mVideoTrack == NULL)) {
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (isAudio) {
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mAudioTrack = source;
56929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            } else {
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mVideoTrack = source;
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info.mSource = source;
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5753c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
5763c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        mTracks.push(info);
5773c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5785ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block
5793c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    mState = CONNECTED;
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis}
5813c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennisvoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err;
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    CHECK(msg->findInt32("result", &err));
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    mSDPLoader.clear();
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mDisconnectReplyID != 0) {
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = UNKNOWN_ERROR;
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err == OK) {
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<ASessionDescription> desc;
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<RefBase> obj;
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        CHECK(msg->findObject("description", &obj));
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        desc = static_cast<ASessionDescription *>(obj.get());
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        AString rtspUri;
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("Unable to find url in SDP");
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            err = UNKNOWN_ERROR;
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        } else {
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            sp<AMessage> notify = new AMessage(kWhatNotify, this);
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mLooper->registerHandler(mHandler);
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6083c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            mHandler->loadSDP(desc);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
61129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mState == CONNECTING) {
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're still in the preparation phase, signal that it
615054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            // failed.
616258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            notifyPrepared(err);
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
619258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        mState = DISCONNECTED;
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        setError(err);
62129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
622258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (mDisconnectReplyID != 0) {
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            finishDisconnectIfPossible();
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis}
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennisvoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mState == DISCONNECTED) {
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return;
631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    status_t err;
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    CHECK(msg->findInt32("result", &err));
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    CHECK_NE(err, (status_t)OK);
63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    mLooper->unregisterHandler(mHandler->id());
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    mHandler.clear();
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (mState == CONNECTING) {
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        // We're still in the preparation phase, signal that it
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // failed.
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notifyPrepared(err);
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    mState = DISCONNECTED;
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    setError(err);
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mDisconnectReplyID != 0) {
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        finishDisconnectIfPossible();
651054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
652054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
653054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mState != DISCONNECTED) {
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mHandler != NULL) {
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mHandler->disconnect();
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else if (mSDPLoader != NULL) {
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mSDPLoader->cancel();
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return;
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
665054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDisconnectReplyID = 0;
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid NuPlayer::RTSPSource::setError(status_t err) {
6698ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    Mutex::Autolock _l(mBufferingLock);
6701e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    mFinalResult = err;
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
67229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
673f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid NuPlayer::RTSPSource::startBufferingIfNecessary() {
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    Mutex::Autolock _l(mBufferingLock);
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!mBuffering) {
67774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffering = true;
67874006804065941841883c4b46ee785070164023fJamie Gennis
679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<AMessage> notify = dupNotify();
68074006804065941841883c4b46ee785070164023fJamie Gennis        notify->setInt32("what", kWhatBufferingStart);
68174006804065941841883c4b46ee785070164023fJamie Gennis        notify->post();
68274006804065941841883c4b46ee785070164023fJamie Gennis    }
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool NuPlayer::RTSPSource::stopBufferingIfNecessary() {
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    Mutex::Autolock _l(mBufferingLock);
68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block
68874006804065941841883c4b46ee785070164023fJamie Gennis    if (mBuffering) {
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!haveSufficientDataOnAllTracks()) {
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
69274006804065941841883c4b46ee785070164023fJamie Gennis
69374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffering = false;
6943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = dupNotify();
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", kWhatBufferingEnd);
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber