Commit 37dc2fcc authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Bug 3329759 Implement streamInformation and volume in OpenMAX AL

- Implement StreamInformation for video size notification.
- Implement the XAVolumeItf for volume control
- Fix bug in GUID -> MPH hash.
- Fixed typo in GenericPlayer::pause() log
- Do not signal a discontinuity automatically when the ABQ is
  cleared because clearing the queue doesn't imply there will
  be a discontinuity in the data (e.g. the same data that was
  cleared could be reenqueued)
- In "native-media" test app: add test code to exercise the
  XAVolumeItf functionality.

Change-Id: I9f69f8cacbdce51b6d96d60141ec1d0f645df991
parent f2f18de5
......@@ -49,8 +49,9 @@ typedef struct XAAndroidBufferItem_ {
typedef XAresult (XAAPIENTRY *xaAndroidBufferQueueCallback)(
XAAndroidBufferQueueItf caller,/* input */
void *pContext, /* input */
const void *pBufferData, /* input */
void *pCallbackContext, /* input */
void *pBufferContext, /* input */
void *pBufferData, /* input */
XAuint32 dataSize, /* input */
XAuint32 dataUsed, /* input */
const XAAndroidBufferItem *pItems,/* input */
......@@ -66,7 +67,7 @@ struct XAAndroidBufferQueueItf_ {
XAresult (*RegisterCallback) (
XAAndroidBufferQueueItf self,
xaAndroidBufferQueueCallback callback,
void* pContext
void* pCallbackContext
);
XAresult (*Clear) (
......@@ -75,7 +76,8 @@ struct XAAndroidBufferQueueItf_ {
XAresult (*Enqueue) (
XAAndroidBufferQueueItf self,
const void *pData,
void *pBufferContext,
void *pData,
XAuint32 dataLength,
const XAAndroidBufferItem *pItems,
XAuint32 itemsLength
......
......@@ -224,8 +224,9 @@ typedef struct SLAndroidBufferItem_ {
typedef SLresult (SLAPIENTRY *slAndroidBufferQueueCallback)(
SLAndroidBufferQueueItf caller,/* input */
void *pContext, /* input */
const void *pBufferData, /* input */
void *pCallbackContext, /* input */
void *pBufferContext, /* input */
void *pBufferData, /* input */
SLuint32 dataSize, /* input */
SLuint32 dataUsed, /* input */
const SLAndroidBufferItem *pItems,/* input */
......@@ -241,7 +242,7 @@ struct SLAndroidBufferQueueItf_ {
SLresult (*RegisterCallback) (
SLAndroidBufferQueueItf self,
slAndroidBufferQueueCallback callback,
void* pContext
void* pCallbackContext
);
SLresult (*Clear) (
......@@ -250,7 +251,8 @@ struct SLAndroidBufferQueueItf_ {
SLresult (*Enqueue) (
SLAndroidBufferQueueItf self,
const void *pData,
void *pBufferContext,
void *pData,
SLuint32 dataLength,
const SLAndroidBufferItem *pItems,
SLuint32 itemsLength
......
......@@ -79,14 +79,15 @@
#define MPH_ANDROIDSIMPLEBUFFERQUEUE 49
// Android API level 10 extended interfaces
#define MPH_ANDROIDBUFFERQUEUE 50
#define MPH_ANDROIDBUFFERQUEUE 50 // used for SL and XA
// OpenMAX AL 1.0.1
#define MPH_XAENGINE 51
#define MPH_XAPLAY 52
#define MPH_XASTREAMINFORMATION 53
#define MPH_XAVOLUME 54
// total number of interface IDs
#define MPH_MAX 54
#define MPH_MAX 55
#endif // !defined(__MPH_H)
......@@ -249,7 +249,9 @@ const signed char MPH_to_MediaPlayer[MPH_MAX] = {
[MPH_OBJECT] = 0,
[MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
[MPH_XAPLAY] = 2,
[MPH_ANDROIDBUFFERQUEUE] = 3,
[MPH_XASTREAMINFORMATION] = 3,
[MPH_XAVOLUME] = 4,
[MPH_ANDROIDBUFFERQUEUE] = 5,
// FIXME more TBD
#else
#include "MPH_to_MediaPlayer.h"
......
......@@ -173,6 +173,8 @@ const struct SLInterfaceID_ SL_IID_array[MPH_MAX] = {
{ 0xb9c293e0, 0xf776, 0x11db, 0x80df, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
// XA_IID_STREAMINFORMATION
{ 0x3a628fe0, 0x1238, 0x11de, 0xad9f, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
// XA_IID_VOLUME
{ 0x088ba520, 0xf777, 0x11db, 0xa5e3, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
// OpenMAX AL 1.0.1 Android API level 10 extended interfaces
// XA_IID_ANDROIDBUFFERQUEUE
......@@ -250,6 +252,7 @@ const XAInterfaceID XA_IID_ENGINE = (XAInterfaceID) &SL_IID_array[MPH_XAENGINE];
const XAInterfaceID XA_IID_PLAY = (XAInterfaceID) &SL_IID_array[MPH_XAPLAY];
const XAInterfaceID XA_IID_STREAMINFORMATION =
(XAInterfaceID) &SL_IID_array[MPH_XASTREAMINFORMATION];
const XAInterfaceID XA_IID_VOLUME = (XAInterfaceID) &SL_IID_array[MPH_XAVOLUME];
// OpenMAX AL 1.0.1 Android API level 10 extended interfaces
const XAInterfaceID XA_IID_ANDROIDBUFFERQUEUE =
......
......@@ -639,7 +639,7 @@ static void sfplayer_prepare(CAudioPlayer *ap, bool lockAP) {
//-----------------------------------------------------------------------------
// Callback associated with an SfPlayer of an SL ES AudioPlayer that gets its data
// from a URI or FD, for prepare and prefetch events
static void sfplayer_handlePrefetchEvent(int event, int data1, void* user) {
static void sfplayer_handlePrefetchEvent(int event, int data1, int data2, void* user) {
if (NULL == user) {
return;
}
......
......@@ -20,7 +20,7 @@
//-----------------------------------------------------------------------------
static void player_handleMediaPlayerEventNotifications(const int event, const int data1, void* user)
static void player_handleMediaPlayerEventNotifications(int event, int data1, int data2, void* user)
{
if (NULL == user) {
return;
......@@ -31,15 +31,55 @@ static void player_handleMediaPlayerEventNotifications(const int event, const in
switch(event) {
case android::GenericPlayer::kEventPrepared: {
case android::GenericPlayer::kEventPrepared: {
if (PLAYER_SUCCESS == data1) {
object_lock_exclusive(&mp->mObject);
SL_LOGV("Received AVPlayer::kEventPrepared from AVPlayer for CMediaPlayer %p", mp);
mp->mAndroidObjState = ANDROID_READY;
object_unlock_exclusive(&mp->mObject);
}
break;
}
case android::GenericPlayer::kEventHasVideoSize: {
SL_LOGV("Received AVPlayer::kEventHasVideoSize (%d,%d) for CMediaPlayer %p",
data1, data2, mp);
object_lock_exclusive(&mp->mObject);
// remove an existing video info entry (here we only have one video stream)
for(size_t i=0 ; i < mp->mStreamInfo.mStreamInfoTable.size() ; i++) {
if (XA_DOMAINTYPE_VIDEO == mp->mStreamInfo.mStreamInfoTable.itemAt(i).domain) {
mp->mStreamInfo.mStreamInfoTable.removeAt(i);
break;
}
}
// update the stream information with a new video info entry
StreamInfo streamInfo;
streamInfo.domain = XA_DOMAINTYPE_VIDEO;
streamInfo.videoInfo.codecId = 0;// unknown, we don't have that info FIXME
streamInfo.videoInfo.width = (XAuint32)data1;
streamInfo.videoInfo.height = (XAuint32)data2;
streamInfo.videoInfo.bitRate = 0;// unknown, we don't have that info FIXME
streamInfo.videoInfo.duration = XA_TIME_UNKNOWN;
StreamInfo &contInfo = mp->mStreamInfo.mStreamInfoTable.editItemAt(0);
contInfo.containerInfo.numStreams = 1;
ssize_t index = mp->mStreamInfo.mStreamInfoTable.add(streamInfo);
xaStreamEventChangeCallback callback = mp->mStreamInfo.mCallback;
void* callbackPContext = mp->mStreamInfo.mContext;
object_unlock_exclusive(&mp->mObject);
// notify (outside of lock) that the stream information has been updated
if ((NULL != callback) && (index >= 0)) {
(*callback)(&mp->mStreamInfo.mItf, XA_STREAMCBEVENT_PROPERTYCHANGE /*eventId*/,
1 /*streamIndex, only one stream supported here, 0 is reserved*/,
NULL /*pEventData, always NULL in OpenMAX AL 1.0.1*/,
callbackPContext /*pContext*/);
}
break;
}
default:
SL_LOGE("Received unknown event %d, data %d from AVPlayer", event, data1);
......@@ -141,11 +181,6 @@ XAresult android_Player_create(CMediaPlayer *mp) {
mp->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
mp->mSessionId = android::AudioSystem::newAudioSessionId();
mp->mAndroidAudioLevels.mAmplFromVolLevel = 1.0f;
mp->mAndroidAudioLevels.mAmplFromStereoPos[0] = 1.0f;
mp->mAndroidAudioLevels.mAmplFromStereoPos[1] = 1.0f;
mp->mAndroidAudioLevels.mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
mp->mAndroidAudioLevels.mAuxSendLevel = 0;
mp->mDirectLevel = 0; // no attenuation
return result;
......@@ -274,6 +309,21 @@ XAresult android_Player_getDuration(IPlay *pPlayItf, XAmillisecond *pDurMsec) {
return result;
}
//-----------------------------------------------------------------------------
/**
* pre-condition: avp != NULL, pVolItf != NULL
*/
XAresult android_Player_volumeUpdate(android::GenericPlayer *avp, IVolume *pVolItf)
{
XAresult result = XA_RESULT_SUCCESS;
avp->updateVolume((bool)pVolItf->mMute, (bool)pVolItf->mEnableStereoPosition,
pVolItf->mStereoPosition, pVolItf->mLevel);
return result;
}
//-----------------------------------------------------------------------------
/**
* pre-condition: avp != NULL
......
......@@ -46,6 +46,11 @@ extern XAresult android_Player_setVideoSurfaceTexture(android::GenericMediaPlaye
extern XAresult android_Player_getDuration(IPlay *pPlayItf, SLmillisecond *pDurMsec);
/**
* pre-condition: avp != NULL, pVolItf != NULL
*/
extern XAresult android_Player_volumeUpdate(android::GenericPlayer *avp, IVolume *pVolItf);
/**************************************************************************************************
* Playback control and events
****************************/
......
......@@ -459,15 +459,15 @@ void AudioSfDecoder::onNotify(const sp<AMessage> &msg) {
int32_t val;
if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val)) {
SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val);
mNotifyClient(kEventPrefetchStatusChange, val, mNotifyUser);
mNotifyClient(kEventPrefetchStatusChange, val, 0, mNotifyUser);
}
else if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val)) {
SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val);
mNotifyClient(kEventPrefetchFillLevelUpdate, val, mNotifyUser);
mNotifyClient(kEventPrefetchFillLevelUpdate, val, 0, mNotifyUser);
}
else if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val)) {
SL_LOGV("\tASfPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val);
mNotifyClient(kEventEndOfStream, val, mNotifyUser);
mNotifyClient(kEventEndOfStream, val, 0, mNotifyUser);
}
else {
GenericPlayer::onNotify(msg);
......
......@@ -24,7 +24,8 @@
namespace android {
//--------------------------------------------------------------------------------------------------
MediaPlayerNotificationClient::MediaPlayerNotificationClient() :
MediaPlayerNotificationClient::MediaPlayerNotificationClient(GenericMediaPlayer* gmp) :
mGenericMediaPlayer(gmp),
mPlayerPrepared(false)
{
......@@ -39,9 +40,18 @@ MediaPlayerNotificationClient::~MediaPlayerNotificationClient() {
void MediaPlayerNotificationClient::notify(int msg, int ext1, int ext2) {
SL_LOGI("MediaPlayerNotificationClient::notify(msg=%d, ext1=%d, ext2=%d)", msg, ext1, ext2);
if (msg == MEDIA_PREPARED) {
switch (msg) {
case MEDIA_PREPARED:
mPlayerPrepared = true;
mPlayerPreparedCondition.signal();
break;
case MEDIA_SET_VIDEO_SIZE:
mGenericMediaPlayer->notify(PLAYEREVENT_VIDEO_SIZE_UPDATE,
(int32_t)ext1, (int32_t)ext2, true /*async*/);
break;
default: { }
}
}
......@@ -70,7 +80,7 @@ GenericMediaPlayer::GenericMediaPlayer(const AudioPlayback_Parameters* params, b
CHECK(mMediaPlayerService.get() != NULL);
mPlayerClient = new MediaPlayerNotificationClient();
mPlayerClient = new MediaPlayerNotificationClient(this);
}
GenericMediaPlayer::~GenericMediaPlayer() {
......@@ -125,6 +135,18 @@ void GenericMediaPlayer::onPause() {
mPlayer->pause();
mStateFlags &= ~kFlagPlaying;
}
}
void GenericMediaPlayer::onVolumeUpdate() {
// use settings lock to read the volume settings
Mutex::Autolock _l(mSettingsLock);
if (this->mAndroidAudioLevels.mMute) {
mPlayer->setVolume(0.0f, 0.0f);
} else {
mPlayer->setVolume(mAndroidAudioLevels.mFinalVolume[0],
mAndroidAudioLevels.mFinalVolume[1]);
}
}
......
......@@ -23,10 +23,11 @@
//--------------------------------------------------------------------------------------------------
namespace android {
class GenericMediaPlayer;
class MediaPlayerNotificationClient : public BnMediaPlayerClient
{
public:
MediaPlayerNotificationClient();
MediaPlayerNotificationClient(GenericMediaPlayer* gmp);
virtual ~MediaPlayerNotificationClient();
// IMediaPlayerClient implementation
......@@ -36,6 +37,7 @@ public:
private:
Mutex mLock;
GenericMediaPlayer* mGenericMediaPlayer;
Condition mPlayerPreparedCondition;
bool mPlayerPrepared;
};
......@@ -53,11 +55,13 @@ public:
virtual void setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture);
protected:
friend class MediaPlayerNotificationClient;
// Async event handlers (called from GenericPlayer's event loop)
virtual void onPrepare();
virtual void onPlay();
virtual void onPause();
virtual void onVolumeUpdate();
bool mHasVideo;
......
......@@ -27,12 +27,16 @@ GenericPlayer::GenericPlayer(const AudioPlayback_Parameters* params) :
mNotifyUser(NULL),
mStateFlags(0),
mLooperPriority(PRIORITY_DEFAULT),
mPlaybackParams(*params)
mPlaybackParams(*params),
mChannelCount(1)
{
SL_LOGI("GenericPlayer::GenericPlayer()");
mLooper = new android::ALooper();
mAndroidAudioLevels.mMute = false;
mAndroidAudioLevels.mFinalVolume[0] = 1.0f;
mAndroidAudioLevels.mFinalVolume[1] = 1.0f;
}
......@@ -111,7 +115,7 @@ void GenericPlayer::play() {
void GenericPlayer::pause() {
SL_LOGI("GenericPlayer::prepare()");
SL_LOGI("GenericPlayer::pause()");
sp<AMessage> msg = new AMessage(kWhatPause, id());
msg->post();
}
......@@ -147,6 +151,52 @@ void GenericPlayer::getDurationMsec(int* msec) {
*msec = -1;
}
//--------------------------------------------------
void GenericPlayer::updateVolume(bool mute, bool useStereoPos,
XApermille stereoPos, XAmillibel volume) {
// compute amplification as the combination of volume level and stereo position
float leftVol = 1.0f, rightVol = 1.0f;
// amplification from volume level
leftVol *= sles_to_android_amplification(volume);
rightVol = leftVol;
// amplification from direct level (changed in SLEffectSendtItf and SLAndroidEffectSendItf)
// FIXME use calculation below when supporting effects
//leftVol *= mAndroidAudioLevels.mAmplFromDirectLevel;
//rightVol *= mAndroidAudioLevels.mAmplFromDirectLevel;
// amplification from stereo position
if (useStereoPos) {
// panning law depends on number of channels of content: stereo panning vs 2ch. balance
if (1 == mChannelCount) {
// stereo panning
double theta = (1000 + stereoPos) * M_PI_4 / 1000.0f; // 0 <= theta <= Pi/2
leftVol *= cos(theta);
rightVol *= sin(theta);
} else {
// stereo balance
if (stereoPos > 0) {
leftVol *= (1000 - stereoPos) / 1000.0f;
rightVol *= 1.0f;
} else {
leftVol *= 1.0f;
rightVol *= (1000 + stereoPos) / 1000.0f;
}
}
}
{
Mutex::Autolock _l(mSettingsLock);
mAndroidAudioLevels.mMute = mute;
mAndroidAudioLevels.mFinalVolume[0] = leftVol;
mAndroidAudioLevels.mFinalVolume[1] = rightVol;
}
// send a message for the volume to be updated by the object which implements the volume
(new AMessage(kWhatVolumeUpdate, id()))->post();
}
//--------------------------------------------------
/*
......@@ -169,6 +219,17 @@ void GenericPlayer::notify(const char* event, int data, bool async) {
}
void GenericPlayer::notify(const char* event, int data1, int data2, bool async) {
sp<AMessage> msg = new AMessage(kWhatNotif, id());
msg->setRect(event, 0, 0, (int32_t)data1, (int32_t)data2);
if (async) {
msg->post();
} else {
this->onNotify(msg);
}
}
//--------------------------------------------------
// AHandler implementation
void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) {
......@@ -197,6 +258,10 @@ void GenericPlayer::onMessageReceived(const sp<AMessage> &msg) {
onLoop(msg);
break;
case kWhatVolumeUpdate:
onVolumeUpdate();
break;
default:
TRESPASS();
}
......@@ -220,10 +285,13 @@ void GenericPlayer::onNotify(const sp<AMessage> &msg) {
return;
}
int32_t val;
if (msg->findInt32(PLAYEREVENT_PREPARED, &val)) {
SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val);
mNotifyClient(kEventPrepared, val, mNotifyUser);
int32_t val1, val2;
if (msg->findInt32(PLAYEREVENT_PREPARED, &val1)) {
SL_LOGV("GenericPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val1);
mNotifyClient(kEventPrepared, val1, 0, mNotifyUser);
} else if (msg->findRect(PLAYEREVENT_VIDEO_SIZE_UPDATE, &val1, &val2, &val1, &val2)) {
SL_LOGD("GenericPlayer notifying %s = %d, %d", PLAYEREVENT_VIDEO_SIZE_UPDATE, val1, val2);
mNotifyClient(kEventHasVideoSize, val1, val2, mNotifyUser);
}
}
......@@ -257,4 +325,9 @@ void GenericPlayer::onLoop(const sp<AMessage> &msg) {
SL_LOGV("GenericPlayer::onLoop");
}
void GenericPlayer::onVolumeUpdate() {
}
} // namespace android
......@@ -23,7 +23,8 @@ class GenericPlayer : public AHandler
public:
enum {
kEventPrepared = 'prep'
kEventPrepared = 'prep',
kEventHasVideoSize = 'vsiz',
};
GenericPlayer(const AudioPlayback_Parameters* params);
......@@ -43,23 +44,28 @@ public:
virtual void getDurationMsec(int* msec); // -1 if unknown
void updateVolume(bool mute, bool useStereoPos, XApermille stereoPos, XAmillibel volume);
protected:
Mutex mSettingsLock;
void resetDataLocator();
DataLocator2 mDataLocator;
int mDataLocatorType;
enum {
kWhatPrepare = 'prep',
kWhatNotif = 'noti',
kWhatPlay = 'play',
kWhatPause = 'paus',
kWhatSeek = 'seek',
kWhatLoop = 'loop',
kWhatPrepare = 'prep',
kWhatNotif = 'noti',
kWhatPlay = 'play',
kWhatPause = 'paus',
kWhatSeek = 'seek',
kWhatLoop = 'loop',
kWhatVolumeUpdate = 'volu'
};
// Send a notification to one of the event listeners
virtual void notify(const char* event, int data, bool async);
virtual void notify(const char* event, int data1, bool async);
virtual void notify(const char* event, int data1, int data2, bool async);
// AHandler implementation
virtual void onMessageReceived(const sp<AMessage> &msg);
......@@ -71,6 +77,7 @@ protected:
virtual void onPause();
virtual void onSeek(const sp<AMessage> &msg);
virtual void onLoop(const sp<AMessage> &msg);
virtual void onVolumeUpdate();
// Event notification from GenericPlayer to OpenSL ES / OpenMAX AL framework
notif_cbf_t mNotifyClient;
......@@ -92,6 +99,9 @@ protected:
AudioPlayback_Parameters mPlaybackParams;
AndroidAudioLevels mAndroidAudioLevels;
int mChannelCount; // this is used for the panning law, and is not exposed outside of the object
private:
DISALLOW_EVIL_CONSTRUCTORS(GenericPlayer);
};
......
......@@ -733,25 +733,25 @@ void SfPlayer::onNotify(const sp<AMessage> &msg) {
int32_t val;
if (msg->findInt32(PLAYEREVENT_PREFETCHSTATUSCHANGE, &val)) {
SL_LOGV("\tSfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHSTATUSCHANGE, val);
mNotifyClient(kEventPrefetchStatusChange, val, mNotifyUser);
mNotifyClient(kEventPrefetchStatusChange, val, 0, mNotifyUser);
}
if (msg->findInt32(PLAYEREVENT_PREFETCHFILLLEVELUPDATE, &val)) {
SL_LOGV("\tSfPlayer notifying %s = %d", PLAYEREVENT_PREFETCHFILLLEVELUPDATE, val);
mNotifyClient(kEventPrefetchFillLevelUpdate, val, mNotifyUser);
mNotifyClient(kEventPrefetchFillLevelUpdate, val, 0, mNotifyUser);
}
if (msg->findInt32(PLAYEREVENT_ENDOFSTREAM, &val)) {
SL_LOGV("\tSfPlayer notifying %s = %d", PLAYEREVENT_ENDOFSTREAM, val);
mNotifyClient(kEventEndOfStream, val, mNotifyUser);
mNotifyClient(kEventEndOfStream, val, 0, mNotifyUser);
}
if (msg->findInt32(PLAYEREVENT_PREPARED, &val)) {
SL_LOGV("\tSfPlayer notifying %s = %d", PLAYEREVENT_PREPARED, val);
mNotifyClient(GenericMediaPlayer::kEventPrepared, val, mNotifyUser);
mNotifyClient(GenericMediaPlayer::kEventPrepared, val, 0, mNotifyUser);
}
if (msg->findInt32(PLAYEREVENT_NEW_AUDIOTRACK, &val)) {
SL_LOGV("\tSfPlayer notifying %s", PLAYEREVENT_NEW_AUDIOTRACK);
mNotifyClient(kEventNewAudioTrack, val, mNotifyUser);
mNotifyClient(kEventNewAudioTrack, val, 0, mNotifyUser);
}
}
......
......@@ -218,6 +218,7 @@ void StreamSourceAppProxy::pullFromBuffQueue() {
// oldFront was only initialized in the code path where callback is initialized
// so no need to check if it's valid
(*callback)(&mAndroidBufferQueue->mItf, callbackPContext,
(void *)oldFront->mBufferContext, /* pBufferContext */
(void *)oldFront->mDataBuffer,/* pBufferData */
oldFront->mDataSize, /* dataSize */
// here a buffer is only dequeued when fully consumed
......@@ -286,11 +287,8 @@ void StreamPlayer::queueRefilled_l() {
void StreamPlayer::appClear_l() {
// the user of StreamPlayer has cleared its AndroidBufferQueue: a discontinuity is expected
Mutex::Autolock _l(mAppProxyLock);
if (mAppProxy != 0) {
mAppProxy->receivedCmd_l(IStreamListener::DISCONTINUITY);
}
// the user of StreamPlayer has cleared its AndroidBufferQueue:
// there's no clear() for the shared memory queue, so this is a no-op
}
......
......@@ -59,27 +59,33 @@ enum AndroidObject_state {
* Structure to maintain the set of audio levels about a player
*/
typedef struct AndroidAudioLevels_struct {
/** send level to aux effect, there's a single aux bus, so there's a single level */
SLmillibel mAuxSendLevel;
/**
* Amplification (can be attenuation) factor derived for the VolumeLevel
* Is this player muted
*/
float mAmplFromVolLevel;
bool mMute;
/**
* Left/right amplification (can be attenuations) factors derived for the StereoPosition
* Send level to aux effect, there's a single aux bus, so there's a single level
*/
float mAmplFromStereoPos[STEREO_CHANNELS];
// FIXME not used yet, will be used when supporting effects in OpenMAX AL
//SLmillibel mAuxSendLevel;
/**
* Attenuation factor derived from direct level
*/
float mAmplFromDirectLevel;
// FIXME not used yet, will be used when supporting effects in OpenMAX AL
//float mAmplFromDirectLevel;
/**
* Android Left/Right volume
* The final volume of an Android AudioTrack or MediaPlayer is a stereo amplification
* (or attenuation) represented as a float from 0.0f to 1.0f
*/
float mFinalVolume[STEREO_CHANNELS];
} AndroidAudioLevels;
/**
* Event notification callback from Android to SL ES framework
*/
typedef void (*notif_cbf_t)(int event, int data1, void* notifUser);
typedef void (*notif_cbf_t)(int event, int data1, int data2, void* notifUser);
/**
* Audio data push callback from Android objects to SL ES framework
......@@ -96,6 +102,7 @@ typedef size_t (*data_push_cbf_t)(const uint8_t *data, size_t size, void* user);
#define PLAYEREVENT_PREFETCHFILLLEVELUPDATE "pflu"
#define PLAYEREVENT_ENDOFSTREAM "eos"
#define PLAYEREVENT_NEW_AUDIOTRACK "nwat"
#define PLAYEREVENT_VIDEO_SIZE_UPDATE "vsiz"
/**
......
......@@ -29,37 +29,61 @@ extern const struct SLInterfaceID_ SL_IID_array[MPH_MAX];
int IID_to_MPH(const SLInterfaceID iid)
{
#define MAX_HASH_VALUE 115
#define MAX_HASH_VALUE 139
static const unsigned char asso_values[] =
{
5, 116, 116, 2, 116, 116, 17, 116, 116, 17,
116, 22, 116, 116, 116, 51, 116, 116, 116, 116,
116, 116, 2, 116, 116, 46, 116, 116, 116, 116,
116, 17, 20, 116, 116, 116, 116, 116, 116, 116,
116, 116, 51, 20, 46, 116, 31, 116, 116, 116,
116, 116, 116, 36, 116, 2, 116, 116, 2, 116,
116, 61, 116, 2, 55, 116, 116, 116, 116, 16,
116, 26, 116, 116, 116, 116, 116, 116, 116, 116,
21, 116, 116, 116, 116, 116, 26, 116, 116, 116,
11, 116, 116, 116, 116, 116, 40, 21, 116, 60,
116, 116, 116, 116, 116, 116, 16, 116, 116, 116,
116, 116, 1, 116, 116, 116, 116, 116, 116, 116,
116, 11, 55, 6, 116, 116, 116, 6, 45, 116,
116, 1, 116, 116, 116, 116, 116, 1, 116, 116,
116, 1, 116, 116, 116, 116, 116, 116, 116, 116,
116, 60, 116, 116, 116, 116, 116, 116, 116, 116,
10, 116, 116, 116, 116, 116, 116, 116, 116, 116,
50, 116, 116, 116, 45, 116, 116, 116, 60, 116,
45, 116, 116, 116, 116, 55, 116, 116, 116, 116,
116, 116, 15, 116, 35, 116, 45, 5, 116, 50,
116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
116, 116, 40, 116, 116, 50, 116, 116, 116, 116,
116, 25, 116, 116, 15, 40, 116, 116, 10, 116,
116, 116, 116, 116, 116, 10, 0, 116, 116, 15,
30, 116, 116, 116, 116, 116, 55, 116, 116, 116,
116, 116, 116, 116, 0, 116
5, 140, 140, 7, 140, 140, 27, 140, 17, 17,
140, 22, 140, 140, 140, 51, 140, 140, 140, 140,
140, 140, 2, 140, 140, 46, 140, 140, 140, 140,
140, 17, 20, 140, 140, 140, 140, 140, 140, 140,
140, 140, 51, 20, 46, 140, 31, 140, 140, 140,
140, 140, 140, 36, 140, 2, 140, 140, 2, 140,
140, 61, 140, 2, 55, 140, 140, 140, 140, 16,
140, 26, 140, 140, 140, 140, 140, 140, 140, 140,
21, 140, 140, 140, 140, 140, 26, 140, 140, 140,
11, 140, 140, 140, 140, 140, 40, 21, 140, 60,
140, 140, 140, 140, 140, 140, 16, 140, 140, 140,
140, 140, 1, 140, 140, 140, 140, 140, 140, 140,
140, 11, 55, 6, 140, 140, 140, 6, 45, 140,
140, 1, 140, 140, 140, 140, 140, 1, 140, 140,
140, 1, 140, 140, 140, 140, 140, 140, 140, 140,
140, 60, 140, 140, 140, 140, 140, 140, 140, 140,
10, 140, 140, 140, 140, 140, 140, 140, 140, 140,
50, 140, 140, 140, 45, 140, 140, 140, 60, 140,
45, 140, 140, 140, 140, 55, 140, 140, 140, 140,
140, 140, 15, 140, 35, 140, 45, 5, 140, 50,
140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
140, 140, 40, 140, 140, 50, 140, 140, 140, 140,
140, 25, 140, 140, 15, 40, 140, 140, 10, 140,
140, 140, 140, 140, 140, 10, 0, 140, 140, 15,
30, 140, 140, 140, 140, 140, 55, 140, 140, 140,
140, 140, 140, 140, 0, 140
};
static const signed char hash_to_MPH[] = {
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
MPH_NULL,
-1,
-1,
......@@ -97,7 +121,7 @@ int IID_to_MPH(const SLInterfaceID iid)
-1,
MPH_BUFFERQUEUE,
MPH_3DMACROSCOPIC,
MPH_BASSBOOST,
MPH_XAVOLUME,
-1,
-1,
MPH_3DLOCATION,
......@@ -107,12 +131,12 @@ int IID_to_MPH(const SLInterfaceID iid)
-1,
MPH_MIDIMESSAGE,
MPH_ANDROIDBUFFERQUEUE,
MPH_MIDIMUTESOLO,
MPH_BASSBOOST,
-1,
-1,
MPH_SEEK,
MPH_OBJECT,
-1,
MPH_MIDIMUTESOLO,
-1,
-1,
MPH_PITCH,
......@@ -180,8 +204,9 @@ int IID_to_MPH(const SLInterfaceID iid)
if (&SL_IID_array[0] <= iid && &SL_IID_array[MPH_MAX] > iid)
return iid - &SL_IID_array[0];
if (NULL != iid) {
unsigned key = asso_values[((unsigned char *)iid)[3]] +
asso_values[((unsigned char *)iid)[0]];
static const unsigned len = sizeof(struct SLInterfaceID_);
unsigned key = len +
asso_values[((unsigned char *)iid)[3]] + asso_values[((unsigned char *)iid)[0]];
if (key <= MAX_HASH_VALUE) {
int MPH = hash_to_MPH[key];
if (MPH >= 0) {
......
// This file is automagically generated by mphtogen, do not edit
-1, 3, -1, 2, 5, 4, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
// This file is automagically generated by mphtogen, do not edit
-1, 3, 4, 5, 16, 6, -1, -1, -1, -1, 17, 7, -1, 1, 18, 8, -1, -1, 19, 20,
-1, 10, 11, -1, -1, -1, -1, 9, -1, 0, -1, 21, 2, 23, 12, 22, 13, -1, 14, -1,
-1, 24, 25, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-1, 24, 25, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
// This file is automagically generated by mphtogen, do not edit
-1, -1, -1, -1, -1, -1, -1, 3, -1, -1, 4, -1, -1, 1, 5, -1, -1, -1, -1, 6,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1,
-1, -1, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-1, -1, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment