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 3548fa06d1e80a872c7495804979256e021e566ae0Wei Jia// Default Buffer Underflow/Prepare/StartServer/Overflow Marks 3648fa06d1e80a872c7495804979256e021e566ae0Wei Jiastatic const int kUnderflowMarkMs = 1000; // 1 second 3748fa06d1e80a872c7495804979256e021e566ae0Wei Jiastatic const int kPrepareMarkMs = 3000; // 3 seconds 3848fa06d1e80a872c7495804979256e021e566ae0Wei Jia//static const int kStartServerMarkMs = 5000; 3948fa06d1e80a872c7495804979256e021e566ae0Wei Jiastatic const int kOverflowMarkMs = 10000; // 10 seconds 40641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 412bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::RTSPSource( 425ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber const sp<AMessage> ¬ify, 431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const sp<IMediaHTTPService> &httpService, 442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber const char *url, 452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber const KeyedVector<String8, String8> *headers, 462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber bool uidValid, 4781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé uid_t uid, 4881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé bool isSDP) 495ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber : Source(notify), 501b86fe063badb5f28c467ade39be0f4008688947Andreas Huber mHTTPService(httpService), 515ab368af38fefacc4009e3ab1c1bbd00e62b3bcfAndreas Huber mURL(url), 522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mUIDValid(uidValid), 532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mUID(uid), 542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mFlags(0), 5581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mIsSDP(isSDP), 562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mState(DISCONNECTED), 572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mFinalResult(OK), 58ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber mDisconnectReplyID(0), 59180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang mBuffering(false), 60641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih mInPreparationPhase(true), 61f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih mEOSPending(false), 62cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson mSeekGeneration(0), 63cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson mEOSTimeoutAudio(0), 64cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson mEOSTimeoutVideo(0) { 659bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia mBufferingSettings.mInitialMarkMs = kPrepareMarkMs; 669bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia mBufferingSettings.mResumePlaybackMarkMs = kOverflowMarkMs; 672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (headers) { 682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mExtraHeaders = *headers; 692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber ssize_t index = 712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log")); 722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (index >= 0) { 742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mFlags |= kFlagIncognito; 752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mExtraHeaders.removeItemsAt(index); 772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 812bfdd428c56c7524d1a11979f200a1762866032dAndreas HuberNuPlayer::RTSPSource::~RTSPSource() { 82602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber if (mLooper != NULL) { 831228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang mLooper->unregisterHandler(id()); 84602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber mLooper->stop(); 85602f5bbd7596ec3fe447fde4329d5d4f0b370835Andreas Huber } 862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 889bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jiastatus_t NuPlayer::RTSPSource::getBufferingSettings( 8948fa06d1e80a872c7495804979256e021e566ae0Wei Jia BufferingSettings* buffering /* nonnull */) { 909bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia Mutex::Autolock _l(mBufferingSettingsLock); 919bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia *buffering = mBufferingSettings; 9248fa06d1e80a872c7495804979256e021e566ae0Wei Jia return OK; 9348fa06d1e80a872c7495804979256e021e566ae0Wei Jia} 9448fa06d1e80a872c7495804979256e021e566ae0Wei Jia 9548fa06d1e80a872c7495804979256e021e566ae0Wei Jiastatus_t NuPlayer::RTSPSource::setBufferingSettings(const BufferingSettings& buffering) { 969bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia Mutex::Autolock _l(mBufferingSettingsLock); 979bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia mBufferingSettings = buffering; 989bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia return OK; 9948fa06d1e80a872c7495804979256e021e566ae0Wei Jia} 10048fa06d1e80a872c7495804979256e021e566ae0Wei Jia 10157cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::prepareAsync() { 102ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia if (mIsSDP && mHTTPService == NULL) { 103ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia notifyPrepared(BAD_VALUE); 104ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia return; 105ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia } 106ce84b2240497cd0923e190ae115e319e4c17d303Wei Jia 1072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mLooper == NULL) { 1082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mLooper = new ALooper; 1092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mLooper->setName("rtsp"); 1102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mLooper->start(); 1112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1121228d6b175de8b21787cbe0c6c4bb5642f4d555eChong Zhang mLooper->registerHandler(this); 1132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 1142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(mHandler == NULL); 11681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé CHECK(mSDPLoader == NULL); 1172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> notify = new AMessage(kWhatNotify, this); 1192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK_EQ(mState, (int)DISCONNECTED); 1212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mState = CONNECTING; 1222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 12381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (mIsSDP) { 12481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mSDPLoader = new SDPLoader(notify, 12581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé (mFlags & kFlagIncognito) ? SDPLoader::kFlagIncognito : 0, 12681e68448f3361eaf8618930471fdc3c21bdf5cbcAndreas Huber mHTTPService); 12781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 12857cea553cb19235553463412db5ad04c99835411Andreas Huber mSDPLoader->load( 12957cea553cb19235553463412db5ad04c99835411Andreas Huber mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders); 13081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } else { 13181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID); 13281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mLooper->registerHandler(mHandler); 13381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 13481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mHandler->connect(); 13581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 136cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson 137180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang startBufferingIfNecessary(); 13857cea553cb19235553463412db5ad04c99835411Andreas Huber} 13957cea553cb19235553463412db5ad04c99835411Andreas Huber 14057cea553cb19235553463412db5ad04c99835411Andreas Hubervoid NuPlayer::RTSPSource::start() { 1412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 1422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1432bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::stop() { 1445834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong if (mLooper == NULL) { 1455834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong return; 1465834181d3f168acb8ff4bf3eff1fd1186afb0bd4James Dong } 1471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDisconnect, this); 1482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber sp<AMessage> dummy; 1502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber msg->postAndAwaitResponse(&dummy); 1512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 1522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::feedMoreTSData() { 154180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang Mutex::Autolock _l(mBufferingLock); 1552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return mFinalResult; 1562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 1572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 158840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Hubersp<MetaData> NuPlayer::RTSPSource::getFormatMeta(bool audio) { 1592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber sp<AnotherPacketSource> source = getSource(audio); 1602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (source == NULL) { 1622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return NULL; 1632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 1642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 1652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return source->getFormat(); 1662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 1672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 168bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huberbool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() { 169bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber // We're going to buffer at least 2 secs worth data on all tracks before 170bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber // starting playback (both at startup and after a seek). 171bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber 172bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber static const int64_t kMinDurationUs = 2000000ll; 173bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber 174cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson int64_t mediaDurationUs = 0; 175cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson getDuration(&mediaDurationUs); 176cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson if ((mAudioTrack != NULL && mAudioTrack->isFinished(mediaDurationUs)) 177cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson || (mVideoTrack != NULL && mVideoTrack->isFinished(mediaDurationUs))) { 178cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson return true; 179cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } 180cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson 181bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber status_t err; 182bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber int64_t durationUs; 183bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber if (mAudioTrack != NULL 184bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber && (durationUs = mAudioTrack->getBufferedDurationUs(&err)) 185bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber < kMinDurationUs 186bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber && err == OK) { 187bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)", 188bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber durationUs / 1E6); 189bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber return false; 190bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber } 191bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber 192bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber if (mVideoTrack != NULL 193bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber && (durationUs = mVideoTrack->getBufferedDurationUs(&err)) 194bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber < kMinDurationUs 195bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber && err == OK) { 196bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)", 197bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber durationUs / 1E6); 198bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber return false; 199bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber } 200bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber 201bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber return true; 202bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber} 203bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber 2042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::dequeueAccessUnit( 2052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber bool audio, sp<ABuffer> *accessUnit) { 206180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang if (!stopBufferingIfNecessary()) { 207180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang return -EWOULDBLOCK; 208bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber } 209bfd4d0d9fe0033abf3f55b94f30f6a58846a875eAndreas Huber 2102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber sp<AnotherPacketSource> source = getSource(audio); 2112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 2122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (source == NULL) { 2132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return -EWOULDBLOCK; 2142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 2152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 2162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber status_t finalResult; 2172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (!source->hasBufferAvailable(&finalResult)) { 218cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson if (finalResult == OK) { 219f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 220f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih // If other source already signaled EOS, this source should also return EOS 221f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (sourceReachedEOS(!audio)) { 222cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson return ERROR_END_OF_STREAM; 223cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } 224cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson 225cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson // If this source has detected near end, give it some time to retrieve more 226f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih // data before returning EOS 227f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih int64_t mediaDurationUs = 0; 228f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih getDuration(&mediaDurationUs); 229cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson if (source->isFinished(mediaDurationUs)) { 230cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson int64_t eosTimeout = audio ? mEOSTimeoutAudio : mEOSTimeoutVideo; 231cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson if (eosTimeout == 0) { 232cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson setEOSTimeout(audio, ALooper::GetNowUs()); 233cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } else if ((ALooper::GetNowUs() - eosTimeout) > kNearEOSTimeoutUs) { 234cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson setEOSTimeout(audio, 0); 235cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson return ERROR_END_OF_STREAM; 236cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } 237cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson return -EWOULDBLOCK; 238cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } 239cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson 240f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (!sourceNearEOS(!audio)) { 241cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson // We should not enter buffering mode 242cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson // if any of the sources already have detected EOS. 243180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang startBufferingIfNecessary(); 244cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } 245cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson 246cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson return -EWOULDBLOCK; 247cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } 248cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson return finalResult; 2492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 2502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 251cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson setEOSTimeout(audio, 0); 252cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson 2532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return source->dequeueAccessUnit(accessUnit); 2542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 2552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 2562bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubersp<AnotherPacketSource> NuPlayer::RTSPSource::getSource(bool audio) { 25749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber if (mTSParser != NULL) { 25849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber sp<MediaSource> source = mTSParser->getSource( 25949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber audio ? ATSParser::AUDIO : ATSParser::VIDEO); 26049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 26149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber return static_cast<AnotherPacketSource *>(source.get()); 26249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 26349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 2642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return audio ? mAudioTrack : mVideoTrack; 2652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 2662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 267cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönssonvoid NuPlayer::RTSPSource::setEOSTimeout(bool audio, int64_t timeout) { 268cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson if (audio) { 269cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson mEOSTimeoutAudio = timeout; 270cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } else { 271cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson mEOSTimeoutVideo = timeout; 272cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson } 273cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson} 274cfc3083927df14bf82403b20a45ae303a01c39f5Roger Jönsson 2752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huberstatus_t NuPlayer::RTSPSource::getDuration(int64_t *durationUs) { 2767e074a8b7548ac769d1f55addacd97f885651b0dRobert Shih *durationUs = -1ll; 2772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 2782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int64_t audioDurationUs; 2792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mAudioTrack != NULL 2802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber && mAudioTrack->getFormat()->findInt64( 2812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber kKeyDuration, &audioDurationUs) 2822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber && audioDurationUs > *durationUs) { 2832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber *durationUs = audioDurationUs; 2842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 2852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 2862bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int64_t videoDurationUs; 2872bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mVideoTrack != NULL 2882bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber && mVideoTrack->getFormat()->findInt64( 2892bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber kKeyDuration, &videoDurationUs) 2902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber && videoDurationUs > *durationUs) { 2912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber *durationUs = videoDurationUs; 2922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 2932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 2942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return OK; 2952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 2962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 297c5de09127e9e0d5df7aa587be317e1487d793245Wei Jiastatus_t NuPlayer::RTSPSource::seekTo(int64_t seekTimeUs, MediaPlayerSeekMode mode) { 2981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatPerformSeek, this); 299ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber msg->setInt32("generation", ++mSeekGeneration); 300ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber msg->setInt64("timeUs", seekTimeUs); 301c5de09127e9e0d5df7aa587be317e1487d793245Wei Jia msg->setInt32("mode", mode); 302ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber 3038d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih sp<AMessage> response; 3048d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih status_t err = msg->postAndAwaitResponse(&response); 3058d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih if (err == OK && response != NULL) { 3068d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih CHECK(response->findInt32("err", &err)); 3078d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih } 3088d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih 3098d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih return err; 310ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber} 311ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber 312ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Hubervoid NuPlayer::RTSPSource::performSeek(int64_t seekTimeUs) { 3132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mState != CONNECTED) { 3148d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih finishSeek(INVALID_OPERATION); 315ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber return; 3162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 3172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 3182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mState = SEEKING; 3192bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mHandler->seek(seekTimeUs); 320f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih mEOSPending = false; 3212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 3222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 323641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::schedulePollBuffering() { 324641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih sp<AMessage> msg = new AMessage(kWhatPollBuffering, this); 325641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih msg->post(1000000ll); // 1 second intervals 326641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih} 327641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 328641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::checkBuffering( 329f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih bool *prepared, bool *underflow, bool *overflow, bool *startServer, bool *finished) { 330641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih size_t numTracks = mTracks.size(); 331f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih size_t preparedCount, underflowCount, overflowCount, startCount, finishedCount; 332f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih preparedCount = underflowCount = overflowCount = startCount = finishedCount = 0; 333c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa 334c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa size_t count = numTracks; 335c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa for (size_t i = 0; i < count; ++i) { 336641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih status_t finalResult; 337641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih TrackInfo *info = &mTracks.editItemAt(i); 338641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih sp<AnotherPacketSource> src = info->mSource; 339c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa if (src == NULL) { 340c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa --numTracks; 341c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa continue; 342c622c584ea0ffb807eb9f711aa30016eae069c92Takahiro Aizawa } 343641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih int64_t bufferedDurationUs = src->getBufferedDurationUs(&finalResult); 344641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 3459bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia int64_t initialMarkUs; 3469bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia int64_t maxRebufferingMarkUs; 3479bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia { 3489bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia Mutex::Autolock _l(mBufferingSettingsLock); 3499bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia initialMarkUs = mBufferingSettings.mInitialMarkMs * 1000ll; 3509bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia // TODO: maxRebufferingMarkUs could be larger than 3519bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia // mBufferingSettings.mResumePlaybackMarkMs * 1000ll. 3529bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia maxRebufferingMarkUs = mBufferingSettings.mResumePlaybackMarkMs * 1000ll; 3539bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia } 354641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih // isFinished when duration is 0 checks for EOS result only 3559bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia if (bufferedDurationUs > initialMarkUs 35648fa06d1e80a872c7495804979256e021e566ae0Wei Jia || src->isFinished(/* duration */ 0)) { 357641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih ++preparedCount; 358641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 359641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 360641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih if (src->isFinished(/* duration */ 0)) { 361641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih ++overflowCount; 362f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih ++finishedCount; 363641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } else { 3649bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia // TODO: redefine kUnderflowMarkMs to a fair value, 3659bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia if (bufferedDurationUs < kUnderflowMarkMs * 1000) { 366641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih ++underflowCount; 367641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 3689bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia if (bufferedDurationUs > maxRebufferingMarkUs) { 369641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih ++overflowCount; 370641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 37148fa06d1e80a872c7495804979256e021e566ae0Wei Jia int64_t startServerMarkUs = 3729bb3803a80a680ea7a3bc11e07b8a89ccddee003Wei Jia (kUnderflowMarkMs * 1000ll + maxRebufferingMarkUs) / 2; 37348fa06d1e80a872c7495804979256e021e566ae0Wei Jia if (bufferedDurationUs < startServerMarkUs) { 374641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih ++startCount; 375641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 376641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 377641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 378641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 379641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih *prepared = (preparedCount == numTracks); 380641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih *underflow = (underflowCount > 0); 381641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih *overflow = (overflowCount == numTracks); 382641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih *startServer = (startCount > 0); 383f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih *finished = (finishedCount > 0); 384641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih} 385641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 386641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shihvoid NuPlayer::RTSPSource::onPollBuffering() { 387f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih bool prepared, underflow, overflow, startServer, finished; 388f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih checkBuffering(&prepared, &underflow, &overflow, &startServer, &finished); 389641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 390641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih if (prepared && mInPreparationPhase) { 391641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih mInPreparationPhase = false; 392641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih notifyPrepared(); 393641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 394641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 395641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih if (!mInPreparationPhase && underflow) { 396641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih startBufferingIfNecessary(); 397641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 398641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 39991ea571836401ba77854d7b3aefb3ccee9c20eb3Robert Shih if (haveSufficientDataOnAllTracks()) { 400641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih stopBufferingIfNecessary(); 40191ea571836401ba77854d7b3aefb3ccee9c20eb3Robert Shih } 40291ea571836401ba77854d7b3aefb3ccee9c20eb3Robert Shih 40391ea571836401ba77854d7b3aefb3ccee9c20eb3Robert Shih if (overflow && mHandler != NULL) { 404641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih mHandler->pause(); 405641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 406641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 407641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih if (startServer && mHandler != NULL) { 408641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih mHandler->resume(); 409641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } 410641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 411f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (finished && mHandler != NULL) { 412f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih mHandler->cancelAccessUnitTimeoutCheck(); 413f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih } 414f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 415641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih schedulePollBuffering(); 416641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih} 417641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih 418f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::signalSourceEOS(status_t result) { 419f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih const bool audio = true; 420f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih const bool video = false; 421f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 422f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih sp<AnotherPacketSource> source = getSource(audio); 423f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (source != NULL) { 424f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih source->signalEOS(result); 425f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih } 426f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 427f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih source = getSource(video); 428f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (source != NULL) { 429f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih source->signalEOS(result); 430f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih } 431f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih} 432f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 433f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihbool NuPlayer::RTSPSource::sourceReachedEOS(bool audio) { 434f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih sp<AnotherPacketSource> source = getSource(audio); 435f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih status_t finalResult; 436f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih return (source != NULL && 437f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih !source->hasBufferAvailable(&finalResult) && 438f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih finalResult == ERROR_END_OF_STREAM); 439f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih} 440f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 441f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihbool NuPlayer::RTSPSource::sourceNearEOS(bool audio) { 442f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih sp<AnotherPacketSource> source = getSource(audio); 443f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih int64_t mediaDurationUs = 0; 444f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih getDuration(&mediaDurationUs); 445f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih return (source != NULL && source->isFinished(mediaDurationUs)); 446f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih} 447f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 448f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::onSignalEOS(const sp<AMessage> &msg) { 449f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih int32_t generation; 450f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih CHECK(msg->findInt32("generation", &generation)); 451f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 452f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (generation != mSeekGeneration) { 453f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih return; 454f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih } 455f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 456f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (mEOSPending) { 457f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih signalSourceEOS(ERROR_END_OF_STREAM); 458f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih mEOSPending = false; 459f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih } 460f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih} 461f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 462f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shihvoid NuPlayer::RTSPSource::postSourceEOSIfNecessary() { 463f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih const bool audio = true; 464f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih const bool video = false; 465f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih // If a source has detected near end, give it some time to retrieve more 466f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih // data before signaling EOS 467f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (sourceNearEOS(audio) || sourceNearEOS(video)) { 468f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih if (!mEOSPending) { 469f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih sp<AMessage> msg = new AMessage(kWhatSignalEOS, this); 470f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih msg->setInt32("generation", mSeekGeneration); 471f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih msg->post(kNearEOSTimeoutUs); 472f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih mEOSPending = true; 473f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih } 474f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih } 475f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih} 476f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 4772bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { 4782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (msg->what() == kWhatDisconnect) { 4793f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 4802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 4812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 4822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mDisconnectReplyID = replyID; 4832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber finishDisconnectIfPossible(); 4842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return; 485ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber } else if (msg->what() == kWhatPerformSeek) { 486ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber int32_t generation; 487ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber CHECK(msg->findInt32("generation", &generation)); 4888d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih CHECK(msg->senderAwaitsResponse(&mSeekReplyID)); 489ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber 490ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber if (generation != mSeekGeneration) { 491ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber // obsolete. 4928d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih finishSeek(OK); 493ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber return; 494ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber } 495ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber 496ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber int64_t seekTimeUs; 497c5de09127e9e0d5df7aa587be317e1487d793245Wei Jia int32_t mode; 498ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber CHECK(msg->findInt64("timeUs", &seekTimeUs)); 499c5de09127e9e0d5df7aa587be317e1487d793245Wei Jia CHECK(msg->findInt32("mode", &mode)); 500ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber 501c5de09127e9e0d5df7aa587be317e1487d793245Wei Jia // TODO: add "mode" to performSeek. 502c5de09127e9e0d5df7aa587be317e1487d793245Wei Jia performSeek(seekTimeUs/*, (MediaPlayerSeekMode)mode */); 503ee736e9e74c5368db8d63214513c85cb74bb0183Andreas Huber return; 504641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih } else if (msg->what() == kWhatPollBuffering) { 505641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih onPollBuffering(); 506641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih return; 507f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih } else if (msg->what() == kWhatSignalEOS) { 508f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih onSignalEOS(msg); 509f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih return; 5102bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 5112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 512b8c35f94470d1518e2def0582aaec4e038c92af0Colin Cross CHECK_EQ(msg->what(), kWhatNotify); 5132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 5142bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int32_t what; 5152bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->findInt32("what", &what)); 5162bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 5172bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber switch (what) { 5182bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber case MyHandler::kWhatConnected: 5197f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber { 5202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber onConnected(); 5217f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber 522ced1c2f8f6c422063092f5cc5c675ccdebb2dc10Chong Zhang notifyVideoSizeChanged(); 5237f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber 5247f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber uint32_t flags = 0; 5257f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber 5267f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber if (mHandler->isSeekable()) { 5274b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang flags = FLAG_CAN_PAUSE 5284b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang | FLAG_CAN_SEEK 5294b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang | FLAG_CAN_SEEK_BACKWARD 5304b7069dac546ad21cf62ca6132d50ea41857d08eChong Zhang | FLAG_CAN_SEEK_FORWARD; 5317f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber } 5327f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber 5337f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber notifyFlagsChanged(flags); 534641e0c718da1c58e5b89379f60465c4e564ebb73Robert Shih schedulePollBuffering(); 5352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber break; 5367f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber } 5372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 5382bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber case MyHandler::kWhatDisconnected: 5397f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber { 5402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber onDisconnected(msg); 5412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber break; 5427f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber } 5432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 5442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber case MyHandler::kWhatSeekDone: 5452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber { 5462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mState = CONNECTED; 5474ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia // Unblock seekTo here in case we attempted to seek in a live stream 5484ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia finishSeek(OK); 5498d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih break; 5508d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih } 5518d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih 5528d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih case MyHandler::kWhatSeekPaused: 5538d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih { 5548d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih sp<AnotherPacketSource> source = getSource(true /* audio */); 5558d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih if (source != NULL) { 5568d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE, 5578d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih /* extra */ NULL, 5588d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih /* discard */ true); 5598d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih } 5608d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih source = getSource(false /* video */); 5618d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih if (source != NULL) { 5628d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih source->queueDiscontinuity(ATSParser::DISCONTINUITY_NONE, 5638d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih /* extra */ NULL, 5648d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih /* discard */ true); 5658d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih }; 5668d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih 5678d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih status_t err = OK; 5688d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih msg->findInt32("err", &err); 5698d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih 5708d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih if (err == OK) { 5718d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih int64_t timeUs; 5728d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih CHECK(msg->findInt64("time", &timeUs)); 5738d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih mHandler->continueSeekAfterPause(timeUs); 5744ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia } else { 5754ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia finishSeek(err); 5768d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih } 5772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber break; 5782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 5792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 5802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber case MyHandler::kWhatAccessUnit: 5812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber { 5822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber size_t trackIndex; 5832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 58449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 58549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber if (mTSParser == NULL) { 58649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber CHECK_LT(trackIndex, mTracks.size()); 58749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } else { 58849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber CHECK_EQ(trackIndex, 0u); 58949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 5902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 5912d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> accessUnit; 5922d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 5932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 5942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int32_t damaged; 5952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (accessUnit->meta()->findInt32("damaged", &damaged) 5962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber && damaged) { 597df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("dropping damaged access unit."); 5982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber break; 5992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 6002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 60149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber if (mTSParser != NULL) { 60249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber size_t offset = 0; 60349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber status_t err = OK; 60449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber while (offset + 188 <= accessUnit->size()) { 60549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber err = mTSParser->feedTSPacket( 60649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber accessUnit->data() + offset, 188); 60749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber if (err != OK) { 60849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber break; 60949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 61049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 61149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber offset += 188; 61249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 61349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 61449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber if (offset < accessUnit->size()) { 61549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber err = ERROR_MALFORMED; 61649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 61749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 61849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber if (err != OK) { 619f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih signalSourceEOS(err); 62049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 621f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih 622f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih postSourceEOSIfNecessary(); 62349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber break; 62449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 62549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 6261906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber TrackInfo *info = &mTracks.editItemAt(trackIndex); 6271906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber 6281906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber sp<AnotherPacketSource> source = info->mSource; 6292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (source != NULL) { 6302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber uint32_t rtpTime; 6312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(accessUnit->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 6322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6331906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber if (!info->mNPTMappingValid) { 6341906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber // This is a live stream, we didn't receive any normal 635c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber // playtime mapping. We won't map to npt time. 636c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber source->queueAccessUnit(accessUnit); 637c9d1696d214d2175327067ccc1991bcb36976404Andreas Huber break; 6381906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber } 6391906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber 6402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int64_t nptUs = 6411906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber ((double)rtpTime - (double)info->mRTPTime) 6421906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber / info->mTimeScale 6432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber * 1000000ll 6441906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber + info->mNormalPlaytimeUs; 6452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber accessUnit->meta()->setInt64("timeUs", nptUs); 6472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber source->queueAccessUnit(accessUnit); 6492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 650f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih postSourceEOSIfNecessary(); 6512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber break; 6522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 6532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber case MyHandler::kWhatEOS: 6552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber { 6562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int32_t finalResult; 6572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->findInt32("finalResult", &finalResult)); 6582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK_NE(finalResult, (status_t)OK); 6592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 66049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber if (mTSParser != NULL) { 661f1d261f1b5914ddc219a23b763ab19363eeedd85Robert Shih signalSourceEOS(finalResult); 66249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 66349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 66449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber size_t trackIndex; 66549694688c82214f5fd9e969e177c9e126a240a26Andreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 66649694688c82214f5fd9e969e177c9e126a240a26Andreas Huber CHECK_LT(trackIndex, mTracks.size()); 66749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 6682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber TrackInfo *info = &mTracks.editItemAt(trackIndex); 6692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber sp<AnotherPacketSource> source = info->mSource; 6702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (source != NULL) { 6712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber source->signalEOS(finalResult); 6722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 6732bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber break; 6752bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 6762bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6772bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber case MyHandler::kWhatSeekDiscontinuity: 6782bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber { 6792bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber size_t trackIndex; 6802bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 6812bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK_LT(trackIndex, mTracks.size()); 6822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber TrackInfo *info = &mTracks.editItemAt(trackIndex); 6842bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber sp<AnotherPacketSource> source = info->mSource; 6852bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (source != NULL) { 686632740c58119a132ce19f6d498e39c5c3773971aChong Zhang source->queueDiscontinuity( 687fef808d42a9c94b0b5ef3c3d5fb0a090edbc42daWei Jia ATSParser::DISCONTINUITY_TIME, 688632740c58119a132ce19f6d498e39c5c3773971aChong Zhang NULL, 689632740c58119a132ce19f6d498e39c5c3773971aChong Zhang true /* discard */); 6902bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 6912bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6922bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber break; 6932bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 6942bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 6952bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber case MyHandler::kWhatNormalPlayTimeMapping: 6962bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber { 6972bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber size_t trackIndex; 6982bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 6992bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK_LT(trackIndex, mTracks.size()); 7002bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7012bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber uint32_t rtpTime; 7022bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->findInt32("rtpTime", (int32_t *)&rtpTime)); 7032bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int64_t nptUs; 7052bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->findInt64("nptUs", &nptUs)); 7062bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7072bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber TrackInfo *info = &mTracks.editItemAt(trackIndex); 7082bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber info->mRTPTime = rtpTime; 7092bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber info->mNormalPlaytimeUs = nptUs; 7101906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber info->mNPTMappingValid = true; 7112bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber break; 7122bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 7132bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 71481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé case SDPLoader::kWhatSDPLoaded: 71581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé { 71681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé onSDPLoaded(msg); 71781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé break; 71881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 71981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 7202bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber default: 7212bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber TRESPASS(); 7222bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 7232bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 7242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7252bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onConnected() { 7262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(mAudioTrack == NULL); 7272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(mVideoTrack == NULL); 7282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber size_t numTracks = mHandler->countTracks(); 7302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber for (size_t i = 0; i < numTracks; ++i) { 7312bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber int32_t timeScale; 7322bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber sp<MetaData> format = mHandler->getTrackFormat(i, &timeScale); 7332bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7342bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber const char *mime; 7352bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(format->findCString(kKeyMIMEType, &mime)); 7362bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 73749694688c82214f5fd9e969e177c9e126a240a26Andreas Huber if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2TS)) { 73849694688c82214f5fd9e969e177c9e126a240a26Andreas Huber // Very special case for MPEG2 Transport Streams. 73949694688c82214f5fd9e969e177c9e126a240a26Andreas Huber CHECK_EQ(numTracks, 1u); 74049694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 74149694688c82214f5fd9e969e177c9e126a240a26Andreas Huber mTSParser = new ATSParser; 74249694688c82214f5fd9e969e177c9e126a240a26Andreas Huber return; 74349694688c82214f5fd9e969e177c9e126a240a26Andreas Huber } 74449694688c82214f5fd9e969e177c9e126a240a26Andreas Huber 7452bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber bool isAudio = !strncasecmp(mime, "audio/", 6); 7462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber bool isVideo = !strncasecmp(mime, "video/", 6); 7472bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7482bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber TrackInfo info; 7492bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber info.mTimeScale = timeScale; 7502bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber info.mRTPTime = 0; 7512bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber info.mNormalPlaytimeUs = 0ll; 7521906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber info.mNPTMappingValid = false; 7532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if ((isAudio && mAudioTrack == NULL) 7552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber || (isVideo && mVideoTrack == NULL)) { 7562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber sp<AnotherPacketSource> source = new AnotherPacketSource(format); 7572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (isAudio) { 7592bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mAudioTrack = source; 7602bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } else { 7612bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mVideoTrack = source; 7622bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 7632bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7642bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber info.mSource = source; 7652bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 7662bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7672bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mTracks.push(info); 7682bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 7692bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 7702bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mState = CONNECTED; 7712bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 7722bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 77381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhévoid NuPlayer::RTSPSource::onSDPLoaded(const sp<AMessage> &msg) { 77481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé status_t err; 77581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé CHECK(msg->findInt32("result", &err)); 77681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 77781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mSDPLoader.clear(); 77881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 77981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (mDisconnectReplyID != 0) { 78081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé err = UNKNOWN_ERROR; 78181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 78281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 78381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (err == OK) { 78481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé sp<ASessionDescription> desc; 78581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé sp<RefBase> obj; 78681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé CHECK(msg->findObject("description", &obj)); 78781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé desc = static_cast<ASessionDescription *>(obj.get()); 78881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 78981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé AString rtspUri; 79081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (!desc->findAttribute(0, "a=control", &rtspUri)) { 79181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé ALOGE("Unable to find url in SDP"); 79281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé err = UNKNOWN_ERROR; 79381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } else { 7941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> notify = new AMessage(kWhatNotify, this); 79581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 79681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID); 79781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mLooper->registerHandler(mHandler); 79881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 79981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mHandler->loadSDP(desc); 80081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 80181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 80281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 80381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (err != OK) { 8047f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber if (mState == CONNECTING) { 8057f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber // We're still in the preparation phase, signal that it 8067f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber // failed. 8077f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber notifyPrepared(err); 8087f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber } 8097f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber 81081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mState = DISCONNECTED; 811180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang setError(err); 81281dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 81381dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (mDisconnectReplyID != 0) { 81481dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé finishDisconnectIfPossible(); 81581dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 81681dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 81781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé} 81881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé 8192bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::onDisconnected(const sp<AMessage> &msg) { 8200ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin if (mState == DISCONNECTED) { 8210ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin return; 8220ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin } 8230ad03bc59d090a0455f858d2f629834c105f6f37Fredrik Rosin 8242bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber status_t err; 8252bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK(msg->findInt32("result", &err)); 8262bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber CHECK_NE(err, (status_t)OK); 8272bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 8282bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mLooper->unregisterHandler(mHandler->id()); 8292bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mHandler.clear(); 8302bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 8317f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber if (mState == CONNECTING) { 8327f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber // We're still in the preparation phase, signal that it 8337f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber // failed. 8347f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber notifyPrepared(err); 8357f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber } 8367f475c34ffc8e35345f2cceee2ef56a50bb5fea6Andreas Huber 8372bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mState = DISCONNECTED; 838180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang setError(err); 8392bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 8402bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mDisconnectReplyID != 0) { 8412bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber finishDisconnectIfPossible(); 8422bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 8432bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 8442bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 8452bfdd428c56c7524d1a11979f200a1762866032dAndreas Hubervoid NuPlayer::RTSPSource::finishDisconnectIfPossible() { 8462bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber if (mState != DISCONNECTED) { 84781dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé if (mHandler != NULL) { 84881dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mHandler->disconnect(); 84981dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } else if (mSDPLoader != NULL) { 85081dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé mSDPLoader->cancel(); 85181dd60e0340ddcf7f1d5fb80b6c30906fabf201aOscar Rydhé } 8522bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber return; 8532bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber } 8542bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 8552bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber (new AMessage)->postReply(mDisconnectReplyID); 8562bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber mDisconnectReplyID = 0; 8572bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} 8582bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber 859180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::setError(status_t err) { 860180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang Mutex::Autolock _l(mBufferingLock); 861180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang mFinalResult = err; 862180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang} 863180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 864180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangvoid NuPlayer::RTSPSource::startBufferingIfNecessary() { 865180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang Mutex::Autolock _l(mBufferingLock); 866180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 867180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang if (!mBuffering) { 868180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang mBuffering = true; 869180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 870180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang sp<AMessage> notify = dupNotify(); 871c9ff2009a0a010eeaba80d76493fbf33fcb561c8Wei Jia notify->setInt32("what", kWhatPauseOnBufferingStart); 872180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang notify->post(); 873180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang } 874180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang} 875180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 876180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhangbool NuPlayer::RTSPSource::stopBufferingIfNecessary() { 877180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang Mutex::Autolock _l(mBufferingLock); 878180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 879180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang if (mBuffering) { 880180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang if (!haveSufficientDataOnAllTracks()) { 881180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang return false; 882180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang } 883180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 884180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang mBuffering = false; 885180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 886180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang sp<AMessage> notify = dupNotify(); 887c9ff2009a0a010eeaba80d76493fbf33fcb561c8Wei Jia notify->setInt32("what", kWhatResumeOnBufferingEnd); 888180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang notify->post(); 889180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang } 890180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 891180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang return true; 892180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang} 893180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 8948d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shihvoid NuPlayer::RTSPSource::finishSeek(status_t err) { 8954ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia if (mSeekReplyID == NULL) { 8964ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia return; 8974ad74b2b4507c8b2714b7b7584578d2d43ae2633Wei Jia } 8988d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih sp<AMessage> seekReply = new AMessage; 8998d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih seekReply->setInt32("err", err); 9008d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih seekReply->postReply(mSeekReplyID); 9018d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih mSeekReplyID = NULL; 9028d237a5ce1e3c1dbc1d538f47e68cff2cc52d799Robert Shih} 903180d1b96ee2312f1056a58e26884a89d25ab62c8Chong Zhang 9042bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber} // namespace android 905