MediaPlayer_to_android.cpp revision e7bfcdc183454ec959ff51342f0973cabba219b2
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 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, 227 const android::sp<android::Surface> &surface) { 228 XAresult result = XA_RESULT_SUCCESS; 229 230 avp->setVideoSurface(surface); 231 232 return result; 233} 234 235 236/** 237 * pre-conditions: avp != NULL, surfaceTexture != NULL 238 */ 239XAresult android_Player_setVideoSurfaceTexture(android::GenericMediaPlayer *avp, 240 const android::sp<android::ISurfaceTexture> &surfaceTexture) { 241 XAresult result = XA_RESULT_SUCCESS; 242 243 avp->setVideoSurfaceTexture(surfaceTexture); 244 245 return result; 246} 247 248 249XAresult android_Player_getDuration(IPlay *pPlayItf, XAmillisecond *pDurMsec) { 250 XAresult result = XA_RESULT_SUCCESS; 251 CMediaPlayer *avp = (CMediaPlayer *)pPlayItf->mThis; 252 253 switch (avp->mAndroidObjType) { 254 255 case AV_PLR_TS_ABQ: // intended fall-through 256 case AV_PLR_URIFD: { 257 // FIXME implement for a MediaPlayer playing on URI or FD (on LocAVPlayer, returns -1) 258 int dur = -1; 259 if (avp->mAVPlayer != 0) { 260 avp->mAVPlayer->getDurationMsec(&dur); 261 } 262 if (dur < 0) { 263 *pDurMsec = SL_TIME_UNKNOWN; 264 } else { 265 *pDurMsec = (XAmillisecond)dur; 266 } 267 } break; 268 269 default: 270 *pDurMsec = XA_TIME_UNKNOWN; 271 break; 272 } 273 274 return result; 275} 276 277//----------------------------------------------------------------------------- 278/** 279 * pre-condition: avp != NULL 280 */ 281XAresult android_Player_setPlayState(android::GenericPlayer *avp, SLuint32 playState, 282 AndroidObject_state* pObjState) 283{ 284 XAresult result = XA_RESULT_SUCCESS; 285 AndroidObject_state objState = *pObjState; 286 287 switch (playState) { 288 case SL_PLAYSTATE_STOPPED: { 289 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_STOPPED"); 290 avp->stop(); 291 } 292 break; 293 case SL_PLAYSTATE_PAUSED: { 294 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PAUSED"); 295 switch(objState) { 296 case ANDROID_UNINITIALIZED: 297 *pObjState = ANDROID_PREPARING; 298 avp->prepare(); 299 break; 300 case ANDROID_PREPARING: 301 break; 302 case ANDROID_READY: 303 avp->pause(); 304 break; 305 default: 306 SL_LOGE("Android object in invalid state"); 307 break; 308 } 309 } 310 break; 311 case SL_PLAYSTATE_PLAYING: { 312 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PLAYING"); 313 switch(objState) { 314 case ANDROID_UNINITIALIZED: 315 *pObjState = ANDROID_PREPARING; 316 avp->prepare(); 317 // intended fall through 318 case ANDROID_PREPARING: 319 // intended fall through 320 case ANDROID_READY: 321 avp->play(); 322 break; 323 default: 324 SL_LOGE("Android object in invalid state"); 325 break; 326 } 327 } 328 break; 329 default: 330 // checked by caller, should not happen 331 break; 332 } 333 334 return result; 335} 336 337 338//----------------------------------------------------------------------------- 339void android_Player_androidBufferQueue_registerCallback_l(CMediaPlayer *mp) { 340 if ((mp->mAndroidObjType == AV_PLR_TS_ABQ) && (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_clear_l(CMediaPlayer *mp) { 352 if ((mp->mAndroidObjType == AV_PLR_TS_ABQ) && (mp->mAVPlayer != 0)) { 353 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get()); 354 splr->appClear_l(); 355 } 356} 357 358 359void android_Player_androidBufferQueue_onRefilled_l(CMediaPlayer *mp) { 360 if ((mp->mAndroidObjType == AV_PLR_TS_ABQ) && (mp->mAVPlayer != 0)) { 361 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get()); 362 splr->queueRefilled_l(); 363 } 364} 365 366 367 368