• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 #include <utils/String8.h>
24 
25 namespace android {
26 
27 struct ABuffer;
28 struct DataSource;
29 struct LiveDataSource;
30 struct M3UParser;
31 struct HTTPBase;
32 
33 struct LiveSession : public AHandler {
34     enum Flags {
35         // Don't log any URLs.
36         kFlagIncognito = 1,
37     };
38     LiveSession(
39             const sp<AMessage> &notify,
40             uint32_t flags = 0, bool uidValid = false, uid_t uid = 0);
41 
42     sp<DataSource> getDataSource();
43 
44     void connect(
45             const char *url,
46             const KeyedVector<String8, String8> *headers = NULL);
47 
48     void disconnect();
49 
50     // Blocks until seek is complete.
51     void seekTo(int64_t timeUs);
52 
53     status_t getDuration(int64_t *durationUs) const;
54 
55     bool isSeekable() const;
56     bool hasDynamicDuration() const;
57 
58     // Posted notification's "what" field will carry one of the following:
59     enum {
60         kWhatPrepared,
61         kWhatPreparationFailed,
62     };
63 
64 protected:
65     virtual ~LiveSession();
66 
67     virtual void onMessageReceived(const sp<AMessage> &msg);
68 
69 private:
70     enum {
71         kMaxNumQueuedFragments = 3,
72         kMaxNumRetries         = 5,
73     };
74 
75     enum {
76         kWhatConnect        = 'conn',
77         kWhatDisconnect     = 'disc',
78         kWhatMonitorQueue   = 'moni',
79         kWhatSeek           = 'seek',
80     };
81 
82     struct BandwidthItem {
83         AString mURI;
84         unsigned long mBandwidth;
85     };
86 
87     sp<AMessage> mNotify;
88     uint32_t mFlags;
89     bool mUIDValid;
90     uid_t mUID;
91 
92     bool mInPreparationPhase;
93 
94     sp<LiveDataSource> mDataSource;
95 
96     sp<HTTPBase> mHTTPDataSource;
97 
98     AString mMasterURL;
99     KeyedVector<String8, String8> mExtraHeaders;
100 
101     Vector<BandwidthItem> mBandwidthItems;
102 
103     KeyedVector<AString, sp<ABuffer> > mAESKeyForURI;
104 
105     ssize_t mPrevBandwidthIndex;
106     int64_t mLastPlaylistFetchTimeUs;
107     sp<M3UParser> mPlaylist;
108     int32_t mSeqNumber;
109     int64_t mSeekTimeUs;
110     int32_t mNumRetries;
111     bool mStartOfPlayback;
112 
113     mutable Mutex mLock;
114     Condition mCondition;
115     int64_t mDurationUs;
116     bool mDurationFixed;  // Duration has been determined once and for all.
117     bool mSeekDone;
118     bool mDisconnectPending;
119 
120     int32_t mMonitorQueueGeneration;
121 
122     enum RefreshState {
123         INITIAL_MINIMUM_RELOAD_DELAY,
124         FIRST_UNCHANGED_RELOAD_ATTEMPT,
125         SECOND_UNCHANGED_RELOAD_ATTEMPT,
126         THIRD_UNCHANGED_RELOAD_ATTEMPT
127     };
128     RefreshState mRefreshState;
129 
130     uint8_t mPlaylistHash[16];
131 
132     void onConnect(const sp<AMessage> &msg);
133     void onDisconnect();
134     void onDownloadNext();
135     void onMonitorQueue();
136     void onSeek(const sp<AMessage> &msg);
137 
138     status_t fetchFile(
139             const char *url, sp<ABuffer> *out,
140             int64_t range_offset = 0, int64_t range_length = -1);
141 
142     sp<M3UParser> fetchPlaylist(const char *url, bool *unchanged);
143     size_t getBandwidthIndex();
144 
145     status_t decryptBuffer(
146             size_t playlistIndex, const sp<ABuffer> &buffer);
147 
148     void postMonitorQueue(int64_t delayUs = 0);
149 
150     bool timeToRefreshPlaylist(int64_t nowUs) const;
151 
152     static int SortByBandwidth(const BandwidthItem *, const BandwidthItem *);
153 
154     // Returns the media time in us of the segment specified by seqNumber.
155     // This is computed by summing the durations of all segments before it.
156     int64_t getSegmentStartTimeUs(int32_t seqNumber) const;
157 
158     void signalEOS(status_t err);
159 
160     DISALLOW_EVIL_CONSTRUCTORS(LiveSession);
161 };
162 
163 }  // namespace android
164 
165 #endif  // LIVE_SESSION_H_
166