PlaylistFetcher.cpp revision dcb89b3b505522efde173c105a851c412f947178
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 <openssl/aes.h>
44#include <openssl/md5.h>
45
46namespace android {
47
48// static
49const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
50
51PlaylistFetcher::PlaylistFetcher(
52        const sp<AMessage> &notify,
53        const sp<LiveSession> &session,
54        const char *uri)
55    : mNotify(notify),
56      mSession(session),
57      mURI(uri),
58      mStreamTypeMask(0),
59      mStartTimeUs(-1ll),
60      mLastPlaylistFetchTimeUs(-1ll),
61      mSeqNumber(-1),
62      mNumRetries(0),
63      mStartup(true),
64      mNextPTSTimeUs(-1ll),
65      mMonitorQueueGeneration(0),
66      mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY),
67      mFirstPTSValid(false),
68      mAbsoluteTimeAnchorUs(0ll) {
69    memset(mPlaylistHash, 0, sizeof(mPlaylistHash));
70}
71
72PlaylistFetcher::~PlaylistFetcher() {
73}
74
75int64_t PlaylistFetcher::getSegmentStartTimeUs(int32_t seqNumber) const {
76    CHECK(mPlaylist != NULL);
77
78    int32_t firstSeqNumberInPlaylist;
79    if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
80                "media-sequence", &firstSeqNumberInPlaylist)) {
81        firstSeqNumberInPlaylist = 0;
82    }
83
84    int32_t lastSeqNumberInPlaylist =
85        firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1;
86
87    CHECK_GE(seqNumber, firstSeqNumberInPlaylist);
88    CHECK_LE(seqNumber, lastSeqNumberInPlaylist);
89
90    int64_t segmentStartUs = 0ll;
91    for (int32_t index = 0;
92            index < seqNumber - firstSeqNumberInPlaylist; ++index) {
93        sp<AMessage> itemMeta;
94        CHECK(mPlaylist->itemAt(
95                    index, NULL /* uri */, &itemMeta));
96
97        int64_t itemDurationUs;
98        CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
99
100        segmentStartUs += itemDurationUs;
101    }
102
103    return segmentStartUs;
104}
105
106bool PlaylistFetcher::timeToRefreshPlaylist(int64_t nowUs) const {
107    if (mPlaylist == NULL) {
108        CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY);
109        return true;
110    }
111
112    int32_t targetDurationSecs;
113    CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
114
115    int64_t targetDurationUs = targetDurationSecs * 1000000ll;
116
117    int64_t minPlaylistAgeUs;
118
119    switch (mRefreshState) {
120        case INITIAL_MINIMUM_RELOAD_DELAY:
121        {
122            size_t n = mPlaylist->size();
123            if (n > 0) {
124                sp<AMessage> itemMeta;
125                CHECK(mPlaylist->itemAt(n - 1, NULL /* uri */, &itemMeta));
126
127                int64_t itemDurationUs;
128                CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
129
130                minPlaylistAgeUs = itemDurationUs;
131                break;
132            }
133
134            // fall through
135        }
136
137        case FIRST_UNCHANGED_RELOAD_ATTEMPT:
138        {
139            minPlaylistAgeUs = targetDurationUs / 2;
140            break;
141        }
142
143        case SECOND_UNCHANGED_RELOAD_ATTEMPT:
144        {
145            minPlaylistAgeUs = (targetDurationUs * 3) / 2;
146            break;
147        }
148
149        case THIRD_UNCHANGED_RELOAD_ATTEMPT:
150        {
151            minPlaylistAgeUs = targetDurationUs * 3;
152            break;
153        }
154
155        default:
156            TRESPASS();
157            break;
158    }
159
160    return mLastPlaylistFetchTimeUs + minPlaylistAgeUs <= nowUs;
161}
162
163status_t PlaylistFetcher::decryptBuffer(
164        size_t playlistIndex, const sp<ABuffer> &buffer) {
165    sp<AMessage> itemMeta;
166    bool found = false;
167    AString method;
168
169    for (ssize_t i = playlistIndex; i >= 0; --i) {
170        AString uri;
171        CHECK(mPlaylist->itemAt(i, &uri, &itemMeta));
172
173        if (itemMeta->findString("cipher-method", &method)) {
174            found = true;
175            break;
176        }
177    }
178
179    if (!found) {
180        method = "NONE";
181    }
182
183    if (method == "NONE") {
184        return OK;
185    } else if (!(method == "AES-128")) {
186        ALOGE("Unsupported cipher method '%s'", method.c_str());
187        return ERROR_UNSUPPORTED;
188    }
189
190    AString keyURI;
191    if (!itemMeta->findString("cipher-uri", &keyURI)) {
192        ALOGE("Missing key uri");
193        return ERROR_MALFORMED;
194    }
195
196    ssize_t index = mAESKeyForURI.indexOfKey(keyURI);
197
198    sp<ABuffer> key;
199    if (index >= 0) {
200        key = mAESKeyForURI.valueAt(index);
201    } else {
202        status_t err = mSession->fetchFile(keyURI.c_str(), &key);
203
204        if (err != OK) {
205            ALOGE("failed to fetch cipher key from '%s'.", keyURI.c_str());
206            return ERROR_IO;
207        } else if (key->size() != 16) {
208            ALOGE("key file '%s' wasn't 16 bytes in size.", keyURI.c_str());
209            return ERROR_MALFORMED;
210        }
211
212        mAESKeyForURI.add(keyURI, key);
213    }
214
215    AES_KEY aes_key;
216    if (AES_set_decrypt_key(key->data(), 128, &aes_key) != 0) {
217        ALOGE("failed to set AES decryption key.");
218        return UNKNOWN_ERROR;
219    }
220
221    unsigned char aes_ivec[16];
222
223    AString iv;
224    if (itemMeta->findString("cipher-iv", &iv)) {
225        if ((!iv.startsWith("0x") && !iv.startsWith("0X"))
226                || iv.size() != 16 * 2 + 2) {
227            ALOGE("malformed cipher IV '%s'.", iv.c_str());
228            return ERROR_MALFORMED;
229        }
230
231        memset(aes_ivec, 0, sizeof(aes_ivec));
232        for (size_t i = 0; i < 16; ++i) {
233            char c1 = tolower(iv.c_str()[2 + 2 * i]);
234            char c2 = tolower(iv.c_str()[3 + 2 * i]);
235            if (!isxdigit(c1) || !isxdigit(c2)) {
236                ALOGE("malformed cipher IV '%s'.", iv.c_str());
237                return ERROR_MALFORMED;
238            }
239            uint8_t nibble1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10;
240            uint8_t nibble2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10;
241
242            aes_ivec[i] = nibble1 << 4 | nibble2;
243        }
244    } else {
245        memset(aes_ivec, 0, sizeof(aes_ivec));
246        aes_ivec[15] = mSeqNumber & 0xff;
247        aes_ivec[14] = (mSeqNumber >> 8) & 0xff;
248        aes_ivec[13] = (mSeqNumber >> 16) & 0xff;
249        aes_ivec[12] = (mSeqNumber >> 24) & 0xff;
250    }
251
252    AES_cbc_encrypt(
253            buffer->data(), buffer->data(), buffer->size(),
254            &aes_key, aes_ivec, AES_DECRYPT);
255
256    // hexdump(buffer->data(), buffer->size());
257
258    size_t n = buffer->size();
259    CHECK_GT(n, 0u);
260
261    size_t pad = buffer->data()[n - 1];
262
263    CHECK_GT(pad, 0u);
264    CHECK_LE(pad, 16u);
265    CHECK_GE((size_t)n, pad);
266    for (size_t i = 0; i < pad; ++i) {
267        CHECK_EQ((unsigned)buffer->data()[n - 1 - i], pad);
268    }
269
270    n -= pad;
271
272    buffer->setRange(buffer->offset(), n);
273
274    return OK;
275}
276
277void PlaylistFetcher::postMonitorQueue(int64_t delayUs) {
278    sp<AMessage> msg = new AMessage(kWhatMonitorQueue, id());
279    msg->setInt32("generation", mMonitorQueueGeneration);
280    msg->post(delayUs);
281}
282
283void PlaylistFetcher::cancelMonitorQueue() {
284    ++mMonitorQueueGeneration;
285}
286
287void PlaylistFetcher::startAsync(
288        const sp<AnotherPacketSource> &audioSource,
289        const sp<AnotherPacketSource> &videoSource,
290        const sp<AnotherPacketSource> &subtitleSource,
291        int64_t startTimeUs) {
292    sp<AMessage> msg = new AMessage(kWhatStart, id());
293
294    uint32_t streamTypeMask = 0ul;
295
296    if (audioSource != NULL) {
297        msg->setPointer("audioSource", audioSource.get());
298        streamTypeMask |= LiveSession::STREAMTYPE_AUDIO;
299    }
300
301    if (videoSource != NULL) {
302        msg->setPointer("videoSource", videoSource.get());
303        streamTypeMask |= LiveSession::STREAMTYPE_VIDEO;
304    }
305
306    if (subtitleSource != NULL) {
307        msg->setPointer("subtitleSource", subtitleSource.get());
308        streamTypeMask |= LiveSession::STREAMTYPE_SUBTITLES;
309    }
310
311    msg->setInt32("streamTypeMask", streamTypeMask);
312    msg->setInt64("startTimeUs", startTimeUs);
313    msg->post();
314}
315
316void PlaylistFetcher::pauseAsync() {
317    (new AMessage(kWhatPause, id()))->post();
318}
319
320void PlaylistFetcher::stopAsync() {
321    (new AMessage(kWhatStop, id()))->post();
322}
323
324void PlaylistFetcher::onMessageReceived(const sp<AMessage> &msg) {
325    switch (msg->what()) {
326        case kWhatStart:
327        {
328            status_t err = onStart(msg);
329
330            sp<AMessage> notify = mNotify->dup();
331            notify->setInt32("what", kWhatStarted);
332            notify->setInt32("err", err);
333            notify->post();
334            break;
335        }
336
337        case kWhatPause:
338        {
339            onPause();
340
341            sp<AMessage> notify = mNotify->dup();
342            notify->setInt32("what", kWhatPaused);
343            notify->post();
344            break;
345        }
346
347        case kWhatStop:
348        {
349            onStop();
350
351            sp<AMessage> notify = mNotify->dup();
352            notify->setInt32("what", kWhatStopped);
353            notify->post();
354            break;
355        }
356
357        case kWhatMonitorQueue:
358        {
359            int32_t generation;
360            CHECK(msg->findInt32("generation", &generation));
361
362            if (generation != mMonitorQueueGeneration) {
363                // Stale event
364                break;
365            }
366
367            onMonitorQueue();
368            break;
369        }
370
371        default:
372            TRESPASS();
373    }
374}
375
376status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) {
377    mPacketSources.clear();
378
379    uint32_t streamTypeMask;
380    CHECK(msg->findInt32("streamTypeMask", (int32_t *)&streamTypeMask));
381
382    int64_t startTimeUs;
383    CHECK(msg->findInt64("startTimeUs", &startTimeUs));
384
385    if (streamTypeMask & LiveSession::STREAMTYPE_AUDIO) {
386        void *ptr;
387        CHECK(msg->findPointer("audioSource", &ptr));
388
389        mPacketSources.add(
390                LiveSession::STREAMTYPE_AUDIO,
391                static_cast<AnotherPacketSource *>(ptr));
392    }
393
394    if (streamTypeMask & LiveSession::STREAMTYPE_VIDEO) {
395        void *ptr;
396        CHECK(msg->findPointer("videoSource", &ptr));
397
398        mPacketSources.add(
399                LiveSession::STREAMTYPE_VIDEO,
400                static_cast<AnotherPacketSource *>(ptr));
401    }
402
403    if (streamTypeMask & LiveSession::STREAMTYPE_SUBTITLES) {
404        void *ptr;
405        CHECK(msg->findPointer("subtitleSource", &ptr));
406
407        mPacketSources.add(
408                LiveSession::STREAMTYPE_SUBTITLES,
409                static_cast<AnotherPacketSource *>(ptr));
410    }
411
412    mStreamTypeMask = streamTypeMask;
413    mStartTimeUs = startTimeUs;
414
415    if (mStartTimeUs >= 0ll) {
416        mSeqNumber = -1;
417        mStartup = true;
418    }
419
420    postMonitorQueue();
421
422    return OK;
423}
424
425void PlaylistFetcher::onPause() {
426    cancelMonitorQueue();
427
428    mPacketSources.clear();
429    mStreamTypeMask = 0;
430}
431
432void PlaylistFetcher::onStop() {
433    cancelMonitorQueue();
434
435    for (size_t i = 0; i < mPacketSources.size(); ++i) {
436        mPacketSources.valueAt(i)->clear();
437    }
438
439    mPacketSources.clear();
440    mStreamTypeMask = 0;
441}
442
443void PlaylistFetcher::notifyError(status_t err) {
444    sp<AMessage> notify = mNotify->dup();
445    notify->setInt32("what", kWhatError);
446    notify->setInt32("err", err);
447    notify->post();
448}
449
450void PlaylistFetcher::queueDiscontinuity(
451        ATSParser::DiscontinuityType type, const sp<AMessage> &extra) {
452    for (size_t i = 0; i < mPacketSources.size(); ++i) {
453        mPacketSources.valueAt(i)->queueDiscontinuity(type, extra);
454    }
455}
456
457void PlaylistFetcher::onMonitorQueue() {
458    bool downloadMore = false;
459
460    status_t finalResult;
461    if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) {
462        sp<AnotherPacketSource> packetSource =
463            mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES);
464
465        int64_t bufferedDurationUs =
466                packetSource->getBufferedDurationUs(&finalResult);
467
468        downloadMore = (bufferedDurationUs < kMinBufferedDurationUs);
469        finalResult = OK;
470    } else {
471        bool first = true;
472        int64_t minBufferedDurationUs = 0ll;
473
474        for (size_t i = 0; i < mPacketSources.size(); ++i) {
475            if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0) {
476                continue;
477            }
478
479            int64_t bufferedDurationUs =
480                mPacketSources.valueAt(i)->getBufferedDurationUs(&finalResult);
481
482            if (first || bufferedDurationUs < minBufferedDurationUs) {
483                minBufferedDurationUs = bufferedDurationUs;
484                first = false;
485            }
486        }
487
488        downloadMore =
489            !first && (minBufferedDurationUs < kMinBufferedDurationUs);
490    }
491
492    if (finalResult == OK && downloadMore) {
493        onDownloadNext();
494    } else {
495        // Nothing to do yet, try again in a second.
496
497        sp<AMessage> msg = mNotify->dup();
498        msg->setInt32("what", kWhatTemporarilyDoneFetching);
499        msg->post();
500
501        postMonitorQueue(1000000ll);
502    }
503}
504
505void PlaylistFetcher::onDownloadNext() {
506    int64_t nowUs = ALooper::GetNowUs();
507
508    if (mLastPlaylistFetchTimeUs < 0ll
509            || (!mPlaylist->isComplete() && timeToRefreshPlaylist(nowUs))) {
510        bool unchanged;
511        sp<M3UParser> playlist = mSession->fetchPlaylist(
512                mURI.c_str(), mPlaylistHash, &unchanged);
513
514        if (playlist == NULL) {
515            if (unchanged) {
516                // We succeeded in fetching the playlist, but it was
517                // unchanged from the last time we tried.
518
519                if (mRefreshState != THIRD_UNCHANGED_RELOAD_ATTEMPT) {
520                    mRefreshState = (RefreshState)(mRefreshState + 1);
521                }
522            } else {
523                ALOGE("failed to load playlist at url '%s'", mURI.c_str());
524                notifyError(ERROR_IO);
525                return;
526            }
527        } else {
528            mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY;
529            mPlaylist = playlist;
530
531            if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
532                updateDuration();
533            }
534        }
535
536        mLastPlaylistFetchTimeUs = ALooper::GetNowUs();
537    }
538
539    int32_t firstSeqNumberInPlaylist;
540    if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
541                "media-sequence", &firstSeqNumberInPlaylist)) {
542        firstSeqNumberInPlaylist = 0;
543    }
544
545    bool seekDiscontinuity = false;
546    bool explicitDiscontinuity = false;
547
548    const int32_t lastSeqNumberInPlaylist =
549        firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1;
550
551    if (mSeqNumber < 0) {
552        CHECK_GE(mStartTimeUs, 0ll);
553
554        if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
555            mSeqNumber = getSeqNumberForTime(mStartTimeUs);
556        } else {
557            // If this is a live session, start 3 segments from the end.
558            mSeqNumber = lastSeqNumberInPlaylist - 3;
559            if (mSeqNumber < firstSeqNumberInPlaylist) {
560                mSeqNumber = firstSeqNumberInPlaylist;
561            }
562        }
563
564        mStartTimeUs = -1ll;
565    }
566
567    if (mSeqNumber < firstSeqNumberInPlaylist
568            || mSeqNumber > lastSeqNumberInPlaylist) {
569        if (!mPlaylist->isComplete() && mNumRetries < kMaxNumRetries) {
570            ++mNumRetries;
571
572            if (mSeqNumber > lastSeqNumberInPlaylist) {
573                mLastPlaylistFetchTimeUs = -1;
574                postMonitorQueue(3000000ll);
575                return;
576            }
577
578            // we've missed the boat, let's start from the lowest sequence
579            // number available and signal a discontinuity.
580
581            ALOGI("We've missed the boat, restarting playback.");
582            mSeqNumber = lastSeqNumberInPlaylist;
583            explicitDiscontinuity = true;
584
585            // fall through
586        } else {
587            ALOGE("Cannot find sequence number %d in playlist "
588                 "(contains %d - %d)",
589                 mSeqNumber, firstSeqNumberInPlaylist,
590                 firstSeqNumberInPlaylist + mPlaylist->size() - 1);
591
592            notifyError(ERROR_END_OF_STREAM);
593            return;
594        }
595    }
596
597    mNumRetries = 0;
598
599    AString uri;
600    sp<AMessage> itemMeta;
601    CHECK(mPlaylist->itemAt(
602                mSeqNumber - firstSeqNumberInPlaylist,
603                &uri,
604                &itemMeta));
605
606    int32_t val;
607    if (itemMeta->findInt32("discontinuity", &val) && val != 0) {
608        explicitDiscontinuity = true;
609    }
610
611    int64_t range_offset, range_length;
612    if (!itemMeta->findInt64("range-offset", &range_offset)
613            || !itemMeta->findInt64("range-length", &range_length)) {
614        range_offset = 0;
615        range_length = -1;
616    }
617
618    ALOGV("fetching segment %d from (%d .. %d)",
619          mSeqNumber, firstSeqNumberInPlaylist, lastSeqNumberInPlaylist);
620
621    ALOGV("fetching '%s'", uri.c_str());
622
623    sp<ABuffer> buffer;
624    status_t err = mSession->fetchFile(
625            uri.c_str(), &buffer, range_offset, range_length);
626
627    if (err != OK) {
628        ALOGE("failed to fetch .ts segment at url '%s'", uri.c_str());
629        notifyError(err);
630        return;
631    }
632
633    CHECK(buffer != NULL);
634
635    err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer);
636
637    if (err != OK) {
638        ALOGE("decryptBuffer failed w/ error %d", err);
639
640        notifyError(err);
641        return;
642    }
643
644    if (mStartup || seekDiscontinuity || explicitDiscontinuity) {
645        // Signal discontinuity.
646
647        if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
648            // If this was a live event this made no sense since
649            // we don't have access to all the segment before the current
650            // one.
651            mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber);
652        }
653
654        if (seekDiscontinuity || explicitDiscontinuity) {
655            ALOGI("queueing discontinuity (seek=%d, explicit=%d)",
656                 seekDiscontinuity, explicitDiscontinuity);
657
658            queueDiscontinuity(
659                    explicitDiscontinuity
660                        ? ATSParser::DISCONTINUITY_FORMATCHANGE
661                        : ATSParser::DISCONTINUITY_SEEK,
662                    NULL /* extra */);
663        }
664    }
665
666    err = extractAndQueueAccessUnits(buffer, itemMeta);
667
668    if (err != OK) {
669        notifyError(err);
670        return;
671    }
672
673    ++mSeqNumber;
674
675    postMonitorQueue();
676
677    mStartup = false;
678}
679
680int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const {
681    int32_t firstSeqNumberInPlaylist;
682    if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
683                "media-sequence", &firstSeqNumberInPlaylist)) {
684        firstSeqNumberInPlaylist = 0;
685    }
686
687    size_t index = 0;
688    int64_t segmentStartUs = 0;
689    while (index < mPlaylist->size()) {
690        sp<AMessage> itemMeta;
691        CHECK(mPlaylist->itemAt(
692                    index, NULL /* uri */, &itemMeta));
693
694        int64_t itemDurationUs;
695        CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
696
697        if (timeUs < segmentStartUs + itemDurationUs) {
698            break;
699        }
700
701        segmentStartUs += itemDurationUs;
702        ++index;
703    }
704
705    if (index >= mPlaylist->size()) {
706        index = mPlaylist->size() - 1;
707    }
708
709    return firstSeqNumberInPlaylist + index;
710}
711
712status_t PlaylistFetcher::extractAndQueueAccessUnits(
713        const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta) {
714    if (buffer->size() > 0 && buffer->data()[0] == 0x47) {
715        // Let's assume this is an MPEG2 transport stream.
716
717        if ((buffer->size() % 188) != 0) {
718            ALOGE("MPEG2 transport stream is not an even multiple of 188 "
719                  "bytes in length.");
720            return ERROR_MALFORMED;
721        }
722
723        if (mTSParser == NULL) {
724            mTSParser = new ATSParser;
725        }
726
727        if (mNextPTSTimeUs >= 0ll) {
728            sp<AMessage> extra = new AMessage;
729            extra->setInt64(IStreamListener::kKeyMediaTimeUs, mNextPTSTimeUs);
730
731            mTSParser->signalDiscontinuity(
732                    ATSParser::DISCONTINUITY_SEEK, extra);
733
734            mNextPTSTimeUs = -1ll;
735        }
736
737        size_t offset = 0;
738        while (offset < buffer->size()) {
739            status_t err = mTSParser->feedTSPacket(buffer->data() + offset, 188);
740
741            if (err != OK) {
742                return err;
743            }
744
745            offset += 188;
746        }
747
748        for (size_t i = mPacketSources.size(); i-- > 0;) {
749            sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
750
751            ATSParser::SourceType type;
752            switch (mPacketSources.keyAt(i)) {
753                case LiveSession::STREAMTYPE_VIDEO:
754                    type = ATSParser::VIDEO;
755                    break;
756
757                case LiveSession::STREAMTYPE_AUDIO:
758                    type = ATSParser::AUDIO;
759                    break;
760
761                case LiveSession::STREAMTYPE_SUBTITLES:
762                {
763                    ALOGE("MPEG2 Transport streams do not contain subtitles.");
764                    return ERROR_MALFORMED;
765                    break;
766                }
767
768                default:
769                    TRESPASS();
770            }
771
772            sp<AnotherPacketSource> source =
773                static_cast<AnotherPacketSource *>(
774                        mTSParser->getSource(type).get());
775
776            if (source == NULL) {
777                ALOGW("MPEG2 Transport stream does not contain %s data.",
778                      type == ATSParser::VIDEO ? "video" : "audio");
779
780                mStreamTypeMask &= ~mPacketSources.keyAt(i);
781                mPacketSources.removeItemsAt(i);
782                continue;
783            }
784
785            sp<ABuffer> accessUnit;
786            status_t finalResult;
787            while (source->hasBufferAvailable(&finalResult)
788                    && source->dequeueAccessUnit(&accessUnit) == OK) {
789                // Note that we do NOT dequeue any discontinuities.
790
791                packetSource->queueAccessUnit(accessUnit);
792            }
793
794            if (packetSource->getFormat() == NULL) {
795                packetSource->setFormat(source->getFormat());
796            }
797        }
798
799        return OK;
800    } else if (buffer->size() >= 7 && !memcmp("WEBVTT\n", buffer->data(), 7)) {
801        if (mStreamTypeMask != LiveSession::STREAMTYPE_SUBTITLES) {
802            ALOGE("This stream only contains subtitles.");
803            return ERROR_MALFORMED;
804        }
805
806        const sp<AnotherPacketSource> packetSource =
807            mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES);
808
809        int64_t durationUs;
810        CHECK(itemMeta->findInt64("durationUs", &durationUs));
811        buffer->meta()->setInt64("timeUs", getSegmentStartTimeUs(mSeqNumber));
812        buffer->meta()->setInt64("durationUs", durationUs);
813
814        packetSource->queueAccessUnit(buffer);
815        return OK;
816    }
817
818    if (mNextPTSTimeUs >= 0ll) {
819        mFirstPTSValid = false;
820        mAbsoluteTimeAnchorUs = mNextPTSTimeUs;
821        mNextPTSTimeUs = -1ll;
822    }
823
824    // This better be an ISO 13818-7 (AAC) or ISO 13818-1 (MPEG) audio
825    // stream prefixed by an ID3 tag.
826
827    bool firstID3Tag = true;
828    uint64_t PTS = 0;
829
830    for (;;) {
831        // Make sure to skip all ID3 tags preceding the audio data.
832        // At least one must be present to provide the PTS timestamp.
833
834        ID3 id3(buffer->data(), buffer->size(), true /* ignoreV1 */);
835        if (!id3.isValid()) {
836            if (firstID3Tag) {
837                ALOGE("Unable to parse ID3 tag.");
838                return ERROR_MALFORMED;
839            } else {
840                break;
841            }
842        }
843
844        if (firstID3Tag) {
845            bool found = false;
846
847            ID3::Iterator it(id3, "PRIV");
848            while (!it.done()) {
849                size_t length;
850                const uint8_t *data = it.getData(&length);
851
852                static const char *kMatchName =
853                    "com.apple.streaming.transportStreamTimestamp";
854                static const size_t kMatchNameLen = strlen(kMatchName);
855
856                if (length == kMatchNameLen + 1 + 8
857                        && !strncmp((const char *)data, kMatchName, kMatchNameLen)) {
858                    found = true;
859                    PTS = U64_AT(&data[kMatchNameLen + 1]);
860                }
861
862                it.next();
863            }
864
865            if (!found) {
866                ALOGE("Unable to extract transportStreamTimestamp from ID3 tag.");
867                return ERROR_MALFORMED;
868            }
869        }
870
871        // skip the ID3 tag
872        buffer->setRange(
873                buffer->offset() + id3.rawSize(), buffer->size() - id3.rawSize());
874
875        firstID3Tag = false;
876    }
877
878    if (!mFirstPTSValid) {
879        mFirstPTSValid = true;
880        mFirstPTS = PTS;
881    }
882    PTS -= mFirstPTS;
883
884    int64_t timeUs = (PTS * 100ll) / 9ll + mAbsoluteTimeAnchorUs;
885
886    if (mStreamTypeMask != LiveSession::STREAMTYPE_AUDIO) {
887        ALOGW("This stream only contains audio data!");
888
889        mStreamTypeMask &= LiveSession::STREAMTYPE_AUDIO;
890
891        if (mStreamTypeMask == 0) {
892            return OK;
893        }
894    }
895
896    sp<AnotherPacketSource> packetSource =
897        mPacketSources.valueFor(LiveSession::STREAMTYPE_AUDIO);
898
899    if (packetSource->getFormat() == NULL && buffer->size() >= 7) {
900        ABitReader bits(buffer->data(), buffer->size());
901
902        // adts_fixed_header
903
904        CHECK_EQ(bits.getBits(12), 0xfffu);
905        bits.skipBits(3);  // ID, layer
906        bool protection_absent = bits.getBits(1) != 0;
907
908        unsigned profile = bits.getBits(2);
909        CHECK_NE(profile, 3u);
910        unsigned sampling_freq_index = bits.getBits(4);
911        bits.getBits(1);  // private_bit
912        unsigned channel_configuration = bits.getBits(3);
913        CHECK_NE(channel_configuration, 0u);
914        bits.skipBits(2);  // original_copy, home
915
916        sp<MetaData> meta = MakeAACCodecSpecificData(
917                profile, sampling_freq_index, channel_configuration);
918
919        meta->setInt32(kKeyIsADTS, true);
920
921        packetSource->setFormat(meta);
922    }
923
924    int64_t numSamples = 0ll;
925    int32_t sampleRate;
926    CHECK(packetSource->getFormat()->findInt32(kKeySampleRate, &sampleRate));
927
928    size_t offset = 0;
929    while (offset < buffer->size()) {
930        const uint8_t *adtsHeader = buffer->data() + offset;
931        CHECK_LT(offset + 5, buffer->size());
932
933        unsigned aac_frame_length =
934            ((adtsHeader[3] & 3) << 11)
935            | (adtsHeader[4] << 3)
936            | (adtsHeader[5] >> 5);
937
938        CHECK_LE(offset + aac_frame_length, buffer->size());
939
940        sp<ABuffer> unit = new ABuffer(aac_frame_length);
941        memcpy(unit->data(), adtsHeader, aac_frame_length);
942
943        int64_t unitTimeUs = timeUs + numSamples * 1000000ll / sampleRate;
944        unit->meta()->setInt64("timeUs", unitTimeUs);
945
946        // Each AAC frame encodes 1024 samples.
947        numSamples += 1024;
948
949        packetSource->queueAccessUnit(unit);
950
951        offset += aac_frame_length;
952    }
953
954    return OK;
955}
956
957void PlaylistFetcher::updateDuration() {
958    int64_t durationUs = 0ll;
959    for (size_t index = 0; index < mPlaylist->size(); ++index) {
960        sp<AMessage> itemMeta;
961        CHECK(mPlaylist->itemAt(
962                    index, NULL /* uri */, &itemMeta));
963
964        int64_t itemDurationUs;
965        CHECK(itemMeta->findInt64("durationUs", &itemDurationUs));
966
967        durationUs += itemDurationUs;
968    }
969
970    sp<AMessage> msg = mNotify->dup();
971    msg->setInt32("what", kWhatDurationUpdate);
972    msg->setInt64("durationUs", durationUs);
973    msg->post();
974}
975
976}  // namespace android
977