Home | History | Annotate | Download | only in libopensles
      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