MediaPlayer_to_android.cpp revision d158d31a6bbb06426b71c3d097b7768bc3fb79a3
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#include "sles_allinclusive.h" 18#include "android/AndroidBufferQueueSource.h" 19#include "utils/RefBase.h" 20#include "android_prompts.h" 21 22//----------------------------------------------------------------------------- 23static void player_handleMediaPlayerEventNotifications(const int event, const int data1, void* user) 24{ 25 if (NULL == user) { 26 return; 27 } 28 29 CMediaPlayer* mp = (CMediaPlayer*) user; 30 //SL_LOGV("received event %d, data %d from AVPlayer", event, data1); 31 32 switch(event) { 33 34 case android::GenericPlayer::kEventPrepared: { 35 if (PLAYER_SUCCESS == data1) { 36 object_lock_exclusive(&mp->mObject); 37 SL_LOGV("Received AVPlayer::kEventPrepared from AVPlayer for CMediaPlayer %p", mp); 38 mp->mAndroidObjState = ANDROID_READY; 39 object_unlock_exclusive(&mp->mObject); 40 } 41 } 42 break; 43 44 default: 45 SL_LOGE("Received unknown event %d, data %d from AVPlayer", event, data1); 46 break; 47 } 48} 49 50 51//----------------------------------------------------------------------------- 52XAresult android_Player_checkSourceSink(CMediaPlayer *mp) { 53 54 XAresult result = XA_RESULT_SUCCESS; 55 56 const SLDataSource *pSrc = &mp->mDataSource.u.mSource; 57 const SLDataSink *pAudioSnk = &mp->mAudioSink.u.mSink; 58 59 // format check: 60 const SLuint32 sourceLocatorType = *(SLuint32 *)pSrc->pLocator; 61 const SLuint32 sourceFormatType = *(SLuint32 *)pSrc->pFormat; 62 const SLuint32 audioSinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 63 //const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat; 64 65 // Source check 66 switch(sourceLocatorType) { 67 68 case XA_DATALOCATOR_ANDROIDBUFFERQUEUE: { 69 switch (sourceFormatType) { 70 case XA_DATAFORMAT_MIME: { 71 SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pSrc->pFormat; 72 if (SL_CONTAINERTYPE_MPEG_TS != df_mime->containerType) { 73 SL_LOGE("Cannot create player with XA_DATALOCATOR_ANDROIDBUFFERQUEUE data source " 74 "that is not fed MPEG-2 TS data"); 75 return SL_RESULT_CONTENT_UNSUPPORTED; 76 } 77 } break; 78 default: 79 SL_LOGE("Cannot create player with XA_DATALOCATOR_ANDROIDBUFFERQUEUE data source " 80 "without SL_DATAFORMAT_MIME format"); 81 return XA_RESULT_CONTENT_UNSUPPORTED; 82 } 83 } break; 84 85 case XA_DATALOCATOR_URI: // intended fall-through 86 case XA_DATALOCATOR_ANDROIDFD: 87 break; 88 89 default: 90 SL_LOGE("Cannot create media player with data locator type 0x%x", 91 (unsigned) sourceLocatorType); 92 return SL_RESULT_PARAMETER_INVALID; 93 }// switch (locatorType) 94 95 // Audio sink check: only playback is supported here 96 switch(audioSinkLocatorType) { 97 98 case XA_DATALOCATOR_OUTPUTMIX: 99 break; 100 101 default: 102 SL_LOGE("Cannot create media player with audio sink data locator of type 0x%x", 103 (unsigned) audioSinkLocatorType); 104 return XA_RESULT_PARAMETER_INVALID; 105 }// switch (locaaudioSinkLocatorTypeorType) 106 107 return result; 108} 109 110 111//----------------------------------------------------------------------------- 112XAresult android_Player_create(CMediaPlayer *mp) { 113 114 XAresult result = XA_RESULT_SUCCESS; 115 116 // FIXME verify data source 117 const SLDataSource *pDataSrc = &mp->mDataSource.u.mSource; 118 // FIXME verify audio data sink 119 const SLDataSink *pAudioSnk = &mp->mAudioSink.u.mSink; 120 // FIXME verify image data sink 121 const SLDataSink *pVideoSnk = &mp->mImageVideoSink.u.mSink; 122 123 XAuint32 sourceLocator = *(XAuint32 *)pDataSrc->pLocator; 124 switch(sourceLocator) { 125 // FIXME support Android simple buffer queue as well 126 case XA_DATALOCATOR_ANDROIDBUFFERQUEUE: 127 mp->mAndroidObjType = AV_PLR_TS_ABQ; 128 break; 129 case XA_DATALOCATOR_URI: // intended fall-through 130 case SL_DATALOCATOR_ANDROIDFD: 131 mp->mAndroidObjType = AV_PLR_URIFD; 132 break; 133 case XA_DATALOCATOR_ADDRESS: // intended fall-through 134 default: 135 SL_LOGE("Unable to create MediaPlayer for data source locator 0x%lx", sourceLocator); 136 result = XA_RESULT_PARAMETER_INVALID; 137 break; 138 } 139 140 mp->mAndroidObjState = ANDROID_UNINITIALIZED; 141 mp->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE; 142 mp->mSessionId = android::AudioSystem::newAudioSessionId(); 143 144 mp->mAndroidAudioLevels.mAmplFromVolLevel = 1.0f; 145 mp->mAndroidAudioLevels.mAmplFromStereoPos[0] = 1.0f; 146 mp->mAndroidAudioLevels.mAmplFromStereoPos[1] = 1.0f; 147 mp->mAndroidAudioLevels.mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value 148 mp->mAndroidAudioLevels.mAuxSendLevel = 0; 149 mp->mDirectLevel = 0; // no attenuation 150 151 return result; 152} 153 154 155//----------------------------------------------------------------------------- 156// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 157XAresult android_Player_realize(CMediaPlayer *mp, SLboolean async) { 158 SL_LOGI("android_Player_realize_l(%p)", mp); 159 XAresult result = XA_RESULT_SUCCESS; 160 161 const SLDataSource *pDataSrc = &mp->mDataSource.u.mSource; 162 const SLuint32 sourceLocator = *(SLuint32 *)pDataSrc->pLocator; 163 164 AudioPlayback_Parameters ap_params; 165 ap_params.sessionId = mp->mSessionId; 166 ap_params.streamType = mp->mStreamType; 167 ap_params.trackcb = NULL; 168 ap_params.trackcbUser = NULL; 169 170 switch(mp->mAndroidObjType) { 171 case AV_PLR_TS_ABQ: { 172 mp->mAVPlayer = new android::StreamPlayer(&ap_params, true /*hasVideo*/); 173 mp->mAVPlayer->init(player_handleMediaPlayerEventNotifications, (void*)mp); 174 } 175 break; 176 case AV_PLR_URIFD: { 177 mp->mAVPlayer = new android::LocAVPlayer(&ap_params, true /*hasVideo*/); 178 mp->mAVPlayer->init(player_handleMediaPlayerEventNotifications, (void*)mp); 179 switch (mp->mDataSource.mLocator.mLocatorType) { 180 case XA_DATALOCATOR_URI: 181 ((android::LocAVPlayer*)mp->mAVPlayer.get())->setDataSource( 182 (const char*)mp->mDataSource.mLocator.mURI.URI); 183 break; 184 case XA_DATALOCATOR_ANDROIDFD: { 185 int64_t offset = (int64_t)mp->mDataSource.mLocator.mFD.offset; 186 ((android::LocAVPlayer*)mp->mAVPlayer.get())->setDataSource( 187 (int)mp->mDataSource.mLocator.mFD.fd, 188 offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ? 189 (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset, 190 (int64_t)mp->mDataSource.mLocator.mFD.length); 191 } 192 break; 193 default: 194 SL_LOGE("Invalid or unsupported data locator type %lu for data source", 195 mp->mDataSource.mLocator.mLocatorType); 196 result = XA_RESULT_PARAMETER_INVALID; 197 } 198 } 199 break; 200 case INVALID_TYPE: // intended fall-through 201 default: 202 SL_LOGE("Unable to realize MediaPlayer, invalid internal Android object type"); 203 result = XA_RESULT_PARAMETER_INVALID; 204 break; 205 } 206 207 return result; 208} 209 210//----------------------------------------------------------------------------- 211XAresult android_Player_destroy(CMediaPlayer *mp) { 212 SL_LOGI("android_Player_destroy(%p)", mp); 213 XAresult result = XA_RESULT_SUCCESS; 214 215 if (mp->mAVPlayer != 0) { 216 mp->mAVPlayer.clear(); 217 } 218 219 return result; 220} 221 222//----------------------------------------------------------------------------- 223/** 224 * pre-conditions: avp != NULL, surface != NULL 225 */ 226XAresult android_Player_setVideoSurface(android::GenericMediaPlayer *avp, void* surface) { 227 XAresult result = XA_RESULT_SUCCESS; 228 229 avp->setVideoSurface(surface); 230 231 return result; 232} 233 234 235//----------------------------------------------------------------------------- 236/** 237 * pre-condition: avp != NULL 238 */ 239XAresult android_Player_setPlayState(android::GenericPlayer *avp, SLuint32 playState, 240 AndroidObject_state* pObjState) 241{ 242 XAresult result = XA_RESULT_SUCCESS; 243 AndroidObject_state objState = *pObjState; 244 245 switch (playState) { 246 case SL_PLAYSTATE_STOPPED: { 247 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_STOPPED"); 248 avp->stop(); 249 } 250 break; 251 case SL_PLAYSTATE_PAUSED: { 252 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PAUSED"); 253 switch(objState) { 254 case(ANDROID_UNINITIALIZED): 255 *pObjState = ANDROID_PREPARING; 256 avp->prepare(); 257 break; 258 case(ANDROID_PREPARING): 259 break; 260 case(ANDROID_READY): 261 avp->pause(); 262 break; 263 default: 264 SL_LOGE("Android object in invalid state"); 265 break; 266 } 267 } 268 break; 269 case SL_PLAYSTATE_PLAYING: { 270 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PLAYING"); 271 switch(objState) { 272 case(ANDROID_UNINITIALIZED): 273 *pObjState = ANDROID_PREPARING; 274 avp->prepare(); 275 // intended fall through 276 case(ANDROID_PREPARING): 277 // intended fall through 278 case(ANDROID_READY): 279 avp->play(); 280 break; 281 default: 282 SL_LOGE("Android object in invalid state"); 283 break; 284 } 285 } 286 break; 287 default: 288 // checked by caller, should not happen 289 break; 290 } 291 292 return result; 293} 294 295 296//----------------------------------------------------------------------------- 297 298 299// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 300void android_Player_androidBufferQueue_registerCallback_l(CMediaPlayer *mp) { 301 if (mp->mAVPlayer != 0) { 302 SL_LOGI("android_Player_androidBufferQueue_registerCallback_l"); 303 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get()); 304 splr->registerQueueCallback( 305 mp->mAndroidBufferQueue.mCallback, 306 abqSrc_callBack_pullFromBuffQueue, 307 (const void*)mp, false /*userIsAudioPlayer*/, 308 mp->mAndroidBufferQueue.mContext, (const void*)&(mp->mAndroidBufferQueue.mItf)); 309 310 } 311} 312 313// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 314void android_Player_androidBufferQueue_enqueue_l(CMediaPlayer *mp, 315 SLuint32 bufferId, SLuint32 length, SLuint32 event, void *pData) { 316 if (mp->mAVPlayer != 0) { 317 android::StreamPlayer* splr = (android::StreamPlayer*)(mp->mAVPlayer.get()); 318 splr->appEnqueue(bufferId, length, event, pData); 319 } 320} 321 322 323 324