• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "MediaPlayerNative"
20 
21 #include <fcntl.h>
22 #include <inttypes.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
27 #include <utils/Log.h>
28 
29 #include <binder/IServiceManager.h>
30 #include <binder/IPCThreadState.h>
31 
32 #include <gui/Surface.h>
33 
34 #include <media/mediaplayer.h>
35 #include <media/AudioResamplerPublic.h>
36 #include <media/AudioSystem.h>
37 #include <media/AVSyncSettings.h>
38 #include <media/IDataSource.h>
39 #include <media/MediaAnalyticsItem.h>
40 
41 #include <binder/MemoryBase.h>
42 
43 #include <utils/KeyedVector.h>
44 #include <utils/String8.h>
45 
46 #include <system/audio.h>
47 #include <system/window.h>
48 
49 namespace android {
50 
MediaPlayer()51 MediaPlayer::MediaPlayer()
52 {
53     ALOGV("constructor");
54     mListener = NULL;
55     mCookie = NULL;
56     mStreamType = AUDIO_STREAM_MUSIC;
57     mAudioAttributesParcel = NULL;
58     mCurrentPosition = -1;
59     mCurrentSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
60     mSeekPosition = -1;
61     mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
62     mCurrentState = MEDIA_PLAYER_IDLE;
63     mPrepareSync = false;
64     mPrepareStatus = NO_ERROR;
65     mLoop = false;
66     mLeftVolume = mRightVolume = 1.0;
67     mVideoWidth = mVideoHeight = 0;
68     mLockThreadId = 0;
69     mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
70     AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
71     mSendLevel = 0;
72     mRetransmitEndpointValid = false;
73 }
74 
~MediaPlayer()75 MediaPlayer::~MediaPlayer()
76 {
77     ALOGV("destructor");
78     if (mAudioAttributesParcel != NULL) {
79         delete mAudioAttributesParcel;
80         mAudioAttributesParcel = NULL;
81     }
82     AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
83     disconnect();
84     IPCThreadState::self()->flushCommands();
85 }
86 
disconnect()87 void MediaPlayer::disconnect()
88 {
89     ALOGV("disconnect");
90     sp<IMediaPlayer> p;
91     {
92         Mutex::Autolock _l(mLock);
93         p = mPlayer;
94         mPlayer.clear();
95     }
96 
97     if (p != 0) {
98         p->disconnect();
99     }
100 }
101 
102 // always call with lock held
clear_l()103 void MediaPlayer::clear_l()
104 {
105     mCurrentPosition = -1;
106     mCurrentSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
107     mSeekPosition = -1;
108     mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
109     mVideoWidth = mVideoHeight = 0;
110     mRetransmitEndpointValid = false;
111 }
112 
setListener(const sp<MediaPlayerListener> & listener)113 status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener)
114 {
115     ALOGV("setListener");
116     Mutex::Autolock _l(mLock);
117     mListener = listener;
118     return NO_ERROR;
119 }
120 
121 
attachNewPlayer(const sp<IMediaPlayer> & player)122 status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player)
123 {
124     status_t err = UNKNOWN_ERROR;
125     sp<IMediaPlayer> p;
126     { // scope for the lock
127         Mutex::Autolock _l(mLock);
128 
129         if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||
130                 (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) {
131             ALOGE("attachNewPlayer called in state %d", mCurrentState);
132             return INVALID_OPERATION;
133         }
134 
135         clear_l();
136         p = mPlayer;
137         mPlayer = player;
138         if (player != 0) {
139             mCurrentState = MEDIA_PLAYER_INITIALIZED;
140             player->getDefaultBufferingSettings(&mCurrentBufferingSettings);
141             err = NO_ERROR;
142         } else {
143             mCurrentBufferingSettings = BufferingSettings();
144             ALOGE("Unable to create media player");
145         }
146     }
147 
148     if (p != 0) {
149         p->disconnect();
150     }
151 
152     return err;
153 }
154 
setDataSource(const sp<IMediaHTTPService> & httpService,const char * url,const KeyedVector<String8,String8> * headers)155 status_t MediaPlayer::setDataSource(
156         const sp<IMediaHTTPService> &httpService,
157         const char *url, const KeyedVector<String8, String8> *headers)
158 {
159     ALOGV("setDataSource(%s)", url);
160     status_t err = BAD_VALUE;
161     if (url != NULL) {
162         const sp<IMediaPlayerService> service(getMediaPlayerService());
163         if (service != 0) {
164             sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
165             if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
166                 (NO_ERROR != player->setDataSource(httpService, url, headers))) {
167                 player.clear();
168             }
169             err = attachNewPlayer(player);
170         }
171     }
172     return err;
173 }
174 
setDataSource(int fd,int64_t offset,int64_t length)175 status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
176 {
177     ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
178     status_t err = UNKNOWN_ERROR;
179     const sp<IMediaPlayerService> service(getMediaPlayerService());
180     if (service != 0) {
181         sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
182         if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
183             (NO_ERROR != player->setDataSource(fd, offset, length))) {
184             player.clear();
185         }
186         err = attachNewPlayer(player);
187     }
188     return err;
189 }
190 
setDataSource(const sp<IDataSource> & source)191 status_t MediaPlayer::setDataSource(const sp<IDataSource> &source)
192 {
193     ALOGV("setDataSource(IDataSource)");
194     status_t err = UNKNOWN_ERROR;
195     const sp<IMediaPlayerService> service(getMediaPlayerService());
196     if (service != 0) {
197         sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
198         if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
199             (NO_ERROR != player->setDataSource(source))) {
200             player.clear();
201         }
202         err = attachNewPlayer(player);
203     }
204     return err;
205 }
206 
invoke(const Parcel & request,Parcel * reply)207 status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
208 {
209     Mutex::Autolock _l(mLock);
210     const bool hasBeenInitialized =
211             (mCurrentState != MEDIA_PLAYER_STATE_ERROR) &&
212             ((mCurrentState & MEDIA_PLAYER_IDLE) != MEDIA_PLAYER_IDLE);
213     if ((mPlayer != NULL) && hasBeenInitialized) {
214         ALOGV("invoke %zu", request.dataSize());
215         return  mPlayer->invoke(request, reply);
216     }
217     ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
218     return INVALID_OPERATION;
219 }
220 
setMetadataFilter(const Parcel & filter)221 status_t MediaPlayer::setMetadataFilter(const Parcel& filter)
222 {
223     ALOGD("setMetadataFilter");
224     Mutex::Autolock lock(mLock);
225     if (mPlayer == NULL) {
226         return NO_INIT;
227     }
228     return mPlayer->setMetadataFilter(filter);
229 }
230 
getMetadata(bool update_only,bool apply_filter,Parcel * metadata)231 status_t MediaPlayer::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
232 {
233     ALOGD("getMetadata");
234     Mutex::Autolock lock(mLock);
235     if (mPlayer == NULL) {
236         return NO_INIT;
237     }
238     return mPlayer->getMetadata(update_only, apply_filter, metadata);
239 }
240 
setVideoSurfaceTexture(const sp<IGraphicBufferProducer> & bufferProducer)241 status_t MediaPlayer::setVideoSurfaceTexture(
242         const sp<IGraphicBufferProducer>& bufferProducer)
243 {
244     ALOGV("setVideoSurfaceTexture");
245     Mutex::Autolock _l(mLock);
246     if (mPlayer == 0) return NO_INIT;
247     return mPlayer->setVideoSurfaceTexture(bufferProducer);
248 }
249 
getDefaultBufferingSettings(BufferingSettings * buffering)250 status_t MediaPlayer::getDefaultBufferingSettings(BufferingSettings* buffering /* nonnull */)
251 {
252     ALOGV("getDefaultBufferingSettings");
253 
254     Mutex::Autolock _l(mLock);
255     if (mPlayer == 0) {
256         return NO_INIT;
257     }
258     return mPlayer->getDefaultBufferingSettings(buffering);
259 }
260 
getBufferingSettings(BufferingSettings * buffering)261 status_t MediaPlayer::getBufferingSettings(BufferingSettings* buffering /* nonnull */)
262 {
263     ALOGV("getBufferingSettings");
264 
265     Mutex::Autolock _l(mLock);
266     if (mPlayer == 0) {
267         return NO_INIT;
268     }
269     *buffering = mCurrentBufferingSettings;
270     return NO_ERROR;
271 }
272 
setBufferingSettings(const BufferingSettings & buffering)273 status_t MediaPlayer::setBufferingSettings(const BufferingSettings& buffering)
274 {
275     ALOGV("setBufferingSettings");
276 
277     Mutex::Autolock _l(mLock);
278     if (mPlayer == 0) {
279         return NO_INIT;
280     }
281     status_t err =  mPlayer->setBufferingSettings(buffering);
282     if (err == NO_ERROR) {
283         mCurrentBufferingSettings = buffering;
284     }
285     return err;
286 }
287 
288 // must call with lock held
prepareAsync_l()289 status_t MediaPlayer::prepareAsync_l()
290 {
291     if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) {
292         if (mAudioAttributesParcel != NULL) {
293             mPlayer->setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel);
294         } else {
295             mPlayer->setAudioStreamType(mStreamType);
296         }
297         mCurrentState = MEDIA_PLAYER_PREPARING;
298         return mPlayer->prepareAsync();
299     }
300     ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
301     return INVALID_OPERATION;
302 }
303 
304 // TODO: In case of error, prepareAsync provides the caller with 2 error codes,
305 // one defined in the Android framework and one provided by the implementation
306 // that generated the error. The sync version of prepare returns only 1 error
307 // code.
prepare()308 status_t MediaPlayer::prepare()
309 {
310     ALOGV("prepare");
311     Mutex::Autolock _l(mLock);
312     mLockThreadId = getThreadId();
313     if (mPrepareSync) {
314         mLockThreadId = 0;
315         return -EALREADY;
316     }
317     mPrepareSync = true;
318     status_t ret = prepareAsync_l();
319     if (ret != NO_ERROR) {
320         mLockThreadId = 0;
321         return ret;
322     }
323 
324     if (mPrepareSync) {
325         mSignal.wait(mLock);  // wait for prepare done
326         mPrepareSync = false;
327     }
328     ALOGV("prepare complete - status=%d", mPrepareStatus);
329     mLockThreadId = 0;
330     return mPrepareStatus;
331 }
332 
prepareAsync()333 status_t MediaPlayer::prepareAsync()
334 {
335     ALOGV("prepareAsync");
336     Mutex::Autolock _l(mLock);
337     return prepareAsync_l();
338 }
339 
start()340 status_t MediaPlayer::start()
341 {
342     ALOGV("start");
343 
344     status_t ret = NO_ERROR;
345     Mutex::Autolock _l(mLock);
346 
347     mLockThreadId = getThreadId();
348 
349     if (mCurrentState & MEDIA_PLAYER_STARTED) {
350         ret = NO_ERROR;
351     } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
352                     MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
353         mPlayer->setLooping(mLoop);
354         mPlayer->setVolume(mLeftVolume, mRightVolume);
355         mPlayer->setAuxEffectSendLevel(mSendLevel);
356         mCurrentState = MEDIA_PLAYER_STARTED;
357         ret = mPlayer->start();
358         if (ret != NO_ERROR) {
359             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
360         } else {
361             if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
362                 ALOGV("playback completed immediately following start()");
363             }
364         }
365     } else {
366         ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
367         ret = INVALID_OPERATION;
368     }
369 
370     mLockThreadId = 0;
371 
372     return ret;
373 }
374 
stop()375 status_t MediaPlayer::stop()
376 {
377     ALOGV("stop");
378     Mutex::Autolock _l(mLock);
379     if (mCurrentState & MEDIA_PLAYER_STOPPED) return NO_ERROR;
380     if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
381                     MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
382         status_t ret = mPlayer->stop();
383         if (ret != NO_ERROR) {
384             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
385         } else {
386             mCurrentState = MEDIA_PLAYER_STOPPED;
387         }
388         return ret;
389     }
390     ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
391     return INVALID_OPERATION;
392 }
393 
pause()394 status_t MediaPlayer::pause()
395 {
396     ALOGV("pause");
397     Mutex::Autolock _l(mLock);
398     if (mCurrentState & (MEDIA_PLAYER_PAUSED|MEDIA_PLAYER_PLAYBACK_COMPLETE))
399         return NO_ERROR;
400     if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) {
401         status_t ret = mPlayer->pause();
402         if (ret != NO_ERROR) {
403             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
404         } else {
405             mCurrentState = MEDIA_PLAYER_PAUSED;
406         }
407         return ret;
408     }
409     ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
410     return INVALID_OPERATION;
411 }
412 
isPlaying()413 bool MediaPlayer::isPlaying()
414 {
415     Mutex::Autolock _l(mLock);
416     if (mPlayer != 0) {
417         bool temp = false;
418         mPlayer->isPlaying(&temp);
419         ALOGV("isPlaying: %d", temp);
420         if ((mCurrentState & MEDIA_PLAYER_STARTED) && ! temp) {
421             ALOGE("internal/external state mismatch corrected");
422             mCurrentState = MEDIA_PLAYER_PAUSED;
423         } else if ((mCurrentState & MEDIA_PLAYER_PAUSED) && temp) {
424             ALOGE("internal/external state mismatch corrected");
425             mCurrentState = MEDIA_PLAYER_STARTED;
426         }
427         return temp;
428     }
429     ALOGV("isPlaying: no active player");
430     return false;
431 }
432 
setPlaybackSettings(const AudioPlaybackRate & rate)433 status_t MediaPlayer::setPlaybackSettings(const AudioPlaybackRate& rate)
434 {
435     ALOGV("setPlaybackSettings: %f %f %d %d",
436             rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
437     // Negative speed and pitch does not make sense. Further validation will
438     // be done by the respective mediaplayers.
439     if (rate.mSpeed < 0.f || rate.mPitch < 0.f) {
440         return BAD_VALUE;
441     }
442     Mutex::Autolock _l(mLock);
443     if (mPlayer == 0 || (mCurrentState & MEDIA_PLAYER_STOPPED)) {
444         return INVALID_OPERATION;
445     }
446 
447     if (rate.mSpeed != 0.f && !(mCurrentState & MEDIA_PLAYER_STARTED)
448             && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED
449                     | MEDIA_PLAYER_PLAYBACK_COMPLETE))) {
450         mPlayer->setLooping(mLoop);
451         mPlayer->setVolume(mLeftVolume, mRightVolume);
452         mPlayer->setAuxEffectSendLevel(mSendLevel);
453     }
454 
455     status_t err = mPlayer->setPlaybackSettings(rate);
456     if (err == OK) {
457         if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER_STARTED) {
458             mCurrentState = MEDIA_PLAYER_PAUSED;
459         } else if (rate.mSpeed != 0.f
460                 && (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED
461                     | MEDIA_PLAYER_PLAYBACK_COMPLETE))) {
462             mCurrentState = MEDIA_PLAYER_STARTED;
463         }
464     }
465     return err;
466 }
467 
getPlaybackSettings(AudioPlaybackRate * rate)468 status_t MediaPlayer::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
469 {
470     Mutex::Autolock _l(mLock);
471     if (mPlayer == 0) return INVALID_OPERATION;
472     return mPlayer->getPlaybackSettings(rate);
473 }
474 
setSyncSettings(const AVSyncSettings & sync,float videoFpsHint)475 status_t MediaPlayer::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
476 {
477     ALOGV("setSyncSettings: %u %u %f %f",
478             sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
479     Mutex::Autolock _l(mLock);
480     if (mPlayer == 0) return INVALID_OPERATION;
481     return mPlayer->setSyncSettings(sync, videoFpsHint);
482 }
483 
getSyncSettings(AVSyncSettings * sync,float * videoFps)484 status_t MediaPlayer::getSyncSettings(
485         AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
486 {
487     Mutex::Autolock _l(mLock);
488     if (mPlayer == 0) return INVALID_OPERATION;
489     return mPlayer->getSyncSettings(sync, videoFps);
490 }
491 
getVideoWidth(int * w)492 status_t MediaPlayer::getVideoWidth(int *w)
493 {
494     ALOGV("getVideoWidth");
495     Mutex::Autolock _l(mLock);
496     if (mPlayer == 0) return INVALID_OPERATION;
497     *w = mVideoWidth;
498     return NO_ERROR;
499 }
500 
getVideoHeight(int * h)501 status_t MediaPlayer::getVideoHeight(int *h)
502 {
503     ALOGV("getVideoHeight");
504     Mutex::Autolock _l(mLock);
505     if (mPlayer == 0) return INVALID_OPERATION;
506     *h = mVideoHeight;
507     return NO_ERROR;
508 }
509 
getCurrentPosition(int * msec)510 status_t MediaPlayer::getCurrentPosition(int *msec)
511 {
512     ALOGV("getCurrentPosition");
513     Mutex::Autolock _l(mLock);
514     if (mPlayer != 0) {
515         if (mCurrentPosition >= 0) {
516             ALOGV("Using cached seek position: %d", mCurrentPosition);
517             *msec = mCurrentPosition;
518             return NO_ERROR;
519         }
520         return mPlayer->getCurrentPosition(msec);
521     }
522     return INVALID_OPERATION;
523 }
524 
getDuration_l(int * msec)525 status_t MediaPlayer::getDuration_l(int *msec)
526 {
527     ALOGV("getDuration_l");
528     bool isValidState = (mCurrentState & (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
529             MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_STOPPED | MEDIA_PLAYER_PLAYBACK_COMPLETE));
530     if (mPlayer != 0 && isValidState) {
531         int durationMs;
532         status_t ret = mPlayer->getDuration(&durationMs);
533 
534         if (ret != OK) {
535             // Do not enter error state just because no duration was available.
536             durationMs = -1;
537             ret = OK;
538         }
539 
540         if (msec) {
541             *msec = durationMs;
542         }
543         return ret;
544     }
545     ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
546             mPlayer.get(), mCurrentState);
547     return INVALID_OPERATION;
548 }
549 
getDuration(int * msec)550 status_t MediaPlayer::getDuration(int *msec)
551 {
552     Mutex::Autolock _l(mLock);
553     return getDuration_l(msec);
554 }
555 
seekTo_l(int msec,MediaPlayerSeekMode mode)556 status_t MediaPlayer::seekTo_l(int msec, MediaPlayerSeekMode mode)
557 {
558     ALOGV("seekTo (%d, %d)", msec, mode);
559     if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
560             MEDIA_PLAYER_PAUSED |  MEDIA_PLAYER_PLAYBACK_COMPLETE) ) ) {
561         if ( msec < 0 ) {
562             ALOGW("Attempt to seek to invalid position: %d", msec);
563             msec = 0;
564         }
565 
566         int durationMs;
567         status_t err = mPlayer->getDuration(&durationMs);
568 
569         if (err != OK) {
570             ALOGW("Stream has no duration and is therefore not seekable.");
571             return err;
572         }
573 
574         if (msec > durationMs) {
575             ALOGW("Attempt to seek to past end of file: request = %d, "
576                   "durationMs = %d",
577                   msec,
578                   durationMs);
579 
580             msec = durationMs;
581         }
582 
583         // cache duration
584         mCurrentPosition = msec;
585         mCurrentSeekMode = mode;
586         if (mSeekPosition < 0) {
587             mSeekPosition = msec;
588             mSeekMode = mode;
589             return mPlayer->seekTo(msec, mode);
590         }
591         else {
592             ALOGV("Seek in progress - queue up seekTo[%d, %d]", msec, mode);
593             return NO_ERROR;
594         }
595     }
596     ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(),
597             mCurrentState);
598     return INVALID_OPERATION;
599 }
600 
seekTo(int msec,MediaPlayerSeekMode mode)601 status_t MediaPlayer::seekTo(int msec, MediaPlayerSeekMode mode)
602 {
603     mLockThreadId = getThreadId();
604     Mutex::Autolock _l(mLock);
605     status_t result = seekTo_l(msec, mode);
606     mLockThreadId = 0;
607 
608     return result;
609 }
610 
reset_l()611 status_t MediaPlayer::reset_l()
612 {
613     mLoop = false;
614     if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
615     mPrepareSync = false;
616     if (mPlayer != 0) {
617         status_t ret = mPlayer->reset();
618         if (ret != NO_ERROR) {
619             ALOGE("reset() failed with return code (%d)", ret);
620             mCurrentState = MEDIA_PLAYER_STATE_ERROR;
621         } else {
622             mPlayer->disconnect();
623             mCurrentState = MEDIA_PLAYER_IDLE;
624         }
625         // setDataSource has to be called again to create a
626         // new mediaplayer.
627         mPlayer = 0;
628         mCurrentBufferingSettings = BufferingSettings();
629         return ret;
630     }
631     clear_l();
632     return NO_ERROR;
633 }
634 
doSetRetransmitEndpoint(const sp<IMediaPlayer> & player)635 status_t MediaPlayer::doSetRetransmitEndpoint(const sp<IMediaPlayer>& player) {
636     Mutex::Autolock _l(mLock);
637 
638     if (player == NULL) {
639         return UNKNOWN_ERROR;
640     }
641 
642     if (mRetransmitEndpointValid) {
643         return player->setRetransmitEndpoint(&mRetransmitEndpoint);
644     }
645 
646     return OK;
647 }
648 
reset()649 status_t MediaPlayer::reset()
650 {
651     ALOGV("reset");
652     Mutex::Autolock _l(mLock);
653     return reset_l();
654 }
655 
setAudioStreamType(audio_stream_type_t type)656 status_t MediaPlayer::setAudioStreamType(audio_stream_type_t type)
657 {
658     ALOGV("MediaPlayer::setAudioStreamType");
659     Mutex::Autolock _l(mLock);
660     if (mStreamType == type) return NO_ERROR;
661     if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
662                 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) {
663         // Can't change the stream type after prepare
664         ALOGE("setAudioStream called in state %d", mCurrentState);
665         return INVALID_OPERATION;
666     }
667     // cache
668     mStreamType = type;
669     return OK;
670 }
671 
getAudioStreamType(audio_stream_type_t * type)672 status_t MediaPlayer::getAudioStreamType(audio_stream_type_t *type)
673 {
674     ALOGV("getAudioStreamType");
675     Mutex::Autolock _l(mLock);
676     *type = mStreamType;
677     return OK;
678 }
679 
setLooping(int loop)680 status_t MediaPlayer::setLooping(int loop)
681 {
682     ALOGV("MediaPlayer::setLooping");
683     Mutex::Autolock _l(mLock);
684     mLoop = (loop != 0);
685     if (mPlayer != 0) {
686         return mPlayer->setLooping(loop);
687     }
688     return OK;
689 }
690 
isLooping()691 bool MediaPlayer::isLooping() {
692     ALOGV("isLooping");
693     Mutex::Autolock _l(mLock);
694     if (mPlayer != 0) {
695         return mLoop;
696     }
697     ALOGV("isLooping: no active player");
698     return false;
699 }
700 
setVolume(float leftVolume,float rightVolume)701 status_t MediaPlayer::setVolume(float leftVolume, float rightVolume)
702 {
703     ALOGV("MediaPlayer::setVolume(%f, %f)", leftVolume, rightVolume);
704     Mutex::Autolock _l(mLock);
705     mLeftVolume = leftVolume;
706     mRightVolume = rightVolume;
707     if (mPlayer != 0) {
708         return mPlayer->setVolume(leftVolume, rightVolume);
709     }
710     return OK;
711 }
712 
setAudioSessionId(audio_session_t sessionId)713 status_t MediaPlayer::setAudioSessionId(audio_session_t sessionId)
714 {
715     ALOGV("MediaPlayer::setAudioSessionId(%d)", sessionId);
716     Mutex::Autolock _l(mLock);
717     if (!(mCurrentState & MEDIA_PLAYER_IDLE)) {
718         ALOGE("setAudioSessionId called in state %d", mCurrentState);
719         return INVALID_OPERATION;
720     }
721     if (sessionId < 0) {
722         return BAD_VALUE;
723     }
724     if (sessionId != mAudioSessionId) {
725         AudioSystem::acquireAudioSessionId(sessionId, -1);
726         AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
727         mAudioSessionId = sessionId;
728     }
729     return NO_ERROR;
730 }
731 
getAudioSessionId()732 audio_session_t MediaPlayer::getAudioSessionId()
733 {
734     Mutex::Autolock _l(mLock);
735     return mAudioSessionId;
736 }
737 
setAuxEffectSendLevel(float level)738 status_t MediaPlayer::setAuxEffectSendLevel(float level)
739 {
740     ALOGV("MediaPlayer::setAuxEffectSendLevel(%f)", level);
741     Mutex::Autolock _l(mLock);
742     mSendLevel = level;
743     if (mPlayer != 0) {
744         return mPlayer->setAuxEffectSendLevel(level);
745     }
746     return OK;
747 }
748 
attachAuxEffect(int effectId)749 status_t MediaPlayer::attachAuxEffect(int effectId)
750 {
751     ALOGV("MediaPlayer::attachAuxEffect(%d)", effectId);
752     Mutex::Autolock _l(mLock);
753     if (mPlayer == 0 ||
754         (mCurrentState & MEDIA_PLAYER_IDLE) ||
755         (mCurrentState == MEDIA_PLAYER_STATE_ERROR )) {
756         ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
757         return INVALID_OPERATION;
758     }
759 
760     return mPlayer->attachAuxEffect(effectId);
761 }
762 
763 // always call with lock held
checkStateForKeySet_l(int key)764 status_t MediaPlayer::checkStateForKeySet_l(int key)
765 {
766     switch(key) {
767     case KEY_PARAMETER_AUDIO_ATTRIBUTES:
768         if (mCurrentState & ( MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_STARTED |
769                 MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE) ) {
770             // Can't change the audio attributes after prepare
771             ALOGE("trying to set audio attributes called in state %d", mCurrentState);
772             return INVALID_OPERATION;
773         }
774         break;
775     default:
776         // parameter doesn't require player state check
777         break;
778     }
779     return OK;
780 }
781 
setParameter(int key,const Parcel & request)782 status_t MediaPlayer::setParameter(int key, const Parcel& request)
783 {
784     ALOGV("MediaPlayer::setParameter(%d)", key);
785     status_t status = INVALID_OPERATION;
786     Mutex::Autolock _l(mLock);
787     if (checkStateForKeySet_l(key) != OK) {
788         return status;
789     }
790     switch (key) {
791     case KEY_PARAMETER_AUDIO_ATTRIBUTES:
792         // save the marshalled audio attributes
793         if (mAudioAttributesParcel != NULL) { delete mAudioAttributesParcel; };
794         mAudioAttributesParcel = new Parcel();
795         mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
796         status = OK;
797         break;
798     default:
799         ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
800         break;
801     }
802 
803     if (mPlayer != NULL) {
804         status = mPlayer->setParameter(key, request);
805     }
806     return status;
807 }
808 
getParameter(int key,Parcel * reply)809 status_t MediaPlayer::getParameter(int key, Parcel *reply)
810 {
811     ALOGV("MediaPlayer::getParameter(%d)", key);
812     Mutex::Autolock _l(mLock);
813     if (mPlayer != NULL) {
814         status_t status =  mPlayer->getParameter(key, reply);
815         if (status != OK) {
816             ALOGD("getParameter returns %d", status);
817         }
818         return status;
819     }
820     ALOGV("getParameter: no active player");
821     return INVALID_OPERATION;
822 }
823 
setRetransmitEndpoint(const char * addrString,uint16_t port)824 status_t MediaPlayer::setRetransmitEndpoint(const char* addrString,
825                                             uint16_t port) {
826     ALOGV("MediaPlayer::setRetransmitEndpoint(%s:%hu)",
827             addrString ? addrString : "(null)", port);
828 
829     Mutex::Autolock _l(mLock);
830     if ((mPlayer != NULL) || (mCurrentState != MEDIA_PLAYER_IDLE))
831         return INVALID_OPERATION;
832 
833     if (NULL == addrString) {
834         mRetransmitEndpointValid = false;
835         return OK;
836     }
837 
838     struct in_addr saddr;
839     if(!inet_aton(addrString, &saddr)) {
840         return BAD_VALUE;
841     }
842 
843     memset(&mRetransmitEndpoint, 0, sizeof(mRetransmitEndpoint));
844     mRetransmitEndpoint.sin_family = AF_INET;
845     mRetransmitEndpoint.sin_addr   = saddr;
846     mRetransmitEndpoint.sin_port   = htons(port);
847     mRetransmitEndpointValid       = true;
848 
849     return OK;
850 }
851 
notify(int msg,int ext1,int ext2,const Parcel * obj)852 void MediaPlayer::notify(int msg, int ext1, int ext2, const Parcel *obj)
853 {
854     ALOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
855     bool send = true;
856     bool locked = false;
857 
858     // TODO: In the future, we might be on the same thread if the app is
859     // running in the same process as the media server. In that case,
860     // this will deadlock.
861     //
862     // The threadId hack below works around this for the care of prepare,
863     // seekTo and start within the same process.
864     // FIXME: Remember, this is a hack, it's not even a hack that is applied
865     // consistently for all use-cases, this needs to be revisited.
866     if (mLockThreadId != getThreadId()) {
867         mLock.lock();
868         locked = true;
869     }
870 
871     // Allows calls from JNI in idle state to notify errors
872     if (!(msg == MEDIA_ERROR && mCurrentState == MEDIA_PLAYER_IDLE) && mPlayer == 0) {
873         ALOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);
874         if (locked) mLock.unlock();   // release the lock when done.
875         return;
876     }
877 
878     switch (msg) {
879     case MEDIA_NOP: // interface test message
880         break;
881     case MEDIA_PREPARED:
882         ALOGV("MediaPlayer::notify() prepared");
883         mCurrentState = MEDIA_PLAYER_PREPARED;
884         if (mPrepareSync) {
885             ALOGV("signal application thread");
886             mPrepareSync = false;
887             mPrepareStatus = NO_ERROR;
888             mSignal.signal();
889         }
890         break;
891     case MEDIA_DRM_INFO:
892         ALOGV("MediaPlayer::notify() MEDIA_DRM_INFO(%d, %d, %d, %p)", msg, ext1, ext2, obj);
893         break;
894     case MEDIA_PLAYBACK_COMPLETE:
895         ALOGV("playback complete");
896         if (mCurrentState == MEDIA_PLAYER_IDLE) {
897             ALOGE("playback complete in idle state");
898         }
899         if (!mLoop) {
900             mCurrentState = MEDIA_PLAYER_PLAYBACK_COMPLETE;
901         }
902         break;
903     case MEDIA_ERROR:
904         // Always log errors.
905         // ext1: Media framework error code.
906         // ext2: Implementation dependant error code.
907         ALOGE("error (%d, %d)", ext1, ext2);
908         mCurrentState = MEDIA_PLAYER_STATE_ERROR;
909         if (mPrepareSync)
910         {
911             ALOGV("signal application thread");
912             mPrepareSync = false;
913             mPrepareStatus = ext1;
914             mSignal.signal();
915             send = false;
916         }
917         break;
918     case MEDIA_INFO:
919         // ext1: Media framework error code.
920         // ext2: Implementation dependant error code.
921         if (ext1 != MEDIA_INFO_VIDEO_TRACK_LAGGING) {
922             ALOGW("info/warning (%d, %d)", ext1, ext2);
923         }
924         break;
925     case MEDIA_SEEK_COMPLETE:
926         ALOGV("Received seek complete");
927         if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) {
928             ALOGV("Executing queued seekTo(%d, %d)", mCurrentPosition, mCurrentSeekMode);
929             mSeekPosition = -1;
930             mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
931             seekTo_l(mCurrentPosition, mCurrentSeekMode);
932         }
933         else {
934             ALOGV("All seeks complete - return to regularly scheduled program");
935             mCurrentPosition = mSeekPosition = -1;
936             mCurrentSeekMode = mSeekMode = MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC;
937         }
938         break;
939     case MEDIA_BUFFERING_UPDATE:
940         ALOGV("buffering %d", ext1);
941         break;
942     case MEDIA_SET_VIDEO_SIZE:
943         ALOGV("New video size %d x %d", ext1, ext2);
944         mVideoWidth = ext1;
945         mVideoHeight = ext2;
946         break;
947     case MEDIA_TIMED_TEXT:
948         ALOGV("Received timed text message");
949         break;
950     case MEDIA_SUBTITLE_DATA:
951         ALOGV("Received subtitle data message");
952         break;
953     case MEDIA_META_DATA:
954         ALOGV("Received timed metadata message");
955         break;
956     default:
957         ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
958         break;
959     }
960 
961     sp<MediaPlayerListener> listener = mListener;
962     if (locked) mLock.unlock();
963 
964     // this prevents re-entrant calls into client code
965     if ((listener != 0) && send) {
966         Mutex::Autolock _l(mNotifyLock);
967         ALOGV("callback application");
968         listener->notify(msg, ext1, ext2, obj);
969         ALOGV("back from callback");
970     }
971 }
972 
died()973 void MediaPlayer::died()
974 {
975     ALOGV("died");
976     notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
977 }
978 
setNextMediaPlayer(const sp<MediaPlayer> & next)979 status_t MediaPlayer::setNextMediaPlayer(const sp<MediaPlayer>& next) {
980     Mutex::Autolock _l(mLock);
981     if (mPlayer == NULL) {
982         return NO_INIT;
983     }
984 
985     if (next != NULL && !(next->mCurrentState &
986             (MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE))) {
987         ALOGE("next player is not prepared");
988         return INVALID_OPERATION;
989     }
990 
991     return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer);
992 }
993 
applyVolumeShaper(const sp<VolumeShaper::Configuration> & configuration,const sp<VolumeShaper::Operation> & operation)994 VolumeShaper::Status MediaPlayer::applyVolumeShaper(
995         const sp<VolumeShaper::Configuration>& configuration,
996         const sp<VolumeShaper::Operation>& operation)
997 {
998     Mutex::Autolock _l(mLock);
999     if (mPlayer == nullptr) {
1000         return VolumeShaper::Status(NO_INIT);
1001     }
1002     VolumeShaper::Status status = mPlayer->applyVolumeShaper(configuration, operation);
1003     return status;
1004 }
1005 
getVolumeShaperState(int id)1006 sp<VolumeShaper::State> MediaPlayer::getVolumeShaperState(int id)
1007 {
1008     Mutex::Autolock _l(mLock);
1009     if (mPlayer == nullptr) {
1010         return nullptr;
1011     }
1012     return mPlayer->getVolumeShaperState(id);
1013 }
1014 
1015 // Modular DRM
prepareDrm(const uint8_t uuid[16],const Vector<uint8_t> & drmSessionId)1016 status_t MediaPlayer::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
1017 {
1018     // TODO change to ALOGV
1019     ALOGD("prepareDrm: uuid: %p  drmSessionId: %p(%zu)", uuid,
1020             drmSessionId.array(), drmSessionId.size());
1021     Mutex::Autolock _l(mLock);
1022     if (mPlayer == NULL) {
1023         return NO_INIT;
1024     }
1025 
1026     // Only allowed it in player's preparing/prepared state.
1027     // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or
1028     // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
1029     // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
1030     if (!(mCurrentState & (MEDIA_PLAYER_PREPARING | MEDIA_PLAYER_PREPARED))) {
1031         ALOGE("prepareDrm is called in the wrong state (%d).", mCurrentState);
1032         return INVALID_OPERATION;
1033     }
1034 
1035     if (drmSessionId.isEmpty()) {
1036         ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId.");
1037         return INVALID_OPERATION;
1038     }
1039 
1040     // Passing down to mediaserver mainly for creating the crypto
1041     status_t status = mPlayer->prepareDrm(uuid, drmSessionId);
1042     ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);
1043 
1044     // TODO change to ALOGV
1045     ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status);
1046 
1047     return status;
1048 }
1049 
releaseDrm()1050 status_t MediaPlayer::releaseDrm()
1051 {
1052     Mutex::Autolock _l(mLock);
1053     if (mPlayer == NULL) {
1054         return NO_INIT;
1055     }
1056 
1057     // Not allowing releaseDrm in an active/resumable state
1058     if (mCurrentState & (MEDIA_PLAYER_STARTED |
1059                          MEDIA_PLAYER_PAUSED |
1060                          MEDIA_PLAYER_PLAYBACK_COMPLETE |
1061                          MEDIA_PLAYER_STATE_ERROR)) {
1062         ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState);
1063         return INVALID_OPERATION;
1064     }
1065 
1066     status_t status = mPlayer->releaseDrm();
1067     // TODO change to ALOGV
1068     ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
1069     if (status != OK) {
1070         ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status);
1071         // Overriding to OK so the client proceed with its own cleanup
1072         // Client can't do more cleanup. mediaserver release its crypto at end of session anyway.
1073         status = OK;
1074     }
1075 
1076     return status;
1077 }
1078 
1079 } // namespace android
1080