RTSPSource.cpp revision 4b7069dac546ad21cf62ca6132d50ea41857d08e
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
2749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber#include <media/stagefright/MediaDefs.h>
282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include <media/stagefright/MetaData.h>
292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
302bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubernamespace android {
312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
32cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonconst int64_t kNearEOSTimeoutUs = 2000000ll; // 2 secs
33cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
342bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::RTSPSource(
355ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber        const sp<AMessage> &notify,
362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *url,
372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const KeyedVector<String8, String8> *headers,
382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool uidValid,
3981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        uid_t uid,
4081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        bool isSDP)
415ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber    : Source(notify),
425ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber      mURL(url),
432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mUIDValid(uidValid),
442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mUID(uid),
452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mFlags(0),
4681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé      mIsSDP(isSDP),
472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mState(DISCONNECTED),
482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mFinalResult(OK),
49ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber      mDisconnectReplyID(0),
50cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mBuffering(true),
51cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mSeekGeneration(0),
52cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mEOSTimeoutAudio(0),
53cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mEOSTimeoutVideo(0) {
542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (headers) {
552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mExtraHeaders = *headers;
562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        ssize_t index =
582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if (index >= 0) {
612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mFlags |= kFlagIncognito;
622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.removeItemsAt(index);
642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
682bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::~RTSPSource() {
69602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    if (mLooper != NULL) {
70602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber        mLooper->stop();
71602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    }
722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7457cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::prepareAsync() {
752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper == NULL) {
762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper = new ALooper;
772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->setName("rtsp");
782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->start();
792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mReflector = new AHandlerReflector<RTSPSource>(this);
812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->registerHandler(mReflector);
822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mHandler == NULL);
8581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(mSDPLoader == NULL);
862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(mState, (int)DISCONNECTED);
902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTING;
912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
9281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mIsSDP) {
9381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mSDPLoader = new SDPLoader(notify,
9481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé                (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0,
9581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé                mUIDValid, mUID);
9681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
9757cea553cb19235553463412db5ad04c99835411Andreas Huber        mSDPLoader->load(
9857cea553cb19235553463412db5ad04c99835411Andreas Huber                mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
9981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    } else {
10081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
10181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mLooper->registerHandler(mHandler);
10281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
10381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mHandler->connect();
10481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
105cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
106cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    sp<AMessage> notifyStart = dupNotify();
107cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    notifyStart->setInt32("what", kWhatBufferingStart);
108cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    notifyStart->post();
10957cea553cb19235553463412db5ad04c99835411Andreas Huber}
11057cea553cb19235553463412db5ad04c99835411Andreas Huber
11157cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::start() {
1122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1142bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::stop() {
1155834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    if (mLooper == NULL) {
1165834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong        return;
1175834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    }
1182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());
1192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> dummy;
1212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    msg->postAndAwaitResponse(&dummy);
1222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
12446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönssonvoid NuPlayer::RTSPSource::pause() {
12546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    int64_t mediaDurationUs = 0;
12646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    getDuration(&mediaDurationUs);
12746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    for (size_t index = 0; index < mTracks.size(); index++) {
12846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        TrackInfo *info = &mTracks.editItemAt(index);
12946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        sp<AnotherPacketSource> source = info->mSource;
13046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
13146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        // Check if EOS or ERROR is received
13246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        if (source != NULL && source->isFinished(mediaDurationUs)) {
13346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson            return;
13446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        }
13546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    }
13646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    mHandler->pause();
13746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson}
13846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
13946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönssonvoid NuPlayer::RTSPSource::resume() {
14046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    mHandler->resume();
14146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson}
14246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
1432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
1442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return mFinalResult;
1452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
147840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) {
1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return NULL;
1522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->getFormat();
1552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
157bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {
158bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // We're going to buffer at least 2 secs worth data on all tracks before
159bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // starting playback (both at startup and after a seek).
160bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
161bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    static const int64_t kMinDurationUs = 2000000ll;
162bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
163cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    int64_t mediaDurationUs = 0;
164cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    getDuration(&mediaDurationUs);
165cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
166cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
167cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return true;
168cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
169cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
170bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    status_t err;
171bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    int64_t durationUs;
172bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mAudioTrack != NULL
173bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
174bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
175bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
176bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
177bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
178bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
179bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
180bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
181bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mVideoTrack != NULL
182bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
183bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
184bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
185bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
186bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
187bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
188bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
189bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
190bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    return true;
191bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber}
192bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
1942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
195cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if (mBuffering) {
196bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        if (!haveSufficientDataOnAllTracks()) {
197bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            return -EWOULDBLOCK;
198bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        }
199bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
200cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mBuffering = false;
201cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
202cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        sp<AMessage> notify = dupNotify();
203cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        notify->setInt32("what", kWhatBufferingEnd);
204cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        notify->post();
205bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
206bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
2072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
2082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
2102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return -EWOULDBLOCK;
2112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t finalResult;
2142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
215cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        if (finalResult == OK) {
216cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            int64_t mediaDurationUs = 0;
217cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            getDuration(&mediaDurationUs);
218cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            sp<AnotherPacketSource> otherSource = getSource(!audio);
219cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            status_t otherFinalResult;
220cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
221cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If other source already signaled EOS, this source should also signal EOS
222cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (otherSource != NULL &&
223cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    !otherSource->hasBufferAvailable(&otherFinalResult) &&
224cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    otherFinalResult == ERROR_END_OF_STREAM) {
225cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                source->signalEOS(ERROR_END_OF_STREAM);
226cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return ERROR_END_OF_STREAM;
227cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
228cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
229cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If this source has detected near end, give it some time to retrieve more
230cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // data before signaling EOS
231cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (source->isFinished(mediaDurationUs)) {
232cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
233cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                if (eosTimeout == 0) {
234cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, ALooper::GetNowUs());
235cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
236cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, 0);
237cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    source->signalEOS(ERROR_END_OF_STREAM);
238cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    return ERROR_END_OF_STREAM;
239cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                }
240cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return -EWOULDBLOCK;
241cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
242cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
243cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) {
244cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // We should not enter buffering mode
245cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // if any of the sources already have detected EOS.
246cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                mBuffering = true;
247cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
248cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                sp<AMessage> notify = dupNotify();
249cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                notify->setInt32("what", kWhatBufferingStart);
250cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                notify->post();
251cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
252cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
253cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            return -EWOULDBLOCK;
254cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        }
255cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return finalResult;
2562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
258cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    setEOSTimeout(audio, 0);
259cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->dequeueAccessUnit(accessUnit);
2612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2632bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
26449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    if (mTSParser != NULL) {
26549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        sp<MediaSource> source = mTSParser->getSource(
26649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
26749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
26849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        return static_cast<AnotherPacketSource *>(source.get());
26949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    }
27049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
2712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return audio ? mAudioTrack : mVideoTrack;
2722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
274cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonvoid NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) {
275cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if (audio) {
276cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutAudio = timeout;
277cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    } else {
278cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutVideo = timeout;
279cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
280cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson}
281cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
2832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    *durationUs = 0ll;
2842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t audioDurationUs;
2862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mAudioTrack != NULL
2872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mAudioTrack->getFormat()->findInt64(
2882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &audioDurationUs)
2892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && audioDurationUs > *durationUs) {
2902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = audioDurationUs;
2912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t videoDurationUs;
2942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mVideoTrack != NULL
2952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mVideoTrack->getFormat()->findInt64(
2962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &videoDurationUs)
2972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && videoDurationUs > *durationUs) {
2982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = videoDurationUs;
2992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return OK;
3022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
305ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPerformSeek, mReflector->id());
306ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
307ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
308ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->post(200000ll);
309ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
310ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    return OK;
311ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber}
312ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
313ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
3142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != CONNECTED) {
315ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = SEEKING;
3192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->seek(seekTimeUs);
3202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3222bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
3232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
3242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        uint32_t replyID;
3252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
3262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
3282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
3292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
330ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
331ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
332ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
333ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
334ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
335ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
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
3567f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyVideoSizeChanged(0, 0);
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;
3812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
3852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
3872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
38849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
38949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser == NULL) {
39049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_LT(trackIndex, mTracks.size());
39149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            } else {
39249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_EQ(trackIndex, 0u);
39349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
3942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3952d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            sp<ABuffer> accessUnit;
3962d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
3972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
3992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
4002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
401df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
4022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
4032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
40549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
40649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                size_t offset = 0;
40749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                status_t err = OK;
40849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                while (offset + 188 <= accessUnit->size()) {
40949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = mTSParser->feedTSPacket(
41049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                            accessUnit->data() + offset, 188);
41149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (err != OK) {
41249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        break;
41349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
41449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
41549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    offset += 188;
41649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
41749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
41849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (offset < accessUnit->size()) {
41949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = ERROR_MALFORMED;
42049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
42149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
42249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (err != OK) {
42349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    sp<AnotherPacketSource> source = getSource(false /* audio */);
42449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
42549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
42649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
42749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
42849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source = getSource(true /* audio */);
42949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
43049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
43149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
43249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
43349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                break;
43449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
43549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
4361906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4371906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
4381906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
4392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
4402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
4412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
4422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4431906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
4441906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
445c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    // playtime mapping. We won't map to npt time.
446c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    source->queueAccessUnit(accessUnit);
447c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    break;
4481906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
4491906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
4502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
4511906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
4521906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
4532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
4541906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
4552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
4572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
4592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
4642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
4662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
4672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
4682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
46949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
47049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                sp<AnotherPacketSource> source = getSource(false /* audio */);
47149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
47249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
47349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
47449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
47549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                source = getSource(true /* audio */);
47649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
47749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
47849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
47949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
48049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                return;
48149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
48249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
48349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            size_t trackIndex;
48449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
48549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_LT(trackIndex, mTracks.size());
48649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
4872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
4892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
4902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
4912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
4972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
4992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
5002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
5012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
5042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
5052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueDiscontinuity(ATSParser::DISCONTINUITY_SEEK, NULL);
5062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
5122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
5152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
5162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
5182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
5192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
5212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
5222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
5252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
5261906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
5272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
53081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        case SDPLoader::kWhatSDPLoaded:
53181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        {
53281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            onSDPLoaded(msg);
53381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            break;
53481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
53581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
5362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
5372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
5382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
5392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
5402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5412bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
5422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
5432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
5442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
5462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
5472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
5482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
5492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
5512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
5522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
55349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
55449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            // Very special case for MPEG2 Transport Streams.
55549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_EQ(numTracks, 1u);
55649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
55749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            mTSParser = new ATSParser;
55849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            return;
55949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        }
56049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
5622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
5632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
5652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
5662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
5672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
5681906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
5692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
5712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
5722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
5732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
5752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
5762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
5772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
5782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
5812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
5842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
5852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
5872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
5882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
58981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhévoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
59081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    status_t err;
59181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(msg->findInt32("result", &err));
59281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
59381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    mSDPLoader.clear();
59481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
59581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mDisconnectReplyID != 0) {
59681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        err = UNKNOWN_ERROR;
59781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
59881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
59981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err == OK) {
60081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<ASessionDescription> desc;
60181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<RefBase> obj;
60281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        CHECK(msg->findObject("description", &obj));
60381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        desc = static_cast<ASessionDescription *>(obj.get());
60481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
60581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        AString rtspUri;
60681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
60781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            ALOGE("Unable to find url in SDP");
60881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            err = UNKNOWN_ERROR;
60981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else {
61081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
61181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
61281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
61381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mLooper->registerHandler(mHandler);
61481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
61581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->loadSDP(desc);
61681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
61781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
61881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
61981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err != OK) {
6207f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        if (mState == CONNECTING) {
6217f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // We're still in the preparation phase, signal that it
6227f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // failed.
6237f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared(err);
6247f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
6257f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
62681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mState = DISCONNECTED;
62781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mFinalResult = err;
62881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
62981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mDisconnectReplyID != 0) {
63081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            finishDisconnectIfPossible();
63181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
63281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
63381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé}
63481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
6352bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
6360ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    if (mState == DISCONNECTED) {
6370ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin        return;
6380ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    }
6390ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin
6402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
6412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
6422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
6432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
6452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
6462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6477f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    if (mState == CONNECTING) {
6487f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // We're still in the preparation phase, signal that it
6497f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // failed.
6507f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        notifyPrepared(err);
6517f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    }
6527f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
6532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
6542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mFinalResult = err;
6552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
6572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
6582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6612bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
6622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
66381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mHandler != NULL) {
66481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->disconnect();
66581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else if (mSDPLoader != NULL) {
66681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mSDPLoader->cancel();
66781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
6682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
6692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
6722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
6732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
676