RTSPSource.cpp revision 7e074a8b7548ac769d1f55addacd97f885651b0d
12bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber/*
22bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * Copyright (C) 2010 The Android Open Source Project
32bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber *
42bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
52bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * you may not use this file except in compliance with the License.
62bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * You may obtain a copy of the License at
72bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber *
82bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
92bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber *
102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * Unless required by applicable law or agreed to in writing, software
112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * See the License for the specific language governing permissions and
142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * limitations under the License.
152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber */
162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber//#define LOG_NDEBUG 0
182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#define LOG_TAG "RTSPSource"
192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include <utils/Log.h>
202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include "RTSPSource.h"
222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include "AnotherPacketSource.h"
242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include "MyHandler.h"
2581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé#include "SDPLoader.h"
262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h>
2849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber#include <media/stagefright/MediaDefs.h>
292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include <media/stagefright/MetaData.h>
302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
312bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubernamespace android {
322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
33cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonconst int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs
34cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
35641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih// Buffer Underflow/Prepare/StartServer/Overflow Marks
36641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihconst int64_t NuPlayer::RTSPSource::kUnderflowMarkUs   =  1000000ll;
37641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihconst int64_t NuPlayer::RTSPSource::kPrepareMarkUs     =  3000000ll;
38641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihconst int64_t NuPlayer::RTSPSource::kStartServerMarkUs =  5000000ll;
39641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihconst int64_t NuPlayer::RTSPSource::kOverflowMarkUs    = 10000000ll;
40641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
412bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::RTSPSource(
425ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber        const sp<AMessage> &notify,
431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const sp<IMediaHTTPService> &httpService,
442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *url,
452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const KeyedVector<String8, String8> *headers,
462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool uidValid,
4781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        uid_t uid,
4881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        bool isSDP)
495ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber    : Source(notify),
501b86fe063badb5f28c467ade39be0f4008688947Andreas Huber      mHTTPService(httpService),
515ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber      mURL(url),
522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mUIDValid(uidValid),
532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mUID(uid),
542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mFlags(0),
5581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé      mIsSDP(isSDP),
562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mState(DISCONNECTED),
572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mFinalResult(OK),
58ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber      mDisconnectReplyID(0),
59180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang      mBuffering(false),
60641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih      mInPreparationPhase(true),
61f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih      mEOSPending(false),
62cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mSeekGeneration(0),
63cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mEOSTimeoutAudio(0),
64cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mEOSTimeoutVideo(0) {
652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (headers) {
662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mExtraHeaders = *headers;
672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        ssize_t index =
692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if (index >= 0) {
722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mFlags |= kFlagIncognito;
732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.removeItemsAt(index);
752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
792bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::~RTSPSource() {
80602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    if (mLooper != NULL) {
811228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->unregisterHandler(id());
82602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber        mLooper->stop();
83602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    }
842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
8657cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::prepareAsync() {
87ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia    if (mIsSDP && mHTTPService == NULL) {
88ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia        notifyPrepared(BAD_VALUE);
89ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia        return;
90ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia    }
91ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia
922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper == NULL) {
932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper = new ALooper;
942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->setName("rtsp");
952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->start();
962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
971228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->registerHandler(this);
982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mHandler == NULL);
10181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(mSDPLoader == NULL);
1022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatNotify, this);
1042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(mState, (int)DISCONNECTED);
1062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTING;
1072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
10881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mIsSDP) {
10981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mSDPLoader = new SDPLoader(notify,
11081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé                (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0,
11181e68448f3361eaf8618930471fdc3c21bdf5cbcAndreas Huber                mHTTPService);
11281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
11357cea553cb19235553463412db5ad04c99835411Andreas Huber        mSDPLoader->load(
11457cea553cb19235553463412db5ad04c99835411Andreas Huber                mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
11581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    } else {
11681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
11781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mLooper->registerHandler(mHandler);
11881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
11981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mHandler->connect();
12081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
121cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
122180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    startBufferingIfNecessary();
12357cea553cb19235553463412db5ad04c99835411Andreas Huber}
12457cea553cb19235553463412db5ad04c99835411Andreas Huber
12557cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::start() {
1262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1282bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::stop() {
1295834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    if (mLooper == NULL) {
1305834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong        return;
1315834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    }
1321d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
1332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> dummy;
1352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    msg->postAndAwaitResponse(&dummy);
1362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
139180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
1402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return mFinalResult;
1412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
143840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) {
1442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return NULL;
1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->getFormat();
1512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
153bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {
154bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // We're going to buffer at least 2 secs worth data on all tracks before
155bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // starting playback (both at startup and after a seek).
156bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
157bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    static const int64_t kMinDurationUs = 2000000ll;
158bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
159cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    int64_t mediaDurationUs = 0;
160cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    getDuration(&mediaDurationUs);
161cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
162cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
163cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return true;
164cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
165cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
166bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    status_t err;
167bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    int64_t durationUs;
168bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mAudioTrack != NULL
169bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
170bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
171bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
172bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
173bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
174bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
175bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
176bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
177bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mVideoTrack != NULL
178bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
179bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
180bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
181bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
182bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
183bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
184bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
185bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
186bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    return true;
187bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber}
188bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
1902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
191180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!stopBufferingIfNecessary()) {
192180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        return -EWOULDBLOCK;
193bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
194bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return -EWOULDBLOCK;
1992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t finalResult;
2022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
203cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        if (finalResult == OK) {
204f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
205f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            // If other source already signaled EOS, this source should also return EOS
206f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            if (sourceReachedEOS(!audio)) {
207cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return ERROR_END_OF_STREAM;
208cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
209cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
210cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If this source has detected near end, give it some time to retrieve more
211f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            // data before returning EOS
212f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            int64_t mediaDurationUs = 0;
213f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            getDuration(&mediaDurationUs);
214cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (source->isFinished(mediaDurationUs)) {
215cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
216cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                if (eosTimeout == 0) {
217cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, ALooper::GetNowUs());
218cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
219cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, 0);
220cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    return ERROR_END_OF_STREAM;
221cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                }
222cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return -EWOULDBLOCK;
223cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
224cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
225f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            if (!sourceNearEOS(!audio)) {
226cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // We should not enter buffering mode
227cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // if any of the sources already have detected EOS.
228180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang                startBufferingIfNecessary();
229cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
230cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
231cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            return -EWOULDBLOCK;
232cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        }
233cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return finalResult;
2342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
236cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    setEOSTimeout(audio, 0);
237cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->dequeueAccessUnit(accessUnit);
2392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2412bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
24249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    if (mTSParser != NULL) {
24349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        sp<MediaSource> source = mTSParser->getSource(
24449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
24549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
24649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        return static_cast<AnotherPacketSource *>(source.get());
24749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    }
24849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
2492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return audio ? mAudioTrack : mVideoTrack;
2502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
252cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonvoid NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) {
253cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if (audio) {
254cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutAudio = timeout;
255cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    } else {
256cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutVideo = timeout;
257cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
258cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson}
259cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
2617e074a8b7548ac769d1f55addacd97f885651b0dRobert Shih    *durationUs = -1ll;
2622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t audioDurationUs;
2642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mAudioTrack != NULL
2652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mAudioTrack->getFormat()->findInt64(
2662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &audioDurationUs)
2672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && audioDurationUs > *durationUs) {
2682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = audioDurationUs;
2692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t videoDurationUs;
2722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mVideoTrack != NULL
2732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mVideoTrack->getFormat()->findInt64(
2742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &videoDurationUs)
2752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && videoDurationUs > *durationUs) {
2762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = videoDurationUs;
2772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return OK;
2802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
2831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
284ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
285ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
286ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
2878d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    sp<AMessage> response;
2888d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
2898d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    if (err == OK && response != NULL) {
2908d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        CHECK(response->findInt32("err", &err));
2918d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    }
2928d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
2938d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    return err;
294ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber}
295ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
296ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
2972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != CONNECTED) {
2988d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        finishSeek(INVALID_OPERATION);
299ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = SEEKING;
3032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->seek(seekTimeUs);
304f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    mEOSPending = false;
3052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
307641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::schedulePollBuffering() {
308641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
309641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    msg->post(1000000ll); // 1 second intervals
310641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih}
311641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
312641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::checkBuffering(
313f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        bool *prepared, bool *underflow, bool *overflow, bool *startServer, bool *finished) {
314641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    size_t numTracks = mTracks.size();
315f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    size_t preparedCount, underflowCount, overflowCount, startCount, finishedCount;
316f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    preparedCount = underflowCount = overflowCount = startCount = finishedCount = 0;
317c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa
318c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa    size_t count = numTracks;
319c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa    for (size_t i = 0; i < count; ++i) {
320641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        status_t finalResult;
321641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        TrackInfo *info = &mTracks.editItemAt(i);
322641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        sp<AnotherPacketSource> src = info->mSource;
323c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa        if (src == NULL) {
324c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa            --numTracks;
325c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa            continue;
326c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa        }
327641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        int64_t bufferedDurationUs = src->getBufferedDurationUs(&finalResult);
328641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
329641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        // isFinished when duration is 0 checks for EOS result only
330641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        if (bufferedDurationUs > kPrepareMarkUs || src->isFinished(/* duration */ 0)) {
331641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            ++preparedCount;
332641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        }
333641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
334641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        if (src->isFinished(/* duration */ 0)) {
335641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            ++overflowCount;
336f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            ++finishedCount;
337641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        } else {
338641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            if (bufferedDurationUs < kUnderflowMarkUs) {
339641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih                ++underflowCount;
340641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            }
341641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            if (bufferedDurationUs > kOverflowMarkUs) {
342641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih                ++overflowCount;
343641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            }
344641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            if (bufferedDurationUs < kStartServerMarkUs) {
345641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih                ++startCount;
346641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            }
347641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        }
348641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
349641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
350641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    *prepared    = (preparedCount == numTracks);
351641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    *underflow   = (underflowCount > 0);
352641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    *overflow    = (overflowCount == numTracks);
353641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    *startServer = (startCount > 0);
354f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    *finished    = (finishedCount > 0);
355641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih}
356641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
357641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::onPollBuffering() {
358f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    bool prepared, underflow, overflow, startServer, finished;
359f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    checkBuffering(&prepared, &underflow, &overflow, &startServer, &finished);
360641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
361641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (prepared && mInPreparationPhase) {
362641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        mInPreparationPhase = false;
363641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        notifyPrepared();
364641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
365641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
366641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (!mInPreparationPhase && underflow) {
367641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        startBufferingIfNecessary();
368641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
369641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
37091ea571836401ba77854d7b3aefb3ccee9c20eb3Robert Shih    if (haveSufficientDataOnAllTracks()) {
371641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        stopBufferingIfNecessary();
37291ea571836401ba77854d7b3aefb3ccee9c20eb3Robert Shih    }
37391ea571836401ba77854d7b3aefb3ccee9c20eb3Robert Shih
37491ea571836401ba77854d7b3aefb3ccee9c20eb3Robert Shih    if (overflow && mHandler != NULL) {
375641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        mHandler->pause();
376641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
377641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
378641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (startServer && mHandler != NULL) {
379641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        mHandler->resume();
380641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
381641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
382f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (finished && mHandler != NULL) {
383f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        mHandler->cancelAccessUnitTimeoutCheck();
384f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
385f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
386641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    schedulePollBuffering();
387641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih}
388641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
389f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::signalSourceEOS(status_t result) {
390f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    const bool audio = true;
391f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    const bool video = false;
392f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
393f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    sp<AnotherPacketSource> source = getSource(audio);
394f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (source != NULL) {
395f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        source->signalEOS(result);
396f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
397f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
398f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    source = getSource(video);
399f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (source != NULL) {
400f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        source->signalEOS(result);
401f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
402f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
403f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
404f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihbool NuPlayer::RTSPSource::sourceReachedEOS(bool audio) {
405f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    sp<AnotherPacketSource> source = getSource(audio);
406f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    status_t finalResult;
407f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    return (source != NULL &&
408f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            !source->hasBufferAvailable(&finalResult) &&
409f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            finalResult == ERROR_END_OF_STREAM);
410f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
411f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
412f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihbool NuPlayer::RTSPSource::sourceNearEOS(bool audio) {
413f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    sp<AnotherPacketSource> source = getSource(audio);
414f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    int64_t mediaDurationUs = 0;
415f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    getDuration(&mediaDurationUs);
416f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    return (source != NULL && source->isFinished(mediaDurationUs));
417f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
418f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
419f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::onSignalEOS(const sp<AMessage> &msg) {
420f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    int32_t generation;
421f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    CHECK(msg->findInt32("generation", &generation));
422f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
423f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (generation != mSeekGeneration) {
424f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        return;
425f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
426f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
427f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (mEOSPending) {
428f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        signalSourceEOS(ERROR_END_OF_STREAM);
429f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        mEOSPending = false;
430f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
431f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
432f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
433f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::postSourceEOSIfNecessary() {
434f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    const bool audio = true;
435f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    const bool video = false;
436f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    // If a source has detected near end, give it some time to retrieve more
437f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    // data before signaling EOS
438f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (sourceNearEOS(audio) || sourceNearEOS(video)) {
439f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        if (!mEOSPending) {
440f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            sp<AMessage> msg = new AMessage(kWhatSignalEOS, this);
441f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            msg->setInt32("generation", mSeekGeneration);
442f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            msg->post(kNearEOSTimeoutUs);
443f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            mEOSPending = true;
444f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        }
445f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
446f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
447f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
4482bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
4492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
4503f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
4512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
4522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
4542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
4552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
456ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
457ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
458ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
4598d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        CHECK(msg->senderAwaitsResponse(&mSeekReplyID));
460ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
461ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
462ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
4638d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            finishSeek(OK);
464ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            return;
465ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        }
466ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
467ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int64_t seekTimeUs;
468ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
469ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
470ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        performSeek(seekTimeUs);
471ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
472641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    } else if (msg->what() == kWhatPollBuffering) {
473641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        onPollBuffering();
474641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        return;
475f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    } else if (msg->what() == kWhatSignalEOS) {
476f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        onSignalEOS(msg);
477f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        return;
4782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
4792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
4812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int32_t what;
4832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("what", &what));
4842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    switch (what) {
4862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatConnected:
4877f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
4882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onConnected();
4897f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
490ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            notifyVideoSizeChanged();
4917f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
4927f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            uint32_t flags = 0;
4937f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
4947f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            if (mHandler->isSeekable()) {
4954b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                flags = FLAG_CAN_PAUSE
4964b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK
4974b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_BACKWARD
4984b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_FORWARD;
4997f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            }
5007f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
5017f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyFlagsChanged(flags);
502641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            schedulePollBuffering();
5032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5047f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
5052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatDisconnected:
5077f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
5082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onDisconnected(msg);
5092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5107f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
5112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDone:
5132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mState = CONNECTED;
5154ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            // Unblock seekTo here in case we attempted to seek in a live stream
5164ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            finishSeek(OK);
5178d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            break;
5188d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        }
5198d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
5208d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        case MyHandler::kWhatSeekPaused:
5218d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        {
5228d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            sp<AnotherPacketSource> source = getSource(true /* audio */);
5238d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (source != NULL) {
5248d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
5258d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* extra */ NULL,
5268d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* discard */ true);
5278d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
5288d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            source = getSource(false /* video */);
5298d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (source != NULL) {
5308d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
5318d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* extra */ NULL,
5328d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* discard */ true);
5338d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            };
5348d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
5358d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            status_t err = OK;
5368d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            msg->findInt32("err", &err);
5378d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
5388d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (err == OK) {
5398d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                int64_t timeUs;
5408d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                CHECK(msg->findInt64("time", &timeUs));
5418d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                mHandler->continueSeekAfterPause(timeUs);
5424ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            } else {
5434ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia                finishSeek(err);
5448d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
5452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
5492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
55249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
55349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser == NULL) {
55449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_LT(trackIndex, mTracks.size());
55549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            } else {
55649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_EQ(trackIndex, 0u);
55749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
5582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5592d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            sp<ABuffer> accessUnit;
5602d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
5612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
5632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
5642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
565df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
5662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
5672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
56949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
57049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                size_t offset = 0;
57149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                status_t err = OK;
57249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                while (offset + 188 <= accessUnit->size()) {
57349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = mTSParser->feedTSPacket(
57449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                            accessUnit->data() + offset, 188);
57549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (err != OK) {
57649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        break;
57749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
57849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
57949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    offset += 188;
58049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
58149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
58249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (offset < accessUnit->size()) {
58349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = ERROR_MALFORMED;
58449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
58549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
58649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (err != OK) {
587f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih                    signalSourceEOS(err);
58849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
589f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
590f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih                postSourceEOSIfNecessary();
59149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                break;
59249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
59349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5941906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5951906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
5961906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
5972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
5982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
5992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
6002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6011906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
6021906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
603c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    // playtime mapping. We won't map to npt time.
604c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    source->queueAccessUnit(accessUnit);
605c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    break;
6061906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
6071906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
6082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
6091906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
6101906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
6112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
6121906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
6132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
6152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
6172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
618f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            postSourceEOSIfNecessary();
6192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
6232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
6242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
6252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
6262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
6272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
62849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
629f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih                signalSourceEOS(finalResult);
63049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
63149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
63249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            size_t trackIndex;
63349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
63449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_LT(trackIndex, mTracks.size());
63549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
6362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
6372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
6382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
6392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
6402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
6412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
6462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
6472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
6482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
6492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
6502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
6522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
6532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
654632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                source->queueDiscontinuity(
655fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        ATSParser::DISCONTINUITY_TIME,
656632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        NULL,
657632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        true /* discard */);
6582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
6592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
6642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
6652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
6662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
6672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
6682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
6702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
6712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
6732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
6742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
6762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
6772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
6781906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
6792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
68281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        case SDPLoader::kWhatSDPLoaded:
68381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        {
68481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            onSDPLoaded(msg);
68581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            break;
68681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
68781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
6882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
6892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
6902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6932bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
6942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
6952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
6962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
6982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
6992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
7002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
7012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
7032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
7042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
70549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
70649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            // Very special case for MPEG2 Transport Streams.
70749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_EQ(numTracks, 1u);
70849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
70949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            mTSParser = new ATSParser;
71049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            return;
71149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        }
71249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
7132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
7142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
7152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
7172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
7182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
7192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
7201906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
7212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
7232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
7242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
7252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
7272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
7282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
7292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
7302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
7312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
7332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
7342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
7362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
7372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
7392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
7402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
74181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhévoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
74281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    status_t err;
74381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(msg->findInt32("result", &err));
74481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
74581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    mSDPLoader.clear();
74681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
74781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mDisconnectReplyID != 0) {
74881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        err = UNKNOWN_ERROR;
74981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
75081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
75181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err == OK) {
75281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<ASessionDescription> desc;
75381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<RefBase> obj;
75481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        CHECK(msg->findObject("description", &obj));
75581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        desc = static_cast<ASessionDescription *>(obj.get());
75681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
75781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        AString rtspUri;
75881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
75981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            ALOGE("Unable to find url in SDP");
76081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            err = UNKNOWN_ERROR;
76181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else {
7621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> notify = new AMessage(kWhatNotify, this);
76381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
76481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
76581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mLooper->registerHandler(mHandler);
76681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
76781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->loadSDP(desc);
76881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
76981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
77081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
77181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err != OK) {
7727f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        if (mState == CONNECTING) {
7737f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // We're still in the preparation phase, signal that it
7747f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // failed.
7757f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared(err);
7767f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
7777f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
77881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mState = DISCONNECTED;
779180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        setError(err);
78081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
78181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mDisconnectReplyID != 0) {
78281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            finishDisconnectIfPossible();
78381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
78481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
78581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé}
78681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
7872bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
7880ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    if (mState == DISCONNECTED) {
7890ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin        return;
7900ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    }
7910ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin
7922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
7932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
7942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
7952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
7972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
7982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7997f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    if (mState == CONNECTING) {
8007f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // We're still in the preparation phase, signal that it
8017f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // failed.
8027f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        notifyPrepared(err);
8037f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    }
8047f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
8052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
806180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    setError(err);
8072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
8082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
8092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
8102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
8112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
8122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
8132bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
8142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
81581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mHandler != NULL) {
81681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->disconnect();
81781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else if (mSDPLoader != NULL) {
81881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mSDPLoader->cancel();
81981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
8202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
8212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
8222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
8232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
8242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
8252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
8262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
827180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::setError(status_t err) {
828180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
829180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    mFinalResult = err;
830180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
831180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
832180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::startBufferingIfNecessary() {
833180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
834180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
835180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!mBuffering) {
836180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = true;
837180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
838180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
839c9ff2009a0a010eeaba80d76493fbf33fcb561c8Wei Jia        notify->setInt32("what", kWhatPauseOnBufferingStart);
840180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
841180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
842180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
843180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
844180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangbool NuPlayer::RTSPSource::stopBufferingIfNecessary() {
845180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
846180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
847180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (mBuffering) {
848180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        if (!haveSufficientDataOnAllTracks()) {
849180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang            return false;
850180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        }
851180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
852180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = false;
853180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
854180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
855c9ff2009a0a010eeaba80d76493fbf33fcb561c8Wei Jia        notify->setInt32("what", kWhatResumeOnBufferingEnd);
856180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
857180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
858180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
859180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    return true;
860180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
861180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
8628d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shihvoid NuPlayer::RTSPSource::finishSeek(status_t err) {
8634ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia    if (mSeekReplyID == NULL) {
8644ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia        return;
8654ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia    }
8668d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    sp<AMessage> seekReply = new AMessage;
8678d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    seekReply->setInt32("err", err);
8688d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    seekReply->postReply(mSeekReplyID);
8698d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    mSeekReplyID = NULL;
8708d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih}
871180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
8722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
873