GenericSource2.cpp 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547
  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 "GenericSource2"
  18. #include "GenericSource2.h"
  19. #include "NuPlayer2Drm.h"
  20. #include "AnotherPacketSource.h"
  21. #include <cutils/properties.h>
  22. #include <media/DataSource.h>
  23. #include <media/MediaBufferHolder.h>
  24. #include <media/NdkWrapper.h>
  25. #include <media/stagefright/foundation/ABuffer.h>
  26. #include <media/stagefright/foundation/ADebug.h>
  27. #include <media/stagefright/foundation/AMessage.h>
  28. #include <media/stagefright/MediaBuffer.h>
  29. #include <media/stagefright/MediaClock.h>
  30. #include <media/stagefright/MediaDefs.h>
  31. #include <media/stagefright/MetaData.h>
  32. #include <media/stagefright/NdkUtils.h>
  33. #include <media/stagefright/Utils.h>
  34. namespace android {
  35. static const int kInitialMarkMs = 5000; // 5secs
  36. //static const int kPausePlaybackMarkMs = 2000; // 2secs
  37. static const int kResumePlaybackMarkMs = 15000; // 15secs
  38. NuPlayer2::GenericSource2::GenericSource2(
  39. const sp<AMessage> &notify,
  40. uid_t uid,
  41. const sp<MediaClock> &mediaClock)
  42. : Source(notify),
  43. mAudioTimeUs(0),
  44. mAudioLastDequeueTimeUs(0),
  45. mVideoTimeUs(0),
  46. mVideoLastDequeueTimeUs(0),
  47. mPrevBufferPercentage(-1),
  48. mPollBufferingGeneration(0),
  49. mSentPauseOnBuffering(false),
  50. mAudioDataGeneration(0),
  51. mVideoDataGeneration(0),
  52. mFetchSubtitleDataGeneration(0),
  53. mFetchTimedTextDataGeneration(0),
  54. mDurationUs(-1ll),
  55. mAudioIsVorbis(false),
  56. mIsSecure(false),
  57. mIsStreaming(false),
  58. mUID(uid),
  59. mMediaClock(mediaClock),
  60. mFd(-1),
  61. mBitrate(-1ll),
  62. mPendingReadBufferTypes(0) {
  63. ALOGV("GenericSource2");
  64. CHECK(mediaClock != NULL);
  65. mBufferingSettings.mInitialMarkMs = kInitialMarkMs;
  66. mBufferingSettings.mResumePlaybackMarkMs = kResumePlaybackMarkMs;
  67. resetDataSource();
  68. }
  69. void NuPlayer2::GenericSource2::resetDataSource() {
  70. ALOGV("resetDataSource");
  71. mDisconnected = false;
  72. mUri.clear();
  73. mUriHeaders.clear();
  74. if (mFd >= 0) {
  75. close(mFd);
  76. mFd = -1;
  77. }
  78. mOffset = 0;
  79. mLength = 0;
  80. mStarted = false;
  81. mPreparing = false;
  82. mIsDrmProtected = false;
  83. mIsDrmReleased = false;
  84. mIsSecure = false;
  85. mMimes.clear();
  86. }
  87. status_t NuPlayer2::GenericSource2::setDataSource(
  88. const char *url,
  89. const KeyedVector<String8, String8> *headers) {
  90. Mutex::Autolock _l(mLock);
  91. ALOGV("setDataSource url: %s", url);
  92. resetDataSource();
  93. mUri = url;
  94. if (headers) {
  95. mUriHeaders = *headers;
  96. }
  97. // delay data source creation to prepareAsync() to avoid blocking
  98. // the calling thread in setDataSource for any significant time.
  99. return OK;
  100. }
  101. status_t NuPlayer2::GenericSource2::setDataSource(
  102. int fd, int64_t offset, int64_t length) {
  103. Mutex::Autolock _l(mLock);
  104. ALOGV("setDataSource %d/%lld/%lld", fd, (long long)offset, (long long)length);
  105. resetDataSource();
  106. mFd = dup(fd);
  107. mOffset = offset;
  108. mLength = length;
  109. // delay data source creation to prepareAsync() to avoid blocking
  110. // the calling thread in setDataSource for any significant time.
  111. return OK;
  112. }
  113. status_t NuPlayer2::GenericSource2::setDataSource(const sp<DataSource>& source) {
  114. Mutex::Autolock _l(mLock);
  115. ALOGV("setDataSource (source: %p)", source.get());
  116. resetDataSource();
  117. mDataSourceWrapper = new AMediaDataSourceWrapper(source);
  118. return OK;
  119. }
  120. sp<MetaData> NuPlayer2::GenericSource2::getFileFormatMeta() const {
  121. Mutex::Autolock _l(mLock);
  122. return mFileMeta;
  123. }
  124. status_t NuPlayer2::GenericSource2::initFromDataSource() {
  125. mExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
  126. CHECK(mFd >=0 || mDataSourceWrapper != NULL);
  127. sp<AMediaDataSourceWrapper> aSourceWrapper = mDataSourceWrapper;
  128. const int fd = mFd;
  129. mLock.unlock();
  130. // This might take long time if data source is not reliable.
  131. status_t err;
  132. if (aSourceWrapper != NULL) {
  133. err = mExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
  134. } else {
  135. err = mExtractor->setDataSource(fd, mOffset, mLength);
  136. }
  137. if (err != OK) {
  138. ALOGE("initFromDataSource, failed to set extractor data source!");
  139. mLock.lock();
  140. return UNKNOWN_ERROR;
  141. }
  142. size_t numtracks = mExtractor->getTrackCount();
  143. if (numtracks == 0) {
  144. ALOGE("initFromDataSource, source has no track!");
  145. mLock.lock();
  146. return UNKNOWN_ERROR;
  147. }
  148. mFileMeta = convertMediaFormatWrapperToMetaData(mExtractor->getFormat());
  149. mLock.lock();
  150. if (mFileMeta != NULL) {
  151. int64_t duration;
  152. if (mFileMeta->findInt64(kKeyDuration, &duration)) {
  153. mDurationUs = duration;
  154. }
  155. }
  156. int32_t totalBitrate = 0;
  157. mMimes.clear();
  158. for (size_t i = 0; i < numtracks; ++i) {
  159. sp<AMediaFormatWrapper> trackFormat = mExtractor->getTrackFormat(i);
  160. if (trackFormat == NULL) {
  161. ALOGE("no metadata for track %zu", i);
  162. return UNKNOWN_ERROR;
  163. }
  164. sp<AMediaExtractorWrapper> trackExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
  165. if (aSourceWrapper != NULL) {
  166. trackExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
  167. } else {
  168. trackExtractor->setDataSource(fd, mOffset, mLength);
  169. }
  170. const char *mime;
  171. sp<MetaData> meta = convertMediaFormatWrapperToMetaData(trackFormat);
  172. CHECK(meta->findCString(kKeyMIMEType, &mime));
  173. ALOGV("initFromDataSource track[%zu]: %s", i, mime);
  174. // Do the string compare immediately with "mime",
  175. // we can't assume "mime" would stay valid after another
  176. // extractor operation, some extractors might modify meta
  177. // during getTrack() and make it invalid.
  178. if (!strncasecmp(mime, "audio/", 6)) {
  179. if (mAudioTrack.mExtractor == NULL) {
  180. mAudioTrack.mIndex = i;
  181. mAudioTrack.mExtractor = trackExtractor;
  182. mAudioTrack.mExtractor->selectTrack(i);
  183. mAudioTrack.mPackets = new AnotherPacketSource(meta);
  184. if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
  185. mAudioIsVorbis = true;
  186. } else {
  187. mAudioIsVorbis = false;
  188. }
  189. mMimes.add(String8(mime));
  190. }
  191. } else if (!strncasecmp(mime, "video/", 6)) {
  192. if (mVideoTrack.mExtractor == NULL) {
  193. mVideoTrack.mIndex = i;
  194. mVideoTrack.mExtractor = trackExtractor;
  195. mVideoTrack.mExtractor->selectTrack(i);
  196. mVideoTrack.mPackets = new AnotherPacketSource(meta);
  197. // video always at the beginning
  198. mMimes.insertAt(String8(mime), 0);
  199. }
  200. }
  201. mExtractors.push(trackExtractor);
  202. int64_t durationUs;
  203. if (meta->findInt64(kKeyDuration, &durationUs)) {
  204. if (durationUs > mDurationUs) {
  205. mDurationUs = durationUs;
  206. }
  207. }
  208. int32_t bitrate;
  209. if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
  210. totalBitrate += bitrate;
  211. } else {
  212. totalBitrate = -1;
  213. }
  214. }
  215. ALOGV("initFromDataSource mExtractors.size(): %zu mIsSecure: %d mime[0]: %s", mExtractors.size(),
  216. mIsSecure, (mMimes.isEmpty() ? "NONE" : mMimes[0].string()));
  217. if (mExtractors.size() == 0) {
  218. ALOGE("b/23705695");
  219. return UNKNOWN_ERROR;
  220. }
  221. // Modular DRM: The return value doesn't affect source initialization.
  222. (void)checkDrmInfo();
  223. mBitrate = totalBitrate;
  224. return OK;
  225. }
  226. status_t NuPlayer2::GenericSource2::getBufferingSettings(
  227. BufferingSettings* buffering /* nonnull */) {
  228. {
  229. Mutex::Autolock _l(mLock);
  230. *buffering = mBufferingSettings;
  231. }
  232. ALOGV("getBufferingSettings{%s}", buffering->toString().string());
  233. return OK;
  234. }
  235. status_t NuPlayer2::GenericSource2::setBufferingSettings(const BufferingSettings& buffering) {
  236. ALOGV("setBufferingSettings{%s}", buffering.toString().string());
  237. Mutex::Autolock _l(mLock);
  238. mBufferingSettings = buffering;
  239. return OK;
  240. }
  241. int64_t NuPlayer2::GenericSource2::getLastReadPosition() {
  242. if (mAudioTrack.mExtractor != NULL) {
  243. return mAudioTimeUs;
  244. } else if (mVideoTrack.mExtractor != NULL) {
  245. return mVideoTimeUs;
  246. } else {
  247. return 0;
  248. }
  249. }
  250. bool NuPlayer2::GenericSource2::isStreaming() const {
  251. Mutex::Autolock _l(mLock);
  252. return mIsStreaming;
  253. }
  254. NuPlayer2::GenericSource2::~GenericSource2() {
  255. ALOGV("~GenericSource2");
  256. if (mLooper != NULL) {
  257. mLooper->unregisterHandler(id());
  258. mLooper->stop();
  259. }
  260. if (mDataSourceWrapper != NULL) {
  261. mDataSourceWrapper->close();
  262. }
  263. resetDataSource();
  264. }
  265. void NuPlayer2::GenericSource2::prepareAsync(int64_t startTimeUs) {
  266. Mutex::Autolock _l(mLock);
  267. ALOGV("prepareAsync: (looper: %d)", (mLooper != NULL));
  268. if (mLooper == NULL) {
  269. mLooper = new ALooper;
  270. mLooper->setName("generic2");
  271. mLooper->start(false, /* runOnCallingThread */
  272. true, /* canCallJava */
  273. PRIORITY_DEFAULT);
  274. mLooper->registerHandler(this);
  275. }
  276. sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
  277. msg->setInt64("startTimeUs", startTimeUs);
  278. msg->post();
  279. }
  280. void NuPlayer2::GenericSource2::onPrepareAsync(int64_t startTimeUs) {
  281. ALOGV("onPrepareAsync: mFd %d mUri %s mDataSourceWrapper: %p",
  282. mFd, mUri.c_str(), mDataSourceWrapper.get());
  283. if (!mUri.empty()) {
  284. const char* uri = mUri.c_str();
  285. size_t numheaders = mUriHeaders.size();
  286. const char **key_values = numheaders ? new const char *[numheaders * 2] : NULL;
  287. for (size_t i = 0; i < numheaders; ++i) {
  288. key_values[i * 2] = mUriHeaders.keyAt(i).c_str();
  289. key_values[i * 2 + 1] = mUriHeaders.valueAt(i).c_str();
  290. }
  291. mLock.unlock();
  292. AMediaDataSource *aSource = AMediaDataSource_newUri(uri, numheaders, key_values);
  293. mLock.lock();
  294. mDataSourceWrapper = aSource ? new AMediaDataSourceWrapper(aSource) : NULL;
  295. delete[] key_values;
  296. // For cached streaming cases, we need to wait for enough
  297. // buffering before reporting prepared.
  298. mIsStreaming = !strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8);
  299. }
  300. if (mDisconnected || (mFd < 0 && mDataSourceWrapper == NULL)) {
  301. ALOGE("mDisconnected(%d) or Failed to create data source!", mDisconnected);
  302. notifyPreparedAndCleanup(UNKNOWN_ERROR);
  303. return;
  304. }
  305. // init extractor from data source
  306. status_t err = initFromDataSource();
  307. if (mFd >= 0) {
  308. close(mFd);
  309. mFd = -1;
  310. }
  311. if (err != OK) {
  312. ALOGE("Failed to init from data source!");
  313. notifyPreparedAndCleanup(err);
  314. return;
  315. }
  316. if (mVideoTrack.mExtractor != NULL) {
  317. sp<MetaData> meta = getFormatMeta_l(false /* audio */);
  318. sp<AMessage> msg = new AMessage;
  319. err = convertMetaDataToMessage(meta, &msg);
  320. if(err != OK) {
  321. notifyPreparedAndCleanup(err);
  322. return;
  323. }
  324. notifyVideoSizeChanged(msg);
  325. }
  326. notifyFlagsChanged(
  327. // FLAG_SECURE will be known if/when prepareDrm is called by the app
  328. // FLAG_PROTECTED will be known if/when prepareDrm is called by the app
  329. FLAG_CAN_PAUSE |
  330. FLAG_CAN_SEEK_BACKWARD |
  331. FLAG_CAN_SEEK_FORWARD |
  332. FLAG_CAN_SEEK);
  333. doSeek(startTimeUs, MediaPlayer2SeekMode::SEEK_CLOSEST);
  334. finishPrepareAsync();
  335. ALOGV("onPrepareAsync: Done");
  336. }
  337. void NuPlayer2::GenericSource2::finishPrepareAsync() {
  338. ALOGV("finishPrepareAsync");
  339. if (mIsStreaming) {
  340. mPreparing = true;
  341. ++mPollBufferingGeneration;
  342. schedulePollBuffering();
  343. } else {
  344. notifyPrepared();
  345. }
  346. if (mAudioTrack.mExtractor != NULL) {
  347. postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
  348. }
  349. if (mVideoTrack.mExtractor != NULL) {
  350. postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
  351. }
  352. }
  353. void NuPlayer2::GenericSource2::notifyPreparedAndCleanup(status_t err) {
  354. if (err != OK) {
  355. mDataSourceWrapper.clear();
  356. mBitrate = -1;
  357. mPrevBufferPercentage = -1;
  358. ++mPollBufferingGeneration;
  359. }
  360. notifyPrepared(err);
  361. }
  362. void NuPlayer2::GenericSource2::start() {
  363. Mutex::Autolock _l(mLock);
  364. ALOGI("start");
  365. if (mAudioTrack.mExtractor != NULL) {
  366. postReadBuffer(MEDIA_TRACK_TYPE_AUDIO);
  367. }
  368. if (mVideoTrack.mExtractor != NULL) {
  369. postReadBuffer(MEDIA_TRACK_TYPE_VIDEO);
  370. }
  371. mStarted = true;
  372. }
  373. void NuPlayer2::GenericSource2::stop() {
  374. Mutex::Autolock _l(mLock);
  375. mStarted = false;
  376. }
  377. void NuPlayer2::GenericSource2::pause() {
  378. Mutex::Autolock _l(mLock);
  379. mStarted = false;
  380. }
  381. void NuPlayer2::GenericSource2::resume() {
  382. Mutex::Autolock _l(mLock);
  383. mStarted = true;
  384. }
  385. void NuPlayer2::GenericSource2::disconnect() {
  386. {
  387. Mutex::Autolock _l(mLock);
  388. mDisconnected = true;
  389. }
  390. if (mDataSourceWrapper != NULL) {
  391. mDataSourceWrapper->close();
  392. }
  393. }
  394. status_t NuPlayer2::GenericSource2::feedMoreTSData() {
  395. return OK;
  396. }
  397. void NuPlayer2::GenericSource2::onMessageReceived(const sp<AMessage> &msg) {
  398. Mutex::Autolock _l(mLock);
  399. switch (msg->what()) {
  400. case kWhatPrepareAsync:
  401. {
  402. int64_t startTimeUs;
  403. CHECK(msg->findInt64("startTimeUs", &startTimeUs));
  404. onPrepareAsync(startTimeUs);
  405. break;
  406. }
  407. case kWhatFetchSubtitleData:
  408. {
  409. fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
  410. mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
  411. break;
  412. }
  413. case kWhatFetchTimedTextData:
  414. {
  415. fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
  416. mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
  417. break;
  418. }
  419. case kWhatSendSubtitleData:
  420. {
  421. sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
  422. mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
  423. break;
  424. }
  425. case kWhatSendGlobalTimedTextData:
  426. {
  427. sendGlobalTextData(kWhatTimedTextData, mFetchTimedTextDataGeneration, msg);
  428. break;
  429. }
  430. case kWhatSendTimedTextData:
  431. {
  432. sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
  433. mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
  434. break;
  435. }
  436. case kWhatChangeAVSource:
  437. {
  438. int32_t trackIndex;
  439. CHECK(msg->findInt32("trackIndex", &trackIndex));
  440. const sp<AMediaExtractorWrapper> extractor = mExtractors.itemAt(trackIndex);
  441. Track* track;
  442. AString mime;
  443. media_track_type trackType, counterpartType;
  444. sp<AMediaFormatWrapper> format = extractor->getTrackFormat(trackIndex);
  445. format->getString(AMEDIAFORMAT_KEY_MIME, &mime);
  446. if (!strncasecmp(mime.c_str(), "audio/", 6)) {
  447. track = &mAudioTrack;
  448. trackType = MEDIA_TRACK_TYPE_AUDIO;
  449. counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
  450. } else {
  451. CHECK(!strncasecmp(mime.c_str(), "video/", 6));
  452. track = &mVideoTrack;
  453. trackType = MEDIA_TRACK_TYPE_VIDEO;
  454. counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
  455. }
  456. track->mExtractor = extractor;
  457. track->mExtractor->selectSingleTrack(trackIndex);
  458. track->mIndex = trackIndex;
  459. ++mAudioDataGeneration;
  460. ++mVideoDataGeneration;
  461. int64_t timeUs, actualTimeUs;
  462. const bool formatChange = true;
  463. if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
  464. timeUs = mAudioLastDequeueTimeUs;
  465. } else {
  466. timeUs = mVideoLastDequeueTimeUs;
  467. }
  468. readBuffer(trackType, timeUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */,
  469. &actualTimeUs, formatChange);
  470. readBuffer(counterpartType, -1, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */,
  471. NULL, !formatChange);
  472. ALOGV("timeUs %lld actualTimeUs %lld", (long long)timeUs, (long long)actualTimeUs);
  473. break;
  474. }
  475. case kWhatSeek:
  476. {
  477. onSeek(msg);
  478. break;
  479. }
  480. case kWhatReadBuffer:
  481. {
  482. onReadBuffer(msg);
  483. break;
  484. }
  485. case kWhatPollBuffering:
  486. {
  487. int32_t generation;
  488. CHECK(msg->findInt32("generation", &generation));
  489. if (generation == mPollBufferingGeneration) {
  490. onPollBuffering();
  491. }
  492. break;
  493. }
  494. default:
  495. Source::onMessageReceived(msg);
  496. break;
  497. }
  498. }
  499. void NuPlayer2::GenericSource2::fetchTextData(
  500. uint32_t sendWhat,
  501. media_track_type type,
  502. int32_t curGen,
  503. const sp<AnotherPacketSource>& packets,
  504. const sp<AMessage>& msg) {
  505. int32_t msgGeneration;
  506. CHECK(msg->findInt32("generation", &msgGeneration));
  507. if (msgGeneration != curGen) {
  508. // stale
  509. return;
  510. }
  511. int32_t avail;
  512. if (packets->hasBufferAvailable(&avail)) {
  513. return;
  514. }
  515. int64_t timeUs;
  516. CHECK(msg->findInt64("timeUs", &timeUs));
  517. int64_t subTimeUs = 0;
  518. readBuffer(type, timeUs, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */, &subTimeUs);
  519. status_t eosResult;
  520. if (!packets->hasBufferAvailable(&eosResult)) {
  521. return;
  522. }
  523. if (msg->what() == kWhatFetchSubtitleData) {
  524. subTimeUs -= 1000000ll; // send subtile data one second earlier
  525. }
  526. sp<AMessage> msg2 = new AMessage(sendWhat, this);
  527. msg2->setInt32("generation", msgGeneration);
  528. mMediaClock->addTimer(msg2, subTimeUs);
  529. }
  530. void NuPlayer2::GenericSource2::sendTextData(
  531. uint32_t what,
  532. media_track_type type,
  533. int32_t curGen,
  534. const sp<AnotherPacketSource>& packets,
  535. const sp<AMessage>& msg) {
  536. int32_t msgGeneration;
  537. CHECK(msg->findInt32("generation", &msgGeneration));
  538. if (msgGeneration != curGen) {
  539. // stale
  540. return;
  541. }
  542. int64_t subTimeUs;
  543. if (packets->nextBufferTime(&subTimeUs) != OK) {
  544. return;
  545. }
  546. int64_t nextSubTimeUs;
  547. readBuffer(type, -1, MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC /* mode */, &nextSubTimeUs);
  548. sp<ABuffer> buffer;
  549. status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
  550. if (dequeueStatus == OK) {
  551. sp<AMessage> notify = dupNotify();
  552. notify->setInt32("what", what);
  553. notify->setBuffer("buffer", buffer);
  554. notify->post();
  555. if (msg->what() == kWhatSendSubtitleData) {
  556. nextSubTimeUs -= 1000000ll; // send subtile data one second earlier
  557. }
  558. mMediaClock->addTimer(msg, nextSubTimeUs);
  559. }
  560. }
  561. void NuPlayer2::GenericSource2::sendGlobalTextData(
  562. uint32_t what,
  563. int32_t curGen,
  564. sp<AMessage> msg) {
  565. int32_t msgGeneration;
  566. CHECK(msg->findInt32("generation", &msgGeneration));
  567. if (msgGeneration != curGen) {
  568. // stale
  569. return;
  570. }
  571. void *data = NULL;
  572. size_t size = 0;
  573. if (mTimedTextTrack.mExtractor->getTrackFormat(mTimedTextTrack.mIndex)->getBuffer(
  574. "text", &data, &size)) {
  575. mGlobalTimedText = new ABuffer(size);
  576. if (mGlobalTimedText->data()) {
  577. memcpy(mGlobalTimedText->data(), data, size);
  578. sp<AMessage> globalMeta = mGlobalTimedText->meta();
  579. globalMeta->setInt64("timeUs", 0);
  580. globalMeta->setString("mime", MEDIA_MIMETYPE_TEXT_3GPP);
  581. globalMeta->setInt32("global", 1);
  582. sp<AMessage> notify = dupNotify();
  583. notify->setInt32("what", what);
  584. notify->setBuffer("buffer", mGlobalTimedText);
  585. notify->post();
  586. }
  587. }
  588. }
  589. sp<AMessage> NuPlayer2::GenericSource2::getFormat(bool audio) {
  590. Mutex::Autolock _l(mLock);
  591. return getFormat_l(audio);
  592. }
  593. sp<MetaData> NuPlayer2::GenericSource2::getFormatMeta(bool audio) {
  594. Mutex::Autolock _l(mLock);
  595. return getFormatMeta_l(audio);
  596. }
  597. sp<AMessage> NuPlayer2::GenericSource2::getFormat_l(bool audio) {
  598. sp<AMediaExtractorWrapper> extractor = audio ? mAudioTrack.mExtractor : mVideoTrack.mExtractor;
  599. size_t trackIndex = audio ? mAudioTrack.mIndex : mVideoTrack.mIndex;
  600. if (extractor == NULL) {
  601. return NULL;
  602. }
  603. return extractor->getTrackFormat(trackIndex)->toAMessage();
  604. }
  605. sp<MetaData> NuPlayer2::GenericSource2::getFormatMeta_l(bool audio) {
  606. sp<AMediaExtractorWrapper> extractor = audio ? mAudioTrack.mExtractor : mVideoTrack.mExtractor;
  607. size_t trackIndex = audio ? mAudioTrack.mIndex : mVideoTrack.mIndex;
  608. if (extractor == NULL) {
  609. return NULL;
  610. }
  611. return convertMediaFormatWrapperToMetaData(extractor->getTrackFormat(trackIndex));
  612. }
  613. status_t NuPlayer2::GenericSource2::dequeueAccessUnit(
  614. bool audio, sp<ABuffer> *accessUnit) {
  615. Mutex::Autolock _l(mLock);
  616. // If has gone through stop/releaseDrm sequence, we no longer send down any buffer b/c
  617. // the codec's crypto object has gone away (b/37960096).
  618. // Note: This will be unnecessary when stop() changes behavior and releases codec (b/35248283).
  619. if (!mStarted && mIsDrmReleased) {
  620. return -EWOULDBLOCK;
  621. }
  622. Track *track = audio ? &mAudioTrack : &mVideoTrack;
  623. if (track->mExtractor == NULL) {
  624. return -EWOULDBLOCK;
  625. }
  626. status_t finalResult;
  627. if (!track->mPackets->hasBufferAvailable(&finalResult)) {
  628. if (finalResult == OK) {
  629. postReadBuffer(
  630. audio ? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
  631. return -EWOULDBLOCK;
  632. }
  633. return finalResult;
  634. }
  635. status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
  636. // start pulling in more buffers if cache is running low
  637. // so that decoder has less chance of being starved
  638. if (!mIsStreaming) {
  639. if (track->mPackets->getAvailableBufferCount(&finalResult) < 2) {
  640. postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
  641. }
  642. } else {
  643. int64_t durationUs = track->mPackets->getBufferedDurationUs(&finalResult);
  644. // TODO: maxRebufferingMarkMs could be larger than
  645. // mBufferingSettings.mResumePlaybackMarkMs
  646. int64_t restartBufferingMarkUs =
  647. mBufferingSettings.mResumePlaybackMarkMs * 1000ll / 2;
  648. if (finalResult == OK) {
  649. if (durationUs < restartBufferingMarkUs) {
  650. postReadBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO);
  651. }
  652. if (track->mPackets->getAvailableBufferCount(&finalResult) < 2
  653. && !mSentPauseOnBuffering && !mPreparing) {
  654. mSentPauseOnBuffering = true;
  655. sp<AMessage> notify = dupNotify();
  656. notify->setInt32("what", kWhatPauseOnBufferingStart);
  657. notify->post();
  658. }
  659. }
  660. }
  661. if (result != OK) {
  662. if (mSubtitleTrack.mExtractor != NULL) {
  663. mSubtitleTrack.mPackets->clear();
  664. mFetchSubtitleDataGeneration++;
  665. }
  666. if (mTimedTextTrack.mExtractor != NULL) {
  667. mTimedTextTrack.mPackets->clear();
  668. mFetchTimedTextDataGeneration++;
  669. }
  670. return result;
  671. }
  672. int64_t timeUs;
  673. status_t eosResult; // ignored
  674. CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
  675. if (audio) {
  676. mAudioLastDequeueTimeUs = timeUs;
  677. } else {
  678. mVideoLastDequeueTimeUs = timeUs;
  679. }
  680. if (mSubtitleTrack.mExtractor != NULL
  681. && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
  682. sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
  683. msg->setInt64("timeUs", timeUs);
  684. msg->setInt32("generation", mFetchSubtitleDataGeneration);
  685. msg->post();
  686. }
  687. if (mTimedTextTrack.mExtractor != NULL
  688. && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
  689. sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
  690. msg->setInt64("timeUs", timeUs);
  691. msg->setInt32("generation", mFetchTimedTextDataGeneration);
  692. msg->post();
  693. }
  694. return result;
  695. }
  696. status_t NuPlayer2::GenericSource2::getDuration(int64_t *durationUs) {
  697. Mutex::Autolock _l(mLock);
  698. *durationUs = mDurationUs;
  699. return OK;
  700. }
  701. size_t NuPlayer2::GenericSource2::getTrackCount() const {
  702. Mutex::Autolock _l(mLock);
  703. return mExtractors.size();
  704. }
  705. sp<AMessage> NuPlayer2::GenericSource2::getTrackInfo(size_t trackIndex) const {
  706. Mutex::Autolock _l(mLock);
  707. size_t trackCount = mExtractors.size();
  708. if (trackIndex >= trackCount) {
  709. return NULL;
  710. }
  711. sp<AMessage> format = mExtractors.itemAt(trackIndex)->getTrackFormat(trackIndex)->toAMessage();
  712. if (format == NULL) {
  713. ALOGE("no metadata for track %zu", trackIndex);
  714. return NULL;
  715. }
  716. AString mime;
  717. CHECK(format->findString(AMEDIAFORMAT_KEY_MIME, &mime));
  718. int32_t trackType;
  719. if (!strncasecmp(mime.c_str(), "video/", 6)) {
  720. trackType = MEDIA_TRACK_TYPE_VIDEO;
  721. } else if (!strncasecmp(mime.c_str(), "audio/", 6)) {
  722. trackType = MEDIA_TRACK_TYPE_AUDIO;
  723. } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_TEXT_3GPP)) {
  724. trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
  725. } else {
  726. trackType = MEDIA_TRACK_TYPE_UNKNOWN;
  727. }
  728. format->setInt32("type", trackType);
  729. AString lang;
  730. if (!format->findString("language", &lang)) {
  731. format->setString("language", "und");
  732. }
  733. if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
  734. int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
  735. format->findInt32(AMEDIAFORMAT_KEY_IS_AUTOSELECT, &isAutoselect);
  736. format->findInt32(AMEDIAFORMAT_KEY_IS_DEFAULT, &isDefault);
  737. format->findInt32(AMEDIAFORMAT_KEY_IS_FORCED_SUBTITLE, &isForced);
  738. format->setInt32("auto", !!isAutoselect);
  739. format->setInt32("default", !!isDefault);
  740. format->setInt32("forced", !!isForced);
  741. }
  742. return format;
  743. }
  744. ssize_t NuPlayer2::GenericSource2::getSelectedTrack(media_track_type type) const {
  745. Mutex::Autolock _l(mLock);
  746. const Track *track = NULL;
  747. switch (type) {
  748. case MEDIA_TRACK_TYPE_VIDEO:
  749. track = &mVideoTrack;
  750. break;
  751. case MEDIA_TRACK_TYPE_AUDIO:
  752. track = &mAudioTrack;
  753. break;
  754. case MEDIA_TRACK_TYPE_TIMEDTEXT:
  755. track = &mTimedTextTrack;
  756. break;
  757. case MEDIA_TRACK_TYPE_SUBTITLE:
  758. track = &mSubtitleTrack;
  759. break;
  760. default:
  761. break;
  762. }
  763. if (track != NULL && track->mExtractor != NULL) {
  764. return track->mIndex;
  765. }
  766. return -1;
  767. }
  768. status_t NuPlayer2::GenericSource2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
  769. Mutex::Autolock _l(mLock);
  770. ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
  771. if (trackIndex >= mExtractors.size()) {
  772. return BAD_INDEX;
  773. }
  774. if (!select) {
  775. Track* track = NULL;
  776. if (mSubtitleTrack.mExtractor != NULL && trackIndex == mSubtitleTrack.mIndex) {
  777. track = &mSubtitleTrack;
  778. mFetchSubtitleDataGeneration++;
  779. } else if (mTimedTextTrack.mExtractor != NULL && trackIndex == mTimedTextTrack.mIndex) {
  780. track = &mTimedTextTrack;
  781. mFetchTimedTextDataGeneration++;
  782. }
  783. if (track == NULL) {
  784. return INVALID_OPERATION;
  785. }
  786. track->mExtractor = NULL;
  787. track->mPackets->clear();
  788. return OK;
  789. }
  790. const sp<AMediaExtractorWrapper> extractor = mExtractors.itemAt(trackIndex);
  791. sp<MetaData> meta = convertMediaFormatWrapperToMetaData(extractor->getTrackFormat(trackIndex));
  792. const char *mime;
  793. CHECK(meta->findCString(kKeyMIMEType, &mime));
  794. if (!strncasecmp(mime, "text/", 5)) {
  795. bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
  796. Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
  797. if (track->mExtractor != NULL && track->mIndex == trackIndex) {
  798. return OK;
  799. }
  800. track->mIndex = trackIndex;
  801. track->mExtractor = mExtractors.itemAt(trackIndex);
  802. track->mExtractor->selectSingleTrack(trackIndex);
  803. if (track->mPackets == NULL) {
  804. track->mPackets = new AnotherPacketSource(meta);
  805. } else {
  806. track->mPackets->clear();
  807. track->mPackets->setFormat(meta);
  808. }
  809. if (isSubtitle) {
  810. mFetchSubtitleDataGeneration++;
  811. } else {
  812. mFetchTimedTextDataGeneration++;
  813. }
  814. status_t eosResult; // ignored
  815. if (mSubtitleTrack.mExtractor != NULL
  816. && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
  817. sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, this);
  818. msg->setInt64("timeUs", timeUs);
  819. msg->setInt32("generation", mFetchSubtitleDataGeneration);
  820. msg->post();
  821. }
  822. sp<AMessage> msg2 = new AMessage(kWhatSendGlobalTimedTextData, this);
  823. msg2->setInt32("generation", mFetchTimedTextDataGeneration);
  824. msg2->post();
  825. if (mTimedTextTrack.mExtractor != NULL
  826. && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
  827. sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, this);
  828. msg->setInt64("timeUs", timeUs);
  829. msg->setInt32("generation", mFetchTimedTextDataGeneration);
  830. msg->post();
  831. }
  832. return OK;
  833. } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
  834. bool audio = !strncasecmp(mime, "audio/", 6);
  835. Track *track = audio ? &mAudioTrack : &mVideoTrack;
  836. if (track->mExtractor != NULL && track->mIndex == trackIndex) {
  837. return OK;
  838. }
  839. sp<AMessage> msg = new AMessage(kWhatChangeAVSource, this);
  840. msg->setInt32("trackIndex", trackIndex);
  841. msg->post();
  842. return OK;
  843. }
  844. return INVALID_OPERATION;
  845. }
  846. status_t NuPlayer2::GenericSource2::seekTo(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
  847. ALOGV("seekTo: %lld, %d", (long long)seekTimeUs, mode);
  848. sp<AMessage> msg = new AMessage(kWhatSeek, this);
  849. msg->setInt64("seekTimeUs", seekTimeUs);
  850. msg->setInt32("mode", mode);
  851. // Need to call readBuffer on |mLooper| to ensure the calls to
  852. // IMediaSource::read* are serialized. Note that IMediaSource::read*
  853. // is called without |mLock| acquired and MediaSource is not thread safe.
  854. sp<AMessage> response;
  855. status_t err = msg->postAndAwaitResponse(&response);
  856. if (err == OK && response != NULL) {
  857. CHECK(response->findInt32("err", &err));
  858. }
  859. return err;
  860. }
  861. void NuPlayer2::GenericSource2::onSeek(const sp<AMessage>& msg) {
  862. int64_t seekTimeUs;
  863. int32_t mode;
  864. CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
  865. CHECK(msg->findInt32("mode", &mode));
  866. sp<AMessage> response = new AMessage;
  867. status_t err = doSeek(seekTimeUs, (MediaPlayer2SeekMode)mode);
  868. response->setInt32("err", err);
  869. sp<AReplyToken> replyID;
  870. CHECK(msg->senderAwaitsResponse(&replyID));
  871. response->postReply(replyID);
  872. }
  873. status_t NuPlayer2::GenericSource2::doSeek(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
  874. if (mVideoTrack.mExtractor != NULL) {
  875. ++mVideoDataGeneration;
  876. int64_t actualTimeUs;
  877. readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, mode, &actualTimeUs);
  878. if (mode != MediaPlayer2SeekMode::SEEK_CLOSEST) {
  879. seekTimeUs = actualTimeUs;
  880. }
  881. mVideoLastDequeueTimeUs = actualTimeUs;
  882. }
  883. if (mAudioTrack.mExtractor != NULL) {
  884. ++mAudioDataGeneration;
  885. readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs, MediaPlayer2SeekMode::SEEK_CLOSEST);
  886. mAudioLastDequeueTimeUs = seekTimeUs;
  887. }
  888. if (mSubtitleTrack.mExtractor != NULL) {
  889. mSubtitleTrack.mPackets->clear();
  890. mFetchSubtitleDataGeneration++;
  891. }
  892. if (mTimedTextTrack.mExtractor != NULL) {
  893. mTimedTextTrack.mPackets->clear();
  894. mFetchTimedTextDataGeneration++;
  895. }
  896. ++mPollBufferingGeneration;
  897. schedulePollBuffering();
  898. return OK;
  899. }
  900. sp<ABuffer> NuPlayer2::GenericSource2::mediaBufferToABuffer(
  901. MediaBufferBase* mb,
  902. media_track_type trackType) {
  903. bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
  904. size_t outLength = mb->range_length();
  905. if (audio && mAudioIsVorbis) {
  906. outLength += sizeof(int32_t);
  907. }
  908. sp<ABuffer> ab;
  909. if (mIsDrmProtected) {
  910. // Modular DRM
  911. // Enabled for both video/audio so 1) media buffer is reused without extra copying
  912. // 2) meta data can be retrieved in onInputBufferFetched for calling queueSecureInputBuffer.
  913. // data is already provided in the buffer
  914. ab = new ABuffer(NULL, mb->range_length());
  915. ab->meta()->setObject("mediaBufferHolder", new MediaBufferHolder(mb));
  916. // Modular DRM: Required b/c of the above add_ref.
  917. // If ref>0, there must be an observer, or it'll crash at release().
  918. // TODO: MediaBuffer might need to be revised to ease such need.
  919. mb->setObserver(this);
  920. // setMediaBufferBase() interestingly doesn't increment the ref count on its own.
  921. // Extra increment (since we want to keep mb alive and attached to ab beyond this function
  922. // call. This is to counter the effect of mb->release() towards the end.
  923. mb->add_ref();
  924. } else {
  925. ab = new ABuffer(outLength);
  926. memcpy(ab->data(),
  927. (const uint8_t *)mb->data() + mb->range_offset(),
  928. mb->range_length());
  929. }
  930. if (audio && mAudioIsVorbis) {
  931. int32_t numPageSamples;
  932. if (!mb->meta_data().findInt32(kKeyValidSamples, &numPageSamples)) {
  933. numPageSamples = -1;
  934. }
  935. uint8_t* abEnd = ab->data() + mb->range_length();
  936. memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
  937. }
  938. sp<AMessage> meta = ab->meta();
  939. int64_t timeUs;
  940. CHECK(mb->meta_data().findInt64(kKeyTime, &timeUs));
  941. meta->setInt64("timeUs", timeUs);
  942. if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
  943. int32_t layerId;
  944. if (mb->meta_data().findInt32(kKeyTemporalLayerId, &layerId)) {
  945. meta->setInt32("temporal-layer-id", layerId);
  946. }
  947. }
  948. if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
  949. AString mime;
  950. sp<AMediaExtractorWrapper> extractor = mTimedTextTrack.mExtractor;
  951. size_t trackIndex = mTimedTextTrack.mIndex;
  952. CHECK(extractor != NULL
  953. && extractor->getTrackFormat(trackIndex)->getString(AMEDIAFORMAT_KEY_MIME, &mime));
  954. meta->setString("mime", mime.c_str());
  955. }
  956. int64_t durationUs;
  957. if (mb->meta_data().findInt64(kKeyDuration, &durationUs)) {
  958. meta->setInt64("durationUs", durationUs);
  959. }
  960. if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
  961. meta->setInt32(AMEDIAFORMAT_KEY_TRACK_INDEX, mSubtitleTrack.mIndex);
  962. }
  963. uint32_t dataType; // unused
  964. const void *seiData;
  965. size_t seiLength;
  966. if (mb->meta_data().findData(kKeySEI, &dataType, &seiData, &seiLength)) {
  967. sp<ABuffer> sei = ABuffer::CreateAsCopy(seiData, seiLength);;
  968. meta->setBuffer("sei", sei);
  969. }
  970. const void *mpegUserDataPointer;
  971. size_t mpegUserDataLength;
  972. if (mb->meta_data().findData(
  973. kKeyMpegUserData, &dataType, &mpegUserDataPointer, &mpegUserDataLength)) {
  974. sp<ABuffer> mpegUserData = ABuffer::CreateAsCopy(mpegUserDataPointer, mpegUserDataLength);
  975. meta->setBuffer(AMEDIAFORMAT_KEY_MPEG_USER_DATA, mpegUserData);
  976. }
  977. mb->release();
  978. mb = NULL;
  979. return ab;
  980. }
  981. int32_t NuPlayer2::GenericSource2::getDataGeneration(media_track_type type) const {
  982. int32_t generation = -1;
  983. switch (type) {
  984. case MEDIA_TRACK_TYPE_VIDEO:
  985. generation = mVideoDataGeneration;
  986. break;
  987. case MEDIA_TRACK_TYPE_AUDIO:
  988. generation = mAudioDataGeneration;
  989. break;
  990. case MEDIA_TRACK_TYPE_TIMEDTEXT:
  991. generation = mFetchTimedTextDataGeneration;
  992. break;
  993. case MEDIA_TRACK_TYPE_SUBTITLE:
  994. generation = mFetchSubtitleDataGeneration;
  995. break;
  996. default:
  997. break;
  998. }
  999. return generation;
  1000. }
  1001. void NuPlayer2::GenericSource2::postReadBuffer(media_track_type trackType) {
  1002. if ((mPendingReadBufferTypes & (1 << trackType)) == 0) {
  1003. mPendingReadBufferTypes |= (1 << trackType);
  1004. sp<AMessage> msg = new AMessage(kWhatReadBuffer, this);
  1005. msg->setInt32("trackType", trackType);
  1006. msg->post();
  1007. }
  1008. }
  1009. void NuPlayer2::GenericSource2::onReadBuffer(const sp<AMessage>& msg) {
  1010. int32_t tmpType;
  1011. CHECK(msg->findInt32("trackType", &tmpType));
  1012. media_track_type trackType = (media_track_type)tmpType;
  1013. mPendingReadBufferTypes &= ~(1 << trackType);
  1014. readBuffer(trackType);
  1015. }
  1016. void NuPlayer2::GenericSource2::readBuffer(
  1017. media_track_type trackType, int64_t seekTimeUs, MediaPlayer2SeekMode mode,
  1018. int64_t *actualTimeUs, bool formatChange) {
  1019. Track *track;
  1020. size_t maxBuffers = 1;
  1021. switch (trackType) {
  1022. case MEDIA_TRACK_TYPE_VIDEO:
  1023. track = &mVideoTrack;
  1024. maxBuffers = 8; // too large of a number may influence seeks
  1025. break;
  1026. case MEDIA_TRACK_TYPE_AUDIO:
  1027. track = &mAudioTrack;
  1028. maxBuffers = 64;
  1029. break;
  1030. case MEDIA_TRACK_TYPE_SUBTITLE:
  1031. track = &mSubtitleTrack;
  1032. break;
  1033. case MEDIA_TRACK_TYPE_TIMEDTEXT:
  1034. track = &mTimedTextTrack;
  1035. break;
  1036. default:
  1037. TRESPASS();
  1038. }
  1039. if (track->mExtractor == NULL) {
  1040. return;
  1041. }
  1042. if (actualTimeUs) {
  1043. *actualTimeUs = seekTimeUs;
  1044. }
  1045. bool seeking = false;
  1046. sp<AMediaExtractorWrapper> extractor = track->mExtractor;
  1047. if (seekTimeUs >= 0) {
  1048. extractor->seekTo(seekTimeUs, mode);
  1049. seeking = true;
  1050. }
  1051. int32_t generation = getDataGeneration(trackType);
  1052. for (size_t numBuffers = 0; numBuffers < maxBuffers; ) {
  1053. Vector<sp<ABuffer> > aBuffers;
  1054. mLock.unlock();
  1055. sp<AMediaFormatWrapper> format;
  1056. ssize_t sampleSize = -1;
  1057. status_t err = extractor->getSampleFormat(format);
  1058. if (err == OK) {
  1059. sampleSize = extractor->getSampleSize();
  1060. }
  1061. if (err != OK || sampleSize < 0) {
  1062. mLock.lock();
  1063. track->mPackets->signalEOS(err != OK ? err : ERROR_END_OF_STREAM);
  1064. break;
  1065. }
  1066. sp<ABuffer> abuf = new ABuffer(sampleSize);
  1067. sampleSize = extractor->readSampleData(abuf);
  1068. mLock.lock();
  1069. // in case track has been changed since we don't have lock for some time.
  1070. if (generation != getDataGeneration(trackType)) {
  1071. break;
  1072. }
  1073. int64_t timeUs = extractor->getSampleTime();
  1074. if (timeUs < 0) {
  1075. track->mPackets->signalEOS(ERROR_MALFORMED);
  1076. break;
  1077. }
  1078. sp<AMessage> meta = abuf->meta();
  1079. format->writeToAMessage(meta);
  1080. meta->setInt64("timeUs", timeUs);
  1081. if (trackType == MEDIA_TRACK_TYPE_AUDIO) {
  1082. mAudioTimeUs = timeUs;
  1083. } else if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
  1084. mVideoTimeUs = timeUs;
  1085. }
  1086. sp<AMediaCodecCryptoInfoWrapper> cryptInfo = extractor->getSampleCryptoInfo();
  1087. if (cryptInfo != NULL) {
  1088. meta->setObject("cryptInfo", cryptInfo);
  1089. }
  1090. queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);
  1091. if (numBuffers == 0 && actualTimeUs != nullptr) {
  1092. *actualTimeUs = timeUs;
  1093. }
  1094. if (seeking) {
  1095. if (meta != nullptr && mode == MediaPlayer2SeekMode::SEEK_CLOSEST
  1096. && seekTimeUs > timeUs) {
  1097. sp<AMessage> extra = new AMessage;
  1098. extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
  1099. meta->setMessage("extra", extra);
  1100. }
  1101. }
  1102. track->mPackets->queueAccessUnit(abuf);
  1103. formatChange = false;
  1104. seeking = false;
  1105. ++numBuffers;
  1106. extractor->advance();
  1107. }
  1108. if (mIsStreaming
  1109. && (trackType == MEDIA_TRACK_TYPE_VIDEO || trackType == MEDIA_TRACK_TYPE_AUDIO)) {
  1110. status_t finalResult;
  1111. int64_t durationUs = track->mPackets->getBufferedDurationUs(&finalResult);
  1112. // TODO: maxRebufferingMarkMs could be larger than
  1113. // mBufferingSettings.mResumePlaybackMarkMs
  1114. int64_t markUs = (mPreparing ? mBufferingSettings.mInitialMarkMs
  1115. : mBufferingSettings.mResumePlaybackMarkMs) * 1000ll;
  1116. if (finalResult == ERROR_END_OF_STREAM || durationUs >= markUs) {
  1117. if (mPreparing || mSentPauseOnBuffering) {
  1118. Track *counterTrack =
  1119. (trackType == MEDIA_TRACK_TYPE_VIDEO ? &mAudioTrack : &mVideoTrack);
  1120. if (counterTrack->mExtractor != NULL) {
  1121. durationUs = counterTrack->mPackets->getBufferedDurationUs(&finalResult);
  1122. }
  1123. if (finalResult == ERROR_END_OF_STREAM || durationUs >= markUs) {
  1124. if (mPreparing) {
  1125. notifyPrepared();
  1126. mPreparing = false;
  1127. } else {
  1128. mSentPauseOnBuffering = false;
  1129. sp<AMessage> notify = dupNotify();
  1130. notify->setInt32("what", kWhatResumeOnBufferingEnd);
  1131. notify->post();
  1132. }
  1133. }
  1134. }
  1135. return;
  1136. }
  1137. postReadBuffer(trackType);
  1138. }
  1139. }
  1140. void NuPlayer2::GenericSource2::queueDiscontinuityIfNeeded(
  1141. bool seeking, bool formatChange, media_track_type trackType, Track *track) {
  1142. // formatChange && seeking: track whose source is changed during selection
  1143. // formatChange && !seeking: track whose source is not changed during selection
  1144. // !formatChange: normal seek
  1145. if ((seeking || formatChange)
  1146. && (trackType == MEDIA_TRACK_TYPE_AUDIO
  1147. || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
  1148. ATSParser::DiscontinuityType type = (formatChange && seeking)
  1149. ? ATSParser::DISCONTINUITY_FORMATCHANGE
  1150. : ATSParser::DISCONTINUITY_NONE;
  1151. track->mPackets->queueDiscontinuity(type, NULL /* extra */, true /* discard */);
  1152. }
  1153. }
  1154. void NuPlayer2::GenericSource2::notifyBufferingUpdate(int32_t percentage) {
  1155. // Buffering percent could go backward as it's estimated from remaining
  1156. // data and last access time. This could cause the buffering position
  1157. // drawn on media control to jitter slightly. Remember previously reported
  1158. // percentage and don't allow it to go backward.
  1159. if (percentage < mPrevBufferPercentage) {
  1160. percentage = mPrevBufferPercentage;
  1161. } else if (percentage > 100) {
  1162. percentage = 100;
  1163. }
  1164. mPrevBufferPercentage = percentage;
  1165. ALOGV("notifyBufferingUpdate: buffering %d%%", percentage);
  1166. sp<AMessage> notify = dupNotify();
  1167. notify->setInt32("what", kWhatBufferingUpdate);
  1168. notify->setInt32("percentage", percentage);
  1169. notify->post();
  1170. }
  1171. void NuPlayer2::GenericSource2::schedulePollBuffering() {
  1172. if (mIsStreaming) {
  1173. sp<AMessage> msg = new AMessage(kWhatPollBuffering, this);
  1174. msg->setInt32("generation", mPollBufferingGeneration);
  1175. // Enquires buffering status every second.
  1176. msg->post(1000000ll);
  1177. }
  1178. }
  1179. void NuPlayer2::GenericSource2::onPollBuffering() {
  1180. int64_t cachedDurationUs = -1ll;
  1181. sp<AMediaExtractorWrapper> extractor;
  1182. if (mVideoTrack.mExtractor != NULL) {
  1183. extractor = mVideoTrack.mExtractor;
  1184. } else if (mAudioTrack.mExtractor != NULL) {
  1185. extractor = mAudioTrack.mExtractor;
  1186. }
  1187. if (extractor != NULL) {
  1188. cachedDurationUs = extractor->getCachedDuration();
  1189. }
  1190. if (cachedDurationUs >= 0ll) {
  1191. ssize_t sampleSize = extractor->getSampleSize();
  1192. if (sampleSize >= 0ll) {
  1193. int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
  1194. int percentage = 100.0 * cachedPosUs / mDurationUs;
  1195. if (percentage > 100) {
  1196. percentage = 100;
  1197. }
  1198. notifyBufferingUpdate(percentage);
  1199. ALOGV("onPollBuffering: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);
  1200. } else {
  1201. notifyBufferingUpdate(100);
  1202. ALOGV("onPollBuffering: EOS");
  1203. }
  1204. }
  1205. schedulePollBuffering();
  1206. }
  1207. // Modular DRM
  1208. status_t NuPlayer2::GenericSource2::prepareDrm(
  1209. const uint8_t uuid[16],
  1210. const Vector<uint8_t> &drmSessionId,
  1211. sp<AMediaCryptoWrapper> *outCrypto) {
  1212. Mutex::Autolock _l(mLock);
  1213. ALOGV("prepareDrm");
  1214. mIsDrmProtected = false;
  1215. mIsDrmReleased = false;
  1216. mIsSecure = false;
  1217. status_t status = OK;
  1218. sp<AMediaCryptoWrapper> crypto =
  1219. new AMediaCryptoWrapper(uuid, drmSessionId.array(), drmSessionId.size());
  1220. if (crypto == NULL) {
  1221. ALOGE("prepareDrm: failed to create crypto.");
  1222. return UNKNOWN_ERROR;
  1223. }
  1224. ALOGV("prepareDrm: crypto created for uuid: %s",
  1225. DrmUUID::toHexString(uuid).string());
  1226. *outCrypto = crypto;
  1227. // as long a there is an active crypto
  1228. mIsDrmProtected = true;
  1229. if (mMimes.size() == 0) {
  1230. status = UNKNOWN_ERROR;
  1231. ALOGE("prepareDrm: Unexpected. Must have at least one track. status: %d", status);
  1232. return status;
  1233. }
  1234. // first mime in this list is either the video track, or the first audio track
  1235. const char *mime = mMimes[0].string();
  1236. mIsSecure = crypto->requiresSecureDecoderComponent(mime);
  1237. ALOGV("prepareDrm: requiresSecureDecoderComponent mime: %s isSecure: %d",
  1238. mime, mIsSecure);
  1239. // Checking the member flags while in the looper to send out the notification.
  1240. // The legacy mDecryptHandle!=NULL check (for FLAG_PROTECTED) is equivalent to mIsDrmProtected.
  1241. notifyFlagsChanged(
  1242. (mIsSecure ? FLAG_SECURE : 0) |
  1243. // Setting "protected screen" only for L1: b/38390836
  1244. (mIsSecure ? FLAG_PROTECTED : 0) |
  1245. FLAG_CAN_PAUSE |
  1246. FLAG_CAN_SEEK_BACKWARD |
  1247. FLAG_CAN_SEEK_FORWARD |
  1248. FLAG_CAN_SEEK);
  1249. if (status == OK) {
  1250. ALOGV("prepareDrm: mCrypto: %p", outCrypto->get());
  1251. ALOGD("prepareDrm ret: %d ", status);
  1252. } else {
  1253. ALOGE("prepareDrm err: %d", status);
  1254. }
  1255. return status;
  1256. }
  1257. status_t NuPlayer2::GenericSource2::releaseDrm() {
  1258. Mutex::Autolock _l(mLock);
  1259. ALOGV("releaseDrm");
  1260. if (mIsDrmProtected) {
  1261. mIsDrmProtected = false;
  1262. // to prevent returning any more buffer after stop/releaseDrm (b/37960096)
  1263. mIsDrmReleased = true;
  1264. ALOGV("releaseDrm: mIsDrmProtected is reset.");
  1265. } else {
  1266. ALOGE("releaseDrm: mIsDrmProtected is already false.");
  1267. }
  1268. return OK;
  1269. }
  1270. status_t NuPlayer2::GenericSource2::checkDrmInfo()
  1271. {
  1272. // clearing the flag at prepare in case the player is reused after stop/releaseDrm with the
  1273. // same source without being reset (called by prepareAsync/initFromDataSource)
  1274. mIsDrmReleased = false;
  1275. if (mExtractor == NULL) {
  1276. ALOGV("checkDrmInfo: No extractor");
  1277. return OK; // letting the caller responds accordingly
  1278. }
  1279. PsshInfo *psshInfo = mExtractor->getPsshInfo();
  1280. if (psshInfo == NULL) {
  1281. ALOGV("checkDrmInfo: No PSSH");
  1282. return OK; // source without DRM info
  1283. }
  1284. PlayerMessage playerMsg;
  1285. status_t ret = NuPlayer2Drm::retrieveDrmInfo(psshInfo, &playerMsg);
  1286. ALOGV("checkDrmInfo: MEDIA_DRM_INFO PSSH drm info size: %d", (int)playerMsg.ByteSize());
  1287. if (ret != OK) {
  1288. ALOGE("checkDrmInfo: failed to retrive DrmInfo %d", ret);
  1289. return UNKNOWN_ERROR;
  1290. }
  1291. int size = playerMsg.ByteSize();
  1292. sp<ABuffer> drmInfoBuf = new ABuffer(size);
  1293. playerMsg.SerializeToArray(drmInfoBuf->data(), size);
  1294. drmInfoBuf->setRange(0, size);
  1295. notifyDrmInfo(drmInfoBuf);
  1296. return OK;
  1297. }
  1298. void NuPlayer2::GenericSource2::signalBufferReturned(MediaBufferBase *buffer)
  1299. {
  1300. //ALOGV("signalBufferReturned %p refCount: %d", buffer, buffer->localRefcount());
  1301. buffer->setObserver(NULL);
  1302. buffer->release(); // this leads to delete since that there is no observor
  1303. }
  1304. } // namespace android