/*
|
* 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.
|
*/
|
|
/* Seek implementation */
|
|
#include "sles_allinclusive.h"
|
|
|
static SLresult ISeek_SetPosition(SLSeekItf self, SLmillisecond pos, SLuint32 seekMode)
|
{
|
SL_ENTER_INTERFACE
|
|
switch (seekMode) {
|
case SL_SEEKMODE_FAST:
|
case SL_SEEKMODE_ACCURATE:
|
{
|
// maximum position is a special value that indicates a seek is not pending
|
if (SL_TIME_UNKNOWN == pos) {
|
pos = SL_TIME_UNKNOWN - 1;
|
}
|
ISeek *thiz = (ISeek *) self;
|
interface_lock_exclusive(thiz);
|
thiz->mPos = pos;
|
// at this point the seek is merely pending, so do not yet update other fields
|
interface_unlock_exclusive_attributes(thiz, ATTR_POSITION);
|
result = SL_RESULT_SUCCESS;
|
}
|
break;
|
default:
|
result = SL_RESULT_PARAMETER_INVALID;
|
break;
|
}
|
|
SL_LEAVE_INTERFACE
|
}
|
|
|
static SLresult ISeek_SetLoop(SLSeekItf self, SLboolean loopEnable,
|
SLmillisecond startPos, SLmillisecond endPos)
|
{
|
SL_ENTER_INTERFACE
|
|
if (!(startPos < endPos)) {
|
result = SL_RESULT_PARAMETER_INVALID;
|
} else {
|
ISeek *thiz = (ISeek *) self;
|
interface_lock_exclusive(thiz);
|
#ifdef ANDROID
|
if ((startPos != 0) && (endPos != SL_TIME_UNKNOWN)) {
|
result = SL_RESULT_FEATURE_UNSUPPORTED;
|
} else {
|
switch (IObjectToObjectID((thiz)->mThis)) {
|
case SL_OBJECTID_AUDIOPLAYER: {
|
CAudioPlayer *ap = InterfaceToCAudioPlayer(thiz);
|
if (NULL != ap) {
|
result = android_audioPlayer_loop(ap, loopEnable);
|
} else {
|
result = SL_RESULT_PARAMETER_INVALID;
|
}
|
break;
|
}
|
case XA_OBJECTID_MEDIAPLAYER: {
|
CMediaPlayer *mp = InterfaceToCMediaPlayer(thiz);
|
if (NULL != mp) {
|
result = android_Player_loop(mp, loopEnable);
|
} else {
|
result = SL_RESULT_PARAMETER_INVALID;
|
}
|
break;
|
}
|
default: {
|
result = SL_RESULT_PARAMETER_INVALID;
|
}
|
}
|
if (SL_RESULT_SUCCESS == result) {
|
thiz->mLoopEnabled = SL_BOOLEAN_FALSE != loopEnable; // normalize
|
// start and end positions already initialized to [0, end of stream]
|
/*thiz->mStartPos = 0;
|
thiz->mEndPos = (SLmillisecond) SL_TIME_UNKNOWN;*/
|
}
|
}
|
#else
|
thiz->mLoopEnabled = SL_BOOLEAN_FALSE != loopEnable; // normalize
|
thiz->mStartPos = startPos;
|
thiz->mEndPos = endPos;
|
result = SL_RESULT_SUCCESS;
|
#endif
|
interface_unlock_exclusive(thiz);
|
}
|
|
SL_LEAVE_INTERFACE
|
}
|
|
|
static SLresult ISeek_GetLoop(SLSeekItf self, SLboolean *pLoopEnabled,
|
SLmillisecond *pStartPos, SLmillisecond *pEndPos)
|
{
|
SL_ENTER_INTERFACE
|
|
if (NULL == pLoopEnabled || NULL == pStartPos || NULL == pEndPos) {
|
result = SL_RESULT_PARAMETER_INVALID;
|
} else {
|
ISeek *thiz = (ISeek *) self;
|
interface_lock_shared(thiz);
|
SLboolean loopEnabled = thiz->mLoopEnabled;
|
SLmillisecond startPos = thiz->mStartPos;
|
SLmillisecond endPos = thiz->mEndPos;
|
interface_unlock_shared(thiz);
|
*pLoopEnabled = loopEnabled;
|
*pStartPos = startPos;
|
*pEndPos = endPos;
|
result = SL_RESULT_SUCCESS;
|
}
|
|
SL_LEAVE_INTERFACE
|
}
|
|
|
static const struct SLSeekItf_ ISeek_Itf = {
|
ISeek_SetPosition,
|
ISeek_SetLoop,
|
ISeek_GetLoop
|
};
|
|
void ISeek_init(void *self)
|
{
|
ISeek *thiz = (ISeek *) self;
|
thiz->mItf = &ISeek_Itf;
|
thiz->mPos = (SLmillisecond) SL_TIME_UNKNOWN;
|
thiz->mStartPos = (SLmillisecond) 0;
|
thiz->mEndPos = (SLmillisecond) SL_TIME_UNKNOWN;
|
thiz->mLoopEnabled = SL_BOOLEAN_FALSE;
|
}
|