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