PlaylistFetcher.cpp revision 1130c49ee00e2faf0e21152da88cda07299232da
1/*
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//#define LOG_NDEBUG 0
18#define LOG_TAG "PlaylistFetcher"
19#include <utils/Log.h>
20
21#include "PlaylistFetcher.h"
22
23#include "LiveDataSource.h"
24#include "LiveSession.h"
25#include "M3UParser.h"
26
27#include "include/avc_utils.h"
28#include "include/HTTPBase.h"
29#include "include/ID3.h"
30#include "mpeg2ts/AnotherPacketSource.h"
31
32#include <media/IStreamSource.h>
33#include <media/stagefright/foundation/ABitReader.h>
34#include <media/stagefright/foundation/ABuffer.h>
35#include <media/stagefright/foundation/ADebug.h>
36#include <media/stagefright/foundation/hexdump.h>
37#include <media/stagefright/FileSource.h>
38#include <media/stagefright/MediaDefs.h>
39#include <media/stagefright/MetaData.h>
40#include <media/stagefright/Utils.h>
41
42#include <ctype.h>
43#include <inttypes.h>
44#include <openssl/aes.h>
45#include <openssl/md5.h>
46
47namespace android {
48
49// static
50const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
51const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
52const int32_t PlaylistFetcher::kDownloadBlockSize = 192;
53const int32_t PlaylistFetcher::kNumSkipFrames = 10;
54
55PlaylistFetcher::PlaylistFetcher(
56        const sp<AMessage> &notify,
57        const sp<LiveSession> &session,
58        const char *uri)
59    : mNotify(notify),
60      mStartTimeUsNotify(notify->dup()),
61      mSession(session),
62      mURI(uri),
63      mStreamTypeMask(0),
64      mStartTimeUs(-1ll),
65      mMinStartTimeUs(0ll),
66      mStopParams(NULL),
67      mLastPlaylistFetchTimeUs(-1ll),
68      mSeqNumber(-1),
69      mNumRetries(0),
70      mStartup(true),
71      mPrepared(false),
72      mSkipToFirstIDRAfterConnect(false),
73      mNextPTSTimeUs(-1ll),
74      mMonitorQueueGeneration(0),
75      mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY),
76      mFirstPTSValid(false),
77      mAbsoluteTimeAnchorUs(0ll) {
78    memset(mPlaylistHash, 0, sizeof(mPlaylistHash));
79    mStartTimeUsNotify->setInt32("what", kWhatStartedAt);
80    mStartTimeUsNotify->setInt32("streamMask", 0);
81}
82
83PlaylistFetcher::~PlaylistFetcher() {
84}
85
86int64_t PlaylistFetcher::getSegmentStartTimeUs(int32_t seqNumber) const {
87    CHECK(mPlaylist != NULL);
88
89    int32_t firstSeqNumberInPlaylist;
90    if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
91                "media-sequence", &firstSeqNumberInPlaylist)) {
92        firstSeqNumberInPlaylist = 0;
93    }
94
95    int32_t lastSeqNumberInPlaylist =
96        firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1;
97
98    CHECK_GE(seqNumber, firstSeqNumberInPlaylist);
99    CHECK_LE(seqNumber, lastSeqNumberInPlaylist);
100
101    int64_t segmentStartUs = 0ll;
102    for (int32_t index = 0;
103            index < seqNumber - firstSeqNumberInPlaylist; ++index) {
104        sp<AMessage> itemMeta;
105        CHECK(mPlaylist->itemAt(
106                    index, NULL /* uri */, &itemMeta));
107
108        int64_t itemDurationUs;
109        CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
110
111        segmentStartUs += itemDurationUs;
112    }
113
114    return segmentStartUs;
115}
116
117int64_t PlaylistFetcher::delayUsToRefreshPlaylist() const {
118    int64_t nowUs = ALooper::GetNowUs();
119
120    if (mPlaylist == NULL || mLastPlaylistFetchTimeUs < 0ll) {
121        CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY);
122        return 0ll;
123    }
124
125    if (mPlaylist->isComplete()) {
126        return (~0llu >> 1);
127    }
128
129    int32_t targetDurationSecs;
130    CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
131
132    int64_t targetDurationUs = targetDurationSecs * 1000000ll;
133
134    int64_t minPlaylistAgeUs;
135
136    switch (mRefreshState) {
137        case INITIAL_MINIMUM_RELOAD_DELAY:
138        {
139            size_t n = mPlaylist->size();
140            if (n > 0) {
141                sp<AMessage> itemMeta;
142                CHECK(mPlaylist->itemAt(n - 1, NULL /* uri */, &itemMeta));
143
144                int64_t itemDurationUs;
145                CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
146
147                minPlaylistAgeUs = itemDurationUs;
148                break;
149            }
150
151            // fall through
152        }
153
154        case FIRST_UNCHANGED_RELOAD_ATTEMPT:
155        {
156            minPlaylistAgeUs = targetDurationUs / 2;
157            break;
158        }
159
160        case SECOND_UNCHANGED_RELOAD_ATTEMPT:
161        {
162            minPlaylistAgeUs = (targetDurationUs * 3) / 2;
163            break;
164        }
165
166        case THIRD_UNCHANGED_RELOAD_ATTEMPT:
167        {
168            minPlaylistAgeUs = targetDurationUs * 3;
169            break;
170        }
171
172        default:
173            TRESPASS();
174            break;
175    }
176
177    int64_t delayUs = mLastPlaylistFetchTimeUs + minPlaylistAgeUs - nowUs;
178    return delayUs > 0ll ? delayUs : 0ll;
179}
180
181status_t PlaylistFetcher::decryptBuffer(
182        size_t playlistIndex, const sp<ABuffer> &buffer,
183        bool first) {
184    sp<AMessage> itemMeta;
185    bool found = false;
186    AString method;
187
188    for (ssize_t i = playlistIndex; i >= 0; --i) {
189        AString uri;
190        CHECK(mPlaylist->itemAt(i, &uri, &itemMeta));
191
192        if (itemMeta->findString("cipher-method", &method)) {
193            found = true;
194            break;
195        }
196    }
197
198    if (!found) {
199        method = "NONE";
200    }
201    buffer->meta()->setString("cipher-method", method.c_str());
202
203    if (method == "NONE") {
204        return OK;
205    } else if (!(method == "AES-128")) {
206        ALOGE("Unsupported cipher method '%s'", method.c_str());
207        return ERROR_UNSUPPORTED;
208    }
209
210    AString keyURI;
211    if (!itemMeta->findString("cipher-uri", &keyURI)) {
212        ALOGE("Missing key uri");
213        return ERROR_MALFORMED;
214    }
215
216    ssize_t index = mAESKeyForURI.indexOfKey(keyURI);
217
218    sp<ABuffer> key;
219    if (index >= 0) {
220        key = mAESKeyForURI.valueAt(index);
221    } else {
222        ssize_t err = mSession->fetchFile(keyURI.c_str(), &key);
223
224        if (err < 0) {
225            ALOGE("failed to fetch cipher key from '%s'.", keyURI.c_str());
226            return ERROR_IO;
227        } else if (key->size() != 16) {
228            ALOGE("key file '%s' wasn't 16 bytes in size.", keyURI.c_str());
229            return ERROR_MALFORMED;
230        }
231
232        mAESKeyForURI.add(keyURI, key);
233    }
234
235    AES_KEY aes_key;
236    if (AES_set_decrypt_key(key->data(), 128, &aes_key) != 0) {
237        ALOGE("failed to set AES decryption key.");
238        return UNKNOWN_ERROR;
239    }
240
241    size_t n = buffer->size();
242    if (!n) {
243        return OK;
244    }
245    CHECK(n % 16 == 0);
246
247    if (first) {
248        // If decrypting the first block in a file, read the iv from the manifest
249        // or derive the iv from the file's sequence number.
250
251        AString iv;
252        if (itemMeta->findString("cipher-iv", &iv)) {
253            if ((!iv.startsWith("0x") && !iv.startsWith("0X"))
254                    || iv.size() != 16 * 2 + 2) {
255                ALOGE("malformed cipher IV '%s'.", iv.c_str());
256                return ERROR_MALFORMED;
257            }
258
259            memset(mAESInitVec, 0, sizeof(mAESInitVec));
260            for (size_t i = 0; i < 16; ++i) {
261                char c1 = tolower(iv.c_str()[2 + 2 * i]);
262                char c2 = tolower(iv.c_str()[3 + 2 * i]);
263                if (!isxdigit(c1) || !isxdigit(c2)) {
264                    ALOGE("malformed cipher IV '%s'.", iv.c_str());
265                    return ERROR_MALFORMED;
266                }
267                uint8_t nibble1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10;
268                uint8_t nibble2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10;
269
270                mAESInitVec[i] = nibble1 << 4 | nibble2;
271            }
272        } else {
273            memset(mAESInitVec, 0, sizeof(mAESInitVec));
274            mAESInitVec[15] = mSeqNumber & 0xff;
275            mAESInitVec[14] = (mSeqNumber >> 8) & 0xff;
276            mAESInitVec[13] = (mSeqNumber >> 16) & 0xff;
277            mAESInitVec[12] = (mSeqNumber >> 24) & 0xff;
278        }
279    }
280
281    AES_cbc_encrypt(
282            buffer->data(), buffer->data(), buffer->size(),
283            &aes_key, mAESInitVec, AES_DECRYPT);
284
285    return OK;
286}
287
288status_t PlaylistFetcher::checkDecryptPadding(const sp<ABuffer> &buffer) {
289    status_t err;
290    AString method;
291    CHECK(buffer->meta()->findString("cipher-method", &method));
292    if (method == "NONE") {
293        return OK;
294    }
295
296    uint8_t padding = 0;
297    if (buffer->size() > 0) {
298        padding = buffer->data()[buffer->size() - 1];
299    }
300
301    if (padding > 16) {
302        return ERROR_MALFORMED;
303    }
304
305    for (size_t i = buffer->size() - padding; i < padding; i++) {
306        if (buffer->data()[i] != padding) {
307            return ERROR_MALFORMED;
308        }
309    }
310
311    buffer->setRange(buffer->offset(), buffer->size() - padding);
312    return OK;
313}
314
315void PlaylistFetcher::postMonitorQueue(int64_t delayUs, int64_t minDelayUs) {
316    int64_t maxDelayUs = delayUsToRefreshPlaylist();
317    if (maxDelayUs < minDelayUs) {
318        maxDelayUs = minDelayUs;
319    }
320    if (delayUs > maxDelayUs) {
321        ALOGV("Need to refresh playlist in %" PRId64 , maxDelayUs);
322        delayUs = maxDelayUs;
323    }
324    sp<AMessage> msg = new AMessage(kWhatMonitorQueue, id());
325    msg->setInt32("generation", mMonitorQueueGeneration);
326    msg->post(delayUs);
327}
328
329void PlaylistFetcher::cancelMonitorQueue() {
330    ++mMonitorQueueGeneration;
331}
332
333void PlaylistFetcher::startAsync(
334        const sp<AnotherPacketSource> &audioSource,
335        const sp<AnotherPacketSource> &videoSource,
336        const sp<AnotherPacketSource> &subtitleSource,
337        int64_t startTimeUs,
338        int64_t minStartTimeUs,
339        int32_t startSeqNumberHint) {
340    sp<AMessage> msg = new AMessage(kWhatStart, id());
341
342    uint32_t streamTypeMask = 0ul;
343
344    if (audioSource != NULL) {
345        msg->setPointer("audioSource", audioSource.get());
346        streamTypeMask |= LiveSession::STREAMTYPE_AUDIO;
347    }
348
349    if (videoSource != NULL) {
350        msg->setPointer("videoSource", videoSource.get());
351        streamTypeMask |= LiveSession::STREAMTYPE_VIDEO;
352    }
353
354    if (subtitleSource != NULL) {
355        msg->setPointer("subtitleSource", subtitleSource.get());
356        streamTypeMask |= LiveSession::STREAMTYPE_SUBTITLES;
357    }
358
359    msg->setInt32("streamTypeMask", streamTypeMask);
360    msg->setInt64("startTimeUs", startTimeUs);
361    msg->setInt64("minStartTimeUs", minStartTimeUs);
362    msg->setInt32("startSeqNumberHint", startSeqNumberHint);
363    msg->post();
364}
365
366void PlaylistFetcher::pauseAsync() {
367    (new AMessage(kWhatPause, id()))->post();
368}
369
370void PlaylistFetcher::stopAsync(bool selfTriggered) {
371    sp<AMessage> msg = new AMessage(kWhatStop, id());
372    msg->setInt32("selfTriggered", selfTriggered);
373    msg->post();
374}
375
376void PlaylistFetcher::resumeUntilAsync(const sp<AMessage> &params) {
377    AMessage* msg = new AMessage(kWhatResumeUntil, id());
378    msg->setMessage("params", params);
379    msg->post();
380}
381
382void PlaylistFetcher::onMessageReceived(const sp<AMessage> &msg) {
383    switch (msg->what()) {
384        case kWhatStart:
385        {
386            status_t err = onStart(msg);
387
388            sp<AMessage> notify = mNotify->dup();
389            notify->setInt32("what", kWhatStarted);
390            notify->setInt32("err", err);
391            notify->post();
392            break;
393        }
394
395        case kWhatPause:
396        {
397            onPause();
398
399            sp<AMessage> notify = mNotify->dup();
400            notify->setInt32("what", kWhatPaused);
401            notify->post();
402            break;
403        }
404
405        case kWhatStop:
406        {
407            onStop(msg);
408
409            sp<AMessage> notify = mNotify->dup();
410            notify->setInt32("what", kWhatStopped);
411            notify->post();
412            break;
413        }
414
415        case kWhatMonitorQueue:
416        case kWhatDownloadNext:
417        {
418            int32_t generation;
419            CHECK(msg->findInt32("generation", &generation));
420
421            if (generation != mMonitorQueueGeneration) {
422                // Stale event
423                break;
424            }
425
426            if (msg->what() == kWhatMonitorQueue) {
427                onMonitorQueue();
428            } else {
429                onDownloadNext();
430            }
431            break;
432        }
433
434        case kWhatResumeUntil:
435        {
436            onResumeUntil(msg);
437            break;
438        }
439
440        default:
441            TRESPASS();
442    }
443}
444
445status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) {
446    mPacketSources.clear();
447
448    uint32_t streamTypeMask;
449    CHECK(msg->findInt32("streamTypeMask", (int32_t *)&streamTypeMask));
450
451    int64_t startTimeUs;
452    int32_t startSeqNumberHint;
453    CHECK(msg->findInt64("startTimeUs", &startTimeUs));
454    CHECK(msg->findInt64("minStartTimeUs", (int64_t *) &mMinStartTimeUs));
455    CHECK(msg->findInt32("startSeqNumberHint", &startSeqNumberHint));
456
457    if (streamTypeMask & LiveSession::STREAMTYPE_AUDIO) {
458        void *ptr;
459        CHECK(msg->findPointer("audioSource", &ptr));
460
461        mPacketSources.add(
462                LiveSession::STREAMTYPE_AUDIO,
463                static_cast<AnotherPacketSource *>(ptr));
464    }
465
466    if (streamTypeMask & LiveSession::STREAMTYPE_VIDEO) {
467        void *ptr;
468        CHECK(msg->findPointer("videoSource", &ptr));
469
470        mPacketSources.add(
471                LiveSession::STREAMTYPE_VIDEO,
472                static_cast<AnotherPacketSource *>(ptr));
473    }
474
475    if (streamTypeMask & LiveSession::STREAMTYPE_SUBTITLES) {
476        void *ptr;
477        CHECK(msg->findPointer("subtitleSource", &ptr));
478
479        mPacketSources.add(
480                LiveSession::STREAMTYPE_SUBTITLES,
481                static_cast<AnotherPacketSource *>(ptr));
482    }
483
484    mStreamTypeMask = streamTypeMask;
485    mStartTimeUs = startTimeUs;
486
487    if (mStartTimeUs >= 0ll) {
488        mSeqNumber = -1;
489        mStartup = true;
490        mPrepared = false;
491    }
492
493    if (startSeqNumberHint >= 0) {
494        mSeqNumber = startSeqNumberHint;
495    }
496
497    postMonitorQueue();
498
499    return OK;
500}
501
502void PlaylistFetcher::onPause() {
503    cancelMonitorQueue();
504}
505
506void PlaylistFetcher::onStop(const sp<AMessage> &msg) {
507    cancelMonitorQueue();
508
509    int32_t selfTriggered;
510    CHECK(msg->findInt32("selfTriggered", &selfTriggered));
511    if (!selfTriggered) {
512        // Self triggered stops only happen during switching, in which case we do not want
513        // to clear the discontinuities queued at the end of packet sources.
514        for (size_t i = 0; i < mPacketSources.size(); i++) {
515            sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
516            packetSource->clear();
517        }
518    }
519
520    mPacketSources.clear();
521    mStreamTypeMask = 0;
522}
523
524// Resume until we have reached the boundary timestamps listed in `msg`; when
525// the remaining time is too short (within a resume threshold) stop immediately
526// instead.
527status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) {
528    sp<AMessage> params;
529    CHECK(msg->findMessage("params", &params));
530
531    bool stop = false;
532    for (size_t i = 0; i < mPacketSources.size(); i++) {
533        sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
534
535        const char *stopKey;
536        int streamType = mPacketSources.keyAt(i);
537        switch (streamType) {
538        case LiveSession::STREAMTYPE_VIDEO:
539            stopKey = "timeUsVideo";
540            break;
541
542        case LiveSession::STREAMTYPE_AUDIO:
543            stopKey = "timeUsAudio";
544            break;
545
546        case LiveSession::STREAMTYPE_SUBTITLES:
547            stopKey = "timeUsSubtitle";
548            break;
549
550        default:
551            TRESPASS();
552        }
553
554        // Don't resume if we would stop within a resume threshold.
555        int64_t latestTimeUs = 0, stopTimeUs = 0;
556        sp<AMessage> latestMeta = packetSource->getLatestMeta();
557        if (latestMeta != NULL
558                && (latestMeta->findInt64("timeUs", &latestTimeUs)
559                && params->findInt64(stopKey, &stopTimeUs))) {
560            int64_t diffUs = stopTimeUs - latestTimeUs;
561            if (diffUs < resumeThreshold(latestMeta)) {
562                stop = true;
563            }
564        }
565    }
566
567    if (stop) {
568        for (size_t i = 0; i < mPacketSources.size(); i++) {
569            mPacketSources.valueAt(i)->queueAccessUnit(mSession->createFormatChangeBuffer());
570        }
571        stopAsync(/* selfTriggered = */ true);
572        return OK;
573    }
574
575    mStopParams = params;
576    postMonitorQueue();
577
578    return OK;
579}
580
581void PlaylistFetcher::notifyError(status_t err) {
582    sp<AMessage> notify = mNotify->dup();
583    notify->setInt32("what", kWhatError);
584    notify->setInt32("err", err);
585    notify->post();
586}
587
588void PlaylistFetcher::queueDiscontinuity(
589        ATSParser::DiscontinuityType type, const sp<AMessage> &extra) {
590    for (size_t i = 0; i < mPacketSources.size(); ++i) {
591        mPacketSources.valueAt(i)->queueDiscontinuity(type, extra);
592    }
593}
594
595void PlaylistFetcher::onMonitorQueue() {
596    bool downloadMore = false;
597    refreshPlaylist();
598
599    int32_t targetDurationSecs;
600    int64_t targetDurationUs = kMinBufferedDurationUs;
601    if (mPlaylist != NULL) {
602        CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
603        targetDurationUs = targetDurationSecs * 1000000ll;
604    }
605
606    // buffer at least 3 times the target duration, or up to 10 seconds
607    int64_t durationToBufferUs = targetDurationUs * 3;
608    if (durationToBufferUs > kMinBufferedDurationUs)  {
609        durationToBufferUs = kMinBufferedDurationUs;
610    }
611
612    int64_t bufferedDurationUs = 0ll;
613    status_t finalResult = NOT_ENOUGH_DATA;
614    if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) {
615        sp<AnotherPacketSource> packetSource =
616            mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES);
617
618        bufferedDurationUs =
619                packetSource->getBufferedDurationUs(&finalResult);
620        finalResult = OK;
621    } else {
622        // Use max stream duration to prevent us from waiting on a non-existent stream;
623        // when we cannot make out from the manifest what streams are included in a playlist
624        // we might assume extra streams.
625        for (size_t i = 0; i < mPacketSources.size(); ++i) {
626            if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0) {
627                continue;
628            }
629
630            int64_t bufferedStreamDurationUs =
631                mPacketSources.valueAt(i)->getBufferedDurationUs(&finalResult);
632            ALOGV("buffered %" PRId64 " for stream %d",
633                    bufferedStreamDurationUs, mPacketSources.keyAt(i));
634            if (bufferedStreamDurationUs > bufferedDurationUs) {
635                bufferedDurationUs = bufferedStreamDurationUs;
636            }
637        }
638    }
639    downloadMore = (bufferedDurationUs < durationToBufferUs);
640
641    // signal start if buffered up at least the target size
642    if (!mPrepared && bufferedDurationUs > targetDurationUs && downloadMore) {
643        mPrepared = true;
644
645        ALOGV("prepared, buffered=%" PRId64 " > %" PRId64 "",
646                bufferedDurationUs, targetDurationUs);
647        sp<AMessage> msg = mNotify->dup();
648        msg->setInt32("what", kWhatTemporarilyDoneFetching);
649        msg->post();
650    }
651
652    if (finalResult == OK && downloadMore) {
653        ALOGV("monitoring, buffered=%" PRId64 " < %" PRId64 "",
654                bufferedDurationUs, durationToBufferUs);
655        // delay the next download slightly; hopefully this gives other concurrent fetchers
656        // a better chance to run.
657        // onDownloadNext();
658        sp<AMessage> msg = new AMessage(kWhatDownloadNext, id());
659        msg->setInt32("generation", mMonitorQueueGeneration);
660        msg->post(1000l);
661    } else {
662        // Nothing to do yet, try again in a second.
663
664        sp<AMessage> msg = mNotify->dup();
665        msg->setInt32("what", kWhatTemporarilyDoneFetching);
666        msg->post();
667
668        int64_t delayUs = mPrepared ? kMaxMonitorDelayUs : targetDurationUs / 2;
669        ALOGV("pausing for %" PRId64 ", buffered=%" PRId64 " > %" PRId64 "",
670                delayUs, bufferedDurationUs, durationToBufferUs);
671        // :TRICKY: need to enforce minimum delay because the delay to
672        // refresh the playlist will become 0
673        postMonitorQueue(delayUs, mPrepared ? targetDurationUs * 2 : 0);
674    }
675}
676
677status_t PlaylistFetcher::refreshPlaylist() {
678    if (delayUsToRefreshPlaylist() <= 0) {
679        bool unchanged;
680        sp<M3UParser> playlist = mSession->fetchPlaylist(
681                mURI.c_str(), mPlaylistHash, &unchanged);
682
683        if (playlist == NULL) {
684            if (unchanged) {
685                // We succeeded in fetching the playlist, but it was
686                // unchanged from the last time we tried.
687
688                if (mRefreshState != THIRD_UNCHANGED_RELOAD_ATTEMPT) {
689                    mRefreshState = (RefreshState)(mRefreshState + 1);
690                }
691            } else {
692                ALOGE("failed to load playlist at url '%s'", mURI.c_str());
693                notifyError(ERROR_IO);
694                return ERROR_IO;
695            }
696        } else {
697            mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY;
698            mPlaylist = playlist;
699
700            if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
701                updateDuration();
702            }
703        }
704
705        mLastPlaylistFetchTimeUs = ALooper::GetNowUs();
706    }
707    return OK;
708}
709
710// static
711bool PlaylistFetcher::bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer) {
712    return buffer->size() > 0 && buffer->data()[0] == 0x47;
713}
714
715void PlaylistFetcher::onDownloadNext() {
716    if (refreshPlaylist() != OK) {
717        return;
718    }
719
720    int32_t firstSeqNumberInPlaylist;
721    if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
722                "media-sequence", &firstSeqNumberInPlaylist)) {
723        firstSeqNumberInPlaylist = 0;
724    }
725
726    bool seekDiscontinuity = false;
727    bool explicitDiscontinuity = false;
728
729    const int32_t lastSeqNumberInPlaylist =
730        firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1;
731
732    if (mStartup && mSeqNumber >= 0
733            && (mSeqNumber < firstSeqNumberInPlaylist || mSeqNumber > lastSeqNumberInPlaylist)) {
734        // in case we guessed wrong during reconfiguration, try fetching the latest content.
735        mSeqNumber = lastSeqNumberInPlaylist;
736    }
737
738    if (mSeqNumber < 0) {
739        CHECK_GE(mStartTimeUs, 0ll);
740
741        if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
742            mSeqNumber = getSeqNumberForTime(mStartTimeUs);
743            ALOGV("Initial sequence number for time %" PRId64 " is %d from (%d .. %d)",
744                    mStartTimeUs, mSeqNumber, firstSeqNumberInPlaylist,
745                    lastSeqNumberInPlaylist);
746        } else {
747            // If this is a live session, start 3 segments from the end.
748            mSeqNumber = lastSeqNumberInPlaylist - 3;
749            if (mSeqNumber < firstSeqNumberInPlaylist) {
750                mSeqNumber = firstSeqNumberInPlaylist;
751            }
752            ALOGV("Initial sequence number for live event %d from (%d .. %d)",
753                    mSeqNumber, firstSeqNumberInPlaylist,
754                    lastSeqNumberInPlaylist);
755        }
756
757        mStartTimeUs = -1ll;
758    }
759
760    if (mSeqNumber < firstSeqNumberInPlaylist
761            || mSeqNumber > lastSeqNumberInPlaylist) {
762        if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) {
763            ++mNumRetries;
764
765            if (mSeqNumber > lastSeqNumberInPlaylist) {
766                // refresh in increasing fraction (1/2, 1/3, ...) of the
767                // playlist's target duration or 3 seconds, whichever is less
768                int32_t targetDurationSecs;
769                CHECK(mPlaylist->meta()->findInt32(
770                        "target-duration", &targetDurationSecs));
771                int64_t delayUs = mPlaylist->size() * targetDurationSecs *
772                        1000000ll / (1 + mNumRetries);
773                if (delayUs > kMaxMonitorDelayUs) {
774                    delayUs = kMaxMonitorDelayUs;
775                }
776                ALOGV("sequence number high: %d from (%d .. %d), "
777                      "monitor in %" PRId64 " (retry=%d)",
778                        mSeqNumber, firstSeqNumberInPlaylist,
779                        lastSeqNumberInPlaylist, delayUs, mNumRetries);
780                postMonitorQueue(delayUs);
781                return;
782            }
783
784            // we've missed the boat, let's start from the lowest sequence
785            // number available and signal a discontinuity.
786
787            ALOGI("We've missed the boat, restarting playback."
788                  "  mStartup=%d, was  looking for %d in %d-%d",
789                    mStartup, mSeqNumber, firstSeqNumberInPlaylist,
790                    lastSeqNumberInPlaylist);
791            mSeqNumber = lastSeqNumberInPlaylist - 3;
792            if (mSeqNumber < firstSeqNumberInPlaylist) {
793                mSeqNumber = firstSeqNumberInPlaylist;
794            }
795            explicitDiscontinuity = true;
796
797            // fall through
798        } else {
799            ALOGE("Cannot find sequence number %d in playlist "
800                 "(contains %d - %d)",
801                 mSeqNumber, firstSeqNumberInPlaylist,
802                  firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1);
803
804            notifyError(ERROR_END_OF_STREAM);
805            return;
806        }
807    }
808
809    mNumRetries = 0;
810
811    AString uri;
812    sp<AMessage> itemMeta;
813    CHECK(mPlaylist->itemAt(
814                mSeqNumber - firstSeqNumberInPlaylist,
815                &uri,
816                &itemMeta));
817
818    int32_t val;
819    if (itemMeta->findInt32("discontinuity", &val) && val != 0) {
820        explicitDiscontinuity = true;
821    }
822
823    int64_t range_offset, range_length;
824    if (!itemMeta->findInt64("range-offset", &range_offset)
825            || !itemMeta->findInt64("range-length", &range_length)) {
826        range_offset = 0;
827        range_length = -1;
828    }
829
830    ALOGV("fetching segment %d from (%d .. %d)",
831          mSeqNumber, firstSeqNumberInPlaylist, lastSeqNumberInPlaylist);
832
833    ALOGV("fetching '%s'", uri.c_str());
834
835    sp<DataSource> source;
836    sp<ABuffer> buffer, tsBuffer;
837    // decrypt a junk buffer to prefetch key; since a session uses only one http connection,
838    // this avoids interleaved connections to the key and segment file.
839    {
840        sp<ABuffer> junk = new ABuffer(16);
841        junk->setRange(0, 16);
842        status_t err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, junk,
843                true /* first */);
844        if (err != OK) {
845            notifyError(err);
846            return;
847        }
848    }
849
850    // block-wise download
851    ssize_t bytesRead;
852    do {
853        bytesRead = mSession->fetchFile(
854                uri.c_str(), &buffer, range_offset, range_length, kDownloadBlockSize, &source);
855
856        if (bytesRead < 0) {
857            status_t err = bytesRead;
858            ALOGE("failed to fetch .ts segment at url '%s'", uri.c_str());
859            notifyError(err);
860            return;
861        }
862
863        CHECK(buffer != NULL);
864
865        size_t size = buffer->size();
866        // Set decryption range.
867        buffer->setRange(size - bytesRead, bytesRead);
868        status_t err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer,
869                buffer->offset() == 0 /* first */);
870        // Unset decryption range.
871        buffer->setRange(0, size);
872
873        if (err != OK) {
874            ALOGE("decryptBuffer failed w/ error %d", err);
875
876            notifyError(err);
877            return;
878        }
879
880        if (mStartup || seekDiscontinuity || explicitDiscontinuity) {
881            // Signal discontinuity.
882
883            if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
884                // If this was a live event this made no sense since
885                // we don't have access to all the segment before the current
886                // one.
887                mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber);
888            }
889
890            if (seekDiscontinuity || explicitDiscontinuity) {
891                ALOGI("queueing discontinuity (seek=%d, explicit=%d)",
892                     seekDiscontinuity, explicitDiscontinuity);
893
894                queueDiscontinuity(
895                        explicitDiscontinuity
896                            ? ATSParser::DISCONTINUITY_FORMATCHANGE
897                            : ATSParser::DISCONTINUITY_SEEK,
898                        NULL /* extra */);
899
900                seekDiscontinuity = false;
901                explicitDiscontinuity = false;
902            }
903        }
904
905        err = OK;
906        if (bufferStartsWithTsSyncByte(buffer)) {
907            // Incremental extraction is only supported for MPEG2 transport streams.
908            if (tsBuffer == NULL) {
909                tsBuffer = new ABuffer(buffer->data(), buffer->capacity());
910                tsBuffer->setRange(0, 0);
911            } else if (tsBuffer->capacity() != buffer->capacity()) {
912                size_t tsOff = tsBuffer->offset(), tsSize = tsBuffer->size();
913                tsBuffer = new ABuffer(buffer->data(), buffer->capacity());
914                tsBuffer->setRange(tsOff, tsSize);
915            }
916            tsBuffer->setRange(tsBuffer->offset(), tsBuffer->size() + bytesRead);
917
918            err = extractAndQueueAccessUnitsFromTs(tsBuffer);
919        }
920
921        if (err == -EAGAIN) {
922            // bad starting sequence number hint
923            mTSParser.clear();
924            postMonitorQueue();
925            return;
926        }
927
928        if (err == ERROR_OUT_OF_RANGE) {
929            // reached stopping point
930            stopAsync(/* selfTriggered = */ true);
931            return;
932        }
933
934        if (err != OK) {
935            notifyError(err);
936            return;
937        }
938
939        mStartup = false;
940    } while (bytesRead != 0);
941
942    if (bufferStartsWithTsSyncByte(buffer)) {
943        // If we still don't see a stream after fetching a full ts segment mark it as
944        // nonexistent.
945        const size_t kNumTypes = ATSParser::NUM_SOURCE_TYPES;
946        ATSParser::SourceType srcTypes[kNumTypes] =
947                { ATSParser::VIDEO, ATSParser::AUDIO };
948        LiveSession::StreamType streamTypes[kNumTypes] =
949                { LiveSession::STREAMTYPE_VIDEO, LiveSession::STREAMTYPE_AUDIO };
950
951        for (size_t i = 0; i < kNumTypes; i++) {
952            ATSParser::SourceType srcType = srcTypes[i];
953            LiveSession::StreamType streamType = streamTypes[i];
954
955            sp<AnotherPacketSource> source =
956                static_cast<AnotherPacketSource *>(
957                    mTSParser->getSource(srcType).get());
958
959            if (source == NULL) {
960                ALOGW("MPEG2 Transport stream does not contain %s data.",
961                      srcType == ATSParser::VIDEO ? "video" : "audio");
962
963                mStreamTypeMask &= ~streamType;
964                mPacketSources.removeItem(streamType);
965            }
966        }
967
968    }
969
970    if (checkDecryptPadding(buffer) != OK) {
971        ALOGE("Incorrect padding bytes after decryption.");
972        notifyError(ERROR_MALFORMED);
973        return;
974    }
975
976    status_t err = OK;
977    if (tsBuffer != NULL) {
978        AString method;
979        CHECK(buffer->meta()->findString("cipher-method", &method));
980        if ((tsBuffer->size() > 0 && method == "NONE")
981                || tsBuffer->size() > 16) {
982            ALOGE("MPEG2 transport stream is not an even multiple of 188 "
983                    "bytes in length.");
984            notifyError(ERROR_MALFORMED);
985            return;
986        }
987    }
988
989    // bulk extract non-ts files
990    if (tsBuffer == NULL) {
991      err = extractAndQueueAccessUnits(buffer, itemMeta);
992    }
993
994    if (err != OK) {
995        notifyError(err);
996        return;
997    }
998
999    ++mSeqNumber;
1000
1001    postMonitorQueue();
1002}
1003
1004int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const {
1005    int32_t firstSeqNumberInPlaylist;
1006    if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
1007                "media-sequence", &firstSeqNumberInPlaylist)) {
1008        firstSeqNumberInPlaylist = 0;
1009    }
1010
1011    size_t index = 0;
1012    int64_t segmentStartUs = 0;
1013    while (index < mPlaylist->size()) {
1014        sp<AMessage> itemMeta;
1015        CHECK(mPlaylist->itemAt(
1016                    index, NULL /* uri */, &itemMeta));
1017
1018        int64_t itemDurationUs;
1019        CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
1020
1021        if (timeUs < segmentStartUs + itemDurationUs) {
1022            break;
1023        }
1024
1025        segmentStartUs += itemDurationUs;
1026        ++index;
1027    }
1028
1029    if (index >= mPlaylist->size()) {
1030        index = mPlaylist->size() - 1;
1031    }
1032
1033    return firstSeqNumberInPlaylist + index;
1034}
1035
1036status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer) {
1037    if (mTSParser == NULL) {
1038        // Use TS_TIMESTAMPS_ARE_ABSOLUTE so pts carry over between fetchers.
1039        mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE);
1040    }
1041
1042    if (mNextPTSTimeUs >= 0ll) {
1043        sp<AMessage> extra = new AMessage;
1044        // Since we are using absolute timestamps, signal an offset of 0 to prevent
1045        // ATSParser from skewing the timestamps of access units.
1046        extra->setInt64(IStreamListener::kKeyMediaTimeUs, 0);
1047
1048        mTSParser->signalDiscontinuity(
1049                ATSParser::DISCONTINUITY_SEEK, extra);
1050
1051        mNextPTSTimeUs = -1ll;
1052    }
1053
1054    size_t offset = 0;
1055    while (offset + 188 <= buffer->size()) {
1056        status_t err = mTSParser->feedTSPacket(buffer->data() + offset, 188);
1057
1058        if (err != OK) {
1059            return err;
1060        }
1061
1062        offset += 188;
1063    }
1064    // setRange to indicate consumed bytes.
1065    buffer->setRange(buffer->offset() + offset, buffer->size() - offset);
1066
1067    status_t err = OK;
1068    for (size_t i = mPacketSources.size(); i-- > 0;) {
1069        sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
1070
1071        const char *key;
1072        ATSParser::SourceType type;
1073        const LiveSession::StreamType stream = mPacketSources.keyAt(i);
1074        switch (stream) {
1075            case LiveSession::STREAMTYPE_VIDEO:
1076                type = ATSParser::VIDEO;
1077                key = "timeUsVideo";
1078                break;
1079
1080            case LiveSession::STREAMTYPE_AUDIO:
1081                type = ATSParser::AUDIO;
1082                key = "timeUsAudio";
1083                break;
1084
1085            case LiveSession::STREAMTYPE_SUBTITLES:
1086            {
1087                ALOGE("MPEG2 Transport streams do not contain subtitles.");
1088                return ERROR_MALFORMED;
1089                break;
1090            }
1091
1092            default:
1093                TRESPASS();
1094        }
1095
1096        sp<AnotherPacketSource> source =
1097            static_cast<AnotherPacketSource *>(
1098                    mTSParser->getSource(type).get());
1099
1100        if (source == NULL) {
1101            continue;
1102        }
1103
1104        if (stream == LiveSession::STREAMTYPE_VIDEO && mVideoMime.empty()) {
1105            const char *mime;
1106            if (source->getFormat()->findCString(kKeyMIMEType, &mime)) {
1107                mVideoMime.setTo(mime);
1108                if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1109                    mSkipToFirstIDRAfterConnect = true;
1110                }
1111            }
1112        }
1113
1114        int64_t timeUs;
1115        sp<ABuffer> accessUnit;
1116        status_t finalResult;
1117        while (source->hasBufferAvailable(&finalResult)
1118                && source->dequeueAccessUnit(&accessUnit) == OK) {
1119
1120            if (stream == LiveSession::STREAMTYPE_VIDEO && mSkipToFirstIDRAfterConnect) {
1121                if (!IsIDR(accessUnit)) {
1122                    continue;
1123                } else {
1124                    mSkipToFirstIDRAfterConnect = false;
1125                }
1126            }
1127
1128            CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
1129            if (mMinStartTimeUs > 0) {
1130                if (timeUs < mMinStartTimeUs) {
1131                    // TODO untested path
1132                    // try a later ts
1133                    int32_t targetDuration;
1134                    mPlaylist->meta()->findInt32("target-duration", &targetDuration);
1135                    int32_t incr = (mMinStartTimeUs - timeUs) / 1000000 / targetDuration;
1136                    if (incr == 0) {
1137                        // increment mSeqNumber by at least one
1138                        incr = 1;
1139                    }
1140                    mSeqNumber += incr;
1141                    err = -EAGAIN;
1142                    break;
1143                } else {
1144                    int64_t startTimeUs;
1145                    if (mStartTimeUsNotify != NULL
1146                            && !mStartTimeUsNotify->findInt64(key, &startTimeUs)) {
1147                        mStartTimeUsNotify->setInt64(key, timeUs);
1148
1149                        uint32_t streamMask = 0;
1150                        mStartTimeUsNotify->findInt32("streamMask", (int32_t *) &streamMask);
1151                        streamMask |= mPacketSources.keyAt(i);
1152                        mStartTimeUsNotify->setInt32("streamMask", streamMask);
1153
1154                        if (streamMask == mStreamTypeMask) {
1155                            mStartTimeUsNotify->post();
1156                            mStartTimeUsNotify.clear();
1157                        }
1158                    }
1159                }
1160            }
1161
1162            if (mStopParams != NULL) {
1163                // Queue discontinuity in original stream.
1164                int64_t stopTimeUs;
1165                if (!mStopParams->findInt64(key, &stopTimeUs) || timeUs >= stopTimeUs) {
1166                    packetSource->queueAccessUnit(mSession->createFormatChangeBuffer());
1167                    mStreamTypeMask &= ~stream;
1168                    mPacketSources.removeItemsAt(i);
1169                    break;
1170                }
1171            }
1172
1173            // Note that we do NOT dequeue any discontinuities except for format change.
1174
1175            // for simplicity, store a reference to the format in each unit
1176            sp<MetaData> format = source->getFormat();
1177            if (format != NULL) {
1178                accessUnit->meta()->setObject("format", format);
1179            }
1180
1181            // Stash the sequence number so we can hint future playlist where to start at.
1182            accessUnit->meta()->setInt32("seq", mSeqNumber);
1183            packetSource->queueAccessUnit(accessUnit);
1184        }
1185
1186        if (err != OK) {
1187            break;
1188        }
1189    }
1190
1191    if (err != OK) {
1192        for (size_t i = mPacketSources.size(); i-- > 0;) {
1193            sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
1194            packetSource->clear();
1195        }
1196        return err;
1197    }
1198
1199    if (!mStreamTypeMask) {
1200        // Signal gap is filled between original and new stream.
1201        ALOGV("ERROR OUT OF RANGE");
1202        return ERROR_OUT_OF_RANGE;
1203    }
1204
1205    return OK;
1206}
1207
1208/* static */
1209bool PlaylistFetcher::bufferStartsWithWebVTTMagicSequence(
1210        const sp<ABuffer> &buffer) {
1211    size_t pos = 0;
1212
1213    // skip possible BOM
1214    if (buffer->size() >= pos + 3 &&
1215            !memcmp("\xef\xbb\xbf", buffer->data() + pos, 3)) {
1216        pos += 3;
1217    }
1218
1219    // accept WEBVTT followed by SPACE, TAB or (CR) LF
1220    if (buffer->size() < pos + 6 ||
1221            memcmp("WEBVTT", buffer->data() + pos, 6)) {
1222        return false;
1223    }
1224    pos += 6;
1225
1226    if (buffer->size() == pos) {
1227        return true;
1228    }
1229
1230    uint8_t sep = buffer->data()[pos];
1231    return sep == ' ' || sep == '\t' || sep == '\n' || sep == '\r';
1232}
1233
1234status_t PlaylistFetcher::extractAndQueueAccessUnits(
1235        const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta) {
1236    if (bufferStartsWithWebVTTMagicSequence(buffer)) {
1237        if (mStreamTypeMask != LiveSession::STREAMTYPE_SUBTITLES) {
1238            ALOGE("This stream only contains subtitles.");
1239            return ERROR_MALFORMED;
1240        }
1241
1242        const sp<AnotherPacketSource> packetSource =
1243            mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES);
1244
1245        int64_t durationUs;
1246        CHECK(itemMeta->findInt64("durationUs", &durationUs));
1247        buffer->meta()->setInt64("timeUs", getSegmentStartTimeUs(mSeqNumber));
1248        buffer->meta()->setInt64("durationUs", durationUs);
1249        buffer->meta()->setInt32("seq", mSeqNumber);
1250
1251        packetSource->queueAccessUnit(buffer);
1252        return OK;
1253    }
1254
1255    if (mNextPTSTimeUs >= 0ll) {
1256        mFirstPTSValid = false;
1257        mAbsoluteTimeAnchorUs = mNextPTSTimeUs;
1258        mNextPTSTimeUs = -1ll;
1259    }
1260
1261    // This better be an ISO 13818-7 (AAC) or ISO 13818-1 (MPEG) audio
1262    // stream prefixed by an ID3 tag.
1263
1264    bool firstID3Tag = true;
1265    uint64_t PTS = 0;
1266
1267    for (;;) {
1268        // Make sure to skip all ID3 tags preceding the audio data.
1269        // At least one must be present to provide the PTS timestamp.
1270
1271        ID3 id3(buffer->data(), buffer->size(), true /* ignoreV1 */);
1272        if (!id3.isValid()) {
1273            if (firstID3Tag) {
1274                ALOGE("Unable to parse ID3 tag.");
1275                return ERROR_MALFORMED;
1276            } else {
1277                break;
1278            }
1279        }
1280
1281        if (firstID3Tag) {
1282            bool found = false;
1283
1284            ID3::Iterator it(id3, "PRIV");
1285            while (!it.done()) {
1286                size_t length;
1287                const uint8_t *data = it.getData(&length);
1288
1289                static const char *kMatchName =
1290                    "com.apple.streaming.transportStreamTimestamp";
1291                static const size_t kMatchNameLen = strlen(kMatchName);
1292
1293                if (length == kMatchNameLen + 1 + 8
1294                        && !strncmp((const char *)data, kMatchName, kMatchNameLen)) {
1295                    found = true;
1296                    PTS = U64_AT(&data[kMatchNameLen + 1]);
1297                }
1298
1299                it.next();
1300            }
1301
1302            if (!found) {
1303                ALOGE("Unable to extract transportStreamTimestamp from ID3 tag.");
1304                return ERROR_MALFORMED;
1305            }
1306        }
1307
1308        // skip the ID3 tag
1309        buffer->setRange(
1310                buffer->offset() + id3.rawSize(), buffer->size() - id3.rawSize());
1311
1312        firstID3Tag = false;
1313    }
1314
1315    if (!mFirstPTSValid) {
1316        mFirstPTSValid = true;
1317        mFirstPTS = PTS;
1318    }
1319    PTS -= mFirstPTS;
1320
1321    int64_t timeUs = (PTS * 100ll) / 9ll + mAbsoluteTimeAnchorUs;
1322
1323    if (mStreamTypeMask != LiveSession::STREAMTYPE_AUDIO) {
1324        ALOGW("This stream only contains audio data!");
1325
1326        mStreamTypeMask &= LiveSession::STREAMTYPE_AUDIO;
1327
1328        if (mStreamTypeMask == 0) {
1329            return OK;
1330        }
1331    }
1332
1333    sp<AnotherPacketSource> packetSource =
1334        mPacketSources.valueFor(LiveSession::STREAMTYPE_AUDIO);
1335
1336    if (packetSource->getFormat() == NULL && buffer->size() >= 7) {
1337        ABitReader bits(buffer->data(), buffer->size());
1338
1339        // adts_fixed_header
1340
1341        CHECK_EQ(bits.getBits(12), 0xfffu);
1342        bits.skipBits(3);  // ID, layer
1343        bool protection_absent = bits.getBits(1) != 0;
1344
1345        unsigned profile = bits.getBits(2);
1346        CHECK_NE(profile, 3u);
1347        unsigned sampling_freq_index = bits.getBits(4);
1348        bits.getBits(1);  // private_bit
1349        unsigned channel_configuration = bits.getBits(3);
1350        CHECK_NE(channel_configuration, 0u);
1351        bits.skipBits(2);  // original_copy, home
1352
1353        sp<MetaData> meta = MakeAACCodecSpecificData(
1354                profile, sampling_freq_index, channel_configuration);
1355
1356        meta->setInt32(kKeyIsADTS, true);
1357
1358        packetSource->setFormat(meta);
1359    }
1360
1361    int64_t numSamples = 0ll;
1362    int32_t sampleRate;
1363    CHECK(packetSource->getFormat()->findInt32(kKeySampleRate, &sampleRate));
1364
1365    size_t offset = 0;
1366    while (offset < buffer->size()) {
1367        const uint8_t *adtsHeader = buffer->data() + offset;
1368        CHECK_LT(offset + 5, buffer->size());
1369
1370        unsigned aac_frame_length =
1371            ((adtsHeader[3] & 3) << 11)
1372            | (adtsHeader[4] << 3)
1373            | (adtsHeader[5] >> 5);
1374
1375        if (aac_frame_length == 0) {
1376            const uint8_t *id3Header = adtsHeader;
1377            if (!memcmp(id3Header, "ID3", 3)) {
1378                ID3 id3(id3Header, buffer->size() - offset, true);
1379                if (id3.isValid()) {
1380                    offset += id3.rawSize();
1381                    continue;
1382                };
1383            }
1384            return ERROR_MALFORMED;
1385        }
1386
1387        CHECK_LE(offset + aac_frame_length, buffer->size());
1388
1389        sp<ABuffer> unit = new ABuffer(aac_frame_length);
1390        memcpy(unit->data(), adtsHeader, aac_frame_length);
1391
1392        int64_t unitTimeUs = timeUs + numSamples * 1000000ll / sampleRate;
1393        unit->meta()->setInt64("timeUs", unitTimeUs);
1394
1395        // Each AAC frame encodes 1024 samples.
1396        numSamples += 1024;
1397
1398        unit->meta()->setInt32("seq", mSeqNumber);
1399        packetSource->queueAccessUnit(unit);
1400
1401        offset += aac_frame_length;
1402    }
1403
1404    return OK;
1405}
1406
1407void PlaylistFetcher::updateDuration() {
1408    int64_t durationUs = 0ll;
1409    for (size_t index = 0; index < mPlaylist->size(); ++index) {
1410        sp<AMessage> itemMeta;
1411        CHECK(mPlaylist->itemAt(
1412                    index, NULL /* uri */, &itemMeta));
1413
1414        int64_t itemDurationUs;
1415        CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
1416
1417        durationUs += itemDurationUs;
1418    }
1419
1420    sp<AMessage> msg = mNotify->dup();
1421    msg->setInt32("what", kWhatDurationUpdate);
1422    msg->setInt64("durationUs", durationUs);
1423    msg->post();
1424}
1425
1426int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) {
1427    int64_t durationUs, threshold;
1428    if (msg->findInt64("durationUs", &durationUs)) {
1429        return kNumSkipFrames * durationUs;
1430    }
1431
1432    sp<RefBase> obj;
1433    msg->findObject("format", &obj);
1434    MetaData *format = static_cast<MetaData *>(obj.get());
1435
1436    const char *mime;
1437    CHECK(format->findCString(kKeyMIMEType, &mime));
1438    bool audio = !strncasecmp(mime, "audio/", 6);
1439    if (audio) {
1440        // Assumes 1000 samples per frame.
1441        int32_t sampleRate;
1442        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
1443        return kNumSkipFrames  /* frames */ * 1000 /* samples */
1444                * (1000000 / sampleRate) /* sample duration (us) */;
1445    } else {
1446        int32_t frameRate;
1447        if (format->findInt32(kKeyFrameRate, &frameRate) && frameRate > 0) {
1448            return kNumSkipFrames * (1000000 / frameRate);
1449        }
1450    }
1451
1452    return 500000ll;
1453}
1454
1455}  // namespace android
1456