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>
2649ce671c4efa4c5d038351ca441e34c5afa5241fDongwon Kang#include <binder/IMemory.h>
2749ce671c4efa4c5d038351ca441e34c5afa5241fDongwon Kang#include <binder/MemoryDealer.h>
28d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang#include <cutils/native_handle.h>
2958ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang#include <hidlmemory/FrameworkUtils.h>
30d1af641a93f297ead1c9c00619cdb62f551b9086Chong Zhang#include <media/cas/DescramblerAPI.h>
3185f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include <media/stagefright/foundation/ABitReader.h>
32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/ADebug.h>
34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/AMessage.h>
35607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang#include <media/stagefright/foundation/ByteUtils.h>
3615d02f84351eaca14099bde11cfbf6f124bea71fDongwon Kang#include <media/stagefright/foundation/MediaKeys.h>
37d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang#include <media/stagefright/foundation/avc_utils.h>
38cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/hexdump.h>
39cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h>
40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h>
41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h>
4232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber#include <media/IStreamSource.h>
43cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/KeyedVector.h>
449bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang#include <utils/Vector.h>
45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
46b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross#include <inttypes.h>
47b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross
48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android {
4958ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhangusing hardware::fromHeap;
50d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_string;
51d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing hardware::hidl_vec;
5258ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhangusing hardware::HidlMemory;
53d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing namespace hardware::cas::V1_0;
54d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangusing namespace hardware::cas::native::V1_0;
55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
566e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber// I want the expression "y" evaluated even if verbose logging is off.
576e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define MY_LOGV(x, y) \
583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    do { unsigned tmp = y; ALOGV(x, tmp); } while (0)
596e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
60cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatic const size_t kTSPacketSize = 188;
61cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
62cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct ATSParser::Program : public RefBase {
63d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID,
64d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            int64_t lastRecoveredPTS);
65cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
668dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    bool parsePSISection(
678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            unsigned pid, ABitReader *br, status_t *err);
688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
69540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Pass to appropriate stream according to pid, and set event if it's a PES
70540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // with a sync frame.
71540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Note that the method itself does not touch event.
72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool parsePID(
7387f2a558dd12043631e12c361abef301bf603140Andreas Huber            unsigned pid, unsigned continuity_counter,
7487f2a558dd12043631e12c361abef301bf603140Andreas Huber            unsigned payload_unit_start_indicator,
753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned transport_scrambling_control,
763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned random_access_indicator,
77540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            ABitReader *br, status_t *err, SyncEvent *event);
78cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
7932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    void signalDiscontinuity(
8032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            DiscontinuityType type, const sp<AMessage> &extra);
8132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void signalEOS(status_t finalResult);
832a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
8445d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissen    sp<AnotherPacketSource> getSource(SourceType type);
85bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    bool hasSource(SourceType type) const;
86cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
87bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    int64_t convertPTSToTimestamp(uint64_t PTS);
88bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
8943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    bool PTSTimeDeltaEstablished() const {
9043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        return mFirstPTSValid;
9143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
9243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
93386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned number() const { return mProgramNumber; }
94386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
95386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    void updateProgramMapPID(unsigned programMapPID) {
96386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        mProgramMapPID = programMapPID;
97386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
98386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
998dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    unsigned programMapPID() const {
1008dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        return mProgramMapPID;
1018dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
1028dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
10387f2a558dd12043631e12c361abef301bf603140Andreas Huber    uint32_t parserFlags() const {
10487f2a558dd12043631e12c361abef301bf603140Andreas Huber        return mParser->mFlags;
10587f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
10687f2a558dd12043631e12c361abef301bf603140Andreas Huber
1073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<CasManager> casManager() const {
1083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return mParser->mCasManager;
1093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
1103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
11182e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    uint64_t firstPTS() const {
11282e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        return mFirstPTS;
11382e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    }
11482e147049625a4cfdcb228a1de7efda594d446c9Robert Shih
1153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    void updateCasSessions();
1163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1173a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    void signalNewSampleAesKey(const sp<AMessage> &keyItem);
1183a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate:
1209bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    struct StreamInfo {
1219bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        unsigned mType;
1229bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        unsigned mPID;
1233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t mCASystemId;
1249bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    };
1259bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ATSParser *mParser;
127386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    unsigned mProgramNumber;
128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned mProgramMapPID;
129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    KeyedVector<unsigned, sp<Stream> > mStreams;
130bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    bool mFirstPTSValid;
131bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    uint64_t mFirstPTS;
132799c9682b3776a55d234396aee4a302437150c26Chong Zhang    int64_t mLastRecoveredPTS;
1333a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    sp<AMessage> mSampleAesKeyItem;
134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
13506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    status_t parseProgramMap(ABitReader *br);
136799c9682b3776a55d234396aee4a302437150c26Chong Zhang    int64_t recoverPTS(uint64_t PTS_33bit);
1373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool findCADescriptor(
1383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ABitReader *br, unsigned infoLength, CADescriptor *caDescriptor);
1399bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    bool switchPIDs(const Vector<StreamInfo> &infos);
140cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
141cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Program);
142cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
143cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
144cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct ATSParser::Stream : public RefBase {
14587f2a558dd12043631e12c361abef301bf603140Andreas Huber    Stream(Program *program,
14687f2a558dd12043631e12c361abef301bf603140Andreas Huber           unsigned elementaryPID,
14787f2a558dd12043631e12c361abef301bf603140Andreas Huber           unsigned streamType,
1483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang           unsigned PCR_PID,
1493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang           int32_t CA_system_ID);
150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
151bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    unsigned type() const { return mStreamType; }
152bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    unsigned pid() const { return mElementaryPID; }
153bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    void setPID(unsigned pid) { mElementaryPID = pid; }
154bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
155bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang    void setCasInfo(
156bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            int32_t systemId,
1573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            const sp<IDescrambler> &descrambler,
1583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            const std::vector<uint8_t> &sessionId);
1593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
160540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Parse the payload and set event when PES with a sync frame is detected.
1619558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    // This method knows when a PES starts; so record mPesStartOffsets in that
162540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // case.
1635403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    status_t parse(
16487f2a558dd12043631e12c361abef301bf603140Andreas Huber            unsigned continuity_counter,
165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned payload_unit_start_indicator,
1663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned transport_scrambling_control,
1673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned random_access_indicator,
168540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            ABitReader *br,
169540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            SyncEvent *event);
170cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    void signalDiscontinuity(
17232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            DiscontinuityType type, const sp<AMessage> &extra);
17332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void signalEOS(status_t finalResult);
1752a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
17682e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    SourceType getSourceType();
17745d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissen    sp<AnotherPacketSource> getSource(SourceType type);
178cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
179bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    bool isAudio() const;
180bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    bool isVideo() const;
1810852843d304006e3ab333081fddda13b07193de8Robert Shih    bool isMeta() const;
182bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
1833a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    void signalNewSampleAesKey(const sp<AMessage> &keyItem);
1843a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
185cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprotected:
186cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    virtual ~Stream();
187cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
188cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate:
1893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    struct SubSampleInfo {
1903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        size_t subSampleSize;
1913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned transport_scrambling_mode;
1923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned random_access_indicator;
1933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    };
194bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    Program *mProgram;
195cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned mElementaryPID;
196cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned mStreamType;
19787f2a558dd12043631e12c361abef301bf603140Andreas Huber    unsigned mPCR_PID;
19887f2a558dd12043631e12c361abef301bf603140Andreas Huber    int32_t mExpectedContinuityCounter;
199cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
200cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<ABuffer> mBuffer;
201cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<AnotherPacketSource> mSource;
202cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool mPayloadStarted;
203be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    bool mEOSReached;
204cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    uint64_t mPrevPTS;
2069558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    List<off64_t> mPesStartOffsets;
20790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
208386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    ElementaryStreamQueue *mQueue;
2096a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber
2103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool mScrambled;
2113a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    bool mSampleEncrypted;
2123a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    sp<AMessage> mSampleAesKeyItem;
2133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<IMemory> mMem;
2143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<MemoryDealer> mDealer;
21558ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang    sp<HidlMemory> mHidlMemory;
216d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
2173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<ABuffer> mDescrambledBuffer;
2183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    List<SubSampleInfo> mSubSamples;
2193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<IDescrambler> mDescrambler;
2203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
221540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Flush accumulated payload if necessary --- i.e. at EOS or at the start of
222540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // another payload. event is set if the flushed payload is PES with a sync
223540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // frame.
224540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    status_t flush(SyncEvent *event);
2253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // Flush accumulated payload for scrambled streams if necessary --- i.e. at
2273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // EOS or at the start of another payload. event is set if the flushed
2283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // payload is PES with a sync frame.
2293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t flushScrambled(SyncEvent *event);
2303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // Check if a PES packet is scrambled at PES level.
2323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    uint32_t getPesScramblingControl(ABitReader *br, int32_t *pesOffset);
2333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
234540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Strip and parse PES headers and pass remaining payload into onPayload
235540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // with parsed metadata. event is set if the PES contains a sync frame.
236540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    status_t parsePES(ABitReader *br, SyncEvent *event);
237540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
238540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Feed the payload into mQueue and if a packet is identified, queue it
239540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // into mSource. If the packet is a sync frame. set event with start offset
240540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // and timestamp of the packet.
241cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    void onPayloadData(
242cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
2433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            unsigned PES_scrambling_control,
2443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            const uint8_t *data, size_t size,
2453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            int32_t payloadOffset, SyncEvent *event);
2463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
2473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // Ensure internal buffers can hold specified size, and will re-allocate
2483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // as needed.
249d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    bool ensureBufferCapacity(size_t size);
25082f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
251cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Stream);
252cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
253cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberstruct ATSParser::PSISection : public RefBase {
2558dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    PSISection();
2568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    status_t append(const void *data, size_t size);
2589ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    void setSkipBytes(uint8_t skip);
2598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    void clear();
2608dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    bool isComplete() const;
2628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    bool isEmpty() const;
2639ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    bool isCRCOkay() const;
2648dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2658dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    const uint8_t *data() const;
2668dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    size_t size() const;
2678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberprotected:
2698dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    virtual ~PSISection();
2708dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2718dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberprivate:
2728dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    sp<ABuffer> mBuffer;
2739ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    uint8_t mSkipBytes;
2749ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    static uint32_t CRC_TABLE[];
2758dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
2768dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(PSISection);
2778dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber};
2788dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
279540006666b4191cd78391378f1c66c21bcf0c4cdWonsik KimATSParser::SyncEvent::SyncEvent(off64_t offset)
2809558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    : mHasReturnedData(false), mOffset(offset), mTimeUs(0) {}
281540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
28245d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissenvoid ATSParser::SyncEvent::init(off64_t offset, const sp<AnotherPacketSource> &source,
28382e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        int64_t timeUs, SourceType type) {
2849558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    mHasReturnedData = true;
285540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    mOffset = offset;
286540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    mMediaSource = source;
287540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    mTimeUs = timeUs;
28882e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    mType = type;
289540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim}
290540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
2919558f6dd733dc450270f38b9a139d384d273ce0aWei Jiavoid ATSParser::SyncEvent::reset() {
2929558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    mHasReturnedData = false;
2939558f6dd733dc450270f38b9a139d384d273ce0aWei Jia}
294cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
295cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
296386d609dc513e838c7e7c4c46c604493ccd560beAndreas HuberATSParser::Program::Program(
297d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        ATSParser *parser, unsigned programNumber, unsigned programMapPID,
298d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        int64_t lastRecoveredPTS)
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : mParser(parser),
300386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber      mProgramNumber(programNumber),
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mProgramMapPID(programMapPID),
302bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber      mFirstPTSValid(false),
303799c9682b3776a55d234396aee4a302437150c26Chong Zhang      mFirstPTS(0),
304d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang      mLastRecoveredPTS(lastRecoveredPTS) {
3053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("new program number %u", programNumber);
306cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
307cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
3088dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::Program::parsePSISection(
3098dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        unsigned pid, ABitReader *br, status_t *err) {
31006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    *err = OK;
31106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
3128dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (pid != mProgramMapPID) {
3138dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        return false;
3148dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
315cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
3168dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    *err = parseProgramMap(br);
31706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
3188dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return true;
3198dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
3208dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
3218dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::Program::parsePID(
32287f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned pid, unsigned continuity_counter,
32387f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned payload_unit_start_indicator,
3243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned transport_scrambling_control,
3253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned random_access_indicator,
326540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        ABitReader *br, status_t *err, SyncEvent *event) {
3278dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    *err = OK;
328cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
329cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    ssize_t index = mStreams.indexOfKey(pid);
330cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (index < 0) {
331cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        return false;
332cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
333cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
3345403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    *err = mStreams.editValueAt(index)->parse(
3353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            continuity_counter,
3363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            payload_unit_start_indicator,
3373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            transport_scrambling_control,
3383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            random_access_indicator,
3393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            br, event);
340cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
341cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return true;
342cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
343cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
34432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::Program::signalDiscontinuity(
34532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        DiscontinuityType type, const sp<AMessage> &extra) {
346b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    int64_t mediaTimeUs;
347b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    if ((type & DISCONTINUITY_TIME)
348b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            && extra != NULL
349b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber            && extra->findInt64(
35015d02f84351eaca14099bde11cfbf6f124bea71fDongwon Kang                kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
351b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber        mFirstPTSValid = false;
352b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    }
353b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber
3542a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    for (size_t i = 0; i < mStreams.size(); ++i) {
35532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        mStreams.editValueAt(i)->signalDiscontinuity(type, extra);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::Program::signalEOS(status_t finalResult) {
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mStreams.size(); ++i) {
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mStreams.editValueAt(i)->signalEOS(finalResult);
3622a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    }
3632a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber}
3642a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
3659bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhangbool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) {
3669bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    bool success = false;
3679bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3689bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    if (mStreams.size() == infos.size()) {
3699bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // build type->PIDs map for old and new mapping
3709bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        size_t i;
3719bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs;
3729bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        for (i = 0; i < mStreams.size(); ++i) {
3739bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type());
3749bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            if (index < 0) {
3759bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>());
3769bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
3779bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid());
3789bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
3799bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        for (i = 0; i < infos.size(); ++i) {
3809bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            ssize_t index = newType2PIDs.indexOfKey(infos[i].mType);
3819bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            if (index < 0) {
3829bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                newType2PIDs.add(infos[i].mType, Vector<int32_t>());
3839bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
3849bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID);
3859bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
3869bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
3879bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // we can recover if the number of streams for each type hasn't changed
3889bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        if (oldType2PIDs.size() == newType2PIDs.size()) {
3899bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            success = true;
3909bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            for (i = 0; i < oldType2PIDs.size(); ++i) {
3919bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // KeyedVector is sorted, we just compare key and size of each index
3929bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i)
3939bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                        || oldType2PIDs[i].size() != newType2PIDs[i].size()) {
3949bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     success = false;
3959bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                     break;
3969bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                }
3979bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
3989bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
3999bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4009bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        if (success) {
4019bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            // save current streams to temp
4029bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            KeyedVector<int32_t, sp<Stream> > temp;
4039bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            for (i = 0; i < mStreams.size(); ++i) {
4049bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                 temp.add(mStreams.keyAt(i), mStreams.editValueAt(i));
4059bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
4069bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4079bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            mStreams.clear();
4089bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            for (i = 0; i < temp.size(); ++i) {
4099bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // The two checks below shouldn't happen,
4109bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // we already checked above the stream count matches
4119bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
412e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (index < 0) {
413e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return false;
414e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
4159bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
416e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (newPIDs.isEmpty()) {
417e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return false;
418e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
4199bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4209bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // get the next PID for temp[i]->type() in the new PID map
4219bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                Vector<int32_t>::iterator it = newPIDs.begin();
4229bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4239bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // change the PID of the stream, and add it back
4249bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                temp.editValueAt(i)->setPID(*it);
4259bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                mStreams.add(temp[i]->pid(), temp.editValueAt(i));
4269bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
4279bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                // removed the used PID
4289bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                newPIDs.erase(it);
4299bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            }
4309bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
4319bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    }
4329bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    return success;
4339bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang}
434bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
4353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangbool ATSParser::Program::findCADescriptor(
4363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader *br, unsigned infoLength,
4373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ATSParser::CADescriptor *caDescriptor) {
4383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool found = false;
4393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    while (infoLength > 2) {
4403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned descriptor_tag = br->getBits(8);
4413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("      tag = 0x%02x", descriptor_tag);
4423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned descriptor_length = br->getBits(8);
4443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("      len = %u", descriptor_length);
4453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
4463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        infoLength -= 2;
4473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (descriptor_length > infoLength) {
4483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            break;
4493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
4503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (descriptor_tag == 9 && descriptor_length >= 4) {
4513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            found = true;
4523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            caDescriptor->mSystemID = br->getBits(16);
4533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            caDescriptor->mPID = br->getBits(16) & 0x1fff;
4543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            infoLength -= 4;
4553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            caDescriptor->mPrivateData.assign(
4563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    br->data(), br->data() + descriptor_length - 4);
4573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            break;
4583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        } else {
4593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            infoLength -= descriptor_length;
4603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            br->skipBits(descriptor_length * 8);
4613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
4623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
4633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    br->skipBits(infoLength * 8);
4643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return found;
4653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
4663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
46706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huberstatus_t ATSParser::Program::parseProgramMap(ABitReader *br) {
468cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned table_id = br->getBits(8);
4693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  table_id = %u", table_id);
4706456ae745e919085c5024f784aaa2703f9695f98David Yeh    if (table_id != 0x02u) {
4716456ae745e919085c5024f784aaa2703f9695f98David Yeh        ALOGE("PMT data error!");
4726456ae745e919085c5024f784aaa2703f9695f98David Yeh        return ERROR_MALFORMED;
4736456ae745e919085c5024f784aaa2703f9695f98David Yeh    }
4746e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    unsigned section_syntax_indicator = br->getBits(1);
4753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  section_syntax_indicator = %u", section_syntax_indicator);
4766456ae745e919085c5024f784aaa2703f9695f98David Yeh    if (section_syntax_indicator != 1u) {
4776456ae745e919085c5024f784aaa2703f9695f98David Yeh        ALOGE("PMT data error!");
4786456ae745e919085c5024f784aaa2703f9695f98David Yeh        return ERROR_MALFORMED;
4796456ae745e919085c5024f784aaa2703f9695f98David Yeh    }
480cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
481e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    br->skipBits(1);  // '0'
4826e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(2));
483cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
484cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned section_length = br->getBits(12);
4853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  section_length = %u", section_length);
486cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
4876e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  program_number = %u", br->getBits(16));
4886e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(2));
4896e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  version_number = %u", br->getBits(5));
4906e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
4916e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  section_number = %u", br->getBits(8));
4926e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  last_section_number = %u", br->getBits(8));
4936e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(3));
49487f2a558dd12043631e12c361abef301bf603140Andreas Huber
49587f2a558dd12043631e12c361abef301bf603140Andreas Huber    unsigned PCR_PID = br->getBits(13);
49687f2a558dd12043631e12c361abef301bf603140Andreas Huber    ALOGV("  PCR_PID = 0x%04x", PCR_PID);
49787f2a558dd12043631e12c361abef301bf603140Andreas Huber
4986e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(4));
499cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
500cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned program_info_length = br->getBits(12);
5013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  program_info_length = %u", program_info_length);
502cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
5033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // descriptors
5043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    CADescriptor programCA;
5053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool hasProgramCA = findCADescriptor(br, program_info_length, &programCA);
5063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (hasProgramCA && !mParser->mCasManager->addProgram(
5073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mProgramNumber, programCA)) {
5083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return ERROR_MALFORMED;
5093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
510cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
511bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    Vector<StreamInfo> infos;
512bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
513cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    // infoBytesRemaining is the number of bytes that make up the
514cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    // variable length section of ES_infos. It does not include the
515cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    // final CRC.
516cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    size_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
517cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
518e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    while (infoBytesRemaining >= 5) {
519cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
520cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned streamType = br->getBits(8);
5213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("    stream_type = 0x%02x", streamType);
522cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
5236e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("    reserved = %u", br->getBits(3));
524cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
525cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned elementaryPID = br->getBits(13);
5263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("    elementary_PID = 0x%04x", elementaryPID);
527cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
5286e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("    reserved = %u", br->getBits(4));
529cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
530cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned ES_info_length = br->getBits(12);
5313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("    ES_info_length = %u", ES_info_length);
532cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
5333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        CADescriptor streamCA;
5343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        bool hasStreamCA = findCADescriptor(br, ES_info_length, &streamCA);
5353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (hasStreamCA && !mParser->mCasManager->addStream(
5363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mProgramNumber, elementaryPID, streamCA)) {
5373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return ERROR_MALFORMED;
538cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
539bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        StreamInfo info;
540bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        info.mType = streamType;
541bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        info.mPID = elementaryPID;
5423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        info.mCASystemId = hasProgramCA ? programCA.mSystemID :
5433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                           hasStreamCA ? streamCA.mSystemID  : -1;
544bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        infos.push(info);
545cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
546cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        infoBytesRemaining -= 5 + ES_info_length;
547cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
548cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
549e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (infoBytesRemaining != 0) {
550e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGW("Section data remains unconsumed");
551e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
5526e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
553bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
554bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    bool PIDsChanged = false;
555bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    for (size_t i = 0; i < infos.size(); ++i) {
556bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        StreamInfo &info = infos.editItemAt(i);
557bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
558bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        ssize_t index = mStreams.indexOfKey(info.mPID);
559bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
560bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
561df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("uh oh. stream PIDs have changed.");
562bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber            PIDsChanged = true;
563bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber            break;
564bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        }
565bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    }
566bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
567bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    if (PIDsChanged) {
56806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber#if 0
569df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("before:");
57006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        for (size_t i = 0; i < mStreams.size(); ++i) {
57106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            sp<Stream> stream = mStreams.editValueAt(i);
57206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
573df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type());
57406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        }
57506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
576df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("after:");
57706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        for (size_t i = 0; i < infos.size(); ++i) {
57806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            StreamInfo &info = infos.editItemAt(i);
57906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
580df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType);
58106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        }
58206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber#endif
58306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
5849bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // we can recover if number of streams for each type remain the same
5859bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        bool success = switchPIDs(infos);
58606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
58706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        if (!success) {
588df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block            ALOGI("Stream PIDs changed and we cannot recover.");
58906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            return ERROR_MALFORMED;
59006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        }
591bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    }
592bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
5933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    bool isAddingScrambledStream = false;
594bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    for (size_t i = 0; i < infos.size(); ++i) {
595bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        StreamInfo &info = infos.editItemAt(i);
596bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
5973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mParser->mCasManager->isCAPid(info.mPID)) {
5983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // skip CA streams (EMM/ECM)
5993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            continue;
6003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
601bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        ssize_t index = mStreams.indexOfKey(info.mPID);
602bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
603bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        if (index < 0) {
60487f2a558dd12043631e12c361abef301bf603140Andreas Huber            sp<Stream> stream = new Stream(
6053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    this, info.mPID, info.mType, PCR_PID, info.mCASystemId);
60687f2a558dd12043631e12c361abef301bf603140Andreas Huber
6073a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            if (mSampleAesKeyItem != NULL) {
6083a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                stream->signalNewSampleAesKey(mSampleAesKeyItem);
6093a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            }
6103a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
6113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            isAddingScrambledStream |= info.mCASystemId >= 0;
612bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber            mStreams.add(info.mPID, stream);
613bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber        }
614bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    }
61506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
6163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (isAddingScrambledStream) {
6173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGI("Receiving scrambled streams without descrambler!");
6183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
6193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
62006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    return OK;
621cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
622cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
623799c9682b3776a55d234396aee4a302437150c26Chong Zhangint64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
624799c9682b3776a55d234396aee4a302437150c26Chong Zhang    // We only have the lower 33-bit of the PTS. It could overflow within a
625799c9682b3776a55d234396aee4a302437150c26Chong Zhang    // reasonable amount of time. To handle the wrap-around, use fancy math
626799c9682b3776a55d234396aee4a302437150c26Chong Zhang    // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
627799c9682b3776a55d234396aee4a302437150c26Chong Zhang    // of the latest recovered PTS.
6289bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    if (mLastRecoveredPTS < 0ll) {
6299bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // Use the original 33bit number for 1st frame, the reason is that
6309bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // if 1st frame wraps to negative that's far away from 0, we could
6319bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // never start. Only start wrapping around from 2nd frame.
6329bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
6339bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    } else {
6349bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        mLastRecoveredPTS = static_cast<int64_t>(
6353728ba367f1e23e652c5539d9488aa0d0d4ec9d7Chad Brubaker                ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000ll)
6369bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                & 0xfffffffe00000000ull) | PTS_33bit);
6379bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // We start from 0, but recovered PTS could be slightly below 0.
6389bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
6399bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
6409bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        if (mLastRecoveredPTS < 0ll) {
6415c9054bc6efc080b265e028f2ebb1abd2a2e3953Chih-Hung Hsieh            ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS);
6429bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang            mLastRecoveredPTS = 0ll;
6439bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang        }
6449bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    }
6459bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang
6469bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang    return mLastRecoveredPTS;
647799c9682b3776a55d234396aee4a302437150c26Chong Zhang}
648799c9682b3776a55d234396aee4a302437150c26Chong Zhang
64945d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissensp<AnotherPacketSource> ATSParser::Program::getSource(SourceType type) {
650cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (size_t i = 0; i < mStreams.size(); ++i) {
65145d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissen        sp<AnotherPacketSource> source = mStreams.editValueAt(i)->getSource(type);
652cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (source != NULL) {
6539ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            return source;
654cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
655cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
656cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
657cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return NULL;
658cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
659cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
660bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shihbool ATSParser::Program::hasSource(SourceType type) const {
661bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    for (size_t i = 0; i < mStreams.size(); ++i) {
662bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        const sp<Stream> &stream = mStreams.valueAt(i);
663bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        if (type == AUDIO && stream->isAudio()) {
664bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih            return true;
665bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        } else if (type == VIDEO && stream->isVideo()) {
666bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih            return true;
6679ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        } else if (type == META && stream->isMeta()) {
6689ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            return true;
669bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        }
670bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    }
671bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
672bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    return false;
673bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih}
674bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
675bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberint64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
676799c9682b3776a55d234396aee4a302437150c26Chong Zhang    PTS = recoverPTS(PTS);
677799c9682b3776a55d234396aee4a302437150c26Chong Zhang
678c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber    if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
679c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        if (!mFirstPTSValid) {
680c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            mFirstPTSValid = true;
681c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            mFirstPTS = PTS;
682c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            PTS = 0;
683c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        } else if (PTS < mFirstPTS) {
684c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            PTS = 0;
685c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        } else {
686c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber            PTS -= mFirstPTS;
687c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        }
688bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
689bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
69087f2a558dd12043631e12c361abef301bf603140Andreas Huber    int64_t timeUs = (PTS * 100) / 9;
69187f2a558dd12043631e12c361abef301bf603140Andreas Huber
69287f2a558dd12043631e12c361abef301bf603140Andreas Huber    if (mParser->mAbsoluteTimeAnchorUs >= 0ll) {
69387f2a558dd12043631e12c361abef301bf603140Andreas Huber        timeUs += mParser->mAbsoluteTimeAnchorUs;
69487f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
69587f2a558dd12043631e12c361abef301bf603140Andreas Huber
696d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    if (mParser->mTimeOffsetValid) {
697d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        timeUs += mParser->mTimeOffsetUs;
698d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    }
699d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
70087f2a558dd12043631e12c361abef301bf603140Andreas Huber    return timeUs;
701bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber}
702bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
7033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangvoid ATSParser::Program::updateCasSessions() {
7043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    for (size_t i = 0; i < mStreams.size(); ++i) {
7053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<Stream> &stream = mStreams.editValueAt(i);
7063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<IDescrambler> descrambler;
7073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        std::vector<uint8_t> sessionId;
708bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang        int32_t systemId;
709bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang        if (mParser->mCasManager->getCasInfo(mProgramNumber, stream->pid(),
710bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang                &systemId, &descrambler, &sessionId)) {
711bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            stream->setCasInfo(systemId, descrambler, sessionId);
7123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
7133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
7143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
7153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
716cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
7173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangstatic const size_t kInitialStreamBufferSize = 192 * 1024;
718cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
719bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas HuberATSParser::Stream::Stream(
72087f2a558dd12043631e12c361abef301bf603140Andreas Huber        Program *program,
72187f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned elementaryPID,
72287f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned streamType,
7233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PCR_PID,
7243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t CA_system_ID)
725bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    : mProgram(program),
726bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber      mElementaryPID(elementaryPID),
727cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mStreamType(streamType),
72887f2a558dd12043631e12c361abef301bf603140Andreas Huber      mPCR_PID(PCR_PID),
72987f2a558dd12043631e12c361abef301bf603140Andreas Huber      mExpectedContinuityCounter(-1),
7306a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber      mPayloadStarted(false),
731be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen      mEOSReached(false),
73290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mPrevPTS(0),
7333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang      mQueue(NULL),
7343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang      mScrambled(CA_system_ID >= 0) {
7353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
7363a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleEncrypted =
7373a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mStreamType == STREAMTYPE_H264_ENCRYPTED ||
7383a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mStreamType == STREAMTYPE_AAC_ENCRYPTED  ||
7393a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mStreamType == STREAMTYPE_AC3_ENCRYPTED;
7403a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
7413a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGV("new stream PID 0x%02x, type 0x%02x, scrambled %d, SampleEncrypted: %d",
7423a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            elementaryPID, streamType, mScrambled, mSampleEncrypted);
7433a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
7443a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    uint32_t flags =
7453a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            (isVideo() && mScrambled) ? ElementaryStreamQueue::kFlag_ScrambledData :
7463a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            (mSampleEncrypted) ? ElementaryStreamQueue::kFlag_SampleEncryptedData :
7473a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            0;
7483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
7493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ElementaryStreamQueue::Mode mode = ElementaryStreamQueue::INVALID;
7503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
751386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    switch (mStreamType) {
752386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_H264:
7533a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_H264_ENCRYPTED:
7543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::H264;
7553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            flags |= (mProgram->parserFlags() & ALIGNED_VIDEO_DATA) ?
7563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    ElementaryStreamQueue::kFlag_AlignedData : 0;
757386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
7583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
7596e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG2_AUDIO_ADTS:
7603a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_AAC_ENCRYPTED:
7613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::AAC;
762386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
7633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
764386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG1_AUDIO:
765386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG2_AUDIO:
7663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::MPEG_AUDIO;
767386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
768386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
769386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG1_VIDEO:
770386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG2_VIDEO:
7713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::MPEG_VIDEO;
772386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
773386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
774386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case STREAMTYPE_MPEG4_VIDEO:
7753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::MPEG4_VIDEO;
776386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
777386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
7789bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang        case STREAMTYPE_LPCM_AC3:
779d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu        case STREAMTYPE_AC3:
7803a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_AC3_ENCRYPTED:
7813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::AC3;
782d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu            break;
783d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu
7840852843d304006e3ab333081fddda13b07193de8Robert Shih        case STREAMTYPE_METADATA:
7853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mode = ElementaryStreamQueue::METADATA;
7860852843d304006e3ab333081fddda13b07193de8Robert Shih            break;
7870852843d304006e3ab333081fddda13b07193de8Robert Shih
788386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        default:
7893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGE("stream PID 0x%02x has invalid stream type 0x%02x",
7903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    elementaryPID, streamType);
7913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return;
792386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
793386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
7943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mQueue = new ElementaryStreamQueue(mode, flags);
79518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
79618ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (mQueue != NULL) {
7973a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        if (mSampleAesKeyItem != NULL) {
7983a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania            mQueue->signalNewSampleAesKey(mSampleAesKeyItem);
7993a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        }
8003a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
8013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ensureBufferCapacity(kInitialStreamBufferSize);
8023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mScrambled && (isAudio() || isVideo())) {
8043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // Set initial format to scrambled
8053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            sp<MetaData> meta = new MetaData();
8063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            meta->setCString(kKeyMIMEType,
8073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
8083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                              : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
809bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            // for MediaExtractor.CasInfo
810bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            meta->setInt32(kKeyCASystemID, CA_system_ID);
8113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mSource = new AnotherPacketSource(meta);
8123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
81318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
814cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
815cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
816cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberATSParser::Stream::~Stream() {
817386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    delete mQueue;
818386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    mQueue = NULL;
819cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
820cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
821d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhangbool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
8223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
823d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        return true;
8243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
8253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
8273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);
8283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<ABuffer> newBuffer, newScrambledBuffer;
8303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<IMemory> newMem;
8313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    sp<MemoryDealer> newDealer;
8323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mScrambled) {
8333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        size_t alignment = MemoryDealer::getAllocationAlignment();
8343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        neededSize = (neededSize + (alignment - 1)) & ~(alignment - 1);
8353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Align to multiples of 64K.
8363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        neededSize = (neededSize + 65535) & ~65535;
8373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newDealer = new MemoryDealer(neededSize, "ATSParser");
8383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newMem = newDealer->allocate(neededSize);
8393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newScrambledBuffer = new ABuffer(newMem->pointer(), newMem->size());
8403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mDescrambledBuffer != NULL) {
8423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            memcpy(newScrambledBuffer->data(),
8433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    mDescrambledBuffer->data(), mDescrambledBuffer->size());
8443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            newScrambledBuffer->setRange(0, mDescrambledBuffer->size());
8453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        } else {
8463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            newScrambledBuffer->setRange(0, 0);
8473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
8483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mMem = newMem;
8493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mDealer = newDealer;
8503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mDescrambledBuffer = newScrambledBuffer;
851d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
852d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        ssize_t offset;
853d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        size_t size;
854d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        sp<IMemoryHeap> heap = newMem->getMemory(&offset, &size);
855d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        if (heap == NULL) {
856d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            return false;
857d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        }
85858ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang
85958ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang        mHidlMemory = fromHeap(heap);
86058ddee30e6cefde8a8f3d4d4aa55954e16c7bb18Chong Zhang        mDescramblerSrcBuffer.heapBase = *mHidlMemory;
861d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        mDescramblerSrcBuffer.offset = (uint64_t) offset;
862d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        mDescramblerSrcBuffer.size = (uint64_t) size;
863d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
864d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        ALOGD("[stream %d] created shared buffer for descrambling, offset %zd, size %zu",
865d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                mElementaryPID, offset, size);
8663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    } else {
8673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Align to multiples of 64K.
8683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        neededSize = (neededSize + 65535) & ~65535;
8693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
8703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    newBuffer = new ABuffer(neededSize);
8723b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mBuffer != NULL) {
8733b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
8743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newBuffer->setRange(0, mBuffer->size());
8753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    } else {
8763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        newBuffer->setRange(0, 0);
8773b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
8783b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mBuffer = newBuffer;
879d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    return true;
8803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
8813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
8825403129e2a2f44620f2ac8109889e5a61be08732Andreas Huberstatus_t ATSParser::Stream::parse(
88387f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned continuity_counter,
8843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned payload_unit_start_indicator,
8853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned transport_scrambling_control,
8863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned random_access_indicator,
8873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader *br, SyncEvent *event) {
88818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (mQueue == NULL) {
8895403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber        return OK;
89018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
89118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
89287f2a558dd12043631e12c361abef301bf603140Andreas Huber    if (mExpectedContinuityCounter >= 0
89387f2a558dd12043631e12c361abef301bf603140Andreas Huber            && (unsigned)mExpectedContinuityCounter != continuity_counter) {
89487f2a558dd12043631e12c361abef301bf603140Andreas Huber        ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
89587f2a558dd12043631e12c361abef301bf603140Andreas Huber
89687f2a558dd12043631e12c361abef301bf603140Andreas Huber        mPayloadStarted = false;
8979558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        mPesStartOffsets.clear();
89887f2a558dd12043631e12c361abef301bf603140Andreas Huber        mBuffer->setRange(0, 0);
8993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mSubSamples.clear();
90087f2a558dd12043631e12c361abef301bf603140Andreas Huber        mExpectedContinuityCounter = -1;
90187f2a558dd12043631e12c361abef301bf603140Andreas Huber
90294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#if 0
90394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        // Uncomment this if you'd rather see no corruption whatsoever on
90494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        // screen and suspend updates until we come across another IDR frame.
90594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
90694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        if (mStreamType == STREAMTYPE_H264) {
90794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            ALOGI("clearing video queue");
90894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            mQueue->clear(true /* clearFormat */);
90994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        }
91094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#endif
91194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
91266830855846db5c211c2da6c055ca9b4167e8974Chong Zhang        if (!payload_unit_start_indicator) {
91366830855846db5c211c2da6c055ca9b4167e8974Chong Zhang            return OK;
91466830855846db5c211c2da6c055ca9b4167e8974Chong Zhang        }
91587f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
91687f2a558dd12043631e12c361abef301bf603140Andreas Huber
91787f2a558dd12043631e12c361abef301bf603140Andreas Huber    mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f;
91887f2a558dd12043631e12c361abef301bf603140Andreas Huber
919cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (payload_unit_start_indicator) {
920540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        off64_t offset = (event != NULL) ? event->getOffset() : 0;
921cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (mPayloadStarted) {
922cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            // Otherwise we run the danger of receiving the trailing bytes
923cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            // of a PES packet that we never saw the start of and assuming
924cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            // we have a a complete PES packet.
925cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
926540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            status_t err = flush(event);
9275403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
9285403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber            if (err != OK) {
92965959d34fdab8319dbf765be5fbf7ff8051eedf1Wonsik Kim                ALOGW("Error (%08x) happened while flushing; we simply discard "
93065959d34fdab8319dbf765be5fbf7ff8051eedf1Wonsik Kim                      "the PES packet and continue.", err);
9315403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber            }
932cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
933cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
934cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        mPayloadStarted = true;
935b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        // There should be at most 2 elements in |mPesStartOffsets|.
936b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        while (mPesStartOffsets.size() >= 2) {
937b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia            mPesStartOffsets.erase(mPesStartOffsets.begin());
938b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        }
9399558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        mPesStartOffsets.push_back(offset);
940cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
941cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
942cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (!mPayloadStarted) {
9435403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber        return OK;
944cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
945cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
946cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    size_t payloadSizeBits = br->numBitsLeft();
947e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (payloadSizeBits % 8 != 0u) {
948e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Wrong value");
949e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return BAD_VALUE;
950e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
951cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
9523e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber    size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
953d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    if (!ensureBufferCapacity(neededSize)) {
954d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        return NO_MEMORY;
955d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang    }
956cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
957cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
958cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
9595403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
9603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mScrambled) {
9613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mSubSamples.push_back({payloadSizeBits / 8,
9623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                 transport_scrambling_control, random_access_indicator});
9633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
9643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
9655403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    return OK;
966cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
967cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
9686e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huberbool ATSParser::Stream::isVideo() const {
9696e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    switch (mStreamType) {
9706e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_H264:
9713a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_H264_ENCRYPTED:
9726e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG1_VIDEO:
9736e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG2_VIDEO:
9746e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG4_VIDEO:
9756e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            return true;
9766e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9776e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        default:
9786e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            return false;
9796e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
9806e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber}
9816e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9826e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huberbool ATSParser::Stream::isAudio() const {
9836e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    switch (mStreamType) {
9846e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG1_AUDIO:
9856e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG2_AUDIO:
9866e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        case STREAMTYPE_MPEG2_AUDIO_ADTS:
9879bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang        case STREAMTYPE_LPCM_AC3:
988d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu        case STREAMTYPE_AC3:
9893a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_AAC_ENCRYPTED:
9903a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        case STREAMTYPE_AC3_ENCRYPTED:
9916e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            return true;
9926e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9936e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        default:
9946e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            return false;
9956e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
9966e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber}
9976e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
9980852843d304006e3ab333081fddda13b07193de8Robert Shihbool ATSParser::Stream::isMeta() const {
9990852843d304006e3ab333081fddda13b07193de8Robert Shih    if (mStreamType == STREAMTYPE_METADATA) {
10000852843d304006e3ab333081fddda13b07193de8Robert Shih        return true;
10010852843d304006e3ab333081fddda13b07193de8Robert Shih    }
10020852843d304006e3ab333081fddda13b07193de8Robert Shih    return false;
10030852843d304006e3ab333081fddda13b07193de8Robert Shih}
10040852843d304006e3ab333081fddda13b07193de8Robert Shih
100532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::Stream::signalDiscontinuity(
100632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        DiscontinuityType type, const sp<AMessage> &extra) {
10070389cc09f7b90f155a8942a0d2e1925cad1dbe2dMarco Nelissen    mExpectedContinuityCounter = -1;
10080389cc09f7b90f155a8942a0d2e1925cad1dbe2dMarco Nelissen
100918ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    if (mQueue == NULL) {
101018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber        return;
101118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber    }
101218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber
10132a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    mPayloadStarted = false;
10149558f6dd733dc450270f38b9a139d384d273ce0aWei Jia    mPesStartOffsets.clear();
1015aabbdc7401ae24a4199f12a283985deb648673c0Robert Shih    mEOSReached = false;
10162a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    mBuffer->setRange(0, 0);
10173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mSubSamples.clear();
10182a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
10196e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    bool clearFormat = false;
10206e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (isAudio()) {
10216e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        if (type & DISCONTINUITY_AUDIO_FORMAT) {
10226e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            clearFormat = true;
10236e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        }
10246e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    } else {
10256e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        if (type & DISCONTINUITY_VIDEO_FORMAT) {
10266e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            clearFormat = true;
10276e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        }
10286e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10306e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    mQueue->clear(clearFormat);
103132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
10326e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (type & DISCONTINUITY_TIME) {
10336e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        uint64_t resumeAtPTS;
10346e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        if (extra != NULL
10356e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                && extra->findInt64(
103615d02f84351eaca14099bde11cfbf6f124bea71fDongwon Kang                    kATSParserKeyResumeAtPTS,
10376e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                    (int64_t *)&resumeAtPTS)) {
10386e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            int64_t resumeAtMediaTimeUs =
10396e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                mProgram->convertPTSToTimestamp(resumeAtPTS);
104032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
1041c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia            extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs);
1042e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber        }
10436e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    }
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10456e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber    if (mSource != NULL) {
10463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<MetaData> meta = mSource->getFormat();
10473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        const char* mime;
10483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (clearFormat && meta != NULL && meta->findCString(kKeyMIMEType, &mime)
10493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                && (!strncasecmp(mime, MEDIA_MIMETYPE_AUDIO_SCRAMBLED, 15)
10503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                 || !strncasecmp(mime, MEDIA_MIMETYPE_VIDEO_SCRAMBLED, 15))){
10513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mSource->clear();
10523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        } else {
10533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            mSource->queueDiscontinuity(type, extra, true);
10543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
1055bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber    }
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1057bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::Stream::signalEOS(status_t finalResult) {
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mSource != NULL) {
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mSource->signalEOS(finalResult);
10612a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    }
1062be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    mEOSReached = true;
1063540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    flush(NULL);
10642a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber}
10652a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
1066540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::Stream::parsePES(ABitReader *br, SyncEvent *event) {
10673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    const uint8_t *basePtr = br->data();
10683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1069cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned packet_startcode_prefix = br->getBits(24);
1070cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
10713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
1072cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1073386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (packet_startcode_prefix != 1) {
10743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Supposedly payload_unit_start=1 unit does not start "
1075386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber             "with startcode.");
10765403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
10775403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber        return ERROR_MALFORMED;
1078386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    }
1079386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1080cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned stream_id = br->getBits(8);
10813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stream_id = 0x%02x", stream_id);
1082cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1083cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned PES_packet_length = br->getBits(16);
10843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("PES_packet_length = %u", PES_packet_length);
1085cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1086cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (stream_id != 0xbc  // program_stream_map
1087cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xbe  // padding_stream
1088cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xbf  // private_stream_2
1089cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xf0  // ECM
1090cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xf1  // EMM
1091cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xff  // program_stream_directory
1092cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xf2  // DSMCC
1093cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            && stream_id != 0xf8) {  // H.222.1 type E
1094e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (br->getBits(2) != 2u) {
1095e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return ERROR_MALFORMED;
1096e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
1097cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
10983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PES_scrambling_control = br->getBits(2);
10993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
11003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
11016e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("PES_priority = %u", br->getBits(1));
11026e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("data_alignment_indicator = %u", br->getBits(1));
11036e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("copyright = %u", br->getBits(1));
11046e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("original_or_copy = %u", br->getBits(1));
1105cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1106cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned PTS_DTS_flags = br->getBits(2);
11073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags);
1108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned ESCR_flag = br->getBits(1);
11103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("ESCR_flag = %u", ESCR_flag);
1111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned ES_rate_flag = br->getBits(1);
11133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("ES_rate_flag = %u", ES_rate_flag);
1114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned DSM_trick_mode_flag = br->getBits(1);
11163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);
1117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned additional_copy_info_flag = br->getBits(1);
11193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag);
1120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
11216e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("PES_CRC_flag = %u", br->getBits(1));
11226e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("PES_extension_flag = %u", br->getBits(1));
1123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned PES_header_data_length = br->getBits(8);
11253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("PES_header_data_length = %u", PES_header_data_length);
1126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned optional_bytes_remaining = PES_header_data_length;
1128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        uint64_t PTS = 0, DTS = 0;
1130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
1132e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (optional_bytes_remaining < 5u) {
1133e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1134e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1135cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
11366456ae745e919085c5024f784aaa2703f9695f98David Yeh            if (br->getBits(4) != PTS_DTS_flags) {
11376456ae745e919085c5024f784aaa2703f9695f98David Yeh                return ERROR_MALFORMED;
11386456ae745e919085c5024f784aaa2703f9695f98David Yeh            }
1139cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            PTS = ((uint64_t)br->getBits(3)) << 30;
1140e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1141e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1142e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1143cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            PTS |= ((uint64_t)br->getBits(15)) << 15;
1144e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1145e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1146e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            PTS |= br->getBits(15);
1148e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1149e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1150e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1152b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross            ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);
1153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            optional_bytes_remaining -= 5;
1155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1156cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            if (PTS_DTS_flags == 3) {
1157e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (optional_bytes_remaining < 5u) {
1158e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1159e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1160cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1161e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (br->getBits(4) != 1u) {
1162e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1163e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                DTS = ((uint64_t)br->getBits(3)) << 30;
1166e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (br->getBits(1) != 1u) {
1167e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1168e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1169cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                DTS |= ((uint64_t)br->getBits(15)) << 15;
1170e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (br->getBits(1) != 1u) {
1171e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1172e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1173cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                DTS |= br->getBits(15);
1174e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                if (br->getBits(1) != 1u) {
1175e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                    return ERROR_MALFORMED;
1176e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                }
1177cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1178b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                ALOGV("DTS = %" PRIu64, DTS);
1179cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                optional_bytes_remaining -= 5;
1181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            }
1182cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1183cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1184cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (ESCR_flag) {
1185e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (optional_bytes_remaining < 6u) {
1186e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1187e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1188cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1189cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            br->getBits(2);
1190cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1191cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
1192e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1193e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1194e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1195cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            ESCR |= ((uint64_t)br->getBits(15)) << 15;
1196e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1197e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1198e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1199cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            ESCR |= br->getBits(15);
1200e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1201e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1202e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1203cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1204b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross            ALOGV("ESCR = %" PRIu64, ESCR);
12056e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber            MY_LOGV("ESCR_extension = %u", br->getBits(9));
1206cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1207e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1208e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1209e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1210cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1211cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            optional_bytes_remaining -= 6;
1212cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1213cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1214cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (ES_rate_flag) {
1215e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (optional_bytes_remaining < 3u) {
1216e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1217e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1218cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1219e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1220e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1221e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
12226e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber            MY_LOGV("ES_rate = %u", br->getBits(22));
1223e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (br->getBits(1) != 1u) {
1224e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1225e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1226cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1227cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            optional_bytes_remaining -= 3;
1228cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1229cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1230cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        br->skipBits(optional_bytes_remaining * 8);
1231cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1232cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        // ES data follows.
12333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t pesOffset = br->data() - basePtr;
1234cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1235cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (PES_packet_length != 0) {
1236e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (PES_packet_length < PES_header_data_length + 3) {
1237e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1238e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1239cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1240cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned dataLength =
1241cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber                PES_packet_length - 3 - PES_header_data_length;
1242cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
12435403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber            if (br->numBitsLeft() < dataLength * 8) {
124429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("PES packet does not carry enough data to contain "
1245b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross                     "payload. (numBitsLeft = %zu, required = %u)",
12465403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber                     br->numBitsLeft(), dataLength * 8);
12475403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
12485403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber                return ERROR_MALFORMED;
12495403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber            }
12505403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
12513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGV("There's %u bytes of payload, PES_packet_length=%u, offset=%d",
12523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    dataLength, PES_packet_length, pesOffset);
12533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
12540da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            onPayloadData(
12553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
12563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    br->data(), dataLength, pesOffset, event);
1257cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1258cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            br->skipBits(dataLength * 8);
1259cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        } else {
12600da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            onPayloadData(
12613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
12623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    br->data(), br->numBitsLeft() / 8, pesOffset, event);
12630da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1264cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            size_t payloadSizeBits = br->numBitsLeft();
1265e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (payloadSizeBits % 8 != 0u) {
1266e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1267e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
1268cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
12693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGV("There's %zu bytes of payload, offset=%d",
12703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    payloadSizeBits / 8, pesOffset);
1271cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1272cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    } else if (stream_id == 0xbe) {  // padding_stream
1273e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (PES_packet_length == 0u) {
1274e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return ERROR_MALFORMED;
1275e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
1276cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        br->skipBits(PES_packet_length * 8);
1277cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    } else {
1278e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (PES_packet_length == 0u) {
1279e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return ERROR_MALFORMED;
1280e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
1281cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        br->skipBits(PES_packet_length * 8);
1282cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
12835403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
12845403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    return OK;
1285cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1286cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
12873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhanguint32_t ATSParser::Stream::getPesScramblingControl(
12883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader *br, int32_t *pesOffset) {
12893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    unsigned packet_startcode_prefix = br->getBits(24);
12903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
12913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
12923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
12933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (packet_startcode_prefix != 1) {
12943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("unit does not start with startcode.");
12953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return 0;
12963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
12973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
12983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (br->numBitsLeft() < 48) {
12993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return 0;
13003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    unsigned stream_id = br->getBits(8);
13033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("stream_id = 0x%02x", stream_id);
13043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    br->skipBits(16); // PES_packet_length
13063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (stream_id != 0xbc  // program_stream_map
13083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xbe  // padding_stream
13093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xbf  // private_stream_2
13103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xf0  // ECM
13113b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xf1  // EMM
13123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xff  // program_stream_directory
13133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xf2  // DSMCC
13143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            && stream_id != 0xf8) {  // H.222.1 type E
13153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (br->getBits(2) != 2u) {
13163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return 0;
13173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13183b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PES_scrambling_control = br->getBits(2);
13203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
13213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13223b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (PES_scrambling_control == 0) {
13233b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return 0;
13243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        br->skipBits(12); // don't care
13273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13283b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PES_header_data_length = br->getBits(8);
13293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("PES_header_data_length = %u", PES_header_data_length);
13303b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (PES_header_data_length * 8 > br->numBitsLeft()) {
13323b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return 0;
13333b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13343b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13353b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        *pesOffset = 9 + PES_header_data_length;
13363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGD("found PES_scrambling_control=%d, PES offset=%d",
13373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                PES_scrambling_control, *pesOffset);
13383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return PES_scrambling_control;
13393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13403b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return 0;
13423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
13433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangstatus_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
13453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mDescrambler == NULL) {
13463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGE("received scrambled packets without descrambler!");
13473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return UNKNOWN_ERROR;
13483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mDescrambledBuffer == NULL || mMem == NULL) {
13513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGE("received scrambled packets without shared memory!");
13523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return UNKNOWN_ERROR;
13543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    int32_t pesOffset = 0;
13573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    int32_t descrambleSubSamples = 0, descrambleBytes = 0;
13583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    uint32_t tsScramblingControl = 0, pesScramblingControl = 0;
13593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // First, go over subsamples to find TS-level scrambling key id, and
13613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // calculate how many subsample we need to descramble (assuming we don't
13623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // have PES-level scrambling).
13633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    for (auto it = mSubSamples.begin(); it != mSubSamples.end(); it++) {
13643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (it->transport_scrambling_mode != 0) {
13653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            // TODO: handle keyId change, use the first non-zero keyId for now.
13663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            if (tsScramblingControl == 0) {
13673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                tsScramblingControl = it->transport_scrambling_mode;
13683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
13693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (tsScramblingControl == 0 || descrambleSubSamples == 0
13713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                || !mQueue->isScrambled()) {
13723b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            descrambleSubSamples++;
13733b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            descrambleBytes += it->subSampleSize;
13743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // If not scrambled at TS-level, check PES-level scrambling
13773b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (tsScramblingControl == 0) {
13783b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader br(mBuffer->data(), mBuffer->size());
13793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        pesScramblingControl = getPesScramblingControl(&br, &pesOffset);
13803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // If not scrambled at PES-level either, or scrambled at PES-level but
13813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // requires output to remain scrambled, we don't need to descramble
13823b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // anything.
13833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (pesScramblingControl == 0 || mQueue->isScrambled()) {
13843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            descrambleSubSamples = 0;
13853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            descrambleBytes = 0;
13863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
13873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
13883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    uint32_t sctrl = tsScramblingControl != 0 ?
13903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            tsScramblingControl : pesScramblingControl;
1391d1af641a93f297ead1c9c00619cdb62f551b9086Chong Zhang    if (mQueue->isScrambled()) {
1392d1af641a93f297ead1c9c00619cdb62f551b9086Chong Zhang        sctrl |= DescramblerPlugin::kScrambling_Flag_PesHeader;
1393d1af641a93f297ead1c9c00619cdb62f551b9086Chong Zhang    }
13943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
13953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    // Perform the 1st pass descrambling if needed
13963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (descrambleBytes > 0) {
13973b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
13983b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mDescrambledBuffer->setRange(0, descrambleBytes);
13993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1400d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        hidl_vec<SubSample> subSamples;
1401d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        subSamples.resize(descrambleSubSamples);
14023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t i = 0;
14043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        for (auto it = mSubSamples.begin();
14053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
14063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
1407d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples[i].numBytesOfClearData = 0;
1408d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
14093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            } else {
1410d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples[i].numBytesOfClearData = it->subSampleSize;
1411d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples[i].numBytesOfEncryptedData = 0;
14123b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
14133b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
1414d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
1415d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        uint64_t srcOffset = 0, dstOffset = 0;
14163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // If scrambled at PES-level, PES header should be skipped
14173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (pesScramblingControl != 0) {
1418d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            srcOffset = dstOffset = pesOffset;
1419d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            subSamples[0].numBytesOfEncryptedData -= pesOffset;
14203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
14213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1422d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        Status status = Status::OK;
1423d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        uint32_t bytesWritten = 0;
1424d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        hidl_string detailedError;
1425d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
1426d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        DestinationBuffer dstBuffer;
1427d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        dstBuffer.type = BufferType::SHARED_MEMORY;
1428d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;
1429d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
1430d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        auto returnVoid = mDescrambler->descramble(
1431d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                (ScramblingControl) sctrl,
1432d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                subSamples,
1433d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                mDescramblerSrcBuffer,
1434d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                srcOffset,
1435d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                dstBuffer,
1436d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                dstOffset,
1437d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                [&status, &bytesWritten, &detailedError] (
1438d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                        Status _status, uint32_t _bytesWritten,
1439d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                        const hidl_string& _detailedError) {
1440d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                    status = _status;
1441d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                    bytesWritten = _bytesWritten;
1442d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                    detailedError = _detailedError;
1443d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                });
1444d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang
1445d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang        if (!returnVoid.isOk()) {
1446d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang            ALOGE("[stream %d] descramble failed, trans=%s",
1447d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                    mElementaryPID, returnVoid.description().c_str());
14483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            return UNKNOWN_ERROR;
14493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
14503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGV("[stream %d] descramble succeeded, %d bytes",
1452d5a416a49d5074e2966f5fe255561cbaaf31a325Chong Zhang                mElementaryPID, bytesWritten);
14533b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
14543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
14553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mQueue->isScrambled()) {
14573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Queue subSample info for scrambled queue
14583b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
14593b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        sp<ABuffer> encSizesBuffer = new ABuffer(mSubSamples.size() * 4);
14603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t *clearSizePtr = (int32_t*)clearSizesBuffer->data();
14613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t *encSizePtr = (int32_t*)encSizesBuffer->data();
14623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t isSync = 0;
14633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t i = 0;
14643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        for (auto it = mSubSamples.begin();
14653b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                it != mSubSamples.end(); it++, i++) {
14663b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            if ((it->transport_scrambling_mode == 0
14673b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    && pesScramblingControl == 0)
14683b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    || i < descrambleSubSamples) {
14693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                clearSizePtr[i] = it->subSampleSize;
14703b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                encSizePtr[i] = 0;
14713b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            } else {
14723b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                clearSizePtr[i] = 0;
14733b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                encSizePtr[i] = it->subSampleSize;
14743b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            }
14753b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            isSync |= it->random_access_indicator;
14763b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
14773b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // Pass the original TS subsample size now. The PES header adjust
14783b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        // will be applied when the scrambled AU is dequeued.
14793b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mQueue->appendScrambledData(
14803b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mBuffer->data(), mBuffer->size(), sctrl,
14813b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                isSync, clearSizesBuffer, encSizesBuffer);
14823b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
14833b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14843b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ABitReader br(mBuffer->data(), mBuffer->size());
14853b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t err = parsePES(&br, event);
14863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (err != OK) {
14883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ALOGE("[stream %d] failed to parse descrambled PES, err=%d",
14893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                mElementaryPID, err);
14903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
14913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return err;
14933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
14943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
14953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1496540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::Stream::flush(SyncEvent *event) {
1497f2cecd570c35d3b6422396dd51c0b4202732bceaJaesung Chung    if (mBuffer == NULL || mBuffer->size() == 0) {
14985403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber        return OK;
1499cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1500cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1501b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross    ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size());
1502cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
15033b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t err = OK;
15043b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mScrambled) {
15053b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        err = flushScrambled(event);
15063b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mSubSamples.clear();
15073b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    } else {
15083b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader br(mBuffer->data(), mBuffer->size());
15093b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        err = parsePES(&br, event);
15103b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
1511cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1512cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mBuffer->setRange(0, 0);
15135403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber
15145403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber    return err;
1515cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1516cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1517cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid ATSParser::Stream::onPayloadData(
151884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
15193b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned PES_scrambling_control,
15203b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        const uint8_t *data, size_t size,
15213b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        int32_t payloadOffset, SyncEvent *event) {
152290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if 0
152390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
152490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber          mStreamType,
152590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber          PTS,
152690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber          (int64_t)PTS - mPrevPTS);
152790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mPrevPTS = PTS;
152890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
152990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
15303a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGV("onPayloadData mStreamType=0x%02x size: %zu", mStreamType, size);
1531cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
153298a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    int64_t timeUs = 0ll;  // no presentation timestamp available.
153398a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
153498a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber        timeUs = mProgram->convertPTSToTimestamp(PTS);
153598a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber    }
153682f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
15373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t err = mQueue->appendData(
15383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            data, size, timeUs, payloadOffset, PES_scrambling_control);
1539decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber
1540be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    if (mEOSReached) {
1541be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen        mQueue->signalEOS();
1542be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen    }
1543be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen
1544decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber    if (err != OK) {
1545decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber        return;
1546decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber    }
154782f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
15486a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber    sp<ABuffer> accessUnit;
1549540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    bool found = false;
1550386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
15516a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber        if (mSource == NULL) {
1552386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            sp<MetaData> meta = mQueue->getFormat();
155382f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
15546a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            if (meta != NULL) {
15553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("Stream PID 0x%08x of type 0x%02x now has data.",
1556386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                     mElementaryPID, mStreamType);
1557386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1558309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih                const char *mime;
1559309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih                if (meta->findCString(kKeyMIMEType, &mime)
15603b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                        && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
15613b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    int32_t sync = 0;
15623b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    if (!accessUnit->meta()->findInt32("isSync", &sync) || !sync) {
15633b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                        continue;
15643b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    }
1565309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih                }
15666a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                mSource = new AnotherPacketSource(meta);
15676a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber                mSource->queueAccessUnit(accessUnit);
15683a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
15693a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                        mElementaryPID, mStreamType);
157082f7321b03eec1e40af9d681370f754ee0279582Andreas Huber            }
1571386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        } else if (mQueue->getFormat() != NULL) {
15722a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber            // After a discontinuity we invalidate the queue's format
15732a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber            // and won't enqueue any access units to the source until
15742a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber            // the queue has reestablished the new format.
15755bc087c573c70c84c6a39946457590b42d392a33Andreas Huber
15765bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            if (mSource->getFormat() == NULL) {
1577386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mSource->setFormat(mQueue->getFormat());
15785bc087c573c70c84c6a39946457590b42d392a33Andreas Huber            }
15796a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber            mSource->queueAccessUnit(accessUnit);
158082f7321b03eec1e40af9d681370f754ee0279582Andreas Huber        }
1581540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
1582b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
1583b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        off64_t pesStartOffset = -1;
1584b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        if (!mPesStartOffsets.empty()) {
1585b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia            pesStartOffset = *mPesStartOffsets.begin();
1586b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia            mPesStartOffsets.erase(mPesStartOffsets.begin());
1587b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        }
1588b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia
1589b08d83e972ba8cb08a6e361d5cdaf97857bcf21fWei Jia        if (pesStartOffset >= 0 && (event != NULL) && !found && mQueue->getFormat() != NULL) {
1590540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            int32_t sync = 0;
1591540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            if (accessUnit->meta()->findInt32("isSync", &sync) && sync) {
1592540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                int64_t timeUs;
1593540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
1594540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                    found = true;
159582e147049625a4cfdcb228a1de7efda594d446c9Robert Shih                    event->init(pesStartOffset, mSource, timeUs, getSourceType());
1596540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                }
1597540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            }
1598540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        }
159982f7321b03eec1e40af9d681370f754ee0279582Andreas Huber    }
160082f7321b03eec1e40af9d681370f754ee0279582Andreas Huber}
160182f7321b03eec1e40af9d681370f754ee0279582Andreas Huber
160282e147049625a4cfdcb228a1de7efda594d446c9Robert ShihATSParser::SourceType ATSParser::Stream::getSourceType() {
160382e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    if (isVideo()) {
160482e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        return VIDEO;
160582e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    } else if (isAudio()) {
160682e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        return AUDIO;
160782e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    } else if (isMeta()) {
160882e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        return META;
160982e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    }
161082e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    return NUM_SOURCE_TYPES;
161182e147049625a4cfdcb228a1de7efda594d446c9Robert Shih}
161282e147049625a4cfdcb228a1de7efda594d446c9Robert Shih
161345d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissensp<AnotherPacketSource> ATSParser::Stream::getSource(SourceType type) {
1614386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    switch (type) {
1615386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case VIDEO:
1616386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        {
16176e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            if (isVideo()) {
1618386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                return mSource;
1619386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1620386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
1621386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1622386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1623386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        case AUDIO:
1624386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        {
16256e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            if (isAudio()) {
1626386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                return mSource;
1627386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1628386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
1629386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
1630386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
16310852843d304006e3ab333081fddda13b07193de8Robert Shih        case META:
16320852843d304006e3ab333081fddda13b07193de8Robert Shih        {
16330852843d304006e3ab333081fddda13b07193de8Robert Shih            if (isMeta()) {
16340852843d304006e3ab333081fddda13b07193de8Robert Shih                return mSource;
16350852843d304006e3ab333081fddda13b07193de8Robert Shih            }
16360852843d304006e3ab333081fddda13b07193de8Robert Shih            break;
16370852843d304006e3ab333081fddda13b07193de8Robert Shih        }
16380852843d304006e3ab333081fddda13b07193de8Robert Shih
1639386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        default:
1640386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            break;
1641cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1642cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1643cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return NULL;
1644cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1645cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1646bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhangvoid ATSParser::Stream::setCasInfo(
1647bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang        int32_t systemId, const sp<IDescrambler> &descrambler,
16483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        const std::vector<uint8_t> &sessionId) {
16493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (mSource != NULL && mDescrambler == NULL && descrambler != NULL) {
16503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        signalDiscontinuity(DISCONTINUITY_FORMAT_ONLY, NULL);
16513b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mDescrambler = descrambler;
16523b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (mQueue->isScrambled()) {
1653bc7aae4ff7e72e5bf0fa888f946835840a4357bbChong Zhang            mQueue->setCasInfo(systemId, sessionId);
16543b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
16553b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
16563b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
16573b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
1658cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber////////////////////////////////////////////////////////////////////////////////
1659cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1660c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas HuberATSParser::ATSParser(uint32_t flags)
166187f2a558dd12043631e12c361abef301bf603140Andreas Huber    : mFlags(flags),
166287f2a558dd12043631e12c361abef301bf603140Andreas Huber      mAbsoluteTimeAnchorUs(-1ll),
1663d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber      mTimeOffsetValid(false),
1664d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber      mTimeOffsetUs(0ll),
1665d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang      mLastRecoveredPTS(-1ll),
166687f2a558dd12043631e12c361abef301bf603140Andreas Huber      mNumTSPacketsParsed(0),
166787f2a558dd12043631e12c361abef301bf603140Andreas Huber      mNumPCRs(0) {
16688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    mPSISections.add(0 /* PID */, new PSISection);
16693b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    mCasManager = new CasManager();
1670cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1671cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1672cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberATSParser::~ATSParser() {
1673cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1674cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1675540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::feedTSPacket(const void *data, size_t size,
1676540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        SyncEvent *event) {
1677e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (size != kTSPacketSize) {
1678e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("Wrong TS packet size");
1679e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return BAD_VALUE;
1680e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
1681cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1682cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    ABitReader br((const uint8_t *)data, kTSPacketSize);
1683540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    return parseTS(&br, event);
1684cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1685cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
16863b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangstatus_t ATSParser::setMediaCas(const sp<ICas> &cas) {
16873b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    status_t err = mCasManager->setMediaCas(cas);
16883b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (err != OK) {
16893b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        return err;
16903b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
16913b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    for (size_t i = 0; i < mPrograms.size(); ++i) {
16923b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        mPrograms.editItemAt(i)->updateCasSessions();
16933b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
16943b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    return OK;
16953b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang}
16963b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
169732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::signalDiscontinuity(
169832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        DiscontinuityType type, const sp<AMessage> &extra) {
1699b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    int64_t mediaTimeUs;
1700d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    if ((type & DISCONTINUITY_TIME) && extra != NULL) {
170115d02f84351eaca14099bde11cfbf6f124bea71fDongwon Kang        if (extra->findInt64(kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
1702d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            mAbsoluteTimeAnchorUs = mediaTimeUs;
1703d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1704d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)
1705d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                && extra->findInt64(
170615d02f84351eaca14099bde11cfbf6f124bea71fDongwon Kang                    kATSParserKeyRecentMediaTimeUs, &mediaTimeUs)) {
1707d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            if (mAbsoluteTimeAnchorUs >= 0ll) {
1708d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                mediaTimeUs -= mAbsoluteTimeAnchorUs;
1709d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            }
1710d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            if (mTimeOffsetValid) {
1711d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                mediaTimeUs -= mTimeOffsetUs;
1712d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            }
1713d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang            mLastRecoveredPTS = (mediaTimeUs * 9) / 100;
1714d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang        }
1715b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber    } else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
171687f2a558dd12043631e12c361abef301bf603140Andreas Huber        int64_t timeUs;
1717e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (!extra->findInt64("timeUs", &timeUs)) {
1718e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            ALOGE("timeUs not found");
1719e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return;
1720e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
172187f2a558dd12043631e12c361abef301bf603140Andreas Huber
1722e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (!mPrograms.empty()) {
1723e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            ALOGE("mPrograms is not empty");
1724e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return;
1725e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
172687f2a558dd12043631e12c361abef301bf603140Andreas Huber        mAbsoluteTimeAnchorUs = timeUs;
172787f2a558dd12043631e12c361abef301bf603140Andreas Huber        return;
1728d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    } else if (type == DISCONTINUITY_TIME_OFFSET) {
1729d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        int64_t offset;
1730e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (!extra->findInt64("offset", &offset)) {
1731e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            ALOGE("offset not found");
1732e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return;
1733e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
1734d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
1735d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        mTimeOffsetValid = true;
1736d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        mTimeOffsetUs = offset;
1737d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        return;
173887f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
173987f2a558dd12043631e12c361abef301bf603140Andreas Huber
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mPrograms.size(); ++i) {
174132f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber        mPrograms.editItemAt(i)->signalDiscontinuity(type, extra);
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::signalEOS(status_t finalResult) {
1746e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (finalResult == (status_t) OK) {
1747e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        ALOGE("finalResult not OK");
1748e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        return;
1749e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17512a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    for (size_t i = 0; i < mPrograms.size(); ++i) {
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mPrograms.editItemAt(i)->signalEOS(finalResult);
17532a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber    }
17542a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber}
17552a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber
1756cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid ATSParser::parseProgramAssociationTable(ABitReader *br) {
1757cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned table_id = br->getBits(8);
17583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  table_id = %u", table_id);
17596456ae745e919085c5024f784aaa2703f9695f98David Yeh    if (table_id != 0x00u) {
17606456ae745e919085c5024f784aaa2703f9695f98David Yeh        ALOGE("PAT data error!");
17616456ae745e919085c5024f784aaa2703f9695f98David Yeh        return ;
17626456ae745e919085c5024f784aaa2703f9695f98David Yeh    }
1763cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned section_syntax_indictor = br->getBits(1);
17643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  section_syntax_indictor = %u", section_syntax_indictor);
1765cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1766e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    br->skipBits(1);  // '0'
17676e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(2));
1768cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1769cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned section_length = br->getBits(12);
17703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("  section_length = %u", section_length);
1771cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17726e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  transport_stream_id = %u", br->getBits(16));
17736e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  reserved = %u", br->getBits(2));
17746e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  version_number = %u", br->getBits(5));
17756e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
17766e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  section_number = %u", br->getBits(8));
17776e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  last_section_number = %u", br->getBits(8));
1778cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1779cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);
1780cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1781cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (size_t i = 0; i < numProgramBytes / 4; ++i) {
1782cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        unsigned program_number = br->getBits(16);
17833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("    program_number = %u", program_number);
1784cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17856e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber        MY_LOGV("    reserved = %u", br->getBits(3));
1786cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1787cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (program_number == 0) {
17886e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber            MY_LOGV("    network_PID = 0x%04x", br->getBits(13));
1789cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        } else {
1790cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned programMapPID = br->getBits(13);
1791cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("    program_map_PID = 0x%04x", programMapPID);
1793cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1794386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            bool found = false;
1795386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            for (size_t index = 0; index < mPrograms.size(); ++index) {
1796386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                const sp<Program> &program = mPrograms.itemAt(index);
1797386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1798386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                if (program->number() == program_number) {
1799386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    program->updateProgramMapPID(programMapPID);
1800386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    found = true;
1801386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                    break;
1802386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                }
1803386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
1804386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1805386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            if (!found) {
1806386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber                mPrograms.push(
1807d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang                        new Program(this, program_number, programMapPID, mLastRecoveredPTS));
18083a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                if (mSampleAesKeyItem != NULL) {
18093a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                    mPrograms.top()->signalNewSampleAesKey(mSampleAesKeyItem);
18103a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania                }
1811386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            }
18128dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18138dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            if (mPSISections.indexOfKey(programMapPID) < 0) {
18148dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                mPSISections.add(programMapPID, new PSISection);
18158dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            }
1816cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1817cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1818cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
18196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
1820cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1821cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
182206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huberstatus_t ATSParser::parsePID(
1823cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ABitReader *br, unsigned PID,
182487f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned continuity_counter,
1825540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        unsigned payload_unit_start_indicator,
18263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned transport_scrambling_control,
18273b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned random_access_indicator,
1828540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        SyncEvent *event) {
18298dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    ssize_t sectionIndex = mPSISections.indexOfKey(PID);
18308dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18318dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (sectionIndex >= 0) {
18324b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber        sp<PSISection> section = mPSISections.valueAt(sectionIndex);
18338dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
1834cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (payload_unit_start_indicator) {
18356456ae745e919085c5024f784aaa2703f9695f98David Yeh            if (!section->isEmpty()) {
18369bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty");
18379bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang                section->clear();
18386456ae745e919085c5024f784aaa2703f9695f98David Yeh            }
18398dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
1840cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            unsigned skip = br->getBits(8);
18419ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim            section->setSkipBytes(skip + 1);  // skip filler bytes + pointer field itself
1842cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            br->skipBits(skip * 8);
1843cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
18448dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
1845e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (br->numBitsLeft() % 8 != 0) {
1846e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            return ERROR_MALFORMED;
1847e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
18488dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        status_t err = section->append(br->data(), br->numBitsLeft() / 8);
18498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18508dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        if (err != OK) {
18518dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            return err;
18528dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        }
18538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        if (!section->isComplete()) {
18558dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            return OK;
18568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        }
18578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18589ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        if (!section->isCRCOkay()) {
18599ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim            return BAD_VALUE;
18609ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        }
18618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        ABitReader sectionBits(section->data(), section->size());
18628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18638dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        if (PID == 0) {
18648dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            parseProgramAssociationTable(&sectionBits);
18658dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        } else {
18668dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            bool handled = false;
18678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            for (size_t i = 0; i < mPrograms.size(); ++i) {
18688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                status_t err;
18698dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                if (!mPrograms.editItemAt(i)->parsePSISection(
18708dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                            PID, &sectionBits, &err)) {
18718dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                    continue;
18728dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                }
18738dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18748dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                if (err != OK) {
18758dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                    return err;
18768dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                }
18778dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18788dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                handled = true;
18798dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                break;
18808dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            }
18818dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18828dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            if (!handled) {
18838dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber                mPSISections.removeItem(PID);
18844b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber                section.clear();
18858dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            }
18868dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        }
18878dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
18884b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber        if (section != NULL) {
18894b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber            section->clear();
18904b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber        }
18918dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
189206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        return OK;
1893cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1894cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1895cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    bool handled = false;
1896cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (size_t i = 0; i < mPrograms.size(); ++i) {
189706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber        status_t err;
1898cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (mPrograms.editItemAt(i)->parsePID(
18993b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    PID, continuity_counter,
19003b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    payload_unit_start_indicator,
19013b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    transport_scrambling_control,
19023b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    random_access_indicator,
1903540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                    br, &err, event)) {
190406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            if (err != OK) {
190506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber                return err;
190606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber            }
190706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
1908cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            handled = true;
1909cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            break;
1910cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
1911cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1912cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1913cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (!handled) {
19143b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        handled = mCasManager->parsePID(br, PID);
19153b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    }
19163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
19173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    if (!handled) {
19183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("PID 0x%04x not handled.", PID);
1919cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
192006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
192106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    return OK;
1922cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1923cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
19243b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhangstatus_t ATSParser::parseAdaptationField(
19253b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        ABitReader *br, unsigned PID, unsigned *random_access_indicator) {
19263b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    *random_access_indicator = 0;
1927cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned adaptation_field_length = br->getBits(8);
192887f2a558dd12043631e12c361abef301bf603140Andreas Huber
1929cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (adaptation_field_length > 0) {
19308a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung        if (adaptation_field_length * 8 > br->numBitsLeft()) {
19318a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung            ALOGV("Adaptation field should be included in a single TS packet.");
19328a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung            return ERROR_MALFORMED;
19338a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung        }
19348a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung
193587f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned discontinuity_indicator = br->getBits(1);
193687f2a558dd12043631e12c361abef301bf603140Andreas Huber
193787f2a558dd12043631e12c361abef301bf603140Andreas Huber        if (discontinuity_indicator) {
193887f2a558dd12043631e12c361abef301bf603140Andreas Huber            ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID);
193987f2a558dd12043631e12c361abef301bf603140Andreas Huber        }
194087f2a558dd12043631e12c361abef301bf603140Andreas Huber
19413b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        *random_access_indicator = br->getBits(1);
19423b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (*random_access_indicator) {
19433b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGV("PID 0x%04x: random_access_indicator = 1", PID);
19443b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
19453b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
19463b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        unsigned elementary_stream_priority_indicator = br->getBits(1);
19473b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        if (elementary_stream_priority_indicator) {
19483b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang            ALOGV("PID 0x%04x: elementary_stream_priority_indicator = 1", PID);
19493b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        }
19503b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang
195187f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned PCR_flag = br->getBits(1);
195287f2a558dd12043631e12c361abef301bf603140Andreas Huber
195387f2a558dd12043631e12c361abef301bf603140Andreas Huber        size_t numBitsRead = 4;
195487f2a558dd12043631e12c361abef301bf603140Andreas Huber
195587f2a558dd12043631e12c361abef301bf603140Andreas Huber        if (PCR_flag) {
1956e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            if (adaptation_field_length * 8 < 52) {
1957e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim                return ERROR_MALFORMED;
1958e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim            }
195987f2a558dd12043631e12c361abef301bf603140Andreas Huber            br->skipBits(4);
196087f2a558dd12043631e12c361abef301bf603140Andreas Huber            uint64_t PCR_base = br->getBits(32);
196187f2a558dd12043631e12c361abef301bf603140Andreas Huber            PCR_base = (PCR_base << 1) | br->getBits(1);
196287f2a558dd12043631e12c361abef301bf603140Andreas Huber
196387f2a558dd12043631e12c361abef301bf603140Andreas Huber            br->skipBits(6);
196487f2a558dd12043631e12c361abef301bf603140Andreas Huber            unsigned PCR_ext = br->getBits(9);
196587f2a558dd12043631e12c361abef301bf603140Andreas Huber
196687f2a558dd12043631e12c361abef301bf603140Andreas Huber            // The number of bytes from the start of the current
196787f2a558dd12043631e12c361abef301bf603140Andreas Huber            // MPEG2 transport stream packet up and including
196887f2a558dd12043631e12c361abef301bf603140Andreas Huber            // the final byte of this PCR_ext field.
196987f2a558dd12043631e12c361abef301bf603140Andreas Huber            size_t byteOffsetFromStartOfTSPacket =
197087f2a558dd12043631e12c361abef301bf603140Andreas Huber                (188 - br->numBitsLeft() / 8);
197187f2a558dd12043631e12c361abef301bf603140Andreas Huber
197287f2a558dd12043631e12c361abef301bf603140Andreas Huber            uint64_t PCR = PCR_base * 300 + PCR_ext;
197387f2a558dd12043631e12c361abef301bf603140Andreas Huber
1974b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross            ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)",
197587f2a558dd12043631e12c361abef301bf603140Andreas Huber                  PID, PCR, PCR / 27E6);
197687f2a558dd12043631e12c361abef301bf603140Andreas Huber
197787f2a558dd12043631e12c361abef301bf603140Andreas Huber            // The number of bytes received by this parser up to and
197887f2a558dd12043631e12c361abef301bf603140Andreas Huber            // including the final byte of this PCR_ext field.
197919cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen            uint64_t byteOffsetFromStart =
198019cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen                uint64_t(mNumTSPacketsParsed) * 188 + byteOffsetFromStartOfTSPacket;
198187f2a558dd12043631e12c361abef301bf603140Andreas Huber
198287f2a558dd12043631e12c361abef301bf603140Andreas Huber            for (size_t i = 0; i < mPrograms.size(); ++i) {
198387f2a558dd12043631e12c361abef301bf603140Andreas Huber                updatePCR(PID, PCR, byteOffsetFromStart);
198487f2a558dd12043631e12c361abef301bf603140Andreas Huber            }
198587f2a558dd12043631e12c361abef301bf603140Andreas Huber
198687f2a558dd12043631e12c361abef301bf603140Andreas Huber            numBitsRead += 52;
198787f2a558dd12043631e12c361abef301bf603140Andreas Huber        }
198887f2a558dd12043631e12c361abef301bf603140Andreas Huber
198987f2a558dd12043631e12c361abef301bf603140Andreas Huber        br->skipBits(adaptation_field_length * 8 - numBitsRead);
1990cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1991e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    return OK;
1992cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
1993cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1994540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::parseTS(ABitReader *br, SyncEvent *event) {
19953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("---");
1996cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1997cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned sync_byte = br->getBits(8);
19986456ae745e919085c5024f784aaa2703f9695f98David Yeh    if (sync_byte != 0x47u) {
19996456ae745e919085c5024f784aaa2703f9695f98David Yeh        ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte);
20006456ae745e919085c5024f784aaa2703f9695f98David Yeh        return BAD_VALUE;
20016456ae745e919085c5024f784aaa2703f9695f98David Yeh    }
2002cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
200352668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber    if (br->getBits(1)) {  // transport_error_indicator
200452668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber        // silently ignore.
200552668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber        return OK;
200652668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber    }
2007cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2008cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned payload_unit_start_indicator = br->getBits(1);
20093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator);
2010cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20116e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber    MY_LOGV("transport_priority = %u", br->getBits(1));
2012cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2013cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned PID = br->getBits(13);
20143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("PID = 0x%04x", PID);
2015cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20163b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    unsigned transport_scrambling_control = br->getBits(2);
20173b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    ALOGV("transport_scrambling_control = %u", transport_scrambling_control);
2018cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2019cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    unsigned adaptation_field_control = br->getBits(2);
20203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("adaptation_field_control = %u", adaptation_field_control);
2021cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned continuity_counter = br->getBits(4);
202387f2a558dd12043631e12c361abef301bf603140Andreas Huber    ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
20240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2025df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
2026cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
202787f2a558dd12043631e12c361abef301bf603140Andreas Huber    status_t err = OK;
202887f2a558dd12043631e12c361abef301bf603140Andreas Huber
20293b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang    unsigned random_access_indicator = 0;
2030e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (adaptation_field_control == 2 || adaptation_field_control == 3) {
20313b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang        err = parseAdaptationField(br, PID, &random_access_indicator);
2032e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    }
2033e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    if (err == OK) {
2034e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        if (adaptation_field_control == 1 || adaptation_field_control == 3) {
2035540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            err = parsePID(br, PID, continuity_counter,
20363b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    payload_unit_start_indicator,
20373b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    transport_scrambling_control,
20383b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    random_access_indicator,
20393b2847fa5506dc265d2e46f067bfbb66ae209f74Chong Zhang                    event);
2040e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim        }
2041cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
204206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber
204387f2a558dd12043631e12c361abef301bf603140Andreas Huber    ++mNumTSPacketsParsed;
204487f2a558dd12043631e12c361abef301bf603140Andreas Huber
204587f2a558dd12043631e12c361abef301bf603140Andreas Huber    return err;
2046cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
2047cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
204845d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissensp<AnotherPacketSource> ATSParser::getSource(SourceType type) {
204945d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissen    sp<AnotherPacketSource> firstSourceFound;
2050cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (size_t i = 0; i < mPrograms.size(); ++i) {
2051386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        const sp<Program> &program = mPrograms.editItemAt(i);
205245d54c6ec48761b75f92cee4618c4fbffa6be24aMarco Nelissen        sp<AnotherPacketSource> source = program->getSource(type);
20539ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        if (source == NULL) {
2054386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            continue;
2055386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        }
20569ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        if (firstSourceFound == NULL) {
20579ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            firstSourceFound = source;
20589ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        }
20599ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        // Prefer programs with both audio/video
20609ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih        switch (type) {
20619ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            case VIDEO: {
20629ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                if (program->hasSource(AUDIO)) {
20639ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                    return source;
20649ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                }
20659ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                break;
20669ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            }
2067386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
20689ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            case AUDIO: {
20699ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                if (program->hasSource(VIDEO)) {
20709ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                    return source;
20719ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                }
20729ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                break;
20739ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            }
2074cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20759ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih            default:
20769ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih                return source;
2077cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
2078cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
2079cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
20809ff1e728de605c4cbc61bc95bb36e515b93654fbRobert Shih    return firstSourceFound;
2081cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
2082cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
2083bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shihbool ATSParser::hasSource(SourceType type) const {
2084bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    for (size_t i = 0; i < mPrograms.size(); ++i) {
2085bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        const sp<Program> &program = mPrograms.itemAt(i);
2086bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        if (program->hasSource(type)) {
2087bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih            return true;
2088bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih        }
2089bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    }
2090bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
2091bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    return false;
2092bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih}
2093bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih
209443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huberbool ATSParser::PTSTimeDeltaEstablished() {
209543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    if (mPrograms.isEmpty()) {
209643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber        return false;
209743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    }
209843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
209943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished();
210043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber}
210143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
210282e147049625a4cfdcb228a1de7efda594d446c9Robert Shihint64_t ATSParser::getFirstPTSTimeUs() {
210382e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    for (size_t i = 0; i < mPrograms.size(); ++i) {
210482e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        sp<ATSParser::Program> program = mPrograms.itemAt(i);
210582e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        if (program->PTSTimeDeltaEstablished()) {
210682e147049625a4cfdcb228a1de7efda594d446c9Robert Shih            return (program->firstPTS() * 100) / 9;
210782e147049625a4cfdcb228a1de7efda594d446c9Robert Shih        }
210882e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    }
210982e147049625a4cfdcb228a1de7efda594d446c9Robert Shih    return -1;
211082e147049625a4cfdcb228a1de7efda594d446c9Robert Shih}
211182e147049625a4cfdcb228a1de7efda594d446c9Robert Shih
2112c9fa35cf7c9c11a8acb77128db1a6a13f1befe3cChad Brubaker__attribute__((no_sanitize("integer")))
211387f2a558dd12043631e12c361abef301bf603140Andreas Hubervoid ATSParser::updatePCR(
211419cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen        unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
211519cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen    ALOGV("PCR 0x%016" PRIx64 " @ %" PRIx64, PCR, byteOffsetFromStart);
211687f2a558dd12043631e12c361abef301bf603140Andreas Huber
211787f2a558dd12043631e12c361abef301bf603140Andreas Huber    if (mNumPCRs == 2) {
211887f2a558dd12043631e12c361abef301bf603140Andreas Huber        mPCR[0] = mPCR[1];
211987f2a558dd12043631e12c361abef301bf603140Andreas Huber        mPCRBytes[0] = mPCRBytes[1];
212087f2a558dd12043631e12c361abef301bf603140Andreas Huber        mSystemTimeUs[0] = mSystemTimeUs[1];
212187f2a558dd12043631e12c361abef301bf603140Andreas Huber        mNumPCRs = 1;
212287f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
212387f2a558dd12043631e12c361abef301bf603140Andreas Huber
212487f2a558dd12043631e12c361abef301bf603140Andreas Huber    mPCR[mNumPCRs] = PCR;
212587f2a558dd12043631e12c361abef301bf603140Andreas Huber    mPCRBytes[mNumPCRs] = byteOffsetFromStart;
212687f2a558dd12043631e12c361abef301bf603140Andreas Huber    mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs();
212787f2a558dd12043631e12c361abef301bf603140Andreas Huber
212887f2a558dd12043631e12c361abef301bf603140Andreas Huber    ++mNumPCRs;
212987f2a558dd12043631e12c361abef301bf603140Andreas Huber
213087f2a558dd12043631e12c361abef301bf603140Andreas Huber    if (mNumPCRs == 2) {
2131c9fa35cf7c9c11a8acb77128db1a6a13f1befe3cChad Brubaker        /* Unsigned overflow here */
213287f2a558dd12043631e12c361abef301bf603140Andreas Huber        double transportRate =
213387f2a558dd12043631e12c361abef301bf603140Andreas Huber            (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]);
213487f2a558dd12043631e12c361abef301bf603140Andreas Huber
213587f2a558dd12043631e12c361abef301bf603140Andreas Huber        ALOGV("transportRate = %.2f bytes/sec", transportRate);
213687f2a558dd12043631e12c361abef301bf603140Andreas Huber    }
213787f2a558dd12043631e12c361abef301bf603140Andreas Huber}
213887f2a558dd12043631e12c361abef301bf603140Andreas Huber
21398dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber////////////////////////////////////////////////////////////////////////////////
21408dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
21419ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
21429ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// CRC32 used for PSI section. The table was generated by following command:
21439ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// $ python pycrc.py --model crc-32-mpeg --algorithm table-driven --generate c
21449ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// Visit http://www.tty1.net/pycrc/index_en.html for more details.
21459ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimuint32_t ATSParser::PSISection::CRC_TABLE[] = {
21469ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
21479ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
21489ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
21499ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
21509ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
21519ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
21529ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
21539ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
21549ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
21559ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
21569ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
21579ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
21589ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
21599ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
21609ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
21619ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
21629ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
21639ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
21649ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
21659ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
21669ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
21679ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
21689ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
21699ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
21709ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
21719ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
21729ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
21739ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
21749ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
21759ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
21769ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
21779ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
21789ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
21799ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
21809ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
21819ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
21829ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
21839ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
21849ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
21859ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
21869ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
21879ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
21889ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
21899ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
21909ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
21919ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
21929ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
21939ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
21949ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
21959ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
21969ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
21979ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
21989ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
21999ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
22009ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
22019ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
22029ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
22039ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
22049ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
22059ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
22069ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
22079ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
22089ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
22099ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
22109ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    };
22119ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22129ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk KimATSParser::PSISection::PSISection() :
22139ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    mSkipBytes(0) {
22148dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22158dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22168dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas HuberATSParser::PSISection::~PSISection() {
22178dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22188dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22198dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberstatus_t ATSParser::PSISection::append(const void *data, size_t size) {
22208dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) {
22218dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        size_t newCapacity =
22228dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            (mBuffer == NULL) ? size : mBuffer->capacity() + size;
22238dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22248dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        newCapacity = (newCapacity + 1023) & ~1023;
22258dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22268dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        sp<ABuffer> newBuffer = new ABuffer(newCapacity);
22278dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22288dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        if (mBuffer != NULL) {
22298dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
22308dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            newBuffer->setRange(0, mBuffer->size());
22318dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        } else {
22328dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber            newBuffer->setRange(0, 0);
22338dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        }
22348dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22358dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        mBuffer = newBuffer;
22368dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
22378dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22388dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    memcpy(mBuffer->data() + mBuffer->size(), data, size);
22398dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    mBuffer->setRange(0, mBuffer->size() + size);
22408dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22418dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return OK;
22428dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22438dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22449ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimvoid ATSParser::PSISection::setSkipBytes(uint8_t skip) {
22459ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    mSkipBytes = skip;
22469ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim}
22479ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22488dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Hubervoid ATSParser::PSISection::clear() {
22498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (mBuffer != NULL) {
22508dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        mBuffer->setRange(0, 0);
22518dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
22529ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    mSkipBytes = 0;
22538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22558dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::PSISection::isComplete() const {
22568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    if (mBuffer == NULL || mBuffer->size() < 3) {
22578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber        return false;
22588dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    }
22598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22608dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff;
22618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return mBuffer->size() >= sectionLength + 3;
22628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22638dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22648dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::PSISection::isEmpty() const {
22658dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return mBuffer == NULL || mBuffer->size() == 0;
22668dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberconst uint8_t *ATSParser::PSISection::data() const {
22698dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return mBuffer == NULL ? NULL : mBuffer->data();
22708dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22718dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22728dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Hubersize_t ATSParser::PSISection::size() const {
22738dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    return mBuffer == NULL ? 0 : mBuffer->size();
22748dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}
22758dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
22769ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimbool ATSParser::PSISection::isCRCOkay() const {
22779ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    if (!isComplete()) {
22789ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        return false;
22799ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    }
22809ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    uint8_t* data = mBuffer->data();
22819ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22829ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    // Return true if section_syntax_indicator says no section follows the field section_length.
22839ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    if ((data[1] & 0x80) == 0) {
22849ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        return true;
22859ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    }
22869ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
22879ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    unsigned sectionLength = U16_AT(data + 1) & 0xfff;
22889ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes);
22899ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
2290c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen
2291c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen    if(sectionLength < mSkipBytes) {
2292c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen        ALOGE("b/28333006");
2293c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen        android_errorWriteLog(0x534e4554, "28333006");
2294c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen        return false;
2295c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen    }
2296c0c9f50d15f7b9ed539c0c6277296d083f41b293Marco Nelissen
22979ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    // Skip the preceding field present when payload start indicator is on.
22989ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    sectionLength -= mSkipBytes;
22999ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim
23009ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    uint32_t crc = 0xffffffff;
23019ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    for(unsigned i = 0; i < sectionLength + 4 /* crc */; i++) {
23029ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        uint8_t b = data[i];
23039ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        int index = ((crc >> 24) ^ (b & 0xff)) & 0xff;
23049ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim        crc = CRC_TABLE[index] ^ (crc << 8);
23059ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    }
23069ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    ALOGV("crc: %08x\n", crc);
23079ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim    return (crc == 0);
23089ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim}
23093a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23103a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania// SAMPLE_AES key handling
23113a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania// TODO: Merge these to their respective class after Widevine-HLS
23123a37f3e948b600405e0c70b8a241778fda44168eHassan Shojaniavoid ATSParser::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
23133a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGD("signalNewSampleAesKey: %p", keyItem.get());
23143a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23153a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleAesKeyItem = keyItem;
23163a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23173a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // a NULL key item will propagate to existing ElementaryStreamQueues
23183a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    for (size_t i = 0; i < mPrograms.size(); ++i) {
23193a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        mPrograms[i]->signalNewSampleAesKey(keyItem);
23203a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    }
23213a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania}
23223a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23233a37f3e948b600405e0c70b8a241778fda44168eHassan Shojaniavoid ATSParser::Program::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
23243a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGD("Program::signalNewSampleAesKey: %p", keyItem.get());
23253a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23263a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleAesKeyItem = keyItem;
23273a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23283a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // a NULL key item will propagate to existing ElementaryStreamQueues
23293a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    for (size_t i = 0; i < mStreams.size(); ++i) {
23303a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania        mStreams[i]->signalNewSampleAesKey(keyItem);
23313a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    }
23323a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania}
23333a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23343a37f3e948b600405e0c70b8a241778fda44168eHassan Shojaniavoid ATSParser::Stream::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
23353a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    ALOGD("Stream::signalNewSampleAesKey: 0x%04x size = %zu keyItem: %p",
23363a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania          mElementaryPID, mBuffer->size(), keyItem.get());
23373a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23383a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    // a NULL key item will propagate to existing ElementaryStreamQueues
23393a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mSampleAesKeyItem = keyItem;
23403a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
23413a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    flush(NULL);
23423a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania    mQueue->signalNewSampleAesKey(keyItem);
23433a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania}
23443a37f3e948b600405e0c70b8a241778fda44168eHassan Shojania
2345cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}  // namespace android
2346