IPlay.c revision dc181a4a041fe4be7c91b92646b236b6d652f4a3
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/* Play implementation */
180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
19979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten#include "sles_allinclusive.h"
20979a3f8743646af9999a89dff9e13b972b7efd87Glenn Kasten
210b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetPlayState(SLPlayItf self, SLuint32 state)
220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
236a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    switch (state) {
250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_PLAYSTATE_STOPPED:
260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_PLAYSTATE_PAUSED:
270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    case SL_PLAYSTATE_PLAYING:
280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        break;
290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    default:
300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_exclusive(this);
340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mState = state;
350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (SL_PLAYSTATE_STOPPED == state) {
360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        this->mPosition = (SLmillisecond) 0;
370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        // this->mPositionSamples = 0;
380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    }
390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifdef USE_ANDROID
40b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) {
416a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = sles_to_android_audioPlayerSetPlayState(this, state);
426a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif
446a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    interface_unlock_exclusive(this);
456a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
480b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPlayState(SLPlayItf self, SLuint32 *pState)
490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pState)
510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLuint32 state = this->mState;
550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pState = state;
570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
600b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetDuration(SLPlayItf self, SLmillisecond *pMsec)
610b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
62dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
630b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // FIXME: for SNDFILE only, check to see if already know duration
640b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // if so, good, otherwise save position,
650b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // read quickly to end of file, counting frames,
660b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // use sample rate to compute duration, then seek back to current position
670b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMsec)
680b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
71dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi#ifdef USE_ANDROID
72dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) {
73dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi        result = sles_to_android_audioPlayerGetDuration(this, &this->mDuration);
74dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    }
75dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi#endif
760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond duration = this->mDuration;
770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMsec = duration;
79dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi    return result;
800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
820b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPosition(SLPlayItf self, SLmillisecond *pMsec)
830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMsec)
850b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
886a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
89b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) {
906a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        sles_to_android_audioPlayerGetPosition(this, &this->mPosition);
916a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
926a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond position = this->mPosition;
940b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
950b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMsec = position;
960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // FIXME handle SL_TIME_UNKNOWN
970b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1000b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_RegisterCallback(SLPlayItf self, slPlayCallback callback,
1010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    void *pContext)
1020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // FIXME This could be a poke lock, if we had atomic double-word load/store
1050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_exclusive(this);
1060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mCallback = callback;
1070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mContext = pContext;
1080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_exclusive(this);
1090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1120b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags)
1130b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1146a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
1150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mEventFlags = eventFlags;
1186a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
119b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) {
1206a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = sles_to_android_audioPlayerUseEventMask(this, eventFlags);
1216a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1226a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1246a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
1250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1270b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetCallbackEventsMask(SLPlayItf self,
1280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLuint32 *pEventFlags)
1290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pEventFlags)
1310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
1340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLuint32 eventFlags = this->mEventFlags;
1350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
1360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pEventFlags = eventFlags;
1370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1400b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec)
1410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1426a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
1430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mMarkerPosition = mSec;
1466a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
147b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) {
1486a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = sles_to_android_audioPlayerUseEventMask(this, this->mEventFlags);
1496a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1506a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1526a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
1530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1550b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_ClearMarkerPosition(SLPlayItf self)
1560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1580b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mMarkerPosition = 0;
1606a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
161b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) {
1626a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // clearing the marker position can be simulated by using the event mask with a
1636a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // cleared flag for the marker
1646a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        SLuint32 eventFlags = this->mEventFlags & (~SL_PLAYEVENT_HEADATMARKER);
1656a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        sles_to_android_audioPlayerUseEventMask(this, eventFlags);
1666a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        // FIXME verify this is still valid for a MediaPlayer
1676a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1686a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1690b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1700b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1710b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1720b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1730b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec)
1740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1750b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMsec)
1760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
1770b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
1790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond markerPosition = this->mMarkerPosition;
1800b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
1810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMsec = markerPosition;
1820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
1830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
1850b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec)
1860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
1876a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    SLresult result = SL_RESULT_SUCCESS;
1880b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
1890b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_poke(this);
1900b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mPositionUpdatePeriod = mSec;
1916a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#ifdef USE_ANDROID
192b7154f2324c8ae44b820c07c69aaa80a4bb9e418Glenn Kasten    if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) {
1936a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi        result = sles_to_android_audioPlayerUseEventMask(this, this->mEventFlags);
1946a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    }
1956a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif
1960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_poke(this);
1976a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi    return result;
1980b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
1990b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
2000b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPositionUpdatePeriod(SLPlayItf self,
2010b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond *pMsec)
2020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
2030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    if (NULL == pMsec)
2040b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        return SL_RESULT_PARAMETER_INVALID;
2050b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
2060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_lock_peek(this);
2070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    SLmillisecond positionUpdatePeriod = this->mPositionUpdatePeriod;
2080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    interface_unlock_peek(this);
2090b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    *pMsec = positionUpdatePeriod;
2100b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    return SL_RESULT_SUCCESS;
2110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
2120b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
2130b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLPlayItf_ IPlay_Itf = {
2140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_SetPlayState,
2150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetPlayState,
2160b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetDuration,
2170b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetPosition,
2180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_RegisterCallback,
2190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_SetCallbackEventsMask,
2200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetCallbackEventsMask,
2210b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_SetMarkerPosition,
2220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_ClearMarkerPosition,
2230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetMarkerPosition,
2240b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_SetPositionUpdatePeriod,
2250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay_GetPositionUpdatePeriod
2260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
2270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
2280b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid IPlay_init(void *self)
2290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{
2300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    IPlay *this = (IPlay *) self;
2310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mItf = &IPlay_Itf;
2320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mState = SL_PLAYSTATE_STOPPED;
2330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mDuration = SL_TIME_UNKNOWN;
2340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#ifndef NDEBUG
2350b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mPosition = (SLmillisecond) 0;
2360b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    // this->mPlay.mPositionSamples = 0;
2370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mCallback = NULL;
2380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mContext = NULL;
2390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mEventFlags = 0;
2400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mMarkerPosition = 0;
2410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    this->mPositionUpdatePeriod = 0;
2420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten#endif
2430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}
244