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),
61cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mSeekGeneration(0),
62cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mEOSTimeoutAudio(0),
63cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mEOSTimeoutVideo(0) {
642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (headers) {
652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mExtraHeaders = *headers;
662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        ssize_t index =
682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if (index >= 0) {
712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mFlags |= kFlagIncognito;
722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.removeItemsAt(index);
742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
782bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::~RTSPSource() {
79602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    if (mLooper != NULL) {
801228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->unregisterHandler(id());
81602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber        mLooper->stop();
82602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    }
832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
8557cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::prepareAsync() {
86ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia    if (mIsSDP && mHTTPService == NULL) {
87ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia        notifyPrepared(BAD_VALUE);
88ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia        return;
89ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia    }
90ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia
912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper == NULL) {
922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper = new ALooper;
932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->setName("rtsp");
942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->start();
952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
961228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->registerHandler(this);
972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mHandler == NULL);
10081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(mSDPLoader == NULL);
1012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1021d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatNotify, this);
1032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(mState, (int)DISCONNECTED);
1052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTING;
1062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
10781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mIsSDP) {
10881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mSDPLoader = new SDPLoader(notify,
10981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé                (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0,
11081e68448f3361eaf8618930471fdc3c21bdf5cbcAndreas Huber                mHTTPService);
11181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
11257cea553cb19235553463412db5ad04c99835411Andreas Huber        mSDPLoader->load(
11357cea553cb19235553463412db5ad04c99835411Andreas Huber                mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
11481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    } else {
11581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
11681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mLooper->registerHandler(mHandler);
11781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
11881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mHandler->connect();
11981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
120cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
121180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    startBufferingIfNecessary();
12257cea553cb19235553463412db5ad04c99835411Andreas Huber}
12357cea553cb19235553463412db5ad04c99835411Andreas Huber
12457cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::start() {
1252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1272bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::stop() {
1285834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    if (mLooper == NULL) {
1295834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong        return;
1305834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    }
1311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
1322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> dummy;
1342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    msg->postAndAwaitResponse(&dummy);
1352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
138180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
1392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return mFinalResult;
1402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
142840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) {
1432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return NULL;
1472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->getFormat();
1502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
152bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {
153bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // We're going to buffer at least 2 secs worth data on all tracks before
154bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // starting playback (both at startup and after a seek).
155bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
156bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    static const int64_t kMinDurationUs = 2000000ll;
157bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
158cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    int64_t mediaDurationUs = 0;
159cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    getDuration(&mediaDurationUs);
160cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
161cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
162cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return true;
163cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
164cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
165bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    status_t err;
166bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    int64_t durationUs;
167bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mAudioTrack != NULL
168bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
169bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
170bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
171bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
172bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
173bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
174bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
175bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
176bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mVideoTrack != NULL
177bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
178bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
179bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
180bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
181bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
182bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
183bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
184bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
185bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    return true;
186bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber}
187bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
1892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
190180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!stopBufferingIfNecessary()) {
191180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        return -EWOULDBLOCK;
192bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
193bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return -EWOULDBLOCK;
1982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t finalResult;
2012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
202cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        if (finalResult == OK) {
203cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            int64_t mediaDurationUs = 0;
204cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            getDuration(&mediaDurationUs);
205cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            sp<AnotherPacketSource> otherSource = getSource(!audio);
206cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            status_t otherFinalResult;
207cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
208cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If other source already signaled EOS, this source should also signal EOS
209cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (otherSource != NULL &&
210cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    !otherSource->hasBufferAvailable(&otherFinalResult) &&
211cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    otherFinalResult == ERROR_END_OF_STREAM) {
212cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                source->signalEOS(ERROR_END_OF_STREAM);
213cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return ERROR_END_OF_STREAM;
214cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
215cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
216cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If this source has detected near end, give it some time to retrieve more
217cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // data before signaling EOS
218cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (source->isFinished(mediaDurationUs)) {
219cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
220cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                if (eosTimeout == 0) {
221cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, ALooper::GetNowUs());
222cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
223cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, 0);
224cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    source->signalEOS(ERROR_END_OF_STREAM);
225cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    return ERROR_END_OF_STREAM;
226cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                }
227cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return -EWOULDBLOCK;
228cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
229cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
230cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) {
231cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // We should not enter buffering mode
232cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // if any of the sources already have detected EOS.
233180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang                startBufferingIfNecessary();
234cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
235cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
236cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            return -EWOULDBLOCK;
237cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        }
238cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return finalResult;
2392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
241cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    setEOSTimeout(audio, 0);
242cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->dequeueAccessUnit(accessUnit);
2442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2462bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
24749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    if (mTSParser != NULL) {
24849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        sp<MediaSource> source = mTSParser->getSource(
24949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
25049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
25149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        return static_cast<AnotherPacketSource *>(source.get());
25249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    }
25349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
2542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return audio ? mAudioTrack : mVideoTrack;
2552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
257cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonvoid NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) {
258cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if (audio) {
259cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutAudio = timeout;
260cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    } else {
261cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutVideo = timeout;
262cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
263cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson}
264cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
2662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    *durationUs = 0ll;
2672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t audioDurationUs;
2692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mAudioTrack != NULL
2702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mAudioTrack->getFormat()->findInt64(
2712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &audioDurationUs)
2722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && audioDurationUs > *durationUs) {
2732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = audioDurationUs;
2742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t videoDurationUs;
2772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mVideoTrack != NULL
2782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mVideoTrack->getFormat()->findInt64(
2792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &videoDurationUs)
2802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && videoDurationUs > *durationUs) {
2812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = videoDurationUs;
2822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return OK;
2852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
2881d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
289ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
290ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
291ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
2928d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    sp<AMessage> response;
2938d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
2948d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    if (err == OK && response != NULL) {
2958d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        CHECK(response->findInt32("err", &err));
2968d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    }
2978d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
2988d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    return err;
299ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber}
300ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
301ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
3022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != CONNECTED) {
3038d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        finishSeek(INVALID_OPERATION);
304ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = SEEKING;
3082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->seek(seekTimeUs);
3092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
311641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::schedulePollBuffering() {
312641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
313641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    msg->post(1000000ll); // 1 second intervals
314641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih}
315641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
316641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::checkBuffering(
317641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        bool *prepared, bool *underflow, bool *overflow, bool *startServer) {
318641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    size_t numTracks = mTracks.size();
319641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    size_t preparedCount, underflowCount, overflowCount, startCount;
320641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    preparedCount = underflowCount = overflowCount = startCount = 0;
321641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    for (size_t i = 0; i < numTracks; ++i) {
322641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        status_t finalResult;
323641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        TrackInfo *info = &mTracks.editItemAt(i);
324641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        sp<AnotherPacketSource> src = info->mSource;
325641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        int64_t bufferedDurationUs = src->getBufferedDurationUs(&finalResult);
326641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
327641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        // isFinished when duration is 0 checks for EOS result only
328641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        if (bufferedDurationUs > kPrepareMarkUs || src->isFinished(/* duration */ 0)) {
329641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            ++preparedCount;
330641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        }
331641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
332641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        if (src->isFinished(/* duration */ 0)) {
333641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            ++overflowCount;
334641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        } else {
335641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            if (bufferedDurationUs < kUnderflowMarkUs) {
336641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih                ++underflowCount;
337641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            }
338641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            if (bufferedDurationUs > kOverflowMarkUs) {
339641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih                ++overflowCount;
340641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            }
341641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            if (bufferedDurationUs < kStartServerMarkUs) {
342641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih                ++startCount;
343641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            }
344641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        }
345641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
346641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
347641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    *prepared    = (preparedCount == numTracks);
348641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    *underflow   = (underflowCount > 0);
349641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    *overflow    = (overflowCount == numTracks);
350641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    *startServer = (startCount > 0);
351641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih}
352641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
353641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::onPollBuffering() {
354641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    bool prepared, underflow, overflow, startServer;
355641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    checkBuffering(&prepared, &underflow, &overflow, &startServer);
356641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
357641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (prepared && mInPreparationPhase) {
358641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        mInPreparationPhase = false;
359641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        notifyPrepared();
360641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
361641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
362641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (!mInPreparationPhase && underflow) {
363641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        startBufferingIfNecessary();
364641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
365641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
366641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (overflow && mHandler != NULL) {
367641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        stopBufferingIfNecessary();
368641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        mHandler->pause();
369641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
370641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
371641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (startServer && mHandler != NULL) {
372641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        mHandler->resume();
373641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
374641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
375641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    schedulePollBuffering();
376641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih}
377641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
3782bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
3792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
3803f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
3812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
3822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
3842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
3852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
386ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
387ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
388ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
3898d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        CHECK(msg->senderAwaitsResponse(&mSeekReplyID));
390ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
391ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
392ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
3938d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            finishSeek(OK);
394ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            return;
395ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        }
396ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
397ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int64_t seekTimeUs;
398ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
399ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
400ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        performSeek(seekTimeUs);
401ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
402641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    } else if (msg->what() == kWhatPollBuffering) {
403641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        onPollBuffering();
404641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        return;
4052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
4062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
4082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int32_t what;
4102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("what", &what));
4112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    switch (what) {
4132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatConnected:
4147f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
4152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onConnected();
4167f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
417ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            notifyVideoSizeChanged();
4187f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
4197f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            uint32_t flags = 0;
4207f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
4217f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            if (mHandler->isSeekable()) {
4224b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                flags = FLAG_CAN_PAUSE
4234b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK
4244b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_BACKWARD
4254b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_FORWARD;
4267f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            }
4277f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
4287f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyFlagsChanged(flags);
429641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            schedulePollBuffering();
4302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4317f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
4322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatDisconnected:
4347f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
4352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onDisconnected(msg);
4362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4377f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
4382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDone:
4402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mState = CONNECTED;
4424ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            // Unblock seekTo here in case we attempted to seek in a live stream
4434ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            finishSeek(OK);
4448d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            break;
4458d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        }
4468d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
4478d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        case MyHandler::kWhatSeekPaused:
4488d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        {
4498d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            sp<AnotherPacketSource> source = getSource(true /* audio */);
4508d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (source != NULL) {
4518d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
4528d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* extra */ NULL,
4538d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* discard */ true);
4548d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
4558d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            source = getSource(false /* video */);
4568d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (source != NULL) {
4578d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
4588d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* extra */ NULL,
4598d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* discard */ true);
4608d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            };
4618d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
4628d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            status_t err = OK;
4638d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            msg->findInt32("err", &err);
4648d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
4658d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (err == OK) {
4668d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                int64_t timeUs;
4678d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                CHECK(msg->findInt64("time", &timeUs));
4688d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                mHandler->continueSeekAfterPause(timeUs);
4694ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            } else {
4704ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia                finishSeek(err);
4718d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
4722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
4762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
4782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
47949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
48049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser == NULL) {
48149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_LT(trackIndex, mTracks.size());
48249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            } else {
48349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_EQ(trackIndex, 0u);
48449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
4852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4862d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            sp<ABuffer> accessUnit;
4872d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
4882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
4902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
4912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
492df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
4932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
4942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
49649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
49749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                size_t offset = 0;
49849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                status_t err = OK;
49949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                while (offset + 188 <= accessUnit->size()) {
50049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = mTSParser->feedTSPacket(
50149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                            accessUnit->data() + offset, 188);
50249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (err != OK) {
50349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        break;
50449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
50549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
50649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    offset += 188;
50749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
50849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
50949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (offset < accessUnit->size()) {
51049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = ERROR_MALFORMED;
51149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
51249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
51349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (err != OK) {
51449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    sp<AnotherPacketSource> source = getSource(false /* audio */);
51549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
51649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
51749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
51849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
51949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source = getSource(true /* audio */);
52049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
52149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
52249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
52349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
52449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                break;
52549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
52649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5271906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5281906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
5291906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
5302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
5312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
5322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
5332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5341906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
5351906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
536c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    // playtime mapping. We won't map to npt time.
537c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    source->queueAccessUnit(accessUnit);
538c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    break;
5391906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
5401906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
5412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
5421906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
5431906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
5442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
5451906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
5462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
5482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
5502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
5552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
5572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
5582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
5592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
56049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
56149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                sp<AnotherPacketSource> source = getSource(false /* audio */);
56249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
56349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
56449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
56549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
56649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                source = getSource(true /* audio */);
56749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
56849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
56949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
57049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
57149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                return;
57249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
57349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
57449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            size_t trackIndex;
57549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
57649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_LT(trackIndex, mTracks.size());
57749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
5802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
5812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
5822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
5882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
5912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
5922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
5952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
596632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                source->queueDiscontinuity(
597fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        ATSParser::DISCONTINUITY_TIME,
598632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        NULL,
599632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        true /* discard */);
6002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
6012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
6062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
6072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
6082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
6092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
6102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
6122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
6132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
6152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
6162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
6182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
6192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
6201906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
6212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
62481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        case SDPLoader::kWhatSDPLoaded:
62581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        {
62681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            onSDPLoaded(msg);
62781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            break;
62881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
62981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
6302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
6312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
6322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6352bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
6362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
6372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
6382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
6402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
6412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
6422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
6432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
6452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
6462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
64749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
64849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            // Very special case for MPEG2 Transport Streams.
64949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_EQ(numTracks, 1u);
65049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
65149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            mTSParser = new ATSParser;
65249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            return;
65349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        }
65449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
6552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
6562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
6572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
6592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
6602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
6612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
6621906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
6632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
6652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
6662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
6672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
6692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
6702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
6712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
6722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
6732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
6752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
6782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
6812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
68381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhévoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
68481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    status_t err;
68581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(msg->findInt32("result", &err));
68681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
68781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    mSDPLoader.clear();
68881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
68981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mDisconnectReplyID != 0) {
69081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        err = UNKNOWN_ERROR;
69181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
69281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
69381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err == OK) {
69481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<ASessionDescription> desc;
69581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<RefBase> obj;
69681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        CHECK(msg->findObject("description", &obj));
69781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        desc = static_cast<ASessionDescription *>(obj.get());
69881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
69981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        AString rtspUri;
70081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
70181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            ALOGE("Unable to find url in SDP");
70281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            err = UNKNOWN_ERROR;
70381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else {
7041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> notify = new AMessage(kWhatNotify, this);
70581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
70681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
70781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mLooper->registerHandler(mHandler);
70881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
70981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->loadSDP(desc);
71081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
71181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
71281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
71381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err != OK) {
7147f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        if (mState == CONNECTING) {
7157f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // We're still in the preparation phase, signal that it
7167f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // failed.
7177f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared(err);
7187f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
7197f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
72081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mState = DISCONNECTED;
721180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        setError(err);
72281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
72381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mDisconnectReplyID != 0) {
72481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            finishDisconnectIfPossible();
72581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
72681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
72781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé}
72881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
7292bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
7300ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    if (mState == DISCONNECTED) {
7310ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin        return;
7320ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    }
7330ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin
7342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
7352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
7362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
7372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
7392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
7402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7417f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    if (mState == CONNECTING) {
7427f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // We're still in the preparation phase, signal that it
7437f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // failed.
7447f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        notifyPrepared(err);
7457f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    }
7467f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
7472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
748180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    setError(err);
7492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
7512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
7522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
7532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
7542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7552bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
7562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
75781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mHandler != NULL) {
75881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->disconnect();
75981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else if (mSDPLoader != NULL) {
76081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mSDPLoader->cancel();
76181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
7622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
7632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
7642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
7662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
7672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
7682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
769180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::setError(status_t err) {
770180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
771180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    mFinalResult = err;
772180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
773180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
774180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::startBufferingIfNecessary() {
775180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
776180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
777180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!mBuffering) {
778180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = true;
779180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
780180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
781c9ff2009a0a010eeaba80d76493fbf33fcb561c8Wei Jia        notify->setInt32("what", kWhatPauseOnBufferingStart);
782180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
783180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
784180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
785180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
786180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangbool NuPlayer::RTSPSource::stopBufferingIfNecessary() {
787180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
788180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
789180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (mBuffering) {
790180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        if (!haveSufficientDataOnAllTracks()) {
791180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang            return false;
792180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        }
793180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
794180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = false;
795180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
796180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
797c9ff2009a0a010eeaba80d76493fbf33fcb561c8Wei Jia        notify->setInt32("what", kWhatResumeOnBufferingEnd);
798180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
799180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
800180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
801180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    return true;
802180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
803180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
8048d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shihvoid NuPlayer::RTSPSource::finishSeek(status_t err) {
8054ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia    if (mSeekReplyID == NULL) {
8064ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia        return;
8074ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia    }
8088d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    sp<AMessage> seekReply = new AMessage;
8098d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    seekReply->setInt32("err", err);
8108d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    seekReply->postReply(mSeekReplyID);
8118d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    mSeekReplyID = NULL;
8128d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih}
813180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
8142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
815