Start support for XAAndroidBufferQueueItf in OpenMAX AL
Added an Android OpenMAX AL header for the Android interfaces
Registered the AndroidBufferQueueItf as an explicit
interface on MediaPlayer.
Updated the Java+Native example to register a callback from
which OpenMAX AL can retrieve the data to play
Started unifying the player object used by OpenMAX AL and
OpenSL ES so they use a common class.
Change-Id: I73cec8c802f74767545c91278e5e73c8c7995218
diff --git a/libopensles/Android.mk b/libopensles/Android.mk
index 38639f2..82353d3 100644
--- a/libopensles/Android.mk
+++ b/libopensles/Android.mk
@@ -51,6 +51,7 @@
locks.c \
sles.c \
sllog.c \
+ android_Player.cpp \
android_AVPlayer.cpp \
android_AudioPlayer.cpp \
android_AudioRecorder.cpp \
diff --git a/libopensles/CMediaPlayer.c b/libopensles/CMediaPlayer.c
index 1c73497..c83b910 100644
--- a/libopensles/CMediaPlayer.c
+++ b/libopensles/CMediaPlayer.c
@@ -39,104 +39,27 @@
#ifdef ANDROID
using namespace android;
-struct MyStreamSource : public BnStreamSource {
- // Caller retains ownership of fd.
- MyStreamSource(int fd);
-
- virtual void setListener(const sp<IStreamListener> &listener);
- virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
-
- virtual void onBufferAvailable(size_t index);
-
-protected:
- virtual ~MyStreamSource();
-
-private:
- int mFd;
-
- sp<IStreamListener> mListener;
- Vector<sp<IMemory> > mBuffers;
-
- DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
-};
-
-MyStreamSource::MyStreamSource(int fd)
- : mFd(fd) {
- CHECK_GE(fd, 0);
-}
-
-MyStreamSource::~MyStreamSource() {
-}
-
-void MyStreamSource::setListener(const sp<IStreamListener> &listener) {
- mListener = listener;
-}
-
-void MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
- mBuffers = buffers;
-}
-
-void MyStreamSource::onBufferAvailable(size_t index) {
- CHECK_LT(index, mBuffers.size());
- sp<IMemory> mem = mBuffers.itemAt(index);
-
- ssize_t n = read(mFd, mem->pointer(), mem->size());
- if (n <= 0) {
- mListener->issueCommand(IStreamListener::EOS, false /* synchronous */);
- } else {
- mListener->queueBuffer(index, n);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct MyClient : public BnMediaPlayerClient {
- MyClient()
- : mEOS(false) {
- }
-
- virtual void notify(int msg, int ext1, int ext2) {
- Mutex::Autolock autoLock(mLock);
-
- if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
- mEOS = true;
- mCondition.signal();
- }
- }
-
- void waitForEOS() {
- Mutex::Autolock autoLock(mLock);
- while (!mEOS) {
- mCondition.wait(mLock);
- }
- }
-
-protected:
- virtual ~MyClient() {
- }
-
-private:
- Mutex mLock;
- Condition mCondition;
-
- bool mEOS;
-
- DISALLOW_EVIL_CONSTRUCTORS(MyClient);
-};
#endif
XAresult CMediaPlayer_Realize(void *self, XAboolean async)
{
-#ifdef ANDROID
CMediaPlayer *thiz = (CMediaPlayer *) self;
+ SLresult result = XA_RESULT_SUCCESS;
+
+#ifdef ANDROID
+ result = android_Player_realize(thiz, async);
+#endif
+
+ // FIXME add support for display surface retrieval
+#if 0
assert(XA_DATALOCATOR_URI == thiz->mDataSource.mLocator.mLocatorType);
// assert(XA_FORMAT_NULL == this->mDataSource.mFormat.mFormatType);
assert(XA_DATALOCATOR_NATIVEDISPLAY == thiz->mImageVideoSink.mLocator.mLocatorType);
// assert(XA_FORMAT_NULL == this->mImageVideoSink.mFormat.mFormatType);
// FIXME ignore the audio sink
-
+#ifdef ANDROID
int fd = open((const char *) thiz->mDataSource.mLocator.mURI.URI, O_RDONLY);
if (0 >= fd) {
return err_to_result(errno);
@@ -165,8 +88,8 @@
player->setVideoSurface(surface);
}
#endif
-
- return XA_RESULT_SUCCESS;
+#endif
+ return result;
}
diff --git a/libopensles/IAndroidBufferQueue.c b/libopensles/IAndroidBufferQueue.c
index f9f74ad..f01be23 100644
--- a/libopensles/IAndroidBufferQueue.c
+++ b/libopensles/IAndroidBufferQueue.c
@@ -28,14 +28,28 @@
interface_lock_exclusive(this);
// verify pre-condition that media object is in the SL_PLAYSTATE_STOPPED state
- if (SL_PLAYSTATE_STOPPED == ((CAudioPlayer*) this->mThis)->mPlay.mState) {
+ // FIXME PRIORITY 1 check play state
+ //if (SL_PLAYSTATE_STOPPED == ((CAudioPlayer*) this->mThis)->mPlay.mState) {
this->mCallback = callback;
this->mContext = pContext;
- result = SL_RESULT_SUCCESS;
- android_audioPlayer_androidBufferQueue_registerCallback_l((CAudioPlayer*) this->mThis);
- } else {
- result = SL_RESULT_PRECONDITIONS_VIOLATED;
- }
+
+ switch (InterfaceToObjectID(this)) {
+ case SL_OBJECTID_AUDIOPLAYER:
+ result = SL_RESULT_SUCCESS;
+ android_audioPlayer_androidBufferQueue_registerCallback_l((CAudioPlayer*) this->mThis);
+ break;
+ case XA_OBJECTID_MEDIAPLAYER:
+ SL_LOGI("IAndroidBufferQueue_RegisterCallback()");
+ result = SL_RESULT_SUCCESS;
+ android_Player_androidBufferQueue_registerCallback_l((CMediaPlayer*) this->mThis);
+ default:
+ result = SL_RESULT_PARAMETER_INVALID;
+ break;
+ }
+
+ //} else {
+ // result = SL_RESULT_PRECONDITIONS_VIOLATED;
+ //}
interface_unlock_exclusive(this);
@@ -75,9 +89,22 @@
// FIXME return value? of particular interest: error is length is larger than size received
// in callback
- result = SL_RESULT_SUCCESS;
- android_audioPlayer_androidBufferQueue_enqueue_l((CAudioPlayer*) this->mThis,
- bufferId, length, event, pData);
+ switch (InterfaceToObjectID(this)) {
+ case SL_OBJECTID_AUDIOPLAYER:
+ result = SL_RESULT_SUCCESS;
+ android_audioPlayer_androidBufferQueue_enqueue_l((CAudioPlayer*) this->mThis,
+ bufferId, length, event, pData);
+ break;
+ case XA_OBJECTID_MEDIAPLAYER:
+ //SL_LOGV("IAndroidBufferQueue_Enqueue()");
+ result = SL_RESULT_SUCCESS;
+ android_Player_androidBufferQueue_enqueue_l((CMediaPlayer*) this->mThis,
+ bufferId, length, event, pData);
+ break;
+ default:
+ result = SL_RESULT_PARAMETER_INVALID;
+ break;
+ }
interface_unlock_exclusive(this);
diff --git a/libopensles/IEngine.c b/libopensles/IEngine.c
index 69ac576..521e487 100644
--- a/libopensles/IEngine.c
+++ b/libopensles/IEngine.c
@@ -976,7 +976,7 @@
&this->mDataSource, DATALOCATOR_MASK_URI
#ifdef ANDROID
| DATALOCATOR_MASK_ANDROIDFD
- // FIXME | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE ???
+ | DATALOCATOR_MASK_ANDROIDBUFFERQUEUE
#endif
, DATAFORMAT_MASK_MIME);
if (XA_RESULT_SUCCESS != result) {
@@ -1038,7 +1038,7 @@
// platform-specific initialization
#ifdef ANDROID
- // ...
+ android_Player_create(this);
#endif
} while (0);
diff --git a/libopensles/MPH_to.c b/libopensles/MPH_to.c
index fd6c7af..53cbf57 100644
--- a/libopensles/MPH_to.c
+++ b/libopensles/MPH_to.c
@@ -251,6 +251,7 @@
[MPH_OBJECT] = 0,
[MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
[MPH_XAPLAY] = 2,
+ [MPH_ANDROIDBUFFERQUEUE] = 3,
// FIXME more TBD
#else
#include "MPH_to_MediaPlayer.h"
diff --git a/libopensles/OpenSLES_IID.c b/libopensles/OpenSLES_IID.c
index fcb4777..7f045b6 100644
--- a/libopensles/OpenSLES_IID.c
+++ b/libopensles/OpenSLES_IID.c
@@ -33,7 +33,8 @@
#include "SLES/OpenSLES.h" /* SL Header */
#include "OMXAL/OpenMAXAL.h"
#ifdef ANDROID
-#include "SLES/OpenSLES_Android.h" /* Android-specific SL Header */
+#include "SLES/OpenSLES_Android.h" /* Android-specific SL Header */
+#include "OMXAL/OpenMAXAL_Android.h"/* Android-specific MAX AL Header */
#endif
#include "MPH.h"
@@ -171,6 +172,10 @@
// XA_IID_PLAY
{ 0xb9c293e0, 0xf776, 0x11db, 0x80df, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
+// OpenMAX AL 1.0.1 Android API level 10 extended interfaces
+ // XA_IID_ANDROIDBUFFERQUEUE
+ // same as SL_IID_ANDROIDBUFFERQUEUE
+
};
#ifdef __cplusplus
@@ -242,6 +247,10 @@
const XAInterfaceID XA_IID_ENGINE = (XAInterfaceID) &SL_IID_array[MPH_XAENGINE];
const XAInterfaceID XA_IID_PLAY = (XAInterfaceID) &SL_IID_array[MPH_XAPLAY];
+// OpenMAX AL 1.0.1 Android API level 10 extended interfaces
+const XAInterfaceID XA_IID_ANDROIDBUFFERQUEUE =
+ (XAInterfaceID) &SL_IID_array[MPH_ANDROIDBUFFERQUEUE]; //same as SL
+
#ifdef __cplusplus
}
#endif
diff --git a/libopensles/android_AVPlayer.cpp b/libopensles/android_AVPlayer.cpp
index 24903c8..2076025 100644
--- a/libopensles/android_AVPlayer.cpp
+++ b/libopensles/android_AVPlayer.cpp
@@ -87,6 +87,7 @@
}
void AVPlayer::init() {
+ SL_LOGI("AVPlayer::init()");
mLooper->registerHandler(this);
mLooper->start(false /*runOnCallingThread*/, false /*canCallJava*/); // use default priority
}
diff --git a/libopensles/android_AudioPlayer.cpp b/libopensles/android_AudioPlayer.cpp
index 0f0a367..73751ab 100644
--- a/libopensles/android_AudioPlayer.cpp
+++ b/libopensles/android_AudioPlayer.cpp
@@ -1563,8 +1563,11 @@
//-----------------------------------------------------------------------------
void android_audioPlayer_androidBufferQueue_registerCallback_l(CAudioPlayer *ap) {
- if (ap->mAndroidObjType == STREAM_SOURCE) {
- android_StreamPlayer_registerCallback_l(ap);
+ if ((ap->mAndroidObjType == STREAM_SOURCE) && (ap->mStreamPlayer != 0)) {
+ android_StreamPlayer_androidBufferQueue_registerCallback(ap->mStreamPlayer.get(),
+ ap->mAndroidBufferQueue.mCallback,
+ ap->mAndroidBufferQueue.mContext,
+ (const void*)&(ap->mAndroidBufferQueue.mItf));
}
}
diff --git a/libopensles/android_Player.cpp b/libopensles/android_Player.cpp
new file mode 100644
index 0000000..64fea87
--- /dev/null
+++ b/libopensles/android_Player.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sles_allinclusive.h"
+#include "utils/RefBase.h"
+#include "android_prompts.h"
+
+
+//-----------------------------------------------------------------------------
+XAresult android_Player_create(CMediaPlayer *mp) {
+
+ XAresult result = XA_RESULT_SUCCESS;
+
+ // FIXME verify data source
+ const SLDataSource *pDataSrc = &mp->mDataSource.u.mSource;
+ // FIXME verify audio data sink
+ const SLDataSink *pAudioSnk = &mp->mAudioSink.u.mSink;
+ // FIXME verify image data sink
+ const SLDataSink *pVideoSnk = &mp->mImageVideoSink.u.mSink;
+
+ SLuint32 sourceLocator = *(SLuint32 *)pDataSrc->pLocator;
+ switch(sourceLocator) {
+ case SL_DATALOCATOR_ANDROIDBUFFERQUEUE:
+ break;
+ case SL_DATALOCATOR_URI: // intended fall-through
+ case SL_DATALOCATOR_ANDROIDFD: // intended fall-through
+ case SL_DATALOCATOR_BUFFERQUEUE: // intended fall-through
+ case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: // intended fall-through
+ default:
+ SL_LOGE("Unable to create MediaPlayer for data source locator 0x%lx", sourceLocator);
+ result = XA_RESULT_PARAMETER_INVALID;
+ break;
+
+ }
+
+
+ // FIXME port all CAudioPlayer initialization to CMediaPlayer
+ // FIXME verify play state is correctly initialized
+/*
+ pAudioPlayer->mAndroidObjState = ANDROID_UNINITIALIZED;
+ pAudioPlayer->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
+ pAudioPlayer->mAudioTrack = NULL;
+
+ pAudioPlayer->mSessionId = android::AudioSystem::newAudioSessionId();
+
+
+ pAudioPlayer->mAmplFromVolLevel = 1.0f;
+ pAudioPlayer->mAmplFromStereoPos[0] = 1.0f;
+ pAudioPlayer->mAmplFromStereoPos[1] = 1.0f;
+ pAudioPlayer->mDirectLevel = 0; // no attenuation
+ pAudioPlayer->mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
+ pAudioPlayer->mAuxSendLevel = 0;
+
+ // initialize interface-specific fields that can be used regardless of whether the interface
+ // is exposed on the AudioPlayer or not
+ // (section no longer applicable, as all previous initializations were the same as the defaults)
+*/
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
+XAresult android_Player_realize(CMediaPlayer *mp, SLboolean async) {
+ SL_LOGI("android_Player_realize_l(%p)", mp);
+ XAresult result = XA_RESULT_SUCCESS;
+
+ const SLDataSource *pDataSrc = &mp->mDataSource.u.mSource;
+ const SLuint32 sourceLocator = *(SLuint32 *)pDataSrc->pLocator;
+
+ AudioPlayback_Parameters ap_params;
+ ap_params.sessionId = 0;// FIXME mp->mSessionId;
+ ap_params.streamType = android::AudioSystem::MUSIC;// FIXME mp->mStreamType;
+ ap_params.trackcb = NULL;
+ ap_params.trackcbUser = NULL;
+
+ switch(sourceLocator) {
+ case SL_DATALOCATOR_ANDROIDBUFFERQUEUE: {
+ mp->mAVPlayer = new android::StreamPlayer(&ap_params);
+ mp->mAVPlayer->init();
+ }
+ break;
+ case SL_DATALOCATOR_URI: // intended fall-through
+ case SL_DATALOCATOR_ANDROIDFD: // intended fall-through
+ case SL_DATALOCATOR_BUFFERQUEUE: // intended fall-through
+ case SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE: // intended fall-through
+ default:
+ SL_LOGE("Unable to realize MediaPlayer for data source locator 0x%lx", sourceLocator);
+ result = XA_RESULT_PARAMETER_INVALID;
+ break;
+
+ }
+
+ return result;
+}
+
+
+//-----------------------------------------------------------------------------
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
+XAresult android_Player_setPlayState(CMediaPlayer *mp, SLuint32 playState,
+ AndroidObject_state objState)
+{
+ XAresult result = XA_RESULT_SUCCESS;
+
+ switch (playState) {
+ case SL_PLAYSTATE_STOPPED: {
+ SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_STOPPED");
+ if (mp->mAVPlayer != 0) {
+ mp->mAVPlayer->stop();
+ }
+ } break;
+ case SL_PLAYSTATE_PAUSED: {
+ SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_PAUSED");
+ switch(objState) {
+ case(ANDROID_UNINITIALIZED):
+ if (mp->mAVPlayer != 0) {
+ mp->mAVPlayer->prepare();
+ }
+ break;
+ case(ANDROID_PREPARING):
+ break;
+ case(ANDROID_READY):
+ if (mp->mAVPlayer != 0) {
+ mp->mAVPlayer->pause();
+ }
+ break;
+ default:
+ break;
+ }
+ } break;
+ case SL_PLAYSTATE_PLAYING: {
+ SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_PLAYING");
+ switch(objState) {
+ case(ANDROID_UNINITIALIZED):
+ // FIXME PRIORITY1 prepare should update the obj state
+ // for the moment test app sets state to PAUSED to prepare, then to PLAYING
+ /*if (mp->mAVPlayer != 0) {
+ mp->mAVPlayer->prepare();
+ }*/
+ // fall through
+ case(ANDROID_PREPARING):
+ case(ANDROID_READY):
+ if (mp->mAVPlayer != 0) {
+ mp->mAVPlayer->play();
+ }
+ break;
+ default:
+ break;
+ }
+ } break;
+
+ default:
+ // checked by caller, should not happen
+ break;
+ }
+
+ return result;
+}
+
+
+//----------------------------------------------------------------
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
+void android_StreamPlayer_setPlayState(CAudioPlayer *ap, SLuint32 playState,
+ AndroidObject_state objState)
+{
+ switch (playState) {
+ case SL_PLAYSTATE_STOPPED: {
+ SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_STOPPED");
+ if (ap->mStreamPlayer != 0) {
+ ap->mStreamPlayer->stop();
+ }
+ } break;
+ case SL_PLAYSTATE_PAUSED: {
+ SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_PAUSED");
+ switch(objState) {
+ case(ANDROID_UNINITIALIZED):
+ if (ap->mStreamPlayer != 0) {
+ ap->mStreamPlayer->prepare();
+ }
+ break;
+ case(ANDROID_PREPARING):
+ break;
+ case(ANDROID_READY):
+ if (ap->mStreamPlayer != 0) {
+ ap->mStreamPlayer->pause();
+ }
+ break;
+ default:
+ break;
+ }
+ } break;
+ case SL_PLAYSTATE_PLAYING: {
+ SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_PLAYING");
+ switch(objState) {
+ case(ANDROID_UNINITIALIZED):
+ // FIXME PRIORITY1 prepare should update the obj state
+ // for the moment test app sets state to PAUSED to prepare, then to PLAYING
+ /*if (ap->mStreamPlayer != 0) {
+ ap->mStreamPlayer->prepare();
+ }*/
+ // fall through
+ case(ANDROID_PREPARING):
+ case(ANDROID_READY):
+ if (ap->mStreamPlayer != 0) {
+ ap->mStreamPlayer->play();
+ }
+ break;
+ default:
+ break;
+ }
+ } break;
+
+ default:
+ // checked by caller, should not happen
+ break;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
+void android_Player_androidBufferQueue_registerCallback_l(CMediaPlayer *mp) {
+ if (mp->mAVPlayer != 0) {
+ SL_LOGI("android_Player_androidBufferQueue_registerCallback_l");
+ android::StreamPlayer* splr = (android::StreamPlayer*)(mp->mAVPlayer.get());
+ splr->registerQueueCallback(mp->mAndroidBufferQueue.mCallback,
+ mp->mAndroidBufferQueue.mContext, (const void*)&(mp->mAndroidBufferQueue.mItf));
+ }
+}
+
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
+void android_Player_androidBufferQueue_enqueue_l(CMediaPlayer *mp,
+ SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, void *pData) {
+ if (mp->mAVPlayer != 0) {
+ android::StreamPlayer* splr = (android::StreamPlayer*)(mp->mAVPlayer.get());
+ splr->appEnqueue(bufferId, length, event, pData);
+ }
+}
+
+
+
diff --git a/libopensles/android_Player.h b/libopensles/android_Player.h
new file mode 100644
index 0000000..46254c7
--- /dev/null
+++ b/libopensles/android_Player.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**************************************************************************************************
+ * Player lifecycle
+ ****************************/
+
+extern XAresult android_Player_create(CMediaPlayer *mp);
+
+extern XAresult android_Player_realize(CMediaPlayer *mp, SLboolean async);
+
+
+/**************************************************************************************************
+ * Configuration
+ ****************************/
+
+
+/**************************************************************************************************
+ * Playback control and events
+ ****************************/
+extern XAresult android_Player_setPlayState(CMediaPlayer *mp, SLuint32 playState,
+ AndroidObject_state objState);
+
+
+
+/**************************************************************************************************
+ * Buffer Queue events
+ ****************************/
+
+/**************************************************************************************************
+ * Android Buffer Queue
+ ****************************/
+
+/* must be called with a lock on mp->mThis */
+extern void android_Player_androidBufferQueue_registerCallback_l(CMediaPlayer *mp);
+/* must be called with a lock on mp->mThis */
+extern void android_Player_androidBufferQueue_enqueue_l(CMediaPlayer *mp,
+ SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, void *pData);
diff --git a/libopensles/android_StreamPlayer.cpp b/libopensles/android_StreamPlayer.cpp
index 3c19be3..5ba684e 100644
--- a/libopensles/android_StreamPlayer.cpp
+++ b/libopensles/android_StreamPlayer.cpp
@@ -20,7 +20,8 @@
#undef this // FIXME shouldn't have to do this, no pun intended
#include <media/IMediaPlayerService.h>
-//----------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
void android_StreamPlayer_realize_l(CAudioPlayer *ap) {
SL_LOGI("android_StreamPlayer_realize_l(%p)", ap);
@@ -34,6 +35,7 @@
}
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
void android_StreamPlayer_destroy(CAudioPlayer *ap) {
SL_LOGI("android_StreamPlayer_destroy(%p)", ap);
@@ -41,71 +43,17 @@
}
-void android_StreamPlayer_setPlayState(CAudioPlayer *ap, SLuint32 playState,
- AndroidObject_state objState)
+//-----------------------------------------------------------------------------
+void android_StreamPlayer_androidBufferQueue_registerCallback(android::StreamPlayer *splr,
+ slAndroidBufferQueueCallback callback, void* context, const void* callerItf)
{
- switch (playState) {
- case SL_PLAYSTATE_STOPPED: {
- SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_STOPPED");
- if (ap->mStreamPlayer != 0) {
- ap->mStreamPlayer->stop();
- }
- } break;
- case SL_PLAYSTATE_PAUSED: {
- SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_PAUSED");
- switch(objState) {
- case(ANDROID_UNINITIALIZED):
- if (ap->mStreamPlayer != 0) {
- ap->mStreamPlayer->prepare();
- }
- break;
- case(ANDROID_PREPARING):
- break;
- case(ANDROID_READY):
- if (ap->mStreamPlayer != 0) {
- ap->mStreamPlayer->pause();
- }
- break;
- default:
- break;
- }
- } break;
- case SL_PLAYSTATE_PLAYING: {
- SL_LOGV("setting StreamPlayer to SL_PLAYSTATE_PLAYING");
- switch(objState) {
- case(ANDROID_UNINITIALIZED):
- // FIXME PRIORITY1 prepare should update the obj state
- // for the moment test app sets state to PAUSED to prepare, then to PLAYING
- /*if (ap->mStreamPlayer != 0) {
- ap->mStreamPlayer->prepare();
- }*/
- // fall through
- case(ANDROID_PREPARING):
- case(ANDROID_READY):
- if (ap->mStreamPlayer != 0) {
- ap->mStreamPlayer->play();
- }
- break;
- default:
- break;
- }
- } break;
-
- default:
- // checked by caller, should not happen
- break;
+ if (splr != NULL) {
+ SL_LOGI("android_Player_androidBufferQueue_registerCallback");
+ splr->registerQueueCallback(callback, context, callerItf);
}
}
-
-void android_StreamPlayer_registerCallback_l(CAudioPlayer *ap) {
- if (ap->mStreamPlayer != 0) {
- ap->mStreamPlayer->appRegisterCallback(ap->mAndroidBufferQueue.mCallback,
- ap->mAndroidBufferQueue.mContext, (const void*)&(ap->mAndroidBufferQueue.mItf));
- }
-}
-
-
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
void android_StreamPlayer_enqueue_l(CAudioPlayer *ap,
SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, void *pData) {
if (ap->mStreamPlayer != 0) {
@@ -114,27 +62,27 @@
}
+// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
void android_StreamPlayer_clear_l(CAudioPlayer *ap) {
if (ap->mStreamPlayer != 0) {
ap->mStreamPlayer->appClear();
}
}
-
+//--------------------------------------------------------------------------------------------------
namespace android {
-//--------------------------------------------------------------------------------------------------
StreamSourceAppProxy::StreamSourceAppProxy(
slAndroidBufferQueueCallback callback, void *context, const void *caller) :
mCallback(callback),
mAppContext(context),
mCaller(caller)
{
- SL_LOGV("StreamSourceAppProxy::StreamSourceAppProxy()");
+ SL_LOGI("StreamSourceAppProxy::StreamSourceAppProxy()");
}
StreamSourceAppProxy::~StreamSourceAppProxy() {
- SL_LOGV("StreamSourceAppProxy::~StreamSourceAppProxy()");
+ SL_LOGI("StreamSourceAppProxy::~StreamSourceAppProxy()");
mListener.clear();
mBuffers.clear();
}
@@ -186,7 +134,7 @@
StreamPlayer::StreamPlayer(AudioPlayback_Parameters* params) : AVPlayer(params),
mAppProxy(0)
{
- SL_LOGV("StreamPlayer::StreamPlayer()");
+ SL_LOGI("StreamPlayer::StreamPlayer()");
mPlaybackParams = *params;
@@ -199,16 +147,19 @@
}
void StreamPlayer::init() {
+ SL_LOGI("StreamPlayer::init()");
AVPlayer::init();
}
-void StreamPlayer::appRegisterCallback(slAndroidBufferQueueCallback callback, void *context,
+void StreamPlayer::registerQueueCallback(slAndroidBufferQueueCallback callback, void *context,
const void *caller) {
+ SL_LOGI("StreamPlayer::registerQueueCallback");
Mutex::Autolock _l(mLock);
mAppProxy = new StreamSourceAppProxy(callback, context, caller);
CHECK(mAppProxy != 0);
+ SL_LOGI("StreamPlayer::registerQueueCallback end");
}
void StreamPlayer::appEnqueue(SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event,
@@ -243,13 +194,16 @@
// Event handlers
void StreamPlayer::onPrepare() {
SL_LOGI("StreamPlayer::onPrepare()");
- mPlayer = mMediaPlayerService->create(getpid(), mPlayerClient /*IMediaPlayerClient*/,
- mAppProxy /*IStreamSource*/, mPlaybackParams.sessionId);
- SL_LOGI("StreamPlayer::onPrepare() after mMediaPlayerService->create()");
-
- // blocks until mPlayer is prepared
- AVPlayer::onPrepare();
- SL_LOGI("StreamPlayer::onPrepare() done");
+ //Mutex::Autolock _l(mLock);
+ if (mAppProxy != 0) {
+ mPlayer = mMediaPlayerService->create(getpid(), mPlayerClient /*IMediaPlayerClient*/,
+ mAppProxy /*IStreamSource*/, mPlaybackParams.sessionId);
+ // blocks until mPlayer is prepared
+ AVPlayer::onPrepare();
+ SL_LOGI("StreamPlayer::onPrepare() done");
+ } else {
+ SL_LOGE("Nothing to do here because there is no registered callback");
+ }
}
diff --git a/libopensles/android_StreamPlayer.h b/libopensles/android_StreamPlayer.h
index fcaef8d..e4e53d9 100644
--- a/libopensles/android_StreamPlayer.h
+++ b/libopensles/android_StreamPlayer.h
@@ -16,31 +16,12 @@
#include <binder/IServiceManager.h>
-//--------------------------------------------------------------------------------------------------
-// FIXME move to mediaplayer.h
-enum media_player_stream_origin {
- MEDIA_PLAYER_STREAM_ORIGIN_INVALID = 0,
- MEDIA_PLAYER_STREAM_ORIGIN_FILE = 1 << 0,
- MEDIA_PLAYER_STREAM_ORIGIN_TRANSPORT_STREAM = 1 << 1
-};
typedef struct StreamPlayback_Parameters_struct {
int streamType;
int sessionId;
} StreamPlayback_Parameters;
-//--------------------------------------------------------------------------------------------------
-/*
- * xxx_l functions are called with a lock on the CAudioPlayer mObject
- */
-extern void android_StreamPlayer_realize_l(CAudioPlayer *ap);
-extern void android_StreamPlayer_destroy(CAudioPlayer *ap);
-extern void android_StreamPlayer_setPlayState(CAudioPlayer *ap, SLuint32 playState,
- AndroidObject_state objState);
-extern void android_StreamPlayer_registerCallback_l(CAudioPlayer *ap);
-extern void android_StreamPlayer_enqueue_l(CAudioPlayer *ap,
- SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, void *pData);
-extern void android_StreamPlayer_clear_l(CAudioPlayer *ap);
//--------------------------------------------------------------------------------------------------
namespace android {
@@ -84,7 +65,7 @@
virtual void init();
- void appRegisterCallback(slAndroidBufferQueueCallback callback, void *context,
+ void registerQueueCallback(slAndroidBufferQueueCallback callback, void *context,
const void *caller);
void appEnqueue(SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, void *pData);
void appClear();
@@ -100,3 +81,19 @@
};
} // namespace android
+
+
+//--------------------------------------------------------------------------------------------------
+/*
+ * xxx_l functions are called with a lock on the CAudioPlayer mObject
+ */
+extern void android_StreamPlayer_realize_l(CAudioPlayer *ap);
+extern void android_StreamPlayer_destroy(CAudioPlayer *ap);
+extern void android_StreamPlayer_setPlayState(CAudioPlayer *ap, SLuint32 playState,
+ AndroidObject_state objState);
+extern void android_StreamPlayer_androidBufferQueue_registerCallback(
+ android::StreamPlayer *splr,
+ slAndroidBufferQueueCallback callback, void* context, const void* callerItf);
+extern void android_StreamPlayer_enqueue_l(CAudioPlayer *ap,
+ SLuint32 bufferId, SLuint32 length, SLAbufferQueueEvent event, void *pData);
+extern void android_StreamPlayer_clear_l(CAudioPlayer *ap);
diff --git a/libopensles/classes.c b/libopensles/classes.c
index 79fccbc..1ca0a52 100644
--- a/libopensles/classes.c
+++ b/libopensles/classes.c
@@ -405,6 +405,7 @@
{MPH_DYNAMICINTERFACEMANAGEMENT, INTERFACE_IMPLICIT,
offsetof(CMediaPlayer, mDynamicInterfaceManagement)},
{MPH_XAPLAY, INTERFACE_IMPLICIT, offsetof(CMediaPlayer, mPlay)},
+ {MPH_ANDROIDBUFFERQUEUE, INTERFACE_EXPLICIT, offsetof(CMediaPlayer, mAndroidBufferQueue)},
};
static const ClassTable CMediaPlayer_class = {
diff --git a/libopensles/classes.h b/libopensles/classes.h
index 4703bea..e339747 100644
--- a/libopensles/classes.h
+++ b/libopensles/classes.h
@@ -299,10 +299,13 @@
typedef struct CMediaPlayer_struct {
IObject mObject;
-#define INTERFACES_MediaPlayer 3
+#define INTERFACES_MediaPlayer 4
XAuint8 mInterfaceStates2[INTERFACES_MediaPlayer - INTERFACES_Default];
IDynamicInterfaceManagement mDynamicInterfaceManagement;
IPlay mPlay;
+#ifdef ANDROID
+ IAndroidBufferQueue mAndroidBufferQueue;
+#endif
// ...
DataLocatorFormat mDataSource;
DataLocatorFormat mBankSource;
@@ -311,6 +314,7 @@
DataLocatorFormat mVibraSink;
DataLocatorFormat mLEDArraySink;
#ifdef ANDROID
- android::sp<android::IMediaPlayer> mPlayer;
+ //android::sp<android::IMediaPlayer> mPlayer;
+ android::sp<android::AVPlayer> mAVPlayer;
#endif
} CMediaPlayer;
diff --git a/libopensles/locks.c b/libopensles/locks.c
index 62a3a71..4d66cc3 100644
--- a/libopensles/locks.c
+++ b/libopensles/locks.c
@@ -192,21 +192,10 @@
{
attributes &= ~ATTR_TRANSPORT; // no need to process asynchronously also
CMediaPlayer *mp = (CMediaPlayer *) this;
- // CMediaPlayer_setPlayState(mp);
- android::sp<android::IMediaPlayer> player = mp->mPlayer;
- if (player != NULL) {
- switch (mp->mPlay.mState) {
- case XA_PLAYSTATE_PLAYING:
- player->start();
- break;
- case XA_PLAYSTATE_PAUSED:
- case XA_PLAYSTATE_STOPPED:
- player->stop();
- break;
- default:
- break;
- }
- }
+ SLuint32 playState = mp->mPlay.mState;
+ // FIXME use object state
+ //AndroidObject_state objState = mp->mAndroidObjState;
+ android_Player_setPlayState(mp, playState, ANDROID_UNINITIALIZED);
}
#endif
break;
diff --git a/libopensles/sles_allinclusive.h b/libopensles/sles_allinclusive.h
index c70a0f5..04bd06a 100644
--- a/libopensles/sles_allinclusive.h
+++ b/libopensles/sles_allinclusive.h
@@ -323,6 +323,7 @@
#define InterfaceToCAudioRecorder(this) (((CAudioRecorder*)InterfaceToIObject(this)))
#ifdef ANDROID
+#include "android_Player.h"
#include "android_AudioPlayer.h"
#endif