MediaPlayer_to_android.cpp revision 37dc2fccf3f122b79ebd554de209d0a3c94ae161
18cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com/* 28cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Copyright (C) 2010 The Android Open Source Project 38cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * 48cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Licensed under the Apache License, Version 2.0 (the "License"); 58cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * you may not use this file except in compliance with the License. 68cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * You may obtain a copy of the License at 78cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * 88cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * http://www.apache.org/licenses/LICENSE-2.0 98cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * 108cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * Unless required by applicable law or agreed to in writing, software 118cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * distributed under the License is distributed on an "AS IS" BASIS, 128cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * See the License for the specific language governing permissions and 148cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com * limitations under the License. 158cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com */ 168cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 178cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "sles_allinclusive.h" 188cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "utils/RefBase.h" 198cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com#include "android_prompts.h" 208cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 218cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 228cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com//----------------------------------------------------------------------------- 238cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.comstatic void player_handleMediaPlayerEventNotifications(int event, int data1, int data2, void* user) 248cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com{ 258cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com if (NULL == user) { 268cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com return; 278cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 288cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 298cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com CMediaPlayer* mp = (CMediaPlayer*) user; 308cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com //SL_LOGV("received event %d, data %d from AVPlayer", event, data1); 318cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 328cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com switch(event) { 338cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 348cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com case android::GenericPlayer::kEventPrepared: { 358cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com if (PLAYER_SUCCESS == data1) { 368cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com object_lock_exclusive(&mp->mObject); 378cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com SL_LOGV("Received AVPlayer::kEventPrepared from AVPlayer for CMediaPlayer %p", mp); 388cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com mp->mAndroidObjState = ANDROID_READY; 398cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com object_unlock_exclusive(&mp->mObject); 408cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 418cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com break; 428cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 438cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 448cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com case android::GenericPlayer::kEventHasVideoSize: { 458cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com SL_LOGV("Received AVPlayer::kEventHasVideoSize (%d,%d) for CMediaPlayer %p", 468cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com data1, data2, mp); 478cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 488cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com object_lock_exclusive(&mp->mObject); 498cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com 508cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // remove an existing video info entry (here we only have one video stream) 518cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com for(size_t i=0 ; i < mp->mStreamInfo.mStreamInfoTable.size() ; i++) { 528cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com if (XA_DOMAINTYPE_VIDEO == mp->mStreamInfo.mStreamInfoTable.itemAt(i).domain) { 538cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com mp->mStreamInfo.mStreamInfoTable.removeAt(i); 548cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com break; 558cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 568cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com } 578cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com // update the stream information with a new video info entry 588cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com StreamInfo streamInfo; 598cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com streamInfo.domain = XA_DOMAINTYPE_VIDEO; 608cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com streamInfo.videoInfo.codecId = 0;// unknown, we don't have that info FIXME 618cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com streamInfo.videoInfo.width = (XAuint32)data1; 628cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com streamInfo.videoInfo.height = (XAuint32)data2; 638cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com streamInfo.videoInfo.bitRate = 0;// unknown, we don't have that info FIXME 648cee797901763ab0922eb9ef484cfdcbc94bee54edisonn@google.com streamInfo.videoInfo.duration = XA_TIME_UNKNOWN; 65 StreamInfo &contInfo = mp->mStreamInfo.mStreamInfoTable.editItemAt(0); 66 contInfo.containerInfo.numStreams = 1; 67 ssize_t index = mp->mStreamInfo.mStreamInfoTable.add(streamInfo); 68 69 xaStreamEventChangeCallback callback = mp->mStreamInfo.mCallback; 70 void* callbackPContext = mp->mStreamInfo.mContext; 71 72 object_unlock_exclusive(&mp->mObject); 73 74 // notify (outside of lock) that the stream information has been updated 75 if ((NULL != callback) && (index >= 0)) { 76 (*callback)(&mp->mStreamInfo.mItf, XA_STREAMCBEVENT_PROPERTYCHANGE /*eventId*/, 77 1 /*streamIndex, only one stream supported here, 0 is reserved*/, 78 NULL /*pEventData, always NULL in OpenMAX AL 1.0.1*/, 79 callbackPContext /*pContext*/); 80 } 81 break; 82 } 83 84 default: 85 SL_LOGE("Received unknown event %d, data %d from AVPlayer", event, data1); 86 break; 87 } 88} 89 90 91//----------------------------------------------------------------------------- 92XAresult android_Player_checkSourceSink(CMediaPlayer *mp) { 93 94 XAresult result = XA_RESULT_SUCCESS; 95 96 const SLDataSource *pSrc = &mp->mDataSource.u.mSource; 97 const SLDataSink *pAudioSnk = &mp->mAudioSink.u.mSink; 98 99 // format check: 100 const SLuint32 sourceLocatorType = *(SLuint32 *)pSrc->pLocator; 101 const SLuint32 sourceFormatType = *(SLuint32 *)pSrc->pFormat; 102 const SLuint32 audioSinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator; 103 //const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat; 104 105 // Source check 106 switch(sourceLocatorType) { 107 108 case XA_DATALOCATOR_ANDROIDBUFFERQUEUE: { 109 switch (sourceFormatType) { 110 case XA_DATAFORMAT_MIME: { 111 SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pSrc->pFormat; 112 if (SL_CONTAINERTYPE_MPEG_TS != df_mime->containerType) { 113 SL_LOGE("Cannot create player with XA_DATALOCATOR_ANDROIDBUFFERQUEUE data source " 114 "that is not fed MPEG-2 TS data"); 115 return SL_RESULT_CONTENT_UNSUPPORTED; 116 } 117 } break; 118 default: 119 SL_LOGE("Cannot create player with XA_DATALOCATOR_ANDROIDBUFFERQUEUE data source " 120 "without SL_DATAFORMAT_MIME format"); 121 return XA_RESULT_CONTENT_UNSUPPORTED; 122 } 123 } break; 124 125 case XA_DATALOCATOR_URI: // intended fall-through 126 case XA_DATALOCATOR_ANDROIDFD: 127 break; 128 129 default: 130 SL_LOGE("Cannot create media player with data locator type 0x%x", 131 (unsigned) sourceLocatorType); 132 return SL_RESULT_PARAMETER_INVALID; 133 }// switch (locatorType) 134 135 // Audio sink check: only playback is supported here 136 switch(audioSinkLocatorType) { 137 138 case XA_DATALOCATOR_OUTPUTMIX: 139 break; 140 141 default: 142 SL_LOGE("Cannot create media player with audio sink data locator of type 0x%x", 143 (unsigned) audioSinkLocatorType); 144 return XA_RESULT_PARAMETER_INVALID; 145 }// switch (locaaudioSinkLocatorTypeorType) 146 147 return result; 148} 149 150 151//----------------------------------------------------------------------------- 152XAresult android_Player_create(CMediaPlayer *mp) { 153 154 XAresult result = XA_RESULT_SUCCESS; 155 156 // FIXME verify data source 157 const SLDataSource *pDataSrc = &mp->mDataSource.u.mSource; 158 // FIXME verify audio data sink 159 const SLDataSink *pAudioSnk = &mp->mAudioSink.u.mSink; 160 // FIXME verify image data sink 161 const SLDataSink *pVideoSnk = &mp->mImageVideoSink.u.mSink; 162 163 XAuint32 sourceLocator = *(XAuint32 *)pDataSrc->pLocator; 164 switch(sourceLocator) { 165 // FIXME support Android simple buffer queue as well 166 case XA_DATALOCATOR_ANDROIDBUFFERQUEUE: 167 mp->mAndroidObjType = AV_PLR_TS_ABQ; 168 break; 169 case XA_DATALOCATOR_URI: // intended fall-through 170 case SL_DATALOCATOR_ANDROIDFD: 171 mp->mAndroidObjType = AV_PLR_URIFD; 172 break; 173 case XA_DATALOCATOR_ADDRESS: // intended fall-through 174 default: 175 SL_LOGE("Unable to create MediaPlayer for data source locator 0x%lx", sourceLocator); 176 result = XA_RESULT_PARAMETER_INVALID; 177 break; 178 } 179 180 mp->mAndroidObjState = ANDROID_UNINITIALIZED; 181 mp->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE; 182 mp->mSessionId = android::AudioSystem::newAudioSessionId(); 183 184 mp->mDirectLevel = 0; // no attenuation 185 186 return result; 187} 188 189 190//----------------------------------------------------------------------------- 191// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 192XAresult android_Player_realize(CMediaPlayer *mp, SLboolean async) { 193 SL_LOGI("android_Player_realize_l(%p)", mp); 194 XAresult result = XA_RESULT_SUCCESS; 195 196 const SLDataSource *pDataSrc = &mp->mDataSource.u.mSource; 197 const SLuint32 sourceLocator = *(SLuint32 *)pDataSrc->pLocator; 198 199 AudioPlayback_Parameters ap_params; 200 ap_params.sessionId = mp->mSessionId; 201 ap_params.streamType = mp->mStreamType; 202 ap_params.trackcb = NULL; 203 ap_params.trackcbUser = NULL; 204 205 switch(mp->mAndroidObjType) { 206 case AV_PLR_TS_ABQ: { 207 mp->mAVPlayer = new android::StreamPlayer(&ap_params, true /*hasVideo*/); 208 mp->mAVPlayer->init(player_handleMediaPlayerEventNotifications, (void*)mp); 209 } 210 break; 211 case AV_PLR_URIFD: { 212 mp->mAVPlayer = new android::LocAVPlayer(&ap_params, true /*hasVideo*/); 213 mp->mAVPlayer->init(player_handleMediaPlayerEventNotifications, (void*)mp); 214 switch (mp->mDataSource.mLocator.mLocatorType) { 215 case XA_DATALOCATOR_URI: 216 ((android::LocAVPlayer*)mp->mAVPlayer.get())->setDataSource( 217 (const char*)mp->mDataSource.mLocator.mURI.URI); 218 break; 219 case XA_DATALOCATOR_ANDROIDFD: { 220 int64_t offset = (int64_t)mp->mDataSource.mLocator.mFD.offset; 221 ((android::LocAVPlayer*)mp->mAVPlayer.get())->setDataSource( 222 (int)mp->mDataSource.mLocator.mFD.fd, 223 offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ? 224 (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset, 225 (int64_t)mp->mDataSource.mLocator.mFD.length); 226 } 227 break; 228 default: 229 SL_LOGE("Invalid or unsupported data locator type %lu for data source", 230 mp->mDataSource.mLocator.mLocatorType); 231 result = XA_RESULT_PARAMETER_INVALID; 232 } 233 } 234 break; 235 case INVALID_TYPE: // intended fall-through 236 default: 237 SL_LOGE("Unable to realize MediaPlayer, invalid internal Android object type"); 238 result = XA_RESULT_PARAMETER_INVALID; 239 break; 240 } 241 242 return result; 243} 244 245//----------------------------------------------------------------------------- 246XAresult android_Player_destroy(CMediaPlayer *mp) { 247 SL_LOGI("android_Player_destroy(%p)", mp); 248 XAresult result = XA_RESULT_SUCCESS; 249 250 if (mp->mAVPlayer != 0) { 251 mp->mAVPlayer.clear(); 252 } 253 254 return result; 255} 256 257//----------------------------------------------------------------------------- 258/** 259 * pre-conditions: avp != NULL, surface != NULL 260 */ 261XAresult android_Player_setVideoSurface(android::GenericMediaPlayer *avp, 262 const android::sp<android::Surface> &surface) { 263 XAresult result = XA_RESULT_SUCCESS; 264 265 avp->setVideoSurface(surface); 266 267 return result; 268} 269 270 271/** 272 * pre-conditions: avp != NULL, surfaceTexture != NULL 273 */ 274XAresult android_Player_setVideoSurfaceTexture(android::GenericMediaPlayer *avp, 275 const android::sp<android::ISurfaceTexture> &surfaceTexture) { 276 XAresult result = XA_RESULT_SUCCESS; 277 278 avp->setVideoSurfaceTexture(surfaceTexture); 279 280 return result; 281} 282 283 284XAresult android_Player_getDuration(IPlay *pPlayItf, XAmillisecond *pDurMsec) { 285 XAresult result = XA_RESULT_SUCCESS; 286 CMediaPlayer *avp = (CMediaPlayer *)pPlayItf->mThis; 287 288 switch (avp->mAndroidObjType) { 289 290 case AV_PLR_TS_ABQ: // intended fall-through 291 case AV_PLR_URIFD: { 292 // FIXME implement for a MediaPlayer playing on URI or FD (on LocAVPlayer, returns -1) 293 int dur = -1; 294 if (avp->mAVPlayer != 0) { 295 avp->mAVPlayer->getDurationMsec(&dur); 296 } 297 if (dur < 0) { 298 *pDurMsec = SL_TIME_UNKNOWN; 299 } else { 300 *pDurMsec = (XAmillisecond)dur; 301 } 302 } break; 303 304 default: 305 *pDurMsec = XA_TIME_UNKNOWN; 306 break; 307 } 308 309 return result; 310} 311 312 313//----------------------------------------------------------------------------- 314/** 315 * pre-condition: avp != NULL, pVolItf != NULL 316 */ 317XAresult android_Player_volumeUpdate(android::GenericPlayer *avp, IVolume *pVolItf) 318{ 319 XAresult result = XA_RESULT_SUCCESS; 320 321 avp->updateVolume((bool)pVolItf->mMute, (bool)pVolItf->mEnableStereoPosition, 322 pVolItf->mStereoPosition, pVolItf->mLevel); 323 324 return result; 325} 326 327//----------------------------------------------------------------------------- 328/** 329 * pre-condition: avp != NULL 330 */ 331XAresult android_Player_setPlayState(android::GenericPlayer *avp, SLuint32 playState, 332 AndroidObject_state* pObjState) 333{ 334 XAresult result = XA_RESULT_SUCCESS; 335 AndroidObject_state objState = *pObjState; 336 337 switch (playState) { 338 case SL_PLAYSTATE_STOPPED: { 339 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_STOPPED"); 340 avp->stop(); 341 } 342 break; 343 case SL_PLAYSTATE_PAUSED: { 344 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PAUSED"); 345 switch(objState) { 346 case ANDROID_UNINITIALIZED: 347 *pObjState = ANDROID_PREPARING; 348 avp->prepare(); 349 break; 350 case ANDROID_PREPARING: 351 break; 352 case ANDROID_READY: 353 avp->pause(); 354 break; 355 default: 356 SL_LOGE("Android object in invalid state"); 357 break; 358 } 359 } 360 break; 361 case SL_PLAYSTATE_PLAYING: { 362 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PLAYING"); 363 switch(objState) { 364 case ANDROID_UNINITIALIZED: 365 *pObjState = ANDROID_PREPARING; 366 avp->prepare(); 367 // intended fall through 368 case ANDROID_PREPARING: 369 // intended fall through 370 case ANDROID_READY: 371 avp->play(); 372 break; 373 default: 374 SL_LOGE("Android object in invalid state"); 375 break; 376 } 377 } 378 break; 379 default: 380 // checked by caller, should not happen 381 break; 382 } 383 384 return result; 385} 386 387 388//----------------------------------------------------------------------------- 389void android_Player_androidBufferQueue_registerCallback_l(CMediaPlayer *mp) { 390 if ((mp->mAndroidObjType == AV_PLR_TS_ABQ) && (mp->mAVPlayer != 0)) { 391 SL_LOGI("android_Player_androidBufferQueue_registerCallback_l"); 392 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get()); 393 splr->registerQueueCallback( 394 (const void*)mp, false /*userIsAudioPlayer*/, 395 mp->mAndroidBufferQueue.mContext, (const void*)&(mp->mAndroidBufferQueue.mItf)); 396 397 } 398} 399 400 401void android_Player_androidBufferQueue_clear_l(CMediaPlayer *mp) { 402 if ((mp->mAndroidObjType == AV_PLR_TS_ABQ) && (mp->mAVPlayer != 0)) { 403 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get()); 404 splr->appClear_l(); 405 } 406} 407 408 409void android_Player_androidBufferQueue_onRefilled_l(CMediaPlayer *mp) { 410 if ((mp->mAndroidObjType == AV_PLR_TS_ABQ) && (mp->mAVPlayer != 0)) { 411 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get()); 412 splr->queueRefilled_l(); 413 } 414} 415 416 417 418