HTTPLiveSource2.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  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 "HTTPLiveSource2"
  18. #include <utils/Log.h>
  19. #include "HTTPLiveSource2.h"
  20. #include "AnotherPacketSource.h"
  21. #include "LiveDataSource.h"
  22. #include <media/MediaHTTPService.h>
  23. #include <media/stagefright/foundation/ABuffer.h>
  24. #include <media/stagefright/foundation/ADebug.h>
  25. #include <media/stagefright/foundation/AMessage.h>
  26. #include <media/stagefright/MediaErrors.h>
  27. #include <media/stagefright/MetaData.h>
  28. #include <media/stagefright/MediaDefs.h>
  29. #include <media/stagefright/Utils.h>
  30. // default buffer prepare/ready/underflow marks
  31. static const int kReadyMarkMs = 5000; // 5 seconds
  32. static const int kPrepareMarkMs = 1500; // 1.5 seconds
  33. namespace android {
  34. NuPlayer2::HTTPLiveSource2::HTTPLiveSource2(
  35. const sp<AMessage> &notify,
  36. const sp<MediaHTTPService> &httpService,
  37. const char *url,
  38. const KeyedVector<String8, String8> *headers)
  39. : Source(notify),
  40. mHTTPService(httpService),
  41. mURL(url),
  42. mFlags(0),
  43. mFinalResult(OK),
  44. mOffset(0),
  45. mFetchSubtitleDataGeneration(0),
  46. mFetchMetaDataGeneration(0),
  47. mHasMetadata(false),
  48. mMetadataSelected(false) {
  49. mBufferingSettings.mInitialMarkMs = kPrepareMarkMs;
  50. mBufferingSettings.mResumePlaybackMarkMs = kReadyMarkMs;
  51. if (headers) {
  52. mExtraHeaders = *headers;
  53. ssize_t index =
  54. mExtraHeaders.indexOfKey(String8("x-hide-urls-from-log"));
  55. if (index >= 0) {
  56. mFlags |= kFlagIncognito;
  57. mExtraHeaders.removeItemsAt(index);
  58. }
  59. }
  60. }
  61. NuPlayer2::HTTPLiveSource2::~HTTPLiveSource2() {
  62. if (mLiveSession != NULL) {
  63. mLiveSession->disconnect();
  64. mLiveLooper->unregisterHandler(mLiveSession->id());
  65. mLiveLooper->unregisterHandler(id());
  66. mLiveLooper->stop();
  67. mLiveSession.clear();
  68. mLiveLooper.clear();
  69. }
  70. }
  71. status_t NuPlayer2::HTTPLiveSource2::getBufferingSettings(
  72. BufferingSettings* buffering /* nonnull */) {
  73. *buffering = mBufferingSettings;
  74. return OK;
  75. }
  76. status_t NuPlayer2::HTTPLiveSource2::setBufferingSettings(const BufferingSettings& buffering) {
  77. mBufferingSettings = buffering;
  78. if (mLiveSession != NULL) {
  79. mLiveSession->setBufferingSettings(mBufferingSettings);
  80. }
  81. return OK;
  82. }
  83. // TODO: fetch data starting from |startTimeUs|
  84. void NuPlayer2::HTTPLiveSource2::prepareAsync(int64_t /* startTimeUs */) {
  85. if (mLiveLooper == NULL) {
  86. mLiveLooper = new ALooper;
  87. mLiveLooper->setName("http live2");
  88. mLiveLooper->start(false, /* runOnCallingThread */
  89. true /* canCallJava */);
  90. mLiveLooper->registerHandler(this);
  91. }
  92. sp<AMessage> notify = new AMessage(kWhatSessionNotify, this);
  93. mLiveSession = new LiveSession(
  94. notify,
  95. (mFlags & kFlagIncognito) ? LiveSession::kFlagIncognito : 0,
  96. mHTTPService);
  97. mLiveLooper->registerHandler(mLiveSession);
  98. mLiveSession->setBufferingSettings(mBufferingSettings);
  99. mLiveSession->connectAsync(
  100. mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders);
  101. }
  102. void NuPlayer2::HTTPLiveSource2::start() {
  103. }
  104. sp<MetaData> NuPlayer2::HTTPLiveSource2::getFormatMeta(bool audio) {
  105. sp<MetaData> meta;
  106. if (mLiveSession != NULL) {
  107. mLiveSession->getStreamFormatMeta(
  108. audio ? LiveSession::STREAMTYPE_AUDIO
  109. : LiveSession::STREAMTYPE_VIDEO,
  110. &meta);
  111. }
  112. return meta;
  113. }
  114. sp<AMessage> NuPlayer2::HTTPLiveSource2::getFormat(bool audio) {
  115. sp<MetaData> meta;
  116. status_t err = -EWOULDBLOCK;
  117. if (mLiveSession != NULL) {
  118. err = mLiveSession->getStreamFormatMeta(
  119. audio ? LiveSession::STREAMTYPE_AUDIO
  120. : LiveSession::STREAMTYPE_VIDEO,
  121. &meta);
  122. }
  123. sp<AMessage> format;
  124. if (err == -EWOULDBLOCK) {
  125. format = new AMessage();
  126. format->setInt32("err", err);
  127. return format;
  128. }
  129. if (err != OK || convertMetaDataToMessage(meta, &format) != OK) {
  130. return NULL;
  131. }
  132. return format;
  133. }
  134. status_t NuPlayer2::HTTPLiveSource2::feedMoreTSData() {
  135. return OK;
  136. }
  137. status_t NuPlayer2::HTTPLiveSource2::dequeueAccessUnit(
  138. bool audio, sp<ABuffer> *accessUnit) {
  139. return mLiveSession->dequeueAccessUnit(
  140. audio ? LiveSession::STREAMTYPE_AUDIO
  141. : LiveSession::STREAMTYPE_VIDEO,
  142. accessUnit);
  143. }
  144. status_t NuPlayer2::HTTPLiveSource2::getDuration(int64_t *durationUs) {
  145. return mLiveSession->getDuration(durationUs);
  146. }
  147. size_t NuPlayer2::HTTPLiveSource2::getTrackCount() const {
  148. return mLiveSession->getTrackCount();
  149. }
  150. sp<AMessage> NuPlayer2::HTTPLiveSource2::getTrackInfo(size_t trackIndex) const {
  151. return mLiveSession->getTrackInfo(trackIndex);
  152. }
  153. ssize_t NuPlayer2::HTTPLiveSource2::getSelectedTrack(media_track_type type) const {
  154. if (mLiveSession == NULL) {
  155. return -1;
  156. } else if (type == MEDIA_TRACK_TYPE_METADATA) {
  157. // MEDIA_TRACK_TYPE_METADATA is always last track
  158. // mMetadataSelected can only be true when mHasMetadata is true
  159. return mMetadataSelected ? (mLiveSession->getTrackCount() - 1) : -1;
  160. } else {
  161. return mLiveSession->getSelectedTrack(type);
  162. }
  163. }
  164. status_t NuPlayer2::HTTPLiveSource2::selectTrack(size_t trackIndex, bool select, int64_t /*timeUs*/) {
  165. if (mLiveSession == NULL) {
  166. return INVALID_OPERATION;
  167. }
  168. status_t err = INVALID_OPERATION;
  169. bool postFetchMsg = false, isSub = false;
  170. if (!mHasMetadata || trackIndex != mLiveSession->getTrackCount() - 1) {
  171. err = mLiveSession->selectTrack(trackIndex, select);
  172. postFetchMsg = select;
  173. isSub = true;
  174. } else {
  175. // metadata track; i.e. (mHasMetadata && trackIndex == mLiveSession->getTrackCount() - 1)
  176. if (mMetadataSelected && !select) {
  177. err = OK;
  178. } else if (!mMetadataSelected && select) {
  179. postFetchMsg = true;
  180. err = OK;
  181. } else {
  182. err = BAD_VALUE; // behave as LiveSession::selectTrack
  183. }
  184. mMetadataSelected = select;
  185. }
  186. if (err == OK) {
  187. int32_t &generation = isSub ? mFetchSubtitleDataGeneration : mFetchMetaDataGeneration;
  188. generation++;
  189. if (postFetchMsg) {
  190. int32_t what = isSub ? kWhatFetchSubtitleData : kWhatFetchMetaData;
  191. sp<AMessage> msg = new AMessage(what, this);
  192. msg->setInt32("generation", generation);
  193. msg->post();
  194. }
  195. }
  196. // LiveSession::selectTrack returns BAD_VALUE when selecting the currently
  197. // selected track, or unselecting a non-selected track. In this case it's an
  198. // no-op so we return OK.
  199. return (err == OK || err == BAD_VALUE) ? (status_t)OK : err;
  200. }
  201. status_t NuPlayer2::HTTPLiveSource2::seekTo(int64_t seekTimeUs, MediaPlayer2SeekMode mode) {
  202. if (mLiveSession->isSeekable()) {
  203. return mLiveSession->seekTo(seekTimeUs, mode);
  204. } else {
  205. return INVALID_OPERATION;
  206. }
  207. }
  208. void NuPlayer2::HTTPLiveSource2::pollForRawData(
  209. const sp<AMessage> &msg, int32_t currentGeneration,
  210. LiveSession::StreamType fetchType, int32_t pushWhat) {
  211. int32_t generation;
  212. CHECK(msg->findInt32("generation", &generation));
  213. if (generation != currentGeneration) {
  214. return;
  215. }
  216. sp<ABuffer> buffer;
  217. while (mLiveSession->dequeueAccessUnit(fetchType, &buffer) == OK) {
  218. sp<AMessage> notify = dupNotify();
  219. notify->setInt32("what", pushWhat);
  220. notify->setBuffer("buffer", buffer);
  221. int64_t timeUs, baseUs, delayUs;
  222. CHECK(buffer->meta()->findInt64("baseUs", &baseUs));
  223. CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
  224. delayUs = baseUs + timeUs - ALooper::GetNowUs();
  225. if (fetchType == LiveSession::STREAMTYPE_SUBTITLES) {
  226. notify->post();
  227. msg->post(delayUs > 0LL ? delayUs : 0LL);
  228. return;
  229. } else if (fetchType == LiveSession::STREAMTYPE_METADATA) {
  230. if (delayUs < -1000000LL) { // 1 second
  231. continue;
  232. }
  233. notify->post();
  234. // push all currently available metadata buffers in each invocation of pollForRawData
  235. // continue;
  236. } else {
  237. TRESPASS();
  238. }
  239. }
  240. // try again in 1 second
  241. msg->post(1000000LL);
  242. }
  243. void NuPlayer2::HTTPLiveSource2::onMessageReceived(const sp<AMessage> &msg) {
  244. switch (msg->what()) {
  245. case kWhatSessionNotify:
  246. {
  247. onSessionNotify(msg);
  248. break;
  249. }
  250. case kWhatFetchSubtitleData:
  251. {
  252. pollForRawData(
  253. msg, mFetchSubtitleDataGeneration,
  254. /* fetch */ LiveSession::STREAMTYPE_SUBTITLES,
  255. /* push */ kWhatSubtitleData);
  256. break;
  257. }
  258. case kWhatFetchMetaData:
  259. {
  260. if (!mMetadataSelected) {
  261. break;
  262. }
  263. pollForRawData(
  264. msg, mFetchMetaDataGeneration,
  265. /* fetch */ LiveSession::STREAMTYPE_METADATA,
  266. /* push */ kWhatTimedMetaData);
  267. break;
  268. }
  269. default:
  270. Source::onMessageReceived(msg);
  271. break;
  272. }
  273. }
  274. void NuPlayer2::HTTPLiveSource2::onSessionNotify(const sp<AMessage> &msg) {
  275. int32_t what;
  276. CHECK(msg->findInt32("what", &what));
  277. switch (what) {
  278. case LiveSession::kWhatPrepared:
  279. {
  280. // notify the current size here if we have it, otherwise report an initial size of (0,0)
  281. sp<AMessage> format = getFormat(false /* audio */);
  282. int32_t width;
  283. int32_t height;
  284. if (format != NULL &&
  285. format->findInt32("width", &width) && format->findInt32("height", &height)) {
  286. notifyVideoSizeChanged(format);
  287. } else {
  288. notifyVideoSizeChanged();
  289. }
  290. uint32_t flags = 0;
  291. if (mLiveSession->isSeekable()) {
  292. flags |= FLAG_CAN_PAUSE;
  293. flags |= FLAG_CAN_SEEK;
  294. flags |= FLAG_CAN_SEEK_BACKWARD;
  295. flags |= FLAG_CAN_SEEK_FORWARD;
  296. }
  297. if (mLiveSession->hasDynamicDuration()) {
  298. flags |= FLAG_DYNAMIC_DURATION;
  299. }
  300. notifyFlagsChanged(flags);
  301. notifyPrepared();
  302. break;
  303. }
  304. case LiveSession::kWhatPreparationFailed:
  305. {
  306. status_t err;
  307. CHECK(msg->findInt32("err", &err));
  308. notifyPrepared(err);
  309. break;
  310. }
  311. case LiveSession::kWhatStreamsChanged:
  312. {
  313. uint32_t changedMask;
  314. CHECK(msg->findInt32(
  315. "changedMask", (int32_t *)&changedMask));
  316. bool audio = changedMask & LiveSession::STREAMTYPE_AUDIO;
  317. bool video = changedMask & LiveSession::STREAMTYPE_VIDEO;
  318. sp<AMessage> reply;
  319. CHECK(msg->findMessage("reply", &reply));
  320. sp<AMessage> notify = dupNotify();
  321. notify->setInt32("what", kWhatQueueDecoderShutdown);
  322. notify->setInt32("audio", audio);
  323. notify->setInt32("video", video);
  324. notify->setMessage("reply", reply);
  325. notify->post();
  326. break;
  327. }
  328. case LiveSession::kWhatBufferingStart:
  329. {
  330. sp<AMessage> notify = dupNotify();
  331. notify->setInt32("what", kWhatPauseOnBufferingStart);
  332. notify->post();
  333. break;
  334. }
  335. case LiveSession::kWhatBufferingEnd:
  336. {
  337. sp<AMessage> notify = dupNotify();
  338. notify->setInt32("what", kWhatResumeOnBufferingEnd);
  339. notify->post();
  340. break;
  341. }
  342. case LiveSession::kWhatBufferingUpdate:
  343. {
  344. sp<AMessage> notify = dupNotify();
  345. int32_t percentage;
  346. CHECK(msg->findInt32("percentage", &percentage));
  347. notify->setInt32("what", kWhatBufferingUpdate);
  348. notify->setInt32("percentage", percentage);
  349. notify->post();
  350. break;
  351. }
  352. case LiveSession::kWhatMetadataDetected:
  353. {
  354. if (!mHasMetadata) {
  355. mHasMetadata = true;
  356. sp<AMessage> notify = dupNotify();
  357. // notification without buffer triggers MEDIA2_INFO_METADATA_UPDATE
  358. notify->setInt32("what", kWhatTimedMetaData);
  359. notify->post();
  360. }
  361. break;
  362. }
  363. case LiveSession::kWhatError:
  364. {
  365. break;
  366. }
  367. default:
  368. TRESPASS();
  369. }
  370. }
  371. } // namespace android