NuPlayer2Driver.cpp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. /*
  2. * Copyright 2017 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. //#define LOG_NDEBUG 0
  17. #define LOG_TAG "NuPlayer2Driver"
  18. #include <inttypes.h>
  19. #include <android-base/macros.h>
  20. #include <utils/Log.h>
  21. #include <cutils/properties.h>
  22. #include "NuPlayer2Driver.h"
  23. #include "NuPlayer2.h"
  24. #include "NuPlayer2Source.h"
  25. #include <media/DataSourceDesc.h>
  26. #include <media/stagefright/foundation/ADebug.h>
  27. #include <media/stagefright/foundation/ALooper.h>
  28. #include <media/stagefright/foundation/AUtils.h>
  29. #include <media/stagefright/foundation/ByteUtils.h>
  30. #include <media/stagefright/MediaClock.h>
  31. #include <media/stagefright/MetaData.h>
  32. #include <media/stagefright/Utils.h>
  33. #include <media/IMediaAnalyticsService.h>
  34. using google::protobuf::RepeatedPtrField;
  35. using android::media::MediaPlayer2Proto::Value;
  36. static const int kDumpLockRetries = 50;
  37. static const int kDumpLockSleepUs = 20000;
  38. namespace android {
  39. struct PlayerMessageWrapper : public RefBase {
  40. static sp<PlayerMessageWrapper> Create(const PlayerMessage *p) {
  41. if (p != NULL) {
  42. sp<PlayerMessageWrapper> pw = new PlayerMessageWrapper();
  43. pw->copyFrom(p);
  44. return pw;
  45. }
  46. return NULL;
  47. }
  48. const PlayerMessage *getPlayerMessage() {
  49. return mPlayerMessage;
  50. }
  51. protected:
  52. virtual ~PlayerMessageWrapper() {
  53. if (mPlayerMessage != NULL) {
  54. delete mPlayerMessage;
  55. }
  56. }
  57. private:
  58. PlayerMessageWrapper()
  59. : mPlayerMessage(NULL) { }
  60. void copyFrom(const PlayerMessage *p) {
  61. if (mPlayerMessage == NULL) {
  62. mPlayerMessage = new PlayerMessage;
  63. }
  64. mPlayerMessage->CopyFrom(*p);
  65. }
  66. PlayerMessage *mPlayerMessage;
  67. };
  68. // key for media statistics
  69. static const char *kKeyPlayer = "nuplayer2";
  70. // attrs for media statistics
  71. // NB: these are matched with public Java API constants defined
  72. // in frameworks/base/media/java/android/media/MediaPlayer2.java
  73. // These must be kept synchronized with the constants there.
  74. static const char *kPlayerVMime = "android.media.mediaplayer.video.mime";
  75. static const char *kPlayerVCodec = "android.media.mediaplayer.video.codec";
  76. static const char *kPlayerWidth = "android.media.mediaplayer.width";
  77. static const char *kPlayerHeight = "android.media.mediaplayer.height";
  78. static const char *kPlayerFrames = "android.media.mediaplayer.frames";
  79. static const char *kPlayerFramesDropped = "android.media.mediaplayer.dropped";
  80. static const char *kPlayerFrameRate = "android.media.mediaplayer.fps";
  81. static const char *kPlayerAMime = "android.media.mediaplayer.audio.mime";
  82. static const char *kPlayerACodec = "android.media.mediaplayer.audio.codec";
  83. static const char *kPlayerDuration = "android.media.mediaplayer.durationMs";
  84. static const char *kPlayerPlaying = "android.media.mediaplayer.playingMs";
  85. static const char *kPlayerError = "android.media.mediaplayer.err";
  86. static const char *kPlayerErrorCode = "android.media.mediaplayer.errcode";
  87. // NB: These are not yet exposed as public Java API constants.
  88. static const char *kPlayerErrorState = "android.media.mediaplayer.errstate";
  89. static const char *kPlayerDataSourceType = "android.media.mediaplayer.dataSource";
  90. //
  91. static const char *kPlayerRebuffering = "android.media.mediaplayer.rebufferingMs";
  92. static const char *kPlayerRebufferingCount = "android.media.mediaplayer.rebuffers";
  93. static const char *kPlayerRebufferingAtExit = "android.media.mediaplayer.rebufferExit";
  94. static const char *kPlayerVersion = "android.media.mediaplayer.version";
  95. NuPlayer2Driver::NuPlayer2Driver(pid_t pid, uid_t uid, const sp<JObjectHolder> &context)
  96. : mState(STATE_IDLE),
  97. mAsyncResult(UNKNOWN_ERROR),
  98. mSrcId(0),
  99. mSetSurfaceInProgress(false),
  100. mDurationUs(-1),
  101. mPositionUs(-1),
  102. mSeekInProgress(false),
  103. mPlayingTimeUs(0),
  104. mRebufferingTimeUs(0),
  105. mRebufferingEvents(0),
  106. mRebufferingAtExit(false),
  107. mLooper(new ALooper),
  108. mNuPlayer2Looper(new ALooper),
  109. mMediaClock(new MediaClock),
  110. mPlayer(new NuPlayer2(pid, uid, mMediaClock, context)),
  111. mPlayerFlags(0),
  112. mMetricsHandle(0),
  113. mPlayerVersion(0),
  114. mClientUid(uid),
  115. mAtEOS(false),
  116. mLooping(false),
  117. mAutoLoop(false) {
  118. ALOGD("NuPlayer2Driver(%p) created, clientPid(%d)", this, pid);
  119. mLooper->setName("NuPlayer2Driver Looper");
  120. mNuPlayer2Looper->setName("NuPlayer2 Looper");
  121. mMediaClock->init();
  122. // XXX: what version are we?
  123. // Ideally, this ticks with the apk version info for the APEX packaging
  124. // set up media metrics record
  125. mMetricsHandle = mediametrics_create(kKeyPlayer);
  126. mediametrics_setUid(mMetricsHandle, mClientUid);
  127. mediametrics_setInt64(mMetricsHandle, kPlayerVersion, mPlayerVersion);
  128. mNuPlayer2Looper->start(
  129. false, /* runOnCallingThread */
  130. true, /* canCallJava */
  131. PRIORITY_AUDIO);
  132. mNuPlayer2Looper->registerHandler(mPlayer);
  133. mPlayer->setDriver(this);
  134. }
  135. NuPlayer2Driver::~NuPlayer2Driver() {
  136. ALOGV("~NuPlayer2Driver(%p)", this);
  137. mNuPlayer2Looper->stop();
  138. mLooper->stop();
  139. // finalize any pending metrics, usually a no-op.
  140. updateMetrics("destructor");
  141. logMetrics("destructor");
  142. mediametrics_delete(mMetricsHandle);
  143. }
  144. status_t NuPlayer2Driver::initCheck() {
  145. mLooper->start(
  146. false, /* runOnCallingThread */
  147. true, /* canCallJava */
  148. PRIORITY_AUDIO);
  149. mLooper->registerHandler(this);
  150. return OK;
  151. }
  152. status_t NuPlayer2Driver::setDataSource(const sp<DataSourceDesc> &dsd) {
  153. ALOGV("setDataSource(%p)", this);
  154. Mutex::Autolock autoLock(mLock);
  155. if (mState != STATE_IDLE) {
  156. return INVALID_OPERATION;
  157. }
  158. mSrcId = dsd->mId;
  159. mState = STATE_SET_DATASOURCE_PENDING;
  160. mPlayer->setDataSourceAsync(dsd);
  161. while (mState == STATE_SET_DATASOURCE_PENDING) {
  162. mCondition.wait(mLock);
  163. }
  164. return mAsyncResult;
  165. }
  166. status_t NuPlayer2Driver::prepareNextDataSource(const sp<DataSourceDesc> &dsd) {
  167. ALOGV("prepareNextDataSource(%p)", this);
  168. Mutex::Autolock autoLock(mLock);
  169. mPlayer->prepareNextDataSourceAsync(dsd);
  170. return OK;
  171. }
  172. status_t NuPlayer2Driver::playNextDataSource(int64_t srcId) {
  173. ALOGV("playNextDataSource(%p)", this);
  174. Mutex::Autolock autoLock(mLock);
  175. mSrcId = srcId;
  176. mPlayer->playNextDataSource(srcId);
  177. return OK;
  178. }
  179. status_t NuPlayer2Driver::setVideoSurfaceTexture(const sp<ANativeWindowWrapper> &nww) {
  180. ALOGV("setVideoSurfaceTexture(%p)", this);
  181. Mutex::Autolock autoLock(mLock);
  182. if (mSetSurfaceInProgress) {
  183. return INVALID_OPERATION;
  184. }
  185. switch (mState) {
  186. case STATE_SET_DATASOURCE_PENDING:
  187. case STATE_RESET_IN_PROGRESS:
  188. return INVALID_OPERATION;
  189. default:
  190. break;
  191. }
  192. mSetSurfaceInProgress = true;
  193. mPlayer->setVideoSurfaceTextureAsync(nww);
  194. while (mSetSurfaceInProgress) {
  195. mCondition.wait(mLock);
  196. }
  197. return OK;
  198. }
  199. status_t NuPlayer2Driver::getBufferingSettings(BufferingSettings* buffering) {
  200. ALOGV("getBufferingSettings(%p)", this);
  201. {
  202. Mutex::Autolock autoLock(mLock);
  203. if (mState == STATE_IDLE) {
  204. return INVALID_OPERATION;
  205. }
  206. }
  207. return mPlayer->getBufferingSettings(buffering);
  208. }
  209. status_t NuPlayer2Driver::setBufferingSettings(const BufferingSettings& buffering) {
  210. ALOGV("setBufferingSettings(%p)", this);
  211. {
  212. Mutex::Autolock autoLock(mLock);
  213. if (mState == STATE_IDLE) {
  214. return INVALID_OPERATION;
  215. }
  216. }
  217. return mPlayer->setBufferingSettings(buffering);
  218. }
  219. status_t NuPlayer2Driver::prepareAsync() {
  220. ALOGV("prepareAsync(%p)", this);
  221. Mutex::Autolock autoLock(mLock);
  222. switch (mState) {
  223. case STATE_UNPREPARED:
  224. mState = STATE_PREPARING;
  225. mPlayer->prepareAsync();
  226. return OK;
  227. default:
  228. return INVALID_OPERATION;
  229. };
  230. }
  231. status_t NuPlayer2Driver::start() {
  232. ALOGD("start(%p), state is %d, eos is %d", this, mState, mAtEOS);
  233. Mutex::Autolock autoLock(mLock);
  234. return start_l();
  235. }
  236. status_t NuPlayer2Driver::start_l() {
  237. switch (mState) {
  238. case STATE_PAUSED:
  239. case STATE_PREPARED:
  240. {
  241. mPlayer->start();
  242. FALLTHROUGH_INTENDED;
  243. }
  244. case STATE_RUNNING:
  245. {
  246. if (mAtEOS) {
  247. mPlayer->rewind();
  248. mAtEOS = false;
  249. mPositionUs = -1;
  250. }
  251. break;
  252. }
  253. default:
  254. return INVALID_OPERATION;
  255. }
  256. mState = STATE_RUNNING;
  257. return OK;
  258. }
  259. status_t NuPlayer2Driver::pause() {
  260. ALOGD("pause(%p)", this);
  261. // The NuPlayerRenderer may get flushed if pause for long enough, e.g. the pause timeout tear
  262. // down for audio offload mode. If that happens, the NuPlayerRenderer will no longer know the
  263. // current position. So similar to seekTo, update |mPositionUs| to the pause position by calling
  264. // getCurrentPosition here.
  265. int64_t unused;
  266. getCurrentPosition(&unused);
  267. Mutex::Autolock autoLock(mLock);
  268. switch (mState) {
  269. case STATE_PAUSED:
  270. return OK;
  271. case STATE_PREPARED:
  272. case STATE_RUNNING:
  273. mState = STATE_PAUSED;
  274. mPlayer->pause();
  275. break;
  276. default:
  277. return INVALID_OPERATION;
  278. }
  279. return OK;
  280. }
  281. bool NuPlayer2Driver::isPlaying() {
  282. return mState == STATE_RUNNING && !mAtEOS;
  283. }
  284. status_t NuPlayer2Driver::setPlaybackSettings(const AudioPlaybackRate &rate) {
  285. status_t err = mPlayer->setPlaybackSettings(rate);
  286. if (err == OK) {
  287. // try to update position
  288. int64_t unused;
  289. getCurrentPosition(&unused);
  290. }
  291. return err;
  292. }
  293. status_t NuPlayer2Driver::getPlaybackSettings(AudioPlaybackRate *rate) {
  294. return mPlayer->getPlaybackSettings(rate);
  295. }
  296. status_t NuPlayer2Driver::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) {
  297. return mPlayer->setSyncSettings(sync, videoFpsHint);
  298. }
  299. status_t NuPlayer2Driver::getSyncSettings(AVSyncSettings *sync, float *videoFps) {
  300. return mPlayer->getSyncSettings(sync, videoFps);
  301. }
  302. status_t NuPlayer2Driver::seekTo(int64_t msec, MediaPlayer2SeekMode mode) {
  303. ALOGD("seekTo(%p) (%lld ms, %d) at state %d", this, (long long)msec, mode, mState);
  304. Mutex::Autolock autoLock(mLock);
  305. int64_t seekTimeUs = msec * 1000LL;
  306. switch (mState) {
  307. case STATE_PREPARED:
  308. case STATE_PAUSED:
  309. case STATE_RUNNING:
  310. {
  311. mAtEOS = false;
  312. mSeekInProgress = true;
  313. mPlayer->seekToAsync(seekTimeUs, mode, true /* needNotify */);
  314. break;
  315. }
  316. default:
  317. return INVALID_OPERATION;
  318. }
  319. mPositionUs = seekTimeUs;
  320. return OK;
  321. }
  322. status_t NuPlayer2Driver::getCurrentPosition(int64_t *msec) {
  323. int64_t tempUs = 0;
  324. {
  325. Mutex::Autolock autoLock(mLock);
  326. if (mSeekInProgress || (mState == STATE_PAUSED && !mAtEOS)) {
  327. tempUs = (mPositionUs <= 0) ? 0 : mPositionUs;
  328. *msec = divRound(tempUs, (int64_t)(1000));
  329. return OK;
  330. }
  331. }
  332. status_t ret = mPlayer->getCurrentPosition(&tempUs);
  333. Mutex::Autolock autoLock(mLock);
  334. // We need to check mSeekInProgress here because mPlayer->seekToAsync is an async call, which
  335. // means getCurrentPosition can be called before seek is completed. Iow, renderer may return a
  336. // position value that's different the seek to position.
  337. if (ret != OK) {
  338. tempUs = (mPositionUs <= 0) ? 0 : mPositionUs;
  339. } else {
  340. mPositionUs = tempUs;
  341. }
  342. *msec = divRound(tempUs, (int64_t)(1000));
  343. return OK;
  344. }
  345. status_t NuPlayer2Driver::getDuration(int64_t *msec) {
  346. Mutex::Autolock autoLock(mLock);
  347. if (mDurationUs < 0) {
  348. return UNKNOWN_ERROR;
  349. }
  350. *msec = (mDurationUs + 500LL) / 1000;
  351. return OK;
  352. }
  353. void NuPlayer2Driver::updateMetrics(const char *where) {
  354. if (where == NULL) {
  355. where = "unknown";
  356. }
  357. ALOGV("updateMetrics(%p) from %s at state %d", this, where, mState);
  358. // gather the final stats for this record
  359. Vector<sp<AMessage>> trackStats;
  360. mPlayer->getStats(&trackStats);
  361. if (trackStats.size() > 0) {
  362. for (size_t i = 0; i < trackStats.size(); ++i) {
  363. const sp<AMessage> &stats = trackStats.itemAt(i);
  364. AString mime;
  365. stats->findString("mime", &mime);
  366. AString name;
  367. stats->findString("component-name", &name);
  368. if (mime.startsWith("video/")) {
  369. int32_t width, height;
  370. mediametrics_setCString(mMetricsHandle, kPlayerVMime, mime.c_str());
  371. if (!name.empty()) {
  372. mediametrics_setCString(mMetricsHandle, kPlayerVCodec, name.c_str());
  373. }
  374. if (stats->findInt32("width", &width)
  375. && stats->findInt32("height", &height)) {
  376. mediametrics_setInt32(mMetricsHandle, kPlayerWidth, width);
  377. mediametrics_setInt32(mMetricsHandle, kPlayerHeight, height);
  378. }
  379. int64_t numFramesTotal = 0;
  380. int64_t numFramesDropped = 0;
  381. stats->findInt64("frames-total", &numFramesTotal);
  382. stats->findInt64("frames-dropped-output", &numFramesDropped);
  383. mediametrics_setInt64(mMetricsHandle, kPlayerFrames, numFramesTotal);
  384. mediametrics_setInt64(mMetricsHandle, kPlayerFramesDropped, numFramesDropped);
  385. float frameRate = 0;
  386. if (stats->findFloat("frame-rate-output", &frameRate)) {
  387. mediametrics_setInt64(mMetricsHandle, kPlayerFrameRate, frameRate);
  388. }
  389. } else if (mime.startsWith("audio/")) {
  390. mediametrics_setCString(mMetricsHandle, kPlayerAMime, mime.c_str());
  391. if (!name.empty()) {
  392. mediametrics_setCString(mMetricsHandle, kPlayerACodec, name.c_str());
  393. }
  394. }
  395. }
  396. }
  397. // always provide duration and playing time, even if they have 0/unknown values.
  398. // getDuration() uses mLock for mutex -- careful where we use it.
  399. int64_t duration_ms = -1;
  400. getDuration(&duration_ms);
  401. mediametrics_setInt64(mMetricsHandle, kPlayerDuration, duration_ms);
  402. mediametrics_setInt64(mMetricsHandle, kPlayerPlaying, (mPlayingTimeUs+500)/1000 );
  403. if (mRebufferingEvents != 0) {
  404. mediametrics_setInt64(mMetricsHandle, kPlayerRebuffering, (mRebufferingTimeUs+500)/1000 );
  405. mediametrics_setInt32(mMetricsHandle, kPlayerRebufferingCount, mRebufferingEvents);
  406. mediametrics_setInt32(mMetricsHandle, kPlayerRebufferingAtExit, mRebufferingAtExit);
  407. }
  408. mediametrics_setCString(mMetricsHandle, kPlayerDataSourceType, mPlayer->getDataSourceType());
  409. }
  410. void NuPlayer2Driver::logMetrics(const char *where) {
  411. if (where == NULL) {
  412. where = "unknown";
  413. }
  414. ALOGV("logMetrics(%p) from %s at state %d", this, where, mState);
  415. if (mMetricsHandle == 0 || mediametrics_isEnabled() == false) {
  416. return;
  417. }
  418. // log only non-empty records
  419. // we always updateMetrics() before we get here
  420. // and that always injects 3 fields (duration, playing time, and
  421. // datasource) into the record.
  422. // So the canonical "empty" record has 3 elements in it.
  423. if (mediametrics_count(mMetricsHandle) > 3) {
  424. mediametrics_selfRecord(mMetricsHandle);
  425. // re-init in case we prepare() and start() again.
  426. mediametrics_delete(mMetricsHandle);
  427. mMetricsHandle = mediametrics_create(kKeyPlayer);
  428. mediametrics_setUid(mMetricsHandle, mClientUid);
  429. mediametrics_setInt64(mMetricsHandle, kPlayerVersion, mPlayerVersion);
  430. } else {
  431. ALOGV("did not have anything to record");
  432. }
  433. }
  434. status_t NuPlayer2Driver::reset() {
  435. ALOGD("reset(%p) at state %d", this, mState);
  436. updateMetrics("reset");
  437. logMetrics("reset");
  438. Mutex::Autolock autoLock(mLock);
  439. switch (mState) {
  440. case STATE_IDLE:
  441. return OK;
  442. case STATE_SET_DATASOURCE_PENDING:
  443. case STATE_RESET_IN_PROGRESS:
  444. return INVALID_OPERATION;
  445. case STATE_PREPARING:
  446. {
  447. notifyListener_l(mSrcId, MEDIA2_PREPARED);
  448. break;
  449. }
  450. default:
  451. break;
  452. }
  453. mState = STATE_RESET_IN_PROGRESS;
  454. mPlayer->resetAsync();
  455. while (mState == STATE_RESET_IN_PROGRESS) {
  456. mCondition.wait(mLock);
  457. }
  458. mDurationUs = -1;
  459. mPositionUs = -1;
  460. mLooping = false;
  461. mPlayingTimeUs = 0;
  462. mRebufferingTimeUs = 0;
  463. mRebufferingEvents = 0;
  464. mRebufferingAtExit = false;
  465. return OK;
  466. }
  467. status_t NuPlayer2Driver::notifyAt(int64_t mediaTimeUs) {
  468. ALOGV("notifyAt(%p), time:%lld", this, (long long)mediaTimeUs);
  469. return mPlayer->notifyAt(mediaTimeUs);
  470. }
  471. status_t NuPlayer2Driver::setLooping(int loop) {
  472. mLooping = loop != 0;
  473. return OK;
  474. }
  475. status_t NuPlayer2Driver::invoke(const PlayerMessage &request, PlayerMessage *response) {
  476. if (response == NULL) {
  477. ALOGE("reply is a NULL pointer");
  478. return BAD_VALUE;
  479. }
  480. RepeatedPtrField<const Value>::const_iterator it = request.values().cbegin();
  481. int32_t methodId = (it++)->int32_value();
  482. switch (methodId) {
  483. case MEDIA_PLAYER2_INVOKE_ID_SET_VIDEO_SCALING_MODE:
  484. {
  485. int mode = (it++)->int32_value();
  486. return mPlayer->setVideoScalingMode(mode);
  487. }
  488. case MEDIA_PLAYER2_INVOKE_ID_GET_TRACK_INFO:
  489. {
  490. int64_t srcId = (it++)->int64_value();
  491. return mPlayer->getTrackInfo(srcId, response);
  492. }
  493. case MEDIA_PLAYER2_INVOKE_ID_SELECT_TRACK:
  494. {
  495. int64_t srcId = (it++)->int64_value();
  496. int trackIndex = (it++)->int32_value();
  497. int64_t msec = 0;
  498. // getCurrentPosition should always return OK
  499. getCurrentPosition(&msec);
  500. return mPlayer->selectTrack(srcId, trackIndex, true /* select */, msec * 1000LL);
  501. }
  502. case MEDIA_PLAYER2_INVOKE_ID_UNSELECT_TRACK:
  503. {
  504. int64_t srcId = (it++)->int64_value();
  505. int trackIndex = (it++)->int32_value();
  506. return mPlayer->selectTrack(
  507. srcId, trackIndex, false /* select */, 0xdeadbeef /* not used */);
  508. }
  509. case MEDIA_PLAYER2_INVOKE_ID_GET_SELECTED_TRACK:
  510. {
  511. int64_t srcId = (it++)->int64_value();
  512. int32_t type = (it++)->int32_value();
  513. return mPlayer->getSelectedTrack(srcId, type, response);
  514. }
  515. default:
  516. {
  517. return INVALID_OPERATION;
  518. }
  519. }
  520. }
  521. void NuPlayer2Driver::setAudioSink(const sp<AudioSink> &audioSink) {
  522. mPlayer->setAudioSink(audioSink);
  523. mAudioSink = audioSink;
  524. }
  525. status_t NuPlayer2Driver::setParameter(
  526. int /* key */, const Parcel & /* request */) {
  527. return INVALID_OPERATION;
  528. }
  529. status_t NuPlayer2Driver::getParameter(int key __unused, Parcel *reply __unused) {
  530. return INVALID_OPERATION;
  531. }
  532. status_t NuPlayer2Driver::getMetrics(char **buffer, size_t *length) {
  533. updateMetrics("api");
  534. if (mediametrics_getAttributes(mMetricsHandle, buffer, length))
  535. return OK;
  536. else
  537. return FAILED_TRANSACTION;
  538. }
  539. void NuPlayer2Driver::notifyResetComplete(int64_t /* srcId */) {
  540. ALOGD("notifyResetComplete(%p)", this);
  541. Mutex::Autolock autoLock(mLock);
  542. CHECK_EQ(mState, STATE_RESET_IN_PROGRESS);
  543. mState = STATE_IDLE;
  544. mCondition.broadcast();
  545. }
  546. void NuPlayer2Driver::notifySetSurfaceComplete(int64_t /* srcId */) {
  547. ALOGV("notifySetSurfaceComplete(%p)", this);
  548. Mutex::Autolock autoLock(mLock);
  549. CHECK(mSetSurfaceInProgress);
  550. mSetSurfaceInProgress = false;
  551. mCondition.broadcast();
  552. }
  553. void NuPlayer2Driver::notifyDuration(int64_t /* srcId */, int64_t durationUs) {
  554. Mutex::Autolock autoLock(mLock);
  555. mDurationUs = durationUs;
  556. }
  557. void NuPlayer2Driver::notifyMorePlayingTimeUs(int64_t /* srcId */, int64_t playingUs) {
  558. Mutex::Autolock autoLock(mLock);
  559. mPlayingTimeUs += playingUs;
  560. }
  561. void NuPlayer2Driver::notifyMoreRebufferingTimeUs(int64_t /* srcId */, int64_t rebufferingUs) {
  562. Mutex::Autolock autoLock(mLock);
  563. mRebufferingTimeUs += rebufferingUs;
  564. mRebufferingEvents++;
  565. }
  566. void NuPlayer2Driver::notifyRebufferingWhenExit(int64_t /* srcId */, bool status) {
  567. Mutex::Autolock autoLock(mLock);
  568. mRebufferingAtExit = status;
  569. }
  570. void NuPlayer2Driver::notifySeekComplete(int64_t srcId) {
  571. ALOGV("notifySeekComplete(%p)", this);
  572. Mutex::Autolock autoLock(mLock);
  573. mSeekInProgress = false;
  574. notifyListener_l(srcId, MEDIA2_SEEK_COMPLETE);
  575. }
  576. status_t NuPlayer2Driver::dump(
  577. int fd, const Vector<String16> & /* args */) const {
  578. Vector<sp<AMessage> > trackStats;
  579. mPlayer->getStats(&trackStats);
  580. AString logString(" NuPlayer2\n");
  581. char buf[256] = {0};
  582. bool locked = false;
  583. for (int i = 0; i < kDumpLockRetries; ++i) {
  584. if (mLock.tryLock() == NO_ERROR) {
  585. locked = true;
  586. break;
  587. }
  588. usleep(kDumpLockSleepUs);
  589. }
  590. if (locked) {
  591. snprintf(buf, sizeof(buf), " state(%d), atEOS(%d), looping(%d), autoLoop(%d)\n",
  592. mState, mAtEOS, mLooping, mAutoLoop);
  593. mLock.unlock();
  594. } else {
  595. snprintf(buf, sizeof(buf), " NPD(%p) lock is taken\n", this);
  596. }
  597. logString.append(buf);
  598. for (size_t i = 0; i < trackStats.size(); ++i) {
  599. const sp<AMessage> &stats = trackStats.itemAt(i);
  600. AString mime;
  601. if (stats->findString("mime", &mime)) {
  602. snprintf(buf, sizeof(buf), " mime(%s)\n", mime.c_str());
  603. logString.append(buf);
  604. }
  605. AString name;
  606. if (stats->findString("component-name", &name)) {
  607. snprintf(buf, sizeof(buf), " decoder(%s)\n", name.c_str());
  608. logString.append(buf);
  609. }
  610. if (mime.startsWith("video/")) {
  611. int32_t width, height;
  612. if (stats->findInt32("width", &width)
  613. && stats->findInt32("height", &height)) {
  614. snprintf(buf, sizeof(buf), " resolution(%d x %d)\n", width, height);
  615. logString.append(buf);
  616. }
  617. int64_t numFramesTotal = 0;
  618. int64_t numFramesDropped = 0;
  619. stats->findInt64("frames-total", &numFramesTotal);
  620. stats->findInt64("frames-dropped-output", &numFramesDropped);
  621. snprintf(buf, sizeof(buf), " numFramesTotal(%lld), numFramesDropped(%lld), "
  622. "percentageDropped(%.2f%%)\n",
  623. (long long)numFramesTotal,
  624. (long long)numFramesDropped,
  625. numFramesTotal == 0
  626. ? 0.0 : (double)(numFramesDropped * 100) / numFramesTotal);
  627. logString.append(buf);
  628. }
  629. }
  630. ALOGI("%s", logString.c_str());
  631. if (fd >= 0) {
  632. FILE *out = fdopen(dup(fd), "w");
  633. fprintf(out, "%s", logString.c_str());
  634. fclose(out);
  635. out = NULL;
  636. }
  637. return OK;
  638. }
  639. void NuPlayer2Driver::onMessageReceived(const sp<AMessage> &msg) {
  640. switch (msg->what()) {
  641. case kWhatNotifyListener: {
  642. int64_t srcId;
  643. int32_t msgId;
  644. int32_t ext1 = 0;
  645. int32_t ext2 = 0;
  646. CHECK(msg->findInt64("srcId", &srcId));
  647. CHECK(msg->findInt32("messageId", &msgId));
  648. msg->findInt32("ext1", &ext1);
  649. msg->findInt32("ext2", &ext2);
  650. sp<PlayerMessageWrapper> in;
  651. sp<RefBase> obj;
  652. if (msg->findObject("obj", &obj) && obj != NULL) {
  653. in = static_cast<PlayerMessageWrapper *>(obj.get());
  654. }
  655. sendEvent(srcId, msgId, ext1, ext2, (in == NULL ? NULL : in->getPlayerMessage()));
  656. break;
  657. }
  658. default:
  659. break;
  660. }
  661. }
  662. void NuPlayer2Driver::notifyListener(
  663. int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
  664. Mutex::Autolock autoLock(mLock);
  665. notifyListener_l(srcId, msg, ext1, ext2, in);
  666. }
  667. void NuPlayer2Driver::notifyListener_l(
  668. int64_t srcId, int msg, int ext1, int ext2, const PlayerMessage *in) {
  669. ALOGD("notifyListener_l(%p), (%lld, %d, %d, %d, %d), loop setting(%d, %d)",
  670. this, (long long)srcId, msg, ext1, ext2,
  671. (in == NULL ? -1 : (int)in->ByteSize()), mAutoLoop, mLooping);
  672. if (srcId == mSrcId) {
  673. switch (msg) {
  674. case MEDIA2_PLAYBACK_COMPLETE:
  675. {
  676. if (mState != STATE_RESET_IN_PROGRESS) {
  677. if (mAutoLoop) {
  678. audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
  679. if (mAudioSink != NULL) {
  680. streamType = mAudioSink->getAudioStreamType();
  681. }
  682. if (streamType == AUDIO_STREAM_NOTIFICATION) {
  683. ALOGW("disabling auto-loop for notification");
  684. mAutoLoop = false;
  685. }
  686. }
  687. if (mLooping || mAutoLoop) {
  688. mPlayer->rewind();
  689. if (mAudioSink != NULL) {
  690. // The renderer has stopped the sink at the end in order to play out
  691. // the last little bit of audio. In looping mode, we need to restart it.
  692. mAudioSink->start();
  693. }
  694. sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
  695. notify->setInt64("srcId", srcId);
  696. notify->setInt32("messageId", MEDIA2_INFO);
  697. notify->setInt32("ext1", MEDIA2_INFO_DATA_SOURCE_REPEAT);
  698. notify->post();
  699. return;
  700. }
  701. if (property_get_bool("persist.debug.sf.stats", false)) {
  702. Vector<String16> args;
  703. dump(-1, args);
  704. }
  705. mPlayer->pause();
  706. mState = STATE_PAUSED;
  707. }
  708. FALLTHROUGH_INTENDED;
  709. }
  710. case MEDIA2_ERROR:
  711. {
  712. // when we have an error, add it to the analytics for this playback.
  713. // ext1 is our primary 'error type' value. Only add ext2 when non-zero.
  714. // [test against msg is due to fall through from previous switch value]
  715. if (msg == MEDIA2_ERROR) {
  716. mediametrics_setInt32(mMetricsHandle, kPlayerError, ext1);
  717. if (ext2 != 0) {
  718. mediametrics_setInt32(mMetricsHandle, kPlayerErrorCode, ext2);
  719. }
  720. mediametrics_setCString(mMetricsHandle, kPlayerErrorState, stateString(mState).c_str());
  721. }
  722. mAtEOS = true;
  723. break;
  724. }
  725. default:
  726. break;
  727. }
  728. }
  729. sp<AMessage> notify = new AMessage(kWhatNotifyListener, this);
  730. notify->setInt64("srcId", srcId);
  731. notify->setInt32("messageId", msg);
  732. notify->setInt32("ext1", ext1);
  733. notify->setInt32("ext2", ext2);
  734. notify->setObject("obj", PlayerMessageWrapper::Create((PlayerMessage*)in));
  735. notify->post();
  736. }
  737. void NuPlayer2Driver::notifySetDataSourceCompleted(int64_t /* srcId */, status_t err) {
  738. Mutex::Autolock autoLock(mLock);
  739. CHECK_EQ(mState, STATE_SET_DATASOURCE_PENDING);
  740. mAsyncResult = err;
  741. mState = (err == OK) ? STATE_UNPREPARED : STATE_IDLE;
  742. mCondition.broadcast();
  743. }
  744. void NuPlayer2Driver::notifyPrepareCompleted(int64_t srcId, status_t err) {
  745. ALOGV("notifyPrepareCompleted %d", err);
  746. Mutex::Autolock autoLock(mLock);
  747. if (srcId != mSrcId) {
  748. if (err == OK) {
  749. notifyListener_l(srcId, MEDIA2_PREPARED);
  750. } else {
  751. notifyListener_l(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
  752. }
  753. return;
  754. }
  755. if (mState != STATE_PREPARING) {
  756. // We were preparing asynchronously when the client called
  757. // reset(), we sent a premature "prepared" notification and
  758. // then initiated the reset. This notification is stale.
  759. CHECK(mState == STATE_RESET_IN_PROGRESS || mState == STATE_IDLE);
  760. return;
  761. }
  762. CHECK_EQ(mState, STATE_PREPARING);
  763. mAsyncResult = err;
  764. if (err == OK) {
  765. // update state before notifying client, so that if client calls back into NuPlayer2Driver
  766. // in response, NuPlayer2Driver has the right state
  767. mState = STATE_PREPARED;
  768. notifyListener_l(srcId, MEDIA2_PREPARED);
  769. } else {
  770. mState = STATE_UNPREPARED;
  771. notifyListener_l(srcId, MEDIA2_ERROR, MEDIA2_ERROR_UNKNOWN, err);
  772. }
  773. sp<MetaData> meta = mPlayer->getFileMeta();
  774. int32_t loop;
  775. if (meta != NULL
  776. && meta->findInt32(kKeyAutoLoop, &loop) && loop != 0) {
  777. mAutoLoop = true;
  778. }
  779. mCondition.broadcast();
  780. }
  781. void NuPlayer2Driver::notifyFlagsChanged(int64_t /* srcId */, uint32_t flags) {
  782. Mutex::Autolock autoLock(mLock);
  783. mPlayerFlags = flags;
  784. }
  785. // Modular DRM
  786. status_t NuPlayer2Driver::prepareDrm(
  787. int64_t srcId, const uint8_t uuid[16], const Vector<uint8_t> &drmSessionId)
  788. {
  789. ALOGV("prepareDrm(%p) state: %d", this, mState);
  790. // leaving the state verification for mediaplayer.cpp
  791. status_t ret = mPlayer->prepareDrm(srcId, uuid, drmSessionId);
  792. ALOGV("prepareDrm ret: %d", ret);
  793. return ret;
  794. }
  795. status_t NuPlayer2Driver::releaseDrm(int64_t srcId)
  796. {
  797. ALOGV("releaseDrm(%p) state: %d", this, mState);
  798. // leaving the state verification for mediaplayer.cpp
  799. status_t ret = mPlayer->releaseDrm(srcId);
  800. ALOGV("releaseDrm ret: %d", ret);
  801. return ret;
  802. }
  803. std::string NuPlayer2Driver::stateString(State state) {
  804. const char *rval = NULL;
  805. char rawbuffer[16]; // allows "%d"
  806. switch (state) {
  807. case STATE_IDLE: rval = "IDLE"; break;
  808. case STATE_SET_DATASOURCE_PENDING: rval = "SET_DATASOURCE_PENDING"; break;
  809. case STATE_UNPREPARED: rval = "UNPREPARED"; break;
  810. case STATE_PREPARING: rval = "PREPARING"; break;
  811. case STATE_PREPARED: rval = "PREPARED"; break;
  812. case STATE_RUNNING: rval = "RUNNING"; break;
  813. case STATE_PAUSED: rval = "PAUSED"; break;
  814. case STATE_RESET_IN_PROGRESS: rval = "RESET_IN_PROGRESS"; break;
  815. default:
  816. // yes, this buffer is shared and vulnerable to races
  817. snprintf(rawbuffer, sizeof(rawbuffer), "%d", state);
  818. rval = rawbuffer;
  819. break;
  820. }
  821. return rval;
  822. }
  823. } // namespace android