mediaplayer2.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261
  1. /*
  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. //#define LOG_NDEBUG 0
  18. #define LOG_TAG "MediaPlayer2Native"
  19. #include <android/binder_ibinder.h>
  20. #include <media/AudioSystem.h>
  21. #include <media/DataSourceDesc.h>
  22. #include <media/MemoryLeakTrackUtil.h>
  23. #include <media/NdkWrapper.h>
  24. #include <media/stagefright/foundation/ADebug.h>
  25. #include <media/stagefright/foundation/ALooperRoster.h>
  26. #include <mediaplayer2/MediaPlayer2AudioOutput.h>
  27. #include <mediaplayer2/mediaplayer2.h>
  28. #include <utils/Log.h>
  29. #include <utils/SortedVector.h>
  30. #include <utils/String8.h>
  31. #include <system/audio.h>
  32. #include <system/window.h>
  33. #include <nuplayer2/NuPlayer2Driver.h>
  34. #include <dirent.h>
  35. #include <sys/stat.h>
  36. namespace android {
  37. extern ALooperRoster gLooperRoster;
  38. namespace {
  39. const int kDumpLockRetries = 50;
  40. const int kDumpLockSleepUs = 20000;
  41. class proxyListener : public MediaPlayer2InterfaceListener {
  42. public:
  43. proxyListener(const wp<MediaPlayer2> &player)
  44. : mPlayer(player) { }
  45. ~proxyListener() { };
  46. virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
  47. const PlayerMessage *obj) override {
  48. sp<MediaPlayer2> player = mPlayer.promote();
  49. if (player != NULL) {
  50. player->notify(srcId, msg, ext1, ext2, obj);
  51. }
  52. }
  53. private:
  54. wp<MediaPlayer2> mPlayer;
  55. };
  56. Mutex sRecordLock;
  57. SortedVector<wp<MediaPlayer2> > *sPlayers;
  58. void ensureInit_l() {
  59. if (sPlayers == NULL) {
  60. sPlayers = new SortedVector<wp<MediaPlayer2> >();
  61. }
  62. }
  63. void addPlayer(const wp<MediaPlayer2>& player) {
  64. Mutex::Autolock lock(sRecordLock);
  65. ensureInit_l();
  66. sPlayers->add(player);
  67. }
  68. void removePlayer(const wp<MediaPlayer2>& player) {
  69. Mutex::Autolock lock(sRecordLock);
  70. ensureInit_l();
  71. sPlayers->remove(player);
  72. }
  73. /**
  74. * The only arguments this understands right now are -c, -von and -voff,
  75. * which are parsed by ALooperRoster::dump()
  76. */
  77. status_t dumpPlayers(int fd, const Vector<String16>& args) {
  78. const size_t SIZE = 256;
  79. char buffer[SIZE];
  80. String8 result;
  81. SortedVector< sp<MediaPlayer2> > players; //to serialise the mutex unlock & client destruction.
  82. {
  83. Mutex::Autolock lock(sRecordLock);
  84. ensureInit_l();
  85. for (int i = 0, n = sPlayers->size(); i < n; ++i) {
  86. sp<MediaPlayer2> p = (*sPlayers)[i].promote();
  87. if (p != 0) {
  88. p->dump(fd, args);
  89. }
  90. players.add(p);
  91. }
  92. }
  93. result.append(" Files opened and/or mapped:\n");
  94. snprintf(buffer, SIZE, "/proc/%d/maps", getpid());
  95. FILE *f = fopen(buffer, "r");
  96. if (f) {
  97. while (!feof(f)) {
  98. fgets(buffer, SIZE, f);
  99. if (strstr(buffer, " /storage/") ||
  100. strstr(buffer, " /system/sounds/") ||
  101. strstr(buffer, " /data/") ||
  102. strstr(buffer, " /system/media/")) {
  103. result.append(" ");
  104. result.append(buffer);
  105. }
  106. }
  107. fclose(f);
  108. } else {
  109. result.append("couldn't open ");
  110. result.append(buffer);
  111. result.append("\n");
  112. }
  113. snprintf(buffer, SIZE, "/proc/%d/fd", getpid());
  114. DIR *d = opendir(buffer);
  115. if (d) {
  116. struct dirent *ent;
  117. while((ent = readdir(d)) != NULL) {
  118. if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
  119. snprintf(buffer, SIZE, "/proc/%d/fd/%s", getpid(), ent->d_name);
  120. struct stat s;
  121. if (lstat(buffer, &s) == 0) {
  122. if ((s.st_mode & S_IFMT) == S_IFLNK) {
  123. char linkto[256];
  124. int len = readlink(buffer, linkto, sizeof(linkto));
  125. if(len > 0) {
  126. if(len > 255) {
  127. linkto[252] = '.';
  128. linkto[253] = '.';
  129. linkto[254] = '.';
  130. linkto[255] = 0;
  131. } else {
  132. linkto[len] = 0;
  133. }
  134. if (strstr(linkto, "/storage/") == linkto ||
  135. strstr(linkto, "/system/sounds/") == linkto ||
  136. strstr(linkto, "/data/") == linkto ||
  137. strstr(linkto, "/system/media/") == linkto) {
  138. result.append(" ");
  139. result.append(buffer);
  140. result.append(" -> ");
  141. result.append(linkto);
  142. result.append("\n");
  143. }
  144. }
  145. } else {
  146. result.append(" unexpected type for ");
  147. result.append(buffer);
  148. result.append("\n");
  149. }
  150. }
  151. }
  152. }
  153. closedir(d);
  154. } else {
  155. result.append("couldn't open ");
  156. result.append(buffer);
  157. result.append("\n");
  158. }
  159. gLooperRoster.dump(fd, args);
  160. bool dumpMem = false;
  161. bool unreachableMemory = false;
  162. for (size_t i = 0; i < args.size(); i++) {
  163. if (args[i] == String16("-m")) {
  164. dumpMem = true;
  165. } else if (args[i] == String16("--unreachable")) {
  166. unreachableMemory = true;
  167. }
  168. }
  169. if (dumpMem) {
  170. result.append("\nDumping memory:\n");
  171. std::string s = dumpMemoryAddresses(100 /* limit */);
  172. result.append(s.c_str(), s.size());
  173. }
  174. if (unreachableMemory) {
  175. result.append("\nDumping unreachable memory:\n");
  176. // TODO - should limit be an argument parameter?
  177. // TODO: enable GetUnreachableMemoryString if it's part of stable API
  178. //std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
  179. //result.append(s.c_str(), s.size());
  180. }
  181. write(fd, result.string(), result.size());
  182. return NO_ERROR;
  183. }
  184. } // anonymous namespace
  185. //static
  186. sp<MediaPlayer2> MediaPlayer2::Create(int32_t sessionId, jobject context) {
  187. sp<MediaPlayer2> player = new MediaPlayer2(sessionId, context);
  188. if (!player->init()) {
  189. return NULL;
  190. }
  191. ALOGV("Create new player(%p)", player.get());
  192. addPlayer(player);
  193. return player;
  194. }
  195. // static
  196. status_t MediaPlayer2::DumpAll(int fd, const Vector<String16>& args) {
  197. return dumpPlayers(fd, args);
  198. }
  199. MediaPlayer2::MediaPlayer2(int32_t sessionId, jobject context) {
  200. ALOGV("constructor");
  201. mSrcId = 0;
  202. mLockThreadId = 0;
  203. mListener = NULL;
  204. mStreamType = AUDIO_STREAM_MUSIC;
  205. mAudioAttributes = NULL;
  206. mContext = new JObjectHolder(context);
  207. mCurrentPosition = -1;
  208. mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
  209. mSeekPosition = -1;
  210. mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
  211. mCurrentState = MEDIA_PLAYER2_IDLE;
  212. mTransitionToNext = false;
  213. mLoop = false;
  214. mVolume = 1.0;
  215. mVideoWidth = mVideoHeight = 0;
  216. mSendLevel = 0;
  217. mPid = AIBinder_getCallingPid();
  218. mUid = AIBinder_getCallingUid();
  219. mAudioOutput = new MediaPlayer2AudioOutput(sessionId, mUid, mPid, NULL /*attributes*/);
  220. }
  221. MediaPlayer2::~MediaPlayer2() {
  222. ALOGV("destructor");
  223. disconnect();
  224. removePlayer(this);
  225. }
  226. bool MediaPlayer2::init() {
  227. // TODO: after merge with NuPlayer2Driver, MediaPlayer2 will have its own
  228. // looper for notification.
  229. return true;
  230. }
  231. void MediaPlayer2::disconnect() {
  232. ALOGV("disconnect");
  233. sp<MediaPlayer2Interface> p;
  234. {
  235. Mutex::Autolock _l(mLock);
  236. p = mPlayer;
  237. mPlayer.clear();
  238. }
  239. if (p != 0) {
  240. p->setListener(NULL);
  241. p->reset();
  242. }
  243. {
  244. Mutex::Autolock _l(mLock);
  245. disconnectNativeWindow_l();
  246. }
  247. }
  248. void MediaPlayer2::clear_l() {
  249. mCurrentPosition = -1;
  250. mCurrentSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
  251. mSeekPosition = -1;
  252. mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
  253. mVideoWidth = mVideoHeight = 0;
  254. }
  255. status_t MediaPlayer2::setListener(const sp<MediaPlayer2Listener>& listener) {
  256. ALOGV("setListener");
  257. Mutex::Autolock _l(mLock);
  258. mListener = listener;
  259. return NO_ERROR;
  260. }
  261. status_t MediaPlayer2::getSrcId(int64_t *srcId) {
  262. if (srcId == NULL) {
  263. return BAD_VALUE;
  264. }
  265. Mutex::Autolock _l(mLock);
  266. *srcId = mSrcId;
  267. return OK;
  268. }
  269. status_t MediaPlayer2::setDataSource(const sp<DataSourceDesc> &dsd) {
  270. if (dsd == NULL) {
  271. return BAD_VALUE;
  272. }
  273. // Microsecond is used in NuPlayer2.
  274. if (dsd->mStartPositionMs > DataSourceDesc::kMaxTimeMs) {
  275. dsd->mStartPositionMs = DataSourceDesc::kMaxTimeMs;
  276. ALOGW("setDataSource, start poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
  277. }
  278. if (dsd->mEndPositionMs > DataSourceDesc::kMaxTimeMs) {
  279. dsd->mEndPositionMs = DataSourceDesc::kMaxTimeMs;
  280. ALOGW("setDataSource, end poistion clamped to %lld ms", (long long)dsd->mStartPositionMs);
  281. }
  282. ALOGV("setDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
  283. sp<MediaPlayer2Interface> oldPlayer;
  284. {
  285. Mutex::Autolock _l(mLock);
  286. if (!((mCurrentState & MEDIA_PLAYER2_IDLE)
  287. || mCurrentState == MEDIA_PLAYER2_STATE_ERROR)) {
  288. ALOGE("setDataSource called in wrong state %d", mCurrentState);
  289. return INVALID_OPERATION;
  290. }
  291. sp<MediaPlayer2Interface> player = new NuPlayer2Driver(mPid, mUid, mContext);
  292. status_t err = player->initCheck();
  293. if (err != NO_ERROR) {
  294. ALOGE("Failed to create player object, initCheck failed(%d)", err);
  295. return err;
  296. }
  297. clear_l();
  298. player->setListener(new proxyListener(this));
  299. player->setAudioSink(mAudioOutput);
  300. err = player->setDataSource(dsd);
  301. if (err != OK) {
  302. ALOGE("setDataSource error: %d", err);
  303. return err;
  304. }
  305. sp<MediaPlayer2Interface> oldPlayer = mPlayer;
  306. mPlayer = player;
  307. mSrcId = dsd->mId;
  308. mCurrentState = MEDIA_PLAYER2_INITIALIZED;
  309. }
  310. if (oldPlayer != NULL) {
  311. oldPlayer->setListener(NULL);
  312. oldPlayer->reset();
  313. }
  314. return OK;
  315. }
  316. status_t MediaPlayer2::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
  317. if (dsd == NULL) {
  318. return BAD_VALUE;
  319. }
  320. ALOGV("prepareNextDataSource type(%d), srcId(%lld)", dsd->mType, (long long)dsd->mId);
  321. Mutex::Autolock _l(mLock);
  322. if (mPlayer == NULL) {
  323. ALOGE("prepareNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
  324. return INVALID_OPERATION;
  325. }
  326. return mPlayer->prepareNextDataSource(dsd);
  327. }
  328. status_t MediaPlayer2::playNextDataSource(int64_t srcId) {
  329. ALOGV("playNextDataSource srcId(%lld)", (long long)srcId);
  330. Mutex::Autolock _l(mLock);
  331. if (mPlayer == NULL) {
  332. ALOGE("playNextDataSource failed: state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
  333. return INVALID_OPERATION;
  334. }
  335. mSrcId = srcId;
  336. mTransitionToNext = true;
  337. return mPlayer->playNextDataSource(srcId);
  338. }
  339. status_t MediaPlayer2::invoke(const PlayerMessage &request, PlayerMessage *reply) {
  340. Mutex::Autolock _l(mLock);
  341. const bool hasBeenInitialized =
  342. (mCurrentState != MEDIA_PLAYER2_STATE_ERROR) &&
  343. ((mCurrentState & MEDIA_PLAYER2_IDLE) != MEDIA_PLAYER2_IDLE);
  344. if ((mPlayer == NULL) || !hasBeenInitialized) {
  345. ALOGE("invoke() failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
  346. return INVALID_OPERATION;
  347. }
  348. return mPlayer->invoke(request, reply);
  349. }
  350. void MediaPlayer2::disconnectNativeWindow_l() {
  351. if (mConnectedWindow != NULL && mConnectedWindow->getANativeWindow() != NULL) {
  352. status_t err = native_window_api_disconnect(
  353. mConnectedWindow->getANativeWindow(), NATIVE_WINDOW_API_MEDIA);
  354. if (err != OK) {
  355. ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
  356. strerror(-err), err);
  357. }
  358. }
  359. mConnectedWindow.clear();
  360. }
  361. status_t MediaPlayer2::setVideoSurfaceTexture(const sp<ANativeWindowWrapper>& nww) {
  362. ANativeWindow *anw = (nww == NULL ? NULL : nww->getANativeWindow());
  363. ALOGV("setVideoSurfaceTexture(%p)", anw);
  364. Mutex::Autolock _l(mLock);
  365. if (mPlayer == 0) {
  366. return NO_INIT;
  367. }
  368. if (anw != NULL) {
  369. if (mConnectedWindow != NULL
  370. && mConnectedWindow->getANativeWindow() == anw) {
  371. return OK;
  372. }
  373. status_t err = native_window_api_connect(anw, NATIVE_WINDOW_API_MEDIA);
  374. if (err != OK) {
  375. ALOGE("setVideoSurfaceTexture failed: %d", err);
  376. // Note that we must do the reset before disconnecting from the ANW.
  377. // Otherwise queue/dequeue calls could be made on the disconnected
  378. // ANW, which may result in errors.
  379. mPlayer->reset();
  380. disconnectNativeWindow_l();
  381. return err;
  382. }
  383. }
  384. // Note that we must set the player's new GraphicBufferProducer before
  385. // disconnecting the old one. Otherwise queue/dequeue calls could be made
  386. // on the disconnected ANW, which may result in errors.
  387. status_t err = mPlayer->setVideoSurfaceTexture(nww);
  388. disconnectNativeWindow_l();
  389. if (err == OK) {
  390. mConnectedWindow = nww;
  391. mLock.unlock();
  392. } else if (anw != NULL) {
  393. mLock.unlock();
  394. status_t err = native_window_api_disconnect(anw, NATIVE_WINDOW_API_MEDIA);
  395. if (err != OK) {
  396. ALOGW("nativeWindowDisconnect returned an error: %s (%d)",
  397. strerror(-err), err);
  398. }
  399. }
  400. return err;
  401. }
  402. status_t MediaPlayer2::getBufferingSettings(BufferingSettings* buffering /* nonnull */) {
  403. ALOGV("getBufferingSettings");
  404. Mutex::Autolock _l(mLock);
  405. if (mPlayer == 0) {
  406. return NO_INIT;
  407. }
  408. status_t ret = mPlayer->getBufferingSettings(buffering);
  409. if (ret == NO_ERROR) {
  410. ALOGV("getBufferingSettings{%s}", buffering->toString().string());
  411. } else {
  412. ALOGE("getBufferingSettings returned %d", ret);
  413. }
  414. return ret;
  415. }
  416. status_t MediaPlayer2::setBufferingSettings(const BufferingSettings& buffering) {
  417. ALOGV("setBufferingSettings{%s}", buffering.toString().string());
  418. Mutex::Autolock _l(mLock);
  419. if (mPlayer == 0) {
  420. return NO_INIT;
  421. }
  422. return mPlayer->setBufferingSettings(buffering);
  423. }
  424. status_t MediaPlayer2::setAudioAttributes_l(const jobject attributes) {
  425. if (mAudioOutput != NULL) {
  426. mAudioOutput->setAudioAttributes(attributes);
  427. }
  428. return NO_ERROR;
  429. }
  430. status_t MediaPlayer2::prepareAsync() {
  431. ALOGV("prepareAsync");
  432. Mutex::Autolock _l(mLock);
  433. if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_INITIALIZED)) {
  434. if (mAudioAttributes != NULL) {
  435. status_t err = setAudioAttributes_l(mAudioAttributes->getJObject());
  436. if (err != OK) {
  437. return err;
  438. }
  439. }
  440. mCurrentState = MEDIA_PLAYER2_PREPARING;
  441. return mPlayer->prepareAsync();
  442. }
  443. ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
  444. return INVALID_OPERATION;
  445. }
  446. status_t MediaPlayer2::start() {
  447. ALOGV("start");
  448. status_t ret = NO_ERROR;
  449. Mutex::Autolock _l(mLock);
  450. mLockThreadId = getThreadId();
  451. if (mCurrentState & MEDIA_PLAYER2_STARTED) {
  452. ret = NO_ERROR;
  453. } else if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER2_PREPARED |
  454. MEDIA_PLAYER2_PLAYBACK_COMPLETE | MEDIA_PLAYER2_PAUSED ) ) ) {
  455. mPlayer->setLooping(mLoop);
  456. if (mAudioOutput != 0) {
  457. mAudioOutput->setVolume(mVolume);
  458. }
  459. if (mAudioOutput != 0) {
  460. mAudioOutput->setAuxEffectSendLevel(mSendLevel);
  461. }
  462. mCurrentState = MEDIA_PLAYER2_STARTED;
  463. ret = mPlayer->start();
  464. if (ret != NO_ERROR) {
  465. mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
  466. } else {
  467. if (mCurrentState == MEDIA_PLAYER2_PLAYBACK_COMPLETE) {
  468. ALOGV("playback completed immediately following start()");
  469. }
  470. }
  471. } else {
  472. ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
  473. ret = INVALID_OPERATION;
  474. }
  475. mLockThreadId = 0;
  476. return ret;
  477. }
  478. status_t MediaPlayer2::pause() {
  479. ALOGV("pause");
  480. Mutex::Autolock _l(mLock);
  481. if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
  482. return NO_ERROR;
  483. if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED))) {
  484. status_t ret = mPlayer->pause();
  485. if (ret != NO_ERROR) {
  486. mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
  487. } else {
  488. mCurrentState = MEDIA_PLAYER2_PAUSED;
  489. mTransitionToNext = false;
  490. }
  491. return ret;
  492. }
  493. ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
  494. return INVALID_OPERATION;
  495. }
  496. bool MediaPlayer2::isPlaying() {
  497. Mutex::Autolock _l(mLock);
  498. if (mPlayer != 0) {
  499. bool temp = mPlayer->isPlaying();
  500. ALOGV("isPlaying: %d", temp);
  501. if ((mCurrentState & MEDIA_PLAYER2_STARTED) && ! temp) {
  502. ALOGE("internal/external state mismatch corrected");
  503. mCurrentState = MEDIA_PLAYER2_PAUSED;
  504. } else if ((mCurrentState & MEDIA_PLAYER2_PAUSED) && temp) {
  505. ALOGE("internal/external state mismatch corrected");
  506. mCurrentState = MEDIA_PLAYER2_STARTED;
  507. }
  508. return temp;
  509. }
  510. ALOGV("isPlaying: no active player");
  511. return false;
  512. }
  513. mediaplayer2_states MediaPlayer2::getState() {
  514. Mutex::Autolock _l(mLock);
  515. if (mCurrentState & MEDIA_PLAYER2_STATE_ERROR) {
  516. return MEDIAPLAYER2_STATE_ERROR;
  517. }
  518. if (mPlayer == 0
  519. || (mCurrentState &
  520. (MEDIA_PLAYER2_IDLE | MEDIA_PLAYER2_INITIALIZED | MEDIA_PLAYER2_PREPARING))) {
  521. return MEDIAPLAYER2_STATE_IDLE;
  522. }
  523. if (mCurrentState & MEDIA_PLAYER2_STARTED) {
  524. return MEDIAPLAYER2_STATE_PLAYING;
  525. }
  526. if (mCurrentState & (MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE)) {
  527. return MEDIAPLAYER2_STATE_PAUSED;
  528. }
  529. // now only mCurrentState & MEDIA_PLAYER2_PREPARED is true
  530. return MEDIAPLAYER2_STATE_PREPARED;
  531. }
  532. status_t MediaPlayer2::setPlaybackSettings(const AudioPlaybackRate& rate) {
  533. ALOGV("setPlaybackSettings: %f %f %d %d",
  534. rate.mSpeed, rate.mPitch, rate.mFallbackMode, rate.mStretchMode);
  535. // Negative speed and pitch does not make sense. Further validation will
  536. // be done by the respective mediaplayers.
  537. if (rate.mSpeed <= 0.f || rate.mPitch < 0.f) {
  538. return BAD_VALUE;
  539. }
  540. Mutex::Autolock _l(mLock);
  541. if (mPlayer == 0) {
  542. return INVALID_OPERATION;
  543. }
  544. status_t err = mPlayer->setPlaybackSettings(rate);
  545. return err;
  546. }
  547. status_t MediaPlayer2::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
  548. Mutex::Autolock _l(mLock);
  549. if (mPlayer == 0) {
  550. return INVALID_OPERATION;
  551. }
  552. status_t ret = mPlayer->getPlaybackSettings(rate);
  553. if (ret == NO_ERROR) {
  554. ALOGV("getPlaybackSettings(%f, %f, %d, %d)",
  555. rate->mSpeed, rate->mPitch, rate->mFallbackMode, rate->mStretchMode);
  556. } else {
  557. ALOGV("getPlaybackSettings returned %d", ret);
  558. }
  559. return ret;
  560. }
  561. status_t MediaPlayer2::setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) {
  562. ALOGV("setSyncSettings: %u %u %f %f",
  563. sync.mSource, sync.mAudioAdjustMode, sync.mTolerance, videoFpsHint);
  564. Mutex::Autolock _l(mLock);
  565. if (mPlayer == 0) return INVALID_OPERATION;
  566. return mPlayer->setSyncSettings(sync, videoFpsHint);
  567. }
  568. status_t MediaPlayer2::getSyncSettings(
  569. AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
  570. Mutex::Autolock _l(mLock);
  571. if (mPlayer == 0) {
  572. return INVALID_OPERATION;
  573. }
  574. status_t ret = mPlayer->getSyncSettings(sync, videoFps);
  575. if (ret == NO_ERROR) {
  576. ALOGV("getSyncSettings(%u, %u, %f, %f)",
  577. sync->mSource, sync->mAudioAdjustMode, sync->mTolerance, *videoFps);
  578. } else {
  579. ALOGV("getSyncSettings returned %d", ret);
  580. }
  581. return ret;
  582. }
  583. status_t MediaPlayer2::getVideoWidth(int *w) {
  584. ALOGV("getVideoWidth");
  585. Mutex::Autolock _l(mLock);
  586. if (mPlayer == 0) {
  587. return INVALID_OPERATION;
  588. }
  589. *w = mVideoWidth;
  590. return NO_ERROR;
  591. }
  592. status_t MediaPlayer2::getVideoHeight(int *h) {
  593. ALOGV("getVideoHeight");
  594. Mutex::Autolock _l(mLock);
  595. if (mPlayer == 0) {
  596. return INVALID_OPERATION;
  597. }
  598. *h = mVideoHeight;
  599. return NO_ERROR;
  600. }
  601. status_t MediaPlayer2::getCurrentPosition(int64_t *msec) {
  602. ALOGV("getCurrentPosition");
  603. Mutex::Autolock _l(mLock);
  604. if (mPlayer == 0) {
  605. return INVALID_OPERATION;
  606. }
  607. if (mCurrentPosition >= 0) {
  608. ALOGV("Using cached seek position: %lld", (long long)mCurrentPosition);
  609. *msec = mCurrentPosition;
  610. return NO_ERROR;
  611. }
  612. status_t ret = mPlayer->getCurrentPosition(msec);
  613. if (ret == NO_ERROR) {
  614. ALOGV("getCurrentPosition = %lld", (long long)*msec);
  615. } else {
  616. ALOGE("getCurrentPosition returned %d", ret);
  617. }
  618. return ret;
  619. }
  620. status_t MediaPlayer2::getDuration(int64_t srcId, int64_t *msec) {
  621. Mutex::Autolock _l(mLock);
  622. // TODO: cache duration for currentSrcId and nextSrcId, and return correct
  623. // value for nextSrcId.
  624. if (srcId != mSrcId) {
  625. *msec = -1;
  626. return OK;
  627. }
  628. ALOGV("getDuration_l");
  629. bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
  630. MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
  631. if (mPlayer == 0 || !isValidState) {
  632. ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
  633. mPlayer.get(), mCurrentState);
  634. return INVALID_OPERATION;
  635. }
  636. int64_t durationMs;
  637. status_t ret = mPlayer->getDuration(&durationMs);
  638. if (ret == NO_ERROR) {
  639. ALOGV("getDuration = %lld", (long long)durationMs);
  640. } else {
  641. ALOGE("getDuration returned %d", ret);
  642. // Do not enter error state just because no duration was available.
  643. durationMs = -1;
  644. }
  645. if (msec) {
  646. *msec = durationMs;
  647. }
  648. return OK;
  649. }
  650. status_t MediaPlayer2::seekTo_l(int64_t msec, MediaPlayer2SeekMode mode) {
  651. ALOGV("seekTo (%lld, %d)", (long long)msec, mode);
  652. if ((mPlayer == 0) || !(mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED |
  653. MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE))) {
  654. ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u",
  655. mPlayer.get(), mCurrentState);
  656. return INVALID_OPERATION;
  657. }
  658. if (msec < 0) {
  659. ALOGW("Attempt to seek to invalid position: %lld", (long long)msec);
  660. msec = 0;
  661. }
  662. int64_t durationMs;
  663. status_t err = mPlayer->getDuration(&durationMs);
  664. if (err != OK) {
  665. ALOGW("Stream has no duration and is therefore not seekable.");
  666. return err;
  667. }
  668. if (msec > durationMs) {
  669. ALOGW("Attempt to seek to past end of file: request = %lld, durationMs = %lld",
  670. (long long)msec, (long long)durationMs);
  671. msec = durationMs;
  672. }
  673. // cache duration
  674. mCurrentPosition = msec;
  675. mCurrentSeekMode = mode;
  676. if (mSeekPosition < 0) {
  677. mSeekPosition = msec;
  678. mSeekMode = mode;
  679. return mPlayer->seekTo(msec, mode);
  680. }
  681. ALOGV("Seek in progress - queue up seekTo[%lld, %d]", (long long)msec, mode);
  682. return NO_ERROR;
  683. }
  684. status_t MediaPlayer2::seekTo(int64_t msec, MediaPlayer2SeekMode mode) {
  685. mLockThreadId = getThreadId();
  686. Mutex::Autolock _l(mLock);
  687. status_t result = seekTo_l(msec, mode);
  688. mLockThreadId = 0;
  689. return result;
  690. }
  691. status_t MediaPlayer2::notifyAt(int64_t mediaTimeUs) {
  692. Mutex::Autolock _l(mLock);
  693. if (mPlayer != 0) {
  694. return INVALID_OPERATION;
  695. }
  696. return mPlayer->notifyAt(mediaTimeUs);
  697. }
  698. status_t MediaPlayer2::reset_l() {
  699. mLoop = false;
  700. if (mCurrentState == MEDIA_PLAYER2_IDLE) {
  701. return NO_ERROR;
  702. }
  703. if (mPlayer != 0) {
  704. status_t ret = mPlayer->reset();
  705. if (ret != NO_ERROR) {
  706. ALOGE("reset() failed with return code (%d)", ret);
  707. mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
  708. } else {
  709. mPlayer->setListener(NULL);
  710. mCurrentState = MEDIA_PLAYER2_IDLE;
  711. mTransitionToNext = false;
  712. }
  713. // setDataSource has to be called again to create a
  714. // new mediaplayer.
  715. mPlayer = 0;
  716. return ret;
  717. }
  718. clear_l();
  719. return NO_ERROR;
  720. }
  721. status_t MediaPlayer2::reset() {
  722. ALOGV("reset");
  723. mLockThreadId = getThreadId();
  724. Mutex::Autolock _l(mLock);
  725. status_t result = reset_l();
  726. mLockThreadId = 0;
  727. return result;
  728. }
  729. status_t MediaPlayer2::setAudioStreamType(audio_stream_type_t type) {
  730. ALOGV("MediaPlayer2::setAudioStreamType");
  731. Mutex::Autolock _l(mLock);
  732. if (mStreamType == type) return NO_ERROR;
  733. if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
  734. MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE ) ) {
  735. // Can't change the stream type after prepare
  736. ALOGE("setAudioStream called in state %d", mCurrentState);
  737. return INVALID_OPERATION;
  738. }
  739. // cache
  740. mStreamType = type;
  741. return OK;
  742. }
  743. status_t MediaPlayer2::getAudioStreamType(audio_stream_type_t *type) {
  744. ALOGV("getAudioStreamType");
  745. Mutex::Autolock _l(mLock);
  746. *type = mStreamType;
  747. return OK;
  748. }
  749. status_t MediaPlayer2::setLooping(int loop) {
  750. ALOGV("MediaPlayer2::setLooping");
  751. Mutex::Autolock _l(mLock);
  752. mLoop = (loop != 0);
  753. if (mPlayer != 0) {
  754. return mPlayer->setLooping(loop);
  755. }
  756. return OK;
  757. }
  758. bool MediaPlayer2::isLooping() {
  759. ALOGV("isLooping");
  760. Mutex::Autolock _l(mLock);
  761. if (mPlayer != 0) {
  762. return mLoop;
  763. }
  764. ALOGV("isLooping: no active player");
  765. return false;
  766. }
  767. status_t MediaPlayer2::setVolume(float volume) {
  768. ALOGV("MediaPlayer2::setVolume(%f)", volume);
  769. Mutex::Autolock _l(mLock);
  770. mVolume = volume;
  771. if (mAudioOutput != 0) {
  772. mAudioOutput->setVolume(volume);
  773. }
  774. return OK;
  775. }
  776. status_t MediaPlayer2::setAudioSessionId(int32_t sessionId) {
  777. ALOGV("MediaPlayer2::setAudioSessionId(%d)", sessionId);
  778. Mutex::Autolock _l(mLock);
  779. if (!(mCurrentState & MEDIA_PLAYER2_IDLE)) {
  780. ALOGE("setAudioSessionId called in state %d", mCurrentState);
  781. return INVALID_OPERATION;
  782. }
  783. if (sessionId < 0) {
  784. return BAD_VALUE;
  785. }
  786. if (mAudioOutput != NULL && sessionId != mAudioOutput->getSessionId()) {
  787. mAudioOutput->setSessionId(sessionId);
  788. }
  789. return NO_ERROR;
  790. }
  791. int32_t MediaPlayer2::getAudioSessionId() {
  792. Mutex::Autolock _l(mLock);
  793. if (mAudioOutput != NULL) {
  794. return mAudioOutput->getSessionId();
  795. }
  796. return 0;
  797. }
  798. status_t MediaPlayer2::setAuxEffectSendLevel(float level) {
  799. ALOGV("MediaPlayer2::setAuxEffectSendLevel(%f)", level);
  800. Mutex::Autolock _l(mLock);
  801. mSendLevel = level;
  802. if (mAudioOutput != 0) {
  803. return mAudioOutput->setAuxEffectSendLevel(level);
  804. }
  805. return OK;
  806. }
  807. status_t MediaPlayer2::attachAuxEffect(int effectId) {
  808. ALOGV("MediaPlayer2::attachAuxEffect(%d)", effectId);
  809. Mutex::Autolock _l(mLock);
  810. if (mAudioOutput == 0 ||
  811. (mCurrentState & MEDIA_PLAYER2_IDLE) ||
  812. (mCurrentState == MEDIA_PLAYER2_STATE_ERROR )) {
  813. ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
  814. return INVALID_OPERATION;
  815. }
  816. return mAudioOutput->attachAuxEffect(effectId);
  817. }
  818. // always call with lock held
  819. status_t MediaPlayer2::checkState_l() {
  820. if (mCurrentState & ( MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
  821. MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE) ) {
  822. // Can't change the audio attributes after prepare
  823. ALOGE("trying to set audio attributes called in state %d", mCurrentState);
  824. return INVALID_OPERATION;
  825. }
  826. return OK;
  827. }
  828. status_t MediaPlayer2::setAudioAttributes(const jobject attributes) {
  829. ALOGV("MediaPlayer2::setAudioAttributes");
  830. status_t status = INVALID_OPERATION;
  831. Mutex::Autolock _l(mLock);
  832. if (checkState_l() != OK) {
  833. return status;
  834. }
  835. mAudioAttributes = new JObjectHolder(attributes);
  836. status = setAudioAttributes_l(attributes);
  837. return status;
  838. }
  839. jobject MediaPlayer2::getAudioAttributes() {
  840. ALOGV("MediaPlayer2::getAudioAttributes)");
  841. Mutex::Autolock _l(mLock);
  842. return mAudioAttributes != NULL ? mAudioAttributes->getJObject() : NULL;
  843. }
  844. status_t MediaPlayer2::getParameter(int key, Parcel *reply) {
  845. ALOGV("MediaPlayer2::getParameter(%d)", key);
  846. Mutex::Autolock _l(mLock);
  847. if (mPlayer == NULL) {
  848. ALOGV("getParameter: no active player");
  849. return INVALID_OPERATION;
  850. }
  851. status_t status = mPlayer->getParameter(key, reply);
  852. if (status != OK) {
  853. ALOGD("getParameter returns %d", status);
  854. }
  855. return status;
  856. }
  857. // for mediametrics
  858. status_t MediaPlayer2::getMetrics(char **buffer, size_t *length) {
  859. ALOGD("MediaPlayer2::getMetrics()");
  860. Mutex::Autolock _l(mLock);
  861. if (mPlayer == NULL) {
  862. ALOGV("getMetrics: no active player");
  863. return INVALID_OPERATION;
  864. }
  865. status_t status = mPlayer->getMetrics(buffer, length);
  866. if (status != OK) {
  867. ALOGD("getMetrics returns %d", status);
  868. }
  869. return status;
  870. }
  871. void MediaPlayer2::notify(int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *obj) {
  872. ALOGV("message received srcId=%lld, msg=%d, ext1=%d, ext2=%d",
  873. (long long)srcId, msg, ext1, ext2);
  874. bool send = true;
  875. bool locked = false;
  876. // TODO: In the future, we might be on the same thread if the app is
  877. // running in the same process as the media server. In that case,
  878. // this will deadlock.
  879. //
  880. // The threadId hack below works around this for the care of prepare,
  881. // seekTo, start, and reset within the same process.
  882. // FIXME: Remember, this is a hack, it's not even a hack that is applied
  883. // consistently for all use-cases, this needs to be revisited.
  884. if (mLockThreadId != getThreadId()) {
  885. mLock.lock();
  886. locked = true;
  887. }
  888. // Allows calls from JNI in idle state to notify errors
  889. if (!(msg == MEDIA2_ERROR && mCurrentState == MEDIA_PLAYER2_IDLE) && mPlayer == 0) {
  890. ALOGV("notify(%lld, %d, %d, %d) callback on disconnected mediaplayer",
  891. (long long)srcId, msg, ext1, ext2);
  892. if (locked) mLock.unlock(); // release the lock when done.
  893. return;
  894. }
  895. switch (msg) {
  896. case MEDIA2_NOP: // interface test message
  897. break;
  898. case MEDIA2_PREPARED:
  899. ALOGV("MediaPlayer2::notify() prepared, srcId=%lld", (long long)srcId);
  900. if (srcId == mSrcId) {
  901. mCurrentState = MEDIA_PLAYER2_PREPARED;
  902. }
  903. break;
  904. case MEDIA2_DRM_INFO:
  905. ALOGV("MediaPlayer2::notify() MEDIA2_DRM_INFO(%lld, %d, %d, %d, %p)",
  906. (long long)srcId, msg, ext1, ext2, obj);
  907. break;
  908. case MEDIA2_PLAYBACK_COMPLETE:
  909. ALOGV("playback complete");
  910. if (mCurrentState == MEDIA_PLAYER2_IDLE) {
  911. ALOGE("playback complete in idle state");
  912. }
  913. if (!mLoop && srcId == mSrcId) {
  914. mCurrentState = MEDIA_PLAYER2_PLAYBACK_COMPLETE;
  915. }
  916. break;
  917. case MEDIA2_ERROR:
  918. // Always log errors.
  919. // ext1: Media framework error code.
  920. // ext2: Implementation dependant error code.
  921. ALOGE("error (%d, %d)", ext1, ext2);
  922. mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
  923. break;
  924. case MEDIA2_INFO:
  925. // ext1: Media framework error code.
  926. // ext2: Implementation dependant error code.
  927. if (ext1 != MEDIA2_INFO_VIDEO_TRACK_LAGGING) {
  928. ALOGW("info/warning (%d, %d)", ext1, ext2);
  929. if (ext1 == MEDIA2_INFO_DATA_SOURCE_START && srcId == mSrcId && mTransitionToNext) {
  930. mCurrentState = MEDIA_PLAYER2_STARTED;
  931. mTransitionToNext = false;
  932. }
  933. }
  934. break;
  935. case MEDIA2_SEEK_COMPLETE:
  936. ALOGV("Received seek complete");
  937. if (mSeekPosition != mCurrentPosition || (mSeekMode != mCurrentSeekMode)) {
  938. ALOGV("Executing queued seekTo(%lld, %d)",
  939. (long long)mCurrentPosition, mCurrentSeekMode);
  940. mSeekPosition = -1;
  941. mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
  942. seekTo_l(mCurrentPosition, mCurrentSeekMode);
  943. }
  944. else {
  945. ALOGV("All seeks complete - return to regularly scheduled program");
  946. mCurrentPosition = mSeekPosition = -1;
  947. mCurrentSeekMode = mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
  948. }
  949. break;
  950. case MEDIA2_BUFFERING_UPDATE:
  951. ALOGV("buffering %d", ext1);
  952. break;
  953. case MEDIA2_SET_VIDEO_SIZE:
  954. ALOGV("New video size %d x %d", ext1, ext2);
  955. mVideoWidth = ext1;
  956. mVideoHeight = ext2;
  957. break;
  958. case MEDIA2_NOTIFY_TIME:
  959. ALOGV("Received notify time message");
  960. break;
  961. case MEDIA2_TIMED_TEXT:
  962. ALOGV("Received timed text message");
  963. break;
  964. case MEDIA2_SUBTITLE_DATA:
  965. ALOGV("Received subtitle data message");
  966. break;
  967. case MEDIA2_META_DATA:
  968. ALOGV("Received timed metadata message");
  969. break;
  970. default:
  971. ALOGV("unrecognized message: (%d, %d, %d)", msg, ext1, ext2);
  972. break;
  973. }
  974. sp<MediaPlayer2Listener> listener = mListener;
  975. if (locked) mLock.unlock();
  976. // this prevents re-entrant calls into client code
  977. if ((listener != 0) && send) {
  978. Mutex::Autolock _l(mNotifyLock);
  979. ALOGV("callback application");
  980. listener->notify(srcId, msg, ext1, ext2, obj);
  981. ALOGV("back from callback");
  982. }
  983. }
  984. // Modular DRM
  985. status_t MediaPlayer2::prepareDrm(
  986. int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t>& drmSessionId) {
  987. // TODO change to ALOGV
  988. ALOGD("prepareDrm: uuid: %p drmSessionId: %p(%zu)", uuid,
  989. drmSessionId.array(), drmSessionId.size());
  990. Mutex::Autolock _l(mLock);
  991. if (mPlayer == NULL) {
  992. return NO_INIT;
  993. }
  994. // Only allowed it in player's preparing/prepared state.
  995. // We get here only if MEDIA_DRM_INFO has already arrived (e.g., prepare is half-way through or
  996. // completed) so the state change to "prepared" might not have happened yet (e.g., buffering).
  997. // Still, we can allow prepareDrm for the use case of being called in OnDrmInfoListener.
  998. if (!(mCurrentState & (MEDIA_PLAYER2_PREPARING | MEDIA_PLAYER2_PREPARED))) {
  999. ALOGW("prepareDrm(%lld) called in non-prepare state(%d)", (long long)srcId, mCurrentState);
  1000. if (srcId == mSrcId) {
  1001. return INVALID_OPERATION;
  1002. }
  1003. }
  1004. if (drmSessionId.isEmpty()) {
  1005. ALOGE("prepareDrm: Unexpected. Can't proceed with crypto. Empty drmSessionId.");
  1006. return INVALID_OPERATION;
  1007. }
  1008. // Passing down to mediaserver mainly for creating the crypto
  1009. status_t status = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
  1010. ALOGE_IF(status != OK, "prepareDrm: Failed at mediaserver with ret: %d", status);
  1011. // TODO change to ALOGV
  1012. ALOGD("prepareDrm: mediaserver::prepareDrm ret=%d", status);
  1013. return status;
  1014. }
  1015. status_t MediaPlayer2::releaseDrm(int64_t srcId) {
  1016. Mutex::Autolock _l(mLock);
  1017. if (mPlayer == NULL) {
  1018. return NO_INIT;
  1019. }
  1020. // Not allowing releaseDrm in an active/resumable state
  1021. if (mCurrentState & (MEDIA_PLAYER2_STARTED |
  1022. MEDIA_PLAYER2_PAUSED |
  1023. MEDIA_PLAYER2_PLAYBACK_COMPLETE |
  1024. MEDIA_PLAYER2_STATE_ERROR)) {
  1025. ALOGE("releaseDrm Unexpected state %d. Can only be called in stopped/idle.", mCurrentState);
  1026. return INVALID_OPERATION;
  1027. }
  1028. status_t status = mPlayer->releaseDrm(srcId);
  1029. // TODO change to ALOGV
  1030. ALOGD("releaseDrm: mediaserver::releaseDrm ret: %d", status);
  1031. if (status != OK) {
  1032. ALOGE("releaseDrm: Failed at mediaserver with ret: %d", status);
  1033. // Overriding to OK so the client proceed with its own cleanup
  1034. // Client can't do more cleanup. mediaserver release its crypto at end of session anyway.
  1035. status = OK;
  1036. }
  1037. return status;
  1038. }
  1039. status_t MediaPlayer2::setPreferredDevice(jobject device) {
  1040. Mutex::Autolock _l(mLock);
  1041. if (mAudioOutput == NULL) {
  1042. ALOGV("setPreferredDevice: audio sink not init");
  1043. return NO_INIT;
  1044. }
  1045. return mAudioOutput->setPreferredDevice(device);
  1046. }
  1047. jobject MediaPlayer2::getRoutedDevice() {
  1048. Mutex::Autolock _l(mLock);
  1049. if (mAudioOutput == NULL) {
  1050. ALOGV("getRoutedDevice: audio sink not init");
  1051. return nullptr;
  1052. }
  1053. return mAudioOutput->getRoutedDevice();
  1054. }
  1055. status_t MediaPlayer2::addAudioDeviceCallback(jobject routingDelegate) {
  1056. Mutex::Autolock _l(mLock);
  1057. if (mAudioOutput == NULL) {
  1058. ALOGV("addAudioDeviceCallback: player not init");
  1059. return NO_INIT;
  1060. }
  1061. return mAudioOutput->addAudioDeviceCallback(routingDelegate);
  1062. }
  1063. status_t MediaPlayer2::removeAudioDeviceCallback(jobject listener) {
  1064. Mutex::Autolock _l(mLock);
  1065. if (mAudioOutput == NULL) {
  1066. ALOGV("addAudioDeviceCallback: player not init");
  1067. return NO_INIT;
  1068. }
  1069. return mAudioOutput->removeAudioDeviceCallback(listener);
  1070. }
  1071. status_t MediaPlayer2::dump(int fd, const Vector<String16>& args) {
  1072. const size_t SIZE = 256;
  1073. char buffer[SIZE];
  1074. String8 result;
  1075. result.append(" MediaPlayer2\n");
  1076. snprintf(buffer, 255, " pid(%d), looping(%s)\n", mPid, mLoop?"true": "false");
  1077. result.append(buffer);
  1078. sp<MediaPlayer2Interface> player;
  1079. sp<MediaPlayer2AudioOutput> audioOutput;
  1080. bool locked = false;
  1081. for (int i = 0; i < kDumpLockRetries; ++i) {
  1082. if (mLock.tryLock() == NO_ERROR) {
  1083. locked = true;
  1084. break;
  1085. }
  1086. usleep(kDumpLockSleepUs);
  1087. }
  1088. if (locked) {
  1089. player = mPlayer;
  1090. audioOutput = mAudioOutput;
  1091. mLock.unlock();
  1092. } else {
  1093. result.append(" lock is taken, no dump from player and audio output\n");
  1094. }
  1095. write(fd, result.string(), result.size());
  1096. if (player != NULL) {
  1097. player->dump(fd, args);
  1098. }
  1099. if (audioOutput != 0) {
  1100. audioOutput->dump(fd, args);
  1101. }
  1102. write(fd, "\n", 1);
  1103. return NO_ERROR;
  1104. }
  1105. } // namespace android