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
29namespace android {
30
31struct ABuffer;
32struct AReplyToken;
33struct AnotherPacketSource;
34class DataSource;
35struct HTTPBase;
36struct MediaHTTPService;
37struct LiveDataSource;
38struct M3UParser;
39struct PlaylistFetcher;
40struct HLSTime;
41struct HTTPDownloader;
42
43struct 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
118protected:
119    virtual ~LiveSession();
120
121    virtual void onMessageReceived(const sp<AMessage> &msg);
122
123private:
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