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