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
17cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#ifndef A_TS_PARSER_H_
18cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
19cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#define A_TS_PARSER_H_
20cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <sys/types.h>
22cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/ABase.h>
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
25540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim#include <media/stagefright/MediaSource.h>
268dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber#include <utils/KeyedVector.h>
27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/Vector.h>
28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/RefBase.h>
29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android {
31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
3286a58cabe322b746ab0eb17f0cade34ed68ba60eBernhard Rosenkränzerclass ABitReader;
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ABuffer;
34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct ATSParser : public RefBase {
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum DiscontinuityType {
376e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        DISCONTINUITY_NONE              = 0,
386e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        DISCONTINUITY_TIME              = 1,
396e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        DISCONTINUITY_AUDIO_FORMAT      = 2,
406e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        DISCONTINUITY_VIDEO_FORMAT      = 4,
4187f2a558dd12043631e12c361abef301bf603140Andreas Huber        DISCONTINUITY_ABSOLUTE_TIME     = 8,
42d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        DISCONTINUITY_TIME_OFFSET       = 16,
436e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber
446e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        // For legacy reasons this also implies a time discontinuity.
456e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        DISCONTINUITY_FORMATCHANGE      =
466e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber            DISCONTINUITY_AUDIO_FORMAT
476e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                | DISCONTINUITY_VIDEO_FORMAT
486e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber                | DISCONTINUITY_TIME,
49a48d372833ccec13c96ece9efcc226e8beac7f59Chong Zhang        DISCONTINUITY_FORMAT_ONLY       =
50a48d372833ccec13c96ece9efcc226e8beac7f59Chong Zhang            DISCONTINUITY_AUDIO_FORMAT
51a48d372833ccec13c96ece9efcc226e8beac7f59Chong Zhang                | DISCONTINUITY_VIDEO_FORMAT,
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber    enum Flags {
55c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        // The 90kHz clock (PTS/DTS) is absolute, i.e. PTS=0 corresponds to
56c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        // a media time of 0.
57c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        // If this flag is _not_ specified, the first PTS encountered in a
58c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        // program of this stream will be assumed to correspond to media time 0
59c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber        // instead.
6087f2a558dd12043631e12c361abef301bf603140Andreas Huber        TS_TIMESTAMPS_ARE_ABSOLUTE = 1,
6187f2a558dd12043631e12c361abef301bf603140Andreas Huber        // Video PES packets contain exactly one (aligned) access unit.
6287f2a558dd12043631e12c361abef301bf603140Andreas Huber        ALIGNED_VIDEO_DATA         = 2,
63c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber    };
64c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber
65540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Event is used to signal sync point event at feedTSPacket().
66540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    struct SyncEvent {
67540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        SyncEvent(off64_t offset);
68540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
69540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        void init(off64_t offset, const sp<MediaSource> &source,
70540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim                int64_t timeUs);
71540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
729558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        bool hasReturnedData() const { return mHasReturnedData; }
739558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        void reset();
749558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        off64_t getOffset() const { return mOffset; }
759558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        const sp<MediaSource> &getMediaSource() const { return mMediaSource; }
769558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        int64_t getTimeUs() const { return mTimeUs; }
77540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
78540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    private:
799558f6dd733dc450270f38b9a139d384d273ce0aWei Jia        bool mHasReturnedData;
80540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        /*
819558f6dd733dc450270f38b9a139d384d273ce0aWei Jia         * mHasReturnedData == false: the current offset (or undefined if the returned data
829558f6dd733dc450270f38b9a139d384d273ce0aWei Jia                                      has been invalidated via reset())
839558f6dd733dc450270f38b9a139d384d273ce0aWei Jia         * mHasReturnedData == true: the start offset of sync payload
84540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim         */
85540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        off64_t mOffset;
86540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        /* The media source object for this event. */
87540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        sp<MediaSource> mMediaSource;
88540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        /* The timestamp of the sync frame. */
89540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        int64_t mTimeUs;
90540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    };
91540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
92c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber    ATSParser(uint32_t flags = 0);
93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
94540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Feed a TS packet into the parser. uninitialized event with the start
95540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // offset of this TS packet goes in, and if the parser detects PES with
96540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // a sync frame, the event will be initiailzed with the start offset of the
97540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // PES. Note that the offset of the event can be different from what we fed,
98540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // as a PES may consist of multiple TS packets.
99540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    //
100540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Even in the case feedTSPacket() returns non-OK value, event still may be
101540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // initialized if the parsing failed after the detection.
102540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    status_t feedTSPacket(
103540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim            const void *data, size_t size, SyncEvent *event = NULL);
10432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
10532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber    void signalDiscontinuity(
10632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber            DiscontinuityType type, const sp<AMessage> &extra);
10732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void signalEOS(status_t finalResult);
109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    enum SourceType {
11143ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih        VIDEO = 0,
11243ca783effd99bba0e6e2dd6fe177a8888578ef8Robert Shih        AUDIO = 1,
1130852843d304006e3ab333081fddda13b07193de8Robert Shih        META  = 2,
1140852843d304006e3ab333081fddda13b07193de8Robert Shih        NUM_SOURCE_TYPES = 3
115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    };
116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    sp<MediaSource> getSource(SourceType type);
117bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih    bool hasSource(SourceType type) const;
118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
11943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    bool PTSTimeDeltaEstablished();
12043c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber
121386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    enum {
122386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        // From ISO/IEC 13818-1: 2000 (E), Table 2-29
1232944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        STREAMTYPE_RESERVED             = 0x00,
124386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        STREAMTYPE_MPEG1_VIDEO          = 0x01,
125386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        STREAMTYPE_MPEG2_VIDEO          = 0x02,
126386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        STREAMTYPE_MPEG1_AUDIO          = 0x03,
127386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        STREAMTYPE_MPEG2_AUDIO          = 0x04,
1286e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber        STREAMTYPE_MPEG2_AUDIO_ADTS     = 0x0f,
129386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        STREAMTYPE_MPEG4_VIDEO          = 0x10,
1300852843d304006e3ab333081fddda13b07193de8Robert Shih        STREAMTYPE_METADATA             = 0x15,
131386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        STREAMTYPE_H264                 = 0x1b,
132dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
133dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        // From ATSC A/53 Part 3:2009, 6.7.1
134dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu        STREAMTYPE_AC3                  = 0x81,
135dd432ce03eccf280d83672f95076b6fbd561047fChangwan Ryu
1369bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang        // Stream type 0x83 is non-standard,
1379bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang        // it could be LPCM or TrueHD AC3
1389bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang        STREAMTYPE_LPCM_AC3             = 0x83,
139386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    };
140386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber
1412944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huberprotected:
1422944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber    virtual ~ATSParser();
1432944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber
1442944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huberprivate:
145cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    struct Program;
146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    struct Stream;
1478dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    struct PSISection;
148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
149c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber    uint32_t mFlags;
150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    Vector<sp<Program> > mPrograms;
151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
1528dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    // Keyed by PID
1538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber    KeyedVector<unsigned, sp<PSISection> > mPSISections;
1548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber
15587f2a558dd12043631e12c361abef301bf603140Andreas Huber    int64_t mAbsoluteTimeAnchorUs;
15687f2a558dd12043631e12c361abef301bf603140Andreas Huber
157d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    bool mTimeOffsetValid;
158d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    int64_t mTimeOffsetUs;
159d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang    int64_t mLastRecoveredPTS;
160d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
16187f2a558dd12043631e12c361abef301bf603140Andreas Huber    size_t mNumTSPacketsParsed;
16287f2a558dd12043631e12c361abef301bf603140Andreas Huber
163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    void parseProgramAssociationTable(ABitReader *br);
164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    void parseProgramMap(ABitReader *br);
165540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Parse PES packet where br is pointing to. If the PES contains a sync
166540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // frame, set event with the time and the start offset of this PES.
167540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Note that the method itself does not touch event.
168540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    void parsePES(ABitReader *br, SyncEvent *event);
169540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim
170540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Strip remaining packet headers and pass to appropriate program/stream
171540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // to parse the payload. If the payload turns out to be PES and contains
172540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // a sync frame, event shall be set with the time and start offset of the
173540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // PES.
174540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // Note that the method itself does not touch event.
17506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber    status_t parsePID(
176cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ABitReader *br, unsigned PID,
17787f2a558dd12043631e12c361abef301bf603140Andreas Huber        unsigned continuity_counter,
178540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        unsigned payload_unit_start_indicator,
179540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim        SyncEvent *event);
180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
181e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim    status_t parseAdaptationField(ABitReader *br, unsigned PID);
182540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    // see feedTSPacket().
183540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim    status_t parseTS(ABitReader *br, SyncEvent *event);
184cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
18519cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen    void updatePCR(unsigned PID, uint64_t PCR, uint64_t byteOffsetFromStart);
18687f2a558dd12043631e12c361abef301bf603140Andreas Huber
18787f2a558dd12043631e12c361abef301bf603140Andreas Huber    uint64_t mPCR[2];
18819cec89f8b05fd05f8034ee1a4cd39ee09c33f02Marco Nelissen    uint64_t mPCRBytes[2];
18987f2a558dd12043631e12c361abef301bf603140Andreas Huber    int64_t mSystemTimeUs[2];
19087f2a558dd12043631e12c361abef301bf603140Andreas Huber    size_t mNumPCRs;
19187f2a558dd12043631e12c361abef301bf603140Andreas Huber
192cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ATSParser);
193cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber};
194cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
195cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}  // namespace android
196cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
197cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#endif  // A_TS_PARSER_H_
198