blob: ab302736d74e9abbc6a74d29c498bb443210797a [file] [log] [blame]
Wei Jia53692fa2017-12-11 10:33:46 -08001/*
2**
3** Copyright 2017, 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 "MediaPlayer2Native"
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
Wei Jia53692fa2017-12-11 10:33:46 -080032#include <media/AudioResamplerPublic.h>
33#include <media/AudioSystem.h>
34#include <media/AVSyncSettings.h>
Wei Jiac5c79da2017-12-21 18:03:05 -080035#include <media/DataSource.h>
Wei Jiac2636032018-02-01 09:15:25 -080036#include <media/DataSourceDesc.h>
Wei Jia53692fa2017-12-11 10:33:46 -080037#include <media/MediaAnalyticsItem.h>
Wei Jia28288fb2017-12-15 13:45:29 -080038#include <media/NdkWrapper.h>
Wei Jia51b69562018-02-05 16:17:13 -080039#include <mediaplayer2/mediaplayer2.h>
Wei Jia53692fa2017-12-11 10:33:46 -080040
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#include "MediaPlayer2Manager.h"
50
51namespace android {
52
Wei Jia53692fa2017-12-11 10:33:46 -080053MediaPlayer2::MediaPlayer2()
54{
55 ALOGV("constructor");
Wei Jiad2bb1bd2018-02-08 09:47:37 -080056 mSrcId = 0;
Wei Jia53692fa2017-12-11 10:33:46 -080057 mListener = NULL;
58 mCookie = NULL;
59 mStreamType = AUDIO_STREAM_MUSIC;
60 mAudioAttributesParcel = NULL;
61 mCurrentPosition = -1;
62 mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
63 mSeekPosition = -1;
64 mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
65 mCurrentState = MEDIA_PLAYER2_IDLE;
66 mPrepareSync = false;
67 mPrepareStatus = NO_ERROR;
68 mLoop = false;
69 mLeftVolume = mRightVolume = 1.0;
70 mVideoWidth = mVideoHeight = 0;
71 mLockThreadId = 0;
72 mAudioSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
73 AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
74 mSendLevel = 0;
Wei Jia53692fa2017-12-11 10:33:46 -080075}
76
77MediaPlayer2::~MediaPlayer2()
78{
79 ALOGV("destructor");
80 if (mAudioAttributesParcel != NULL) {
81 delete mAudioAttributesParcel;
82 mAudioAttributesParcel = NULL;
83 }
84 AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
85 disconnect();
86 IPCThreadState::self()->flushCommands();
87}
88
89void MediaPlayer2::disconnect()
90{
91 ALOGV("disconnect");
92 sp<MediaPlayer2Engine> p;
93 {
94 Mutex::Autolock _l(mLock);
95 p = mPlayer;
96 mPlayer.clear();
97 }
98
99 if (p != 0) {
100 p->disconnect();
101 }
102}
103
104// always call with lock held
105void MediaPlayer2::clear_l()
106{
107 mCurrentPosition = -1;
108 mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
109 mSeekPosition = -1;
110 mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
111 mVideoWidth = mVideoHeight = 0;
Wei Jia53692fa2017-12-11 10:33:46 -0800112}
113
114status_t MediaPlayer2::setListener(const sp<MediaPlayer2Listener>& listener)
115{
116 ALOGV("setListener");
117 Mutex::Autolock _l(mLock);
118 mListener = listener;
119 return NO_ERROR;
120}
121
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800122status_t MediaPlayer2::getSrcId(int64_t *srcId) {
123 if (srcId == NULL) {
124 return BAD_VALUE;
125 }
Wei Jia53692fa2017-12-11 10:33:46 -0800126
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800127 Mutex::Autolock _l(mLock);
128 *srcId = mSrcId;
129 return OK;
130}
131
132status_t MediaPlayer2::attachNewPlayer(const sp<MediaPlayer2Engine>& player, long srcId)
Wei Jia53692fa2017-12-11 10:33:46 -0800133{
134 status_t err = UNKNOWN_ERROR;
135 sp<MediaPlayer2Engine> p;
136 { // scope for the lock
137 Mutex::Autolock _l(mLock);
138
139 if ( !( (mCurrentState & MEDIA_PLAYER2_IDLE) ||
140 (mCurrentState == MEDIA_PLAYER2_STATE_ERROR ) ) ) {
141 ALOGE("attachNewPlayer called in state %d", mCurrentState);
142 return INVALID_OPERATION;
143 }
144
145 clear_l();
146 p = mPlayer;
147 mPlayer = player;
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800148 mSrcId = srcId;
Wei Jia53692fa2017-12-11 10:33:46 -0800149 if (player != 0) {
150 mCurrentState = MEDIA_PLAYER2_INITIALIZED;
151 err = NO_ERROR;
152 } else {
153 ALOGE("Unable to create media player");
154 }
155 }
156
157 if (p != 0) {
158 p->disconnect();
159 }
160
161 return err;
162}
163
Wei Jiac2636032018-02-01 09:15:25 -0800164status_t MediaPlayer2::setDataSource(const sp<DataSourceDesc> &dsd)
Wei Jia53692fa2017-12-11 10:33:46 -0800165{
Wei Jiac2636032018-02-01 09:15:25 -0800166 if (dsd == NULL) {
167 return BAD_VALUE;
Wei Jia53692fa2017-12-11 10:33:46 -0800168 }
Wei Jiac2636032018-02-01 09:15:25 -0800169 ALOGV("setDataSource type(%d)", dsd->mType);
Wei Jia53692fa2017-12-11 10:33:46 -0800170 status_t err = UNKNOWN_ERROR;
171 sp<MediaPlayer2Engine> player(MediaPlayer2Manager::get().create(this, mAudioSessionId));
Wei Jia65fdcf72018-02-02 17:43:04 -0800172 if (NO_ERROR != player->setDataSource(dsd)) {
Wei Jia53692fa2017-12-11 10:33:46 -0800173 player.clear();
174 }
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800175 err = attachNewPlayer(player, dsd->mId);
Wei Jia53692fa2017-12-11 10:33:46 -0800176 return err;
177}
178
179status_t MediaPlayer2::invoke(const Parcel& request, Parcel *reply)
180{
181 Mutex::Autolock _l(mLock);
182 const bool hasBeenInitialized =
183 (mCurrentState != MEDIA_PLAYER2_STATE_ERROR) &&
184 ((mCurrentState & MEDIA_PLAYER2_IDLE) != MEDIA_PLAYER2_IDLE);
185 if ((mPlayer != NULL) && hasBeenInitialized) {
186 ALOGV("invoke %zu", request.dataSize());
187 return mPlayer->invoke(request, reply);
188 }
189 ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
190 return INVALID_OPERATION;
191}
192
193status_t MediaPlayer2::setMetadataFilter(const Parcel& filter)
194{
195 ALOGD("setMetadataFilter");
196 Mutex::Autolock lock(mLock);
197 if (mPlayer == NULL) {
198 return NO_INIT;
199 }
200 return mPlayer->setMetadataFilter(filter);
201}
202
203status_t MediaPlayer2::getMetadata(bool update_only, bool apply_filter, Parcel *metadata)
204{
205 ALOGD("getMetadata");
206 Mutex::Autolock lock(mLock);
207 if (mPlayer == NULL) {
208 return NO_INIT;
209 }
210 return mPlayer->getMetadata(update_only, apply_filter, metadata);
211}
212
Wei Jia28288fb2017-12-15 13:45:29 -0800213status_t MediaPlayer2::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww)
Wei Jia53692fa2017-12-11 10:33:46 -0800214{
215 ALOGV("setVideoSurfaceTexture");
216 Mutex::Autolock _l(mLock);
217 if (mPlayer == 0) return NO_INIT;
Wei Jia28288fb2017-12-15 13:45:29 -0800218 return mPlayer->setVideoSurfaceTexture(nww);
Wei Jia53692fa2017-12-11 10:33:46 -0800219}
220
221status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */)
222{
223 ALOGV("getBufferingSettings");
224
225 Mutex::Autolock _l(mLock);
226 if (mPlayer == 0) {
227 return NO_INIT;
228 }
229 return mPlayer->getBufferingSettings(buffering);
230}
231
232status_t MediaPlayer2::setBufferingSettings(const BufferingSettings& buffering)
233{
234 ALOGV("setBufferingSettings");
235
236 Mutex::Autolock _l(mLock);
237 if (mPlayer == 0) {
238 return NO_INIT;
239 }
240 return mPlayer->setBufferingSettings(buffering);
241}
242
243// must call with lock held
244status_t MediaPlayer2::prepareAsync_l()
245{
246 if ( (mPlayer != 0) && ( mCurrentState & (MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_STOPPED) ) ) {
247 if (mAudioAttributesParcel != NULL) {
248 mPlayer->setParameter(MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES, *mAudioAttributesParcel);
249 } else {
250 mPlayer->setAudioStreamType(mStreamType);
251 }
252 mCurrentState = MEDIA_PLAYER2_PREPARING;
253 return mPlayer->prepareAsync();
254 }
255 ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
256 return INVALID_OPERATION;
257}
258
259// TODO: In case of error, prepareAsync provides the caller with 2 error codes,
260// one defined in the Android framework and one provided by the implementation
261// that generated the error. The sync version of prepare returns only 1 error
262// code.
263status_t MediaPlayer2::prepare()
264{
265 ALOGV("prepare");
266 Mutex::Autolock _l(mLock);
267 mLockThreadId = getThreadId();
268 if (mPrepareSync) {
269 mLockThreadId = 0;
270 return -EALREADY;
271 }
272 mPrepareSync = true;
273 status_t ret = prepareAsync_l();
274 if (ret != NO_ERROR) {
275 mLockThreadId = 0;
276 return ret;
277 }
278
279 if (mPrepareSync) {
280 mSignal.wait(mLock); // wait for prepare done
281 mPrepareSync = false;
282 }
283 ALOGV("prepare complete - status=%d", mPrepareStatus);
284 mLockThreadId = 0;
285 return mPrepareStatus;
286}
287
288status_t MediaPlayer2::prepareAsync()
289{
290 ALOGV("prepareAsync");
291 Mutex::Autolock _l(mLock);
292 return prepareAsync_l();
293}
294
295status_t MediaPlayer2::start()
296{
297 ALOGV("start");
298
299 status_t ret = NO_ERROR;
300 Mutex::Autolock _l(mLock);
301
302 mLockThreadId = getThreadId();
303
304 if (mCurrentState & MEDIA_PLAYER2_STARTED) {
305 ret = NO_ERROR;
306 } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_PREPARED |
307 MEDIA_PLAYER2_PLAYBACK_COMPLETE | MEDIA_PLAYER2_PAUSED ) ) ) {
308 mPlayer->setLooping(mLoop);
309 mPlayer->setVolume(mLeftVolume, mRightVolume);
310 mPlayer->setAuxEffectSendLevel(mSendLevel);
311 mCurrentState = MEDIA_PLAYER2_STARTED;
312 ret = mPlayer->start();
313 if (ret != NO_ERROR) {
314 mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
315 } else {
316 if (mCurrentState == MEDIA_PLAYER2_PLAYBACK_COMPLETE) {
317 ALOGV("playback completed immediately following start()");
318 }
319 }
320 } else {
321 ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
322 ret = INVALID_OPERATION;
323 }
324
325 mLockThreadId = 0;
326
327 return ret;
328}
329
330status_t MediaPlayer2::stop()
331{
332 ALOGV("stop");
333 Mutex::Autolock _l(mLock);
334 if (mCurrentState & MEDIA_PLAYER2_STOPPED) return NO_ERROR;
335 if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
336 MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) ) {
337 status_t ret = mPlayer->stop();
338 if (ret != NO_ERROR) {
339 mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
340 } else {
341 mCurrentState = MEDIA_PLAYER2_STOPPED;
342 }
343 return ret;
344 }
345 ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
346 return INVALID_OPERATION;
347}
348
349status_t MediaPlayer2::pause()
350{
351 ALOGV("pause");
352 Mutex::Autolock _l(mLock);
353 if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
354 return NO_ERROR;
355 if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_STARTED)) {
356 status_t ret = mPlayer->pause();
357 if (ret != NO_ERROR) {
358 mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
359 } else {
360 mCurrentState = MEDIA_PLAYER2_PAUSED;
361 }
362 return ret;
363 }
364 ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
365 return INVALID_OPERATION;
366}
367
368bool MediaPlayer2::isPlaying()
369{
370 Mutex::Autolock _l(mLock);
371 if (mPlayer != 0) {
372 bool temp = false;
373 mPlayer->isPlaying(&temp);
374 ALOGV("isPlaying: %d", temp);
375 if ((mCurrentState & MEDIA_PLAYER2_STARTED) && ! temp) {
376 ALOGE("internal/external state mismatch corrected");
377 mCurrentState = MEDIA_PLAYER2_PAUSED;
378 } else if ((mCurrentState & MEDIA_PLAYER2_PAUSED) && temp) {
379 ALOGE("internal/external state mismatch corrected");
380 mCurrentState = MEDIA_PLAYER2_STARTED;
381 }
382 return temp;
383 }
384 ALOGV("isPlaying: no active player");
385 return false;
386}
387
388status_t MediaPlayer2::setPlaybackSettings(const AudioPlaybackRate& rate)
389{
390 ALOGV("setPlaybackSettings: %f %f %d %d",
391 rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
392 // Negative speed and pitch does not make sense. Further validation will
393 // be done by the respective mediaplayers.
394 if (rate.mSpeed < 0.f || rate.mPitch < 0.f) {
395 return BAD_VALUE;
396 }
397 Mutex::Autolock _l(mLock);
398 if (mPlayer == 0 || (mCurrentState & MEDIA_PLAYER2_STOPPED)) {
399 return INVALID_OPERATION;
400 }
401
402 if (rate.mSpeed != 0.f && !(mCurrentState & MEDIA_PLAYER2_STARTED)
403 && (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_PAUSED
404 | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
405 mPlayer->setLooping(mLoop);
406 mPlayer->setVolume(mLeftVolume, mRightVolume);
407 mPlayer->setAuxEffectSendLevel(mSendLevel);
408 }
409
410 status_t err = mPlayer->setPlaybackSettings(rate);
411 if (err == OK) {
412 if (rate.mSpeed == 0.f && mCurrentState == MEDIA_PLAYER2_STARTED) {
413 mCurrentState = MEDIA_PLAYER2_PAUSED;
414 } else if (rate.mSpeed != 0.f
415 && (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_PAUSED
416 | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
417 mCurrentState = MEDIA_PLAYER2_STARTED;
418 }
419 }
420 return err;
421}
422
423status_t MediaPlayer2::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */)
424{
425 Mutex::Autolock _l(mLock);
426 if (mPlayer == 0) return INVALID_OPERATION;
427 return mPlayer->getPlaybackSettings(rate);
428}
429
430status_t MediaPlayer2::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint)
431{
432 ALOGV("setSyncSettings: %u %u %f %f",
433 sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
434 Mutex::Autolock _l(mLock);
435 if (mPlayer == 0) return INVALID_OPERATION;
436 return mPlayer->setSyncSettings(sync, videoFpsHint);
437}
438
439status_t MediaPlayer2::getSyncSettings(
440 AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */)
441{
442 Mutex::Autolock _l(mLock);
443 if (mPlayer == 0) return INVALID_OPERATION;
444 return mPlayer->getSyncSettings(sync, videoFps);
445}
446
447status_t MediaPlayer2::getVideoWidth(int *w)
448{
449 ALOGV("getVideoWidth");
450 Mutex::Autolock _l(mLock);
451 if (mPlayer == 0) return INVALID_OPERATION;
452 *w = mVideoWidth;
453 return NO_ERROR;
454}
455
456status_t MediaPlayer2::getVideoHeight(int *h)
457{
458 ALOGV("getVideoHeight");
459 Mutex::Autolock _l(mLock);
460 if (mPlayer == 0) return INVALID_OPERATION;
461 *h = mVideoHeight;
462 return NO_ERROR;
463}
464
465status_t MediaPlayer2::getCurrentPosition(int *msec)
466{
467 ALOGV("getCurrentPosition");
468 Mutex::Autolock _l(mLock);
469 if (mPlayer != 0) {
470 if (mCurrentPosition >= 0) {
471 ALOGV("Using cached seek position: %d", mCurrentPosition);
472 *msec = mCurrentPosition;
473 return NO_ERROR;
474 }
475 return mPlayer->getCurrentPosition(msec);
476 }
477 return INVALID_OPERATION;
478}
479
480status_t MediaPlayer2::getDuration_l(int *msec)
481{
482 ALOGV("getDuration_l");
483 bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
484 MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_STOPPED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
485 if (mPlayer != 0 && isValidState) {
486 int durationMs;
487 status_t ret = mPlayer->getDuration(&durationMs);
488
489 if (ret != OK) {
490 // Do not enter error state just because no duration was available.
491 durationMs = -1;
492 ret = OK;
493 }
494
495 if (msec) {
496 *msec = durationMs;
497 }
498 return ret;
499 }
500 ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
501 mPlayer.get(), mCurrentState);
502 return INVALID_OPERATION;
503}
504
505status_t MediaPlayer2::getDuration(int *msec)
506{
507 Mutex::Autolock _l(mLock);
508 return getDuration_l(msec);
509}
510
511status_t MediaPlayer2::seekTo_l(int msec, MediaPlayer2SeekMode mode)
512{
513 ALOGV("seekTo (%d, %d)", msec, mode);
514 if ((mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
515 MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) ) {
516 if ( msec < 0 ) {
517 ALOGW("Attempt to seek to invalid position: %d", msec);
518 msec = 0;
519 }
520
521 int durationMs;
522 status_t err = mPlayer->getDuration(&durationMs);
523
524 if (err != OK) {
525 ALOGW("Stream has no duration and is therefore not seekable.");
526 return err;
527 }
528
529 if (msec > durationMs) {
530 ALOGW("Attempt to seek to past end of file: request = %d, "
531 "durationMs = %d",
532 msec,
533 durationMs);
534
535 msec = durationMs;
536 }
537
538 // cache duration
539 mCurrentPosition = msec;
540 mCurrentSeekMode = mode;
541 if (mSeekPosition < 0) {
542 mSeekPosition = msec;
543 mSeekMode = mode;
544 return mPlayer->seekTo(msec, mode);
545 }
546 else {
547 ALOGV("Seek in progress - queue up seekTo[%d, %d]", msec, mode);
548 return NO_ERROR;
549 }
550 }
551 ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(),
552 mCurrentState);
553 return INVALID_OPERATION;
554}
555
556status_t MediaPlayer2::seekTo(int msec, MediaPlayer2SeekMode mode)
557{
558 mLockThreadId = getThreadId();
559 Mutex::Autolock _l(mLock);
560 status_t result = seekTo_l(msec, mode);
561 mLockThreadId = 0;
562
563 return result;
564}
565
566status_t MediaPlayer2::notifyAt(int64_t mediaTimeUs)
567{
568 Mutex::Autolock _l(mLock);
569 if (mPlayer != 0) {
570 return mPlayer->notifyAt(mediaTimeUs);
571 }
572 return INVALID_OPERATION;
573}
574
575status_t MediaPlayer2::reset_l()
576{
577 mLoop = false;
578 if (mCurrentState == MEDIA_PLAYER2_IDLE) return NO_ERROR;
579 mPrepareSync = false;
580 if (mPlayer != 0) {
581 status_t ret = mPlayer->reset();
582 if (ret != NO_ERROR) {
583 ALOGE("reset() failed with return code (%d)", ret);
584 mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
585 } else {
586 mPlayer->disconnect();
587 mCurrentState = MEDIA_PLAYER2_IDLE;
588 }
589 // setDataSource has to be called again to create a
590 // new mediaplayer.
591 mPlayer = 0;
592 return ret;
593 }
594 clear_l();
595 return NO_ERROR;
596}
597
Wei Jia53692fa2017-12-11 10:33:46 -0800598status_t MediaPlayer2::reset()
599{
600 ALOGV("reset");
601 mLockThreadId = getThreadId();
602 Mutex::Autolock _l(mLock);
603 status_t result = reset_l();
604 mLockThreadId = 0;
605
606 return result;
607}
608
609status_t MediaPlayer2::setAudioStreamType(audio_stream_type_t type)
610{
611 ALOGV("MediaPlayer2::setAudioStreamType");
612 Mutex::Autolock _l(mLock);
613 if (mStreamType == type) return NO_ERROR;
614 if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
615 MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) {
616 // Can't change the stream type after prepare
617 ALOGE("setAudioStream called in state %d", mCurrentState);
618 return INVALID_OPERATION;
619 }
620 // cache
621 mStreamType = type;
622 return OK;
623}
624
625status_t MediaPlayer2::getAudioStreamType(audio_stream_type_t *type)
626{
627 ALOGV("getAudioStreamType");
628 Mutex::Autolock _l(mLock);
629 *type = mStreamType;
630 return OK;
631}
632
633status_t MediaPlayer2::setLooping(int loop)
634{
635 ALOGV("MediaPlayer2::setLooping");
636 Mutex::Autolock _l(mLock);
637 mLoop = (loop != 0);
638 if (mPlayer != 0) {
639 return mPlayer->setLooping(loop);
640 }
641 return OK;
642}
643
644bool MediaPlayer2::isLooping() {
645 ALOGV("isLooping");
646 Mutex::Autolock _l(mLock);
647 if (mPlayer != 0) {
648 return mLoop;
649 }
650 ALOGV("isLooping: no active player");
651 return false;
652}
653
654status_t MediaPlayer2::setVolume(float leftVolume, float rightVolume)
655{
656 ALOGV("MediaPlayer2::setVolume(%f, %f)", leftVolume, rightVolume);
657 Mutex::Autolock _l(mLock);
658 mLeftVolume = leftVolume;
659 mRightVolume = rightVolume;
660 if (mPlayer != 0) {
661 return mPlayer->setVolume(leftVolume, rightVolume);
662 }
663 return OK;
664}
665
666status_t MediaPlayer2::setAudioSessionId(audio_session_t sessionId)
667{
668 ALOGV("MediaPlayer2::setAudioSessionId(%d)", sessionId);
669 Mutex::Autolock _l(mLock);
670 if (!(mCurrentState & MEDIA_PLAYER2_IDLE)) {
671 ALOGE("setAudioSessionId called in state %d", mCurrentState);
672 return INVALID_OPERATION;
673 }
674 if (sessionId < 0) {
675 return BAD_VALUE;
676 }
677 if (sessionId != mAudioSessionId) {
678 AudioSystem::acquireAudioSessionId(sessionId, -1);
679 AudioSystem::releaseAudioSessionId(mAudioSessionId, -1);
680 mAudioSessionId = sessionId;
681 }
682 return NO_ERROR;
683}
684
685audio_session_t MediaPlayer2::getAudioSessionId()
686{
687 Mutex::Autolock _l(mLock);
688 return mAudioSessionId;
689}
690
691status_t MediaPlayer2::setAuxEffectSendLevel(float level)
692{
693 ALOGV("MediaPlayer2::setAuxEffectSendLevel(%f)", level);
694 Mutex::Autolock _l(mLock);
695 mSendLevel = level;
696 if (mPlayer != 0) {
697 return mPlayer->setAuxEffectSendLevel(level);
698 }
699 return OK;
700}
701
702status_t MediaPlayer2::attachAuxEffect(int effectId)
703{
704 ALOGV("MediaPlayer2::attachAuxEffect(%d)", effectId);
705 Mutex::Autolock _l(mLock);
706 if (mPlayer == 0 ||
707 (mCurrentState & MEDIA_PLAYER2_IDLE) ||
708 (mCurrentState == MEDIA_PLAYER2_STATE_ERROR )) {
709 ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
710 return INVALID_OPERATION;
711 }
712
713 return mPlayer->attachAuxEffect(effectId);
714}
715
716// always call with lock held
717status_t MediaPlayer2::checkStateForKeySet_l(int key)
718{
719 switch(key) {
720 case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
721 if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
722 MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) {
723 // Can't change the audio attributes after prepare
724 ALOGE("trying to set audio attributes called in state %d", mCurrentState);
725 return INVALID_OPERATION;
726 }
727 break;
728 default:
729 // parameter doesn't require player state check
730 break;
731 }
732 return OK;
733}
734
735status_t MediaPlayer2::setParameter(int key, const Parcel& request)
736{
737 ALOGV("MediaPlayer2::setParameter(%d)", key);
738 status_t status = INVALID_OPERATION;
739 Mutex::Autolock _l(mLock);
740 if (checkStateForKeySet_l(key) != OK) {
741 return status;
742 }
743 switch (key) {
744 case MEDIA2_KEY_PARAMETER_AUDIO_ATTRIBUTES:
745 // save the marshalled audio attributes
746 if (mAudioAttributesParcel != NULL) { delete mAudioAttributesParcel; };
747 mAudioAttributesParcel = new Parcel();
748 mAudioAttributesParcel->appendFrom(&request, 0, request.dataSize());
749 status = OK;
750 break;
751 default:
752 ALOGV_IF(mPlayer == NULL, "setParameter: no active player");
753 break;
754 }
755
756 if (mPlayer != NULL) {
757 status = mPlayer->setParameter(key, request);
758 }
759 return status;
760}
761
762status_t MediaPlayer2::getParameter(int key, Parcel *reply)
763{
764 ALOGV("MediaPlayer2::getParameter(%d)", key);
765 Mutex::Autolock _l(mLock);
766 if (mPlayer != NULL) {
767 status_t status = mPlayer->getParameter(key, reply);
768 if (status != OK) {
769 ALOGD("getParameter returns %d", status);
770 }
771 return status;
772 }
773 ALOGV("getParameter: no active player");
774 return INVALID_OPERATION;
775}
776
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800777void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const Parcel *obj)
Wei Jia53692fa2017-12-11 10:33:46 -0800778{
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800779 ALOGV("message received srcId=%lld, msg=%d, ext1=%d, ext2=%d",
780 (long long)srcId, msg, ext1, ext2);
Wei Jia53692fa2017-12-11 10:33:46 -0800781 bool send = true;
782 bool locked = false;
783
784 // TODO: In the future, we might be on the same thread if the app is
785 // running in the same process as the media server. In that case,
786 // this will deadlock.
787 //
788 // The threadId hack below works around this for the care of prepare,
789 // seekTo, start, and reset within the same process.
790 // FIXME: Remember, this is a hack, it's not even a hack that is applied
791 // consistently for all use-cases, this needs to be revisited.
792 if (mLockThreadId != getThreadId()) {
793 mLock.lock();
794 locked = true;
795 }
796
797 // Allows calls from JNI in idle state to notify errors
798 if (!(msg == MEDIA2_ERROR && mCurrentState == MEDIA_PLAYER2_IDLE) && mPlayer == 0) {
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800799 ALOGV("notify(%lld, %d, %d, %d) callback on disconnected mediaplayer",
800 (long long)srcId, msg, ext1, ext2);
Wei Jia53692fa2017-12-11 10:33:46 -0800801 if (locked) mLock.unlock(); // release the lock when done.
802 return;
803 }
804
805 switch (msg) {
806 case MEDIA2_NOP: // interface test message
807 break;
808 case MEDIA2_PREPARED:
809 ALOGV("MediaPlayer2::notify() prepared");
810 mCurrentState = MEDIA_PLAYER2_PREPARED;
811 if (mPrepareSync) {
812 ALOGV("signal application thread");
813 mPrepareSync = false;
814 mPrepareStatus = NO_ERROR;
815 mSignal.signal();
816 }
817 break;
818 case MEDIA2_DRM_INFO:
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800819 ALOGV("MediaPlayer2::notify() MEDIA2_DRM_INFO(%lld, %d, %d, %d, %p)",
820 (long long)srcId, msg, ext1, ext2, obj);
Wei Jia53692fa2017-12-11 10:33:46 -0800821 break;
822 case MEDIA2_PLAYBACK_COMPLETE:
823 ALOGV("playback complete");
824 if (mCurrentState == MEDIA_PLAYER2_IDLE) {
825 ALOGE("playback complete in idle state");
826 }
827 if (!mLoop) {
828 mCurrentState = MEDIA_PLAYER2_PLAYBACK_COMPLETE;
829 }
830 break;
831 case MEDIA2_ERROR:
832 // Always log errors.
833 // ext1: Media framework error code.
834 // ext2: Implementation dependant error code.
835 ALOGE("error (%d, %d)", ext1, ext2);
836 mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
837 if (mPrepareSync)
838 {
839 ALOGV("signal application thread");
840 mPrepareSync = false;
841 mPrepareStatus = ext1;
842 mSignal.signal();
843 send = false;
844 }
845 break;
846 case MEDIA2_INFO:
847 // ext1: Media framework error code.
848 // ext2: Implementation dependant error code.
849 if (ext1 != MEDIA2_INFO_VIDEO_TRACK_LAGGING) {
850 ALOGW("info/warning (%d, %d)", ext1, ext2);
851 }
852 break;
853 case MEDIA2_SEEK_COMPLETE:
854 ALOGV("Received seek complete");
855 if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) {
856 ALOGV("Executing queued seekTo(%d, %d)", mCurrentPosition, mCurrentSeekMode);
857 mSeekPosition = -1;
858 mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
859 seekTo_l(mCurrentPosition, mCurrentSeekMode);
860 }
861 else {
862 ALOGV("All seeks complete - return to regularly scheduled program");
863 mCurrentPosition = mSeekPosition = -1;
864 mCurrentSeekMode = mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
865 }
866 break;
867 case MEDIA2_BUFFERING_UPDATE:
868 ALOGV("buffering %d", ext1);
869 break;
870 case MEDIA2_SET_VIDEO_SIZE:
871 ALOGV("New video size %d x %d", ext1, ext2);
872 mVideoWidth = ext1;
873 mVideoHeight = ext2;
874 break;
875 case MEDIA2_NOTIFY_TIME:
876 ALOGV("Received notify time message");
877 break;
878 case MEDIA2_TIMED_TEXT:
879 ALOGV("Received timed text message");
880 break;
881 case MEDIA2_SUBTITLE_DATA:
882 ALOGV("Received subtitle data message");
883 break;
884 case MEDIA2_META_DATA:
885 ALOGV("Received timed metadata message");
886 break;
887 default:
888 ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
889 break;
890 }
891
892 sp<MediaPlayer2Listener> listener = mListener;
893 if (locked) mLock.unlock();
894
895 // this prevents re-entrant calls into client code
896 if ((listener != 0) && send) {
897 Mutex::Autolock _l(mNotifyLock);
898 ALOGV("callback application");
Wei Jiad2bb1bd2018-02-08 09:47:37 -0800899 listener->notify(srcId, msg, ext1, ext2, obj);
Wei Jia53692fa2017-12-11 10:33:46 -0800900 ALOGV("back from callback");
901 }
902}
903
904status_t MediaPlayer2::setNextMediaPlayer(const sp<MediaPlayer2>& next) {
905 Mutex::Autolock _l(mLock);
906 if (mPlayer == NULL) {
907 return NO_INIT;
908 }
909
910 if (next != NULL && !(next->mCurrentState &
911 (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
912 ALOGE("next player is not prepared");
913 return INVALID_OPERATION;
914 }
915
916 return mPlayer->setNextPlayer(next == NULL ? NULL : next->mPlayer);
917}
918
Wei Jia53692fa2017-12-11 10:33:46 -0800919// Modular DRM
920status_t MediaPlayer2::prepareDrm(const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId)
921{
922 // TODO change to ALOGV
923 ALOGD("prepareDrm: uuid: %p drmSessionId: %p(%zu)", uuid,
924 drmSessionId.array(), drmSessionId.size());
925 Mutex::Autolock _l(mLock);
926 if (mPlayer == NULL) {
927 return NO_INIT;
928 }
929
930 // Only allowed it in player's preparing/prepared state.
931 // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or
932 // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
933 // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
934 if (!(mCurrentState & (MEDIA_PLAYER2_PREPARING | MEDIA_PLAYER2_PREPARED))) {
935 ALOGE("prepareDrm is called in the wrong state (%d).", mCurrentState);
936 return INVALID_OPERATION;
937 }
938
939 if (drmSessionId.isEmpty()) {
940 ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId.");
941 return INVALID_OPERATION;
942 }
943
944 // Passing down to mediaserver mainly for creating the crypto
945 status_t status = mPlayer->prepareDrm(uuid, drmSessionId);
946 ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);
947
948 // TODO change to ALOGV
949 ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status);
950
951 return status;
952}
953
954status_t MediaPlayer2::releaseDrm()
955{
956 Mutex::Autolock _l(mLock);
957 if (mPlayer == NULL) {
958 return NO_INIT;
959 }
960
961 // Not allowing releaseDrm in an active/resumable state
962 if (mCurrentState & (MEDIA_PLAYER2_STARTED |
963 MEDIA_PLAYER2_PAUSED |
964 MEDIA_PLAYER2_PLAYBACK_COMPLETE |
965 MEDIA_PLAYER2_STATE_ERROR)) {
966 ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState);
967 return INVALID_OPERATION;
968 }
969
970 status_t status = mPlayer->releaseDrm();
971 // TODO change to ALOGV
972 ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
973 if (status != OK) {
974 ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status);
975 // Overriding to OK so the client proceed with its own cleanup
976 // Client can't do more cleanup. mediaserver release its crypto at end of session anyway.
977 status = OK;
978 }
979
980 return status;
981}
982
983status_t MediaPlayer2::setOutputDevice(audio_port_handle_t deviceId)
984{
985 Mutex::Autolock _l(mLock);
986 if (mPlayer == NULL) {
987 ALOGV("setOutputDevice: player not init");
988 return NO_INIT;
989 }
990 return mPlayer->setOutputDevice(deviceId);
991}
992
993audio_port_handle_t MediaPlayer2::getRoutedDeviceId()
994{
995 Mutex::Autolock _l(mLock);
996 if (mPlayer == NULL) {
997 ALOGV("getRoutedDeviceId: player not init");
998 return AUDIO_PORT_HANDLE_NONE;
999 }
1000 audio_port_handle_t deviceId;
1001 status_t status = mPlayer->getRoutedDeviceId(&deviceId);
1002 if (status != NO_ERROR) {
1003 return AUDIO_PORT_HANDLE_NONE;
1004 }
1005 return deviceId;
1006}
1007
1008status_t MediaPlayer2::enableAudioDeviceCallback(bool enabled)
1009{
1010 Mutex::Autolock _l(mLock);
1011 if (mPlayer == NULL) {
1012 ALOGV("addAudioDeviceCallback: player not init");
1013 return NO_INIT;
1014 }
1015 return mPlayer->enableAudioDeviceCallback(enabled);
1016}
1017
1018} // namespace android