ATSParser.cpp revision d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3
1cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber/*
2cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
4cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * you may not use this file except in compliance with the License.
6cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * You may obtain a copy of the License at
7cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
8cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
10cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * See the License for the specific language governing permissions and
14cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * limitations under the License.
15cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber */
16cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0
186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "ATSParser"
196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h>
20cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ATSParser.h"
21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "AnotherPacketSource.h"
223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang#include "CasManager.h"
236a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include "ESQueue.h"
24cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
25d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang#include <android/hardware/cas/native/1.0/IDescrambler.h>
26d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang#include <cutils/native_handle.h>
2785f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include <media/stagefright/foundation/ABitReader.h>
28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/ADebug.h>
30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/AMessage.h>
31607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang#include <media/stagefright/foundation/ByteUtils.h>
32d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang#include <media/stagefright/foundation/avc_utils.h>
33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h>
35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h>
36cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h>
3732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber#include <media/IStreamSource.h>
38cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/KeyedVector.h>
399bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang#include <utils/Vector.h>
40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
41b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross#include <inttypes.h>
42b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross
43cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android {
44d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_handle;
45d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_memory;
46d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_string;
47d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_vec;
48d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing namespace hardware::cas::V1_0;
49d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing namespace hardware::cas::native::V1_0;
50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
516e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber// I want the expression "y" evaluated even if verbose logging is off.
526e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define MY_LOGV(x, y) \
533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    do { unsigned tmp = y; ALOGV(x, tmp); } while (0)
546e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatic const size_t kTSPacketSize = 188;
56cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
57cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct ATSParser::Program : public RefBase {
58d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID,
59d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            int64_t lastRecoveredPTS);
60cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    bool parsePSISection(
628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            unsigned pid, ABitReader *br, status_t *err);
638dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
64540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Pass to appropriate stream according to pid, and set event if it's a PES
65540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // with a sync frame.
66540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Note that the method itself does not touch event.
67cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool parsePID(
6887f2a558dd12043631e12c361abef301bf603140Andreas Huber            unsigned pid, unsigned continuity_counter,
6987f2a558dd12043631e12c361abef301bf603140Andreas Huber            unsigned payload_unit_start_indicator,
703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned transport_scrambling_control,
713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned random_access_indicator,
72540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            ABitReader *br, status_t *err, SyncEvent *event);
73cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
7432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    void signalDiscontinuity(
7532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            DiscontinuityType type, const sp<AMessage> &extra);
7632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void signalEOS(status_t finalResult);
782a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
79cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MediaSource> getSource(SourceType type);
80bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    bool hasSource(SourceType type) const;
81cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
82bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    int64_t convertPTSToTimestamp(uint64_t PTS);
83bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
8443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    bool PTSTimeDeltaEstablished() const {
8543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        return mFirstPTSValid;
8643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
8743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
88386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned number() const { return mProgramNumber; }
89386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
90386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    void updateProgramMapPID(unsigned programMapPID) {
91386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        mProgramMapPID = programMapPID;
92386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
93386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
948dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    unsigned programMapPID() const {
958dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        return mProgramMapPID;
968dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
978dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
9887f2a558dd12043631e12c361abef301bf603140Andreas Huber    uint32_t parserFlags() const {
9987f2a558dd12043631e12c361abef301bf603140Andreas Huber        return mParser->mFlags;
10087f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
10187f2a558dd12043631e12c361abef301bf603140Andreas Huber
1023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<CasManager> casManager() const {
1033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return mParser->mCasManager;
1043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
1053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
10682e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    uint64_t firstPTS() const {
10782e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        return mFirstPTS;
10882e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    }
10982e147049625a4cfdcb228a1de7efda594d446c9Robert Shih
1103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    void updateCasSessions();
1113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1123a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    void signalNewSampleAesKey(const sp<AMessage> &keyItem);
1133a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate:
1159bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    struct StreamInfo {
1169bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        unsigned mType;
1179bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        unsigned mPID;
1183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t mCASystemId;
1199bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    };
1209bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ATSParser *mParser;
122386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned mProgramNumber;
123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned mProgramMapPID;
124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    KeyedVector<unsigned, sp<Stream> > mStreams;
125bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    bool mFirstPTSValid;
126bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    uint64_t mFirstPTS;
127799c9682b3776a55d234396aee4a302437150c26Chong Zhang    int64_t mLastRecoveredPTS;
1283a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    sp<AMessage> mSampleAesKeyItem;
129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
13006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    status_t parseProgramMap(ABitReader *br);
131799c9682b3776a55d234396aee4a302437150c26Chong Zhang    int64_t recoverPTS(uint64_t PTS_33bit);
1323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool findCADescriptor(
1333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ABitReader *br, unsigned infoLength, CADescriptor *caDescriptor);
1349bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    bool switchPIDs(const Vector<StreamInfo> &infos);
135cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
136cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Program);
137cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
138cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
139cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct ATSParser::Stream : public RefBase {
14087f2a558dd12043631e12c361abef301bf603140Andreas Huber    Stream(Program *program,
14187f2a558dd12043631e12c361abef301bf603140Andreas Huber           unsigned elementaryPID,
14287f2a558dd12043631e12c361abef301bf603140Andreas Huber           unsigned streamType,
1433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang           unsigned PCR_PID,
1443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang           int32_t CA_system_ID);
145cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
146bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    unsigned type() const { return mStreamType; }
147bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    unsigned pid() const { return mElementaryPID; }
148bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    void setPID(unsigned pid) { mElementaryPID = pid; }
149bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
150bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang    void setCasInfo(
151bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            int32_t systemId,
1523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            const sp<IDescrambler> &descrambler,
1533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            const std::vector<uint8_t> &sessionId);
1543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
155540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Parse the payload and set event when PES with a sync frame is detected.
1569558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    // This method knows when a PES starts; so record mPesStartOffsets in that
157540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // case.
1585403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    status_t parse(
15987f2a558dd12043631e12c361abef301bf603140Andreas Huber            unsigned continuity_counter,
160cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned payload_unit_start_indicator,
1613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned transport_scrambling_control,
1623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned random_access_indicator,
163540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            ABitReader *br,
164540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            SyncEvent *event);
165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
16632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    void signalDiscontinuity(
16732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            DiscontinuityType type, const sp<AMessage> &extra);
16832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void signalEOS(status_t finalResult);
1702a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
17182e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    SourceType getSourceType();
172cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MediaSource> getSource(SourceType type);
173cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
174bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    bool isAudio() const;
175bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    bool isVideo() const;
1760852843d304006e3ab333081fddda13b07193de8Robert Shih    bool isMeta() const;
177bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
1783a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    void signalNewSampleAesKey(const sp<AMessage> &keyItem);
1793a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprotected:
181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual ~Stream();
182cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
183cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate:
1843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    struct SubSampleInfo {
1853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        size_t subSampleSize;
1863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned transport_scrambling_mode;
1873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned random_access_indicator;
1883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    };
189bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    Program *mProgram;
190cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned mElementaryPID;
191cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned mStreamType;
19287f2a558dd12043631e12c361abef301bf603140Andreas Huber    unsigned mPCR_PID;
19387f2a558dd12043631e12c361abef301bf603140Andreas Huber    int32_t mExpectedContinuityCounter;
194cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
195cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<ABuffer> mBuffer;
196cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<AnotherPacketSource> mSource;
197cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool mPayloadStarted;
198be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    bool mEOSReached;
199cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    uint64_t mPrevPTS;
2019558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    List<off64_t> mPesStartOffsets;
20290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
203386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    ElementaryStreamQueue *mQueue;
2046a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
2053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool mScrambled;
2063a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    bool mSampleEncrypted;
2073a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    sp<AMessage> mSampleAesKeyItem;
2083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<IMemory> mMem;
2093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<MemoryDealer> mDealer;
210d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
2113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<ABuffer> mDescrambledBuffer;
2123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    List<SubSampleInfo> mSubSamples;
2133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<IDescrambler> mDescrambler;
2143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
215540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Flush accumulated payload if necessary --- i.e. at EOS or at the start of
216540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // another payload. event is set if the flushed payload is PES with a sync
217540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // frame.
218540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    status_t flush(SyncEvent *event);
2193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // Flush accumulated payload for scrambled streams if necessary --- i.e. at
2213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // EOS or at the start of another payload. event is set if the flushed
2223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // payload is PES with a sync frame.
2233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t flushScrambled(SyncEvent *event);
2243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // Check if a PES packet is scrambled at PES level.
2263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    uint32_t getPesScramblingControl(ABitReader *br, int32_t *pesOffset);
2273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
228540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Strip and parse PES headers and pass remaining payload into onPayload
229540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // with parsed metadata. event is set if the PES contains a sync frame.
230540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    status_t parsePES(ABitReader *br, SyncEvent *event);
231540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
232540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Feed the payload into mQueue and if a packet is identified, queue it
233540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // into mSource. If the packet is a sync frame. set event with start offset
234540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // and timestamp of the packet.
235cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    void onPayloadData(
236cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
2373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned PES_scrambling_control,
2383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            const uint8_t *data, size_t size,
2393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            int32_t payloadOffset, SyncEvent *event);
2403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // Ensure internal buffers can hold specified size, and will re-allocate
2423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // as needed.
243d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    bool ensureBufferCapacity(size_t size);
24482f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
245cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Stream);
246cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
247cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2488dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberstruct ATSParser::PSISection : public RefBase {
2498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    PSISection();
2508dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2518dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    status_t append(const void *data, size_t size);
2529ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    void setSkipBytes(uint8_t skip);
2538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    void clear();
2548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2558dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    bool isComplete() const;
2568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    bool isEmpty() const;
2579ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    bool isCRCOkay() const;
2588dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    const uint8_t *data() const;
2608dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    size_t size() const;
2618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberprotected:
2638dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    virtual ~PSISection();
2648dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2658dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberprivate:
2668dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    sp<ABuffer> mBuffer;
2679ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    uint8_t mSkipBytes;
2689ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    static uint32_t CRC_TABLE[];
2698dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2708dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(PSISection);
2718dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber};
2728dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
273540006666b4191cd78391378f1c66c21bcf0c4cdWonsik KimATSParser::SyncEvent::SyncEvent(off64_t offset)
2749558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    : mHasReturnedData(false), mOffset(offset), mTimeUs(0) {}
275540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
276540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimvoid ATSParser::SyncEvent::init(off64_t offset, const sp<MediaSource> &source,
27782e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        int64_t timeUs, SourceType type) {
2789558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    mHasReturnedData = true;
279540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    mOffset = offset;
280540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    mMediaSource = source;
281540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    mTimeUs = timeUs;
28282e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    mType = type;
283540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim}
284540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
2859558f6dd733dc450270f38b9a139d384d273ce0aWei Jiavoid ATSParser::SyncEvent::reset() {
2869558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    mHasReturnedData = false;
2879558f6dd733dc450270f38b9a139d384d273ce0aWei Jia}
288cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
289cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
290386d609dc513e838c7e7c4c46c604493ccd560beAndreas HuberATSParser::Program::Program(
291d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        ATSParser *parser, unsigned programNumber, unsigned programMapPID,
292d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        int64_t lastRecoveredPTS)
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : mParser(parser),
294386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber      mProgramNumber(programNumber),
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mProgramMapPID(programMapPID),
296bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber      mFirstPTSValid(false),
297799c9682b3776a55d234396aee4a302437150c26Chong Zhang      mFirstPTS(0),
298d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang      mLastRecoveredPTS(lastRecoveredPTS) {
2993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("new program number %u", programNumber);
300cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
301cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
3028dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::Program::parsePSISection(
3038dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        unsigned pid, ABitReader *br, status_t *err) {
30406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    *err = OK;
30506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
3068dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (pid != mProgramMapPID) {
3078dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        return false;
3088dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
309cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
3108dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    *err = parseProgramMap(br);
31106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
3128dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return true;
3138dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
3148dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
3158dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::Program::parsePID(
31687f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned pid, unsigned continuity_counter,
31787f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned payload_unit_start_indicator,
3183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned transport_scrambling_control,
3193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned random_access_indicator,
320540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        ABitReader *br, status_t *err, SyncEvent *event) {
3218dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    *err = OK;
322cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
323cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    ssize_t index = mStreams.indexOfKey(pid);
324cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (index < 0) {
325cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return false;
326cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
327cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
3285403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    *err = mStreams.editValueAt(index)->parse(
3293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            continuity_counter,
3303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            payload_unit_start_indicator,
3313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            transport_scrambling_control,
3323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            random_access_indicator,
3333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            br, event);
334cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
335cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return true;
336cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
337cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
33832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::Program::signalDiscontinuity(
33932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        DiscontinuityType type, const sp<AMessage> &extra) {
340b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    int64_t mediaTimeUs;
341b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    if ((type & DISCONTINUITY_TIME)
342b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            && extra != NULL
343b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            && extra->findInt64(
344b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber                IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) {
345b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        mFirstPTSValid = false;
346b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    }
347b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
3482a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    for (size_t i = 0; i < mStreams.size(); ++i) {
34932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        mStreams.editValueAt(i)->signalDiscontinuity(type, extra);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::Program::signalEOS(status_t finalResult) {
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mStreams.size(); ++i) {
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mStreams.editValueAt(i)->signalEOS(finalResult);
3562a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    }
3572a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber}
3582a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
3599bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhangbool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) {
3609bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    bool success = false;
3619bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3629bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    if (mStreams.size() == infos.size()) {
3639bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // build type->PIDs map for old and new mapping
3649bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        size_t i;
3659bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs;
3669bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        for (i = 0; i < mStreams.size(); ++i) {
3679bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type());
3689bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            if (index < 0) {
3699bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>());
3709bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
3719bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid());
3729bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
3739bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        for (i = 0; i < infos.size(); ++i) {
3749bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            ssize_t index = newType2PIDs.indexOfKey(infos[i].mType);
3759bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            if (index < 0) {
3769bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                newType2PIDs.add(infos[i].mType, Vector<int32_t>());
3779bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
3789bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID);
3799bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
3809bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3819bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // we can recover if the number of streams for each type hasn't changed
3829bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        if (oldType2PIDs.size() == newType2PIDs.size()) {
3839bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            success = true;
3849bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            for (i = 0; i < oldType2PIDs.size(); ++i) {
3859bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // KeyedVector is sorted, we just compare key and size of each index
3869bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i)
3879bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                        || oldType2PIDs[i].size() != newType2PIDs[i].size()) {
3889bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     success = false;
3899bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     break;
3909bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                }
3919bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
3929bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
3939bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3949bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        if (success) {
3959bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            // save current streams to temp
3969bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            KeyedVector<int32_t, sp<Stream> > temp;
3979bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            for (i = 0; i < mStreams.size(); ++i) {
3989bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                 temp.add(mStreams.keyAt(i), mStreams.editValueAt(i));
3999bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
4009bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4019bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            mStreams.clear();
4029bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            for (i = 0; i < temp.size(); ++i) {
4039bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // The two checks below shouldn't happen,
4049bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // we already checked above the stream count matches
4059bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
406e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (index < 0) {
407e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return false;
408e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
4099bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
410e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (newPIDs.isEmpty()) {
411e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return false;
412e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
4139bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4149bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // get the next PID for temp[i]->type() in the new PID map
4159bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                Vector<int32_t>::iterator it = newPIDs.begin();
4169bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4179bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // change the PID of the stream, and add it back
4189bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                temp.editValueAt(i)->setPID(*it);
4199bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                mStreams.add(temp[i]->pid(), temp.editValueAt(i));
4209bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4219bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // removed the used PID
4229bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                newPIDs.erase(it);
4239bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
4249bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
4259bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    }
4269bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    return success;
4279bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang}
428bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
4293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangbool ATSParser::Program::findCADescriptor(
4303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader *br, unsigned infoLength,
4313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ATSParser::CADescriptor *caDescriptor) {
4323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool found = false;
4333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    while (infoLength > 2) {
4343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned descriptor_tag = br->getBits(8);
4353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("      tag = 0x%02x", descriptor_tag);
4363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned descriptor_length = br->getBits(8);
4383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("      len = %u", descriptor_length);
4393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        infoLength -= 2;
4413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (descriptor_length > infoLength) {
4423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            break;
4433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
4443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (descriptor_tag == 9 && descriptor_length >= 4) {
4453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            found = true;
4463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            caDescriptor->mSystemID = br->getBits(16);
4473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            caDescriptor->mPID = br->getBits(16) & 0x1fff;
4483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            infoLength -= 4;
4493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            caDescriptor->mPrivateData.assign(
4503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    br->data(), br->data() + descriptor_length - 4);
4513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            break;
4523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        } else {
4533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            infoLength -= descriptor_length;
4543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            br->skipBits(descriptor_length * 8);
4553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
4563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
4573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    br->skipBits(infoLength * 8);
4583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return found;
4593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
4603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
46106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huberstatus_t ATSParser::Program::parseProgramMap(ABitReader *br) {
462cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned table_id = br->getBits(8);
4633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  table_id = %u", table_id);
4646456ae745e919085c5024f784aaa2703f9695f98David Yeh    if (table_id != 0x02u) {
4656456ae745e919085c5024f784aaa2703f9695f98David Yeh        ALOGE("PMT data error!");
4666456ae745e919085c5024f784aaa2703f9695f98David Yeh        return ERROR_MALFORMED;
4676456ae745e919085c5024f784aaa2703f9695f98David Yeh    }
4686e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    unsigned section_syntax_indicator = br->getBits(1);
4693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  section_syntax_indicator = %u", section_syntax_indicator);
4706456ae745e919085c5024f784aaa2703f9695f98David Yeh    if (section_syntax_indicator != 1u) {
4716456ae745e919085c5024f784aaa2703f9695f98David Yeh        ALOGE("PMT data error!");
4726456ae745e919085c5024f784aaa2703f9695f98David Yeh        return ERROR_MALFORMED;
4736456ae745e919085c5024f784aaa2703f9695f98David Yeh    }
474cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
475e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    br->skipBits(1);  // '0'
4766e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(2));
477cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
478cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned section_length = br->getBits(12);
4793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  section_length = %u", section_length);
480cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
4816e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  program_number = %u", br->getBits(16));
4826e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(2));
4836e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  version_number = %u", br->getBits(5));
4846e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
4856e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  section_number = %u", br->getBits(8));
4866e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  last_section_number = %u", br->getBits(8));
4876e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(3));
48887f2a558dd12043631e12c361abef301bf603140Andreas Huber
48987f2a558dd12043631e12c361abef301bf603140Andreas Huber    unsigned PCR_PID = br->getBits(13);
49087f2a558dd12043631e12c361abef301bf603140Andreas Huber    ALOGV("  PCR_PID = 0x%04x", PCR_PID);
49187f2a558dd12043631e12c361abef301bf603140Andreas Huber
4926e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(4));
493cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
494cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned program_info_length = br->getBits(12);
4953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  program_info_length = %u", program_info_length);
496cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
4973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // descriptors
4983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    CADescriptor programCA;
4993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool hasProgramCA = findCADescriptor(br, program_info_length, &programCA);
5003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (hasProgramCA && !mParser->mCasManager->addProgram(
5013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mProgramNumber, programCA)) {
5023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return ERROR_MALFORMED;
5033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
504cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
505bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    Vector<StreamInfo> infos;
506bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
507cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    // infoBytesRemaining is the number of bytes that make up the
508cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    // variable length section of ES_infos. It does not include the
509cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    // final CRC.
510cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    size_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
511cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
512e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    while (infoBytesRemaining >= 5) {
513cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
514cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned streamType = br->getBits(8);
5153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("    stream_type = 0x%02x", streamType);
516cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
5176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("    reserved = %u", br->getBits(3));
518cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
519cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned elementaryPID = br->getBits(13);
5203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("    elementary_PID = 0x%04x", elementaryPID);
521cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
5226e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("    reserved = %u", br->getBits(4));
523cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
524cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned ES_info_length = br->getBits(12);
5253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("    ES_info_length = %u", ES_info_length);
526cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
5273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        CADescriptor streamCA;
5283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        bool hasStreamCA = findCADescriptor(br, ES_info_length, &streamCA);
5293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (hasStreamCA && !mParser->mCasManager->addStream(
5303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mProgramNumber, elementaryPID, streamCA)) {
5313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return ERROR_MALFORMED;
532cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
533bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        StreamInfo info;
534bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        info.mType = streamType;
535bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        info.mPID = elementaryPID;
5363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        info.mCASystemId = hasProgramCA ? programCA.mSystemID :
5373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                           hasStreamCA ? streamCA.mSystemID  : -1;
538bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        infos.push(info);
539cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
540cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        infoBytesRemaining -= 5 + ES_info_length;
541cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
542cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
543e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (infoBytesRemaining != 0) {
544e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGW("Section data remains unconsumed");
545e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
5466e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
547bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
548bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    bool PIDsChanged = false;
549bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    for (size_t i = 0; i < infos.size(); ++i) {
550bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        StreamInfo &info = infos.editItemAt(i);
551bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
552bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        ssize_t index = mStreams.indexOfKey(info.mPID);
553bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
554bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
555df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("uh oh. stream PIDs have changed.");
556bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber            PIDsChanged = true;
557bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber            break;
558bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        }
559bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    }
560bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
561bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    if (PIDsChanged) {
56206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber#if 0
563df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("before:");
56406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        for (size_t i = 0; i < mStreams.size(); ++i) {
56506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            sp<Stream> stream = mStreams.editValueAt(i);
56606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
567df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type());
56806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        }
56906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
570df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("after:");
57106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        for (size_t i = 0; i < infos.size(); ++i) {
57206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            StreamInfo &info = infos.editItemAt(i);
57306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
574df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType);
57506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        }
57606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber#endif
57706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
5789bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // we can recover if number of streams for each type remain the same
5799bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        bool success = switchPIDs(infos);
58006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
58106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        if (!success) {
582df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("Stream PIDs changed and we cannot recover.");
58306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            return ERROR_MALFORMED;
58406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        }
585bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    }
586bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
5873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool isAddingScrambledStream = false;
588bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    for (size_t i = 0; i < infos.size(); ++i) {
589bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        StreamInfo &info = infos.editItemAt(i);
590bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
5913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mParser->mCasManager->isCAPid(info.mPID)) {
5923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // skip CA streams (EMM/ECM)
5933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            continue;
5943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
595bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        ssize_t index = mStreams.indexOfKey(info.mPID);
596bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
597bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        if (index < 0) {
59887f2a558dd12043631e12c361abef301bf603140Andreas Huber            sp<Stream> stream = new Stream(
5993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    this, info.mPID, info.mType, PCR_PID, info.mCASystemId);
60087f2a558dd12043631e12c361abef301bf603140Andreas Huber
6013a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            if (mSampleAesKeyItem != NULL) {
6023a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                stream->signalNewSampleAesKey(mSampleAesKeyItem);
6033a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            }
6043a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
6053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            isAddingScrambledStream |= info.mCASystemId >= 0;
606bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber            mStreams.add(info.mPID, stream);
607bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        }
608bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    }
60906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
6103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (isAddingScrambledStream) {
6113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGI("Receiving scrambled streams without descrambler!");
6123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
6133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
61406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    return OK;
615cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
616cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
617799c9682b3776a55d234396aee4a302437150c26Chong Zhangint64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
618799c9682b3776a55d234396aee4a302437150c26Chong Zhang    // We only have the lower 33-bit of the PTS. It could overflow within a
619799c9682b3776a55d234396aee4a302437150c26Chong Zhang    // reasonable amount of time. To handle the wrap-around, use fancy math
620799c9682b3776a55d234396aee4a302437150c26Chong Zhang    // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
621799c9682b3776a55d234396aee4a302437150c26Chong Zhang    // of the latest recovered PTS.
6229bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    if (mLastRecoveredPTS < 0ll) {
6239bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // Use the original 33bit number for 1st frame, the reason is that
6249bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // if 1st frame wraps to negative that's far away from 0, we could
6259bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // never start. Only start wrapping around from 2nd frame.
6269bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
6279bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    } else {
6289bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        mLastRecoveredPTS = static_cast<int64_t>(
6293728ba367f1e23e652c5539d9488aa0d0d4ec9d7Chad Brubaker                ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000ll)
6309bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                & 0xfffffffe00000000ull) | PTS_33bit);
6319bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // We start from 0, but recovered PTS could be slightly below 0.
6329bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
6339bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
6349bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        if (mLastRecoveredPTS < 0ll) {
6355c9054bc6efc080b265e028f2ebb1abd2a2e3953Chih-Hung Hsieh            ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS);
6369bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            mLastRecoveredPTS = 0ll;
6379bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
6389bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    }
6399bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
6409bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    return mLastRecoveredPTS;
641799c9682b3776a55d234396aee4a302437150c26Chong Zhang}
642799c9682b3776a55d234396aee4a302437150c26Chong Zhang
643cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> ATSParser::Program::getSource(SourceType type) {
644cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (size_t i = 0; i < mStreams.size(); ++i) {
645cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        sp<MediaSource> source = mStreams.editValueAt(i)->getSource(type);
646cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (source != NULL) {
6479ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            return source;
648cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
649cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
650cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
651cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return NULL;
652cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
653cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
654bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shihbool ATSParser::Program::hasSource(SourceType type) const {
655bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    for (size_t i = 0; i < mStreams.size(); ++i) {
656bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        const sp<Stream> &stream = mStreams.valueAt(i);
657bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        if (type == AUDIO && stream->isAudio()) {
658bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih            return true;
659bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        } else if (type == VIDEO && stream->isVideo()) {
660bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih            return true;
6619ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        } else if (type == META && stream->isMeta()) {
6629ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            return true;
663bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        }
664bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    }
665bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
666bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    return false;
667bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih}
668bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
669bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberint64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
670799c9682b3776a55d234396aee4a302437150c26Chong Zhang    PTS = recoverPTS(PTS);
671799c9682b3776a55d234396aee4a302437150c26Chong Zhang
672c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber    if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
673c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        if (!mFirstPTSValid) {
674c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            mFirstPTSValid = true;
675c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            mFirstPTS = PTS;
676c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            PTS = 0;
677c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        } else if (PTS < mFirstPTS) {
678c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            PTS = 0;
679c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        } else {
680c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            PTS -= mFirstPTS;
681c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        }
682bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
683bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
68487f2a558dd12043631e12c361abef301bf603140Andreas Huber    int64_t timeUs = (PTS * 100) / 9;
68587f2a558dd12043631e12c361abef301bf603140Andreas Huber
68687f2a558dd12043631e12c361abef301bf603140Andreas Huber    if (mParser->mAbsoluteTimeAnchorUs >= 0ll) {
68787f2a558dd12043631e12c361abef301bf603140Andreas Huber        timeUs += mParser->mAbsoluteTimeAnchorUs;
68887f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
68987f2a558dd12043631e12c361abef301bf603140Andreas Huber
690d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    if (mParser->mTimeOffsetValid) {
691d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        timeUs += mParser->mTimeOffsetUs;
692d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    }
693d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
69487f2a558dd12043631e12c361abef301bf603140Andreas Huber    return timeUs;
695bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber}
696bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
6973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangvoid ATSParser::Program::updateCasSessions() {
6983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    for (size_t i = 0; i < mStreams.size(); ++i) {
6993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<Stream> &stream = mStreams.editValueAt(i);
7003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<IDescrambler> descrambler;
7013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        std::vector<uint8_t> sessionId;
702bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang        int32_t systemId;
703bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang        if (mParser->mCasManager->getCasInfo(mProgramNumber, stream->pid(),
704bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang                &systemId, &descrambler, &sessionId)) {
705bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            stream->setCasInfo(systemId, descrambler, sessionId);
7063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
7073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
7083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
7093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
710cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
7113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangstatic const size_t kInitialStreamBufferSize = 192 * 1024;
712cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
713bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas HuberATSParser::Stream::Stream(
71487f2a558dd12043631e12c361abef301bf603140Andreas Huber        Program *program,
71587f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned elementaryPID,
71687f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned streamType,
7173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PCR_PID,
7183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t CA_system_ID)
719bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    : mProgram(program),
720bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber      mElementaryPID(elementaryPID),
721cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mStreamType(streamType),
72287f2a558dd12043631e12c361abef301bf603140Andreas Huber      mPCR_PID(PCR_PID),
72387f2a558dd12043631e12c361abef301bf603140Andreas Huber      mExpectedContinuityCounter(-1),
7246a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber      mPayloadStarted(false),
725be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen      mEOSReached(false),
72690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mPrevPTS(0),
7273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang      mQueue(NULL),
7283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang      mScrambled(CA_system_ID >= 0) {
7293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
7303a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleEncrypted =
7313a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mStreamType == STREAMTYPE_H264_ENCRYPTED ||
7323a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mStreamType == STREAMTYPE_AAC_ENCRYPTED  ||
7333a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mStreamType == STREAMTYPE_AC3_ENCRYPTED;
7343a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
7353a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGV("new stream PID 0x%02x, type 0x%02x, scrambled %d, SampleEncrypted: %d",
7363a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            elementaryPID, streamType, mScrambled, mSampleEncrypted);
7373a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
7383a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    uint32_t flags =
7393a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            (isVideo() && mScrambled) ? ElementaryStreamQueue::kFlag_ScrambledData :
7403a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            (mSampleEncrypted) ? ElementaryStreamQueue::kFlag_SampleEncryptedData :
7413a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            0;
7423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
7433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ElementaryStreamQueue::Mode mode = ElementaryStreamQueue::INVALID;
7443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
745386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    switch (mStreamType) {
746386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_H264:
7473a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_H264_ENCRYPTED:
7483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::H264;
7493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            flags |= (mProgram->parserFlags() & ALIGNED_VIDEO_DATA) ?
7503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    ElementaryStreamQueue::kFlag_AlignedData : 0;
751386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
7523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
7536e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG2_AUDIO_ADTS:
7543a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_AAC_ENCRYPTED:
7553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::AAC;
756386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
7573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
758386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG1_AUDIO:
759386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG2_AUDIO:
7603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::MPEG_AUDIO;
761386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
762386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
763386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG1_VIDEO:
764386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG2_VIDEO:
7653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::MPEG_VIDEO;
766386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
767386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
768386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG4_VIDEO:
7693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::MPEG4_VIDEO;
770386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
771386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
7729bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang        case STREAMTYPE_LPCM_AC3:
773d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu        case STREAMTYPE_AC3:
7743a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_AC3_ENCRYPTED:
7753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::AC3;
776d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu            break;
777d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu
7780852843d304006e3ab333081fddda13b07193de8Robert Shih        case STREAMTYPE_METADATA:
7793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::METADATA;
7800852843d304006e3ab333081fddda13b07193de8Robert Shih            break;
7810852843d304006e3ab333081fddda13b07193de8Robert Shih
782386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        default:
7833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGE("stream PID 0x%02x has invalid stream type 0x%02x",
7843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    elementaryPID, streamType);
7853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return;
786386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
787386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
7883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mQueue = new ElementaryStreamQueue(mode, flags);
78918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
79018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (mQueue != NULL) {
7913a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        if (mSampleAesKeyItem != NULL) {
7923a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mQueue->signalNewSampleAesKey(mSampleAesKeyItem);
7933a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        }
7943a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
7953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ensureBufferCapacity(kInitialStreamBufferSize);
7963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
7973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mScrambled && (isAudio() || isVideo())) {
7983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // Set initial format to scrambled
7993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            sp<MetaData> meta = new MetaData();
8003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            meta->setCString(kKeyMIMEType,
8013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
8023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                              : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
803bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            // for MediaExtractor.CasInfo
804bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            meta->setInt32(kKeyCASystemID, CA_system_ID);
8053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mSource = new AnotherPacketSource(meta);
8063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
80718ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
808cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
809cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
810cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberATSParser::Stream::~Stream() {
811386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    delete mQueue;
812386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    mQueue = NULL;
813cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
814cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
815d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangbool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
8163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
817d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        return true;
8183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
8193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
8213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);
8223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<ABuffer> newBuffer, newScrambledBuffer;
8243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<IMemory> newMem;
8253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<MemoryDealer> newDealer;
8263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mScrambled) {
8273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        size_t alignment = MemoryDealer::getAllocationAlignment();
8283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        neededSize = (neededSize + (alignment - 1)) & ~(alignment - 1);
8293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Align to multiples of 64K.
8303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        neededSize = (neededSize + 65535) & ~65535;
8313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newDealer = new MemoryDealer(neededSize, "ATSParser");
8323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newMem = newDealer->allocate(neededSize);
8333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newScrambledBuffer = new ABuffer(newMem->pointer(), newMem->size());
8343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mDescrambledBuffer != NULL) {
8363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            memcpy(newScrambledBuffer->data(),
8373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    mDescrambledBuffer->data(), mDescrambledBuffer->size());
8383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            newScrambledBuffer->setRange(0, mDescrambledBuffer->size());
8393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        } else {
8403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            newScrambledBuffer->setRange(0, 0);
8413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
8423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mMem = newMem;
8433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mDealer = newDealer;
8443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mDescrambledBuffer = newScrambledBuffer;
845d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
846d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        ssize_t offset;
847d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        size_t size;
848d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        sp<IMemoryHeap> heap = newMem->getMemory(&offset, &size);
849d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        if (heap == NULL) {
850d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            return false;
851d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        }
852d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        native_handle_t* nativeHandle = native_handle_create(1, 0);
853d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        if (!nativeHandle) {
854d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            ALOGE("[stream %d] failed to create native handle", mElementaryPID);
855d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            return false;
856d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        }
857d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        nativeHandle->data[0] = heap->getHeapID();
858d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        mDescramblerSrcBuffer.heapBase = hidl_memory("ashmem",
859d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                hidl_handle(nativeHandle), heap->getSize());
860d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        mDescramblerSrcBuffer.offset = (uint64_t) offset;
861d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        mDescramblerSrcBuffer.size = (uint64_t) size;
862d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
863d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        ALOGD("[stream %d] created shared buffer for descrambling, offset %zd, size %zu",
864d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                mElementaryPID, offset, size);
8653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    } else {
8663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Align to multiples of 64K.
8673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        neededSize = (neededSize + 65535) & ~65535;
8683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
8693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    newBuffer = new ABuffer(neededSize);
8713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mBuffer != NULL) {
8723b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
8733b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newBuffer->setRange(0, mBuffer->size());
8743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    } else {
8753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newBuffer->setRange(0, 0);
8763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
8773b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mBuffer = newBuffer;
878d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    return true;
8793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
8803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8815403129e2a2f44620f2ac8109889e5a61be08732Andreas Huberstatus_t ATSParser::Stream::parse(
88287f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned continuity_counter,
8833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned payload_unit_start_indicator,
8843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned transport_scrambling_control,
8853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned random_access_indicator,
8863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader *br, SyncEvent *event) {
88718ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (mQueue == NULL) {
8885403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber        return OK;
88918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
89018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
89187f2a558dd12043631e12c361abef301bf603140Andreas Huber    if (mExpectedContinuityCounter >= 0
89287f2a558dd12043631e12c361abef301bf603140Andreas Huber            && (unsigned)mExpectedContinuityCounter != continuity_counter) {
89387f2a558dd12043631e12c361abef301bf603140Andreas Huber        ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
89487f2a558dd12043631e12c361abef301bf603140Andreas Huber
89587f2a558dd12043631e12c361abef301bf603140Andreas Huber        mPayloadStarted = false;
8969558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        mPesStartOffsets.clear();
89787f2a558dd12043631e12c361abef301bf603140Andreas Huber        mBuffer->setRange(0, 0);
8983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mSubSamples.clear();
89987f2a558dd12043631e12c361abef301bf603140Andreas Huber        mExpectedContinuityCounter = -1;
90087f2a558dd12043631e12c361abef301bf603140Andreas Huber
90194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#if 0
90294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        // Uncomment this if you'd rather see no corruption whatsoever on
90394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        // screen and suspend updates until we come across another IDR frame.
90494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
90594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        if (mStreamType == STREAMTYPE_H264) {
90694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            ALOGI("clearing video queue");
90794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            mQueue->clear(true /* clearFormat */);
90894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        }
90994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#endif
91094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
91166830855846db5c211c2da6c055ca9b4167e8974Chong Zhang        if (!payload_unit_start_indicator) {
91266830855846db5c211c2da6c055ca9b4167e8974Chong Zhang            return OK;
91366830855846db5c211c2da6c055ca9b4167e8974Chong Zhang        }
91487f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
91587f2a558dd12043631e12c361abef301bf603140Andreas Huber
91687f2a558dd12043631e12c361abef301bf603140Andreas Huber    mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f;
91787f2a558dd12043631e12c361abef301bf603140Andreas Huber
918cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (payload_unit_start_indicator) {
919540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        off64_t offset = (event != NULL) ? event->getOffset() : 0;
920cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (mPayloadStarted) {
921cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            // Otherwise we run the danger of receiving the trailing bytes
922cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            // of a PES packet that we never saw the start of and assuming
923cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            // we have a a complete PES packet.
924cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
925540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            status_t err = flush(event);
9265403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
9275403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber            if (err != OK) {
92865959d34fdab8319dbf765be5fbf7ff8051eedf1Wonsik Kim                ALOGW("Error (%08x) happened while flushing; we simply discard "
92965959d34fdab8319dbf765be5fbf7ff8051eedf1Wonsik Kim                      "the PES packet and continue.", err);
9305403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber            }
931cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
932cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
933cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        mPayloadStarted = true;
934b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        // There should be at most 2 elements in |mPesStartOffsets|.
935b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        while (mPesStartOffsets.size() >= 2) {
936b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia            mPesStartOffsets.erase(mPesStartOffsets.begin());
937b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        }
9389558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        mPesStartOffsets.push_back(offset);
939cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
940cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
941cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (!mPayloadStarted) {
9425403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber        return OK;
943cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
944cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
945cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    size_t payloadSizeBits = br->numBitsLeft();
946e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (payloadSizeBits % 8 != 0u) {
947e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Wrong value");
948e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return BAD_VALUE;
949e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
950cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
9513e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber    size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
952d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    if (!ensureBufferCapacity(neededSize)) {
953d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        return NO_MEMORY;
954d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    }
955cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
956cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
957cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
9585403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
9593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mScrambled) {
9603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mSubSamples.push_back({payloadSizeBits / 8,
9613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                 transport_scrambling_control, random_access_indicator});
9623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
9633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
9645403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    return OK;
965cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
966cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
9676e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huberbool ATSParser::Stream::isVideo() const {
9686e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    switch (mStreamType) {
9696e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_H264:
9703a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_H264_ENCRYPTED:
9716e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG1_VIDEO:
9726e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG2_VIDEO:
9736e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG4_VIDEO:
9746e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            return true;
9756e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9766e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        default:
9776e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            return false;
9786e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
9796e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber}
9806e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9816e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huberbool ATSParser::Stream::isAudio() const {
9826e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    switch (mStreamType) {
9836e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG1_AUDIO:
9846e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG2_AUDIO:
9856e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG2_AUDIO_ADTS:
9869bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang        case STREAMTYPE_LPCM_AC3:
987d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu        case STREAMTYPE_AC3:
9883a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_AAC_ENCRYPTED:
9893a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_AC3_ENCRYPTED:
9906e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            return true;
9916e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9926e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        default:
9936e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            return false;
9946e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
9956e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber}
9966e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9970852843d304006e3ab333081fddda13b07193de8Robert Shihbool ATSParser::Stream::isMeta() const {
9980852843d304006e3ab333081fddda13b07193de8Robert Shih    if (mStreamType == STREAMTYPE_METADATA) {
9990852843d304006e3ab333081fddda13b07193de8Robert Shih        return true;
10000852843d304006e3ab333081fddda13b07193de8Robert Shih    }
10010852843d304006e3ab333081fddda13b07193de8Robert Shih    return false;
10020852843d304006e3ab333081fddda13b07193de8Robert Shih}
10030852843d304006e3ab333081fddda13b07193de8Robert Shih
100432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::Stream::signalDiscontinuity(
100532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        DiscontinuityType type, const sp<AMessage> &extra) {
10060389cc09f7b90f155a8942a0d2e1925cad1dbe2dMarco Nelissen    mExpectedContinuityCounter = -1;
10070389cc09f7b90f155a8942a0d2e1925cad1dbe2dMarco Nelissen
100818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (mQueue == NULL) {
100918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        return;
101018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
101118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
10122a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    mPayloadStarted = false;
10139558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    mPesStartOffsets.clear();
1014aabbdc7401ae24a4199f12a283985deb648673c0Robert Shih    mEOSReached = false;
10152a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    mBuffer->setRange(0, 0);
10163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mSubSamples.clear();
10172a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
10186e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    bool clearFormat = false;
10196e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (isAudio()) {
10206e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        if (type & DISCONTINUITY_AUDIO_FORMAT) {
10216e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            clearFormat = true;
10226e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        }
10236e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    } else {
10246e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        if (type & DISCONTINUITY_VIDEO_FORMAT) {
10256e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            clearFormat = true;
10266e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        }
10276e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10296e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    mQueue->clear(clearFormat);
103032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
10316e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (type & DISCONTINUITY_TIME) {
10326e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        uint64_t resumeAtPTS;
10336e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        if (extra != NULL
10346e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                && extra->findInt64(
10356e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    IStreamListener::kKeyResumeAtPTS,
10366e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    (int64_t *)&resumeAtPTS)) {
10376e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            int64_t resumeAtMediaTimeUs =
10386e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                mProgram->convertPTSToTimestamp(resumeAtPTS);
103932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
1040c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs);
1041e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber        }
10426e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10446e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (mSource != NULL) {
10453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<MetaData> meta = mSource->getFormat();
10463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        const char* mime;
10473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (clearFormat && meta != NULL && meta->findCString(kKeyMIMEType, &mime)
10483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                && (!strncasecmp(mime, MEDIA_MIMETYPE_AUDIO_SCRAMBLED, 15)
10493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                 || !strncasecmp(mime, MEDIA_MIMETYPE_VIDEO_SCRAMBLED, 15))){
10503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mSource->clear();
10513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        } else {
10523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mSource->queueDiscontinuity(type, extra, true);
10533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
1054bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1056bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::Stream::signalEOS(status_t finalResult) {
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mSource != NULL) {
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mSource->signalEOS(finalResult);
10602a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    }
1061be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    mEOSReached = true;
1062540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    flush(NULL);
10632a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber}
10642a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
1065540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::Stream::parsePES(ABitReader *br, SyncEvent *event) {
10663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    const uint8_t *basePtr = br->data();
10673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1068cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned packet_startcode_prefix = br->getBits(24);
1069cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
10703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
1071cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1072386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (packet_startcode_prefix != 1) {
10733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Supposedly payload_unit_start=1 unit does not start "
1074386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber             "with startcode.");
10755403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
10765403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber        return ERROR_MALFORMED;
1077386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1078386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1079cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned stream_id = br->getBits(8);
10803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stream_id = 0x%02x", stream_id);
1081cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1082cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned PES_packet_length = br->getBits(16);
10833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("PES_packet_length = %u", PES_packet_length);
1084cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1085cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (stream_id != 0xbc  // program_stream_map
1086cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xbe  // padding_stream
1087cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xbf  // private_stream_2
1088cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xf0  // ECM
1089cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xf1  // EMM
1090cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xff  // program_stream_directory
1091cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xf2  // DSMCC
1092cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xf8) {  // H.222.1 type E
1093e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (br->getBits(2) != 2u) {
1094e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return ERROR_MALFORMED;
1095e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
1096cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
10973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PES_scrambling_control = br->getBits(2);
10983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
10993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
11006e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("PES_priority = %u", br->getBits(1));
11016e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("data_alignment_indicator = %u", br->getBits(1));
11026e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("copyright = %u", br->getBits(1));
11036e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("original_or_copy = %u", br->getBits(1));
1104cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1105cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned PTS_DTS_flags = br->getBits(2);
11063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags);
1107cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned ESCR_flag = br->getBits(1);
11093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("ESCR_flag = %u", ESCR_flag);
1110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned ES_rate_flag = br->getBits(1);
11123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("ES_rate_flag = %u", ES_rate_flag);
1113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned DSM_trick_mode_flag = br->getBits(1);
11153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);
1116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned additional_copy_info_flag = br->getBits(1);
11183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag);
1119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
11206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("PES_CRC_flag = %u", br->getBits(1));
11216e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("PES_extension_flag = %u", br->getBits(1));
1122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned PES_header_data_length = br->getBits(8);
11243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("PES_header_data_length = %u", PES_header_data_length);
1125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned optional_bytes_remaining = PES_header_data_length;
1127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        uint64_t PTS = 0, DTS = 0;
1129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
1131e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (optional_bytes_remaining < 5u) {
1132e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1133e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
11356456ae745e919085c5024f784aaa2703f9695f98David Yeh            if (br->getBits(4) != PTS_DTS_flags) {
11366456ae745e919085c5024f784aaa2703f9695f98David Yeh                return ERROR_MALFORMED;
11376456ae745e919085c5024f784aaa2703f9695f98David Yeh            }
1138cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            PTS = ((uint64_t)br->getBits(3)) << 30;
1139e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1140e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1141e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1142cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            PTS |= ((uint64_t)br->getBits(15)) << 15;
1143e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1144e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1145e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            PTS |= br->getBits(15);
1147e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1148e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1149e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1151b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross            ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);
1152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            optional_bytes_remaining -= 5;
1154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            if (PTS_DTS_flags == 3) {
1156e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (optional_bytes_remaining < 5u) {
1157e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1158e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1159cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1160e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (br->getBits(4) != 1u) {
1161e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1162e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                DTS = ((uint64_t)br->getBits(3)) << 30;
1165e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (br->getBits(1) != 1u) {
1166e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1167e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1168cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                DTS |= ((uint64_t)br->getBits(15)) << 15;
1169e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (br->getBits(1) != 1u) {
1170e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1171e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1172cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                DTS |= br->getBits(15);
1173e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (br->getBits(1) != 1u) {
1174e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1175e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1176cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1177b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                ALOGV("DTS = %" PRIu64, DTS);
1178cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1179cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                optional_bytes_remaining -= 5;
1180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            }
1181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1182cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1183cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (ESCR_flag) {
1184e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (optional_bytes_remaining < 6u) {
1185e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1186e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1187cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1188cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            br->getBits(2);
1189cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1190cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
1191e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1192e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1193e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1194cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            ESCR |= ((uint64_t)br->getBits(15)) << 15;
1195e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1196e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1197e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1198cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            ESCR |= br->getBits(15);
1199e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1200e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1201e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1202cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1203b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross            ALOGV("ESCR = %" PRIu64, ESCR);
12046e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber            MY_LOGV("ESCR_extension = %u", br->getBits(9));
1205cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1206e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1207e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1208e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1209cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1210cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            optional_bytes_remaining -= 6;
1211cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1212cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1213cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (ES_rate_flag) {
1214e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (optional_bytes_remaining < 3u) {
1215e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1216e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1217cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1218e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1219e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1220e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
12216e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber            MY_LOGV("ES_rate = %u", br->getBits(22));
1222e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1223e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1224e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1225cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1226cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            optional_bytes_remaining -= 3;
1227cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1228cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1229cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        br->skipBits(optional_bytes_remaining * 8);
1230cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1231cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        // ES data follows.
12323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t pesOffset = br->data() - basePtr;
1233cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1234cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (PES_packet_length != 0) {
1235e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (PES_packet_length < PES_header_data_length + 3) {
1236e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1237e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1238cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1239cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned dataLength =
1240cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                PES_packet_length - 3 - PES_header_data_length;
1241cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
12425403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber            if (br->numBitsLeft() < dataLength * 8) {
124329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("PES packet does not carry enough data to contain "
1244b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                     "payload. (numBitsLeft = %zu, required = %u)",
12455403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber                     br->numBitsLeft(), dataLength * 8);
12465403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
12475403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber                return ERROR_MALFORMED;
12485403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber            }
12495403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
12503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGV("There's %u bytes of payload, PES_packet_length=%u, offset=%d",
12513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    dataLength, PES_packet_length, pesOffset);
12523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
12530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            onPayloadData(
12543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
12553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    br->data(), dataLength, pesOffset, event);
1256cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1257cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            br->skipBits(dataLength * 8);
1258cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        } else {
12590da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            onPayloadData(
12603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
12613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    br->data(), br->numBitsLeft() / 8, pesOffset, event);
12620da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1263cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            size_t payloadSizeBits = br->numBitsLeft();
1264e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (payloadSizeBits % 8 != 0u) {
1265e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1266e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1267cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
12683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGV("There's %zu bytes of payload, offset=%d",
12693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    payloadSizeBits / 8, pesOffset);
1270cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1271cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    } else if (stream_id == 0xbe) {  // padding_stream
1272e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (PES_packet_length == 0u) {
1273e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return ERROR_MALFORMED;
1274e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
1275cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        br->skipBits(PES_packet_length * 8);
1276cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    } else {
1277e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (PES_packet_length == 0u) {
1278e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return ERROR_MALFORMED;
1279e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
1280cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        br->skipBits(PES_packet_length * 8);
1281cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
12825403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
12835403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    return OK;
1284cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1285cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
12863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhanguint32_t ATSParser::Stream::getPesScramblingControl(
12873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader *br, int32_t *pesOffset) {
12883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    unsigned packet_startcode_prefix = br->getBits(24);
12893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
12903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
12913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
12923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (packet_startcode_prefix != 1) {
12933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("unit does not start with startcode.");
12943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return 0;
12953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
12963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
12973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (br->numBitsLeft() < 48) {
12983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return 0;
12993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    unsigned stream_id = br->getBits(8);
13023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("stream_id = 0x%02x", stream_id);
13033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    br->skipBits(16); // PES_packet_length
13053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (stream_id != 0xbc  // program_stream_map
13073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xbe  // padding_stream
13083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xbf  // private_stream_2
13093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xf0  // ECM
13103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xf1  // EMM
13113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xff  // program_stream_directory
13123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xf2  // DSMCC
13133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xf8) {  // H.222.1 type E
13143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (br->getBits(2) != 2u) {
13153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return 0;
13163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PES_scrambling_control = br->getBits(2);
13193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
13203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (PES_scrambling_control == 0) {
13223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return 0;
13233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        br->skipBits(12); // don't care
13263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PES_header_data_length = br->getBits(8);
13283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("PES_header_data_length = %u", PES_header_data_length);
13293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (PES_header_data_length * 8 > br->numBitsLeft()) {
13313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return 0;
13323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        *pesOffset = 9 + PES_header_data_length;
13353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGD("found PES_scrambling_control=%d, PES offset=%d",
13363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                PES_scrambling_control, *pesOffset);
13373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return PES_scrambling_control;
13383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return 0;
13413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
13423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangstatus_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
13443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mDescrambler == NULL) {
13453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGE("received scrambled packets without descrambler!");
13463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return UNKNOWN_ERROR;
13473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mDescrambledBuffer == NULL || mMem == NULL) {
13503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGE("received scrambled packets without shared memory!");
13513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return UNKNOWN_ERROR;
13533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    int32_t pesOffset = 0;
13563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    int32_t descrambleSubSamples = 0, descrambleBytes = 0;
13573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    uint32_t tsScramblingControl = 0, pesScramblingControl = 0;
13583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // First, go over subsamples to find TS-level scrambling key id, and
13603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // calculate how many subsample we need to descramble (assuming we don't
13613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // have PES-level scrambling).
13623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    for (auto it = mSubSamples.begin(); it != mSubSamples.end(); it++) {
13633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (it->transport_scrambling_mode != 0) {
13643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // TODO: handle keyId change, use the first non-zero keyId for now.
13653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            if (tsScramblingControl == 0) {
13663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                tsScramblingControl = it->transport_scrambling_mode;
13673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
13683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (tsScramblingControl == 0 || descrambleSubSamples == 0
13703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                || !mQueue->isScrambled()) {
13713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            descrambleSubSamples++;
13723b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            descrambleBytes += it->subSampleSize;
13733b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // If not scrambled at TS-level, check PES-level scrambling
13763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (tsScramblingControl == 0) {
13773b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader br(mBuffer->data(), mBuffer->size());
13783b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        pesScramblingControl = getPesScramblingControl(&br, &pesOffset);
13793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // If not scrambled at PES-level either, or scrambled at PES-level but
13803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // requires output to remain scrambled, we don't need to descramble
13813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // anything.
13823b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (pesScramblingControl == 0 || mQueue->isScrambled()) {
13833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            descrambleSubSamples = 0;
13843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            descrambleBytes = 0;
13853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    uint32_t sctrl = tsScramblingControl != 0 ?
13893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            tsScramblingControl : pesScramblingControl;
13903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // Perform the 1st pass descrambling if needed
13923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (descrambleBytes > 0) {
13933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
13943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mDescrambledBuffer->setRange(0, descrambleBytes);
13953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1396d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        hidl_vec<SubSample> subSamples;
1397d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        subSamples.resize(descrambleSubSamples);
13983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t i = 0;
14003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        for (auto it = mSubSamples.begin();
14013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
14023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
1403d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples[i].numBytesOfClearData = 0;
1404d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
14053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            } else {
1406d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples[i].numBytesOfClearData = it->subSampleSize;
1407d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples[i].numBytesOfEncryptedData = 0;
14083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
14093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
1410d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
1411d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        uint64_t srcOffset = 0, dstOffset = 0;
14123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // If scrambled at PES-level, PES header should be skipped
14133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (pesScramblingControl != 0) {
1414d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            srcOffset = dstOffset = pesOffset;
1415d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            subSamples[0].numBytesOfEncryptedData -= pesOffset;
14163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
14173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1418d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        Status status = Status::OK;
1419d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        uint32_t bytesWritten = 0;
1420d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        hidl_string detailedError;
1421d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
1422d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        DestinationBuffer dstBuffer;
1423d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        dstBuffer.type = BufferType::SHARED_MEMORY;
1424d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;
1425d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
1426d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        auto returnVoid = mDescrambler->descramble(
1427d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                (ScramblingControl) sctrl,
1428d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples,
1429d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                mDescramblerSrcBuffer,
1430d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                srcOffset,
1431d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                dstBuffer,
1432d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                dstOffset,
1433d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                [&status, &bytesWritten, &detailedError] (
1434d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                        Status _status, uint32_t _bytesWritten,
1435d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                        const hidl_string& _detailedError) {
1436d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                    status = _status;
1437d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                    bytesWritten = _bytesWritten;
1438d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                    detailedError = _detailedError;
1439d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                });
1440d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
1441d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        if (!returnVoid.isOk()) {
1442d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            ALOGE("[stream %d] descramble failed, trans=%s",
1443d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                    mElementaryPID, returnVoid.description().c_str());
14443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return UNKNOWN_ERROR;
14453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
14463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("[stream %d] descramble succeeded, %d bytes",
1448d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                mElementaryPID, bytesWritten);
14493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
14503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
14513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mQueue->isScrambled()) {
14533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Queue subSample info for scrambled queue
14543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
14553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<ABuffer> encSizesBuffer = new ABuffer(mSubSamples.size() * 4);
14563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t *clearSizePtr = (int32_t*)clearSizesBuffer->data();
14573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t *encSizePtr = (int32_t*)encSizesBuffer->data();
14583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t isSync = 0;
14593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t i = 0;
14603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        for (auto it = mSubSamples.begin();
14613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                it != mSubSamples.end(); it++, i++) {
14623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            if ((it->transport_scrambling_mode == 0
14633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    && pesScramblingControl == 0)
14643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    || i < descrambleSubSamples) {
14653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                clearSizePtr[i] = it->subSampleSize;
14663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                encSizePtr[i] = 0;
14673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            } else {
14683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                clearSizePtr[i] = 0;
14693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                encSizePtr[i] = it->subSampleSize;
14703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
14713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            isSync |= it->random_access_indicator;
14723b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
14733b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Pass the original TS subsample size now. The PES header adjust
14743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // will be applied when the scrambled AU is dequeued.
14753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mQueue->appendScrambledData(
14763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mBuffer->data(), mBuffer->size(), sctrl,
14773b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                isSync, clearSizesBuffer, encSizesBuffer);
14783b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
14793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ABitReader br(mBuffer->data(), mBuffer->size());
14813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t err = parsePES(&br, event);
14823b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (err != OK) {
14843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGE("[stream %d] failed to parse descrambled PES, err=%d",
14853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mElementaryPID, err);
14863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
14873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return err;
14893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
14903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1492540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::Stream::flush(SyncEvent *event) {
1493f2cecd570c35d3b6422396dd51c0b4202732bceaJaesung Chung    if (mBuffer == NULL || mBuffer->size() == 0) {
14945403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber        return OK;
1495cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1496cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1497b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size());
1498cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
14993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t err = OK;
15003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mScrambled) {
15013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        err = flushScrambled(event);
15023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mSubSamples.clear();
15033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    } else {
15043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader br(mBuffer->data(), mBuffer->size());
15053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        err = parsePES(&br, event);
15063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
1507cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1508cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mBuffer->setRange(0, 0);
15095403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
15105403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    return err;
1511cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1512cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1513cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid ATSParser::Stream::onPayloadData(
151484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
15153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PES_scrambling_control,
15163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        const uint8_t *data, size_t size,
15173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t payloadOffset, SyncEvent *event) {
151890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if 0
151990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
152090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber          mStreamType,
152190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber          PTS,
152290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber          (int64_t)PTS - mPrevPTS);
152390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mPrevPTS = PTS;
152490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
152590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
15263a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGV("onPayloadData mStreamType=0x%02x size: %zu", mStreamType, size);
1527cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
152898a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    int64_t timeUs = 0ll;  // no presentation timestamp available.
152998a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
153098a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber        timeUs = mProgram->convertPTSToTimestamp(PTS);
153198a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    }
153282f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
15333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t err = mQueue->appendData(
15343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            data, size, timeUs, payloadOffset, PES_scrambling_control);
1535decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
1536be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    if (mEOSReached) {
1537be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        mQueue->signalEOS();
1538be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    }
1539be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen
1540decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber    if (err != OK) {
1541decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber        return;
1542decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber    }
154382f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
15446a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    sp<ABuffer> accessUnit;
1545540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    bool found = false;
1546386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
15476a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (mSource == NULL) {
1548386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            sp<MetaData> meta = mQueue->getFormat();
154982f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
15506a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            if (meta != NULL) {
15513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("Stream PID 0x%08x of type 0x%02x now has data.",
1552386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                     mElementaryPID, mStreamType);
1553386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1554309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih                const char *mime;
1555309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih                if (meta->findCString(kKeyMIMEType, &mime)
15563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                        && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
15573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    int32_t sync = 0;
15583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    if (!accessUnit->meta()->findInt32("isSync", &sync) || !sync) {
15593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                        continue;
15603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    }
1561309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih                }
15626a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                mSource = new AnotherPacketSource(meta);
15636a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                mSource->queueAccessUnit(accessUnit);
15643a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
15653a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                        mElementaryPID, mStreamType);
156682f7321b03eec1e40af9d681370f754ee0279582Andreas Huber            }
1567386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        } else if (mQueue->getFormat() != NULL) {
15682a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber            // After a discontinuity we invalidate the queue's format
15692a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber            // and won't enqueue any access units to the source until
15702a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber            // the queue has reestablished the new format.
15715bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
15725bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            if (mSource->getFormat() == NULL) {
1573386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mSource->setFormat(mQueue->getFormat());
15745bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            }
15756a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            mSource->queueAccessUnit(accessUnit);
157682f7321b03eec1e40af9d681370f754ee0279582Andreas Huber        }
1577540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
1578b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
1579b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        off64_t pesStartOffset = -1;
1580b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        if (!mPesStartOffsets.empty()) {
1581b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia            pesStartOffset = *mPesStartOffsets.begin();
1582b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia            mPesStartOffsets.erase(mPesStartOffsets.begin());
1583b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        }
1584b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia
1585b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        if (pesStartOffset >= 0 && (event != NULL) && !found && mQueue->getFormat() != NULL) {
1586540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            int32_t sync = 0;
1587540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            if (accessUnit->meta()->findInt32("isSync", &sync) && sync) {
1588540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                int64_t timeUs;
1589540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
1590540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                    found = true;
159182e147049625a4cfdcb228a1de7efda594d446c9Robert Shih                    event->init(pesStartOffset, mSource, timeUs, getSourceType());
1592540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                }
1593540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            }
1594540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        }
159582f7321b03eec1e40af9d681370f754ee0279582Andreas Huber    }
159682f7321b03eec1e40af9d681370f754ee0279582Andreas Huber}
159782f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
159882e147049625a4cfdcb228a1de7efda594d446c9Robert ShihATSParser::SourceType ATSParser::Stream::getSourceType() {
159982e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    if (isVideo()) {
160082e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        return VIDEO;
160182e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    } else if (isAudio()) {
160282e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        return AUDIO;
160382e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    } else if (isMeta()) {
160482e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        return META;
160582e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    }
160682e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    return NUM_SOURCE_TYPES;
160782e147049625a4cfdcb228a1de7efda594d446c9Robert Shih}
160882e147049625a4cfdcb228a1de7efda594d446c9Robert Shih
1609cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> ATSParser::Stream::getSource(SourceType type) {
1610386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    switch (type) {
1611386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case VIDEO:
1612386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        {
16136e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            if (isVideo()) {
1614386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                return mSource;
1615386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1616386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
1617386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1618386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1619386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case AUDIO:
1620386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        {
16216e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            if (isAudio()) {
1622386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                return mSource;
1623386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1624386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
1625386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1626386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
16270852843d304006e3ab333081fddda13b07193de8Robert Shih        case META:
16280852843d304006e3ab333081fddda13b07193de8Robert Shih        {
16290852843d304006e3ab333081fddda13b07193de8Robert Shih            if (isMeta()) {
16300852843d304006e3ab333081fddda13b07193de8Robert Shih                return mSource;
16310852843d304006e3ab333081fddda13b07193de8Robert Shih            }
16320852843d304006e3ab333081fddda13b07193de8Robert Shih            break;
16330852843d304006e3ab333081fddda13b07193de8Robert Shih        }
16340852843d304006e3ab333081fddda13b07193de8Robert Shih
1635386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        default:
1636386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
1637cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1638cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1639cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return NULL;
1640cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1641cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1642bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhangvoid ATSParser::Stream::setCasInfo(
1643bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang        int32_t systemId, const sp<IDescrambler> &descrambler,
16443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        const std::vector<uint8_t> &sessionId) {
16453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mSource != NULL && mDescrambler == NULL && descrambler != NULL) {
16463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        signalDiscontinuity(DISCONTINUITY_FORMAT_ONLY, NULL);
16473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mDescrambler = descrambler;
16483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mQueue->isScrambled()) {
1649bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            mQueue->setCasInfo(systemId, sessionId);
16503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
16513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
16523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
16533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1654cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
1655cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1656c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas HuberATSParser::ATSParser(uint32_t flags)
165787f2a558dd12043631e12c361abef301bf603140Andreas Huber    : mFlags(flags),
165887f2a558dd12043631e12c361abef301bf603140Andreas Huber      mAbsoluteTimeAnchorUs(-1ll),
1659d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber      mTimeOffsetValid(false),
1660d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber      mTimeOffsetUs(0ll),
1661d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang      mLastRecoveredPTS(-1ll),
166287f2a558dd12043631e12c361abef301bf603140Andreas Huber      mNumTSPacketsParsed(0),
166387f2a558dd12043631e12c361abef301bf603140Andreas Huber      mNumPCRs(0) {
16648dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    mPSISections.add(0 /* PID */, new PSISection);
16653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mCasManager = new CasManager();
1666cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1667cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1668cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberATSParser::~ATSParser() {
1669cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1670cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1671540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::feedTSPacket(const void *data, size_t size,
1672540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        SyncEvent *event) {
1673e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (size != kTSPacketSize) {
1674e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Wrong TS packet size");
1675e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return BAD_VALUE;
1676e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
1677cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1678cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    ABitReader br((const uint8_t *)data, kTSPacketSize);
1679540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    return parseTS(&br, event);
1680cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1681cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
16823b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangstatus_t ATSParser::setMediaCas(const sp<ICas> &cas) {
16833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t err = mCasManager->setMediaCas(cas);
16843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (err != OK) {
16853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return err;
16863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
16873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    for (size_t i = 0; i < mPrograms.size(); ++i) {
16883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mPrograms.editItemAt(i)->updateCasSessions();
16893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
16903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return OK;
16913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
16923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
169332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::signalDiscontinuity(
169432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        DiscontinuityType type, const sp<AMessage> &extra) {
1695b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    int64_t mediaTimeUs;
1696d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if ((type & DISCONTINUITY_TIME) && extra != NULL) {
1697d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        if (extra->findInt64(IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) {
1698d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            mAbsoluteTimeAnchorUs = mediaTimeUs;
1699d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1700d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)
1701d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                && extra->findInt64(
1702d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                    IStreamListener::kKeyRecentMediaTimeUs, &mediaTimeUs)) {
1703d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            if (mAbsoluteTimeAnchorUs >= 0ll) {
1704d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                mediaTimeUs -= mAbsoluteTimeAnchorUs;
1705d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            }
1706d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            if (mTimeOffsetValid) {
1707d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                mediaTimeUs -= mTimeOffsetUs;
1708d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            }
1709d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            mLastRecoveredPTS = (mediaTimeUs * 9) / 100;
1710d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1711b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    } else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
171287f2a558dd12043631e12c361abef301bf603140Andreas Huber        int64_t timeUs;
1713e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (!extra->findInt64("timeUs", &timeUs)) {
1714e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            ALOGE("timeUs not found");
1715e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return;
1716e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
171787f2a558dd12043631e12c361abef301bf603140Andreas Huber
1718e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (!mPrograms.empty()) {
1719e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            ALOGE("mPrograms is not empty");
1720e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return;
1721e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
172287f2a558dd12043631e12c361abef301bf603140Andreas Huber        mAbsoluteTimeAnchorUs = timeUs;
172387f2a558dd12043631e12c361abef301bf603140Andreas Huber        return;
1724d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    } else if (type == DISCONTINUITY_TIME_OFFSET) {
1725d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        int64_t offset;
1726e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (!extra->findInt64("offset", &offset)) {
1727e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            ALOGE("offset not found");
1728e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return;
1729e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
1730d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
1731d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        mTimeOffsetValid = true;
1732d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        mTimeOffsetUs = offset;
1733d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        return;
173487f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
173587f2a558dd12043631e12c361abef301bf603140Andreas Huber
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mPrograms.size(); ++i) {
173732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        mPrograms.editItemAt(i)->signalDiscontinuity(type, extra);
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::signalEOS(status_t finalResult) {
1742e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (finalResult == (status_t) OK) {
1743e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("finalResult not OK");
1744e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return;
1745e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17472a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    for (size_t i = 0; i < mPrograms.size(); ++i) {
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mPrograms.editItemAt(i)->signalEOS(finalResult);
17492a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    }
17502a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber}
17512a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
1752cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid ATSParser::parseProgramAssociationTable(ABitReader *br) {
1753cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned table_id = br->getBits(8);
17543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  table_id = %u", table_id);
17556456ae745e919085c5024f784aaa2703f9695f98David Yeh    if (table_id != 0x00u) {
17566456ae745e919085c5024f784aaa2703f9695f98David Yeh        ALOGE("PAT data error!");
17576456ae745e919085c5024f784aaa2703f9695f98David Yeh        return ;
17586456ae745e919085c5024f784aaa2703f9695f98David Yeh    }
1759cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned section_syntax_indictor = br->getBits(1);
17603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  section_syntax_indictor = %u", section_syntax_indictor);
1761cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1762e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    br->skipBits(1);  // '0'
17636e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(2));
1764cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1765cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned section_length = br->getBits(12);
17663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  section_length = %u", section_length);
1767cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17686e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  transport_stream_id = %u", br->getBits(16));
17696e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(2));
17706e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  version_number = %u", br->getBits(5));
17716e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
17726e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  section_number = %u", br->getBits(8));
17736e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  last_section_number = %u", br->getBits(8));
1774cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1775cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);
1776cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1777cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (size_t i = 0; i < numProgramBytes / 4; ++i) {
1778cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned program_number = br->getBits(16);
17793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("    program_number = %u", program_number);
1780cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17816e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("    reserved = %u", br->getBits(3));
1782cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1783cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (program_number == 0) {
17846e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber            MY_LOGV("    network_PID = 0x%04x", br->getBits(13));
1785cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        } else {
1786cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned programMapPID = br->getBits(13);
1787cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("    program_map_PID = 0x%04x", programMapPID);
1789cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1790386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            bool found = false;
1791386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            for (size_t index = 0; index < mPrograms.size(); ++index) {
1792386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                const sp<Program> &program = mPrograms.itemAt(index);
1793386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1794386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (program->number() == program_number) {
1795386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    program->updateProgramMapPID(programMapPID);
1796386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    found = true;
1797386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    break;
1798386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
1799386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1800386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1801386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            if (!found) {
1802386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mPrograms.push(
1803d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                        new Program(this, program_number, programMapPID, mLastRecoveredPTS));
18043a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                if (mSampleAesKeyItem != NULL) {
18053a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    mPrograms.top()->signalNewSampleAesKey(mSampleAesKeyItem);
18063a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                }
1807386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
18088dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18098dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            if (mPSISections.indexOfKey(programMapPID) < 0) {
18108dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                mPSISections.add(programMapPID, new PSISection);
18118dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            }
1812cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1813cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1814cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
18156e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
1816cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1817cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
181806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huberstatus_t ATSParser::parsePID(
1819cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ABitReader *br, unsigned PID,
182087f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned continuity_counter,
1821540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        unsigned payload_unit_start_indicator,
18223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned transport_scrambling_control,
18233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned random_access_indicator,
1824540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        SyncEvent *event) {
18258dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    ssize_t sectionIndex = mPSISections.indexOfKey(PID);
18268dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18278dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (sectionIndex >= 0) {
18284b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber        sp<PSISection> section = mPSISections.valueAt(sectionIndex);
18298dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
1830cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (payload_unit_start_indicator) {
18316456ae745e919085c5024f784aaa2703f9695f98David Yeh            if (!section->isEmpty()) {
18329bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty");
18339bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                section->clear();
18346456ae745e919085c5024f784aaa2703f9695f98David Yeh            }
18358dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
1836cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned skip = br->getBits(8);
18379ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim            section->setSkipBytes(skip + 1);  // skip filler bytes + pointer field itself
1838cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            br->skipBits(skip * 8);
1839cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
18408dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
1841e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (br->numBitsLeft() % 8 != 0) {
1842e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return ERROR_MALFORMED;
1843e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
18448dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        status_t err = section->append(br->data(), br->numBitsLeft() / 8);
18458dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18468dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        if (err != OK) {
18478dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            return err;
18488dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        }
18498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18508dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        if (!section->isComplete()) {
18518dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            return OK;
18528dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        }
18538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18549ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        if (!section->isCRCOkay()) {
18559ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim            return BAD_VALUE;
18569ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        }
18578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        ABitReader sectionBits(section->data(), section->size());
18588dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        if (PID == 0) {
18608dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            parseProgramAssociationTable(&sectionBits);
18618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        } else {
18628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            bool handled = false;
18638dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            for (size_t i = 0; i < mPrograms.size(); ++i) {
18648dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                status_t err;
18658dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                if (!mPrograms.editItemAt(i)->parsePSISection(
18668dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                            PID, &sectionBits, &err)) {
18678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                    continue;
18688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                }
18698dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18708dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                if (err != OK) {
18718dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                    return err;
18728dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                }
18738dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18748dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                handled = true;
18758dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                break;
18768dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            }
18778dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18788dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            if (!handled) {
18798dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                mPSISections.removeItem(PID);
18804b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber                section.clear();
18818dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            }
18828dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        }
18838dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18844b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber        if (section != NULL) {
18854b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber            section->clear();
18864b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber        }
18878dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
188806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        return OK;
1889cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1890cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1891cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool handled = false;
1892cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (size_t i = 0; i < mPrograms.size(); ++i) {
189306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        status_t err;
1894cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (mPrograms.editItemAt(i)->parsePID(
18953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    PID, continuity_counter,
18963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    payload_unit_start_indicator,
18973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    transport_scrambling_control,
18983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    random_access_indicator,
1899540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                    br, &err, event)) {
190006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            if (err != OK) {
190106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber                return err;
190206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            }
190306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
1904cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            handled = true;
1905cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            break;
1906cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1907cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1908cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1909cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (!handled) {
19103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        handled = mCasManager->parsePID(br, PID);
19113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
19123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
19133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (!handled) {
19143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("PID 0x%04x not handled.", PID);
1915cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
191606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
191706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    return OK;
1918cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1919cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
19203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangstatus_t ATSParser::parseAdaptationField(
19213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader *br, unsigned PID, unsigned *random_access_indicator) {
19223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    *random_access_indicator = 0;
1923cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned adaptation_field_length = br->getBits(8);
192487f2a558dd12043631e12c361abef301bf603140Andreas Huber
1925cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (adaptation_field_length > 0) {
19268a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung        if (adaptation_field_length * 8 > br->numBitsLeft()) {
19278a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung            ALOGV("Adaptation field should be included in a single TS packet.");
19288a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung            return ERROR_MALFORMED;
19298a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung        }
19308a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung
193187f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned discontinuity_indicator = br->getBits(1);
193287f2a558dd12043631e12c361abef301bf603140Andreas Huber
193387f2a558dd12043631e12c361abef301bf603140Andreas Huber        if (discontinuity_indicator) {
193487f2a558dd12043631e12c361abef301bf603140Andreas Huber            ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID);
193587f2a558dd12043631e12c361abef301bf603140Andreas Huber        }
193687f2a558dd12043631e12c361abef301bf603140Andreas Huber
19373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        *random_access_indicator = br->getBits(1);
19383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (*random_access_indicator) {
19393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGV("PID 0x%04x: random_access_indicator = 1", PID);
19403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
19413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
19423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned elementary_stream_priority_indicator = br->getBits(1);
19433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (elementary_stream_priority_indicator) {
19443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGV("PID 0x%04x: elementary_stream_priority_indicator = 1", PID);
19453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
19463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
194787f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned PCR_flag = br->getBits(1);
194887f2a558dd12043631e12c361abef301bf603140Andreas Huber
194987f2a558dd12043631e12c361abef301bf603140Andreas Huber        size_t numBitsRead = 4;
195087f2a558dd12043631e12c361abef301bf603140Andreas Huber
195187f2a558dd12043631e12c361abef301bf603140Andreas Huber        if (PCR_flag) {
1952e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (adaptation_field_length * 8 < 52) {
1953e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1954e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
195587f2a558dd12043631e12c361abef301bf603140Andreas Huber            br->skipBits(4);
195687f2a558dd12043631e12c361abef301bf603140Andreas Huber            uint64_t PCR_base = br->getBits(32);
195787f2a558dd12043631e12c361abef301bf603140Andreas Huber            PCR_base = (PCR_base << 1) | br->getBits(1);
195887f2a558dd12043631e12c361abef301bf603140Andreas Huber
195987f2a558dd12043631e12c361abef301bf603140Andreas Huber            br->skipBits(6);
196087f2a558dd12043631e12c361abef301bf603140Andreas Huber            unsigned PCR_ext = br->getBits(9);
196187f2a558dd12043631e12c361abef301bf603140Andreas Huber
196287f2a558dd12043631e12c361abef301bf603140Andreas Huber            // The number of bytes from the start of the current
196387f2a558dd12043631e12c361abef301bf603140Andreas Huber            // MPEG2 transport stream packet up and including
196487f2a558dd12043631e12c361abef301bf603140Andreas Huber            // the final byte of this PCR_ext field.
196587f2a558dd12043631e12c361abef301bf603140Andreas Huber            size_t byteOffsetFromStartOfTSPacket =
196687f2a558dd12043631e12c361abef301bf603140Andreas Huber                (188 - br->numBitsLeft() / 8);
196787f2a558dd12043631e12c361abef301bf603140Andreas Huber
196887f2a558dd12043631e12c361abef301bf603140Andreas Huber            uint64_t PCR = PCR_base * 300 + PCR_ext;
196987f2a558dd12043631e12c361abef301bf603140Andreas Huber
1970b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross            ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)",
197187f2a558dd12043631e12c361abef301bf603140Andreas Huber                  PID, PCR, PCR / 27E6);
197287f2a558dd12043631e12c361abef301bf603140Andreas Huber
197387f2a558dd12043631e12c361abef301bf603140Andreas Huber            // The number of bytes received by this parser up to and
197487f2a558dd12043631e12c361abef301bf603140Andreas Huber            // including the final byte of this PCR_ext field.
197519cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen            uint64_t byteOffsetFromStart =
197619cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen                uint64_t(mNumTSPacketsParsed) * 188 + byteOffsetFromStartOfTSPacket;
197787f2a558dd12043631e12c361abef301bf603140Andreas Huber
197887f2a558dd12043631e12c361abef301bf603140Andreas Huber            for (size_t i = 0; i < mPrograms.size(); ++i) {
197987f2a558dd12043631e12c361abef301bf603140Andreas Huber                updatePCR(PID, PCR, byteOffsetFromStart);
198087f2a558dd12043631e12c361abef301bf603140Andreas Huber            }
198187f2a558dd12043631e12c361abef301bf603140Andreas Huber
198287f2a558dd12043631e12c361abef301bf603140Andreas Huber            numBitsRead += 52;
198387f2a558dd12043631e12c361abef301bf603140Andreas Huber        }
198487f2a558dd12043631e12c361abef301bf603140Andreas Huber
198587f2a558dd12043631e12c361abef301bf603140Andreas Huber        br->skipBits(adaptation_field_length * 8 - numBitsRead);
1986cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1987e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    return OK;
1988cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1989cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1990540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::parseTS(ABitReader *br, SyncEvent *event) {
19913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("---");
1992cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1993cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned sync_byte = br->getBits(8);
19946456ae745e919085c5024f784aaa2703f9695f98David Yeh    if (sync_byte != 0x47u) {
19956456ae745e919085c5024f784aaa2703f9695f98David Yeh        ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte);
19966456ae745e919085c5024f784aaa2703f9695f98David Yeh        return BAD_VALUE;
19976456ae745e919085c5024f784aaa2703f9695f98David Yeh    }
1998cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
199952668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber    if (br->getBits(1)) {  // transport_error_indicator
200052668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber        // silently ignore.
200152668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber        return OK;
200252668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber    }
2003cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2004cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned payload_unit_start_indicator = br->getBits(1);
20053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator);
2006cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20076e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("transport_priority = %u", br->getBits(1));
2008cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2009cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned PID = br->getBits(13);
20103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("PID = 0x%04x", PID);
2011cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    unsigned transport_scrambling_control = br->getBits(2);
20133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("transport_scrambling_control = %u", transport_scrambling_control);
2014cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2015cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned adaptation_field_control = br->getBits(2);
20163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("adaptation_field_control = %u", adaptation_field_control);
2017cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned continuity_counter = br->getBits(4);
201987f2a558dd12043631e12c361abef301bf603140Andreas Huber    ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
20200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2021df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
2022cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
202387f2a558dd12043631e12c361abef301bf603140Andreas Huber    status_t err = OK;
202487f2a558dd12043631e12c361abef301bf603140Andreas Huber
20253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    unsigned random_access_indicator = 0;
2026e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (adaptation_field_control == 2 || adaptation_field_control == 3) {
20273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        err = parseAdaptationField(br, PID, &random_access_indicator);
2028e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
2029e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (err == OK) {
2030e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (adaptation_field_control == 1 || adaptation_field_control == 3) {
2031540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            err = parsePID(br, PID, continuity_counter,
20323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    payload_unit_start_indicator,
20333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    transport_scrambling_control,
20343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    random_access_indicator,
20353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    event);
2036e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
2037cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
203806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
203987f2a558dd12043631e12c361abef301bf603140Andreas Huber    ++mNumTSPacketsParsed;
204087f2a558dd12043631e12c361abef301bf603140Andreas Huber
204187f2a558dd12043631e12c361abef301bf603140Andreas Huber    return err;
2042cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
2043cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2044cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> ATSParser::getSource(SourceType type) {
20459ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih    sp<MediaSource> firstSourceFound;
2046cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (size_t i = 0; i < mPrograms.size(); ++i) {
2047386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        const sp<Program> &program = mPrograms.editItemAt(i);
20489ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        sp<MediaSource> source = program->getSource(type);
20499ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        if (source == NULL) {
2050386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            continue;
2051386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
20529ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        if (firstSourceFound == NULL) {
20539ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            firstSourceFound = source;
20549ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        }
20559ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        // Prefer programs with both audio/video
20569ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        switch (type) {
20579ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            case VIDEO: {
20589ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                if (program->hasSource(AUDIO)) {
20599ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                    return source;
20609ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                }
20619ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                break;
20629ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            }
2063386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
20649ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            case AUDIO: {
20659ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                if (program->hasSource(VIDEO)) {
20669ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                    return source;
20679ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                }
20689ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                break;
20699ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            }
2070cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20719ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            default:
20729ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                return source;
2073cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
2074cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
2075cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20769ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih    return firstSourceFound;
2077cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
2078cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2079bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shihbool ATSParser::hasSource(SourceType type) const {
2080bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    for (size_t i = 0; i < mPrograms.size(); ++i) {
2081bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        const sp<Program> &program = mPrograms.itemAt(i);
2082bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        if (program->hasSource(type)) {
2083bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih            return true;
2084bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        }
2085bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    }
2086bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
2087bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    return false;
2088bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih}
2089bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
209043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huberbool ATSParser::PTSTimeDeltaEstablished() {
209143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mPrograms.isEmpty()) {
209243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        return false;
209343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
209443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
209543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished();
209643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
209743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
209882e147049625a4cfdcb228a1de7efda594d446c9Robert Shihint64_t ATSParser::getFirstPTSTimeUs() {
209982e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    for (size_t i = 0; i < mPrograms.size(); ++i) {
210082e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        sp<ATSParser::Program> program = mPrograms.itemAt(i);
210182e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        if (program->PTSTimeDeltaEstablished()) {
210282e147049625a4cfdcb228a1de7efda594d446c9Robert Shih            return (program->firstPTS() * 100) / 9;
210382e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        }
210482e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    }
210582e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    return -1;
210682e147049625a4cfdcb228a1de7efda594d446c9Robert Shih}
210782e147049625a4cfdcb228a1de7efda594d446c9Robert Shih
2108c9fa35cf7c9c11a8acb77128db1a6a13f1befe3cChad Brubaker__attribute__((no_sanitize("integer")))
210987f2a558dd12043631e12c361abef301bf603140Andreas Hubervoid ATSParser::updatePCR(
211019cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen        unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
211119cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen    ALOGV("PCR 0x%016" PRIx64 " @ %" PRIx64, PCR, byteOffsetFromStart);
211287f2a558dd12043631e12c361abef301bf603140Andreas Huber
211387f2a558dd12043631e12c361abef301bf603140Andreas Huber    if (mNumPCRs == 2) {
211487f2a558dd12043631e12c361abef301bf603140Andreas Huber        mPCR[0] = mPCR[1];
211587f2a558dd12043631e12c361abef301bf603140Andreas Huber        mPCRBytes[0] = mPCRBytes[1];
211687f2a558dd12043631e12c361abef301bf603140Andreas Huber        mSystemTimeUs[0] = mSystemTimeUs[1];
211787f2a558dd12043631e12c361abef301bf603140Andreas Huber        mNumPCRs = 1;
211887f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
211987f2a558dd12043631e12c361abef301bf603140Andreas Huber
212087f2a558dd12043631e12c361abef301bf603140Andreas Huber    mPCR[mNumPCRs] = PCR;
212187f2a558dd12043631e12c361abef301bf603140Andreas Huber    mPCRBytes[mNumPCRs] = byteOffsetFromStart;
212287f2a558dd12043631e12c361abef301bf603140Andreas Huber    mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs();
212387f2a558dd12043631e12c361abef301bf603140Andreas Huber
212487f2a558dd12043631e12c361abef301bf603140Andreas Huber    ++mNumPCRs;
212587f2a558dd12043631e12c361abef301bf603140Andreas Huber
212687f2a558dd12043631e12c361abef301bf603140Andreas Huber    if (mNumPCRs == 2) {
2127c9fa35cf7c9c11a8acb77128db1a6a13f1befe3cChad Brubaker        /* Unsigned overflow here */
212887f2a558dd12043631e12c361abef301bf603140Andreas Huber        double transportRate =
212987f2a558dd12043631e12c361abef301bf603140Andreas Huber            (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]);
213087f2a558dd12043631e12c361abef301bf603140Andreas Huber
213187f2a558dd12043631e12c361abef301bf603140Andreas Huber        ALOGV("transportRate = %.2f bytes/sec", transportRate);
213287f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
213387f2a558dd12043631e12c361abef301bf603140Andreas Huber}
213487f2a558dd12043631e12c361abef301bf603140Andreas Huber
21358dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber////////////////////////////////////////////////////////////////////////////////
21368dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
21379ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
21389ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// CRC32 used for PSI section. The table was generated by following command:
21399ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// $ python pycrc.py --model crc-32-mpeg --algorithm table-driven --generate c
21409ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// Visit http://www.tty1.net/pycrc/index_en.html for more details.
21419ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimuint32_t ATSParser::PSISection::CRC_TABLE[] = {
21429ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
21439ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
21449ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
21459ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
21469ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
21479ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
21489ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
21499ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
21509ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
21519ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
21529ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
21539ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
21549ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
21559ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
21569ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
21579ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
21589ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
21599ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
21609ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
21619ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
21629ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
21639ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
21649ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
21659ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
21669ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
21679ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
21689ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
21699ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
21709ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
21719ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
21729ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
21739ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
21749ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
21759ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
21769ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
21779ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
21789ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
21799ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
21809ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
21819ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
21829ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
21839ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
21849ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
21859ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
21869ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
21879ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
21889ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
21899ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
21909ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
21919ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
21929ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
21939ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
21949ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
21959ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
21969ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
21979ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
21989ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
21999ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
22009ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
22019ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
22029ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
22039ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
22049ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
22059ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
22069ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    };
22079ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22089ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk KimATSParser::PSISection::PSISection() :
22099ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    mSkipBytes(0) {
22108dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22118dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22128dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas HuberATSParser::PSISection::~PSISection() {
22138dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22148dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22158dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberstatus_t ATSParser::PSISection::append(const void *data, size_t size) {
22168dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) {
22178dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        size_t newCapacity =
22188dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            (mBuffer == NULL) ? size : mBuffer->capacity() + size;
22198dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22208dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        newCapacity = (newCapacity + 1023) & ~1023;
22218dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22228dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        sp<ABuffer> newBuffer = new ABuffer(newCapacity);
22238dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22248dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        if (mBuffer != NULL) {
22258dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
22268dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            newBuffer->setRange(0, mBuffer->size());
22278dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        } else {
22288dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            newBuffer->setRange(0, 0);
22298dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        }
22308dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22318dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        mBuffer = newBuffer;
22328dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
22338dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22348dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    memcpy(mBuffer->data() + mBuffer->size(), data, size);
22358dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    mBuffer->setRange(0, mBuffer->size() + size);
22368dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22378dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return OK;
22388dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22398dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22409ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimvoid ATSParser::PSISection::setSkipBytes(uint8_t skip) {
22419ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    mSkipBytes = skip;
22429ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim}
22439ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22448dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Hubervoid ATSParser::PSISection::clear() {
22458dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (mBuffer != NULL) {
22468dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        mBuffer->setRange(0, 0);
22478dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
22489ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    mSkipBytes = 0;
22498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22508dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22518dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::PSISection::isComplete() const {
22528dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (mBuffer == NULL || mBuffer->size() < 3) {
22538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        return false;
22548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
22558dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff;
22578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return mBuffer->size() >= sectionLength + 3;
22588dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22608dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::PSISection::isEmpty() const {
22618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return mBuffer == NULL || mBuffer->size() == 0;
22628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22638dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22648dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberconst uint8_t *ATSParser::PSISection::data() const {
22658dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return mBuffer == NULL ? NULL : mBuffer->data();
22668dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Hubersize_t ATSParser::PSISection::size() const {
22698dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return mBuffer == NULL ? 0 : mBuffer->size();
22708dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22718dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22729ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimbool ATSParser::PSISection::isCRCOkay() const {
22739ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    if (!isComplete()) {
22749ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        return false;
22759ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    }
22769ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    uint8_t* data = mBuffer->data();
22779ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22789ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    // Return true if section_syntax_indicator says no section follows the field section_length.
22799ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    if ((data[1] & 0x80) == 0) {
22809ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        return true;
22819ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    }
22829ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22839ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    unsigned sectionLength = U16_AT(data + 1) & 0xfff;
22849ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes);
22859ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
2286c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen
2287c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen    if(sectionLength < mSkipBytes) {
2288c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen        ALOGE("b/28333006");
2289c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen        android_errorWriteLog(0x534e4554, "28333006");
2290c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen        return false;
2291c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen    }
2292c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen
22939ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    // Skip the preceding field present when payload start indicator is on.
22949ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    sectionLength -= mSkipBytes;
22959ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22969ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    uint32_t crc = 0xffffffff;
22979ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    for(unsigned i = 0; i < sectionLength + 4 /* crc */; i++) {
22989ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        uint8_t b = data[i];
22999ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        int index = ((crc >> 24) ^ (b & 0xff)) & 0xff;
23009ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        crc = CRC_TABLE[index] ^ (crc << 8);
23019ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    }
23029ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    ALOGV("crc: %08x\n", crc);
23039ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    return (crc == 0);
23049ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim}
23053a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23063a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania// SAMPLE_AES key handling
23073a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania// TODO: Merge these to their respective class after Widevine-HLS
23083a37f3e948b600405e0c70b8a241778fda44168eHassan Shojaniavoid ATSParser::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
23093a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGD("signalNewSampleAesKey: %p", keyItem.get());
23103a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23113a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleAesKeyItem = keyItem;
23123a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23133a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // a NULL key item will propagate to existing ElementaryStreamQueues
23143a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    for (size_t i = 0; i < mPrograms.size(); ++i) {
23153a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        mPrograms[i]->signalNewSampleAesKey(keyItem);
23163a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    }
23173a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania}
23183a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23193a37f3e948b600405e0c70b8a241778fda44168eHassan Shojaniavoid ATSParser::Program::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
23203a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGD("Program::signalNewSampleAesKey: %p", keyItem.get());
23213a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23223a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleAesKeyItem = keyItem;
23233a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23243a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // a NULL key item will propagate to existing ElementaryStreamQueues
23253a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    for (size_t i = 0; i < mStreams.size(); ++i) {
23263a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        mStreams[i]->signalNewSampleAesKey(keyItem);
23273a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    }
23283a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania}
23293a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23303a37f3e948b600405e0c70b8a241778fda44168eHassan Shojaniavoid ATSParser::Stream::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
23313a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGD("Stream::signalNewSampleAesKey: 0x%04x size = %zu keyItem: %p",
23323a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania          mElementaryPID, mBuffer->size(), keyItem.get());
23333a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23343a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // a NULL key item will propagate to existing ElementaryStreamQueues
23353a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleAesKeyItem = keyItem;
23363a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23373a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    flush(NULL);
23383a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mQueue->signalNewSampleAesKey(keyItem);
23393a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania}
23403a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
2341cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}  // namespace android
2342