Home | History | Annotate | Download | only in itf
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /* Seek implementation */
     18 
     19 #include "sles_allinclusive.h"
     20 
     21 
     22 static SLresult ISeek_SetPosition(SLSeekItf self, SLmillisecond pos, SLuint32 seekMode)
     23 {
     24     SL_ENTER_INTERFACE
     25 
     26     switch (seekMode) {
     27     case SL_SEEKMODE_FAST:
     28     case SL_SEEKMODE_ACCURATE:
     29         {
     30         // maximum position is a special value that indicates a seek is not pending
     31         if (SL_TIME_UNKNOWN == pos) {
     32             pos = SL_TIME_UNKNOWN - 1;
     33         }
     34         ISeek *thiz = (ISeek *) self;
     35         interface_lock_exclusive(thiz);
     36         thiz->mPos = pos;
     37         // at this point the seek is merely pending, so do not yet update other fields
     38         interface_unlock_exclusive_attributes(thiz, ATTR_POSITION);
     39         result = SL_RESULT_SUCCESS;
     40         }
     41         break;
     42     default:
     43         result = SL_RESULT_PARAMETER_INVALID;
     44         break;
     45     }
     46 
     47     SL_LEAVE_INTERFACE
     48 }
     49 
     50 
     51 static SLresult ISeek_SetLoop(SLSeekItf self, SLboolean loopEnable,
     52     SLmillisecond startPos, SLmillisecond endPos)
     53 {
     54     SL_ENTER_INTERFACE
     55 
     56     if (!(startPos < endPos)) {
     57         result = SL_RESULT_PARAMETER_INVALID;
     58     } else {
     59         ISeek *thiz = (ISeek *) self;
     60         interface_lock_exclusive(thiz);
     61 #ifdef ANDROID
     62         if ((startPos != 0) && (endPos != SL_TIME_UNKNOWN)) {
     63             result = SL_RESULT_FEATURE_UNSUPPORTED;
     64         } else {
     65             switch (IObjectToObjectID((thiz)->mThis)) {
     66               case SL_OBJECTID_AUDIOPLAYER: {
     67                 CAudioPlayer *ap = InterfaceToCAudioPlayer(thiz);
     68                 if (NULL != ap) {
     69                     result = android_audioPlayer_loop(ap, loopEnable);
     70                 } else {
     71                     result = SL_RESULT_PARAMETER_INVALID;
     72                 }
     73                 break;
     74               }
     75               case XA_OBJECTID_MEDIAPLAYER: {
     76                 CMediaPlayer *mp = InterfaceToCMediaPlayer(thiz);
     77                 if (NULL != mp) {
     78                     result = android_Player_loop(mp, loopEnable);
     79                 } else {
     80                     result = SL_RESULT_PARAMETER_INVALID;
     81                 }
     82                 break;
     83               }
     84               default: {
     85                 result = SL_RESULT_PARAMETER_INVALID;
     86               }
     87             }
     88             if (SL_RESULT_SUCCESS == result) {
     89                 thiz->mLoopEnabled = SL_BOOLEAN_FALSE != loopEnable; // normalize
     90                 // start and end positions already initialized to [0, end of stream]
     91                 /*thiz->mStartPos = 0;
     92                   thiz->mEndPos = (SLmillisecond) SL_TIME_UNKNOWN;*/
     93             }
     94         }
     95 #else
     96         thiz->mLoopEnabled = SL_BOOLEAN_FALSE != loopEnable; // normalize
     97         thiz->mStartPos = startPos;
     98         thiz->mEndPos = endPos;
     99         result = SL_RESULT_SUCCESS;
    100 #endif
    101         interface_unlock_exclusive(thiz);
    102     }
    103 
    104     SL_LEAVE_INTERFACE
    105 }
    106 
    107 
    108 static SLresult ISeek_GetLoop(SLSeekItf self, SLboolean *pLoopEnabled,
    109     SLmillisecond *pStartPos, SLmillisecond *pEndPos)
    110 {
    111     SL_ENTER_INTERFACE
    112 
    113     if (NULL == pLoopEnabled || NULL == pStartPos || NULL == pEndPos) {
    114         result = SL_RESULT_PARAMETER_INVALID;
    115     } else {
    116         ISeek *thiz = (ISeek *) self;
    117         interface_lock_shared(thiz);
    118         SLboolean loopEnabled = thiz->mLoopEnabled;
    119         SLmillisecond startPos = thiz->mStartPos;
    120         SLmillisecond endPos = thiz->mEndPos;
    121         interface_unlock_shared(thiz);
    122         *pLoopEnabled = loopEnabled;
    123         *pStartPos = startPos;
    124         *pEndPos = endPos;
    125         result = SL_RESULT_SUCCESS;
    126     }
    127 
    128     SL_LEAVE_INTERFACE
    129 }
    130 
    131 
    132 static const struct SLSeekItf_ ISeek_Itf = {
    133     ISeek_SetPosition,
    134     ISeek_SetLoop,
    135     ISeek_GetLoop
    136 };
    137 
    138 void ISeek_init(void *self)
    139 {
    140     ISeek *thiz = (ISeek *) self;
    141     thiz->mItf = &ISeek_Itf;
    142     thiz->mPos = (SLmillisecond) SL_TIME_UNKNOWN;
    143     thiz->mStartPos = (SLmillisecond) 0;
    144     thiz->mEndPos = (SLmillisecond) SL_TIME_UNKNOWN;
    145     thiz->mLoopEnabled = SL_BOOLEAN_FALSE;
    146 }
    147