RTSPSource.cpp revision f1d261f1b5914ddc219a23b763ab19363eeedd85
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) {
2612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    *durationUs = 0ll;
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
370641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (overflow && mHandler != NULL) {
371641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        stopBufferingIfNecessary();
372641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        mHandler->pause();
373641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
374641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
375641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    if (startServer && mHandler != NULL) {
376641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        mHandler->resume();
377641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    }
378641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
379f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (finished && mHandler != NULL) {
380f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        mHandler->cancelAccessUnitTimeoutCheck();
381f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
382f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
383641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    schedulePollBuffering();
384641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih}
385641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih
386f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::signalSourceEOS(status_t result) {
387f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    const bool audio = true;
388f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    const bool video = false;
389f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
390f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    sp<AnotherPacketSource> source = getSource(audio);
391f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (source != NULL) {
392f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        source->signalEOS(result);
393f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
394f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
395f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    source = getSource(video);
396f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (source != NULL) {
397f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        source->signalEOS(result);
398f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
399f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
400f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
401f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihbool NuPlayer::RTSPSource::sourceReachedEOS(bool audio) {
402f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    sp<AnotherPacketSource> source = getSource(audio);
403f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    status_t finalResult;
404f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    return (source != NULL &&
405f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            !source->hasBufferAvailable(&finalResult) &&
406f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            finalResult == ERROR_END_OF_STREAM);
407f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
408f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
409f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihbool NuPlayer::RTSPSource::sourceNearEOS(bool audio) {
410f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    sp<AnotherPacketSource> source = getSource(audio);
411f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    int64_t mediaDurationUs = 0;
412f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    getDuration(&mediaDurationUs);
413f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    return (source != NULL && source->isFinished(mediaDurationUs));
414f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
415f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
416f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::onSignalEOS(const sp<AMessage> &msg) {
417f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    int32_t generation;
418f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    CHECK(msg->findInt32("generation", &generation));
419f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
420f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (generation != mSeekGeneration) {
421f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        return;
422f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
423f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
424f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (mEOSPending) {
425f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        signalSourceEOS(ERROR_END_OF_STREAM);
426f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        mEOSPending = false;
427f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
428f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
429f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
430f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::postSourceEOSIfNecessary() {
431f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    const bool audio = true;
432f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    const bool video = false;
433f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    // If a source has detected near end, give it some time to retrieve more
434f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    // data before signaling EOS
435f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    if (sourceNearEOS(audio) || sourceNearEOS(video)) {
436f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        if (!mEOSPending) {
437f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            sp<AMessage> msg = new AMessage(kWhatSignalEOS, this);
438f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            msg->setInt32("generation", mSeekGeneration);
439f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            msg->post(kNearEOSTimeoutUs);
440f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            mEOSPending = true;
441f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        }
442f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    }
443f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih}
444f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
4452bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
4462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
4473f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
4482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
4492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
4512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
4522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
453ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
454ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
455ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
4568d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        CHECK(msg->senderAwaitsResponse(&mSeekReplyID));
457ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
458ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
459ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
4608d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            finishSeek(OK);
461ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            return;
462ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        }
463ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
464ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int64_t seekTimeUs;
465ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
466ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
467ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        performSeek(seekTimeUs);
468ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
469641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih    } else if (msg->what() == kWhatPollBuffering) {
470641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        onPollBuffering();
471641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih        return;
472f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih    } else if (msg->what() == kWhatSignalEOS) {
473f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        onSignalEOS(msg);
474f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih        return;
4752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
4762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
4782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int32_t what;
4802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("what", &what));
4812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    switch (what) {
4832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatConnected:
4847f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
4852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onConnected();
4867f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
487ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            notifyVideoSizeChanged();
4887f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
4897f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            uint32_t flags = 0;
4907f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
4917f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            if (mHandler->isSeekable()) {
4924b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                flags = FLAG_CAN_PAUSE
4934b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK
4944b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_BACKWARD
4954b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_FORWARD;
4967f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            }
4977f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
4987f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyFlagsChanged(flags);
499641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih            schedulePollBuffering();
5002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5017f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
5022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatDisconnected:
5047f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
5052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onDisconnected(msg);
5062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5077f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
5082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDone:
5102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mState = CONNECTED;
5124ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            // Unblock seekTo here in case we attempted to seek in a live stream
5134ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            finishSeek(OK);
5148d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            break;
5158d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        }
5168d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
5178d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        case MyHandler::kWhatSeekPaused:
5188d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        {
5198d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            sp<AnotherPacketSource> source = getSource(true /* audio */);
5208d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (source != NULL) {
5218d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
5228d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* extra */ NULL,
5238d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* discard */ true);
5248d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
5258d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            source = getSource(false /* video */);
5268d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (source != NULL) {
5278d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
5288d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* extra */ NULL,
5298d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* discard */ true);
5308d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            };
5318d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
5328d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            status_t err = OK;
5338d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            msg->findInt32("err", &err);
5348d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
5358d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (err == OK) {
5368d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                int64_t timeUs;
5378d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                CHECK(msg->findInt64("time", &timeUs));
5388d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                mHandler->continueSeekAfterPause(timeUs);
5394ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia            } else {
5404ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia                finishSeek(err);
5418d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
5422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
5462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
54949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
55049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser == NULL) {
55149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_LT(trackIndex, mTracks.size());
55249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            } else {
55349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_EQ(trackIndex, 0u);
55449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
5552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5562d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            sp<ABuffer> accessUnit;
5572d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
5582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
5602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
5612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
562df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
5632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
5642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
56649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
56749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                size_t offset = 0;
56849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                status_t err = OK;
56949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                while (offset + 188 <= accessUnit->size()) {
57049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = mTSParser->feedTSPacket(
57149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                            accessUnit->data() + offset, 188);
57249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (err != OK) {
57349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        break;
57449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
57549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
57649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    offset += 188;
57749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
57849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
57949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (offset < accessUnit->size()) {
58049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = ERROR_MALFORMED;
58149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
58249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
58349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (err != OK) {
584f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih                    signalSourceEOS(err);
58549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
586f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih
587f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih                postSourceEOSIfNecessary();
58849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                break;
58949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
59049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5911906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5921906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
5931906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
5942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
5952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
5962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
5972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5981906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
5991906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
600c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    // playtime mapping. We won't map to npt time.
601c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    source->queueAccessUnit(accessUnit);
602c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    break;
6031906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
6041906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
6052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
6061906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
6071906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
6082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
6091906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
6102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
6122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
6142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
615f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih            postSourceEOSIfNecessary();
6162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
6202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
6212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
6222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
6232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
6242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
62549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
626f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih                signalSourceEOS(finalResult);
62749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
62849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
62949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            size_t trackIndex;
63049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
63149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_LT(trackIndex, mTracks.size());
63249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
6332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
6342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
6352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
6362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
6372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
6382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
6432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
6442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
6452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
6462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
6472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
6492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
6502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
651632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                source->queueDiscontinuity(
652fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        ATSParser::DISCONTINUITY_TIME,
653632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        NULL,
654632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        true /* discard */);
6552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
6562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
6612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
6622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
6632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
6642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
6652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
6672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
6682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
6702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
6712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
6732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
6742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
6751906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
6762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
6772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
67981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        case SDPLoader::kWhatSDPLoaded:
68081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        {
68181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            onSDPLoaded(msg);
68281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            break;
68381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
68481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
6852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
6862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
6872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6902bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
6912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
6922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
6932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
6952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
6962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
6972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
6982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
7002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
7012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
70249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
70349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            // Very special case for MPEG2 Transport Streams.
70449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_EQ(numTracks, 1u);
70549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
70649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            mTSParser = new ATSParser;
70749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            return;
70849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        }
70949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
7102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
7112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
7122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
7142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
7152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
7162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
7171906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
7182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
7202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
7212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
7222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
7242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
7252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
7262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
7272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
7282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
7302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
7312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
7332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
7342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
7362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
7372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
73881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhévoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
73981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    status_t err;
74081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(msg->findInt32("result", &err));
74181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
74281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    mSDPLoader.clear();
74381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
74481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mDisconnectReplyID != 0) {
74581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        err = UNKNOWN_ERROR;
74681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
74781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
74881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err == OK) {
74981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<ASessionDescription> desc;
75081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<RefBase> obj;
75181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        CHECK(msg->findObject("description", &obj));
75281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        desc = static_cast<ASessionDescription *>(obj.get());
75381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
75481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        AString rtspUri;
75581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
75681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            ALOGE("Unable to find url in SDP");
75781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            err = UNKNOWN_ERROR;
75881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else {
7591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> notify = new AMessage(kWhatNotify, this);
76081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
76181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
76281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mLooper->registerHandler(mHandler);
76381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
76481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->loadSDP(desc);
76581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
76681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
76781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
76881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err != OK) {
7697f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        if (mState == CONNECTING) {
7707f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // We're still in the preparation phase, signal that it
7717f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // failed.
7727f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared(err);
7737f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
7747f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
77581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mState = DISCONNECTED;
776180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        setError(err);
77781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
77881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mDisconnectReplyID != 0) {
77981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            finishDisconnectIfPossible();
78081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
78181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
78281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé}
78381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
7842bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
7850ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    if (mState == DISCONNECTED) {
7860ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin        return;
7870ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    }
7880ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin
7892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
7902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
7912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
7922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
7942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
7952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7967f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    if (mState == CONNECTING) {
7977f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // We're still in the preparation phase, signal that it
7987f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // failed.
7997f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        notifyPrepared(err);
8007f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    }
8017f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
8022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
803180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    setError(err);
8042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
8052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
8062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
8072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
8082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
8092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
8102bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
8112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
81281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mHandler != NULL) {
81381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->disconnect();
81481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else if (mSDPLoader != NULL) {
81581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mSDPLoader->cancel();
81681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
8172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
8182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
8192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
8202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
8212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
8222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
8232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
824180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::setError(status_t err) {
825180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
826180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    mFinalResult = err;
827180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
828180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
829180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::startBufferingIfNecessary() {
830180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
831180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
832180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!mBuffering) {
833180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = true;
834180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
835180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
836c9ff2009a0a010eeaba80d76493fbf33fcb561c8Wei Jia        notify->setInt32("what", kWhatPauseOnBufferingStart);
837180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
838180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
839180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
840180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
841180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangbool NuPlayer::RTSPSource::stopBufferingIfNecessary() {
842180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
843180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
844180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (mBuffering) {
845180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        if (!haveSufficientDataOnAllTracks()) {
846180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang            return false;
847180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        }
848180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
849180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = false;
850180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
851180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
852c9ff2009a0a010eeaba80d76493fbf33fcb561c8Wei Jia        notify->setInt32("what", kWhatResumeOnBufferingEnd);
853180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
854180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
855180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
856180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    return true;
857180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
858180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
8598d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shihvoid NuPlayer::RTSPSource::finishSeek(status_t err) {
8604ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia    if (mSeekReplyID == NULL) {
8614ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia        return;
8624ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia    }
8638d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    sp<AMessage> seekReply = new AMessage;
8648d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    seekReply->setInt32("err", err);
8658d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    seekReply->postReply(mSeekReplyID);
8668d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    mSeekReplyID = NULL;
8678d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih}
868180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
8692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
870