RTSPSource.cpp revision 3f27436a9346f043f52265da1e6a74cde2bffd4d
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() {
14146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    mHandler->resume();
14246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson}
14346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
1442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
145180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
1462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return mFinalResult;
1472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
149840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) {
1502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return NULL;
1542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->getFormat();
1572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
159bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {
160bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // We're going to buffer at least 2 secs worth data on all tracks before
161bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // starting playback (both at startup and after a seek).
162bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
163bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    static const int64_t kMinDurationUs = 2000000ll;
164bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
165cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    int64_t mediaDurationUs = 0;
166cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    getDuration(&mediaDurationUs);
167cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
168cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
169cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return true;
170cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
171cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
172bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    status_t err;
173bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    int64_t durationUs;
174bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mAudioTrack != NULL
175bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
176bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
177bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
178bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
179bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
180bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
181bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
182bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
183bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mVideoTrack != NULL
184bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
185bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
186bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
187bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
188bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
189bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
190bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
191bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
192bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    return true;
193bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber}
194bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
1962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
197180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!stopBufferingIfNecessary()) {
198180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        return -EWOULDBLOCK;
199bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
200bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
2012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
2022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
2042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return -EWOULDBLOCK;
2052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t finalResult;
2082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
209cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        if (finalResult == OK) {
210cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            int64_t mediaDurationUs = 0;
211cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            getDuration(&mediaDurationUs);
212cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            sp<AnotherPacketSource> otherSource = getSource(!audio);
213cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            status_t otherFinalResult;
214cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
215cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If other source already signaled EOS, this source should also signal EOS
216cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (otherSource != NULL &&
217cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    !otherSource->hasBufferAvailable(&otherFinalResult) &&
218cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    otherFinalResult == ERROR_END_OF_STREAM) {
219cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                source->signalEOS(ERROR_END_OF_STREAM);
220cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return ERROR_END_OF_STREAM;
221cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
222cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
223cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If this source has detected near end, give it some time to retrieve more
224cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // data before signaling EOS
225cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (source->isFinished(mediaDurationUs)) {
226cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
227cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                if (eosTimeout == 0) {
228cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, ALooper::GetNowUs());
229cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
230cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, 0);
231cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    source->signalEOS(ERROR_END_OF_STREAM);
232cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    return ERROR_END_OF_STREAM;
233cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                }
234cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return -EWOULDBLOCK;
235cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
236cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
237cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) {
238cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // We should not enter buffering mode
239cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // if any of the sources already have detected EOS.
240180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang                startBufferingIfNecessary();
241cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
242cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
243cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            return -EWOULDBLOCK;
244cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        }
245cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return finalResult;
2462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
248cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    setEOSTimeout(audio, 0);
249cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->dequeueAccessUnit(accessUnit);
2512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2532bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
25449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    if (mTSParser != NULL) {
25549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        sp<MediaSource> source = mTSParser->getSource(
25649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
25749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
25849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        return static_cast<AnotherPacketSource *>(source.get());
25949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    }
26049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
2612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return audio ? mAudioTrack : mVideoTrack;
2622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
264cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonvoid NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) {
265cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if (audio) {
266cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutAudio = timeout;
267cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    } else {
268cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutVideo = timeout;
269cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
270cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson}
271cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
2732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    *durationUs = 0ll;
2742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t audioDurationUs;
2762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mAudioTrack != NULL
2772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mAudioTrack->getFormat()->findInt64(
2782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &audioDurationUs)
2792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && audioDurationUs > *durationUs) {
2802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = audioDurationUs;
2812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t videoDurationUs;
2842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mVideoTrack != NULL
2852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mVideoTrack->getFormat()->findInt64(
2862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &videoDurationUs)
2872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && videoDurationUs > *durationUs) {
2882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = videoDurationUs;
2892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return OK;
2922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
2951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatPerformSeek, this);
296ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
297ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
298ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->post(200000ll);
299ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
300ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    return OK;
301ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber}
302ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
303ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
3042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != CONNECTED) {
305ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = SEEKING;
3092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->seek(seekTimeUs);
3102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3122bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
3132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
3143f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
3152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
3162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
3182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
3192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
320ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
321ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
322ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
323ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
324ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
325ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
326ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            return;
327ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        }
328ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
329ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int64_t seekTimeUs;
330ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
331ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
332ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        performSeek(seekTimeUs);
333ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
3372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int32_t what;
3392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("what", &what));
3402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    switch (what) {
3422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatConnected:
3437f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
3442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onConnected();
3457f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
346ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang            notifyVideoSizeChanged();
3477f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3487f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            uint32_t flags = 0;
3497f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3507f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            if (mHandler->isSeekable()) {
3514b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                flags = FLAG_CAN_PAUSE
3524b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK
3534b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_BACKWARD
3544b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_FORWARD;
3557f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            }
3567f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3577f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyFlagsChanged(flags);
3587f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared();
3592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3607f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
3612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatDisconnected:
3637f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
3642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onDisconnected(msg);
3652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3667f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
3672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDone:
3692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mState = CONNECTED;
3712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
3752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
3772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
37849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
37949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser == NULL) {
38049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_LT(trackIndex, mTracks.size());
38149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            } else {
38249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_EQ(trackIndex, 0u);
38349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
3842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3852d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            sp<ABuffer> accessUnit;
3862d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
3872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
3892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
3902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
391df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
3922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
3932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
3942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
39549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
39649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                size_t offset = 0;
39749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                status_t err = OK;
39849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                while (offset + 188 <= accessUnit->size()) {
39949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = mTSParser->feedTSPacket(
40049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                            accessUnit->data() + offset, 188);
40149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (err != OK) {
40249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        break;
40349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
40449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
40549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    offset += 188;
40649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
40749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
40849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (offset < accessUnit->size()) {
40949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = ERROR_MALFORMED;
41049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
41149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
41249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (err != OK) {
41349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    sp<AnotherPacketSource> source = getSource(false /* audio */);
41449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
41549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
41649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
41749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
41849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source = getSource(true /* audio */);
41949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
42049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
42149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
42249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
42349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                break;
42449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
42549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
4261906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4271906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
4281906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
4292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
4302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
4312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
4322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4331906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
4341906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
435c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    // playtime mapping. We won't map to npt time.
436c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    source->queueAccessUnit(accessUnit);
437c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    break;
4381906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
4391906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
4402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
4411906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
4421906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
4432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
4441906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
4452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
4472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
4492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
4542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
4562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
4572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
4582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
45949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
46049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                sp<AnotherPacketSource> source = getSource(false /* audio */);
46149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
46249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
46349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
46449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
46549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                source = getSource(true /* audio */);
46649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
46749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
46849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
46949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
47049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                return;
47149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
47249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
47349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            size_t trackIndex;
47449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
47549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_LT(trackIndex, mTracks.size());
47649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
4772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
4792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
4802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
4812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
4872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
4892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
4902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
4912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
4942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
495632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                source->queueDiscontinuity(
496fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia                        ATSParser::DISCONTINUITY_TIME,
497632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        NULL,
498632740c58119a132ce19f6d498e39c5c3773971aChong Zhang                        true /* discard */);
4992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
5052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
5082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
5092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
5112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
5122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
5142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
5152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
5182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
5191906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
5202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
52381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        case SDPLoader::kWhatSDPLoaded:
52481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        {
52581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            onSDPLoaded(msg);
52681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            break;
52781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
52881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
5292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
5302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
5312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
5322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
5332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5342bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
5352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
5362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
5372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
5392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
5402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
5412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
5422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
5442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
5452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
54649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
54749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            // Very special case for MPEG2 Transport Streams.
54849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_EQ(numTracks, 1u);
54949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
55049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            mTSParser = new ATSParser;
55149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            return;
55249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        }
55349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
5552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
5562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
5582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
5592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
5602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
5611906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
5622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
5642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
5652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
5662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
5682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
5692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
5702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
5712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
5742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
5772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
5782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
5802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
5812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
58281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhévoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
58381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    status_t err;
58481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(msg->findInt32("result", &err));
58581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
58681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    mSDPLoader.clear();
58781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
58881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mDisconnectReplyID != 0) {
58981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        err = UNKNOWN_ERROR;
59081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
59181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
59281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err == OK) {
59381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<ASessionDescription> desc;
59481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<RefBase> obj;
59581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        CHECK(msg->findObject("description", &obj));
59681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        desc = static_cast<ASessionDescription *>(obj.get());
59781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
59881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        AString rtspUri;
59981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
60081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            ALOGE("Unable to find url in SDP");
60181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            err = UNKNOWN_ERROR;
60281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else {
6031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> notify = new AMessage(kWhatNotify, this);
60481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
60581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
60681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mLooper->registerHandler(mHandler);
60781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
60881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->loadSDP(desc);
60981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
61081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
61181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
61281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err != OK) {
6137f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        if (mState == CONNECTING) {
6147f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // We're still in the preparation phase, signal that it
6157f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // failed.
6167f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared(err);
6177f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
6187f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
61981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mState = DISCONNECTED;
620180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        setError(err);
62181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
62281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mDisconnectReplyID != 0) {
62381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            finishDisconnectIfPossible();
62481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
62581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
62681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé}
62781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
6282bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
6290ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    if (mState == DISCONNECTED) {
6300ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin        return;
6310ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    }
6320ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin
6332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
6342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
6352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
6362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
6382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
6392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6407f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    if (mState == CONNECTING) {
6417f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // We're still in the preparation phase, signal that it
6427f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // failed.
6437f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        notifyPrepared(err);
6447f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    }
6457f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
6462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
647180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    setError(err);
6482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
6502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
6512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6542bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
6552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
65681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mHandler != NULL) {
65781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->disconnect();
65881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else if (mSDPLoader != NULL) {
65981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mSDPLoader->cancel();
66081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
6612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
6622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
6652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
6662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
668180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::setError(status_t err) {
669180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
670180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    mFinalResult = err;
671180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
672180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
673180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::startBufferingIfNecessary() {
674180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
675180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
676180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (!mBuffering) {
677180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = true;
678180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
679180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
680180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->setInt32("what", kWhatBufferingStart);
681180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
682180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
683180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
684180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
685180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangbool NuPlayer::RTSPSource::stopBufferingIfNecessary() {
686180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    Mutex::Autolock _l(mBufferingLock);
687180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
688180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    if (mBuffering) {
689180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        if (!haveSufficientDataOnAllTracks()) {
690180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang            return false;
691180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        }
692180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
693180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        mBuffering = false;
694180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
695180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        sp<AMessage> notify = dupNotify();
696180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->setInt32("what", kWhatBufferingEnd);
697180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang        notify->post();
698180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    }
699180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
700180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang    return true;
701180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang}
702180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
703180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang
7042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
705