LiveSession.h revision 5abbd3dcbb0bb32a3d4b90dddbcf90458967eb6f
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef LIVE_SESSION_H_ 18 19#define LIVE_SESSION_H_ 20 21#include <media/stagefright/foundation/AHandler.h> 22#include <media/mediaplayer.h> 23 24#include <utils/String8.h> 25 26#include "mpeg2ts/ATSParser.h" 27 28namespace android { 29 30struct ABuffer; 31struct AReplyToken; 32struct AnotherPacketSource; 33class DataSource; 34struct HTTPBase; 35struct IMediaHTTPService; 36struct LiveDataSource; 37struct M3UParser; 38struct PlaylistFetcher; 39struct HLSTime; 40struct HTTPDownloader; 41 42struct LiveSession : public AHandler { 43 enum Flags { 44 // Don't log any URLs. 45 kFlagIncognito = 1, 46 }; 47 48 enum StreamIndex { 49 kAudioIndex = 0, 50 kVideoIndex = 1, 51 kSubtitleIndex = 2, 52 kMaxStreams = 3, 53 kMetaDataIndex = 3, 54 kNumSources = 4, 55 }; 56 57 enum StreamType { 58 STREAMTYPE_AUDIO = 1 << kAudioIndex, 59 STREAMTYPE_VIDEO = 1 << kVideoIndex, 60 STREAMTYPE_SUBTITLES = 1 << kSubtitleIndex, 61 STREAMTYPE_METADATA = 1 << kMetaDataIndex, 62 }; 63 64 enum SeekMode { 65 kSeekModeExactPosition = 0, // used for seeking 66 kSeekModeNextSample = 1, // used for seamless switching 67 kSeekModeNextSegment = 2, // used for seamless switching 68 }; 69 70 LiveSession( 71 const sp<AMessage> ¬ify, 72 uint32_t flags, 73 const sp<IMediaHTTPService> &httpService); 74 75 int64_t calculateMediaTimeUs(int64_t firstTimeUs, int64_t timeUs, int32_t discontinuitySeq); 76 status_t dequeueAccessUnit(StreamType stream, sp<ABuffer> *accessUnit); 77 78 status_t getStreamFormat(StreamType stream, sp<AMessage> *format); 79 80 sp<HTTPDownloader> getHTTPDownloader(); 81 82 void connectAsync( 83 const char *url, 84 const KeyedVector<String8, String8> *headers = NULL); 85 86 status_t disconnect(); 87 88 // Blocks until seek is complete. 89 status_t seekTo(int64_t timeUs); 90 91 status_t getDuration(int64_t *durationUs) const; 92 size_t getTrackCount() const; 93 sp<AMessage> getTrackInfo(size_t trackIndex) const; 94 status_t selectTrack(size_t index, bool select); 95 ssize_t getSelectedTrack(media_track_type /* type */) const; 96 97 bool isSeekable() const; 98 bool hasDynamicDuration() const; 99 100 static const char *getKeyForStream(StreamType type); 101 static const char *getNameForStream(StreamType type); 102 static ATSParser::SourceType getSourceTypeForStream(StreamType type); 103 104 enum { 105 kWhatStreamsChanged, 106 kWhatError, 107 kWhatPrepared, 108 kWhatPreparationFailed, 109 kWhatBufferingStart, 110 kWhatBufferingEnd, 111 kWhatBufferingUpdate, 112 kWhatMetadataDetected, 113 }; 114 115protected: 116 virtual ~LiveSession(); 117 118 virtual void onMessageReceived(const sp<AMessage> &msg); 119 120private: 121 friend struct PlaylistFetcher; 122 123 enum { 124 kWhatConnect = 'conn', 125 kWhatDisconnect = 'disc', 126 kWhatSeek = 'seek', 127 kWhatFetcherNotify = 'notf', 128 kWhatChangeConfiguration = 'chC0', 129 kWhatChangeConfiguration2 = 'chC2', 130 kWhatChangeConfiguration3 = 'chC3', 131 kWhatPollBuffering = 'poll', 132 }; 133 134 // Bandwidth Switch Mark Defaults 135 static const int64_t kUpSwitchMarkUs; 136 static const int64_t kDownSwitchMarkUs; 137 static const int64_t kUpSwitchMarginUs; 138 static const int64_t kResumeThresholdUs; 139 140 // Buffer Prepare/Ready/Underflow Marks 141 static const int64_t kReadyMarkUs; 142 static const int64_t kPrepareMarkUs; 143 static const int64_t kUnderflowMarkUs; 144 145 struct BandwidthEstimator; 146 struct BandwidthItem { 147 size_t mPlaylistIndex; 148 unsigned long mBandwidth; 149 }; 150 151 struct FetcherInfo { 152 sp<PlaylistFetcher> mFetcher; 153 int64_t mDurationUs; 154 bool mToBeRemoved; 155 bool mToBeResumed; 156 }; 157 158 struct StreamItem { 159 const char *mType; 160 AString mUri, mNewUri; 161 SeekMode mSeekMode; 162 size_t mCurDiscontinuitySeq; 163 int64_t mLastDequeuedTimeUs; 164 int64_t mLastSampleDurationUs; 165 StreamItem() 166 : StreamItem("") {} 167 StreamItem(const char *type) 168 : mType(type), 169 mSeekMode(kSeekModeExactPosition) { 170 reset(); 171 } 172 void reset() { 173 mCurDiscontinuitySeq = 0; 174 mLastDequeuedTimeUs = -1ll; 175 mLastSampleDurationUs = 0ll; 176 } 177 AString uriKey() { 178 AString key(mType); 179 key.append("URI"); 180 return key; 181 } 182 }; 183 StreamItem mStreams[kMaxStreams]; 184 185 sp<AMessage> mNotify; 186 uint32_t mFlags; 187 sp<IMediaHTTPService> mHTTPService; 188 189 bool mBuffering; 190 bool mInPreparationPhase; 191 int32_t mPollBufferingGeneration; 192 int32_t mPrevBufferPercentage; 193 194 KeyedVector<String8, String8> mExtraHeaders; 195 196 AString mMasterURL; 197 198 Vector<BandwidthItem> mBandwidthItems; 199 ssize_t mCurBandwidthIndex; 200 ssize_t mOrigBandwidthIndex; 201 int32_t mLastBandwidthBps; 202 sp<BandwidthEstimator> mBandwidthEstimator; 203 204 sp<M3UParser> mPlaylist; 205 int32_t mMaxWidth; 206 int32_t mMaxHeight; 207 208 sp<ALooper> mFetcherLooper; 209 KeyedVector<AString, FetcherInfo> mFetcherInfos; 210 uint32_t mStreamMask; 211 212 // Masks used during reconfiguration: 213 // mNewStreamMask: streams in the variant playlist we're switching to; 214 // we don't want to immediately overwrite the original value. 215 uint32_t mNewStreamMask; 216 217 // mSwapMask: streams that have started to playback content in the new variant playlist; 218 // we use this to track reconfiguration progress. 219 uint32_t mSwapMask; 220 221 KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources; 222 // A second set of packet sources that buffer content for the variant we're switching to. 223 KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources2; 224 225 int32_t mSwitchGeneration; 226 int32_t mSubtitleGeneration; 227 228 size_t mContinuationCounter; 229 sp<AMessage> mContinuation; 230 sp<AMessage> mSeekReply; 231 232 int64_t mLastDequeuedTimeUs; 233 int64_t mRealTimeBaseUs; 234 235 bool mReconfigurationInProgress; 236 bool mSwitchInProgress; 237 int64_t mUpSwitchMark; 238 int64_t mDownSwitchMark; 239 int64_t mUpSwitchMargin; 240 241 sp<AReplyToken> mDisconnectReplyID; 242 sp<AReplyToken> mSeekReplyID; 243 244 bool mFirstTimeUsValid; 245 int64_t mFirstTimeUs; 246 int64_t mLastSeekTimeUs; 247 bool mHasMetadata; 248 249 KeyedVector<size_t, int64_t> mDiscontinuityAbsStartTimesUs; 250 KeyedVector<size_t, int64_t> mDiscontinuityOffsetTimesUs; 251 252 sp<PlaylistFetcher> addFetcher(const char *uri); 253 254 void onConnect(const sp<AMessage> &msg); 255 void onMasterPlaylistFetched(const sp<AMessage> &msg); 256 void onSeek(const sp<AMessage> &msg); 257 258 bool UriIsSameAsIndex( const AString &uri, int32_t index, bool newUri); 259 sp<AnotherPacketSource> getPacketSourceForStreamIndex(size_t trackIndex, bool newUri); 260 sp<AnotherPacketSource> getMetadataSource( 261 sp<AnotherPacketSource> sources[kNumSources], uint32_t streamMask, bool newUri); 262 263 bool resumeFetcher( 264 const AString &uri, uint32_t streamMask, 265 int64_t timeUs = -1ll, bool newUri = false); 266 267 float getAbortThreshold( 268 ssize_t currentBWIndex, ssize_t targetBWIndex) const; 269 void addBandwidthMeasurement(size_t numBytes, int64_t delayUs); 270 size_t getBandwidthIndex(int32_t bandwidthBps); 271 HLSTime latestMediaSegmentStartTime() const; 272 273 static int SortByBandwidth(const BandwidthItem *, const BandwidthItem *); 274 static StreamType indexToType(int idx); 275 static ssize_t typeToIndex(int32_t type); 276 277 void changeConfiguration( 278 int64_t timeUs, ssize_t bwIndex = -1, bool pickTrack = false); 279 void onChangeConfiguration(const sp<AMessage> &msg); 280 void onChangeConfiguration2(const sp<AMessage> &msg); 281 void onChangeConfiguration3(const sp<AMessage> &msg); 282 283 void swapPacketSource(StreamType stream); 284 void tryToFinishBandwidthSwitch(const AString &oldUri); 285 void cancelBandwidthSwitch(bool resume = false); 286 bool checkSwitchProgress( 287 sp<AMessage> &msg, int64_t delayUs, bool *needResumeUntil); 288 289 bool switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow); 290 291 void schedulePollBuffering(); 292 void cancelPollBuffering(); 293 void restartPollBuffering(); 294 void onPollBuffering(); 295 bool checkBuffering(bool &underflow, bool &ready, bool &down, bool &up); 296 void startBufferingIfNecessary(); 297 void stopBufferingIfNecessary(); 298 void notifyBufferingUpdate(int32_t percentage); 299 300 void finishDisconnect(); 301 302 void postPrepared(status_t err); 303 void postError(status_t err); 304 305 DISALLOW_EVIL_CONSTRUCTORS(LiveSession); 306}; 307 308} // namespace android 309 310#endif // LIVE_SESSION_H_ 311