ATSParser.cpp revision 9bcf3ae6c9a413afc7accb5b48db3e5c3c829785
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ATSParser"
19#include <utils/Log.h>
20
21#include "ATSParser.h"
22
23#include "AnotherPacketSource.h"
24#include "ESQueue.h"
25#include "include/avc_utils.h"
26
27#include <media/stagefright/foundation/ABitReader.h>
28#include <media/stagefright/foundation/ABuffer.h>
29#include <media/stagefright/foundation/ADebug.h>
30#include <media/stagefright/foundation/AMessage.h>
31#include <media/stagefright/foundation/hexdump.h>
32#include <media/stagefright/MediaDefs.h>
33#include <media/stagefright/MediaErrors.h>
34#include <media/stagefright/MetaData.h>
35#include <media/stagefright/Utils.h>
36#include <media/IStreamSource.h>
37#include <utils/KeyedVector.h>
38#include <utils/Vector.h>
39
40#include <inttypes.h>
41
42namespace android {
43
44// I want the expression "y" evaluated even if verbose logging is off.
45#define MY_LOGV(x, y) \
46    do { unsigned tmp = y; ALOGV(x, tmp); } while (0)
47
48static const size_t kTSPacketSize = 188;
49
50struct ATSParser::Program : public RefBase {
51    Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID);
52
53    bool parsePSISection(
54            unsigned pid, ABitReader *br, status_t *err);
55
56    bool parsePID(
57            unsigned pid, unsigned continuity_counter,
58            unsigned payload_unit_start_indicator,
59            ABitReader *br, status_t *err);
60
61    void signalDiscontinuity(
62            DiscontinuityType type, const sp<AMessage> &extra);
63
64    void signalEOS(status_t finalResult);
65
66    sp<MediaSource> getSource(SourceType type);
67    bool hasSource(SourceType type) const;
68
69    int64_t convertPTSToTimestamp(uint64_t PTS);
70
71    bool PTSTimeDeltaEstablished() const {
72        return mFirstPTSValid;
73    }
74
75    unsigned number() const { return mProgramNumber; }
76
77    void updateProgramMapPID(unsigned programMapPID) {
78        mProgramMapPID = programMapPID;
79    }
80
81    unsigned programMapPID() const {
82        return mProgramMapPID;
83    }
84
85    uint32_t parserFlags() const {
86        return mParser->mFlags;
87    }
88
89private:
90    struct StreamInfo {
91        unsigned mType;
92        unsigned mPID;
93    };
94
95    ATSParser *mParser;
96    unsigned mProgramNumber;
97    unsigned mProgramMapPID;
98    KeyedVector<unsigned, sp<Stream> > mStreams;
99    bool mFirstPTSValid;
100    uint64_t mFirstPTS;
101    int64_t mLastRecoveredPTS;
102
103    status_t parseProgramMap(ABitReader *br);
104    int64_t recoverPTS(uint64_t PTS_33bit);
105    bool switchPIDs(const Vector<StreamInfo> &infos);
106
107    DISALLOW_EVIL_CONSTRUCTORS(Program);
108};
109
110struct ATSParser::Stream : public RefBase {
111    Stream(Program *program,
112           unsigned elementaryPID,
113           unsigned streamType,
114           unsigned PCR_PID);
115
116    unsigned type() const { return mStreamType; }
117    unsigned pid() const { return mElementaryPID; }
118    void setPID(unsigned pid) { mElementaryPID = pid; }
119
120    status_t parse(
121            unsigned continuity_counter,
122            unsigned payload_unit_start_indicator,
123            ABitReader *br);
124
125    void signalDiscontinuity(
126            DiscontinuityType type, const sp<AMessage> &extra);
127
128    void signalEOS(status_t finalResult);
129
130    sp<MediaSource> getSource(SourceType type);
131
132    bool isAudio() const;
133    bool isVideo() const;
134
135protected:
136    virtual ~Stream();
137
138private:
139    Program *mProgram;
140    unsigned mElementaryPID;
141    unsigned mStreamType;
142    unsigned mPCR_PID;
143    int32_t mExpectedContinuityCounter;
144
145    sp<ABuffer> mBuffer;
146    sp<AnotherPacketSource> mSource;
147    bool mPayloadStarted;
148
149    uint64_t mPrevPTS;
150
151    ElementaryStreamQueue *mQueue;
152
153    status_t flush();
154    status_t parsePES(ABitReader *br);
155
156    void onPayloadData(
157            unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
158            const uint8_t *data, size_t size);
159
160    void extractAACFrames(const sp<ABuffer> &buffer);
161
162    DISALLOW_EVIL_CONSTRUCTORS(Stream);
163};
164
165struct ATSParser::PSISection : public RefBase {
166    PSISection();
167
168    status_t append(const void *data, size_t size);
169    void clear();
170
171    bool isComplete() const;
172    bool isEmpty() const;
173
174    const uint8_t *data() const;
175    size_t size() const;
176
177protected:
178    virtual ~PSISection();
179
180private:
181    sp<ABuffer> mBuffer;
182
183    DISALLOW_EVIL_CONSTRUCTORS(PSISection);
184};
185
186////////////////////////////////////////////////////////////////////////////////
187
188ATSParser::Program::Program(
189        ATSParser *parser, unsigned programNumber, unsigned programMapPID)
190    : mParser(parser),
191      mProgramNumber(programNumber),
192      mProgramMapPID(programMapPID),
193      mFirstPTSValid(false),
194      mFirstPTS(0),
195      mLastRecoveredPTS(-1ll) {
196    ALOGV("new program number %u", programNumber);
197}
198
199bool ATSParser::Program::parsePSISection(
200        unsigned pid, ABitReader *br, status_t *err) {
201    *err = OK;
202
203    if (pid != mProgramMapPID) {
204        return false;
205    }
206
207    *err = parseProgramMap(br);
208
209    return true;
210}
211
212bool ATSParser::Program::parsePID(
213        unsigned pid, unsigned continuity_counter,
214        unsigned payload_unit_start_indicator,
215        ABitReader *br, status_t *err) {
216    *err = OK;
217
218    ssize_t index = mStreams.indexOfKey(pid);
219    if (index < 0) {
220        return false;
221    }
222
223    *err = mStreams.editValueAt(index)->parse(
224            continuity_counter, payload_unit_start_indicator, br);
225
226    return true;
227}
228
229void ATSParser::Program::signalDiscontinuity(
230        DiscontinuityType type, const sp<AMessage> &extra) {
231    int64_t mediaTimeUs;
232    if ((type & DISCONTINUITY_TIME)
233            && extra != NULL
234            && extra->findInt64(
235                IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) {
236        mFirstPTSValid = false;
237    }
238
239    for (size_t i = 0; i < mStreams.size(); ++i) {
240        mStreams.editValueAt(i)->signalDiscontinuity(type, extra);
241    }
242}
243
244void ATSParser::Program::signalEOS(status_t finalResult) {
245    for (size_t i = 0; i < mStreams.size(); ++i) {
246        mStreams.editValueAt(i)->signalEOS(finalResult);
247    }
248}
249
250bool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) {
251    bool success = false;
252
253    if (mStreams.size() == infos.size()) {
254        // build type->PIDs map for old and new mapping
255        size_t i;
256        KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs;
257        for (i = 0; i < mStreams.size(); ++i) {
258            ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type());
259            if (index < 0) {
260                oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>());
261            }
262            oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid());
263        }
264        for (i = 0; i < infos.size(); ++i) {
265            ssize_t index = newType2PIDs.indexOfKey(infos[i].mType);
266            if (index < 0) {
267                newType2PIDs.add(infos[i].mType, Vector<int32_t>());
268            }
269            newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID);
270        }
271
272        // we can recover if the number of streams for each type hasn't changed
273        if (oldType2PIDs.size() == newType2PIDs.size()) {
274            success = true;
275            for (i = 0; i < oldType2PIDs.size(); ++i) {
276                // KeyedVector is sorted, we just compare key and size of each index
277                if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i)
278                        || oldType2PIDs[i].size() != newType2PIDs[i].size()) {
279                     success = false;
280                     break;
281                }
282            }
283        }
284
285        if (success) {
286            // save current streams to temp
287            KeyedVector<int32_t, sp<Stream> > temp;
288            for (i = 0; i < mStreams.size(); ++i) {
289                 temp.add(mStreams.keyAt(i), mStreams.editValueAt(i));
290            }
291
292            mStreams.clear();
293            for (i = 0; i < temp.size(); ++i) {
294                // The two checks below shouldn't happen,
295                // we already checked above the stream count matches
296                ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
297                CHECK(index >= 0);
298                Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
299                CHECK(newPIDs.size() > 0);
300
301                // get the next PID for temp[i]->type() in the new PID map
302                Vector<int32_t>::iterator it = newPIDs.begin();
303
304                // change the PID of the stream, and add it back
305                temp.editValueAt(i)->setPID(*it);
306                mStreams.add(temp[i]->pid(), temp.editValueAt(i));
307
308                // removed the used PID
309                newPIDs.erase(it);
310            }
311        }
312    }
313    return success;
314}
315
316status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
317    unsigned table_id = br->getBits(8);
318    ALOGV("  table_id = %u", table_id);
319    if (table_id != 0x02u) {
320        ALOGE("PMT data error!");
321        return ERROR_MALFORMED;
322    }
323    unsigned section_syntax_indicator = br->getBits(1);
324    ALOGV("  section_syntax_indicator = %u", section_syntax_indicator);
325    if (section_syntax_indicator != 1u) {
326        ALOGE("PMT data error!");
327        return ERROR_MALFORMED;
328    }
329
330    CHECK_EQ(br->getBits(1), 0u);
331    MY_LOGV("  reserved = %u", br->getBits(2));
332
333    unsigned section_length = br->getBits(12);
334    ALOGV("  section_length = %u", section_length);
335    CHECK_EQ(section_length & 0xc00, 0u);
336    CHECK_LE(section_length, 1021u);
337
338    MY_LOGV("  program_number = %u", br->getBits(16));
339    MY_LOGV("  reserved = %u", br->getBits(2));
340    MY_LOGV("  version_number = %u", br->getBits(5));
341    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
342    MY_LOGV("  section_number = %u", br->getBits(8));
343    MY_LOGV("  last_section_number = %u", br->getBits(8));
344    MY_LOGV("  reserved = %u", br->getBits(3));
345
346    unsigned PCR_PID = br->getBits(13);
347    ALOGV("  PCR_PID = 0x%04x", PCR_PID);
348
349    MY_LOGV("  reserved = %u", br->getBits(4));
350
351    unsigned program_info_length = br->getBits(12);
352    ALOGV("  program_info_length = %u", program_info_length);
353    CHECK_EQ(program_info_length & 0xc00, 0u);
354
355    br->skipBits(program_info_length * 8);  // skip descriptors
356
357    Vector<StreamInfo> infos;
358
359    // infoBytesRemaining is the number of bytes that make up the
360    // variable length section of ES_infos. It does not include the
361    // final CRC.
362    size_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
363
364    while (infoBytesRemaining > 0) {
365        CHECK_GE(infoBytesRemaining, 5u);
366
367        unsigned streamType = br->getBits(8);
368        ALOGV("    stream_type = 0x%02x", streamType);
369
370        MY_LOGV("    reserved = %u", br->getBits(3));
371
372        unsigned elementaryPID = br->getBits(13);
373        ALOGV("    elementary_PID = 0x%04x", elementaryPID);
374
375        MY_LOGV("    reserved = %u", br->getBits(4));
376
377        unsigned ES_info_length = br->getBits(12);
378        ALOGV("    ES_info_length = %u", ES_info_length);
379        CHECK_EQ(ES_info_length & 0xc00, 0u);
380
381        CHECK_GE(infoBytesRemaining - 5, ES_info_length);
382
383#if 0
384        br->skipBits(ES_info_length * 8);  // skip descriptors
385#else
386        unsigned info_bytes_remaining = ES_info_length;
387        while (info_bytes_remaining >= 2) {
388            MY_LOGV("      tag = 0x%02x", br->getBits(8));
389
390            unsigned descLength = br->getBits(8);
391            ALOGV("      len = %u", descLength);
392
393            CHECK_GE(info_bytes_remaining, 2 + descLength);
394
395            br->skipBits(descLength * 8);
396
397            info_bytes_remaining -= descLength + 2;
398        }
399        CHECK_EQ(info_bytes_remaining, 0u);
400#endif
401
402        StreamInfo info;
403        info.mType = streamType;
404        info.mPID = elementaryPID;
405        infos.push(info);
406
407        infoBytesRemaining -= 5 + ES_info_length;
408    }
409
410    CHECK_EQ(infoBytesRemaining, 0u);
411    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
412
413    bool PIDsChanged = false;
414    for (size_t i = 0; i < infos.size(); ++i) {
415        StreamInfo &info = infos.editItemAt(i);
416
417        ssize_t index = mStreams.indexOfKey(info.mPID);
418
419        if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
420            ALOGI("uh oh. stream PIDs have changed.");
421            PIDsChanged = true;
422            break;
423        }
424    }
425
426    if (PIDsChanged) {
427#if 0
428        ALOGI("before:");
429        for (size_t i = 0; i < mStreams.size(); ++i) {
430            sp<Stream> stream = mStreams.editValueAt(i);
431
432            ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type());
433        }
434
435        ALOGI("after:");
436        for (size_t i = 0; i < infos.size(); ++i) {
437            StreamInfo &info = infos.editItemAt(i);
438
439            ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType);
440        }
441#endif
442
443        // we can recover if number of streams for each type remain the same
444        bool success = switchPIDs(infos);
445
446        if (!success) {
447            ALOGI("Stream PIDs changed and we cannot recover.");
448            return ERROR_MALFORMED;
449        }
450    }
451
452    for (size_t i = 0; i < infos.size(); ++i) {
453        StreamInfo &info = infos.editItemAt(i);
454
455        ssize_t index = mStreams.indexOfKey(info.mPID);
456
457        if (index < 0) {
458            sp<Stream> stream = new Stream(
459                    this, info.mPID, info.mType, PCR_PID);
460
461            mStreams.add(info.mPID, stream);
462        }
463    }
464
465    return OK;
466}
467
468int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
469    // We only have the lower 33-bit of the PTS. It could overflow within a
470    // reasonable amount of time. To handle the wrap-around, use fancy math
471    // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
472    // of the latest recovered PTS.
473    if (mLastRecoveredPTS < 0ll) {
474        // Use the original 33bit number for 1st frame, the reason is that
475        // if 1st frame wraps to negative that's far away from 0, we could
476        // never start. Only start wrapping around from 2nd frame.
477        mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
478    } else {
479        mLastRecoveredPTS = static_cast<int64_t>(
480                ((mLastRecoveredPTS - PTS_33bit + 0x100000000ll)
481                & 0xfffffffe00000000ull) | PTS_33bit);
482        // We start from 0, but recovered PTS could be slightly below 0.
483        // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
484        // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
485        if (mLastRecoveredPTS < 0ll) {
486            ALOGI("Clamping negative recovered PTS (%lld) to 0", mLastRecoveredPTS);
487            mLastRecoveredPTS = 0ll;
488        }
489    }
490
491    return mLastRecoveredPTS;
492}
493
494sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
495    size_t index = (type == AUDIO) ? 0 : 0;
496
497    for (size_t i = 0; i < mStreams.size(); ++i) {
498        sp<MediaSource> source = mStreams.editValueAt(i)->getSource(type);
499        if (source != NULL) {
500            if (index == 0) {
501                return source;
502            }
503            --index;
504        }
505    }
506
507    return NULL;
508}
509
510bool ATSParser::Program::hasSource(SourceType type) const {
511    for (size_t i = 0; i < mStreams.size(); ++i) {
512        const sp<Stream> &stream = mStreams.valueAt(i);
513        if (type == AUDIO && stream->isAudio()) {
514            return true;
515        } else if (type == VIDEO && stream->isVideo()) {
516            return true;
517        }
518    }
519
520    return false;
521}
522
523int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
524    PTS = recoverPTS(PTS);
525
526    if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
527        if (!mFirstPTSValid) {
528            mFirstPTSValid = true;
529            mFirstPTS = PTS;
530            PTS = 0;
531        } else if (PTS < mFirstPTS) {
532            PTS = 0;
533        } else {
534            PTS -= mFirstPTS;
535        }
536    }
537
538    int64_t timeUs = (PTS * 100) / 9;
539
540    if (mParser->mAbsoluteTimeAnchorUs >= 0ll) {
541        timeUs += mParser->mAbsoluteTimeAnchorUs;
542    }
543
544    if (mParser->mTimeOffsetValid) {
545        timeUs += mParser->mTimeOffsetUs;
546    }
547
548    return timeUs;
549}
550
551////////////////////////////////////////////////////////////////////////////////
552
553ATSParser::Stream::Stream(
554        Program *program,
555        unsigned elementaryPID,
556        unsigned streamType,
557        unsigned PCR_PID)
558    : mProgram(program),
559      mElementaryPID(elementaryPID),
560      mStreamType(streamType),
561      mPCR_PID(PCR_PID),
562      mExpectedContinuityCounter(-1),
563      mPayloadStarted(false),
564      mPrevPTS(0),
565      mQueue(NULL) {
566    switch (mStreamType) {
567        case STREAMTYPE_H264:
568            mQueue = new ElementaryStreamQueue(
569                    ElementaryStreamQueue::H264,
570                    (mProgram->parserFlags() & ALIGNED_VIDEO_DATA)
571                        ? ElementaryStreamQueue::kFlag_AlignedData : 0);
572            break;
573        case STREAMTYPE_MPEG2_AUDIO_ADTS:
574            mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC);
575            break;
576        case STREAMTYPE_MPEG1_AUDIO:
577        case STREAMTYPE_MPEG2_AUDIO:
578            mQueue = new ElementaryStreamQueue(
579                    ElementaryStreamQueue::MPEG_AUDIO);
580            break;
581
582        case STREAMTYPE_MPEG1_VIDEO:
583        case STREAMTYPE_MPEG2_VIDEO:
584            mQueue = new ElementaryStreamQueue(
585                    ElementaryStreamQueue::MPEG_VIDEO);
586            break;
587
588        case STREAMTYPE_MPEG4_VIDEO:
589            mQueue = new ElementaryStreamQueue(
590                    ElementaryStreamQueue::MPEG4_VIDEO);
591            break;
592
593        case STREAMTYPE_LPCM_AC3:
594        case STREAMTYPE_AC3:
595            mQueue = new ElementaryStreamQueue(
596                    ElementaryStreamQueue::AC3);
597            break;
598
599        default:
600            break;
601    }
602
603    ALOGV("new stream PID 0x%02x, type 0x%02x", elementaryPID, streamType);
604
605    if (mQueue != NULL) {
606        mBuffer = new ABuffer(192 * 1024);
607        mBuffer->setRange(0, 0);
608    }
609}
610
611ATSParser::Stream::~Stream() {
612    delete mQueue;
613    mQueue = NULL;
614}
615
616status_t ATSParser::Stream::parse(
617        unsigned continuity_counter,
618        unsigned payload_unit_start_indicator, ABitReader *br) {
619    if (mQueue == NULL) {
620        return OK;
621    }
622
623    if (mExpectedContinuityCounter >= 0
624            && (unsigned)mExpectedContinuityCounter != continuity_counter) {
625        ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
626
627        mPayloadStarted = false;
628        mBuffer->setRange(0, 0);
629        mExpectedContinuityCounter = -1;
630
631#if 0
632        // Uncomment this if you'd rather see no corruption whatsoever on
633        // screen and suspend updates until we come across another IDR frame.
634
635        if (mStreamType == STREAMTYPE_H264) {
636            ALOGI("clearing video queue");
637            mQueue->clear(true /* clearFormat */);
638        }
639#endif
640
641        if (!payload_unit_start_indicator) {
642            return OK;
643        }
644    }
645
646    mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f;
647
648    if (payload_unit_start_indicator) {
649        if (mPayloadStarted) {
650            // Otherwise we run the danger of receiving the trailing bytes
651            // of a PES packet that we never saw the start of and assuming
652            // we have a a complete PES packet.
653
654            status_t err = flush();
655
656            if (err != OK) {
657                return err;
658            }
659        }
660
661        mPayloadStarted = true;
662    }
663
664    if (!mPayloadStarted) {
665        return OK;
666    }
667
668    size_t payloadSizeBits = br->numBitsLeft();
669    CHECK_EQ(payloadSizeBits % 8, 0u);
670
671    size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
672    if (mBuffer->capacity() < neededSize) {
673        // Increment in multiples of 64K.
674        neededSize = (neededSize + 65535) & ~65535;
675
676        ALOGI("resizing buffer to %zu bytes", neededSize);
677
678        sp<ABuffer> newBuffer = new ABuffer(neededSize);
679        memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
680        newBuffer->setRange(0, mBuffer->size());
681        mBuffer = newBuffer;
682    }
683
684    memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
685    mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
686
687    return OK;
688}
689
690bool ATSParser::Stream::isVideo() const {
691    switch (mStreamType) {
692        case STREAMTYPE_H264:
693        case STREAMTYPE_MPEG1_VIDEO:
694        case STREAMTYPE_MPEG2_VIDEO:
695        case STREAMTYPE_MPEG4_VIDEO:
696            return true;
697
698        default:
699            return false;
700    }
701}
702
703bool ATSParser::Stream::isAudio() const {
704    switch (mStreamType) {
705        case STREAMTYPE_MPEG1_AUDIO:
706        case STREAMTYPE_MPEG2_AUDIO:
707        case STREAMTYPE_MPEG2_AUDIO_ADTS:
708        case STREAMTYPE_LPCM_AC3:
709        case STREAMTYPE_AC3:
710            return true;
711
712        default:
713            return false;
714    }
715}
716
717void ATSParser::Stream::signalDiscontinuity(
718        DiscontinuityType type, const sp<AMessage> &extra) {
719    mExpectedContinuityCounter = -1;
720
721    if (mQueue == NULL) {
722        return;
723    }
724
725    mPayloadStarted = false;
726    mBuffer->setRange(0, 0);
727
728    bool clearFormat = false;
729    if (isAudio()) {
730        if (type & DISCONTINUITY_AUDIO_FORMAT) {
731            clearFormat = true;
732        }
733    } else {
734        if (type & DISCONTINUITY_VIDEO_FORMAT) {
735            clearFormat = true;
736        }
737    }
738
739    mQueue->clear(clearFormat);
740
741    if (type & DISCONTINUITY_TIME) {
742        uint64_t resumeAtPTS;
743        if (extra != NULL
744                && extra->findInt64(
745                    IStreamListener::kKeyResumeAtPTS,
746                    (int64_t *)&resumeAtPTS)) {
747            int64_t resumeAtMediaTimeUs =
748                mProgram->convertPTSToTimestamp(resumeAtPTS);
749
750            extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs);
751        }
752    }
753
754    if (mSource != NULL) {
755        mSource->queueDiscontinuity(type, extra, true);
756    }
757}
758
759void ATSParser::Stream::signalEOS(status_t finalResult) {
760    if (mSource != NULL) {
761        mSource->signalEOS(finalResult);
762    }
763}
764
765status_t ATSParser::Stream::parsePES(ABitReader *br) {
766    unsigned packet_startcode_prefix = br->getBits(24);
767
768    ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
769
770    if (packet_startcode_prefix != 1) {
771        ALOGV("Supposedly payload_unit_start=1 unit does not start "
772             "with startcode.");
773
774        return ERROR_MALFORMED;
775    }
776
777    CHECK_EQ(packet_startcode_prefix, 0x000001u);
778
779    unsigned stream_id = br->getBits(8);
780    ALOGV("stream_id = 0x%02x", stream_id);
781
782    unsigned PES_packet_length = br->getBits(16);
783    ALOGV("PES_packet_length = %u", PES_packet_length);
784
785    if (stream_id != 0xbc  // program_stream_map
786            && stream_id != 0xbe  // padding_stream
787            && stream_id != 0xbf  // private_stream_2
788            && stream_id != 0xf0  // ECM
789            && stream_id != 0xf1  // EMM
790            && stream_id != 0xff  // program_stream_directory
791            && stream_id != 0xf2  // DSMCC
792            && stream_id != 0xf8) {  // H.222.1 type E
793        CHECK_EQ(br->getBits(2), 2u);
794
795        MY_LOGV("PES_scrambling_control = %u", br->getBits(2));
796        MY_LOGV("PES_priority = %u", br->getBits(1));
797        MY_LOGV("data_alignment_indicator = %u", br->getBits(1));
798        MY_LOGV("copyright = %u", br->getBits(1));
799        MY_LOGV("original_or_copy = %u", br->getBits(1));
800
801        unsigned PTS_DTS_flags = br->getBits(2);
802        ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags);
803
804        unsigned ESCR_flag = br->getBits(1);
805        ALOGV("ESCR_flag = %u", ESCR_flag);
806
807        unsigned ES_rate_flag = br->getBits(1);
808        ALOGV("ES_rate_flag = %u", ES_rate_flag);
809
810        unsigned DSM_trick_mode_flag = br->getBits(1);
811        ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);
812
813        unsigned additional_copy_info_flag = br->getBits(1);
814        ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag);
815
816        MY_LOGV("PES_CRC_flag = %u", br->getBits(1));
817        MY_LOGV("PES_extension_flag = %u", br->getBits(1));
818
819        unsigned PES_header_data_length = br->getBits(8);
820        ALOGV("PES_header_data_length = %u", PES_header_data_length);
821
822        unsigned optional_bytes_remaining = PES_header_data_length;
823
824        uint64_t PTS = 0, DTS = 0;
825
826        if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
827            CHECK_GE(optional_bytes_remaining, 5u);
828
829            if (br->getBits(4) != PTS_DTS_flags) {
830                ALOGE("PES data Error!");
831                return ERROR_MALFORMED;
832            }
833            PTS = ((uint64_t)br->getBits(3)) << 30;
834            CHECK_EQ(br->getBits(1), 1u);
835            PTS |= ((uint64_t)br->getBits(15)) << 15;
836            CHECK_EQ(br->getBits(1), 1u);
837            PTS |= br->getBits(15);
838            CHECK_EQ(br->getBits(1), 1u);
839
840            ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);
841
842            optional_bytes_remaining -= 5;
843
844            if (PTS_DTS_flags == 3) {
845                CHECK_GE(optional_bytes_remaining, 5u);
846
847                CHECK_EQ(br->getBits(4), 1u);
848
849                DTS = ((uint64_t)br->getBits(3)) << 30;
850                CHECK_EQ(br->getBits(1), 1u);
851                DTS |= ((uint64_t)br->getBits(15)) << 15;
852                CHECK_EQ(br->getBits(1), 1u);
853                DTS |= br->getBits(15);
854                CHECK_EQ(br->getBits(1), 1u);
855
856                ALOGV("DTS = %" PRIu64, DTS);
857
858                optional_bytes_remaining -= 5;
859            }
860        }
861
862        if (ESCR_flag) {
863            CHECK_GE(optional_bytes_remaining, 6u);
864
865            br->getBits(2);
866
867            uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
868            CHECK_EQ(br->getBits(1), 1u);
869            ESCR |= ((uint64_t)br->getBits(15)) << 15;
870            CHECK_EQ(br->getBits(1), 1u);
871            ESCR |= br->getBits(15);
872            CHECK_EQ(br->getBits(1), 1u);
873
874            ALOGV("ESCR = %" PRIu64, ESCR);
875            MY_LOGV("ESCR_extension = %u", br->getBits(9));
876
877            CHECK_EQ(br->getBits(1), 1u);
878
879            optional_bytes_remaining -= 6;
880        }
881
882        if (ES_rate_flag) {
883            CHECK_GE(optional_bytes_remaining, 3u);
884
885            CHECK_EQ(br->getBits(1), 1u);
886            MY_LOGV("ES_rate = %u", br->getBits(22));
887            CHECK_EQ(br->getBits(1), 1u);
888
889            optional_bytes_remaining -= 3;
890        }
891
892        br->skipBits(optional_bytes_remaining * 8);
893
894        // ES data follows.
895
896        if (PES_packet_length != 0) {
897            CHECK_GE(PES_packet_length, PES_header_data_length + 3);
898
899            unsigned dataLength =
900                PES_packet_length - 3 - PES_header_data_length;
901
902            if (br->numBitsLeft() < dataLength * 8) {
903                ALOGE("PES packet does not carry enough data to contain "
904                     "payload. (numBitsLeft = %zu, required = %u)",
905                     br->numBitsLeft(), dataLength * 8);
906
907                return ERROR_MALFORMED;
908            }
909
910            CHECK_GE(br->numBitsLeft(), dataLength * 8);
911
912            onPayloadData(
913                    PTS_DTS_flags, PTS, DTS, br->data(), dataLength);
914
915            br->skipBits(dataLength * 8);
916        } else {
917            onPayloadData(
918                    PTS_DTS_flags, PTS, DTS,
919                    br->data(), br->numBitsLeft() / 8);
920
921            size_t payloadSizeBits = br->numBitsLeft();
922            CHECK_EQ(payloadSizeBits % 8, 0u);
923
924            ALOGV("There's %zu bytes of payload.", payloadSizeBits / 8);
925        }
926    } else if (stream_id == 0xbe) {  // padding_stream
927        CHECK_NE(PES_packet_length, 0u);
928        br->skipBits(PES_packet_length * 8);
929    } else {
930        CHECK_NE(PES_packet_length, 0u);
931        br->skipBits(PES_packet_length * 8);
932    }
933
934    return OK;
935}
936
937status_t ATSParser::Stream::flush() {
938    if (mBuffer->size() == 0) {
939        return OK;
940    }
941
942    ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size());
943
944    ABitReader br(mBuffer->data(), mBuffer->size());
945
946    status_t err = parsePES(&br);
947
948    mBuffer->setRange(0, 0);
949
950    return err;
951}
952
953void ATSParser::Stream::onPayloadData(
954        unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
955        const uint8_t *data, size_t size) {
956#if 0
957    ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
958          mStreamType,
959          PTS,
960          (int64_t)PTS - mPrevPTS);
961    mPrevPTS = PTS;
962#endif
963
964    ALOGV("onPayloadData mStreamType=0x%02x", mStreamType);
965
966    int64_t timeUs = 0ll;  // no presentation timestamp available.
967    if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
968        timeUs = mProgram->convertPTSToTimestamp(PTS);
969    }
970
971    status_t err = mQueue->appendData(data, size, timeUs);
972
973    if (err != OK) {
974        return;
975    }
976
977    sp<ABuffer> accessUnit;
978    while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
979        if (mSource == NULL) {
980            sp<MetaData> meta = mQueue->getFormat();
981
982            if (meta != NULL) {
983                ALOGV("Stream PID 0x%08x of type 0x%02x now has data.",
984                     mElementaryPID, mStreamType);
985
986                const char *mime;
987                if (meta->findCString(kKeyMIMEType, &mime)
988                        && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
989                        && !IsIDR(accessUnit)) {
990                    continue;
991                }
992                mSource = new AnotherPacketSource(meta);
993                mSource->queueAccessUnit(accessUnit);
994            }
995        } else if (mQueue->getFormat() != NULL) {
996            // After a discontinuity we invalidate the queue's format
997            // and won't enqueue any access units to the source until
998            // the queue has reestablished the new format.
999
1000            if (mSource->getFormat() == NULL) {
1001                mSource->setFormat(mQueue->getFormat());
1002            }
1003            mSource->queueAccessUnit(accessUnit);
1004        }
1005    }
1006}
1007
1008sp<MediaSource> ATSParser::Stream::getSource(SourceType type) {
1009    switch (type) {
1010        case VIDEO:
1011        {
1012            if (isVideo()) {
1013                return mSource;
1014            }
1015            break;
1016        }
1017
1018        case AUDIO:
1019        {
1020            if (isAudio()) {
1021                return mSource;
1022            }
1023            break;
1024        }
1025
1026        default:
1027            break;
1028    }
1029
1030    return NULL;
1031}
1032
1033////////////////////////////////////////////////////////////////////////////////
1034
1035ATSParser::ATSParser(uint32_t flags)
1036    : mFlags(flags),
1037      mAbsoluteTimeAnchorUs(-1ll),
1038      mTimeOffsetValid(false),
1039      mTimeOffsetUs(0ll),
1040      mNumTSPacketsParsed(0),
1041      mNumPCRs(0) {
1042    mPSISections.add(0 /* PID */, new PSISection);
1043}
1044
1045ATSParser::~ATSParser() {
1046}
1047
1048status_t ATSParser::feedTSPacket(const void *data, size_t size) {
1049    CHECK_EQ(size, kTSPacketSize);
1050
1051    ABitReader br((const uint8_t *)data, kTSPacketSize);
1052    return parseTS(&br);
1053}
1054
1055void ATSParser::signalDiscontinuity(
1056        DiscontinuityType type, const sp<AMessage> &extra) {
1057    int64_t mediaTimeUs;
1058    if ((type & DISCONTINUITY_TIME)
1059            && extra != NULL
1060            && extra->findInt64(
1061                IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) {
1062        mAbsoluteTimeAnchorUs = mediaTimeUs;
1063    } else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
1064        int64_t timeUs;
1065        CHECK(extra->findInt64("timeUs", &timeUs));
1066
1067        CHECK(mPrograms.empty());
1068        mAbsoluteTimeAnchorUs = timeUs;
1069        return;
1070    } else if (type == DISCONTINUITY_TIME_OFFSET) {
1071        int64_t offset;
1072        CHECK(extra->findInt64("offset", &offset));
1073
1074        mTimeOffsetValid = true;
1075        mTimeOffsetUs = offset;
1076        return;
1077    }
1078
1079    for (size_t i = 0; i < mPrograms.size(); ++i) {
1080        mPrograms.editItemAt(i)->signalDiscontinuity(type, extra);
1081    }
1082}
1083
1084void ATSParser::signalEOS(status_t finalResult) {
1085    CHECK_NE(finalResult, (status_t)OK);
1086
1087    for (size_t i = 0; i < mPrograms.size(); ++i) {
1088        mPrograms.editItemAt(i)->signalEOS(finalResult);
1089    }
1090}
1091
1092void ATSParser::parseProgramAssociationTable(ABitReader *br) {
1093    unsigned table_id = br->getBits(8);
1094    ALOGV("  table_id = %u", table_id);
1095    if (table_id != 0x00u) {
1096        ALOGE("PAT data error!");
1097        return ;
1098    }
1099    unsigned section_syntax_indictor = br->getBits(1);
1100    ALOGV("  section_syntax_indictor = %u", section_syntax_indictor);
1101    CHECK_EQ(section_syntax_indictor, 1u);
1102
1103    CHECK_EQ(br->getBits(1), 0u);
1104    MY_LOGV("  reserved = %u", br->getBits(2));
1105
1106    unsigned section_length = br->getBits(12);
1107    ALOGV("  section_length = %u", section_length);
1108    CHECK_EQ(section_length & 0xc00, 0u);
1109
1110    MY_LOGV("  transport_stream_id = %u", br->getBits(16));
1111    MY_LOGV("  reserved = %u", br->getBits(2));
1112    MY_LOGV("  version_number = %u", br->getBits(5));
1113    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
1114    MY_LOGV("  section_number = %u", br->getBits(8));
1115    MY_LOGV("  last_section_number = %u", br->getBits(8));
1116
1117    size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);
1118    CHECK_EQ((numProgramBytes % 4), 0u);
1119
1120    for (size_t i = 0; i < numProgramBytes / 4; ++i) {
1121        unsigned program_number = br->getBits(16);
1122        ALOGV("    program_number = %u", program_number);
1123
1124        MY_LOGV("    reserved = %u", br->getBits(3));
1125
1126        if (program_number == 0) {
1127            MY_LOGV("    network_PID = 0x%04x", br->getBits(13));
1128        } else {
1129            unsigned programMapPID = br->getBits(13);
1130
1131            ALOGV("    program_map_PID = 0x%04x", programMapPID);
1132
1133            bool found = false;
1134            for (size_t index = 0; index < mPrograms.size(); ++index) {
1135                const sp<Program> &program = mPrograms.itemAt(index);
1136
1137                if (program->number() == program_number) {
1138                    program->updateProgramMapPID(programMapPID);
1139                    found = true;
1140                    break;
1141                }
1142            }
1143
1144            if (!found) {
1145                mPrograms.push(
1146                        new Program(this, program_number, programMapPID));
1147            }
1148
1149            if (mPSISections.indexOfKey(programMapPID) < 0) {
1150                mPSISections.add(programMapPID, new PSISection);
1151            }
1152        }
1153    }
1154
1155    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
1156}
1157
1158status_t ATSParser::parsePID(
1159        ABitReader *br, unsigned PID,
1160        unsigned continuity_counter,
1161        unsigned payload_unit_start_indicator) {
1162    ssize_t sectionIndex = mPSISections.indexOfKey(PID);
1163
1164    if (sectionIndex >= 0) {
1165        sp<PSISection> section = mPSISections.valueAt(sectionIndex);
1166
1167        if (payload_unit_start_indicator) {
1168            if (!section->isEmpty()) {
1169                ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty");
1170                section->clear();
1171            }
1172
1173            unsigned skip = br->getBits(8);
1174            br->skipBits(skip * 8);
1175        }
1176
1177        CHECK((br->numBitsLeft() % 8) == 0);
1178        status_t err = section->append(br->data(), br->numBitsLeft() / 8);
1179
1180        if (err != OK) {
1181            return err;
1182        }
1183
1184        if (!section->isComplete()) {
1185            return OK;
1186        }
1187
1188        ABitReader sectionBits(section->data(), section->size());
1189
1190        if (PID == 0) {
1191            parseProgramAssociationTable(&sectionBits);
1192        } else {
1193            bool handled = false;
1194            for (size_t i = 0; i < mPrograms.size(); ++i) {
1195                status_t err;
1196                if (!mPrograms.editItemAt(i)->parsePSISection(
1197                            PID, &sectionBits, &err)) {
1198                    continue;
1199                }
1200
1201                if (err != OK) {
1202                    return err;
1203                }
1204
1205                handled = true;
1206                break;
1207            }
1208
1209            if (!handled) {
1210                mPSISections.removeItem(PID);
1211                section.clear();
1212            }
1213        }
1214
1215        if (section != NULL) {
1216            section->clear();
1217        }
1218
1219        return OK;
1220    }
1221
1222    bool handled = false;
1223    for (size_t i = 0; i < mPrograms.size(); ++i) {
1224        status_t err;
1225        if (mPrograms.editItemAt(i)->parsePID(
1226                    PID, continuity_counter, payload_unit_start_indicator,
1227                    br, &err)) {
1228            if (err != OK) {
1229                return err;
1230            }
1231
1232            handled = true;
1233            break;
1234        }
1235    }
1236
1237    if (!handled) {
1238        ALOGV("PID 0x%04x not handled.", PID);
1239    }
1240
1241    return OK;
1242}
1243
1244void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) {
1245    unsigned adaptation_field_length = br->getBits(8);
1246
1247    if (adaptation_field_length > 0) {
1248        unsigned discontinuity_indicator = br->getBits(1);
1249
1250        if (discontinuity_indicator) {
1251            ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID);
1252        }
1253
1254        br->skipBits(2);
1255        unsigned PCR_flag = br->getBits(1);
1256
1257        size_t numBitsRead = 4;
1258
1259        if (PCR_flag) {
1260            br->skipBits(4);
1261            uint64_t PCR_base = br->getBits(32);
1262            PCR_base = (PCR_base << 1) | br->getBits(1);
1263
1264            br->skipBits(6);
1265            unsigned PCR_ext = br->getBits(9);
1266
1267            // The number of bytes from the start of the current
1268            // MPEG2 transport stream packet up and including
1269            // the final byte of this PCR_ext field.
1270            size_t byteOffsetFromStartOfTSPacket =
1271                (188 - br->numBitsLeft() / 8);
1272
1273            uint64_t PCR = PCR_base * 300 + PCR_ext;
1274
1275            ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)",
1276                  PID, PCR, PCR / 27E6);
1277
1278            // The number of bytes received by this parser up to and
1279            // including the final byte of this PCR_ext field.
1280            size_t byteOffsetFromStart =
1281                mNumTSPacketsParsed * 188 + byteOffsetFromStartOfTSPacket;
1282
1283            for (size_t i = 0; i < mPrograms.size(); ++i) {
1284                updatePCR(PID, PCR, byteOffsetFromStart);
1285            }
1286
1287            numBitsRead += 52;
1288        }
1289
1290        CHECK_GE(adaptation_field_length * 8, numBitsRead);
1291
1292        br->skipBits(adaptation_field_length * 8 - numBitsRead);
1293    }
1294}
1295
1296status_t ATSParser::parseTS(ABitReader *br) {
1297    ALOGV("---");
1298
1299    unsigned sync_byte = br->getBits(8);
1300    if (sync_byte != 0x47u) {
1301        ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte);
1302        return BAD_VALUE;
1303    }
1304
1305    if (br->getBits(1)) {  // transport_error_indicator
1306        // silently ignore.
1307        return OK;
1308    }
1309
1310    unsigned payload_unit_start_indicator = br->getBits(1);
1311    ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator);
1312
1313    MY_LOGV("transport_priority = %u", br->getBits(1));
1314
1315    unsigned PID = br->getBits(13);
1316    ALOGV("PID = 0x%04x", PID);
1317
1318    MY_LOGV("transport_scrambling_control = %u", br->getBits(2));
1319
1320    unsigned adaptation_field_control = br->getBits(2);
1321    ALOGV("adaptation_field_control = %u", adaptation_field_control);
1322
1323    unsigned continuity_counter = br->getBits(4);
1324    ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
1325
1326    // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
1327
1328    if (adaptation_field_control == 2 || adaptation_field_control == 3) {
1329        parseAdaptationField(br, PID);
1330    }
1331
1332    status_t err = OK;
1333
1334    if (adaptation_field_control == 1 || adaptation_field_control == 3) {
1335        err = parsePID(
1336                br, PID, continuity_counter, payload_unit_start_indicator);
1337    }
1338
1339    ++mNumTSPacketsParsed;
1340
1341    return err;
1342}
1343
1344sp<MediaSource> ATSParser::getSource(SourceType type) {
1345    int which = -1;  // any
1346
1347    for (size_t i = 0; i < mPrograms.size(); ++i) {
1348        const sp<Program> &program = mPrograms.editItemAt(i);
1349
1350        if (which >= 0 && (int)program->number() != which) {
1351            continue;
1352        }
1353
1354        sp<MediaSource> source = program->getSource(type);
1355
1356        if (source != NULL) {
1357            return source;
1358        }
1359    }
1360
1361    return NULL;
1362}
1363
1364bool ATSParser::hasSource(SourceType type) const {
1365    for (size_t i = 0; i < mPrograms.size(); ++i) {
1366        const sp<Program> &program = mPrograms.itemAt(i);
1367        if (program->hasSource(type)) {
1368            return true;
1369        }
1370    }
1371
1372    return false;
1373}
1374
1375bool ATSParser::PTSTimeDeltaEstablished() {
1376    if (mPrograms.isEmpty()) {
1377        return false;
1378    }
1379
1380    return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished();
1381}
1382
1383void ATSParser::updatePCR(
1384        unsigned /* PID */, uint64_t PCR, size_t byteOffsetFromStart) {
1385    ALOGV("PCR 0x%016" PRIx64 " @ %zu", PCR, byteOffsetFromStart);
1386
1387    if (mNumPCRs == 2) {
1388        mPCR[0] = mPCR[1];
1389        mPCRBytes[0] = mPCRBytes[1];
1390        mSystemTimeUs[0] = mSystemTimeUs[1];
1391        mNumPCRs = 1;
1392    }
1393
1394    mPCR[mNumPCRs] = PCR;
1395    mPCRBytes[mNumPCRs] = byteOffsetFromStart;
1396    mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs();
1397
1398    ++mNumPCRs;
1399
1400    if (mNumPCRs == 2) {
1401        double transportRate =
1402            (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]);
1403
1404        ALOGV("transportRate = %.2f bytes/sec", transportRate);
1405    }
1406}
1407
1408////////////////////////////////////////////////////////////////////////////////
1409
1410ATSParser::PSISection::PSISection() {
1411}
1412
1413ATSParser::PSISection::~PSISection() {
1414}
1415
1416status_t ATSParser::PSISection::append(const void *data, size_t size) {
1417    if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) {
1418        size_t newCapacity =
1419            (mBuffer == NULL) ? size : mBuffer->capacity() + size;
1420
1421        newCapacity = (newCapacity + 1023) & ~1023;
1422
1423        sp<ABuffer> newBuffer = new ABuffer(newCapacity);
1424
1425        if (mBuffer != NULL) {
1426            memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
1427            newBuffer->setRange(0, mBuffer->size());
1428        } else {
1429            newBuffer->setRange(0, 0);
1430        }
1431
1432        mBuffer = newBuffer;
1433    }
1434
1435    memcpy(mBuffer->data() + mBuffer->size(), data, size);
1436    mBuffer->setRange(0, mBuffer->size() + size);
1437
1438    return OK;
1439}
1440
1441void ATSParser::PSISection::clear() {
1442    if (mBuffer != NULL) {
1443        mBuffer->setRange(0, 0);
1444    }
1445}
1446
1447bool ATSParser::PSISection::isComplete() const {
1448    if (mBuffer == NULL || mBuffer->size() < 3) {
1449        return false;
1450    }
1451
1452    unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff;
1453    return mBuffer->size() >= sectionLength + 3;
1454}
1455
1456bool ATSParser::PSISection::isEmpty() const {
1457    return mBuffer == NULL || mBuffer->size() == 0;
1458}
1459
1460const uint8_t *ATSParser::PSISection::data() const {
1461    return mBuffer == NULL ? NULL : mBuffer->data();
1462}
1463
1464size_t ATSParser::PSISection::size() const {
1465    return mBuffer == NULL ? 0 : mBuffer->size();
1466}
1467
1468}  // namespace android
1469