1 /* 2 * Copyright (C) 2012 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 PLAYLIST_FETCHER_H_ 18 19 #define PLAYLIST_FETCHER_H_ 20 21 #include <media/stagefright/foundation/AHandler.h> 22 #include <openssl/aes.h> 23 24 #include "mpeg2ts/ATSParser.h" 25 #include "LiveSession.h" 26 27 namespace android { 28 29 struct ABuffer; 30 struct AnotherPacketSource; 31 class DataSource; 32 struct HTTPBase; 33 struct LiveDataSource; 34 struct M3UParser; 35 class String8; 36 37 struct PlaylistFetcher : public AHandler { 38 static const int64_t kMinBufferedDurationUs; 39 static const int32_t kDownloadBlockSize; 40 static const int64_t kFetcherResumeThreshold; 41 42 enum { 43 kWhatStarted, 44 kWhatPaused, 45 kWhatStopped, 46 kWhatError, 47 kWhatDurationUpdate, 48 kWhatTargetDurationUpdate, 49 kWhatPrepared, 50 kWhatPreparationFailed, 51 kWhatStartedAt, 52 kWhatStopReached, 53 kWhatPlaylistFetched, 54 kWhatMetadataDetected, 55 }; 56 57 PlaylistFetcher( 58 const sp<AMessage> ¬ify, 59 const sp<LiveSession> &session, 60 const char *uri, 61 int32_t id, 62 int32_t subtitleGeneration); 63 64 int32_t getFetcherID() const; 65 66 void startAsync( 67 const sp<AnotherPacketSource> &audioSource, 68 const sp<AnotherPacketSource> &videoSource, 69 const sp<AnotherPacketSource> &subtitleSource, 70 const sp<AnotherPacketSource> &metadataSource, 71 int64_t startTimeUs = -1ll, // starting timestamps 72 int64_t segmentStartTimeUs = -1ll, // starting position within playlist 73 // startTimeUs!=segmentStartTimeUs only when playlist is live 74 int32_t startDiscontinuitySeq = -1, 75 LiveSession::SeekMode seekMode = LiveSession::kSeekModeExactPosition); 76 77 void pauseAsync(float thresholdRatio, bool disconnect); 78 79 void stopAsync(bool clear = true); 80 81 void resumeUntilAsync(const sp<AMessage> ¶ms); 82 83 void fetchPlaylistAsync(); 84 getStreamTypeMaskPlaylistFetcher85 uint32_t getStreamTypeMask() const { 86 return mStreamTypeMask; 87 } 88 89 protected: 90 virtual ~PlaylistFetcher(); 91 virtual void onMessageReceived(const sp<AMessage> &msg); 92 93 private: 94 enum { 95 kMaxNumRetries = 5, 96 }; 97 98 enum { 99 kWhatStart = 'strt', 100 kWhatPause = 'paus', 101 kWhatStop = 'stop', 102 kWhatMonitorQueue = 'moni', 103 kWhatResumeUntil = 'rsme', 104 kWhatDownloadNext = 'dlnx', 105 kWhatFetchPlaylist = 'flst' 106 }; 107 108 struct DownloadState; 109 110 static const int64_t kMaxMonitorDelayUs; 111 static const int32_t kNumSkipFrames; 112 113 static bool bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer); 114 static bool bufferStartsWithWebVTTMagicSequence(const sp<ABuffer>& buffer); 115 116 // notifications to mSession 117 sp<AMessage> mNotify; 118 sp<AMessage> mStartTimeUsNotify; 119 120 sp<HTTPDownloader> mHTTPDownloader; 121 sp<LiveSession> mSession; 122 AString mURI; 123 124 int32_t mFetcherID; 125 126 uint32_t mStreamTypeMask; 127 int64_t mStartTimeUs; 128 129 // Start time relative to the beginning of the first segment in the initial 130 // playlist. It's value is initialized to a non-negative value only when we are 131 // adapting or switching tracks. 132 int64_t mSegmentStartTimeUs; 133 134 int32_t mDiscontinuitySeq; 135 bool mStartTimeUsRelative; 136 sp<AMessage> mStopParams; // message containing the latest timestamps we should fetch. 137 138 KeyedVector<LiveSession::StreamType, sp<AnotherPacketSource> > 139 mPacketSources; 140 141 KeyedVector<AString, sp<ABuffer> > mAESKeyForURI; 142 143 int64_t mLastPlaylistFetchTimeUs; 144 int64_t mPlaylistTimeUs; 145 sp<M3UParser> mPlaylist; 146 int32_t mSeqNumber; 147 int32_t mNumRetries; 148 bool mStartup; 149 bool mIDRFound; 150 int32_t mSeekMode; 151 bool mTimeChangeSignaled; 152 int64_t mNextPTSTimeUs; 153 154 int32_t mMonitorQueueGeneration; 155 const int32_t mSubtitleGeneration; 156 157 int32_t mLastDiscontinuitySeq; 158 159 enum RefreshState { 160 INITIAL_MINIMUM_RELOAD_DELAY, 161 FIRST_UNCHANGED_RELOAD_ATTEMPT, 162 SECOND_UNCHANGED_RELOAD_ATTEMPT, 163 THIRD_UNCHANGED_RELOAD_ATTEMPT 164 }; 165 RefreshState mRefreshState; 166 167 uint8_t mPlaylistHash[16]; 168 169 sp<ATSParser> mTSParser; 170 171 bool mFirstPTSValid; 172 int64_t mFirstTimeUs; 173 int64_t mSegmentFirstPTS; 174 sp<AnotherPacketSource> mVideoBuffer; 175 176 // Stores the initialization vector to decrypt the next block of cipher text, which can 177 // either be derived from the sequence number, read from the manifest, or copied from 178 // the last block of cipher text (cipher-block chaining). 179 unsigned char mAESInitVec[AES_BLOCK_SIZE]; 180 unsigned char mKeyData[AES_BLOCK_SIZE]; 181 bool mSampleAesKeyItemChanged; 182 sp<AMessage> mSampleAesKeyItem; 183 184 Mutex mThresholdLock; 185 float mThresholdRatio; 186 187 sp<DownloadState> mDownloadState; 188 189 bool mHasMetadata; 190 191 // Set first to true if decrypting the first segment of a playlist segment. When 192 // first is true, reset the initialization vector based on the available 193 // information in the manifest; otherwise, use the initialization vector as 194 // updated by the last call to AES_cbc_encrypt. 195 // 196 // For the input to decrypt correctly, decryptBuffer must be called on 197 // consecutive byte ranges on block boundaries, e.g. 0..15, 16..47, 48..63, 198 // and so on. 199 status_t decryptBuffer( 200 size_t playlistIndex, const sp<ABuffer> &buffer, 201 bool first = true); 202 status_t checkDecryptPadding(const sp<ABuffer> &buffer); 203 204 void postMonitorQueue(int64_t delayUs = 0, int64_t minDelayUs = 0); 205 void cancelMonitorQueue(); 206 void setStoppingThreshold(float thresholdRatio, bool disconnect); 207 void resetStoppingThreshold(bool disconnect); 208 float getStoppingThreshold(); 209 bool shouldPauseDownload(); 210 211 int64_t delayUsToRefreshPlaylist() const; 212 status_t refreshPlaylist(); 213 214 // Returns the media time in us of the segment specified by seqNumber. 215 // This is computed by summing the durations of all segments before it. 216 int64_t getSegmentStartTimeUs(int32_t seqNumber) const; 217 // Returns the duration time in us of the segment specified. 218 int64_t getSegmentDurationUs(int32_t seqNumber) const; 219 220 status_t onStart(const sp<AMessage> &msg); 221 void onPause(); 222 void onStop(const sp<AMessage> &msg); 223 void onMonitorQueue(); 224 void onDownloadNext(); 225 void initSeqNumberForLiveStream( 226 int32_t &firstSeqNumberInPlaylist, 227 int32_t &lastSeqNumberInPlaylist); 228 bool initDownloadState( 229 AString &uri, 230 sp<AMessage> &itemMeta, 231 int32_t &firstSeqNumberInPlaylist, 232 int32_t &lastSeqNumberInPlaylist); 233 234 // Resume a fetcher to continue until the stopping point stored in msg. 235 status_t onResumeUntil(const sp<AMessage> &msg); 236 237 const sp<ABuffer> &setAccessUnitProperties( 238 const sp<ABuffer> &accessUnit, 239 const sp<AnotherPacketSource> &source, 240 bool discard = false); 241 bool isStartTimeReached(int64_t timeUs); 242 status_t extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer); 243 244 status_t extractAndQueueAccessUnits( 245 const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta); 246 247 void notifyStopReached(); 248 void notifyError(status_t err); 249 250 void queueDiscontinuity( 251 ATSParser::DiscontinuityType type, const sp<AMessage> &extra); 252 253 bool adjustSeqNumberWithAnchorTime(int64_t anchorTimeUs); 254 int32_t getSeqNumberForDiscontinuity(size_t discontinuitySeq) const; 255 int32_t getSeqNumberForTime(int64_t timeUs) const; 256 257 void updateDuration(); 258 void updateTargetDuration(); 259 260 DISALLOW_EVIL_CONSTRUCTORS(PlaylistFetcher); 261 }; 262 263 } // namespace android 264 265 #endif // PLAYLIST_FETCHER_H_ 266 267