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 #include <binder/ProcessState.h> 17 #include <sys/stat.h> 18 #include <media/AudioTrack.h> 19 #include <media/stagefright/foundation/ADebug.h> 20 #include <media/stagefright/foundation/AHandler.h> 21 #include <media/stagefright/foundation/ALooper.h> 22 #include <media/stagefright/foundation/AMessage.h> 23 #include <media/stagefright/DataSource.h> 24 #include <media/stagefright/FileSource.h> 25 #include <media/stagefright/MediaDefs.h> 26 #include <media/stagefright/MediaExtractor.h> 27 #include <media/stagefright/MetaData.h> 28 #include <media/stagefright/OMXClient.h> 29 #include <media/stagefright/OMXCodec.h> 30 31 #include "NuCachedSource2.h" 32 #include "NuHTTPDataSource.h" 33 #include "ThrottledSource.h" 34 35 #ifdef USERDEBUG_BUILD 36 #define _DEBUG_AUDIO_TESTS 1 37 #endif 38 39 #define DURATION_CACHED_HIGH_US 30000000 // 30s 40 #define DURATION_CACHED_MED_US 10000000 // 10s 41 #define DURATION_CACHED_LOW_US 2000000 // 2s 42 43 /* 44 * by how much time data is written to the AudioTrack ahead of the scheduled render time 45 */ 46 #define RENDER_SAFETY_DELAY_US 5000 // 5ms 47 48 #define SIZE_CACHED_HIGH_BYTES 1000000 49 #define SIZE_CACHED_MED_BYTES 700000 50 #define SIZE_CACHED_LOW_BYTES 400000 51 52 /* 53 * events sent to mNotifyClient during prepare, prefetch, and playback 54 */ 55 #define EVENT_PREPARED "prep" 56 #define EVENT_PREFETCHSTATUSCHANGE "prsc" 57 #define EVENT_PREFETCHFILLLEVELUPDATE "pflu" 58 #define EVENT_ENDOFSTREAM "eos" 59 #define EVENT_NEW_AUDIOTRACK "nwat" 60 61 #define SFPLAYER_SUCCESS 1 62 #define SFPLAYER_FD_FIND_FILE_SIZE ((int64_t)0xFFFFFFFFFFFFFFFFll) 63 64 #define NO_FILL_LEVEL_UPDATE -1 65 #define NO_STATUS_UPDATE kStatusUnknown 66 67 68 typedef struct AudioPlayback_Parameters_struct { 69 int streamType; 70 int sessionId; 71 android::AudioTrack::callback_t trackcb; 72 void* trackcbUser; 73 } AudioPlayback_Parameters; 74 75 76 namespace android { 77 78 typedef void (*notif_client_t)(int event, const int data1, void* notifUser); 79 80 struct SfPlayer : public AHandler { 81 SfPlayer(AudioPlayback_Parameters *app); 82 83 enum CacheStatus { 84 kStatusUnknown = -1, 85 kStatusEmpty = 0, 86 kStatusLow, 87 kStatusIntermediate, 88 kStatusEnough, 89 kStatusHigh 90 }; 91 92 enum { 93 kEventPrepared = 'prep', 94 kEventPrefetchStatusChange = 'prsc', 95 kEventPrefetchFillLevelUpdate = 'pflu', 96 kEventEndOfStream = 'eos', 97 kEventNewAudioTrack = 'nwat' 98 }; 99 100 void armLooper(); 101 void setNotifListener(const notif_client_t cbf, void* notifUser); 102 103 void setDataSource(const char *uri); 104 void setDataSource(const int fd, const int64_t offset, const int64_t length); 105 106 void setCacheFillUpdateThreshold(int16_t thr) { mCacheFillNotifThreshold = thr; } 107 108 void prepare(); 109 void play(); 110 void pause(); 111 void stop(); 112 void seek(int64_t timeMsec); 113 void loop(bool loop); 114 bool wantPrefetch(); 115 void startPrefetch_async(); 116 117 /** 118 * returns the duration in microseconds, -1 if unknown 119 */ 120 int64_t getDurationUsec() { return mDurationUsec; } 121 int32_t getNumChannels() { return mNumChannels; } 122 int32_t getSampleRateHz() { return mSampleRateHz; } 123 AudioTrack* getAudioTrack() { return mAudioTrack; } 124 uint32_t getPositionMsec(); 125 126 protected: 127 virtual ~SfPlayer(); 128 virtual void onMessageReceived(const sp<AMessage> &msg); 129 130 private: 131 132 enum { 133 kDataLocatorNone = 'none', 134 kDataLocatorUri = 'uri', 135 kDataLocatorFd = 'fd', 136 }; 137 138 enum { 139 kWhatPrepare = 'prep', 140 kWhatDecode = 'deco', 141 kWhatRender = 'rend', 142 kWhatCheckCache = 'cach', 143 kWhatNotif = 'noti', 144 kWhatPlay = 'play', 145 kWhatPause = 'paus', 146 kWhatSeek = 'seek', 147 kWhatLoop = 'loop', 148 }; 149 150 enum { 151 kFlagPlaying = 1, 152 kFlagPreparing = 2, 153 kFlagBuffering = 4, 154 kFlagSeeking = 8, 155 kFlagLooping = 16, 156 }; 157 158 struct FdInfo { 159 int fd; 160 int64_t offset; 161 int64_t length; 162 }; 163 164 union DataLocator { 165 char* uri; 166 FdInfo fdi; 167 }; 168 #ifdef _DEBUG_AUDIO_TESTS 169 FILE *mMonitorAudioFp; // Automated tests 170 #endif 171 // mutex used for seek flag and seek time read/write 172 Mutex mSeekLock; 173 174 AudioTrack *mAudioTrack; 175 176 sp<ALooper> mRenderLooper; 177 sp<DataSource> mDataSource; 178 sp<MediaSource> mAudioSource; 179 uint32_t mFlags; 180 int64_t mBitrate; // in bits/sec 181 int32_t mNumChannels; 182 int32_t mSampleRateHz; 183 int64_t mTimeDelta; 184 int64_t mDurationUsec; 185 CacheStatus mCacheStatus; 186 int64_t mSeekTimeMsec; 187 int64_t mLastDecodedPositionUs; 188 int16_t mCacheFill; // cache fill level in permille 189 int16_t mLastNotifiedCacheFill; // last cache fill level communicated to the listener 190 int16_t mCacheFillNotifThreshold; // threshold in cache fill level for cache fill to be reported 191 AudioPlayback_Parameters mPlaybackParams; 192 193 DataLocator mDataLocator; 194 int mDataLocatorType; 195 196 notif_client_t mNotifyClient; 197 void* mNotifyUser; 198 199 // mutex used for protecting the decode buffer 200 Mutex mDecodeBufferLock; 201 // buffer passed from decoder to renderer 202 MediaBuffer *mDecodeBuffer; 203 204 // message handlers 205 void onPrepare(const sp<AMessage> &msg); 206 void onDecode(); 207 void onRender(const sp<AMessage> &msg); 208 void onCheckCache(const sp<AMessage> &msg); 209 void onNotify(const sp<AMessage> &msg); 210 void onPlay(); 211 void onPause(); 212 void onSeek(const sp<AMessage> &msg); 213 void onLoop(const sp<AMessage> &msg); 214 215 CacheStatus getCacheRemaining(bool *eos); 216 int64_t getPositionUsec(); 217 void reachedEndOfStream(); 218 void updatePlaybackParamsFromSource(); 219 void notifyStatus(); 220 void notifyCacheFill(); 221 void notifyPrepared(status_t prepareRes); 222 void notify(const sp<AMessage> &msg, bool async); 223 224 void resetDataLocator(); 225 226 DISALLOW_EVIL_CONSTRUCTORS(SfPlayer); 227 }; 228 229 } // namespace android 230