RTSPSource.cpp revision bfd4d0d9fe0033abf3f55b94f30f6a58846a875e
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"
252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber#include <media/stagefright/MetaData.h>
272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
282bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubernamespace android {
292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
302bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::RTSPSource(
312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *url,
322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const KeyedVector<String8, String8> *headers,
332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool uidValid,
342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        uid_t uid)
352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    : mURL(url),
362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mUIDValid(uidValid),
372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mUID(uid),
382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mFlags(0),
392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mState(DISCONNECTED),
402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber      mFinalResult(OK),
41ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber      mDisconnectReplyID(0),
42bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber      mStartingUp(true),
43ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber      mSeekGeneration(0) {
442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (headers) {
452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mExtraHeaders = *headers;
462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        ssize_t index =
482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if (index >= 0) {
512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mFlags |= kFlagIncognito;
522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.removeItemsAt(index);
542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
582bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::~RTSPSource() {
592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper != NULL) {
602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->stop();
612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
642bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::start() {
652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper == NULL) {
662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper = new ALooper;
672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->setName("rtsp");
682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->start();
692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mReflector = new AHandlerReflector<RTSPSource>(this);
712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->registerHandler(mReflector);
722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mHandler == NULL);
752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->registerHandler(mHandler);
802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(mState, (int)DISCONNECTED);
822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTING;
832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->connect();
852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
872bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::stop() {
882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());
892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> dummy;
912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    msg->postAndAwaitResponse(&dummy);
922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return mFinalResult;
962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
982bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormat(bool audio) {
992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return NULL;
1032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->getFormat();
1062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
108bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() {
109bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // We're going to buffer at least 2 secs worth data on all tracks before
110bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    // starting playback (both at startup and after a seek).
111bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
112bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    static const int64_t kMinDurationUs = 2000000ll;
113bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
114bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    status_t err;
115bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    int64_t durationUs;
116bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mAudioTrack != NULL
117bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mAudioTrack->getBufferedDurationUs(&err))
118bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
119bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
120bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)",
121bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
122bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
123bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
124bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
125bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mVideoTrack != NULL
126bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && (durationUs = mVideoTrack->getBufferedDurationUs(&err))
127bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber                    < kMinDurationUs
128bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            && err == OK) {
129bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)",
130bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber              durationUs / 1E6);
131bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        return false;
132bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
133bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
134bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    return true;
135bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber}
136bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
1382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
139bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    if (mStartingUp) {
140bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        if (!haveSufficientDataOnAllTracks()) {
141bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            return -EWOULDBLOCK;
142bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        }
143bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
144bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber        mStartingUp = false;
145bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber    }
146bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber
1472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return -EWOULDBLOCK;
1512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t finalResult;
1542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
1552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return finalResult == OK ? -EWOULDBLOCK : finalResult;
1562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->dequeueAccessUnit(accessUnit);
1592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1612bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
1622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return audio ? mAudioTrack : mVideoTrack;
1632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
1662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    *durationUs = 0ll;
1672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t audioDurationUs;
1692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mAudioTrack != NULL
1702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mAudioTrack->getFormat()->findInt64(
1712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &audioDurationUs)
1722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && audioDurationUs > *durationUs) {
1732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = audioDurationUs;
1742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t videoDurationUs;
1772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mVideoTrack != NULL
1782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mVideoTrack->getFormat()->findInt64(
1792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &videoDurationUs)
1802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && videoDurationUs > *durationUs) {
1812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = videoDurationUs;
1822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return OK;
1852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
188ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPerformSeek, mReflector->id());
189ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
190ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
191ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->post(200000ll);
192ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
193ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    return OK;
194ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber}
195ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
196ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
1972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != CONNECTED) {
198ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
1992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = SEEKING;
2022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->seek(seekTimeUs);
2032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberbool NuPlayer::RTSPSource::isSeekable() {
2062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return true;
2072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
2082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2092bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
2102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
2112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        uint32_t replyID;
2122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
2132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
2152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
2162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
217ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
218ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
219ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
220ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
221ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
222ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
223ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            return;
224ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        }
225ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
226ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int64_t seekTimeUs;
227ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
228ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
229ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        performSeek(seekTimeUs);
230ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
2312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
2322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
2342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int32_t what;
2362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("what", &what));
2372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    switch (what) {
2392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatConnected:
2402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onConnected();
2412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatDisconnected:
2442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onDisconnected(msg);
2452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDone:
2482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
2492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mState = CONNECTED;
250bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber            mStartingUp = true;
2512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
2532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
2552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
2562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
2572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
2582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
2592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2602d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            sp<ABuffer> accessUnit;
2612d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
2622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
2642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
2652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
266df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
2672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
2682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
2692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2701906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
2711906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
2721906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
2732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
2742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
2752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
2762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2771906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
2781906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
2791906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // playtime mapping. Assume the first packets correspond
2801906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // to time 0.
2811906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
282d2927a79dc933a134e022281a4679a65e340dc3aOwen Lin                    ALOGV("This is a live stream, assuming time = 0");
2831906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
2841906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    info->mRTPTime = rtpTime;
2851906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    info->mNormalPlaytimeUs = 0ll;
2861906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    info->mNPTMappingValid = true;
2871906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
2881906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
2892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
2901906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
2911906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
2922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
2931906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
2942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
2962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
2982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
2992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
3032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
3052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
3062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
3072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
3092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
3102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
3112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
3132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
3142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
3152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
3162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
3172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
3222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
3242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
3252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
3262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
3282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
3292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
3302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueDiscontinuity(ATSParser::DISCONTINUITY_SEEK, NULL);
3312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
3322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
3372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
3392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
3402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
3412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
3432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
3442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
3462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
3472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
3492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
3502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
3511906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
3522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
3562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
3572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3602bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
3612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
3622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
3632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
3652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
3662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
3672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
3682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
3702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
3712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
3732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
3742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
3762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
3772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
3782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
3791906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
3802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
3822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
3832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
3842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
3862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
3872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
3882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
3892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
3902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
3922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
3952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
3982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4002bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
4012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
4022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
4032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
4042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
4062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
4072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
4092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mFinalResult = err;
4102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
4122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
4132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
4142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
4152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4162bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
4172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
4182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mHandler->disconnect();
4192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
4202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
4212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
4232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
4242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
4252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
4262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
427