summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--wilhelm/src/android/AudioPlayer_to_android.cpp35
-rw-r--r--wilhelm/src/android/MediaPlayer_to_android.cpp37
-rw-r--r--wilhelm/src/android/android_GenericMediaPlayer.cpp3
-rw-r--r--wilhelm/src/android/android_GenericPlayer.cpp3
-rw-r--r--wilhelm/src/android/android_GenericPlayer.h1
-rw-r--r--wilhelm/src/android/android_defs.h1
6 files changed, 79 insertions, 1 deletions
diff --git a/wilhelm/src/android/AudioPlayer_to_android.cpp b/wilhelm/src/android/AudioPlayer_to_android.cpp
index 335d03fe..75084b70 100644
--- a/wilhelm/src/android/AudioPlayer_to_android.cpp
+++ b/wilhelm/src/android/AudioPlayer_to_android.cpp
@@ -838,6 +838,41 @@ static void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void*
}
break;
+ case android::GenericPlayer::kEventErrorAfterPrepare: {
+ SL_LOGI("kEventErrorAfterPrepare");
+
+ // assume no callback
+ slPrefetchCallback callback = NULL;
+ void* callbackPContext = NULL;
+
+ object_lock_exclusive(&ap->mObject);
+ if (IsInterfaceInitialized(&ap->mObject, MPH_PREFETCHSTATUS)) {
+ SL_LOGI("inited");
+ ap->mPrefetchStatus.mLevel = 0;
+ ap->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
+ if (!(~ap->mPrefetchStatus.mCallbackEventsMask &
+ (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
+ SL_LOGI("enabled");
+ callback = ap->mPrefetchStatus.mCallback;
+ callbackPContext = ap->mPrefetchStatus.mContext;
+ }
+ }
+ object_unlock_exclusive(&ap->mObject);
+
+ // FIXME there's interesting information in data1, but no API to convey it to client
+ SL_LOGE("Error after prepare: %d", data1);
+
+ // callback with no lock held
+ SL_LOGE("callback=%p context=%p", callback, callbackPContext);
+ if (NULL != callback) {
+ (*callback)(&ap->mPrefetchStatus.mItf, callbackPContext,
+ SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
+ }
+
+ }
+ break;
+
+
default:
break;
}
diff --git a/wilhelm/src/android/MediaPlayer_to_android.cpp b/wilhelm/src/android/MediaPlayer_to_android.cpp
index 97217d78..77df09eb 100644
--- a/wilhelm/src/android/MediaPlayer_to_android.cpp
+++ b/wilhelm/src/android/MediaPlayer_to_android.cpp
@@ -38,6 +38,10 @@ static void player_handleMediaPlayerEventNotifications(int event, int data1, int
}
CMediaPlayer* mp = (CMediaPlayer*) user;
+ if (!android::CallbackProtector::enterCbIfOk(mp->mCallbackProtector)) {
+ // it is not safe to enter the callback (the media player is about to go away)
+ return;
+ }
union {
char c[sizeof(int)];
int i;
@@ -244,10 +248,43 @@ static void player_handleMediaPlayerEventNotifications(int event, int data1, int
}
break;
+ case android::GenericPlayer::kEventErrorAfterPrepare: {
+ SL_LOGV("kEventErrorAfterPrepare");
+
+ // assume no callback
+ slPrefetchCallback callback = NULL;
+ void* callbackPContext = NULL;
+
+ object_lock_exclusive(&mp->mObject);
+ if (IsInterfaceInitialized(&mp->mObject, MPH_XAPREFETCHSTATUS)) {
+ mp->mPrefetchStatus.mLevel = 0;
+ mp->mPrefetchStatus.mStatus = SL_PREFETCHSTATUS_UNDERFLOW;
+ if (!(~mp->mPrefetchStatus.mCallbackEventsMask &
+ (SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE))) {
+ callback = mp->mPrefetchStatus.mCallback;
+ callbackPContext = mp->mPrefetchStatus.mContext;
+ }
+ }
+ object_unlock_exclusive(&mp->mObject);
+
+ // FIXME there's interesting information in data1, but no API to convey it to client
+ SL_LOGE("Error after prepare: %d", data1);
+
+ // callback with no lock held
+ if (NULL != callback) {
+ (*callback)(&mp->mPrefetchStatus.mItf, callbackPContext,
+ SL_PREFETCHEVENT_FILLLEVELCHANGE | SL_PREFETCHEVENT_STATUSCHANGE);
+ }
+
+ }
+ break;
+
default: {
SL_LOGE("Received unknown event %d, data %d from AVPlayer", event, data1);
}
}
+
+ mp->mCallbackProtector->exitCb();
}
diff --git a/wilhelm/src/android/android_GenericMediaPlayer.cpp b/wilhelm/src/android/android_GenericMediaPlayer.cpp
index 69a7def6..91d09726 100644
--- a/wilhelm/src/android/android_GenericMediaPlayer.cpp
+++ b/wilhelm/src/android/android_GenericMediaPlayer.cpp
@@ -136,7 +136,8 @@ void MediaPlayerNotificationClient::notify(int msg, int ext1, int ext2, const Pa
mPlayerPrepared = PREPARE_COMPLETED_UNSUCCESSFULLY;
mPlayerPreparedCondition.signal();
} else {
- // FIXME Currently no mechanism to inform client of errors after preparation
+ // inform client of errors after preparation
+ genericMediaPlayer->notify(PLAYEREVENT_ERRORAFTERPREPARE, ext1, true /*async*/);
}
}
break;
diff --git a/wilhelm/src/android/android_GenericPlayer.cpp b/wilhelm/src/android/android_GenericPlayer.cpp
index ef469ae0..10e613fc 100644
--- a/wilhelm/src/android/android_GenericPlayer.cpp
+++ b/wilhelm/src/android/android_GenericPlayer.cpp
@@ -429,6 +429,9 @@ void GenericPlayer::onNotify(const sp<AMessage> &msg) {
} else if (msg->findInt32(PLAYEREVENT_PLAY, &val1)) {
SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PLAY, val1);
notifClient(kEventPlay, val1, 0, notifUser);
+ } else if (msg->findInt32(PLAYEREVENT_ERRORAFTERPREPARE, &val1)) {
+ SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_ERRORAFTERPREPARE, val1);
+ notifClient(kEventErrorAfterPrepare, val1, 0, notifUser);
} else {
SL_LOGV("GenericPlayer notifying unknown");
}
diff --git a/wilhelm/src/android/android_GenericPlayer.h b/wilhelm/src/android/android_GenericPlayer.h
index 76ae919f..b1228c04 100644
--- a/wilhelm/src/android/android_GenericPlayer.h
+++ b/wilhelm/src/android/android_GenericPlayer.h
@@ -52,6 +52,7 @@ public:
kEventEndOfStream = 'eos',
kEventChannelCount = 'ccnt',
kEventPlay = 'play', // SL_PLAYEVENT_*
+ kEventErrorAfterPrepare = 'easp', // error after successful prepare
};
diff --git a/wilhelm/src/android/android_defs.h b/wilhelm/src/android/android_defs.h
index df9c24e8..2332a73e 100644
--- a/wilhelm/src/android/android_defs.h
+++ b/wilhelm/src/android/android_defs.h
@@ -114,6 +114,7 @@ typedef size_t (*data_push_cbf_t)(const uint8_t *data, size_t size, CAudioPlayer
#define PLAYEREVENT_VIDEO_SIZE_UPDATE "vsiz"
#define PLAYEREVENT_CHANNEL_COUNT "ccnt" // channel count is now known
#define PLAYEREVENT_PLAY "play" // SL_PLAYEVENT_*
+#define PLAYEREVENT_ERRORAFTERPREPARE "easp" // error after successful prepare
/**