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