RTSPSource.cpp revision 81e68448f3361eaf8618930471fdc3c21bdf5cbc
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),
53cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson      mBuffering(true),
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) {
73602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber        mLooper->stop();
74602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber    }
752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
7757cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::prepareAsync() {
782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper == NULL) {
792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper = new ALooper;
802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->setName("rtsp");
812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->start();
822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mReflector = new AHandlerReflector<RTSPSource>(this);
842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->registerHandler(mReflector);
852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mHandler == NULL);
8881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(mSDPLoader == NULL);
892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
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
109cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    sp<AMessage> notifyStart = dupNotify();
110cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    notifyStart->setInt32("what", kWhatBufferingStart);
111cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    notifyStart->post();
11257cea553cb19235553463412db5ad04c99835411Andreas Huber}
11357cea553cb19235553463412db5ad04c99835411Andreas Huber
11457cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::start() {
1152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1172bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::stop() {
1185834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    if (mLooper == NULL) {
1195834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong        return;
1205834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong    }
1212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());
1222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> dummy;
1242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    msg->postAndAwaitResponse(&dummy);
1252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
12746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönssonvoid NuPlayer::RTSPSource::pause() {
12846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    int64_t mediaDurationUs = 0;
12946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    getDuration(&mediaDurationUs);
13046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    for (size_t index = 0; index < mTracks.size(); index++) {
13146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        TrackInfo *info = &mTracks.editItemAt(index);
13246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        sp<AnotherPacketSource> source = info->mSource;
13346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
13446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        // Check if EOS or ERROR is received
13546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        if (source != NULL && source->isFinished(mediaDurationUs)) {
13646d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson            return;
13746d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson        }
13846d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    }
13946d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    mHandler->pause();
14046d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson}
14146d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
14246d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönssonvoid NuPlayer::RTSPSource::resume() {
14346d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson    mHandler->resume();
14446d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson}
14546d13e3606b87d71379287672b54b50d0d9aa5ccRoger Jönsson
1462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
1472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return mFinalResult;
1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
150840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) {
1512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return NULL;
1552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->getFormat();
1582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
160bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {
161bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // We're going to buffer at least 2 secs worth data on all tracks before
162bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // starting playback (both at startup and after a seek).
163bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
164bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    static const int64_t kMinDurationUs = 2000000ll;
165bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
166cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    int64_t mediaDurationUs = 0;
167cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    getDuration(&mediaDurationUs);
168cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs))
169cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) {
170cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return true;
171cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
172cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
173bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    status_t err;
174bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    int64_t durationUs;
175bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mAudioTrack != NULL
176bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
177bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
178bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
179bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
180bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
181bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
182bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
183bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
184bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mVideoTrack != NULL
185bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
186bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
187bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
188bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
189bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
190bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
191bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
192bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
193bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    return true;
194bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber}
195bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
1972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
198cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if (mBuffering) {
199bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        if (!haveSufficientDataOnAllTracks()) {
200bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            return -EWOULDBLOCK;
201bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        }
202bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
203cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mBuffering = false;
204cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
205cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        sp<AMessage> notify = dupNotify();
206cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        notify->setInt32("what", kWhatBufferingEnd);
207cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        notify->post();
208bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
209bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
2102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
2112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
2132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return -EWOULDBLOCK;
2142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t finalResult;
2172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
218cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        if (finalResult == OK) {
219cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            int64_t mediaDurationUs = 0;
220cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            getDuration(&mediaDurationUs);
221cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            sp<AnotherPacketSource> otherSource = getSource(!audio);
222cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            status_t otherFinalResult;
223cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
224cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If other source already signaled EOS, this source should also signal EOS
225cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (otherSource != NULL &&
226cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    !otherSource->hasBufferAvailable(&otherFinalResult) &&
227cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    otherFinalResult == ERROR_END_OF_STREAM) {
228cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                source->signalEOS(ERROR_END_OF_STREAM);
229cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return ERROR_END_OF_STREAM;
230cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
231cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
232cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // If this source has detected near end, give it some time to retrieve more
233cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            // data before signaling EOS
234cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (source->isFinished(mediaDurationUs)) {
235cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo;
236cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                if (eosTimeout == 0) {
237cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, ALooper::GetNowUs());
238cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) {
239cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    setEOSTimeout(audio, 0);
240cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    source->signalEOS(ERROR_END_OF_STREAM);
241cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                    return ERROR_END_OF_STREAM;
242cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                }
243cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                return -EWOULDBLOCK;
244cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
245cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
246cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            if (!(otherSource != NULL && otherSource->isFinished(mediaDurationUs))) {
247cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // We should not enter buffering mode
248cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                // if any of the sources already have detected EOS.
249cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                mBuffering = true;
250cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
251cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                sp<AMessage> notify = dupNotify();
252cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                notify->setInt32("what", kWhatBufferingStart);
253cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson                notify->post();
254cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            }
255cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
256cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson            return -EWOULDBLOCK;
257cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        }
258cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        return finalResult;
2592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
261cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    setEOSTimeout(audio, 0);
262cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->dequeueAccessUnit(accessUnit);
2642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2662bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
26749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    if (mTSParser != NULL) {
26849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        sp<MediaSource> source = mTSParser->getSource(
26949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                audio ? ATSParser::AUDIO : ATSParser::VIDEO);
27049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
27149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        return static_cast<AnotherPacketSource *>(source.get());
27249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber    }
27349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
2742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return audio ? mAudioTrack : mVideoTrack;
2752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
277cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonvoid NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) {
278cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    if (audio) {
279cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutAudio = timeout;
280cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    } else {
281cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson        mEOSTimeoutVideo = timeout;
282cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson    }
283cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson}
284cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson
2852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
2862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    *durationUs = 0ll;
2872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t audioDurationUs;
2892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mAudioTrack != NULL
2902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mAudioTrack->getFormat()->findInt64(
2912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &audioDurationUs)
2922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && audioDurationUs > *durationUs) {
2932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = audioDurationUs;
2942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t videoDurationUs;
2972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mVideoTrack != NULL
2982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mVideoTrack->getFormat()->findInt64(
2992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &videoDurationUs)
3002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && videoDurationUs > *durationUs) {
3012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = videoDurationUs;
3022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return OK;
3052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
308ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPerformSeek, mReflector->id());
309ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
310ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
311ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->post(200000ll);
312ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
313ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    return OK;
314ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber}
315ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
316ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
3172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != CONNECTED) {
318ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = SEEKING;
3222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->seek(seekTimeUs);
3232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3252bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
3262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
3272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        uint32_t replyID;
3282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
3292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
3312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
3322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
333ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
334ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
335ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
336ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
337ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
338ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
339ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            return;
340ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        }
341ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
342ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int64_t seekTimeUs;
343ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
344ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
345ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        performSeek(seekTimeUs);
346ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
3472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
3502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int32_t what;
3522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("what", &what));
3532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    switch (what) {
3552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatConnected:
3567f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
3572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onConnected();
3587f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3597f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyVideoSizeChanged(0, 0);
3607f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3617f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            uint32_t flags = 0;
3627f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3637f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            if (mHandler->isSeekable()) {
3644b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                flags = FLAG_CAN_PAUSE
3654b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK
3664b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_BACKWARD
3674b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang                        | FLAG_CAN_SEEK_FORWARD;
3687f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            }
3697f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
3707f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyFlagsChanged(flags);
3717f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared();
3722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3737f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
3742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatDisconnected:
3767f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        {
3772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onDisconnected(msg);
3782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3797f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
3802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDone:
3822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mState = CONNECTED;
3842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
3882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
3902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
39149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
39249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser == NULL) {
39349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_LT(trackIndex, mTracks.size());
39449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            } else {
39549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                CHECK_EQ(trackIndex, 0u);
39649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
3972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3982d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            sp<ABuffer> accessUnit;
3992d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
4002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
4022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
4032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
404df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
4052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
4062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
40849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
40949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                size_t offset = 0;
41049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                status_t err = OK;
41149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                while (offset + 188 <= accessUnit->size()) {
41249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = mTSParser->feedTSPacket(
41349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                            accessUnit->data() + offset, 188);
41449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (err != OK) {
41549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        break;
41649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
41749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
41849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    offset += 188;
41949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
42049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
42149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (offset < accessUnit->size()) {
42249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    err = ERROR_MALFORMED;
42349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
42449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
42549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (err != OK) {
42649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    sp<AnotherPacketSource> source = getSource(false /* audio */);
42749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
42849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
42949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
43049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
43149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source = getSource(true /* audio */);
43249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    if (source != NULL) {
43349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                        source->signalEOS(err);
43449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    }
43549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
43649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                break;
43749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
43849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
4391906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4401906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
4411906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
4422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
4432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
4442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
4452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4461906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
4471906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
448c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    // playtime mapping. We won't map to npt time.
449c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    source->queueAccessUnit(accessUnit);
450c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber                    break;
4511906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
4521906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
4532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
4541906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
4551906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
4562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
4571906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
4582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
4602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
4622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
4672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
4682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
4692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
4702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
4712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
47249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            if (mTSParser != NULL) {
47349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                sp<AnotherPacketSource> source = getSource(false /* audio */);
47449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
47549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
47649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
47749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
47849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                source = getSource(true /* audio */);
47949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                if (source != NULL) {
48049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                    source->signalEOS(finalResult);
48149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                }
48249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
48349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber                return;
48449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            }
48549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
48649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            size_t trackIndex;
48749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
48849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_LT(trackIndex, mTracks.size());
48949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
4902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
4912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
4922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
4932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
4942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
4952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
4972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
4982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
5002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
5032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
5042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
5072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
5082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueDiscontinuity(ATSParser::DISCONTINUITY_SEEK, NULL);
5092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
5152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
5162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
5172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
5182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
5192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
5212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
5222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
5242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
5252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
5272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
5282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
5291906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
5302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
5312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
53381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        case SDPLoader::kWhatSDPLoaded:
53481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        {
53581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            onSDPLoaded(msg);
53681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            break;
53781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
53881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
5392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
5402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
5412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
5422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
5432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5442bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
5452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
5462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
5472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
5492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
5502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
5512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
5522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
5542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
5552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
55649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) {
55749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            // Very special case for MPEG2 Transport Streams.
55849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            CHECK_EQ(numTracks, 1u);
55949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
56049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            mTSParser = new ATSParser;
56149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber            return;
56249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber        }
56349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber
5642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
5652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
5662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
5682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
5692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
5702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
5711906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
5722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
5742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
5752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
5762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
5782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
5792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
5802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
5812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
5822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
5842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
5852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
5872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
5882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
5892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
5902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
5912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
59281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhévoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) {
59381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    status_t err;
59481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    CHECK(msg->findInt32("result", &err));
59581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
59681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    mSDPLoader.clear();
59781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
59881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (mDisconnectReplyID != 0) {
59981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        err = UNKNOWN_ERROR;
60081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
60181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
60281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err == OK) {
60381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<ASessionDescription> desc;
60481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        sp<RefBase> obj;
60581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        CHECK(msg->findObject("description", &obj));
60681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        desc = static_cast<ASessionDescription *>(obj.get());
60781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
60881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        AString rtspUri;
60981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (!desc->findAttribute(0, "a=control", &rtspUri)) {
61081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            ALOGE("Unable to find url in SDP");
61181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            err = UNKNOWN_ERROR;
61281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else {
61381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
61481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
61581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID);
61681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mLooper->registerHandler(mHandler);
61781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
61881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->loadSDP(desc);
61981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
62081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
62181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
62281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    if (err != OK) {
6237f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        if (mState == CONNECTING) {
6247f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // We're still in the preparation phase, signal that it
6257f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            // failed.
6267f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber            notifyPrepared(err);
6277f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        }
6287f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
62981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mState = DISCONNECTED;
63081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        mFinalResult = err;
63181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
63281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mDisconnectReplyID != 0) {
63381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            finishDisconnectIfPossible();
63481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
63581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé    }
63681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé}
63781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé
6382bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
6390ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    if (mState == DISCONNECTED) {
6400ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin        return;
6410ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin    }
6420ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin
6432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
6442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
6452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
6462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
6482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
6492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6507f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    if (mState == CONNECTING) {
6517f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // We're still in the preparation phase, signal that it
6527f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        // failed.
6537f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber        notifyPrepared(err);
6547f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber    }
6557f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber
6562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
6572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mFinalResult = err;
6582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
6602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
6612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6642bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
6652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
66681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        if (mHandler != NULL) {
66781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mHandler->disconnect();
66881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        } else if (mSDPLoader != NULL) {
66981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé            mSDPLoader->cancel();
67081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé        }
6712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
6722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
6732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
6752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
6762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
6772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
6782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
679