xref: /aosp_15_r20/frameworks/wilhelm/src/android/android_GenericPlayer.h (revision bebae9c0e76121f8312ccb50385c080b3a0b023c)
1*bebae9c0SAndroid Build Coastguard Worker /*
2*bebae9c0SAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*bebae9c0SAndroid Build Coastguard Worker  *
4*bebae9c0SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*bebae9c0SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*bebae9c0SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*bebae9c0SAndroid Build Coastguard Worker  *
8*bebae9c0SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*bebae9c0SAndroid Build Coastguard Worker  *
10*bebae9c0SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*bebae9c0SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*bebae9c0SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*bebae9c0SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*bebae9c0SAndroid Build Coastguard Worker  * limitations under the License.
15*bebae9c0SAndroid Build Coastguard Worker  */
16*bebae9c0SAndroid Build Coastguard Worker 
17*bebae9c0SAndroid Build Coastguard Worker #ifndef __ANDROID_GENERICPLAYER_H__
18*bebae9c0SAndroid Build Coastguard Worker #define __ANDROID_GENERICPLAYER_H__
19*bebae9c0SAndroid Build Coastguard Worker 
20*bebae9c0SAndroid Build Coastguard Worker #include <media/stagefright/foundation/AHandler.h>
21*bebae9c0SAndroid Build Coastguard Worker #include <media/stagefright/foundation/ALooper.h>
22*bebae9c0SAndroid Build Coastguard Worker #include <media/stagefright/foundation/AMessage.h>
23*bebae9c0SAndroid Build Coastguard Worker 
24*bebae9c0SAndroid Build Coastguard Worker //--------------------------------------------------------------------------------------------------
25*bebae9c0SAndroid Build Coastguard Worker /**
26*bebae9c0SAndroid Build Coastguard Worker  * Message parameters for AHandler messages, see list in GenericPlayer::kWhatxxx
27*bebae9c0SAndroid Build Coastguard Worker  */
28*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_SEEK_SEEKTIME_MS                  "seekTimeMs"
29*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_LOOP_LOOPING                      "looping"
30*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_BUFFERING_UPDATE                  "bufferingUpdate"
31*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_BUFFERING_UPDATETHRESHOLD_PERCENT "buffUpdateThreshold"
32*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_ATTACHAUXEFFECT                   "attachAuxEffect"
33*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_SETAUXEFFECTSENDLEVEL             "setAuxEffectSendLevel"
34*bebae9c0SAndroid Build Coastguard Worker // Parameters for kWhatSetPlayEvents
35*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_SETPLAYEVENTS_FLAGS               "setPlayEventsFlags"
36*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_SETPLAYEVENTS_MARKER              "setPlayEventsMarker"
37*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_SETPLAYEVENTS_UPDATE              "setPlayEventsUpdate"
38*bebae9c0SAndroid Build Coastguard Worker // Parameters for kWhatOneShot (see explanation at definition of kWhatOneShot below)
39*bebae9c0SAndroid Build Coastguard Worker #define WHATPARAM_ONESHOT_GENERATION                "oneShotGeneration"
40*bebae9c0SAndroid Build Coastguard Worker 
41*bebae9c0SAndroid Build Coastguard Worker namespace android {
42*bebae9c0SAndroid Build Coastguard Worker 
43*bebae9c0SAndroid Build Coastguard Worker // abstract base class
44*bebae9c0SAndroid Build Coastguard Worker class GenericPlayer : public AHandler
45*bebae9c0SAndroid Build Coastguard Worker {
46*bebae9c0SAndroid Build Coastguard Worker public:
47*bebae9c0SAndroid Build Coastguard Worker 
48*bebae9c0SAndroid Build Coastguard Worker     enum {
49*bebae9c0SAndroid Build Coastguard Worker         kEventPrepared                = 0,
50*bebae9c0SAndroid Build Coastguard Worker         kEventHasVideoSize            = 1,
51*bebae9c0SAndroid Build Coastguard Worker         kEventPrefetchStatusChange    = 2,
52*bebae9c0SAndroid Build Coastguard Worker         kEventPrefetchFillLevelUpdate = 3,
53*bebae9c0SAndroid Build Coastguard Worker         kEventEndOfStream             = 4,
54*bebae9c0SAndroid Build Coastguard Worker         kEventChannelCount            = 5,
55*bebae9c0SAndroid Build Coastguard Worker         kEventPlay                    = 6, // SL_PLAYEVENT_*
56*bebae9c0SAndroid Build Coastguard Worker         kEventErrorAfterPrepare       = 7, // error after successful prepare
57*bebae9c0SAndroid Build Coastguard Worker     };
58*bebae9c0SAndroid Build Coastguard Worker 
59*bebae9c0SAndroid Build Coastguard Worker 
60*bebae9c0SAndroid Build Coastguard Worker     explicit GenericPlayer(const AudioPlayback_Parameters* params);
61*bebae9c0SAndroid Build Coastguard Worker     virtual ~GenericPlayer();
62*bebae9c0SAndroid Build Coastguard Worker 
63*bebae9c0SAndroid Build Coastguard Worker     void init(const notif_cbf_t cbf, void* notifUser);
64*bebae9c0SAndroid Build Coastguard Worker     virtual void preDestroy();
65*bebae9c0SAndroid Build Coastguard Worker 
66*bebae9c0SAndroid Build Coastguard Worker     void setDataSource(const char *uri);
67*bebae9c0SAndroid Build Coastguard Worker     void setDataSource(int fd, int64_t offset, int64_t length, bool closeAfterUse = false);
68*bebae9c0SAndroid Build Coastguard Worker 
69*bebae9c0SAndroid Build Coastguard Worker     void prepare();
70*bebae9c0SAndroid Build Coastguard Worker     virtual void play();
71*bebae9c0SAndroid Build Coastguard Worker     void pause();
72*bebae9c0SAndroid Build Coastguard Worker     void stop();
73*bebae9c0SAndroid Build Coastguard Worker     // timeMsec must be >= 0 or == ANDROID_UNKNOWN_TIME (used by StreamPlayer after discontinuity)
74*bebae9c0SAndroid Build Coastguard Worker     void seek(int64_t timeMsec);
75*bebae9c0SAndroid Build Coastguard Worker     void loop(bool loop);
76*bebae9c0SAndroid Build Coastguard Worker     void setBufferingUpdateThreshold(int16_t thresholdPercent);
77*bebae9c0SAndroid Build Coastguard Worker 
78*bebae9c0SAndroid Build Coastguard Worker     void getDurationMsec(int* msec); //msec != NULL, ANDROID_UNKNOWN_TIME if unknown
79*bebae9c0SAndroid Build Coastguard Worker     virtual void getPositionMsec(int* msec) = 0; //msec != NULL, ANDROID_UNKNOWN_TIME if unknown
80*bebae9c0SAndroid Build Coastguard Worker 
setVideoSurfaceTexture(const sp<IGraphicBufferProducer> & bufferProducer __unused)81*bebae9c0SAndroid Build Coastguard Worker     virtual void setVideoSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer __unused)
82*bebae9c0SAndroid Build Coastguard Worker             { }
83*bebae9c0SAndroid Build Coastguard Worker 
84*bebae9c0SAndroid Build Coastguard Worker     void setVolume(float leftVol, float rightVol);
85*bebae9c0SAndroid Build Coastguard Worker     void attachAuxEffect(int32_t effectId);
86*bebae9c0SAndroid Build Coastguard Worker     void setAuxEffectSendLevel(float level);
87*bebae9c0SAndroid Build Coastguard Worker 
88*bebae9c0SAndroid Build Coastguard Worker     virtual void setPlaybackRate(int32_t ratePermille);
89*bebae9c0SAndroid Build Coastguard Worker 
90*bebae9c0SAndroid Build Coastguard Worker     // Call after changing any of the IPlay settings related to SL_PLAYEVENT_*
91*bebae9c0SAndroid Build Coastguard Worker     void setPlayEvents(int32_t eventFlags, int32_t markerPosition, int32_t positionUpdatePeriod);
92*bebae9c0SAndroid Build Coastguard Worker 
93*bebae9c0SAndroid Build Coastguard Worker protected:
94*bebae9c0SAndroid Build Coastguard Worker     // mutex used for set vs use of volume, duration, and cache (fill, threshold) settings
95*bebae9c0SAndroid Build Coastguard Worker     Mutex mSettingsLock;
96*bebae9c0SAndroid Build Coastguard Worker 
97*bebae9c0SAndroid Build Coastguard Worker     void resetDataLocator();
98*bebae9c0SAndroid Build Coastguard Worker     DataLocator2 mDataLocator;
99*bebae9c0SAndroid Build Coastguard Worker     int          mDataLocatorType;
100*bebae9c0SAndroid Build Coastguard Worker 
101*bebae9c0SAndroid Build Coastguard Worker     // Constants used to identify the messages in this player's AHandler message loop
102*bebae9c0SAndroid Build Coastguard Worker     //   in onMessageReceived()
103*bebae9c0SAndroid Build Coastguard Worker     enum {
104*bebae9c0SAndroid Build Coastguard Worker         kWhatPrepare         = 0,  // start preparation
105*bebae9c0SAndroid Build Coastguard Worker         kWhatNotif           = 1,  // send a notification to client
106*bebae9c0SAndroid Build Coastguard Worker         kWhatPlay            = 2,  // start player
107*bebae9c0SAndroid Build Coastguard Worker         kWhatPause           = 3,  // pause or stop player
108*bebae9c0SAndroid Build Coastguard Worker         kWhatSeek            = 4,  // request a seek to specified position
109*bebae9c0SAndroid Build Coastguard Worker         kWhatSeekComplete    = 5,  // seek request has completed
110*bebae9c0SAndroid Build Coastguard Worker         kWhatLoop            = 6,  // set the player's looping status
111*bebae9c0SAndroid Build Coastguard Worker         kWhatVolumeUpdate    = 7,  // set the channel gains to specified values
112*bebae9c0SAndroid Build Coastguard Worker         kWhatBufferingUpdate = 8,
113*bebae9c0SAndroid Build Coastguard Worker         kWhatBuffUpdateThres = 9,
114*bebae9c0SAndroid Build Coastguard Worker         kWhatAttachAuxEffect = 10,
115*bebae9c0SAndroid Build Coastguard Worker         kWhatSetAuxEffectSendLevel = 11,
116*bebae9c0SAndroid Build Coastguard Worker         kWhatSetPlayEvents   = 12,  // process new IPlay settings related to SL_PLAYEVENT_*
117*bebae9c0SAndroid Build Coastguard Worker         kWhatOneShot         = 13,  // deferred (non-0 timeout) handler for SL_PLAYEVENT_*
118*bebae9c0SAndroid Build Coastguard Worker         // As used here, "one-shot" is the software equivalent of a "retriggerable monostable
119*bebae9c0SAndroid Build Coastguard Worker         // multivibrator" from electronics.  Briefly, a one-shot is a timer that can be triggered
120*bebae9c0SAndroid Build Coastguard Worker         // to fire at some point in the future.  It is "retriggerable" because while the timer
121*bebae9c0SAndroid Build Coastguard Worker         // is active, it is possible to replace the current timeout value by a new value.
122*bebae9c0SAndroid Build Coastguard Worker         // This is done by cancelling the current timer (using a generation count),
123*bebae9c0SAndroid Build Coastguard Worker         // and then posting another timer with the new desired value.
124*bebae9c0SAndroid Build Coastguard Worker     };
125*bebae9c0SAndroid Build Coastguard Worker 
126*bebae9c0SAndroid Build Coastguard Worker     // Send a notification to one of the event listeners
127*bebae9c0SAndroid Build Coastguard Worker     virtual void notify(const char* event, int data1, bool async);
128*bebae9c0SAndroid Build Coastguard Worker     virtual void notify(const char* event, int data1, int data2, bool async);
129*bebae9c0SAndroid Build Coastguard Worker 
130*bebae9c0SAndroid Build Coastguard Worker     // AHandler implementation
131*bebae9c0SAndroid Build Coastguard Worker     virtual void onMessageReceived(const sp<AMessage> &msg);
132*bebae9c0SAndroid Build Coastguard Worker 
133*bebae9c0SAndroid Build Coastguard Worker     // Async event handlers (called from GenericPlayer's event loop)
134*bebae9c0SAndroid Build Coastguard Worker     virtual void onPrepare();
135*bebae9c0SAndroid Build Coastguard Worker     virtual void onNotify(const sp<AMessage> &msg);
136*bebae9c0SAndroid Build Coastguard Worker     virtual void onPlay();
137*bebae9c0SAndroid Build Coastguard Worker     virtual void onPause();
138*bebae9c0SAndroid Build Coastguard Worker     virtual void onSeek(const sp<AMessage> &msg);
139*bebae9c0SAndroid Build Coastguard Worker     virtual void onLoop(const sp<AMessage> &msg);
140*bebae9c0SAndroid Build Coastguard Worker     virtual void onVolumeUpdate();
141*bebae9c0SAndroid Build Coastguard Worker     virtual void onSeekComplete();
142*bebae9c0SAndroid Build Coastguard Worker     virtual void onBufferingUpdate(const sp<AMessage> &msg);
143*bebae9c0SAndroid Build Coastguard Worker     virtual void onSetBufferingUpdateThreshold(const sp<AMessage> &msg);
144*bebae9c0SAndroid Build Coastguard Worker     virtual void onAttachAuxEffect(const sp<AMessage> &msg);
145*bebae9c0SAndroid Build Coastguard Worker     virtual void onSetAuxEffectSendLevel(const sp<AMessage> &msg);
146*bebae9c0SAndroid Build Coastguard Worker     void onSetPlayEvents(const sp<AMessage> &msg);
147*bebae9c0SAndroid Build Coastguard Worker     void onOneShot(const sp<AMessage> &msg);
148*bebae9c0SAndroid Build Coastguard Worker 
149*bebae9c0SAndroid Build Coastguard Worker     // Convenience methods
150*bebae9c0SAndroid Build Coastguard Worker     //   for async notifications of prefetch status and cache fill level, needs to be called
151*bebae9c0SAndroid Build Coastguard Worker     //     with mSettingsLock locked
152*bebae9c0SAndroid Build Coastguard Worker     void notifyStatus();
153*bebae9c0SAndroid Build Coastguard Worker     void notifyCacheFill();
154*bebae9c0SAndroid Build Coastguard Worker     //   for internal async notification to update state that the player is no longer seeking
155*bebae9c0SAndroid Build Coastguard Worker     void seekComplete();
156*bebae9c0SAndroid Build Coastguard Worker     void bufferingUpdate(int16_t fillLevelPerMille);
157*bebae9c0SAndroid Build Coastguard Worker 
158*bebae9c0SAndroid Build Coastguard Worker     // Event notification from GenericPlayer to OpenSL ES / OpenMAX AL framework
159*bebae9c0SAndroid Build Coastguard Worker     notif_cbf_t mNotifyClient;
160*bebae9c0SAndroid Build Coastguard Worker     void*       mNotifyUser;
161*bebae9c0SAndroid Build Coastguard Worker     // lock to protect mNotifyClient and mNotifyUser updates
162*bebae9c0SAndroid Build Coastguard Worker     Mutex       mNotifyClientLock;
163*bebae9c0SAndroid Build Coastguard Worker 
164*bebae9c0SAndroid Build Coastguard Worker     // Bits for mStateFlags
165*bebae9c0SAndroid Build Coastguard Worker     enum {
166*bebae9c0SAndroid Build Coastguard Worker         kFlagPrepared               = 1 << 0,   // use only for successful preparation
167*bebae9c0SAndroid Build Coastguard Worker         kFlagPreparing              = 1 << 1,
168*bebae9c0SAndroid Build Coastguard Worker         kFlagPlaying                = 1 << 2,
169*bebae9c0SAndroid Build Coastguard Worker         kFlagBuffering              = 1 << 3,
170*bebae9c0SAndroid Build Coastguard Worker         kFlagSeeking                = 1 << 4,   // set if we (not Stagefright) initiated a seek
171*bebae9c0SAndroid Build Coastguard Worker         kFlagLooping                = 1 << 5,   // set if looping is enabled
172*bebae9c0SAndroid Build Coastguard Worker         kFlagPreparedUnsuccessfully = 1 << 6,
173*bebae9c0SAndroid Build Coastguard Worker     };
174*bebae9c0SAndroid Build Coastguard Worker 
175*bebae9c0SAndroid Build Coastguard Worker     // Only accessed from event loop, does not need a mutex
176*bebae9c0SAndroid Build Coastguard Worker     uint32_t mStateFlags;
177*bebae9c0SAndroid Build Coastguard Worker 
178*bebae9c0SAndroid Build Coastguard Worker     sp<ALooper> mLooper;
179*bebae9c0SAndroid Build Coastguard Worker 
180*bebae9c0SAndroid Build Coastguard Worker     const AudioPlayback_Parameters mPlaybackParams;
181*bebae9c0SAndroid Build Coastguard Worker 
182*bebae9c0SAndroid Build Coastguard Worker     // protected by mSettingsLock after construction
183*bebae9c0SAndroid Build Coastguard Worker     AndroidAudioLevels mAndroidAudioLevels;
184*bebae9c0SAndroid Build Coastguard Worker 
185*bebae9c0SAndroid Build Coastguard Worker     // protected by mSettingsLock
186*bebae9c0SAndroid Build Coastguard Worker     int32_t mDurationMsec;
187*bebae9c0SAndroid Build Coastguard Worker     int16_t mPlaybackRatePermille;
188*bebae9c0SAndroid Build Coastguard Worker 
189*bebae9c0SAndroid Build Coastguard Worker     CacheStatus_t mCacheStatus;
190*bebae9c0SAndroid Build Coastguard Worker     int16_t mCacheFill; // cache fill level + played back level in permille
191*bebae9c0SAndroid Build Coastguard Worker     int16_t mLastNotifiedCacheFill; // last cache fill level communicated to the listener
192*bebae9c0SAndroid Build Coastguard Worker     int16_t mCacheFillNotifThreshold; // threshold in cache fill level for cache fill to be reported
193*bebae9c0SAndroid Build Coastguard Worker 
194*bebae9c0SAndroid Build Coastguard Worker     // Call any time any of the IPlay copies, current position, or play state changes, and
195*bebae9c0SAndroid Build Coastguard Worker     // supply the latest known position or ANDROID_UNKNOWN_TIME if position is unknown to caller.
196*bebae9c0SAndroid Build Coastguard Worker     void updateOneShot(int positionMs = ANDROID_UNKNOWN_TIME);
197*bebae9c0SAndroid Build Coastguard Worker 
198*bebae9c0SAndroid Build Coastguard Worker     // players that "render" data to present it to the user (a music player, a video player),
199*bebae9c0SAndroid Build Coastguard Worker     // should return true, while players that only decode (hopefully faster than "real time")
200*bebae9c0SAndroid Build Coastguard Worker     // should return false.
advancesPositionInRealTime()201*bebae9c0SAndroid Build Coastguard Worker     virtual bool advancesPositionInRealTime() const { return true; }
202*bebae9c0SAndroid Build Coastguard Worker 
203*bebae9c0SAndroid Build Coastguard Worker private:
204*bebae9c0SAndroid Build Coastguard Worker 
205*bebae9c0SAndroid Build Coastguard Worker     // Our copy of some important IPlay member variables, except in Android units
206*bebae9c0SAndroid Build Coastguard Worker     int32_t mEventFlags;
207*bebae9c0SAndroid Build Coastguard Worker     int32_t mMarkerPositionMs;
208*bebae9c0SAndroid Build Coastguard Worker     int32_t mPositionUpdatePeriodMs;
209*bebae9c0SAndroid Build Coastguard Worker 
210*bebae9c0SAndroid Build Coastguard Worker     // We need to be able to cancel any pending one-shot event(s) prior to posting
211*bebae9c0SAndroid Build Coastguard Worker     // a new one-shot.  As AMessage does not currently support cancellation by
212*bebae9c0SAndroid Build Coastguard Worker     // "what" category, we simulate this by keeping a generation counter for
213*bebae9c0SAndroid Build Coastguard Worker     // one-shots.  When a one-shot event is delivered, it checks to see if it is
214*bebae9c0SAndroid Build Coastguard Worker     // still the current one-shot.  If not, it returns immediately, thus
215*bebae9c0SAndroid Build Coastguard Worker     // effectively cancelling itself.  Note that counter wrap-around is possible
216*bebae9c0SAndroid Build Coastguard Worker     // but unlikely and benign.
217*bebae9c0SAndroid Build Coastguard Worker     int32_t mOneShotGeneration;
218*bebae9c0SAndroid Build Coastguard Worker 
219*bebae9c0SAndroid Build Coastguard Worker     // Play position at time of the most recently delivered SL_PLAYEVENT_HEADATNEWPOS,
220*bebae9c0SAndroid Build Coastguard Worker     // or ANDROID_UNKNOWN_TIME if a SL_PLAYEVENT_HEADATNEWPOS has never been delivered.
221*bebae9c0SAndroid Build Coastguard Worker     int32_t mDeliveredNewPosMs;
222*bebae9c0SAndroid Build Coastguard Worker 
223*bebae9c0SAndroid Build Coastguard Worker     // Play position most recently observed by updateOneShot, or ANDROID_UNKNOWN_TIME
224*bebae9c0SAndroid Build Coastguard Worker     // if the play position has never been observed.
225*bebae9c0SAndroid Build Coastguard Worker     int32_t mObservedPositionMs;
226*bebae9c0SAndroid Build Coastguard Worker 
227*bebae9c0SAndroid Build Coastguard Worker     DISALLOW_EVIL_CONSTRUCTORS(GenericPlayer);
228*bebae9c0SAndroid Build Coastguard Worker };
229*bebae9c0SAndroid Build Coastguard Worker 
230*bebae9c0SAndroid Build Coastguard Worker } // namespace android
231*bebae9c0SAndroid Build Coastguard Worker 
232*bebae9c0SAndroid Build Coastguard Worker extern void android_player_volumeUpdate(float *pVolumes /*[2]*/, const IVolume *volumeItf,
233*bebae9c0SAndroid Build Coastguard Worker         unsigned channelCount, float amplFromDirectLevel, const bool *audibilityFactors /*[2]*/);
234*bebae9c0SAndroid Build Coastguard Worker 
235*bebae9c0SAndroid Build Coastguard Worker #endif /* __ANDROID_GENERICPLAYER_H__ */
236