MediaPlayer_to_android.cpp revision 70c49ae2867094072a4365423417ea452bf82231
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//-----------------------------------------------------------------------------
22static void player_handleMediaPlayerEventNotifications(const int event, const int data1, void* user)
23{
24    if (NULL == user) {
25        return;
26    }
27
28    CMediaPlayer* mp = (CMediaPlayer*) user;
29    //SL_LOGV("received event %d, data %d from AVPlayer", event, data1);
30
31    switch(event) {
32
33    case android::GenericPlayer::kEventPrepared: {
34        if (PLAYER_SUCCESS == data1) {
35            object_lock_exclusive(&mp->mObject);
36            SL_LOGV("Received AVPlayer::kEventPrepared from AVPlayer for CMediaPlayer %p", mp);
37            mp->mAndroidObjState = ANDROID_READY;
38            object_unlock_exclusive(&mp->mObject);
39        }
40        }
41        break;
42
43    default:
44        SL_LOGE("Received unknown event %d, data %d from AVPlayer", event, data1);
45        break;
46    }
47}
48
49
50//-----------------------------------------------------------------------------
51XAresult android_Player_checkSourceSink(CMediaPlayer *mp) {
52
53    XAresult result = XA_RESULT_SUCCESS;
54
55    const SLDataSource *pSrc    = &mp->mDataSource.u.mSource;
56    const SLDataSink *pAudioSnk = &mp->mAudioSink.u.mSink;
57
58    // format check:
59    const SLuint32 sourceLocatorType = *(SLuint32 *)pSrc->pLocator;
60    const SLuint32 sourceFormatType  = *(SLuint32 *)pSrc->pFormat;
61    const SLuint32 audioSinkLocatorType = *(SLuint32 *)pAudioSnk->pLocator;
62    //const SLuint32 sinkFormatType = *(SLuint32 *)pAudioSnk->pFormat;
63
64    // Source check
65    switch(sourceLocatorType) {
66
67    case XA_DATALOCATOR_ANDROIDBUFFERQUEUE: {
68        switch (sourceFormatType) {
69        case XA_DATAFORMAT_MIME: {
70            SLDataFormat_MIME *df_mime = (SLDataFormat_MIME *) pSrc->pFormat;
71            if (SL_CONTAINERTYPE_MPEG_TS != df_mime->containerType) {
72                SL_LOGE("Cannot create player with XA_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
73                        "that is not fed MPEG-2 TS data");
74                return SL_RESULT_CONTENT_UNSUPPORTED;
75            }
76        } break;
77        default:
78            SL_LOGE("Cannot create player with XA_DATALOCATOR_ANDROIDBUFFERQUEUE data source "
79                    "without SL_DATAFORMAT_MIME format");
80            return XA_RESULT_CONTENT_UNSUPPORTED;
81        }
82    } break;
83
84    case XA_DATALOCATOR_URI: // intended fall-through
85    case XA_DATALOCATOR_ANDROIDFD:
86        break;
87
88    default:
89        SL_LOGE("Cannot create media player with data locator type 0x%x",
90                (unsigned) sourceLocatorType);
91        return SL_RESULT_PARAMETER_INVALID;
92    }// switch (locatorType)
93
94    // Audio sink check: only playback is supported here
95    switch(audioSinkLocatorType) {
96
97    case XA_DATALOCATOR_OUTPUTMIX:
98        break;
99
100    default:
101        SL_LOGE("Cannot create media player with audio sink data locator of type 0x%x",
102                (unsigned) audioSinkLocatorType);
103        return XA_RESULT_PARAMETER_INVALID;
104    }// switch (locaaudioSinkLocatorTypeorType)
105
106    return result;
107}
108
109
110//-----------------------------------------------------------------------------
111XAresult android_Player_create(CMediaPlayer *mp) {
112
113    XAresult result = XA_RESULT_SUCCESS;
114
115    // FIXME verify data source
116    const SLDataSource *pDataSrc = &mp->mDataSource.u.mSource;
117    // FIXME verify audio data sink
118    const SLDataSink *pAudioSnk = &mp->mAudioSink.u.mSink;
119    // FIXME verify image data sink
120    const SLDataSink *pVideoSnk = &mp->mImageVideoSink.u.mSink;
121
122    XAuint32 sourceLocator = *(XAuint32 *)pDataSrc->pLocator;
123    switch(sourceLocator) {
124    // FIXME support Android simple buffer queue as well
125    case XA_DATALOCATOR_ANDROIDBUFFERQUEUE:
126        mp->mAndroidObjType = AV_PLR_TS_ABQ;
127        break;
128    case XA_DATALOCATOR_URI: // intended fall-through
129    case SL_DATALOCATOR_ANDROIDFD:
130        mp->mAndroidObjType = AV_PLR_URIFD;
131        break;
132    case XA_DATALOCATOR_ADDRESS: // intended fall-through
133    default:
134        SL_LOGE("Unable to create MediaPlayer for data source locator 0x%lx", sourceLocator);
135        result = XA_RESULT_PARAMETER_INVALID;
136        break;
137    }
138
139    mp->mAndroidObjState = ANDROID_UNINITIALIZED;
140    mp->mStreamType = ANDROID_DEFAULT_OUTPUT_STREAM_TYPE;
141    mp->mSessionId = android::AudioSystem::newAudioSessionId();
142
143    mp->mAndroidAudioLevels.mAmplFromVolLevel = 1.0f;
144    mp->mAndroidAudioLevels.mAmplFromStereoPos[0] = 1.0f;
145    mp->mAndroidAudioLevels.mAmplFromStereoPos[1] = 1.0f;
146    mp->mAndroidAudioLevels.mAmplFromDirectLevel = 1.0f; // matches initial mDirectLevel value
147    mp->mAndroidAudioLevels.mAuxSendLevel = 0;
148    mp->mDirectLevel = 0; // no attenuation
149
150    return result;
151}
152
153
154//-----------------------------------------------------------------------------
155// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
156XAresult android_Player_realize(CMediaPlayer *mp, SLboolean async) {
157    SL_LOGI("android_Player_realize_l(%p)", mp);
158    XAresult result = XA_RESULT_SUCCESS;
159
160    const SLDataSource *pDataSrc = &mp->mDataSource.u.mSource;
161    const SLuint32 sourceLocator = *(SLuint32 *)pDataSrc->pLocator;
162
163    AudioPlayback_Parameters ap_params;
164    ap_params.sessionId = mp->mSessionId;
165    ap_params.streamType = mp->mStreamType;
166    ap_params.trackcb = NULL;
167    ap_params.trackcbUser = NULL;
168
169    switch(mp->mAndroidObjType) {
170    case AV_PLR_TS_ABQ: {
171        mp->mAVPlayer = new android::StreamPlayer(&ap_params, true /*hasVideo*/);
172        mp->mAVPlayer->init(player_handleMediaPlayerEventNotifications, (void*)mp);
173        }
174        break;
175    case AV_PLR_URIFD: {
176        mp->mAVPlayer = new android::LocAVPlayer(&ap_params, true /*hasVideo*/);
177        mp->mAVPlayer->init(player_handleMediaPlayerEventNotifications, (void*)mp);
178        switch (mp->mDataSource.mLocator.mLocatorType) {
179        case XA_DATALOCATOR_URI:
180            ((android::LocAVPlayer*)mp->mAVPlayer.get())->setDataSource(
181                    (const char*)mp->mDataSource.mLocator.mURI.URI);
182            break;
183        case XA_DATALOCATOR_ANDROIDFD: {
184            int64_t offset = (int64_t)mp->mDataSource.mLocator.mFD.offset;
185            ((android::LocAVPlayer*)mp->mAVPlayer.get())->setDataSource(
186                    (int)mp->mDataSource.mLocator.mFD.fd,
187                    offset == SL_DATALOCATOR_ANDROIDFD_USE_FILE_SIZE ?
188                            (int64_t)PLAYER_FD_FIND_FILE_SIZE : offset,
189                    (int64_t)mp->mDataSource.mLocator.mFD.length);
190            }
191            break;
192        default:
193            SL_LOGE("Invalid or unsupported data locator type %lu for data source",
194                    mp->mDataSource.mLocator.mLocatorType);
195            result = XA_RESULT_PARAMETER_INVALID;
196        }
197        }
198        break;
199    case INVALID_TYPE: // intended fall-through
200    default:
201        SL_LOGE("Unable to realize MediaPlayer, invalid internal Android object type");
202        result = XA_RESULT_PARAMETER_INVALID;
203        break;
204    }
205
206    return result;
207}
208
209//-----------------------------------------------------------------------------
210XAresult android_Player_destroy(CMediaPlayer *mp) {
211    SL_LOGI("android_Player_destroy(%p)", mp);
212    XAresult result = XA_RESULT_SUCCESS;
213
214    if (mp->mAVPlayer != 0) {
215        mp->mAVPlayer.clear();
216    }
217
218    return result;
219}
220
221//-----------------------------------------------------------------------------
222/**
223 * pre-conditions: avp != NULL, surface != NULL
224 */
225XAresult android_Player_setVideoSurface(android::GenericMediaPlayer *avp,
226        const android::sp<android::Surface> &surface) {
227    XAresult result = XA_RESULT_SUCCESS;
228
229    avp->setVideoSurface(surface);
230
231    return result;
232}
233
234
235/**
236 * pre-conditions: avp != NULL, surfaceTexture != NULL
237 */
238XAresult android_Player_setVideoSurfaceTexture(android::GenericMediaPlayer *avp,
239        const android::sp<android::ISurfaceTexture> &surfaceTexture) {
240    XAresult result = XA_RESULT_SUCCESS;
241
242    avp->setVideoSurfaceTexture(surfaceTexture);
243
244    return result;
245}
246
247
248XAresult android_Player_getDuration(IPlay *pPlayItf, XAmillisecond *pDurMsec) {
249    XAresult result = XA_RESULT_SUCCESS;
250    CMediaPlayer *avp = (CMediaPlayer *)pPlayItf->mThis;
251
252    switch (avp->mAndroidObjType) {
253
254    case AV_PLR_TS_ABQ: // intended fall-through
255    case AV_PLR_URIFD: {
256        // FIXME implement for a MediaPlayer playing on URI or FD (on LocAVPlayer, returns -1)
257        int dur = -1;
258        if (avp->mAVPlayer != 0) {
259            avp->mAVPlayer->getDurationMsec(&dur);
260        }
261        if (dur < 0) {
262            *pDurMsec = SL_TIME_UNKNOWN;
263        } else {
264            *pDurMsec = (XAmillisecond)dur;
265        }
266    } break;
267
268    default:
269        *pDurMsec = XA_TIME_UNKNOWN;
270        break;
271    }
272
273    return result;
274}
275
276//-----------------------------------------------------------------------------
277/**
278 * pre-condition: avp != NULL
279 */
280XAresult android_Player_setPlayState(android::GenericPlayer *avp, SLuint32 playState,
281        AndroidObject_state* pObjState)
282{
283    XAresult result = XA_RESULT_SUCCESS;
284    AndroidObject_state objState = *pObjState;
285
286    switch (playState) {
287     case SL_PLAYSTATE_STOPPED: {
288         SL_LOGV("setting AVPlayer to SL_PLAYSTATE_STOPPED");
289         avp->stop();
290         }
291         break;
292     case SL_PLAYSTATE_PAUSED: {
293         SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PAUSED");
294         switch(objState) {
295         case(ANDROID_UNINITIALIZED):
296             *pObjState = ANDROID_PREPARING;
297             avp->prepare();
298             break;
299         case(ANDROID_PREPARING):
300             break;
301         case(ANDROID_READY):
302             avp->pause();
303             break;
304         default:
305             SL_LOGE("Android object in invalid state");
306             break;
307         }
308         }
309         break;
310     case SL_PLAYSTATE_PLAYING: {
311         SL_LOGV("setting AVPlayer to SL_PLAYSTATE_PLAYING");
312         switch(objState) {
313         case(ANDROID_UNINITIALIZED):
314             *pObjState = ANDROID_PREPARING;
315             avp->prepare();
316             // intended fall through
317         case(ANDROID_PREPARING):
318             // intended fall through
319         case(ANDROID_READY):
320             avp->play();
321             break;
322         default:
323             SL_LOGE("Android object in invalid state");
324             break;
325         }
326         }
327         break;
328     default:
329         // checked by caller, should not happen
330         break;
331     }
332
333    return result;
334}
335
336
337//-----------------------------------------------------------------------------
338// FIXME abstract out the diff between CMediaPlayer and CAudioPlayer
339void android_Player_androidBufferQueue_registerCallback_l(CMediaPlayer *mp) {
340    if (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_onRefilled_l(CMediaPlayer *mp) {
352    if (mp->mAVPlayer != 0) {
353        android::StreamPlayer* splr = static_cast<android::StreamPlayer*>(mp->mAVPlayer.get());
354        splr->queueRefilled_l();
355    }
356}
357
358
359
360