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 
ISeek_SetPosition(SLSeekItf self,SLmillisecond pos,SLuint32 seekMode)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 
ISeek_SetLoop(SLSeekItf self,SLboolean loopEnable,SLmillisecond startPos,SLmillisecond endPos)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 
ISeek_GetLoop(SLSeekItf self,SLboolean * pLoopEnabled,SLmillisecond * pStartPos,SLmillisecond * pEndPos)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 
ISeek_init(void * self)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