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