10b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/*
20b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
30b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
40b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
50b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * you may not use this file except in compliance with the License.
60b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * You may obtain a copy of the License at
70b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
80b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
90b167267bda99b68346045ccab14e810121d5de4Glenn Kasten *
100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * Unless required by applicable law or agreed to in writing, software
110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * See the License for the specific language governing permissions and
140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten * limitations under the License.
150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten */
160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten/* Seek implementation */
180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#include "sles_allinclusive.h"
200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
22d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult ISeek_SetPosition(SLSeekItf self, SLmillisecond pos, SLuint32 seekMode)
230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
24ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
25ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    switch (seekMode) {
270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_SEEKMODE_FAST:
280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_SEEKMODE_ACCURATE:
29ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        {
30ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // maximum position is a special value that indicates a seek is not pending
318c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten        if (SL_TIME_UNKNOWN == pos) {
32ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            pos = SL_TIME_UNKNOWN - 1;
338c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten        }
34bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        ISeek *thiz = (ISeek *) self;
35bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        interface_lock_exclusive(thiz);
36bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mPos = pos;
37c319fbb542c4649fbda6048cb909e6574cf4e3d2Jean-Michel Trivi        // at this point the seek is merely pending, so do not yet update other fields
38bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        interface_unlock_exclusive_attributes(thiz, ATTR_POSITION);
39ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
40ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        break;
420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    default:
43ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
44ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        break;
450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
46ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
47ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
50ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
510b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult ISeek_SetLoop(SLSeekItf self, SLboolean loopEnable,
520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond startPos, SLmillisecond endPos)
530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
54ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
55ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
56ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!(startPos < endPos)) {
57ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
58ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
59bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        ISeek *thiz = (ISeek *) self;
60bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        interface_lock_exclusive(thiz);
61d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#ifdef ANDROID
62d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi        if ((startPos != 0) && (endPos != SL_TIME_UNKNOWN)) {
63d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi            result = SL_RESULT_FEATURE_UNSUPPORTED;
64d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi        } else {
6592b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi            switch (IObjectToObjectID((thiz)->mThis)) {
6692b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi              case SL_OBJECTID_AUDIOPLAYER: {
6792b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                CAudioPlayer *ap = InterfaceToCAudioPlayer(thiz);
6892b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                if (NULL != ap) {
69f5ff1a75f55677163bd9a8bd804e8f5c33ef592cGlenn Kasten                    result = android_audioPlayer_loop(ap, loopEnable);
7092b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                } else {
7192b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                    result = SL_RESULT_PARAMETER_INVALID;
7292b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                }
7392b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                break;
7492b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi              }
7592b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi              case XA_OBJECTID_MEDIAPLAYER: {
7692b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                CMediaPlayer *mp = InterfaceToCMediaPlayer(thiz);
7792b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                if (NULL != mp) {
7892b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                    result = android_Player_loop(mp, loopEnable);
7992b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                } else {
8092b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                    result = SL_RESULT_PARAMETER_INVALID;
8192b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                }
8292b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                break;
8392b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi              }
8492b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi              default: {
8592b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                result = SL_RESULT_PARAMETER_INVALID;
8692b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi              }
8792b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi            }
8892b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi            if (SL_RESULT_SUCCESS == result) {
8992b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                thiz->mLoopEnabled = SL_BOOLEAN_FALSE != loopEnable; // normalize
9092b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                // start and end positions already initialized to [0, end of stream]
9192b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                /*thiz->mStartPos = 0;
9292b245bf8828db9e469febebbe8774c00570b5b9Jean-Michel Trivi                  thiz->mEndPos = (SLmillisecond) SL_TIME_UNKNOWN;*/
93d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi            }
94d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi        }
95d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#else
96bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mLoopEnabled = SL_BOOLEAN_FALSE != loopEnable; // normalize
97bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mStartPos = startPos;
98bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        thiz->mEndPos = endPos;
99ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
100d94d32190f845b41f212c9c1918758e33fef6382Jean-Michel Trivi#endif
101bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        interface_unlock_exclusive(thiz);
102ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
1050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
107ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1080b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult ISeek_GetLoop(SLSeekItf self, SLboolean *pLoopEnabled,
1090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond *pStartPos, SLmillisecond *pEndPos)
1100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pLoopEnabled || NULL == pStartPos || NULL == pEndPos) {
114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
116bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        ISeek *thiz = (ISeek *) self;
117bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        interface_lock_shared(thiz);
118bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        SLboolean loopEnabled = thiz->mLoopEnabled;
119bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        SLmillisecond startPos = thiz->mStartPos;
120bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        SLmillisecond endPos = thiz->mEndPos;
121bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten        interface_unlock_shared(thiz);
122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pLoopEnabled = loopEnabled;
123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pStartPos = startPos;
124ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pEndPos = endPos;
125ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
126ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
127ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
1290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
131ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1320b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLSeekItf_ ISeek_Itf = {
1330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    ISeek_SetPosition,
1340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    ISeek_SetLoop,
1350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    ISeek_GetLoop
1360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
1370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1380b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid ISeek_init(void *self)
1390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
140bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    ISeek *thiz = (ISeek *) self;
141bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mItf = &ISeek_Itf;
142bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mPos = (SLmillisecond) SL_TIME_UNKNOWN;
143bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mStartPos = (SLmillisecond) 0;
144bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mEndPos = (SLmillisecond) SL_TIME_UNKNOWN;
145bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten    thiz->mLoopEnabled = SL_BOOLEAN_FALSE;
1460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
147