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