RTSPSource.cpp revision 8d237a5ce1e3c1dbc1d538f47e68cff2cc52d799
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
352bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::RTSPSource(
365ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber        const sp<AMessage> &notify,
371b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const sp<IMediaHTTPService> &httpService,
382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *url,
392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const KeyedVector<String8, String8> *headers,
402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool uidValid,
4181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        uid_t uid,
4281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        bool isSDP)
435ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber    : Source(notify),
441b86fe063badb5f28c467ade39be0f4008688947Andreas Huber      mHTTPService(httpService),
455ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber      mURL(url),
462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mUIDValid(uidValid),
472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mUID(uid),
482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mFlags(0),
4981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé      mIsSDP(isSDP),
502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mState(DISCONNECTED),
512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mFinalResult(OK),
52ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber      mDisconnectReplyID(0),
53180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang      mBuffering(false),
54cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mSeekGeneration(0),
55cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mEOSTimeoutAudio(0),
56cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mEOSTimeoutVideo(0) {
572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (headers) {
582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mExtraHeaders = *headers;
592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        ssize_t index =
612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if (index >= 0) {
642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mFlags |= kFlagIncognito;
652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.removeItemsAt(index);
672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
712bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::~RTSPSource() {
72602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    if (mLooper != NULL) {
731228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->unregisterHandler(id());
74602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber        mLooper->stop();
75602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    }
762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7857cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::prepareAsync() {
792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper == NULL) {
802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper = new ALooper;
812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->setName("rtsp");
822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->start();
832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
841228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang        mLooper->registerHandler(this);
852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mHandler == NULL);
8881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(mSDPLoader == NULL);
892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatNotify, this);
912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(mState, (int)DISCONNECTED);
932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTING;
942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
9581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mIsSDP) {
9681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mSDPLoader = new SDPLoader(notify,
9781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé                (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0,
9881e68448f3361eaf8618930471fdc3c21bdf5cbcAndreas Huber                mHTTPService);
9981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
10057cea553cb19235553463412db5ad04c99835411Andreas Huber        mSDPLoader->load(
10157cea553cb19235553463412db5ad04c99835411Andreas Huber                mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
10281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    } else {
10381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
10481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mLooper->registerHandler(mHandler);
10581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
10681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mHandler->connect();
10781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
108cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
109180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    startBufferingIfNecessary();
11057cea553cb19235553463412db5ad04c99835411Andreas Huber}
11157cea553cb19235553463412db5ad04c99835411Andreas Huber
11257cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::start() {
1132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1152bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::stop() {
1165834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    if (mLooper == NULL) {
1175834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong        return;
1185834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    }
1191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
1202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> dummy;
1222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    msg->postAndAwaitResponse(&dummy);
1232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
12546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönssonvoid NuPlayer::RTSPSource::pause() {
12646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    int64_t mediaDurationUs = 0;
12746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    getDuration(&mediaDurationUs);
12846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    for (size_t index = 0; index < mTracks.size(); index++) {
12946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        TrackInfo *info = &mTracks.editItemAt(index);
13046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        sp<AnotherPacketSource> source = info->mSource;
13146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
13246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        // Check if EOS or ERROR is received
13346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        if (source != NULL && source->isFinished(mediaDurationUs)) {
13446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson            return;
13546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        }
13646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    }
13746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    mHandler->pause();
13846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson}
13946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
14046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönssonvoid NuPlayer::RTSPSource::resume() {
1418d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    if (mHandler != NULL) {
1428d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        mHandler->resume();
1438d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    }
14446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson}
14546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
1462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
147180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return mFinalResult;
1492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
151840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) {
1522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return NULL;
1562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->getFormat();
1592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
161bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {
162bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // We're going to buffer at least 2 secs worth data on all tracks before
163bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // starting playback (both at startup and after a seek).
164bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
165bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    static const int64_t kMinDurationUs = 2000000ll;
166bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
167cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    int64_t mediaDurationUs = 0;
168cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    getDuration(&mediaDurationUs);
169cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
170cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
171cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return true;
172cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
173cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
174bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    status_t err;
175bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    int64_t durationUs;
176bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mAudioTrack != NULL
177bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
178bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
179bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
180bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
181bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
182bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
183bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
184bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
185bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mVideoTrack != NULL
186bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
187bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
188bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
189bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
190bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
191bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
192bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
193bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
194bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    return true;
195bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber}
196bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
1982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
199180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!stopBufferingIfNecessary()) {
200180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        return -EWOULDBLOCK;
201bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
202bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
2032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
2042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
2062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return -EWOULDBLOCK;
2072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t finalResult;
2102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
211cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        if (finalResult == OK) {
212cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            int64_t mediaDurationUs = 0;
213cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            getDuration(&mediaDurationUs);
214cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            sp<AnotherPacketSource> otherSource = getSource(!audio);
215cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            status_t otherFinalResult;
216cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
217cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If other source already signaled EOS, this source should also signal EOS
218cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (otherSource != NULL &&
219cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    !otherSource->hasBufferAvailable(&otherFinalResult) &&
220cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    otherFinalResult == ERROR_END_OF_STREAM) {
221cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                source->signalEOS(ERROR_END_OF_STREAM);
222cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return ERROR_END_OF_STREAM;
223cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
224cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
225cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If this source has detected near end, give it some time to retrieve more
226cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // data before signaling EOS
227cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (source->isFinished(mediaDurationUs)) {
228cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
229cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                if (eosTimeout == 0) {
230cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, ALooper::GetNowUs());
231cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
232cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, 0);
233cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    source->signalEOS(ERROR_END_OF_STREAM);
234cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    return ERROR_END_OF_STREAM;
235cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                }
236cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return -EWOULDBLOCK;
237cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
238cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
239cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) {
240cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // We should not enter buffering mode
241cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // if any of the sources already have detected EOS.
242180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang                startBufferingIfNecessary();
243cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
244cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
245cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            return -EWOULDBLOCK;
246cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        }
247cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return finalResult;
2482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
250cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    setEOSTimeout(audio, 0);
251cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->dequeueAccessUnit(accessUnit);
2532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2552bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
25649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    if (mTSParser != NULL) {
25749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        sp<MediaSource> source = mTSParser->getSource(
25849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
25949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
26049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        return static_cast<AnotherPacketSource *>(source.get());
26149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    }
26249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
2632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return audio ? mAudioTrack : mVideoTrack;
2642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
266cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonvoid NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) {
267cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if (audio) {
268cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutAudio = timeout;
269cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    } else {
270cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutVideo = timeout;
271cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
272cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson}
273cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
2752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    *durationUs = 0ll;
2762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t audioDurationUs;
2782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mAudioTrack != NULL
2792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mAudioTrack->getFormat()->findInt64(
2802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &audioDurationUs)
2812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && audioDurationUs > *durationUs) {
2822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = audioDurationUs;
2832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t videoDurationUs;
2862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mVideoTrack != NULL
2872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mVideoTrack->getFormat()->findInt64(
2882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &videoDurationUs)
2892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && videoDurationUs > *durationUs) {
2902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = videoDurationUs;
2912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return OK;
2942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
2971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
298ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
299ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
300ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
3018d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    sp<AMessage> response;
3028d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    status_t err = msg->postAndAwaitResponse(&response);
3038d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    if (err == OK && response != NULL) {
3048d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        CHECK(response->findInt32("err", &err));
3058d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    }
3068d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
3078d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    return err;
308ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber}
309ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
310ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
3112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != CONNECTED) {
3128d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        finishSeek(INVALID_OPERATION);
313ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = SEEKING;
3172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->seek(seekTimeUs);
3182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3202bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
3212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
3223f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
3232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
3242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
3262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
3272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
328ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
329ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
330ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
3318d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        CHECK(msg->senderAwaitsResponse(&mSeekReplyID));
332ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
333ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
334ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
3358d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            finishSeek(OK);
336ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            return;
337ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        }
338ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
339ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int64_t seekTimeUs;
340ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
341ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
342ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        performSeek(seekTimeUs);
343ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
3472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int32_t what;
3492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("what", &what));
3502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    switch (what) {
3522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatConnected:
3537f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
3542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onConnected();
3557f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
356ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            notifyVideoSizeChanged();
3577f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3587f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            uint32_t flags = 0;
3597f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3607f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            if (mHandler->isSeekable()) {
3614b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                flags = FLAG_CAN_PAUSE
3624b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK
3634b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_BACKWARD
3644b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_FORWARD;
3657f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            }
3667f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3677f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyFlagsChanged(flags);
3687f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared();
3692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3707f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
3712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatDisconnected:
3737f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
3742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onDisconnected(msg);
3752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3767f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
3772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDone:
3792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mState = CONNECTED;
3818d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (mSeekReplyID != NULL) {
3828d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                // Unblock seekTo here in case we attempted to seek in a live stream
3838d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                finishSeek(OK);
3848d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
3858d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            break;
3868d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        }
3878d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
3888d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        case MyHandler::kWhatSeekPaused:
3898d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih        {
3908d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            sp<AnotherPacketSource> source = getSource(true /* audio */);
3918d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (source != NULL) {
3928d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
3938d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* extra */ NULL,
3948d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* discard */ true);
3958d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
3968d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            source = getSource(false /* video */);
3978d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (source != NULL) {
3988d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE,
3998d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* extra */ NULL,
4008d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                        /* discard */ true);
4018d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            };
4028d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
4038d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            status_t err = OK;
4048d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            msg->findInt32("err", &err);
4058d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            finishSeek(err);
4068d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih
4078d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            if (err == OK) {
4088d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                int64_t timeUs;
4098d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                CHECK(msg->findInt64("time", &timeUs));
4108d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih                mHandler->continueSeekAfterPause(timeUs);
4118d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih            }
4122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
4162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
4182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
41949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
42049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser == NULL) {
42149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_LT(trackIndex, mTracks.size());
42249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            } else {
42349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_EQ(trackIndex, 0u);
42449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
4252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4262d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            sp<ABuffer> accessUnit;
4272d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
4282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
4302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
4312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
432df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
4332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
4342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
43649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
43749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                size_t offset = 0;
43849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                status_t err = OK;
43949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                while (offset + 188 <= accessUnit->size()) {
44049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = mTSParser->feedTSPacket(
44149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                            accessUnit->data() + offset, 188);
44249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (err != OK) {
44349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        break;
44449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
44549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
44649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    offset += 188;
44749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
44849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
44949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (offset < accessUnit->size()) {
45049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = ERROR_MALFORMED;
45149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
45249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
45349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (err != OK) {
45449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    sp<AnotherPacketSource> source = getSource(false /* audio */);
45549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
45649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
45749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
45849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
45949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source = getSource(true /* audio */);
46049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
46149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
46249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
46349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
46449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                break;
46549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
46649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
4671906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4681906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
4691906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
4702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
4712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
4722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
4732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4741906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
4751906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
476c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    // playtime mapping. We won't map to npt time.
477c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    source->queueAccessUnit(accessUnit);
478c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    break;
4791906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
4801906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
4812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
4821906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
4831906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
4842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
4851906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
4862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
4882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
4902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
4952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
4972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
4982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
4992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
50049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
50149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                sp<AnotherPacketSource> source = getSource(false /* audio */);
50249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
50349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
50449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
50549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
50649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                source = getSource(true /* audio */);
50749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
50849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
50949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
51049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
51149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                return;
51249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
51349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
51449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            size_t trackIndex;
51549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
51649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_LT(trackIndex, mTracks.size());
51749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
5202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
5212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
5222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
5282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
5312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
5322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
5352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
536632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                source->queueDiscontinuity(
537fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        ATSParser::DISCONTINUITY_TIME,
538632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        NULL,
539632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        true /* discard */);
5402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
5462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
5492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
5502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
5522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
5532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
5552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
5562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
5592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
5601906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
5612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
56481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        case SDPLoader::kWhatSDPLoaded:
56581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        {
56681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            onSDPLoaded(msg);
56781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            break;
56881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
56981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
5702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
5712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
5722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
5732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
5742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5752bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
5762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
5772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
5782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
5802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
5812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
5822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
5832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
5852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
5862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
58749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
58849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            // Very special case for MPEG2 Transport Streams.
58949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_EQ(numTracks, 1u);
59049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
59149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            mTSParser = new ATSParser;
59249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            return;
59349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        }
59449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
5962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
5972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
5992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
6002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
6012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
6021906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
6032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
6052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
6062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
6072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
6092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
6102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
6112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
6122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
6132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
6152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
6162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
6182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
6212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
62381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhévoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
62481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    status_t err;
62581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(msg->findInt32("result", &err));
62681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
62781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    mSDPLoader.clear();
62881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
62981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mDisconnectReplyID != 0) {
63081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        err = UNKNOWN_ERROR;
63181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
63281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
63381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err == OK) {
63481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<ASessionDescription> desc;
63581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<RefBase> obj;
63681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        CHECK(msg->findObject("description", &obj));
63781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        desc = static_cast<ASessionDescription *>(obj.get());
63881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
63981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        AString rtspUri;
64081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
64181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            ALOGE("Unable to find url in SDP");
64281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            err = UNKNOWN_ERROR;
64381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else {
6441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> notify = new AMessage(kWhatNotify, this);
64581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
64681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
64781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mLooper->registerHandler(mHandler);
64881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
64981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->loadSDP(desc);
65081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
65181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
65281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
65381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err != OK) {
6547f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        if (mState == CONNECTING) {
6557f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // We're still in the preparation phase, signal that it
6567f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // failed.
6577f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared(err);
6587f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
6597f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
66081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mState = DISCONNECTED;
661180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        setError(err);
66281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
66381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mDisconnectReplyID != 0) {
66481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            finishDisconnectIfPossible();
66581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
66681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
66781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé}
66881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
6692bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
6700ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    if (mState == DISCONNECTED) {
6710ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin        return;
6720ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    }
6730ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin
6742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
6752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
6762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
6772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
6792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
6802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6817f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    if (mState == CONNECTING) {
6827f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // We're still in the preparation phase, signal that it
6837f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // failed.
6847f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        notifyPrepared(err);
6857f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    }
6867f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
6872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
688180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    setError(err);
6892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
6912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
6922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6952bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
6962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
69781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mHandler != NULL) {
69881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->disconnect();
69981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else if (mSDPLoader != NULL) {
70081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mSDPLoader->cancel();
70181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
7022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
7032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
7042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
7062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
7072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
7082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
709180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::setError(status_t err) {
710180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
711180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    mFinalResult = err;
712180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
713180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
714180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::startBufferingIfNecessary() {
715180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
716180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
717180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!mBuffering) {
718180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = true;
719180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
720180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
721180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->setInt32("what", kWhatBufferingStart);
722180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
723180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
724180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
725180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
726180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangbool NuPlayer::RTSPSource::stopBufferingIfNecessary() {
727180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
728180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
729180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (mBuffering) {
730180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        if (!haveSufficientDataOnAllTracks()) {
731180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang            return false;
732180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        }
733180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
734180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = false;
735180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
736180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
737180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->setInt32("what", kWhatBufferingEnd);
738180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
739180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
740180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
741180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    return true;
742180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
743180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
7448d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shihvoid NuPlayer::RTSPSource::finishSeek(status_t err) {
7458d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    CHECK(mSeekReplyID != NULL);
7468d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    sp<AMessage> seekReply = new AMessage;
7478d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    seekReply->setInt32("err", err);
7488d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    seekReply->postReply(mSeekReplyID);
7498d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih    mSeekReplyID = NULL;
7508d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih}
751180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
7522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
753