MediaPlayer_to_android.cpp revision ad1ab1d13a9b043202b9d5cdc1d8c4ef66cbbca8
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, 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 249//----------------------------------------------------------------------------- 250/** 251 * pre-condition: avp != NULL 252 */ 253XAresult android_Player_setPlayState(android::GenericPlayer *avp, SLuint32 playState, 254 AndroidObject_state* pObjState) 255{ 256 XAresult result = XA_RESULT_SUCCESS; 257 AndroidObject_state objState = *pObjState; 258 259 switch (playState) { 260 case SL_PLAYSTATE_STOPPED: { 261 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_STOPPED"); 262 avp->stop(); 263 } 264 break; 265 case SL_PLAYSTATE_PAUSED: { 266 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PAUSED"); 267 switch(objState) { 268 case(ANDROID_UNINITIALIZED): 269 *pObjState = ANDROID_PREPARING; 270 avp->prepare(); 271 break; 272 case(ANDROID_PREPARING): 273 break; 274 case(ANDROID_READY): 275 avp->pause(); 276 break; 277 default: 278 SL_LOGE("Android object in invalid state"); 279 break; 280 } 281 } 282 break; 283 case SL_PLAYSTATE_PLAYING: { 284 SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PLAYING"); 285 switch(objState) { 286 case(ANDROID_UNINITIALIZED): 287 *pObjState = ANDROID_PREPARING; 288 avp->prepare(); 289 // intended fall through 290 case(ANDROID_PREPARING): 291 // intended fall through 292 case(ANDROID_READY): 293 avp->play(); 294 break; 295 default: 296 SL_LOGE("Android object in invalid state"); 297 break; 298 } 299 } 300 break; 301 default: 302 // checked by caller, should not happen 303 break; 304 } 305 306 return result; 307} 308 309 310//----------------------------------------------------------------------------- 311 312 313// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 314void android_Player_androidBufferQueue_registerCallback_l(CMediaPlayer *mp) { 315 if (mp->mAVPlayer != 0) { 316 SL_LOGI("android_Player_androidBufferQueue_registerCallback_l"); 317 android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get()); 318 splr->registerQueueCallback( 319 mp->mAndroidBufferQueue.mCallback, 320 abqSrc_callBack_pullFromBuffQueue, 321 (const void*)mp, false /*userIsAudioPlayer*/, 322 mp->mAndroidBufferQueue.mContext, (const void*)&(mp->mAndroidBufferQueue.mItf)); 323 324 } 325} 326 327// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer 328void android_Player_androidBufferQueue_enqueue_l(CMediaPlayer *mp, 329 SLuint32 bufferId, SLuint32 length, SLuint32 event, void *pData) { 330 if (mp->mAVPlayer != 0) { 331 android::StreamPlayer* splr = (android::StreamPlayer*)(mp->mAVPlayer.get()); 332 splr->appEnqueue(bufferId, length, event, pData); 333 } 334} 335 336 337 338