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