diff options
-rw-r--r-- | opensles/libopensles/android_AudioPlayer.cpp | 39 | ||||
-rw-r--r-- | opensles/libopensles/android_prompts.h | 2 | ||||
-rw-r--r-- | opensles/tests/mimeUri/slesTestPlayUri.cpp | 5 |
3 files changed, 43 insertions, 3 deletions
diff --git a/opensles/libopensles/android_AudioPlayer.cpp b/opensles/libopensles/android_AudioPlayer.cpp index cf83ee19..a120f5eb 100644 --- a/opensles/libopensles/android_AudioPlayer.cpp +++ b/opensles/libopensles/android_AudioPlayer.cpp @@ -394,15 +394,49 @@ static void sfplayer_handlePrefetchEvent(const int event, const int data1, void* switch(event) { case(android::SfPlayer::kEventPrepared): { - object_lock_exclusive(&ap->mObject); if (SFPLAYER_SUCCESS != data1) { + object_lock_exclusive(&ap->mObject); + ap->mAudioTrack = NULL; ap->mNumChannels = 0; ap->mSampleRateMilliHz = 0; ap->mAndroidObjState = ANDROID_UNINITIALIZED; + object_unlock_exclusive(&ap->mObject); + + // SfPlayer prepare() failed prefetching, there is no event in SLPrefetchStatus to + // indicate a prefetch error, so we signal it by sending simulataneously two events: + // - SL_PREFETCHEVENT_FILLLEVELCHANGE with a level of 0 + // - SL_PREFETCHEVENT_STATUSCHANGE with a status of SL_PREFETCHSTATUS_UNDERFLOW + SL_LOGE(ERROR_PLAYER_PREFETCH_d, data1); + if (!IsInterfaceInitialized(&(ap->mObject), MPH_PREFETCHSTATUS)) { + break; + } + + slPrefetchCallback callback = NULL; + void* callbackPContext = NULL; + + interface_lock_exclusive(&ap->mPrefetchStatus); + ap->mPrefetchStatus.mLevel = 0; + ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW; + if ((ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_FILLLEVELCHANGE) + && (ap->mPrefetchStatus.mCallbackEventsMask & SL_PREFETCHEVENT_STATUSCHANGE)) { + callback = ap->mPrefetchStatus.mCallback; + callbackPContext = ap->mPrefetchStatus.mContext; + } + interface_unlock_exclusive(&ap->mPrefetchStatus); + + // callback with no lock held + if (NULL != callback) { + (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext, + SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE); + } + + } else { + object_lock_exclusive(&ap->mObject); + ap->mAudioTrack = ap->mSfPlayer->getAudioTrack(); ap->mNumChannels = ap->mSfPlayer->getNumChannels(); ap->mSampleRateMilliHz = android_to_sles_sampleRate(ap->mSfPlayer->getSampleRateHz()); @@ -414,9 +448,10 @@ static void sfplayer_handlePrefetchEvent(const int event, const int data1, void* android_audioPlayer_setPlayRate(ap, ap->mPlaybackRate.mRate, false /*lockAP*/); ap->mAndroidObjState = ANDROID_READY; + + object_unlock_exclusive(&ap->mObject); } - object_unlock_exclusive(&ap->mObject); } break; case(android::SfPlayer::kEventPrefetchFillLevelUpdate): { diff --git a/opensles/libopensles/android_prompts.h b/opensles/libopensles/android_prompts.h index 71504904..8923f9cc 100644 --- a/opensles/libopensles/android_prompts.h +++ b/opensles/libopensles/android_prompts.h @@ -26,6 +26,8 @@ "Cannot realize AudioPlayer: with unknown data source locator" #define ERROR_PLAYER_NEW_NULL_TRACK \ "Internal error: new AudioTrack shouldn't be NULL" +#define ERROR_PLAYER_PREFETCH_d \ + "Error (%d) encountered while prefetching" //----------------------------------------------------------------------------- // Android AudioRecorder errors diff --git a/opensles/tests/mimeUri/slesTestPlayUri.cpp b/opensles/tests/mimeUri/slesTestPlayUri.cpp index 819f9cf0..fdab0431 100644 --- a/opensles/tests/mimeUri/slesTestPlayUri.cpp +++ b/opensles/tests/mimeUri/slesTestPlayUri.cpp @@ -48,6 +48,9 @@ #define MAX_NUMBER_INTERFACES 2 +#define PREFETCHEVENT_ERROR_CANDIDATE \ + (SL_PREFETCHEVENT_STATUSCHANGE | SL_PREFETCHEVENT_FILLLEVELCHANGE) + //----------------------------------------------------------------- //* Exits the application if an error is encountered */ #define CheckErr(x) ExitOnErrorFunc(x,__LINE__) @@ -69,7 +72,7 @@ void PrefetchEventCallback( SLPrefetchStatusItf caller, void *pContext, SLuint3 SLuint32 status; //fprintf(stdout, "PrefetchEventCallback: received event %lu\n", event); (*caller)->GetPrefetchStatus(caller, &status); - if ((event & (SL_PREFETCHEVENT_STATUSCHANGE|SL_PREFETCHEVENT_FILLLEVELCHANGE)) + if ((PREFETCHEVENT_ERROR_CANDIDATE == (event & PREFETCHEVENT_ERROR_CANDIDATE)) && (level == 0) && (status == SL_PREFETCHSTATUS_UNDERFLOW)) { fprintf(stdout, "PrefetchEventCallback: Error while prefetching data, exiting\n"); //exit(EXIT_FAILURE); |