Home | History | Annotate | Download | only in httplive
      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 
     28 namespace android {
     29 
     30 struct ABuffer;
     31 struct AReplyToken;
     32 struct AnotherPacketSource;
     33 class DataSource;
     34 struct HTTPBase;
     35 struct IMediaHTTPService;
     36 struct LiveDataSource;
     37 struct M3UParser;
     38 struct PlaylistFetcher;
     39 struct HLSTime;
     40 struct HTTPDownloader;
     41 
     42 struct 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> &notify,
     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 
    115 protected:
    116     virtual ~LiveSession();
    117 
    118     virtual void onMessageReceived(const sp<AMessage> &msg);
    119 
    120 private:
    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         int64_t mLastFailureUs;
    150     };
    151 
    152     struct FetcherInfo {
    153         sp<PlaylistFetcher> mFetcher;
    154         int64_t mDurationUs;
    155         bool mToBeRemoved;
    156         bool mToBeResumed;
    157     };
    158 
    159     struct StreamItem {
    160         const char *mType;
    161         AString mUri, mNewUri;
    162         SeekMode mSeekMode;
    163         size_t mCurDiscontinuitySeq;
    164         int64_t mLastDequeuedTimeUs;
    165         int64_t mLastSampleDurationUs;
    166         StreamItem()
    167             : StreamItem("") {}
    168         StreamItem(const char *type)
    169             : mType(type),
    170               mSeekMode(kSeekModeExactPosition) {
    171                   reset();
    172               }
    173         void reset() {
    174             mCurDiscontinuitySeq = 0;
    175             mLastDequeuedTimeUs = -1ll;
    176             mLastSampleDurationUs = 0ll;
    177         }
    178         AString uriKey() {
    179             AString key(mType);
    180             key.append("URI");
    181             return key;
    182         }
    183     };
    184     StreamItem mStreams[kMaxStreams];
    185 
    186     sp<AMessage> mNotify;
    187     uint32_t mFlags;
    188     sp<IMediaHTTPService> mHTTPService;
    189 
    190     bool mBuffering;
    191     bool mInPreparationPhase;
    192     int32_t mPollBufferingGeneration;
    193     int32_t mPrevBufferPercentage;
    194 
    195     KeyedVector<String8, String8> mExtraHeaders;
    196 
    197     AString mMasterURL;
    198 
    199     Vector<BandwidthItem> mBandwidthItems;
    200     ssize_t mCurBandwidthIndex;
    201     ssize_t mOrigBandwidthIndex;
    202     int32_t mLastBandwidthBps;
    203     bool mLastBandwidthStable;
    204     sp<BandwidthEstimator> mBandwidthEstimator;
    205 
    206     sp<M3UParser> mPlaylist;
    207     int32_t mMaxWidth;
    208     int32_t mMaxHeight;
    209 
    210     sp<ALooper> mFetcherLooper;
    211     KeyedVector<AString, FetcherInfo> mFetcherInfos;
    212     uint32_t mStreamMask;
    213 
    214     // Masks used during reconfiguration:
    215     // mNewStreamMask: streams in the variant playlist we're switching to;
    216     // we don't want to immediately overwrite the original value.
    217     uint32_t mNewStreamMask;
    218 
    219     // mSwapMask: streams that have started to playback content in the new variant playlist;
    220     // we use this to track reconfiguration progress.
    221     uint32_t mSwapMask;
    222 
    223     KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources;
    224     // A second set of packet sources that buffer content for the variant we're switching to.
    225     KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources2;
    226 
    227     int32_t mSwitchGeneration;
    228     int32_t mSubtitleGeneration;
    229 
    230     size_t mContinuationCounter;
    231     sp<AMessage> mContinuation;
    232     sp<AMessage> mSeekReply;
    233 
    234     int64_t mLastDequeuedTimeUs;
    235     int64_t mRealTimeBaseUs;
    236 
    237     bool mReconfigurationInProgress;
    238     bool mSwitchInProgress;
    239     int64_t mUpSwitchMark;
    240     int64_t mDownSwitchMark;
    241     int64_t mUpSwitchMargin;
    242 
    243     sp<AReplyToken> mDisconnectReplyID;
    244     sp<AReplyToken> mSeekReplyID;
    245 
    246     bool mFirstTimeUsValid;
    247     int64_t mFirstTimeUs;
    248     int64_t mLastSeekTimeUs;
    249     bool mHasMetadata;
    250 
    251     KeyedVector<size_t, int64_t> mDiscontinuityAbsStartTimesUs;
    252     KeyedVector<size_t, int64_t> mDiscontinuityOffsetTimesUs;
    253 
    254     sp<PlaylistFetcher> addFetcher(const char *uri);
    255 
    256     void onConnect(const sp<AMessage> &msg);
    257     void onMasterPlaylistFetched(const sp<AMessage> &msg);
    258     void onSeek(const sp<AMessage> &msg);
    259 
    260     bool UriIsSameAsIndex( const AString &uri, int32_t index, bool newUri);
    261     sp<AnotherPacketSource> getPacketSourceForStreamIndex(size_t trackIndex, bool newUri);
    262     sp<AnotherPacketSource> getMetadataSource(
    263             sp<AnotherPacketSource> sources[kNumSources], uint32_t streamMask, bool newUri);
    264 
    265     bool resumeFetcher(
    266             const AString &uri, uint32_t streamMask,
    267             int64_t timeUs = -1ll, bool newUri = false);
    268 
    269     float getAbortThreshold(
    270             ssize_t currentBWIndex, ssize_t targetBWIndex) const;
    271     void addBandwidthMeasurement(size_t numBytes, int64_t delayUs);
    272     size_t getBandwidthIndex(int32_t bandwidthBps);
    273     ssize_t getLowestValidBandwidthIndex() const;
    274     HLSTime latestMediaSegmentStartTime() const;
    275 
    276     static bool isBandwidthValid(const BandwidthItem &item);
    277     static int SortByBandwidth(const BandwidthItem *, const BandwidthItem *);
    278     static StreamType indexToType(int idx);
    279     static ssize_t typeToIndex(int32_t type);
    280 
    281     void changeConfiguration(
    282             int64_t timeUs, ssize_t bwIndex = -1, bool pickTrack = false);
    283     void onChangeConfiguration(const sp<AMessage> &msg);
    284     void onChangeConfiguration2(const sp<AMessage> &msg);
    285     void onChangeConfiguration3(const sp<AMessage> &msg);
    286 
    287     void swapPacketSource(StreamType stream);
    288     void tryToFinishBandwidthSwitch(const AString &oldUri);
    289     void cancelBandwidthSwitch(bool resume = false);
    290     bool checkSwitchProgress(
    291             sp<AMessage> &msg, int64_t delayUs, bool *needResumeUntil);
    292 
    293     bool switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow);
    294     bool tryBandwidthFallback();
    295 
    296     void schedulePollBuffering();
    297     void cancelPollBuffering();
    298     void restartPollBuffering();
    299     void onPollBuffering();
    300     bool checkBuffering(bool &underflow, bool &ready, bool &down, bool &up);
    301     void startBufferingIfNecessary();
    302     void stopBufferingIfNecessary();
    303     void notifyBufferingUpdate(int32_t percentage);
    304 
    305     void finishDisconnect();
    306 
    307     void postPrepared(status_t err);
    308     void postError(status_t err);
    309 
    310     DISALLOW_EVIL_CONSTRUCTORS(LiveSession);
    311 };
    312 
    313 }  // namespace android
    314 
    315 #endif  // LIVE_SESSION_H_
    316