RTSPSource.cpp revision df64d15042bbd5e0e4933ac49bf3c177dd94752c
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),
42ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber      mSeekGeneration(0) {
432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (headers) {
442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mExtraHeaders = *headers;
452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        ssize_t index =
472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if (index >= 0) {
502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mFlags |= kFlagIncognito;
512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mExtraHeaders.removeItemsAt(index);
532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
572bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::~RTSPSource() {
582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper != NULL) {
592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->stop();
602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
632bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::start() {
642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mLooper == NULL) {
652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper = new ALooper;
662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->setName("rtsp");
672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->start();
682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mReflector = new AHandlerReflector<RTSPSource>(this);
702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mLooper->registerHandler(mReflector);
712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mHandler == NULL);
742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatNotify, mReflector->id());
762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID);
782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->registerHandler(mHandler);
792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(mState, (int)DISCONNECTED);
812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTING;
822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->connect();
842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
862bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::stop() {
872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDisconnect, mReflector->id());
882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AMessage> dummy;
902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    msg->postAndAwaitResponse(&dummy);
912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() {
942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return mFinalResult;
952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
972bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormat(bool audio) {
982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return NULL;
1022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->getFormat();
1052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit(
1082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool audio, sp<ABuffer> *accessUnit) {
1092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    sp<AnotherPacketSource> source = getSource(audio);
1102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (source == NULL) {
1122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return -EWOULDBLOCK;
1132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t finalResult;
1162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (!source->hasBufferAvailable(&finalResult)) {
1172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return finalResult == OK ? -EWOULDBLOCK : finalResult;
1182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return source->dequeueAccessUnit(accessUnit);
1212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1232bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) {
1242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return audio ? mAudioTrack : mVideoTrack;
1252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) {
1282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    *durationUs = 0ll;
1292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t audioDurationUs;
1312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mAudioTrack != NULL
1322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mAudioTrack->getFormat()->findInt64(
1332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &audioDurationUs)
1342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && audioDurationUs > *durationUs) {
1352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = audioDurationUs;
1362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int64_t videoDurationUs;
1392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mVideoTrack != NULL
1402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && mVideoTrack->getFormat()->findInt64(
1412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                kKeyDuration, &videoDurationUs)
1422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            && videoDurationUs > *durationUs) {
1432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        *durationUs = videoDurationUs;
1442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return OK;
1472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs) {
150ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPerformSeek, mReflector->id());
151ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt32("generation", ++mSeekGeneration);
152ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->setInt64("timeUs", seekTimeUs);
153ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    msg->post(200000ll);
154ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
155ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    return OK;
156ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber}
157ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
158ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) {
1592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != CONNECTED) {
160ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
1612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = SEEKING;
1642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler->seek(seekTimeUs);
1652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberbool NuPlayer::RTSPSource::isSeekable() {
1682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    return true;
1692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
1702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1712bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) {
1722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (msg->what() == kWhatDisconnect) {
1732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        uint32_t replyID;
1742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(msg->senderAwaitsResponse(&replyID));
1752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mDisconnectReplyID = replyID;
1772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
1782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
179ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber    } else if (msg->what() == kWhatPerformSeek) {
180ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int32_t generation;
181ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt32("generation", &generation));
182ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
183ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        if (generation != mSeekGeneration) {
184ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            // obsolete.
185ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber            return;
186ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        }
187ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
188ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        int64_t seekTimeUs;
189ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        CHECK(msg->findInt64("timeUs", &seekTimeUs));
190ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber
191ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        performSeek(seekTimeUs);
192ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber        return;
1932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
1942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_EQ(msg->what(), (int)kWhatNotify);
1962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
1972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    int32_t what;
1982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("what", &what));
1992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    switch (what) {
2012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatConnected:
2022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onConnected();
2032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatDisconnected:
2062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            onDisconnected(msg);
2072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDone:
2102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
2112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            mState = CONNECTED;
2122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
2142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatAccessUnit:
2162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
2172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
2182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
2192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
2202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<RefBase> obj;
2222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findObject("accessUnit", &obj));
2232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<ABuffer> accessUnit = static_cast<ABuffer *>(obj.get());
2252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t damaged;
2272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (accessUnit->meta()->findInt32("damaged", &damaged)
2282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                    && damaged) {
229df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("dropping damaged access unit.");
2302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                break;
2312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
2322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2331906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
2341906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
2351906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            sp<AnotherPacketSource> source = info->mSource;
2362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
2372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                uint32_t rtpTime;
2382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
2392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2401906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                if (!info->mNPTMappingValid) {
2411906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // This is a live stream, we didn't receive any normal
2421906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // playtime mapping. Assume the first packets correspond
2431906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    // to time 0.
2441906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
245d2927a79dc933a134e022281a4679a65e340dc3aOwen Lin                    ALOGV("This is a live stream, assuming time = 0");
2461906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
2471906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    info->mRTPTime = rtpTime;
2481906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    info->mNormalPlaytimeUs = 0ll;
2491906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    info->mNPTMappingValid = true;
2501906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                }
2511906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
2522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                int64_t nptUs =
2531906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                    ((double)rtpTime - (double)info->mRTPTime)
2541906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        / info->mTimeScale
2552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                        * 1000000ll
2561906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber                        + info->mNormalPlaytimeUs;
2572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                accessUnit->meta()->setInt64("timeUs", nptUs);
2592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueAccessUnit(accessUnit);
2612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
2622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
2642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatEOS:
2662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
2672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
2682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
2692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
2702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int32_t finalResult;
2722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("finalResult", &finalResult));
2732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_NE(finalResult, (status_t)OK);
2742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
2762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
2772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
2782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->signalEOS(finalResult);
2792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
2802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
2832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatSeekDiscontinuity:
2852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
2862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
2872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
2882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
2892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
2912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = info->mSource;
2922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (source != NULL) {
2932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                source->queueDiscontinuity(ATSParser::DISCONTINUITY_SEEK, NULL);
2942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
2952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
2972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
2982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
2992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        case MyHandler::kWhatNormalPlayTimeMapping:
3002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        {
3012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            size_t trackIndex;
3022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
3032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK_LT(trackIndex, mTracks.size());
3042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            uint32_t rtpTime;
3062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime));
3072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            int64_t nptUs;
3092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            CHECK(msg->findInt64("nptUs", &nptUs));
3102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TrackInfo *info = &mTracks.editItemAt(trackIndex);
3122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mRTPTime = rtpTime;
3132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info->mNormalPlaytimeUs = nptUs;
3141906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber            info->mNPTMappingValid = true;
3152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            break;
3162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        default:
3192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            TRESPASS();
3202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3232bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() {
3242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mAudioTrack == NULL);
3252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(mVideoTrack == NULL);
3262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    size_t numTracks = mHandler->countTracks();
3282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    for (size_t i = 0; i < numTracks; ++i) {
3292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        int32_t timeScale;
3302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale);
3312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        const char *mime;
3332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        CHECK(format->findCString(kKeyMIMEType, &mime));
3342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isAudio = !strncasecmp(mime, "audio/", 6);
3362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        bool isVideo = !strncasecmp(mime, "video/", 6);
3372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        TrackInfo info;
3392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mTimeScale = timeScale;
3402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mRTPTime = 0;
3412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        info.mNormalPlaytimeUs = 0ll;
3421906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        info.mNPTMappingValid = false;
3432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        if ((isAudio && mAudioTrack == NULL)
3452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                || (isVideo && mVideoTrack == NULL)) {
3462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            sp<AnotherPacketSource> source = new AnotherPacketSource(format);
3472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            if (isAudio) {
3492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mAudioTrack = source;
3502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            } else {
3512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber                mVideoTrack = source;
3522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            }
3532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber            info.mSource = source;
3552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        }
3562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mTracks.push(info);
3582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = CONNECTED;
3612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3632bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) {
3642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    status_t err;
3652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK(msg->findInt32("result", &err));
3662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    CHECK_NE(err, (status_t)OK);
3672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mLooper->unregisterHandler(mHandler->id());
3692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mHandler.clear();
3702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mState = DISCONNECTED;
3722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mFinalResult = err;
3732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mDisconnectReplyID != 0) {
3752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        finishDisconnectIfPossible();
3762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3792bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() {
3802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    if (mState != DISCONNECTED) {
3812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        mHandler->disconnect();
3822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        return;
3832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    }
3842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    (new AMessage)->postReply(mDisconnectReplyID);
3862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    mDisconnectReplyID = 0;
3872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}
3882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber
3892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber}  // namespace android
390