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 21ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 220b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetPlayState(SLPlayItf self, SLuint32 state) 230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 24ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 25ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten switch (state) { 270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_PLAYSTATE_STOPPED: 280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_PLAYSTATE_PAUSED: 290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten case SL_PLAYSTATE_PLAYING: 30ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten { 31bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 324b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten unsigned attr = ATTR_NONE; 33ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 3494a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#ifdef USE_OUTPUTMIXEXT 35bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CAudioPlayer *audioPlayer = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ? 36bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten (CAudioPlayer *) thiz->mThis : NULL; 3794a37e8117fb72790882dfb815f99e2365754c74Glenn Kasten#endif 38bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 39f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten SLuint32 oldState = thiz->mState; 40f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten if (state != oldState) { 414b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef USE_OUTPUTMIXEXT 42f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten for (;; interface_cond_wait(thiz)) { 434b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 444b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // We are comparing the old state (left) vs. new state (right). 454b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // Note that the old state is 3 bits wide, but new state is only 2 bits wide. 464b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // That is why the old state is on the left and new state is on the right. 47f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten switch ((oldState << 2) | state) { 484b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 494b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPED << 2) | SL_PLAYSTATE_STOPPED: 504b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PAUSED << 2) | SL_PLAYSTATE_PAUSED: 514b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PLAYING << 2) | SL_PLAYSTATE_PLAYING: 52f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten // no-op, and unreachable due to earlier "if (state != oldState)" 534b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 544b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 554b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPED << 2) | SL_PLAYSTATE_PLAYING: 564b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PAUSED << 2) | SL_PLAYSTATE_PLAYING: 57f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten attr = ATTR_PLAY_STATE; 584b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // set enqueue attribute if queue is non-empty and state becomes PLAYING 594b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten if ((NULL != audioPlayer) && (audioPlayer->mBufferQueue.mFront != 604b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten audioPlayer->mBufferQueue.mRear)) { 61f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten // note that USE_OUTPUTMIXEXT does not support ATTR_ABQ_ENQUEUE 62d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi attr |= ATTR_BQ_ENQUEUE; 634b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 644b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // fall through 654b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 664b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPED << 2) | SL_PLAYSTATE_PAUSED: 674b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PLAYING << 2) | SL_PLAYSTATE_PAUSED: 684b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // easy 69bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mState = state; 704b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 714b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 724b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_STOPPED: 734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // either spurious wakeup, or someone else requested same transition 744b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten continue; 754b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 764b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_PAUSED: 774b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_STOPPING << 2) | SL_PLAYSTATE_PLAYING: 784b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // wait for other guy to finish his transition, then retry ours 794b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten continue; 804b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 814b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PAUSED << 2) | SL_PLAYSTATE_STOPPED: 824b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case (SL_PLAYSTATE_PLAYING << 2) | SL_PLAYSTATE_STOPPED: 834b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // tell mixer to stop, then wait for mixer to acknowledge the request to stop 84bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mState = SL_PLAYSTATE_STOPPING; 854b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten continue; 864b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 874b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten default: 884b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten // unexpected state 894b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten assert(SL_BOOLEAN_FALSE); 904b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten result = SL_RESULT_INTERNAL_ERROR; 914b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 924b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 934b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 944b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 954b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 96f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten } 974b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#else 98f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten // Here life looks easy for an Android, but there are other troubles in play land 99f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten thiz->mState = state; 100f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten attr = ATTR_PLAY_STATE; 101f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten // no need to set ATTR_BQ_ENQUEUE or ATTR_ABQ_ENQUEUE 1024b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif 103f4647bf85968ab30eb07f9a80b99177d91068f94Glenn Kasten } 104a8179ea15c4ff78db589d742b135649f0eda7ef2Glenn Kasten // SL_LOGD("set play state %d", state); 105bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive_attributes(thiz, attr); 106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 1070b167267bda99b68346045ccab14e810121d5de4Glenn Kasten break; 1080b167267bda99b68346045ccab14e810121d5de4Glenn Kasten default: 109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 1104b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 1110b167267bda99b68346045ccab14e810121d5de4Glenn Kasten } 112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 1140b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 1150b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1170b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPlayState(SLPlayItf self, SLuint32 *pState) 1180b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 121ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pState) { 122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 124bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 1255933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_lock_shared(thiz); 126bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLuint32 state = thiz->mState; 1275933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_unlock_shared(thiz); 128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 1294b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#ifdef USE_OUTPUTMIXEXT 1304b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten switch (state) { 1314b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case SL_PLAYSTATE_STOPPED: // as is 1324b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case SL_PLAYSTATE_PAUSED: 1334b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case SL_PLAYSTATE_PLAYING: 1344b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 1354b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten case SL_PLAYSTATE_STOPPING: // these states require re-mapping 1364b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten state = SL_PLAYSTATE_STOPPED; 1374b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 1384b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten default: // impossible 1394b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten assert(SL_BOOLEAN_FALSE); 1404b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten state = SL_PLAYSTATE_STOPPED; 1414b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten result = SL_RESULT_INTERNAL_ERROR; 1424b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten break; 1434b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten } 1444b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif 1454b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten *pState = state; 146ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 147ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 148ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 1490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 1500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 151ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1520b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetDuration(SLPlayItf self, SLmillisecond *pMsec) 1530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 154ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 155ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 156ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMsec) { 157ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 158ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 159ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 160bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 161ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // even though this is a getter, it can modify state due to caching 162bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 163bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLmillisecond duration = thiz->mDuration; 164ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 1653d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten if (SL_TIME_UNKNOWN == duration) { 166ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLmillisecond temp; 1673d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten switch (InterfaceToObjectID(thiz)) { 1683d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten case SL_OBJECTID_AUDIOPLAYER: 1693d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten result = android_audioPlayer_getDuration(thiz, &temp); 1703d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten break; 1713d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten case XA_OBJECTID_MEDIAPLAYER: 1723d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten result = android_Player_getDuration(thiz, &temp); 1733d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten break; 1743d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten default: 1753d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten result = SL_RESULT_FEATURE_UNSUPPORTED; 1763d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten break; 1773d332ff421e7179c36fb652771cc8ded53383729Glenn Kasten } 178ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (SL_RESULT_SUCCESS == result) { 179ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten duration = temp; 180bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDuration = duration; 181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 182e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 183e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else 1848c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // will be set by containing AudioPlayer or MidiPlayer object at Realize, if known, 1858c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // otherwise the duration will be updated each time a new maximum position is detected 186dc181a4a041fe4be7c91b92646b236b6d652f4a3Jean-Michel Trivi#endif 187bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 188ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMsec = duration; 189ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 190ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 191ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 1920b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 1930b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 194ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 1950b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetPosition(SLPlayItf self, SLmillisecond *pMsec) 1960b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 197ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 198ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 199ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMsec) { 200ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 201ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 202bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 203ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SLmillisecond position; 204bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_shared(thiz); 205ef8931ae547cd703e69df9ad350d69825da0f546Jean-Michel Trivi#ifdef ANDROID 20635a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi // Android does not use the mPosition field for audio and media players 20735a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi // and doesn't cache the position 20835a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi switch (IObjectToObjectID((thiz)->mThis)) { 20935a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi case SL_OBJECTID_AUDIOPLAYER: 210bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten android_audioPlayer_getPosition(thiz, &position); 21135a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi break; 21235a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi case XA_OBJECTID_MEDIAPLAYER: 21335a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi android_Player_getPosition(thiz, &position); 21435a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi break; 21535a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi default: 21635a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi // we shouldn'be here 21735a5a30fdad179ccf38d8d756590411326159a89Jean-Michel Trivi assert(SL_BOOLEAN_FALSE); 2188c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 219e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten#else 220ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten // on other platforms we depend on periodic updates to the current position 221bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten position = thiz->mPosition; 2228c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // if a seek is pending, then lie about current position so the seek appears synchronous 223bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) { 224bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CAudioPlayer *audioPlayer = (CAudioPlayer *) thiz->mThis; 2258c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten SLmillisecond pos = audioPlayer->mSeek.mPos; 2268c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (SL_TIME_UNKNOWN != pos) { 2278c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten position = pos; 2288c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 2298c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 2306a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi#endif 231bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_shared(thiz); 232ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMsec = position; 233ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 234ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 235ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 236ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 2370b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 2380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 239ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 240d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IPlay_RegisterCallback(SLPlayItf self, slPlayCallback callback, void *pContext) 2410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 242ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 243ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 244bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 245bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 246bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mCallback = callback; 247bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mContext = pContext; 248e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten // omits _attributes b/c noone cares deeply enough about these fields to need quick notification 249bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 250ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 251ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 252ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 2530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 2540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 255ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 2560b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetCallbackEventsMask(SLPlayItf self, SLuint32 eventFlags) 2570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 258ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 259ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 2608c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten if (eventFlags & ~(SL_PLAYEVENT_HEADATEND | SL_PLAYEVENT_HEADATMARKER | 2618c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten SL_PLAYEVENT_HEADATNEWPOS | SL_PLAYEVENT_HEADMOVING | SL_PLAYEVENT_HEADSTALLED)) { 2628c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 2638c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } else { 264bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 265bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 266bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->mEventFlags != eventFlags) { 2678c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#ifdef USE_OUTPUTMIXEXT 2688c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // enabling the "head at new position" play event will postpone the next update event 269bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (!(thiz->mEventFlags & SL_PLAYEVENT_HEADATNEWPOS) && 2708c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten (eventFlags & SL_PLAYEVENT_HEADATNEWPOS)) { 271bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFramesSincePositionUpdate = 0; 2728c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 2738c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#endif 274bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mEventFlags = eventFlags; 275bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT); 27645b349f3c585a0750417722f72224a35baaab734Glenn Kasten } else { 277bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 27845b349f3c585a0750417722f72224a35baaab734Glenn Kasten } 2798c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten result = SL_RESULT_SUCCESS; 2808c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 281ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 282ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 2830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 2840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 285ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 286d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IPlay_GetCallbackEventsMask(SLPlayItf self, SLuint32 *pEventFlags) 2870b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 288ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 289ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 290ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pEventFlags) { 291ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 292ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 293bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 2945933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_lock_shared(thiz); 295bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLuint32 eventFlags = thiz->mEventFlags; 2965933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_unlock_shared(thiz); 297ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pEventFlags = eventFlags; 298ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 299ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 300ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 301ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3020b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3030b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 304ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3050b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetMarkerPosition(SLPlayItf self, SLmillisecond mSec) 3060b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 307ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 308ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 30945b349f3c585a0750417722f72224a35baaab734Glenn Kasten if (SL_TIME_UNKNOWN == mSec) { 31045b349f3c585a0750417722f72224a35baaab734Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 31145b349f3c585a0750417722f72224a35baaab734Glenn Kasten } else { 31245b349f3c585a0750417722f72224a35baaab734Glenn Kasten IPlay *thiz = (IPlay *) self; 31345b349f3c585a0750417722f72224a35baaab734Glenn Kasten bool significant = false; 31445b349f3c585a0750417722f72224a35baaab734Glenn Kasten interface_lock_exclusive(thiz); 31545b349f3c585a0750417722f72224a35baaab734Glenn Kasten if (thiz->mMarkerPosition != mSec) { 31645b349f3c585a0750417722f72224a35baaab734Glenn Kasten thiz->mMarkerPosition = mSec; 31745b349f3c585a0750417722f72224a35baaab734Glenn Kasten if (thiz->mEventFlags & SL_PLAYEVENT_HEADATMARKER) { 31845b349f3c585a0750417722f72224a35baaab734Glenn Kasten significant = true; 31945b349f3c585a0750417722f72224a35baaab734Glenn Kasten } 3205933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten } 32145b349f3c585a0750417722f72224a35baaab734Glenn Kasten if (significant) { 32245b349f3c585a0750417722f72224a35baaab734Glenn Kasten interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT); 32345b349f3c585a0750417722f72224a35baaab734Glenn Kasten } else { 32445b349f3c585a0750417722f72224a35baaab734Glenn Kasten interface_unlock_exclusive(thiz); 32545b349f3c585a0750417722f72224a35baaab734Glenn Kasten } 32645b349f3c585a0750417722f72224a35baaab734Glenn Kasten result = SL_RESULT_SUCCESS; 3275933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten } 328ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 329ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 332ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3330b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_ClearMarkerPosition(SLPlayItf self) 3340b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 335ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 336ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 337bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 3385933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten bool significant = false; 339bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 3405933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten // clearing the marker position is equivalent to setting the marker to SL_TIME_UNKNOWN 3415933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten if (thiz->mMarkerPosition != SL_TIME_UNKNOWN) { 3425933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten thiz->mMarkerPosition = SL_TIME_UNKNOWN; 3435933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten if (thiz->mEventFlags & SL_PLAYEVENT_HEADATMARKER) { 3445933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten significant = true; 3455933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten } 3465933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten } 3475933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten if (significant) { 3485933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT); 3495933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten } else { 3505933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_unlock_exclusive(thiz); 3516a7bf7733e955d4d89204627c34fb357d542a9ecJean-Michel Trivi } 352ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 353ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 354ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3560b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 357ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3580b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_GetMarkerPosition(SLPlayItf self, SLmillisecond *pMsec) 3590b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 360ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 361ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 362ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMsec) { 363ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 364ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 365bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 3665933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_lock_shared(thiz); 367bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLmillisecond markerPosition = thiz->mMarkerPosition; 3685933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_unlock_shared(thiz); 369ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMsec = markerPosition; 37045b349f3c585a0750417722f72224a35baaab734Glenn Kasten if (SL_TIME_UNKNOWN == markerPosition) { 37145b349f3c585a0750417722f72224a35baaab734Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 37245b349f3c585a0750417722f72224a35baaab734Glenn Kasten } else { 37345b349f3c585a0750417722f72224a35baaab734Glenn Kasten result = SL_RESULT_SUCCESS; 37445b349f3c585a0750417722f72224a35baaab734Glenn Kasten } 375ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 376ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 377ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 3780b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 3790b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 380ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 3810b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic SLresult IPlay_SetPositionUpdatePeriod(SLPlayItf self, SLmillisecond mSec) 3820b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 383ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 384ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 385ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (0 == mSec) { 386ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 387ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 388bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 3895933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten bool significant = false; 390bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_lock_exclusive(thiz); 391bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (thiz->mPositionUpdatePeriod != mSec) { 392bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mPositionUpdatePeriod = mSec; 3938c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#ifdef USE_OUTPUTMIXEXT 394bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) { 395bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten CAudioPlayer *audioPlayer = (CAudioPlayer *) thiz->mThis; 3968c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten SLuint32 frameUpdatePeriod = ((long long) mSec * 3978c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten (long long) audioPlayer->mSampleRateMilliHz) / 1000000LL; 398ab7724988c1ff39ad3fc95a7ae0e638357708f7cGlenn Kasten if (0 == frameUpdatePeriod) { 3998c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten frameUpdatePeriod = ~0; 400ab7724988c1ff39ad3fc95a7ae0e638357708f7cGlenn Kasten } 401bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFrameUpdatePeriod = frameUpdatePeriod; 4028c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten // setting a new update period postpones the next callback 403bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFramesSincePositionUpdate = 0; 4048c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten } 4058c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#endif 4065933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten if (thiz->mEventFlags & SL_PLAYEVENT_HEADATNEWPOS) { 4075933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten significant = true; 4085933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten } 4095933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten } 4105933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten if (significant) { 411bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT); 41245b349f3c585a0750417722f72224a35baaab734Glenn Kasten } else { 413bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten interface_unlock_exclusive(thiz); 41445b349f3c585a0750417722f72224a35baaab734Glenn Kasten } 415ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 416ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 417ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 418ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 4190b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 4200b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 421ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 422d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IPlay_GetPositionUpdatePeriod(SLPlayItf self, SLmillisecond *pMsec) 4230b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 424ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_ENTER_INTERFACE 425ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 426ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten if (NULL == pMsec) { 427ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_PARAMETER_INVALID; 428ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } else { 429bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 4305933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_lock_shared(thiz); 431bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten SLmillisecond positionUpdatePeriod = thiz->mPositionUpdatePeriod; 4325933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten interface_unlock_shared(thiz); 433ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten *pMsec = positionUpdatePeriod; 434ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten result = SL_RESULT_SUCCESS; 435ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten } 436ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 437ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten SL_LEAVE_INTERFACE 4380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 4390b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 440ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten 4410b167267bda99b68346045ccab14e810121d5de4Glenn Kastenstatic const struct SLPlayItf_ IPlay_Itf = { 4420b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_SetPlayState, 4430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetPlayState, 4440b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetDuration, 4450b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetPosition, 4460b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_RegisterCallback, 4470b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_SetCallbackEventsMask, 4480b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetCallbackEventsMask, 4490b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_SetMarkerPosition, 4500b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_ClearMarkerPosition, 4510b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetMarkerPosition, 4520b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_SetPositionUpdatePeriod, 4530b167267bda99b68346045ccab14e810121d5de4Glenn Kasten IPlay_GetPositionUpdatePeriod 4540b167267bda99b68346045ccab14e810121d5de4Glenn Kasten}; 4550b167267bda99b68346045ccab14e810121d5de4Glenn Kasten 4560b167267bda99b68346045ccab14e810121d5de4Glenn Kastenvoid IPlay_init(void *self) 4570b167267bda99b68346045ccab14e810121d5de4Glenn Kasten{ 458bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IPlay *thiz = (IPlay *) self; 459bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mItf = &IPlay_Itf; 460bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mState = SL_PLAYSTATE_STOPPED; 461bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mDuration = SL_TIME_UNKNOWN; // will be set by containing player object 462bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mPosition = (SLmillisecond) 0; 463bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mCallback = NULL; 464bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mContext = NULL; 465bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mEventFlags = 0; 4665933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten thiz->mMarkerPosition = SL_TIME_UNKNOWN; 4675933f3d5e532aaac31ce0e6551c59f0197c0ae3cGlenn Kasten thiz->mPositionUpdatePeriod = 1000; // per spec 4688c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#ifdef USE_OUTPUTMIXEXT 469bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFrameUpdatePeriod = 0; // because we don't know the sample rate yet 470bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLastSeekPosition = 0; 471bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFramesSinceLastSeek = 0; 472bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFramesSincePositionUpdate = 0; 4738c065779232fdd89abace68d2fc7bea786a010d7Glenn Kasten#endif 4740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten} 475