114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber/*
214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * Copyright (C) 2012 The Android Open Source Project
314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *
414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * you may not use this file except in compliance with the License.
614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * You may obtain a copy of the License at
714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *
814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber *
1014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * Unless required by applicable law or agreed to in writing, software
1114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * See the License for the specific language governing permissions and
1414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber * limitations under the License.
1514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber */
1614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
1714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#ifndef PLAYLIST_FETCHER_H_
1814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
1914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#define PLAYLIST_FETCHER_H_
2014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
2114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include <media/stagefright/foundation/AHandler.h>
2214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
2314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include "mpeg2ts/ATSParser.h"
2414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#include "LiveSession.h"
2514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
2614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Hubernamespace android {
2714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
2814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct ABuffer;
2914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct AnotherPacketSource;
3014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct DataSource;
3114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct HTTPBase;
3214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct LiveDataSource;
3314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct M3UParser;
3414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct String8;
3514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
3614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberstruct PlaylistFetcher : public AHandler {
3714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    enum {
3814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatStarted,
3914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatPaused,
4014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatStopped,
4114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatError,
4214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatDurationUpdate,
4314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatTemporarilyDoneFetching,
4414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatPrepared,
4514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatPreparationFailed,
46777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih        kWhatStartedAt,
4714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    };
4814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    PlaylistFetcher(
5014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            const sp<AMessage> &notify,
5114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            const sp<LiveSession> &session,
5214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            const char *uri);
5314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
5414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<DataSource> getDataSource();
5514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
5614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void startAsync(
5714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            const sp<AnotherPacketSource> &audioSource,
5814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            const sp<AnotherPacketSource> &videoSource,
5914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            const sp<AnotherPacketSource> &subtitleSource,
60777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih            int64_t startTimeUs = -1ll,
61777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih            int64_t minStartTimeUs = 0ll /* start after this timestamp */,
62777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih            int32_t startSeqNumberHint = -1 /* try starting at this sequence number */);
6314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
6414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void pauseAsync();
6514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
66ceeabe15f4e7bc73efdfcafed917202de9d515cbRobert Shih    void stopAsync(bool selfTriggered = false);
6714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
68777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    void resumeUntilAsync(const sp<AMessage> &params);
69777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih
7014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberprotected:
7114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    virtual ~PlaylistFetcher();
7214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
7314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
7414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huberprivate:
7514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    enum {
7614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kMaxNumRetries         = 5,
7714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    };
7814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
7914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    enum {
8014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatStart          = 'strt',
8114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatPause          = 'paus',
8214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatStop           = 'stop',
8314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        kWhatMonitorQueue   = 'moni',
84777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih        kWhatResumeUntil    = 'rsme',
85777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih        kWhatDownloadNext   = 'dlnx',
8614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    };
8714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
8814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    static const int64_t kMinBufferedDurationUs;
896708a45ba1b5eacf583d5e80b2075b68940fe0abLajos Molnar    static const int64_t kMaxMonitorDelayUs;
9043ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih    static const int32_t kDownloadBlockSize;
91777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    static const int32_t kNumSkipFrames;
9214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
9343ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih    static bool bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer);
9443ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih
95777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    // notifications to mSession
9614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<AMessage> mNotify;
97777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    sp<AMessage> mStartTimeUsNotify;
98777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih
9914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<LiveSession> mSession;
10014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    AString mURI;
10114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
10214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint32_t mStreamTypeMask;
10314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t mStartTimeUs;
104777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    int64_t mMinStartTimeUs; // start fetching no earlier than this value
105777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    sp<AMessage> mStopParams; // message containing the latest timestamps we should fetch.
10614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
10714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    KeyedVector<LiveSession::StreamType, sp<AnotherPacketSource> >
10814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        mPacketSources;
10914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
11014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    KeyedVector<AString, sp<ABuffer> > mAESKeyForURI;
11114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
11214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t mLastPlaylistFetchTimeUs;
11314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<M3UParser> mPlaylist;
11414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int32_t mSeqNumber;
11514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int32_t mNumRetries;
11614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    bool mStartup;
1176708a45ba1b5eacf583d5e80b2075b68940fe0abLajos Molnar    bool mPrepared;
11814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t mNextPTSTimeUs;
11914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
12014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int32_t mMonitorQueueGeneration;
12114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
12214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    enum RefreshState {
12314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        INITIAL_MINIMUM_RELOAD_DELAY,
12414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        FIRST_UNCHANGED_RELOAD_ATTEMPT,
12514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        SECOND_UNCHANGED_RELOAD_ATTEMPT,
12614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber        THIRD_UNCHANGED_RELOAD_ATTEMPT
12714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    };
12814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    RefreshState mRefreshState;
12914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
13014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint8_t mPlaylistHash[16];
13114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
13214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    sp<ATSParser> mTSParser;
13314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
13414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    bool mFirstPTSValid;
13514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    uint64_t mFirstPTS;
13614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t mAbsoluteTimeAnchorUs;
13714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
1382cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // Stores the initialization vector to decrypt the next block of cipher text, which can
1392cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // either be derived from the sequence number, read from the manifest, or copied from
1402cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // the last block of cipher text (cipher-block chaining).
1412cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    unsigned char mAESInitVec[16];
1422cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih
1432cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // Set first to true if decrypting the first segment of a playlist segment. When
1442cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // first is true, reset the initialization vector based on the available
1452cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // information in the manifest; otherwise, use the initialization vector as
1462cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // updated by the last call to AES_cbc_encrypt.
1472cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    //
1482cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // For the input to decrypt correctly, decryptBuffer must be called on
1492cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // consecutive byte ranges on block boundaries, e.g. 0..15, 16..47, 48..63,
1502cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    // and so on.
15114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    status_t decryptBuffer(
1522cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih            size_t playlistIndex, const sp<ABuffer> &buffer,
1532cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih            bool first = true);
1542cd94583868b775a548233a4f7cd1d988fc6344fRobert Shih    status_t checkDecryptPadding(const sp<ABuffer> &buffer);
15514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
1566708a45ba1b5eacf583d5e80b2075b68940fe0abLajos Molnar    void postMonitorQueue(int64_t delayUs = 0, int64_t minDelayUs = 0);
15714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void cancelMonitorQueue();
15814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
1596708a45ba1b5eacf583d5e80b2075b68940fe0abLajos Molnar    int64_t delayUsToRefreshPlaylist() const;
1606708a45ba1b5eacf583d5e80b2075b68940fe0abLajos Molnar    status_t refreshPlaylist();
16114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
16214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // Returns the media time in us of the segment specified by seqNumber.
16314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    // This is computed by summing the durations of all segments before it.
16414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int64_t getSegmentStartTimeUs(int32_t seqNumber) const;
16514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
16614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    status_t onStart(const sp<AMessage> &msg);
16714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void onPause();
168ceeabe15f4e7bc73efdfcafed917202de9d515cbRobert Shih    void onStop(const sp<AMessage> &msg);
16914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void onMonitorQueue();
17014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void onDownloadNext();
17114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
172777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    // Resume a fetcher to continue until the stopping point stored in msg.
173777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    status_t onResumeUntil(const sp<AMessage> &msg);
174777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih
17543ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih    status_t extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer);
17643ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih
177dcb89b3b505522efde173c105a851c412f947178Chong Zhang    status_t extractAndQueueAccessUnits(
178dcb89b3b505522efde173c105a851c412f947178Chong Zhang            const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta);
17914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
18014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void notifyError(status_t err);
18114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
18214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void queueDiscontinuity(
18314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber            ATSParser::DiscontinuityType type, const sp<AMessage> &extra);
18414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
18514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    int32_t getSeqNumberForTime(int64_t timeUs) const;
18614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
18714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    void updateDuration();
18814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
189777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    // Before resuming a fetcher in onResume, check the remaining duration is longer than that
190777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    // returned by resumeThreshold.
191777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih    int64_t resumeThreshold(const sp<AMessage> &msg);
192777ee5ed736c8f6c3f7d196ea022f7432bfd23e1Robert Shih
19314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(PlaylistFetcher);
19414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber};
19514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
19614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber}  // namespace android
19714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
19814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber#endif  // PLAYLIST_FETCHER_H_
19914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
200