blob: 63a907c135d38e7baa684a87a0434f1e848bf6fd [file] [log] [blame]
Andreas Huberafed0e12011-09-20 15:39:58 -07001/*
2 * Copyright (C) 2012 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
17#include "GenericSource.h"
18
19#include "AnotherPacketSource.h"
20
21#include <media/stagefright/foundation/ABuffer.h>
22#include <media/stagefright/foundation/ADebug.h>
23#include <media/stagefright/foundation/AMessage.h>
24#include <media/stagefright/DataSource.h>
25#include <media/stagefright/FileSource.h>
26#include <media/stagefright/MediaBuffer.h>
27#include <media/stagefright/MediaDefs.h>
28#include <media/stagefright/MediaExtractor.h>
29#include <media/stagefright/MediaSource.h>
30#include <media/stagefright/MetaData.h>
Lajos Molnarcc227032014-07-17 15:33:06 -070031#include "../../libstagefright/include/WVMExtractor.h"
Andreas Huberafed0e12011-09-20 15:39:58 -070032
33namespace android {
34
35NuPlayer::GenericSource::GenericSource(
Andreas Huberb5f25f02013-02-05 10:14:26 -080036 const sp<AMessage> &notify,
Andreas Huber1b86fe02014-01-29 11:13:26 -080037 const sp<IMediaHTTPService> &httpService,
Andreas Huberafed0e12011-09-20 15:39:58 -070038 const char *url,
Lajos Molnarcc227032014-07-17 15:33:06 -070039 const KeyedVector<String8, String8> *headers,
40 bool isWidevine,
41 bool uidValid,
42 uid_t uid)
Andreas Huberb5f25f02013-02-05 10:14:26 -080043 : Source(notify),
Robert Shih05312bc2014-07-16 15:47:09 -070044 mFetchSubtitleDataGeneration(0),
Andreas Huberb5f25f02013-02-05 10:14:26 -080045 mDurationUs(0ll),
Lajos Molnarcc227032014-07-17 15:33:06 -070046 mAudioIsVorbis(false),
47 mIsWidevine(isWidevine),
48 mUIDValid(uidValid),
49 mUID(uid) {
Andreas Huberafed0e12011-09-20 15:39:58 -070050 DataSource::RegisterDefaultSniffers();
51
52 sp<DataSource> dataSource =
Andreas Huber1b86fe02014-01-29 11:13:26 -080053 DataSource::CreateFromURI(httpService, url, headers);
Andreas Huberafed0e12011-09-20 15:39:58 -070054 CHECK(dataSource != NULL);
55
56 initFromDataSource(dataSource);
57}
58
59NuPlayer::GenericSource::GenericSource(
Andreas Huberb5f25f02013-02-05 10:14:26 -080060 const sp<AMessage> &notify,
Andreas Huberafed0e12011-09-20 15:39:58 -070061 int fd, int64_t offset, int64_t length)
Andreas Huberb5f25f02013-02-05 10:14:26 -080062 : Source(notify),
Robert Shih05312bc2014-07-16 15:47:09 -070063 mFetchSubtitleDataGeneration(0),
Andreas Huberb5f25f02013-02-05 10:14:26 -080064 mDurationUs(0ll),
Andreas Huberafed0e12011-09-20 15:39:58 -070065 mAudioIsVorbis(false) {
66 DataSource::RegisterDefaultSniffers();
67
68 sp<DataSource> dataSource = new FileSource(dup(fd), offset, length);
69
70 initFromDataSource(dataSource);
71}
72
73void NuPlayer::GenericSource::initFromDataSource(
74 const sp<DataSource> &dataSource) {
Lajos Molnarcc227032014-07-17 15:33:06 -070075 sp<MediaExtractor> extractor;
76
77 if (mIsWidevine) {
78 String8 mimeType;
79 float confidence;
80 sp<AMessage> dummy;
81 bool success;
82
83 success = SniffWVM(dataSource, &mimeType, &confidence, &dummy);
84 if (!success
85 || strcasecmp(
86 mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
87 ALOGE("unsupported widevine mime: %s", mimeType.string());
88 return;
89 }
90
91 sp<WVMExtractor> wvmExtractor = new WVMExtractor(dataSource);
92 wvmExtractor->setAdaptiveStreamingMode(true);
93 if (mUIDValid) {
94 wvmExtractor->setUID(mUID);
95 }
96 extractor = wvmExtractor;
97 } else {
98 extractor = MediaExtractor::Create(dataSource);
99 }
Andreas Huberafed0e12011-09-20 15:39:58 -0700100
101 CHECK(extractor != NULL);
102
Marco Nelissenc1f4b2b2014-06-17 14:48:32 -0700103 sp<MetaData> fileMeta = extractor->getMetaData();
104 if (fileMeta != NULL) {
105 int64_t duration;
106 if (fileMeta->findInt64(kKeyDuration, &duration)) {
107 mDurationUs = duration;
108 }
109 }
110
Andreas Huberafed0e12011-09-20 15:39:58 -0700111 for (size_t i = 0; i < extractor->countTracks(); ++i) {
112 sp<MetaData> meta = extractor->getTrackMetaData(i);
113
114 const char *mime;
115 CHECK(meta->findCString(kKeyMIMEType, &mime));
116
Robert Shihdd235722014-06-12 14:49:23 -0700117 sp<MediaSource> track = extractor->getTrack(i);
Andreas Huberafed0e12011-09-20 15:39:58 -0700118
119 if (!strncasecmp(mime, "audio/", 6)) {
120 if (mAudioTrack.mSource == NULL) {
Robert Shihdd235722014-06-12 14:49:23 -0700121 mAudioTrack.mIndex = i;
122 mAudioTrack.mSource = track;
Andreas Huberafed0e12011-09-20 15:39:58 -0700123
124 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
125 mAudioIsVorbis = true;
126 } else {
127 mAudioIsVorbis = false;
128 }
129 }
130 } else if (!strncasecmp(mime, "video/", 6)) {
131 if (mVideoTrack.mSource == NULL) {
Robert Shihdd235722014-06-12 14:49:23 -0700132 mVideoTrack.mIndex = i;
133 mVideoTrack.mSource = track;
Andreas Huberafed0e12011-09-20 15:39:58 -0700134 }
135 }
136
137 if (track != NULL) {
Robert Shih05312bc2014-07-16 15:47:09 -0700138 CHECK_EQ(track->start(), (status_t)OK);
Robert Shihdd235722014-06-12 14:49:23 -0700139 mSources.push(track);
Andreas Huberafed0e12011-09-20 15:39:58 -0700140 int64_t durationUs;
141 if (meta->findInt64(kKeyDuration, &durationUs)) {
142 if (durationUs > mDurationUs) {
143 mDurationUs = durationUs;
144 }
145 }
146 }
147 }
148}
149
Lajos Molnarcc227032014-07-17 15:33:06 -0700150status_t NuPlayer::GenericSource::setBuffers(bool audio, Vector<MediaBuffer *> &buffers) {
151 if (mIsWidevine && !audio) {
152 return mVideoTrack.mSource->setBuffers(buffers);
153 }
154 return INVALID_OPERATION;
155}
156
Andreas Huberafed0e12011-09-20 15:39:58 -0700157NuPlayer::GenericSource::~GenericSource() {
158}
159
Andreas Huber9575c962013-02-05 13:59:56 -0800160void NuPlayer::GenericSource::prepareAsync() {
161 if (mVideoTrack.mSource != NULL) {
162 sp<MetaData> meta = mVideoTrack.mSource->getFormat();
163
164 int32_t width, height;
165 CHECK(meta->findInt32(kKeyWidth, &width));
166 CHECK(meta->findInt32(kKeyHeight, &height));
167
168 notifyVideoSizeChanged(width, height);
169 }
170
171 notifyFlagsChanged(
Lajos Molnarcc227032014-07-17 15:33:06 -0700172 (mIsWidevine ? FLAG_SECURE : 0)
173 | FLAG_CAN_PAUSE
Andreas Huber9575c962013-02-05 13:59:56 -0800174 | FLAG_CAN_SEEK_BACKWARD
175 | FLAG_CAN_SEEK_FORWARD
176 | FLAG_CAN_SEEK);
177
178 notifyPrepared();
179}
180
Andreas Huberafed0e12011-09-20 15:39:58 -0700181void NuPlayer::GenericSource::start() {
182 ALOGI("start");
183
184 if (mAudioTrack.mSource != NULL) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700185 mAudioTrack.mPackets =
186 new AnotherPacketSource(mAudioTrack.mSource->getFormat());
187
Robert Shih05312bc2014-07-16 15:47:09 -0700188 readBuffer(MEDIA_TRACK_TYPE_AUDIO);
Andreas Huberafed0e12011-09-20 15:39:58 -0700189 }
190
191 if (mVideoTrack.mSource != NULL) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700192 mVideoTrack.mPackets =
193 new AnotherPacketSource(mVideoTrack.mSource->getFormat());
194
Robert Shih05312bc2014-07-16 15:47:09 -0700195 readBuffer(MEDIA_TRACK_TYPE_VIDEO);
Andreas Huberafed0e12011-09-20 15:39:58 -0700196 }
197}
198
199status_t NuPlayer::GenericSource::feedMoreTSData() {
200 return OK;
201}
202
Robert Shih05312bc2014-07-16 15:47:09 -0700203void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) {
204 switch (msg->what()) {
205 case kWhatFetchSubtitleData:
206 {
207 int32_t generation;
208 CHECK(msg->findInt32("generation", &generation));
209 if (generation != mFetchSubtitleDataGeneration) {
210 // stale
211 break;
212 }
213
214 int32_t avail;
215 if (mSubtitleTrack.mPackets->hasBufferAvailable(&avail)) {
216 break;
217 }
218
219 int64_t timeUs;
220 CHECK(msg->findInt64("timeUs", &timeUs));
221
222 int64_t subTimeUs;
223 readBuffer(MEDIA_TRACK_TYPE_SUBTITLE, timeUs, &subTimeUs);
224
225 const int64_t oneSecUs = 1000000ll;
226 const int64_t delayUs = subTimeUs - timeUs - oneSecUs;
227 sp<AMessage> msg2 = new AMessage(kWhatSendSubtitleData, id());
228 msg2->setInt32("generation", generation);
229 msg2->post(delayUs < 0 ? 0 : delayUs);
230 ALOGV("kWhatFetchSubtitleData generation %d, delayUs %lld",
231 mFetchSubtitleDataGeneration, delayUs);
232
233 break;
234 }
235
236 case kWhatSendSubtitleData:
237 {
238 int32_t generation;
239 CHECK(msg->findInt32("generation", &generation));
240 if (generation != mFetchSubtitleDataGeneration) {
241 // stale
242 break;
243 }
244
245 int64_t subTimeUs;
246 if (mSubtitleTrack.mPackets->nextBufferTime(&subTimeUs) != OK) {
247 break;
248 }
249
250 int64_t nextSubTimeUs;
251 readBuffer(MEDIA_TRACK_TYPE_SUBTITLE, -1, &nextSubTimeUs);
252
253 sp<ABuffer> buffer;
254 status_t dequeueStatus = mSubtitleTrack.mPackets->dequeueAccessUnit(&buffer);
255 if (dequeueStatus != OK) {
256 ALOGE("kWhatSendSubtitleData dequeueAccessUnit: %d", dequeueStatus);
257 } else {
258 sp<AMessage> notify = dupNotify();
259 notify->setInt32("what", kWhatSubtitleData);
260 notify->setBuffer("buffer", buffer);
261 notify->post();
262
263 const int64_t delayUs = nextSubTimeUs - subTimeUs;
264 msg->post(delayUs < 0 ? 0 : delayUs);
265 }
266
267 break;
268 }
269
270 case kWhatChangeAVSource:
271 {
272 int32_t trackIndex;
273 CHECK(msg->findInt32("trackIndex", &trackIndex));
274 const sp<MediaSource> source = mSources.itemAt(trackIndex);
275
276 Track* track;
277 const char *mime;
278 media_track_type trackType, counterpartType;
279 sp<MetaData> meta = source->getFormat();
280 meta->findCString(kKeyMIMEType, &mime);
281 if (!strncasecmp(mime, "audio/", 6)) {
282 track = &mAudioTrack;
283 trackType = MEDIA_TRACK_TYPE_AUDIO;
284 counterpartType = MEDIA_TRACK_TYPE_VIDEO;;
285 } else {
286 CHECK(!strncasecmp(mime, "video/", 6));
287 track = &mVideoTrack;
288 trackType = MEDIA_TRACK_TYPE_VIDEO;
289 counterpartType = MEDIA_TRACK_TYPE_AUDIO;;
290 }
291
292
293 track->mSource = source;
294 track->mIndex = trackIndex;
295
296 status_t avail;
297 if (!track->mPackets->hasBufferAvailable(&avail)) {
298 // sync from other source
299 TRESPASS();
300 break;
301 }
302
303 int64_t timeUs, actualTimeUs;
304 const bool formatChange = true;
305 sp<AMessage> latestMeta = track->mPackets->getLatestMeta();
306 CHECK(latestMeta != NULL && latestMeta->findInt64("timeUs", &timeUs));
307 readBuffer(trackType, timeUs, &actualTimeUs, formatChange);
308 readBuffer(counterpartType, -1, NULL, formatChange);
309 ALOGV("timeUs %lld actualTimeUs %lld", timeUs, actualTimeUs);
310
311 break;
312 }
313
314 default:
315 Source::onMessageReceived(msg);
316 break;
317 }
318}
319
Andreas Huber84066782011-08-16 09:34:26 -0700320sp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
Andreas Huberafed0e12011-09-20 15:39:58 -0700321 sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
322
323 if (source == NULL) {
324 return NULL;
325 }
326
327 return source->getFormat();
328}
329
330status_t NuPlayer::GenericSource::dequeueAccessUnit(
331 bool audio, sp<ABuffer> *accessUnit) {
332 Track *track = audio ? &mAudioTrack : &mVideoTrack;
333
334 if (track->mSource == NULL) {
335 return -EWOULDBLOCK;
336 }
337
Lajos Molnarcc227032014-07-17 15:33:06 -0700338 if (mIsWidevine && !audio) {
339 // try to read a buffer as we may not have been able to the last time
Robert Shih05312bc2014-07-16 15:47:09 -0700340 readBuffer(MEDIA_TRACK_TYPE_AUDIO, -1ll);
Lajos Molnarcc227032014-07-17 15:33:06 -0700341 }
342
Andreas Huberafed0e12011-09-20 15:39:58 -0700343 status_t finalResult;
344 if (!track->mPackets->hasBufferAvailable(&finalResult)) {
Lajos Molnarcc227032014-07-17 15:33:06 -0700345 return (finalResult == OK ? -EWOULDBLOCK : finalResult);
Andreas Huberafed0e12011-09-20 15:39:58 -0700346 }
347
348 status_t result = track->mPackets->dequeueAccessUnit(accessUnit);
349
Robert Shih05312bc2014-07-16 15:47:09 -0700350 if (!track->mPackets->hasBufferAvailable(&finalResult)) {
351 readBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO, -1ll);
352 }
353
354 if (mSubtitleTrack.mSource == NULL) {
355 return result;
356 }
357
358 CHECK(mSubtitleTrack.mPackets != NULL);
359 if (result != OK) {
360 mSubtitleTrack.mPackets->clear();
361 mFetchSubtitleDataGeneration++;
362 return result;
363 }
364
365 int64_t timeUs;
366 status_t eosResult; // ignored
367 CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
368 if (!mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
369 sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
370 msg->setInt64("timeUs", timeUs);
371 msg->setInt32("generation", mFetchSubtitleDataGeneration);
372 msg->post();
373 }
Andreas Huberafed0e12011-09-20 15:39:58 -0700374
375 return result;
376}
377
378status_t NuPlayer::GenericSource::getDuration(int64_t *durationUs) {
379 *durationUs = mDurationUs;
380 return OK;
381}
382
Robert Shihdd235722014-06-12 14:49:23 -0700383size_t NuPlayer::GenericSource::getTrackCount() const {
384 return mSources.size();
385}
386
387sp<AMessage> NuPlayer::GenericSource::getTrackInfo(size_t trackIndex) const {
388 size_t trackCount = mSources.size();
389 if (trackIndex >= trackCount) {
390 return NULL;
391 }
392
393 sp<AMessage> format = new AMessage();
394 sp<MetaData> meta = mSources.itemAt(trackIndex)->getFormat();
395
396 const char *mime;
397 CHECK(meta->findCString(kKeyMIMEType, &mime));
398
399 int32_t trackType;
400 if (!strncasecmp(mime, "video/", 6)) {
401 trackType = MEDIA_TRACK_TYPE_VIDEO;
402 } else if (!strncasecmp(mime, "audio/", 6)) {
403 trackType = MEDIA_TRACK_TYPE_AUDIO;
404 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
405 trackType = MEDIA_TRACK_TYPE_TIMEDTEXT;
406 } else {
407 trackType = MEDIA_TRACK_TYPE_UNKNOWN;
408 }
409 format->setInt32("type", trackType);
410
411 const char *lang;
412 if (!meta->findCString(kKeyMediaLanguage, &lang)) {
413 lang = "und";
414 }
415 format->setString("language", lang);
416
417 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
418 format->setString("mime", mime);
419
420 int32_t isAutoselect = 1, isDefault = 0, isForced = 0;
421 meta->findInt32(kKeyTrackIsAutoselect, &isAutoselect);
422 meta->findInt32(kKeyTrackIsDefault, &isDefault);
423 meta->findInt32(kKeyTrackIsForced, &isForced);
424
425 format->setInt32("auto", !!isAutoselect);
426 format->setInt32("default", !!isDefault);
427 format->setInt32("forced", !!isForced);
428 }
429
430 return format;
431}
432
Robert Shih05312bc2014-07-16 15:47:09 -0700433status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) {
434 ALOGV("selectTrack: %zu", trackIndex);
435 if (trackIndex >= mSources.size()) {
436 return BAD_INDEX;
437 }
438
439 if (!select) {
440 if (mSubtitleTrack.mSource == NULL || trackIndex != mSubtitleTrack.mIndex) {
441 return INVALID_OPERATION;
442 }
443 mSubtitleTrack.mSource = NULL;
444 mSubtitleTrack.mPackets->clear();
445 mFetchSubtitleDataGeneration++;
446 return OK;
447 }
448
449 const sp<MediaSource> source = mSources.itemAt(trackIndex);
450 sp<MetaData> meta = source->getFormat();
451 const char *mime;
452 CHECK(meta->findCString(kKeyMIMEType, &mime));
453 if (!strncasecmp(mime, "text/", 5)) {
454 if (mSubtitleTrack.mSource != NULL && mSubtitleTrack.mIndex == trackIndex) {
455 return OK;
456 }
457 mSubtitleTrack.mIndex = trackIndex;
458 mSubtitleTrack.mSource = mSources.itemAt(trackIndex);
459 if (mSubtitleTrack.mPackets == NULL) {
460 mSubtitleTrack.mPackets = new AnotherPacketSource(mSubtitleTrack.mSource->getFormat());
461 } else {
462 mSubtitleTrack.mPackets->clear();
463
464 }
465 mFetchSubtitleDataGeneration++;
466 return OK;
467 } else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
468 bool audio = !strncasecmp(mime, "audio/", 6);
469 Track *track = audio ? &mAudioTrack : &mVideoTrack;
470 if (track->mSource != NULL && track->mIndex == trackIndex) {
471 return OK;
472 }
473
474 sp<AMessage> msg = new AMessage(kWhatChangeAVSource, id());
475 msg->setInt32("trackIndex", trackIndex);
476 msg->post();
477 return OK;
478 }
479
480 return INVALID_OPERATION;
481}
482
Andreas Huberafed0e12011-09-20 15:39:58 -0700483status_t NuPlayer::GenericSource::seekTo(int64_t seekTimeUs) {
484 if (mVideoTrack.mSource != NULL) {
485 int64_t actualTimeUs;
Robert Shih05312bc2014-07-16 15:47:09 -0700486 readBuffer(MEDIA_TRACK_TYPE_VIDEO, seekTimeUs, &actualTimeUs);
Andreas Huberafed0e12011-09-20 15:39:58 -0700487
488 seekTimeUs = actualTimeUs;
489 }
490
491 if (mAudioTrack.mSource != NULL) {
Robert Shih05312bc2014-07-16 15:47:09 -0700492 readBuffer(MEDIA_TRACK_TYPE_AUDIO, seekTimeUs);
Andreas Huberafed0e12011-09-20 15:39:58 -0700493 }
494
495 return OK;
496}
497
Robert Shih05312bc2014-07-16 15:47:09 -0700498sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
499 MediaBuffer* mb,
500 media_track_type trackType,
501 int64_t *actualTimeUs) {
502 bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
503 size_t outLength = mb->range_length();
504
505 if (audio && mAudioIsVorbis) {
506 outLength += sizeof(int32_t);
507 }
508
509 sp<ABuffer> ab;
510 if (mIsWidevine && !audio) {
511 // data is already provided in the buffer
512 ab = new ABuffer(NULL, mb->range_length());
513 ab->meta()->setPointer("mediaBuffer", mb);
514 mb->add_ref();
515 } else {
516 ab = new ABuffer(outLength);
517 memcpy(ab->data(),
518 (const uint8_t *)mb->data() + mb->range_offset(),
519 mb->range_length());
520 }
521
522 if (audio && mAudioIsVorbis) {
523 int32_t numPageSamples;
524 if (!mb->meta_data()->findInt32(kKeyValidSamples, &numPageSamples)) {
525 numPageSamples = -1;
526 }
527
528 uint8_t* abEnd = ab->data() + mb->range_length();
529 memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
530 }
531
532 int64_t timeUs;
533 CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
534
535 sp<AMessage> meta = ab->meta();
536 meta->setInt64("timeUs", timeUs);
537
538 int64_t durationUs;
539 if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
540 meta->setInt64("durationUs", durationUs);
541 }
542
543 if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
544 meta->setInt32("trackIndex", mSubtitleTrack.mIndex);
545 }
546
547 if (actualTimeUs) {
548 *actualTimeUs = timeUs;
549 }
550
551 mb->release();
552 mb = NULL;
553
554 return ab;
555}
556
Andreas Huberafed0e12011-09-20 15:39:58 -0700557void NuPlayer::GenericSource::readBuffer(
Robert Shih05312bc2014-07-16 15:47:09 -0700558 media_track_type trackType, int64_t seekTimeUs, int64_t *actualTimeUs, bool formatChange) {
559 Track *track;
560 switch (trackType) {
561 case MEDIA_TRACK_TYPE_VIDEO:
562 track = &mVideoTrack;
563 break;
564 case MEDIA_TRACK_TYPE_AUDIO:
565 track = &mAudioTrack;
566 break;
567 case MEDIA_TRACK_TYPE_SUBTITLE:
568 track = &mSubtitleTrack;
569 break;
570 default:
571 TRESPASS();
572 }
573
574 if (track->mSource == NULL) {
575 return;
576 }
Andreas Huberafed0e12011-09-20 15:39:58 -0700577
578 if (actualTimeUs) {
579 *actualTimeUs = seekTimeUs;
580 }
581
582 MediaSource::ReadOptions options;
583
584 bool seeking = false;
585
586 if (seekTimeUs >= 0) {
Robert Shih05312bc2014-07-16 15:47:09 -0700587 options.setSeekTo(seekTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
Andreas Huberafed0e12011-09-20 15:39:58 -0700588 seeking = true;
589 }
590
Robert Shih05312bc2014-07-16 15:47:09 -0700591 if (mIsWidevine && trackType != MEDIA_TRACK_TYPE_AUDIO) {
Lajos Molnarcc227032014-07-17 15:33:06 -0700592 options.setNonBlocking();
593 }
594
Andreas Huberafed0e12011-09-20 15:39:58 -0700595 for (;;) {
596 MediaBuffer *mbuf;
597 status_t err = track->mSource->read(&mbuf, &options);
598
599 options.clearSeekTo();
600
601 if (err == OK) {
Robert Shih05312bc2014-07-16 15:47:09 -0700602 // formatChange && seeking: track whose source is changed during selection
603 // formatChange && !seeking: track whose source is not changed during selection
604 // !formatChange: normal seek
605 if ((seeking || formatChange) && trackType != MEDIA_TRACK_TYPE_SUBTITLE) {
606 ATSParser::DiscontinuityType type = formatChange
607 ? (seeking
608 ? ATSParser::DISCONTINUITY_FORMATCHANGE
609 : ATSParser::DISCONTINUITY_NONE)
610 : ATSParser::DISCONTINUITY_SEEK;
611 track->mPackets->queueDiscontinuity( type, NULL, true /* discard */);
Andreas Huberafed0e12011-09-20 15:39:58 -0700612 }
613
Robert Shih05312bc2014-07-16 15:47:09 -0700614 sp<ABuffer> buffer = mediaBufferToABuffer(mbuf, trackType, actualTimeUs);
Andreas Huberafed0e12011-09-20 15:39:58 -0700615 track->mPackets->queueAccessUnit(buffer);
616 break;
Lajos Molnarcc227032014-07-17 15:33:06 -0700617 } else if (err == WOULD_BLOCK) {
618 break;
Andreas Huberafed0e12011-09-20 15:39:58 -0700619 } else if (err == INFO_FORMAT_CHANGED) {
620#if 0
621 track->mPackets->queueDiscontinuity(
Chong Zhang632740c2014-06-26 13:03:47 -0700622 ATSParser::DISCONTINUITY_FORMATCHANGE,
623 NULL,
624 false /* discard */);
Andreas Huberafed0e12011-09-20 15:39:58 -0700625#endif
626 } else {
627 track->mPackets->signalEOS(err);
628 break;
629 }
630 }
631}
632
Andreas Huberafed0e12011-09-20 15:39:58 -0700633} // namespace android