/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "ATSParser"
#include <utils/Log.h>
#include "ATSParser.h"
#include "AnotherPacketSource.h"
#include "CasManager.h"
#include "ESQueue.h"

#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <cutils/ashmem.h>
#include <cutils/native_handle.h>
#include <hidlmemory/mapping.h>
#include <media/cas/DescramblerAPI.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/ByteUtils.h>
#include <media/stagefright/foundation/MediaKeys.h>
#include <media/stagefright/foundation/avc_utils.h>
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/IStreamSource.h>
#include <utils/KeyedVector.h>
#include <utils/Vector.h>

#include <inttypes.h>

namespace android {
using hardware::hidl_handle;
using hardware::hidl_string;
using hardware::hidl_vec;
using hardware::hidl_memory;
using namespace hardware::cas::V1_0;
using namespace hardware::cas::native::V1_0;
typedef hidl::memory::V1_0::IMemory TMemory;

// I want the expression "y" evaluated even if verbose logging is off.
#define MY_LOGV(x, y) \
    do { unsigned tmp = y; ALOGV(x, tmp); } while (0)

static const size_t kTSPacketSize = 188;

struct ATSParser::Program : public RefBase {
    Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID,
            int64_t lastRecoveredPTS);

    bool parsePSISection(
            unsigned pid, ABitReader *br, status_t *err);

    // Pass to appropriate stream according to pid, and set event if it's a PES
    // with a sync frame.
    // Note that the method itself does not touch event.
    bool parsePID(
            unsigned pid, unsigned continuity_counter,
            unsigned payload_unit_start_indicator,
            unsigned transport_scrambling_control,
            unsigned random_access_indicator,
            ABitReader *br, status_t *err, SyncEvent *event);

    void signalDiscontinuity(
            DiscontinuityType type, const sp<AMessage> &extra);

    void signalEOS(status_t finalResult);

    sp<AnotherPacketSource> getSource(SourceType type);
    bool hasSource(SourceType type) const;

    int64_t convertPTSToTimestamp(uint64_t PTS);

    bool PTSTimeDeltaEstablished() const {
        return mFirstPTSValid;
    }

    unsigned number() const { return mProgramNumber; }

    void updateProgramMapPID(unsigned programMapPID) {
        mProgramMapPID = programMapPID;
    }

    unsigned programMapPID() const {
        return mProgramMapPID;
    }

    uint32_t parserFlags() const {
        return mParser->mFlags;
    }

    sp<CasManager> casManager() const {
        return mParser->mCasManager;
    }

    uint64_t firstPTS() const {
        return mFirstPTS;
    }

    void updateCasSessions();

    void signalNewSampleAesKey(const sp<AMessage> &keyItem);

private:

    ATSParser *mParser;
    unsigned mProgramNumber;
    unsigned mProgramMapPID;
    uint32_t mPMTVersion;
    uint32_t mPMT_CRC;
    KeyedVector<unsigned, sp<Stream> > mStreams;
    bool mFirstPTSValid;
    uint64_t mFirstPTS;
    int64_t mLastRecoveredPTS;
    sp<AMessage> mSampleAesKeyItem;

    status_t parseProgramMap(ABitReader *br);
    int64_t recoverPTS(uint64_t PTS_33bit);
    bool findCADescriptor(
            ABitReader *br, unsigned infoLength, CADescriptor *caDescriptor);
    bool switchPIDs(const Vector<StreamInfo> &infos);

    DISALLOW_EVIL_CONSTRUCTORS(Program);
};

struct ATSParser::Stream : public RefBase {
    Stream(Program *program, unsigned PCR_PID, const StreamInfo &info);

    unsigned type() const { return mStreamType; }
    unsigned typeExt() const { return mStreamTypeExt; }
    unsigned pid() const { return mElementaryPID; }
    void setPID(unsigned pid) { mElementaryPID = pid; }
    void setAudioPresentations(AudioPresentationCollection audioPresentations) {
        mAudioPresentations = audioPresentations;
    }

    void setCasInfo(
            int32_t systemId,
            const sp<IDescrambler> &descrambler,
            const std::vector<uint8_t> &sessionId);

    // Parse the payload and set event when PES with a sync frame is detected.
    // This method knows when a PES starts; so record mPesStartOffsets in that
    // case.
    status_t parse(
            unsigned continuity_counter,
            unsigned payload_unit_start_indicator,
            unsigned transport_scrambling_control,
            unsigned random_access_indicator,
            ABitReader *br,
            SyncEvent *event);

    void signalDiscontinuity(
            DiscontinuityType type, const sp<AMessage> &extra);

    void signalEOS(status_t finalResult);

    SourceType getSourceType();
    sp<AnotherPacketSource> getSource(SourceType type);

    bool isAudio() const;
    bool isVideo() const;
    bool isMeta() const;

    void signalNewSampleAesKey(const sp<AMessage> &keyItem);

protected:
    virtual ~Stream();

private:
    struct SubSampleInfo {
        size_t subSampleSize;
        unsigned transport_scrambling_mode;
        unsigned random_access_indicator;
    };
    Program *mProgram;
    unsigned mElementaryPID;
    unsigned mStreamType;
    unsigned mStreamTypeExt;
    unsigned mPCR_PID;
    int32_t mExpectedContinuityCounter;

    sp<ABuffer> mBuffer;
    sp<AnotherPacketSource> mSource;
    bool mPayloadStarted;
    bool mEOSReached;

    uint64_t mPrevPTS;
    List<off64_t> mPesStartOffsets;

    ElementaryStreamQueue *mQueue;

    bool mScrambled;
    bool mSampleEncrypted;
    sp<AMessage> mSampleAesKeyItem;
    sp<TMemory> mHidlMemory;
    hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
    sp<ABuffer> mDescrambledBuffer;
    List<SubSampleInfo> mSubSamples;
    sp<IDescrambler> mDescrambler;
    AudioPresentationCollection mAudioPresentations;

    // Send audio presentations along with access units.
    void addAudioPresentations(const sp<ABuffer> &buffer);

    // Flush accumulated payload if necessary --- i.e. at EOS or at the start of
    // another payload. event is set if the flushed payload is PES with a sync
    // frame.
    status_t flush(SyncEvent *event);

    // Flush accumulated payload for scrambled streams if necessary --- i.e. at
    // EOS or at the start of another payload. event is set if the flushed
    // payload is PES with a sync frame.
    status_t flushScrambled(SyncEvent *event);

    // Check if a PES packet is scrambled at PES level.
    uint32_t getPesScramblingControl(ABitReader *br, int32_t *pesOffset);

    // Strip and parse PES headers and pass remaining payload into onPayload
    // with parsed metadata. event is set if the PES contains a sync frame.
    status_t parsePES(ABitReader *br, SyncEvent *event);

    // Feed the payload into mQueue and if a packet is identified, queue it
    // into mSource. If the packet is a sync frame. set event with start offset
    // and timestamp of the packet.
    void onPayloadData(
            unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
            unsigned PES_scrambling_control,
            const uint8_t *data, size_t size,
            int32_t payloadOffset, SyncEvent *event);

    // Ensure internal buffers can hold specified size, and will re-allocate
    // as needed.
    bool ensureBufferCapacity(size_t size);

    DISALLOW_EVIL_CONSTRUCTORS(Stream);
};

struct ATSParser::PSISection : public RefBase {
    PSISection();

    status_t append(const void *data, size_t size);
    void setSkipBytes(uint8_t skip);
    void clear();

    bool isComplete() const;
    bool isEmpty() const;
    bool isCRCOkay() const;

    const uint8_t *data() const;
    size_t size() const;

protected:
    virtual ~PSISection();

private:
    sp<ABuffer> mBuffer;
    uint8_t mSkipBytes;
    static uint32_t CRC_TABLE[];

    DISALLOW_EVIL_CONSTRUCTORS(PSISection);
};

ATSParser::SyncEvent::SyncEvent(off64_t offset)
    : mHasReturnedData(false), mOffset(offset), mTimeUs(0) {}

void ATSParser::SyncEvent::init(off64_t offset, const sp<AnotherPacketSource> &source,
        int64_t timeUs, SourceType type) {
    mHasReturnedData = true;
    mOffset = offset;
    mMediaSource = source;
    mTimeUs = timeUs;
    mType = type;
}

void ATSParser::SyncEvent::reset() {
    mHasReturnedData = false;
}
////////////////////////////////////////////////////////////////////////////////

ATSParser::Program::Program(
        ATSParser *parser, unsigned programNumber, unsigned programMapPID,
        int64_t lastRecoveredPTS)
    : mParser(parser),
      mProgramNumber(programNumber),
      mProgramMapPID(programMapPID),
      mPMTVersion(0xffffffff),
      mPMT_CRC(0xffffffff),
      mFirstPTSValid(false),
      mFirstPTS(0),
      mLastRecoveredPTS(lastRecoveredPTS) {
    ALOGV("new program number %u", programNumber);
}

bool ATSParser::Program::parsePSISection(
        unsigned pid, ABitReader *br, status_t *err) {
    *err = OK;

    if (pid != mProgramMapPID) {
        return false;
    }

    *err = parseProgramMap(br);

    return true;
}

bool ATSParser::Program::parsePID(
        unsigned pid, unsigned continuity_counter,
        unsigned payload_unit_start_indicator,
        unsigned transport_scrambling_control,
        unsigned random_access_indicator,
        ABitReader *br, status_t *err, SyncEvent *event) {
    *err = OK;

    ssize_t index = mStreams.indexOfKey(pid);
    if (index < 0) {
        return false;
    }

    *err = mStreams.editValueAt(index)->parse(
            continuity_counter,
            payload_unit_start_indicator,
            transport_scrambling_control,
            random_access_indicator,
            br, event);

    return true;
}

void ATSParser::Program::signalDiscontinuity(
        DiscontinuityType type, const sp<AMessage> &extra) {
    int64_t mediaTimeUs;
    if ((type & DISCONTINUITY_TIME)
            && extra != NULL
            && extra->findInt64(
                kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
        mFirstPTSValid = false;
    }

    for (size_t i = 0; i < mStreams.size(); ++i) {
        mStreams.editValueAt(i)->signalDiscontinuity(type, extra);
    }
}

void ATSParser::Program::signalEOS(status_t finalResult) {
    for (size_t i = 0; i < mStreams.size(); ++i) {
        mStreams.editValueAt(i)->signalEOS(finalResult);
    }
}

bool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) {
    bool success = false;

    if (mStreams.size() == infos.size()) {
        // build type->PIDs map for old and new mapping
        size_t i;
        KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs;
        for (i = 0; i < mStreams.size(); ++i) {
            ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type());
            if (index < 0) {
                oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>());
            }
            oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid());
        }
        for (i = 0; i < infos.size(); ++i) {
            ssize_t index = newType2PIDs.indexOfKey(infos[i].mType);
            if (index < 0) {
                newType2PIDs.add(infos[i].mType, Vector<int32_t>());
            }
            newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID);
        }

        // we can recover if the number of streams for each type hasn't changed
        if (oldType2PIDs.size() == newType2PIDs.size()) {
            success = true;
            for (i = 0; i < oldType2PIDs.size(); ++i) {
                // KeyedVector is sorted, we just compare key and size of each index
                if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i)
                        || oldType2PIDs[i].size() != newType2PIDs[i].size()) {
                     success = false;
                     break;
                }
            }
        }

        if (success) {
            // save current streams to temp
            KeyedVector<int32_t, sp<Stream> > temp;
            for (i = 0; i < mStreams.size(); ++i) {
                 temp.add(mStreams.keyAt(i), mStreams.editValueAt(i));
            }

            mStreams.clear();
            for (i = 0; i < temp.size(); ++i) {
                // The two checks below shouldn't happen,
                // we already checked above the stream count matches
                ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
                if (index < 0) {
                    return false;
                }
                Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
                if (newPIDs.isEmpty()) {
                    return false;
                }

                // get the next PID for temp[i]->type() in the new PID map
                Vector<int32_t>::iterator it = newPIDs.begin();

                // change the PID of the stream, and add it back
                temp.editValueAt(i)->setPID(*it);
                mStreams.add(temp[i]->pid(), temp.editValueAt(i));

                // removed the used PID
                newPIDs.erase(it);
            }
        }
    }
    return success;
}

bool ATSParser::Program::findCADescriptor(
        ABitReader *br, unsigned infoLength,
        ATSParser::CADescriptor *caDescriptor) {
    bool found = false;
    while (infoLength > 2) {
        if (br->numBitsLeft() < 16) {
            ALOGE("Not enough data left in bitreader");
            return false;
        }
        unsigned descriptor_tag = br->getBits(8);
        ALOGV("      tag = 0x%02x", descriptor_tag);

        unsigned descriptor_length = br->getBits(8);
        ALOGV("      len = %u", descriptor_length);

        infoLength -= 2;
        if (descriptor_length > infoLength) {
            break;
        }
        if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
            found = true;
            if (br->numBitsLeft() < 32) {
                ALOGE("Not enough data left in bitreader");
                return false;
            }
            caDescriptor->mSystemID = br->getBits(16);
            caDescriptor->mPID = br->getBits(16) & 0x1fff;
            infoLength -= 4;
            caDescriptor->mPrivateData.assign(
                    br->data(), br->data() + descriptor_length - 4);
            break;
        } else {
            infoLength -= descriptor_length;
            if (!br->skipBits(descriptor_length * 8)) {
                ALOGE("Not enough data left in bitreader");
                return false;
            }
        }
    }
    if (!br->skipBits(infoLength * 8)) {
        ALOGE("Not enough data left in bitreader");
        return false;
    }
    return found;
}

status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
    if (br->numBitsLeft() < 10) {
        ALOGE("Not enough data left in bitreader!");
        return ERROR_MALFORMED;
    }
    unsigned table_id = br->getBits(8);
    ALOGV("  table_id = %u", table_id);
    if (table_id != 0x02u) {
        ALOGE("PMT data error!");
        return ERROR_MALFORMED;
    }
    unsigned section_syntax_indicator = br->getBits(1);
    ALOGV("  section_syntax_indicator = %u", section_syntax_indicator);
    if (section_syntax_indicator != 1u) {
        ALOGE("PMT data error!");
        return ERROR_MALFORMED;
    }

    br->skipBits(1);  // '0'
    if (br->numBitsLeft() < 86) {
        ALOGE("Not enough data left in bitreader!");
        return ERROR_MALFORMED;
    }
    MY_LOGV("  reserved = %u", br->getBits(2));

    unsigned section_length = br->getBits(12);
    ALOGV("  section_length = %u", section_length);

    MY_LOGV("  program_number = %u", br->getBits(16));
    MY_LOGV("  reserved = %u", br->getBits(2));
    bool audioPresentationsChanged = false;
    unsigned pmtVersion = br->getBits(5);
    if (pmtVersion != mPMTVersion) {
        audioPresentationsChanged = true;
        mPMTVersion = pmtVersion;
    }
    MY_LOGV("  version_number = %u", pmtVersion);
    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
    MY_LOGV("  section_number = %u", br->getBits(8));
    MY_LOGV("  last_section_number = %u", br->getBits(8));
    MY_LOGV("  reserved = %u", br->getBits(3));

    unsigned PCR_PID = br->getBits(13);
    ALOGV("  PCR_PID = 0x%04x", PCR_PID);

    MY_LOGV("  reserved = %u", br->getBits(4));

    unsigned program_info_length = br->getBits(12);
    ALOGV("  program_info_length = %u", program_info_length);

    // descriptors
    CADescriptor programCA;
    bool hasProgramCA = findCADescriptor(br, program_info_length, &programCA);
    if (hasProgramCA && !mParser->mCasManager->addProgram(
            mProgramNumber, programCA)) {
        return ERROR_MALFORMED;
    }

    Vector<StreamInfo> infos;

    // infoBytesRemaining is the number of bytes that make up the
    // variable length section of ES_infos. It does not include the
    // final CRC.
    int32_t infoBytesRemaining = section_length - 9 - program_info_length - 4;

    while (infoBytesRemaining >= 5) {
        StreamInfo info;
        if (br->numBitsLeft() < 40) {
            ALOGE("Not enough data left in bitreader!");
            return ERROR_MALFORMED;
        }
        info.mType = br->getBits(8);
        ALOGV("    stream_type = 0x%02x", info.mType);
        MY_LOGV("    reserved = %u", br->getBits(3));

        info.mPID = br->getBits(13);
        ALOGV("    elementary_PID = 0x%04x", info.mPID);

        MY_LOGV("    reserved = %u", br->getBits(4));

        unsigned ES_info_length = br->getBits(12);
        ALOGV("    ES_info_length = %u", ES_info_length);
        infoBytesRemaining -= 5 + ES_info_length;

        CADescriptor streamCA;
        info.mTypeExt = EXT_DESCRIPTOR_DVB_RESERVED_MAX;

        info.mAudioPresentations.clear();
        bool hasStreamCA = false;
        while (ES_info_length > 2 && infoBytesRemaining >= 0) {
            if (br->numBitsLeft() < 16) {
                ALOGE("Not enough data left in bitreader!");
                return ERROR_MALFORMED;
            }
            unsigned descriptor_tag = br->getBits(8);
            ALOGV("      tag = 0x%02x", descriptor_tag);

            unsigned descriptor_length = br->getBits(8);
            ALOGV("      len = %u", descriptor_length);

            ES_info_length -= 2;
            if (descriptor_length > ES_info_length) {
                return ERROR_MALFORMED;
            }

            // The DTS descriptor is used in the PSI PMT to identify streams which carry
            // DTS audio(core only). If a DTS descriptor is present, a DTS-HD or DTS-UHD
            // descriptors shall not be present in the same ES_info descriptor loop.
            if (descriptor_tag == DESCRIPTOR_DTS) {
                info.mType = STREAMTYPE_DTS;
                ES_info_length -= descriptor_length;
                if (!br->skipBits(descriptor_length * 8)) {
                    ALOGE("Not enough data left in bitreader!");
                    return ERROR_MALFORMED;
                }
            } else if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
                hasStreamCA = true;
                if (br->numBitsLeft() < 32) {
                    ALOGE("Not enough data left in bitreader!");
                    return ERROR_MALFORMED;
                }
                streamCA.mSystemID = br->getBits(16);
                streamCA.mPID = br->getBits(16) & 0x1fff;
                ES_info_length -= descriptor_length;
                descriptor_length -= 4;
                streamCA.mPrivateData.assign(br->data(), br->data() + descriptor_length);
                if (!br->skipBits(descriptor_length * 8)) {
                    ALOGE("Not enough data left in bitreader!");
                    return ERROR_MALFORMED;
                }
            } else if (info.mType == STREAMTYPE_PES_PRIVATE_DATA &&
                       descriptor_tag == DESCRIPTOR_DVB_EXTENSION && descriptor_length >= 1) {
                if (br->numBitsLeft() < 8) {
                    ALOGE("Not enough data left in bitreader!");
                    return ERROR_MALFORMED;
                }
                unsigned descTagExt = br->getBits(8);
                ALOGV("      tag_ext = 0x%02x", descTagExt);
                ES_info_length -= descriptor_length;
                descriptor_length--;
                if (br->numBitsLeft() < (descriptor_length * 8)) {
                    ALOGE("Not enough data left in bitreader!");
                    return ERROR_MALFORMED;
                }
                // The AC4 descriptor is used in the PSI PMT to identify streams which carry AC4
                // audio.
                if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
                    info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
                    br->skipBits(descriptor_length * 8);
                } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
                    // DTS HD extended descriptor which can accommodate core only formats
                    // as well as extension only and core + extension combinations.
                    info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_HD;
                    br->skipBits(descriptor_length * 8);
                } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
                    // The DTS-UHD descriptor is used in the PSI PMT to identify streams
                    // which carry DTS-UHD audio
                    info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_UHD;
                    br->skipBits(descriptor_length * 8);
                } else if (descTagExt == EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION &&
                           descriptor_length >= 1) {
                    if (br->numBitsLeft() < 8) {
                        ALOGE("Not enough data left in bitreader!");
                        return ERROR_MALFORMED;
                    }
                    // DVB BlueBook A038 Table 110
                    unsigned num_preselections = br->getBits(5);
                    br->skipBits(3);  // reserved
                    for (unsigned i = 0; i < num_preselections; ++i) {
                        if (br->numBitsLeft() < 16) {
                            ALOGE("Not enough data left in bitreader!");
                            return ERROR_MALFORMED;
                        }
                        AudioPresentationV1 ap;
                        ap.mPresentationId = br->getBits(5);  // preselection_id

                        // audio_rendering_indication
                        ap.mMasteringIndication = static_cast<MasteringIndication>(br->getBits(3));
                        ap.mAudioDescriptionAvailable = (br->getBits(1) == 1);
                        ap.mSpokenSubtitlesAvailable = (br->getBits(1) == 1);
                        ap.mDialogueEnhancementAvailable = (br->getBits(1) == 1);

                        bool interactivity_enabled = (br->getBits(1) == 1);
                        MY_LOGV("      interactivity_enabled = %d", interactivity_enabled);

                        bool language_code_present = (br->getBits(1) == 1);
                        bool text_label_present = (br->getBits(1) == 1);

                        bool multi_stream_info_present = (br->getBits(1) == 1);
                        bool future_extension = (br->getBits(1) == 1);
                        if (language_code_present) {
                            if (br->numBitsLeft() < 24) {
                                ALOGE("Not enough data left in bitreader!");
                                return ERROR_MALFORMED;
                            }
                            char language[4];
                            language[0] = br->getBits(8);
                            language[1] = br->getBits(8);
                            language[2] = br->getBits(8);
                            language[3] = 0;
                            ap.mLanguage = String8(language);
                        }

                        // This maps the presentation id to the message id in the
                        // EXT_DESCRIPTOR_DVB_MESSAGE so that we can get the presentation label.
                        if (text_label_present) {
                            if (br->numBitsLeft() < 8) {
                                ALOGE("Not enough data left in bitreader!");
                                return ERROR_MALFORMED;
                            }
                            unsigned message_id = br->getBits(8);
                            MY_LOGV("      message_id = %u", message_id);
                        }

                        if (multi_stream_info_present) {
                            if (br->numBitsLeft() < 8) {
                                ALOGE("Not enough data left in bitreader!");
                                return ERROR_MALFORMED;
                            }
                            unsigned num_aux_components = br->getBits(3);
                            br->skipBits(5);  // reserved
                            if (br->numBitsLeft() < (num_aux_components * 8)) {
                                ALOGE("Not enough data left in bitreader!");
                                return ERROR_MALFORMED;
                            }
                            br->skipBits(num_aux_components * 8);  // component_tag
                        }
                        if (future_extension) {
                            if (br->numBitsLeft() < 8) {
                                return ERROR_MALFORMED;
                            }
                            br->skipBits(3);  // reserved
                            unsigned future_extension_length = br->getBits(5);
                            if (br->numBitsLeft() < (future_extension_length * 8)) {
                                ALOGE("Not enough data left in bitreader!");
                                return ERROR_MALFORMED;
                            }
                            br->skipBits(future_extension_length * 8);  // future_extension_byte
                        }
                        info.mAudioPresentations.push_back(std::move(ap));
                    }
                } else {
                    if (!br->skipBits(descriptor_length * 8)) {
                        ALOGE("Not enough data left in bitreader!");
                        return ERROR_MALFORMED;
                    }
                }
            } else {
                ES_info_length -= descriptor_length;
                if (!br->skipBits(descriptor_length * 8)) {
                    ALOGE("Not enough data left in bitreader!");
                    return ERROR_MALFORMED;
                }
            }
        }
        if (hasStreamCA && !mParser->mCasManager->addStream(
                mProgramNumber, info.mPID, streamCA)) {
            return ERROR_MALFORMED;
        }
        if (hasProgramCA) {
            info.mCADescriptor = programCA;
        } else if (hasStreamCA) {
            info.mCADescriptor = streamCA;
        }

        infos.push(info);
    }

    if (infoBytesRemaining != 0) {
        ALOGW("Section data remains unconsumed");
    }
    if (br->numBitsLeft() < 32) {
        ALOGE("Not enough data left in bitreader!");
        return ERROR_MALFORMED;
    }
    unsigned crc = br->getBits(32);
    if (crc != mPMT_CRC) {
        audioPresentationsChanged = true;
        mPMT_CRC = crc;
    }
    MY_LOGV("  CRC = 0x%08x", crc);

    bool PIDsChanged = false;
    for (size_t i = 0; i < infos.size(); ++i) {
        StreamInfo &info = infos.editItemAt(i);

        ssize_t index = mStreams.indexOfKey(info.mPID);

        if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
            ALOGI("uh oh. stream PIDs have changed.");
            PIDsChanged = true;
            break;
        }
    }

    if (PIDsChanged) {
#if 0
        ALOGI("before:");
        for (size_t i = 0; i < mStreams.size(); ++i) {
            sp<Stream> stream = mStreams.editValueAt(i);

            ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type());
        }

        ALOGI("after:");
        for (size_t i = 0; i < infos.size(); ++i) {
            StreamInfo &info = infos.editItemAt(i);

            ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType);
        }
#endif

        // we can recover if number of streams for each type remain the same
        bool success = switchPIDs(infos);

        if (!success) {
            ALOGI("Stream PIDs changed and we cannot recover.");
            return ERROR_MALFORMED;
        }
    }

    bool isAddingScrambledStream = false;
    for (size_t i = 0; i < infos.size(); ++i) {
        StreamInfo &info = infos.editItemAt(i);

        if (mParser->mCasManager->isCAPid(info.mPID)) {
            // skip CA streams (EMM/ECM)
            continue;
        }
        ssize_t index = mStreams.indexOfKey(info.mPID);

        if (index < 0) {
            sp<Stream> stream = new Stream(this, PCR_PID, info);

            if (mSampleAesKeyItem != NULL) {
                stream->signalNewSampleAesKey(mSampleAesKeyItem);
            }

            isAddingScrambledStream |= info.mCADescriptor.mSystemID >= 0;
            mStreams.add(info.mPID, stream);
        }
        else if (index >= 0 && mStreams.editValueAt(index)->isAudio()
                 && audioPresentationsChanged) {
            mStreams.editValueAt(index)->setAudioPresentations(info.mAudioPresentations);
        }
    }

    if (isAddingScrambledStream) {
        ALOGI("Receiving scrambled streams without descrambler!");
        return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
    }
    return OK;
}

int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
    // We only have the lower 33-bit of the PTS. It could overflow within a
    // reasonable amount of time. To handle the wrap-around, use fancy math
    // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
    // of the latest recovered PTS.
    if (mLastRecoveredPTS < 0LL) {
        // Use the original 33bit number for 1st frame, the reason is that
        // if 1st frame wraps to negative that's far away from 0, we could
        // never start. Only start wrapping around from 2nd frame.
        mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
    } else {
        mLastRecoveredPTS = static_cast<int64_t>(
                ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000LL)
                & 0xfffffffe00000000ull) | PTS_33bit);
        // We start from 0, but recovered PTS could be slightly below 0.
        // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
        // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
        if (mLastRecoveredPTS < 0LL) {
            ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS);
            mLastRecoveredPTS = 0LL;
        }
    }

    return mLastRecoveredPTS;
}

sp<AnotherPacketSource> ATSParser::Program::getSource(SourceType type) {
    for (size_t i = 0; i < mStreams.size(); ++i) {
        sp<AnotherPacketSource> source = mStreams.editValueAt(i)->getSource(type);
        if (source != NULL) {
            return source;
        }
    }

    return NULL;
}

bool ATSParser::Program::hasSource(SourceType type) const {
    for (size_t i = 0; i < mStreams.size(); ++i) {
        const sp<Stream> &stream = mStreams.valueAt(i);
        if (type == AUDIO && stream->isAudio()) {
            return true;
        } else if (type == VIDEO && stream->isVideo()) {
            return true;
        } else if (type == META && stream->isMeta()) {
            return true;
        }
    }

    return false;
}

int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
    PTS = recoverPTS(PTS);

    if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
        if (!mFirstPTSValid) {
            mFirstPTSValid = true;
            mFirstPTS = PTS;
            PTS = 0;
        } else if (PTS < mFirstPTS) {
            PTS = 0;
        } else {
            PTS -= mFirstPTS;
        }
    }

    int64_t timeUs = (PTS * 100) / 9;

    if (mParser->mAbsoluteTimeAnchorUs >= 0LL) {
        timeUs += mParser->mAbsoluteTimeAnchorUs;
    }

    if (mParser->mTimeOffsetValid) {
        timeUs += mParser->mTimeOffsetUs;
    }

    return timeUs;
}

void ATSParser::Program::updateCasSessions() {
    for (size_t i = 0; i < mStreams.size(); ++i) {
        sp<Stream> &stream = mStreams.editValueAt(i);
        sp<IDescrambler> descrambler;
        std::vector<uint8_t> sessionId;
        int32_t systemId;
        if (mParser->mCasManager->getCasInfo(mProgramNumber, stream->pid(),
                &systemId, &descrambler, &sessionId)) {
            stream->setCasInfo(systemId, descrambler, sessionId);
        }
    }
}

////////////////////////////////////////////////////////////////////////////////
static const size_t kInitialStreamBufferSize = 192 * 1024;

ATSParser::Stream::Stream(
        Program *program, unsigned PCR_PID, const StreamInfo &info)
    : mProgram(program),
      mElementaryPID(info.mPID),
      mStreamType(info.mType),
      mStreamTypeExt(info.mTypeExt),
      mPCR_PID(PCR_PID),
      mExpectedContinuityCounter(-1),
      mPayloadStarted(false),
      mEOSReached(false),
      mPrevPTS(0),
      mQueue(NULL),
      mScrambled(info.mCADescriptor.mSystemID >= 0),
      mAudioPresentations(info.mAudioPresentations) {
    mSampleEncrypted =
            mStreamType == STREAMTYPE_H264_ENCRYPTED ||
            mStreamType == STREAMTYPE_AAC_ENCRYPTED  ||
            mStreamType == STREAMTYPE_AC3_ENCRYPTED;

    ALOGV("new stream PID 0x%02x, type 0x%02x, scrambled %d, SampleEncrypted: %d",
            info.mPID, info.mType, mScrambled, mSampleEncrypted);

    uint32_t flags = 0;
    if (((isVideo() || isAudio()) && mScrambled)) {
        flags = ElementaryStreamQueue::kFlag_ScrambledData;
    } else if (mSampleEncrypted) {
        flags = ElementaryStreamQueue::kFlag_SampleEncryptedData;
    }

    ElementaryStreamQueue::Mode mode = ElementaryStreamQueue::INVALID;

    switch (mStreamType) {
        case STREAMTYPE_H264:
        case STREAMTYPE_H264_ENCRYPTED:
            mode = ElementaryStreamQueue::H264;
            flags |= (mProgram->parserFlags() & ALIGNED_VIDEO_DATA) ?
                    ElementaryStreamQueue::kFlag_AlignedData : 0;
            break;

        case STREAMTYPE_MPEG2_AUDIO_ADTS:
        case STREAMTYPE_AAC_ENCRYPTED:
            mode = ElementaryStreamQueue::AAC;
            break;

        case STREAMTYPE_MPEG1_AUDIO:
        case STREAMTYPE_MPEG2_AUDIO:
            mode = ElementaryStreamQueue::MPEG_AUDIO;
            break;

        case STREAMTYPE_MPEG1_VIDEO:
        case STREAMTYPE_MPEG2_VIDEO:
            mode = ElementaryStreamQueue::MPEG_VIDEO;
            break;

        case STREAMTYPE_MPEG4_VIDEO:
            mode = ElementaryStreamQueue::MPEG4_VIDEO;
            break;

        case STREAMTYPE_LPCM_AC3:
        case STREAMTYPE_AC3:
        case STREAMTYPE_AC3_ENCRYPTED:
            mode = ElementaryStreamQueue::AC3;
            break;

        case STREAMTYPE_EAC3:
            mode = ElementaryStreamQueue::EAC3;
            break;

        case STREAMTYPE_DTS:
            mode = ElementaryStreamQueue::DTS;
            break;

        case STREAMTYPE_PES_PRIVATE_DATA:
            if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) {
                mode = ElementaryStreamQueue::AC4;
            } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
                mode = ElementaryStreamQueue::DTS_HD;
            } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
                mode = ElementaryStreamQueue::DTS_UHD;
            }
            break;

        case STREAMTYPE_METADATA:
            mode = ElementaryStreamQueue::METADATA;
            break;

        default:
            ALOGE("stream PID 0x%02x has invalid stream type 0x%02x",
                    info.mPID, info.mType);
            return;
    }

    mQueue = new ElementaryStreamQueue(mode, flags);

    if (mQueue != NULL) {
        if (mSampleAesKeyItem != NULL) {
            mQueue->signalNewSampleAesKey(mSampleAesKeyItem);
        }

        ensureBufferCapacity(kInitialStreamBufferSize);

        if (mScrambled && (isAudio() || isVideo())) {
            // Set initial format to scrambled
            sp<MetaData> meta = new MetaData();
            meta->setCString(kKeyMIMEType,
                    isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
                              : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
            // for MediaExtractor.CasInfo
            const CADescriptor &descriptor = info.mCADescriptor;
            meta->setInt32(kKeyCASystemID, descriptor.mSystemID);

            meta->setData(kKeyCAPrivateData, 0,
                    descriptor.mPrivateData.data(),
                    descriptor.mPrivateData.size());

            mSource = new AnotherPacketSource(meta);
        }
    }
}

ATSParser::Stream::~Stream() {
    delete mQueue;
    mQueue = NULL;
}

bool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
    if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
        return true;
    }

    ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
            mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);

    sp<ABuffer> newBuffer, newScrambledBuffer;
    sp<TMemory> newMem;
    if (mScrambled) {
        int fd = ashmem_create_region("mediaATS", neededSize);
        if (fd < 0) {
             ALOGE("[stream %d] create_ashmem_region failed for size %zu. FD returned: %d",
                    mElementaryPID, neededSize, fd);
            return false;
        }

        native_handle_t* handle = native_handle_create(1 /*numFds*/, 0/*numInts*/);
        if (handle == nullptr) {
            ALOGE("[stream %d] failed to create a native_handle_t", mElementaryPID);
            if (close(fd)) {
                ALOGE("[stream %d] failed to close ashmem fd. errno: %s", mElementaryPID,
                      strerror(errno));
            }

            return false;
        }

        handle->data[0] = fd;
        hidl_handle memHandle;
        memHandle.setTo(handle, true /*shouldOwn*/);
        hidl_memory hidlMemToken("ashmem", memHandle, neededSize);

        newMem = mapMemory(hidlMemToken);
        if (newMem == nullptr || newMem->getPointer() == nullptr) {
            ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
            return false;
        }

        newScrambledBuffer = new ABuffer(newMem->getPointer(), newMem->getSize());

        if (mDescrambledBuffer != NULL) {
            memcpy(newScrambledBuffer->data(),
                    mDescrambledBuffer->data(), mDescrambledBuffer->size());
            newScrambledBuffer->setRange(0, mDescrambledBuffer->size());
        } else {
            newScrambledBuffer->setRange(0, 0);
        }
        mHidlMemory = newMem;
        mDescrambledBuffer = newScrambledBuffer;

        mDescramblerSrcBuffer.heapBase = hidlMemToken;
        mDescramblerSrcBuffer.offset = 0ULL;
        mDescramblerSrcBuffer.size =  (uint64_t)neededSize;

        ALOGD("[stream %d] created shared buffer for descrambling, size %zu",
                mElementaryPID, neededSize);
    } else {
        // Align to multiples of 64K.
        neededSize = (neededSize + 65535) & ~65535;
    }

    newBuffer = new ABuffer(neededSize);
    if (mBuffer != NULL) {
        memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
        newBuffer->setRange(0, mBuffer->size());
    } else {
        newBuffer->setRange(0, 0);
    }
    mBuffer = newBuffer;
    return true;
}

status_t ATSParser::Stream::parse(
        unsigned continuity_counter,
        unsigned payload_unit_start_indicator,
        unsigned transport_scrambling_control,
        unsigned random_access_indicator,
        ABitReader *br, SyncEvent *event) {
    if (mQueue == NULL) {
        return OK;
    }

    if (mExpectedContinuityCounter >= 0
            && (unsigned)mExpectedContinuityCounter != continuity_counter) {
        ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);

        mPayloadStarted = false;
        mPesStartOffsets.clear();
        mBuffer->setRange(0, 0);
        mSubSamples.clear();
        mExpectedContinuityCounter = -1;

#if 0
        // Uncomment this if you'd rather see no corruption whatsoever on
        // screen and suspend updates until we come across another IDR frame.

        if (mStreamType == STREAMTYPE_H264) {
            ALOGI("clearing video queue");
            mQueue->clear(true /* clearFormat */);
        }
#endif

        if (!payload_unit_start_indicator) {
            return OK;
        }
    }

    mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f;

    if (payload_unit_start_indicator) {
        off64_t offset = (event != NULL) ? event->getOffset() : 0;
        if (mPayloadStarted) {
            // Otherwise we run the danger of receiving the trailing bytes
            // of a PES packet that we never saw the start of and assuming
            // we have a a complete PES packet.

            status_t err = flush(event);

            if (err != OK) {
                ALOGW("Error (%08x) happened while flushing; we simply discard "
                      "the PES packet and continue.", err);
            }
        }

        mPayloadStarted = true;
        // There should be at most 2 elements in |mPesStartOffsets|.
        while (mPesStartOffsets.size() >= 2) {
            mPesStartOffsets.erase(mPesStartOffsets.begin());
        }
        mPesStartOffsets.push_back(offset);
    }

    if (!mPayloadStarted) {
        return OK;
    }

    size_t payloadSizeBits = br->numBitsLeft();
    if (payloadSizeBits % 8 != 0u) {
        ALOGE("Wrong value");
        return BAD_VALUE;
    }

    size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
    if (!ensureBufferCapacity(neededSize)) {
        return NO_MEMORY;
    }

    memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
    mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);

    if (mScrambled) {
        mSubSamples.push_back({payloadSizeBits / 8,
                 transport_scrambling_control, random_access_indicator});
    }

    return OK;
}

bool ATSParser::Stream::isVideo() const {
    switch (mStreamType) {
        case STREAMTYPE_H264:
        case STREAMTYPE_H264_ENCRYPTED:
        case STREAMTYPE_MPEG1_VIDEO:
        case STREAMTYPE_MPEG2_VIDEO:
        case STREAMTYPE_MPEG4_VIDEO:
            return true;

        default:
            return false;
    }
}

bool ATSParser::Stream::isAudio() const {
    switch (mStreamType) {
        case STREAMTYPE_MPEG1_AUDIO:
        case STREAMTYPE_MPEG2_AUDIO:
        case STREAMTYPE_MPEG2_AUDIO_ADTS:
        case STREAMTYPE_LPCM_AC3:
        case STREAMTYPE_AC3:
        case STREAMTYPE_EAC3:
        case STREAMTYPE_AAC_ENCRYPTED:
        case STREAMTYPE_AC3_ENCRYPTED:
        case STREAMTYPE_DTS:
            return true;
        case STREAMTYPE_PES_PRIVATE_DATA:
            return (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4
                    || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD
                    || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD);

        default:
            return false;
    }
}

bool ATSParser::Stream::isMeta() const {
    if (mStreamType == STREAMTYPE_METADATA) {
        return true;
    }
    return false;
}

void ATSParser::Stream::signalDiscontinuity(
        DiscontinuityType type, const sp<AMessage> &extra) {
    mExpectedContinuityCounter = -1;

    if (mQueue == NULL) {
        return;
    }

    mPayloadStarted = false;
    mPesStartOffsets.clear();
    mEOSReached = false;
    mBuffer->setRange(0, 0);
    mSubSamples.clear();

    bool clearFormat = false;
    if (isAudio()) {
        if (type & DISCONTINUITY_AUDIO_FORMAT) {
            clearFormat = true;
        }
    } else {
        if (type & DISCONTINUITY_VIDEO_FORMAT) {
            clearFormat = true;
        }
    }

    mQueue->clear(clearFormat);

    if (type & DISCONTINUITY_TIME) {
        uint64_t resumeAtPTS;
        if (extra != NULL
                && extra->findInt64(
                    kATSParserKeyResumeAtPTS,
                    (int64_t *)&resumeAtPTS)) {
            int64_t resumeAtMediaTimeUs =
                mProgram->convertPTSToTimestamp(resumeAtPTS);

            extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs);
        }
    }

    if (mSource != NULL) {
        sp<MetaData> meta = mSource->getFormat();
        const char* mime;
        if (clearFormat && meta != NULL && meta->findCString(kKeyMIMEType, &mime)
                && (!strncasecmp(mime, MEDIA_MIMETYPE_AUDIO_SCRAMBLED, 15)
                 || !strncasecmp(mime, MEDIA_MIMETYPE_VIDEO_SCRAMBLED, 15))){
            mSource->clear();
        } else {
            mSource->queueDiscontinuity(type, extra, true);
        }
    }
}

void ATSParser::Stream::signalEOS(status_t finalResult) {
    if (mSource != NULL) {
        mSource->signalEOS(finalResult);
    }
    mEOSReached = true;
    flush(NULL);
}

status_t ATSParser::Stream::parsePES(ABitReader *br, SyncEvent *event) {
    const uint8_t *basePtr = br->data();

    if (br->numBitsLeft() < 48) {
        ALOGE("Not enough data left in bitreader!");
        return ERROR_MALFORMED;
    }
    unsigned packet_startcode_prefix = br->getBits(24);

    ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);

    if (packet_startcode_prefix != 1) {
        ALOGV("Supposedly payload_unit_start=1 unit does not start "
             "with startcode.");

        return ERROR_MALFORMED;
    }

    unsigned stream_id = br->getBits(8);
    ALOGV("stream_id = 0x%02x", stream_id);

    unsigned PES_packet_length = br->getBits(16);
    ALOGV("PES_packet_length = %u", PES_packet_length);

    if (stream_id != 0xbc  // program_stream_map
            && stream_id != 0xbe  // padding_stream
            && stream_id != 0xbf  // private_stream_2
            && stream_id != 0xf0  // ECM
            && stream_id != 0xf1  // EMM
            && stream_id != 0xff  // program_stream_directory
            && stream_id != 0xf2  // DSMCC
            && stream_id != 0xf8) {  // H.222.1 type E
        if (br->numBitsLeft() < 2 || br->getBits(2) != 2u) {
            return ERROR_MALFORMED;
        }

        if (br->numBitsLeft() < 22) {
            ALOGE("Not enough data left in bitreader!");
            return ERROR_MALFORMED;
        }
        unsigned PES_scrambling_control = br->getBits(2);
        ALOGV("PES_scrambling_control = %u", PES_scrambling_control);

        MY_LOGV("PES_priority = %u", br->getBits(1));
        MY_LOGV("data_alignment_indicator = %u", br->getBits(1));
        MY_LOGV("copyright = %u", br->getBits(1));
        MY_LOGV("original_or_copy = %u", br->getBits(1));

        unsigned PTS_DTS_flags = br->getBits(2);
        ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags);

        unsigned ESCR_flag = br->getBits(1);
        ALOGV("ESCR_flag = %u", ESCR_flag);

        unsigned ES_rate_flag = br->getBits(1);
        ALOGV("ES_rate_flag = %u", ES_rate_flag);

        unsigned DSM_trick_mode_flag = br->getBits(1);
        ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);

        unsigned additional_copy_info_flag = br->getBits(1);
        ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag);

        MY_LOGV("PES_CRC_flag = %u", br->getBits(1));
        MY_LOGV("PES_extension_flag = %u", br->getBits(1));

        unsigned PES_header_data_length = br->getBits(8);
        ALOGV("PES_header_data_length = %u", PES_header_data_length);

        unsigned optional_bytes_remaining = PES_header_data_length;

        uint64_t PTS = 0, DTS = 0;

        if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
            if (optional_bytes_remaining < 5u) {
                return ERROR_MALFORMED;
            }

            if (br->numBitsLeft() < 7 || br->getBits(4) != PTS_DTS_flags) {
                return ERROR_MALFORMED;
            }
            PTS = ((uint64_t)br->getBits(3)) << 30;
            if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            PTS |= ((uint64_t)br->getBits(15)) << 15;
            if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            PTS |= br->getBits(15);
            if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }

            ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);

            optional_bytes_remaining -= 5;

            if (PTS_DTS_flags == 3) {
                if (optional_bytes_remaining < 5u) {
                    return ERROR_MALFORMED;
                }

                if (br->numBitsLeft() < 7 || br->getBits(4) != 1u) {
                    return ERROR_MALFORMED;
                }

                DTS = ((uint64_t)br->getBits(3)) << 30;
                if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
                    return ERROR_MALFORMED;
                }
                DTS |= ((uint64_t)br->getBits(15)) << 15;
                if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
                    return ERROR_MALFORMED;
                }
                DTS |= br->getBits(15);
                if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
                    return ERROR_MALFORMED;
                }

                ALOGV("DTS = %" PRIu64, DTS);

                optional_bytes_remaining -= 5;
            }
        }

        if (ESCR_flag) {
            if (optional_bytes_remaining < 6u) {
                return ERROR_MALFORMED;
            }

            if (br->numBitsLeft() < 5) {
                ALOGE("Not enough data left in bitreader!");
                return ERROR_MALFORMED;
            }
            br->getBits(2);

            uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
            if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            ESCR |= ((uint64_t)br->getBits(15)) << 15;
            if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            ESCR |= br->getBits(15);
            if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }

            ALOGV("ESCR = %" PRIu64, ESCR);
            if (br->numBitsLeft() < 10) {
                ALOGE("Not enough data left in bitreader!");
                return ERROR_MALFORMED;
            }
            MY_LOGV("ESCR_extension = %u", br->getBits(9));

            if (br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }

            optional_bytes_remaining -= 6;
        }

        if (ES_rate_flag) {
            if (optional_bytes_remaining < 3u) {
                return ERROR_MALFORMED;
            }

            if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }
            if (br->numBitsLeft() < 22) {
                ALOGE("Not enough data left in bitreader!");
                return ERROR_MALFORMED;
            }
            MY_LOGV("ES_rate = %u", br->getBits(22));
            if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
                return ERROR_MALFORMED;
            }

            optional_bytes_remaining -= 3;
        }

        if (!br->skipBits(optional_bytes_remaining * 8)) {
            ALOGE("Not enough data left in bitreader!");
            return ERROR_MALFORMED;
        }

        // ES data follows.
        int32_t pesOffset = br->data() - basePtr;

        if (PES_packet_length != 0) {
            if (PES_packet_length < PES_header_data_length + 3) {
                return ERROR_MALFORMED;
            }

            unsigned dataLength =
                PES_packet_length - 3 - PES_header_data_length;

            if (br->numBitsLeft() < dataLength * 8) {
                ALOGE("PES packet does not carry enough data to contain "
                     "payload. (numBitsLeft = %zu, required = %u)",
                     br->numBitsLeft(), dataLength * 8);

                return ERROR_MALFORMED;
            }

            ALOGV("There's %u bytes of payload, PES_packet_length=%u, offset=%d",
                    dataLength, PES_packet_length, pesOffset);

            onPayloadData(
                    PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
                    br->data(), dataLength, pesOffset, event);

            if (!br->skipBits(dataLength * 8)) {
                ALOGE("Not enough data left in bitreader!");
                return ERROR_MALFORMED;
            }
        } else {
            onPayloadData(
                    PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
                    br->data(), br->numBitsLeft() / 8, pesOffset, event);

            size_t payloadSizeBits = br->numBitsLeft();
            if (payloadSizeBits % 8 != 0u) {
                return ERROR_MALFORMED;
            }

            ALOGV("There's %zu bytes of payload, offset=%d",
                    payloadSizeBits / 8, pesOffset);
        }
    } else if (stream_id == 0xbe) {  // padding_stream
        if (PES_packet_length == 0u || !br->skipBits(PES_packet_length * 8)) {
            return ERROR_MALFORMED;
        }
    } else {
        if (PES_packet_length == 0u || !br->skipBits(PES_packet_length * 8)) {
            return ERROR_MALFORMED;
        }
    }

    return OK;
}

uint32_t ATSParser::Stream::getPesScramblingControl(
        ABitReader *br, int32_t *pesOffset) {
    if (br->numBitsLeft() < 24) {
        ALOGE("Not enough data left in bitreader!");
        return 0;
    }
    unsigned packet_startcode_prefix = br->getBits(24);

    ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);

    if (packet_startcode_prefix != 1) {
        ALOGV("unit does not start with startcode.");
        return 0;
    }

    if (br->numBitsLeft() < 48) {
        ALOGE("Not enough data left in bitreader!");
        return 0;
    }

    unsigned stream_id = br->getBits(8);
    ALOGV("stream_id = 0x%02x", stream_id);

    br->skipBits(16); // PES_packet_length

    if (stream_id != 0xbc  // program_stream_map
            && stream_id != 0xbe  // padding_stream
            && stream_id != 0xbf  // private_stream_2
            && stream_id != 0xf0  // ECM
            && stream_id != 0xf1  // EMM
            && stream_id != 0xff  // program_stream_directory
            && stream_id != 0xf2  // DSMCC
            && stream_id != 0xf8) {  // H.222.1 type E
        if (br->getBits(2) != 2u) {
            return 0;
        }

        unsigned PES_scrambling_control = br->getBits(2);
        ALOGV("PES_scrambling_control = %u", PES_scrambling_control);

        if (PES_scrambling_control == 0) {
            return 0;
        }

        br->skipBits(12); // don't care

        unsigned PES_header_data_length = br->getBits(8);
        ALOGV("PES_header_data_length = %u", PES_header_data_length);

        if (PES_header_data_length * 8 > br->numBitsLeft()) {
            return 0;
        }

        *pesOffset = 9 + PES_header_data_length;
        ALOGD("found PES_scrambling_control=%d, PES offset=%d",
                PES_scrambling_control, *pesOffset);
        return PES_scrambling_control;
    }

    return 0;
}

status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
    if (mDescrambler == NULL) {
        ALOGE("received scrambled packets without descrambler!");
        return UNKNOWN_ERROR;
    }

    if (mDescrambledBuffer == NULL || mHidlMemory == NULL) {
        ALOGE("received scrambled packets without shared memory!");

        return UNKNOWN_ERROR;
    }

    int32_t pesOffset = 0;
    int32_t descrambleSubSamples = 0, descrambleBytes = 0;
    uint32_t tsScramblingControl = 0, pesScramblingControl = 0;

    // First, go over subsamples to find TS-level scrambling key id, and
    // calculate how many subsample we need to descramble (assuming we don't
    // have PES-level scrambling).
    for (auto it = mSubSamples.begin(); it != mSubSamples.end(); it++) {
        if (it->transport_scrambling_mode != 0) {
            // TODO: handle keyId change, use the first non-zero keyId for now.
            if (tsScramblingControl == 0) {
                tsScramblingControl = it->transport_scrambling_mode;
            }
        }
        if (tsScramblingControl == 0 || descrambleSubSamples == 0
                || !mQueue->isScrambled()) {
            descrambleSubSamples++;
            descrambleBytes += it->subSampleSize;
        }
    }
    // If not scrambled at TS-level, check PES-level scrambling
    if (tsScramblingControl == 0) {
        ABitReader br(mBuffer->data(), mBuffer->size());
        pesScramblingControl = getPesScramblingControl(&br, &pesOffset);
        // If not scrambled at PES-level either, or scrambled at PES-level but
        // requires output to remain scrambled, we don't need to descramble
        // anything.
        if (pesScramblingControl == 0 || mQueue->isScrambled()) {
            descrambleSubSamples = 0;
            descrambleBytes = 0;
        }
    }

    uint32_t sctrl = tsScramblingControl != 0 ?
            tsScramblingControl : pesScramblingControl;
    if (mQueue->isScrambled()) {
        sctrl |= DescramblerPlugin::kScrambling_Flag_PesHeader;
    }

    // Perform the 1st pass descrambling if needed
    if (descrambleBytes > 0) {
        memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
        mDescrambledBuffer->setRange(0, mBuffer->size());

        hidl_vec<SubSample> subSamples;
        subSamples.resize(descrambleSubSamples);

        int32_t i = 0;
        for (auto it = mSubSamples.begin();
                it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
            if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
                subSamples[i].numBytesOfClearData = 0;
                subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
            } else {
                subSamples[i].numBytesOfClearData = it->subSampleSize;
                subSamples[i].numBytesOfEncryptedData = 0;
            }
        }

        // If scrambled at PES-level, PES header is in the clear
        if (pesScramblingControl != 0) {
            subSamples[0].numBytesOfClearData = pesOffset;
            subSamples[0].numBytesOfEncryptedData -= pesOffset;
        }

        Status status = Status::OK;
        uint32_t bytesWritten = 0;
        hidl_string detailedError;

        DestinationBuffer dstBuffer;
        dstBuffer.type = BufferType::SHARED_MEMORY;
        dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;

        auto returnVoid = mDescrambler->descramble(
                (ScramblingControl) sctrl,
                subSamples,
                mDescramblerSrcBuffer,
                0 /*srcOffset*/,
                dstBuffer,
                0 /*dstOffset*/,
                [&status, &bytesWritten, &detailedError] (
                        Status _status, uint32_t _bytesWritten,
                        const hidl_string& _detailedError) {
                    status = _status;
                    bytesWritten = _bytesWritten;
                    detailedError = _detailedError;
                });

        if (!returnVoid.isOk() || status != Status::OK) {
            ALOGE("[stream %d] descramble failed, trans=%s, status=%d",
                    mElementaryPID, returnVoid.description().c_str(), status);
            return UNKNOWN_ERROR;
        }

        ALOGV("[stream %d] descramble succeeded, %d bytes",
                mElementaryPID, bytesWritten);

        // Set descrambleBytes to the returned result.
        // Note that this might be smaller than the total length of input data.
        // (eg. when we're descrambling the PES header portion of a secure stream,
        // the plugin might cut it off right after the PES header.)
        descrambleBytes = bytesWritten;
    }

    // |buffer| points to the buffer from which we'd parse the PES header.
    // When the output stream is scrambled, it points to mDescrambledBuffer
    // (unless all packets in this PES are actually clear, in which case,
    // it points to mBuffer since we never copied into mDescrambledBuffer).
    // When the output stream is clear, it points to mBuffer, and we'll
    // copy all descrambled data back to mBuffer.
    sp<ABuffer> buffer = mBuffer;
    if (mQueue->isScrambled()) {
        // Queue subSample info for scrambled queue
        sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
        sp<ABuffer> encSizesBuffer = new ABuffer(mSubSamples.size() * 4);
        int32_t *clearSizePtr = (int32_t*)clearSizesBuffer->data();
        int32_t *encSizePtr = (int32_t*)encSizesBuffer->data();
        int32_t isSync = 0;
        int32_t i = 0;
        for (auto it = mSubSamples.begin();
                it != mSubSamples.end(); it++, i++) {
            if ((it->transport_scrambling_mode == 0
                    && pesScramblingControl == 0)) {
                clearSizePtr[i] = it->subSampleSize;
                encSizePtr[i] = 0;
            } else {
                clearSizePtr[i] = 0;
                encSizePtr[i] = it->subSampleSize;
            }
            isSync |= it->random_access_indicator;
        }

        // If scrambled at PES-level, PES header is in the clear
        if (pesScramblingControl != 0) {
            clearSizePtr[0] = pesOffset;
            encSizePtr[0] -= pesOffset;
        }
        // Pass the original TS subsample size now. The PES header adjust
        // will be applied when the scrambled AU is dequeued.
        // Note that if descrambleBytes is 0, it means this PES contains only
        // all ts packets, leadingClearBytes is entire buffer size.
        mQueue->appendScrambledData(
                mBuffer->data(), mBuffer->size(),
                (descrambleBytes > 0) ? descrambleBytes : mBuffer->size(),
                sctrl, isSync, clearSizesBuffer, encSizesBuffer);

        if (descrambleBytes > 0) {
            buffer = mDescrambledBuffer;
        }
    } else {
        memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
    }

    ABitReader br(buffer->data(), buffer->size());
    status_t err = parsePES(&br, event);

    if (err != OK) {
        ALOGE("[stream %d] failed to parse descrambled PES, err=%d",
                mElementaryPID, err);
    }

    return err;
}


status_t ATSParser::Stream::flush(SyncEvent *event) {
    if (mBuffer == NULL || mBuffer->size() == 0) {
        return OK;
    }

    ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size());

    status_t err = OK;
    if (mScrambled) {
        err = flushScrambled(event);
        mSubSamples.clear();
    } else {
        ABitReader br(mBuffer->data(), mBuffer->size());
        err = parsePES(&br, event);
    }

    mBuffer->setRange(0, 0);

    return err;
}

void ATSParser::Stream::addAudioPresentations(const sp<ABuffer> &buffer) {
    std::ostringstream outStream(std::ios::out);
    serializeAudioPresentations(mAudioPresentations, &outStream);
    sp<ABuffer> ap = ABuffer::CreateAsCopy(outStream.str().data(), outStream.str().size());
    buffer->meta()->setBuffer("audio-presentation-info", ap);
}

void ATSParser::Stream::onPayloadData(
        unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
        unsigned PES_scrambling_control,
        const uint8_t *data, size_t size,
        int32_t payloadOffset, SyncEvent *event) {
#if 0
    ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
          mStreamType,
          PTS,
          (int64_t)PTS - mPrevPTS);
    mPrevPTS = PTS;
#endif

    ALOGV("onPayloadData mStreamType=0x%02x size: %zu", mStreamType, size);

    int64_t timeUs = 0LL;  // no presentation timestamp available.
    if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
        timeUs = mProgram->convertPTSToTimestamp(PTS);
    }

    status_t err = mQueue->appendData(
            data, size, timeUs, payloadOffset, PES_scrambling_control);

    if (mEOSReached) {
        mQueue->signalEOS();
    }

    if (err != OK) {
        return;
    }

    sp<ABuffer> accessUnit;
    bool found = false;
    while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
        if (mSource == NULL) {
            sp<MetaData> meta = mQueue->getFormat();

            if (meta != NULL) {
                ALOGV("Stream PID 0x%08x of type 0x%02x now has data.",
                     mElementaryPID, mStreamType);

                const char *mime;
                if (meta->findCString(kKeyMIMEType, &mime)
                        && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
                    int32_t sync = 0;
                    if (!accessUnit->meta()->findInt32("isSync", &sync) || !sync) {
                        continue;
                    }
                }
                mSource = new AnotherPacketSource(meta);
                if (mAudioPresentations.size() > 0) {
                    addAudioPresentations(accessUnit);
                }
                mSource->queueAccessUnit(accessUnit);
                ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
                        mElementaryPID, mStreamType);
            }
        } else if (mQueue->getFormat() != NULL) {
            // After a discontinuity we invalidate the queue's format
            // and won't enqueue any access units to the source until
            // the queue has reestablished the new format.

            if (mSource->getFormat() == NULL) {
                mSource->setFormat(mQueue->getFormat());
            }
            if (mAudioPresentations.size() > 0) {
                addAudioPresentations(accessUnit);
            }
            mSource->queueAccessUnit(accessUnit);
        }

        // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
        off64_t pesStartOffset = -1;
        if (!mPesStartOffsets.empty()) {
            pesStartOffset = *mPesStartOffsets.begin();
            mPesStartOffsets.erase(mPesStartOffsets.begin());
        }

        if (pesStartOffset >= 0 && (event != NULL) && !found && mQueue->getFormat() != NULL) {
            int32_t sync = 0;
            if (accessUnit->meta()->findInt32("isSync", &sync) && sync) {
                int64_t timeUs;
                if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
                    found = true;
                    event->init(pesStartOffset, mSource, timeUs, getSourceType());
                }
            }
        }
    }
}

ATSParser::SourceType ATSParser::Stream::getSourceType() {
    if (isVideo()) {
        return VIDEO;
    } else if (isAudio()) {
        return AUDIO;
    } else if (isMeta()) {
        return META;
    }
    return NUM_SOURCE_TYPES;
}

sp<AnotherPacketSource> ATSParser::Stream::getSource(SourceType type) {
    switch (type) {
        case VIDEO:
        {
            if (isVideo()) {
                return mSource;
            }
            break;
        }

        case AUDIO:
        {
            if (isAudio()) {
                return mSource;
            }
            break;
        }

        case META:
        {
            if (isMeta()) {
                return mSource;
            }
            break;
        }

        default:
            break;
    }

    return NULL;
}

void ATSParser::Stream::setCasInfo(
        int32_t systemId, const sp<IDescrambler> &descrambler,
        const std::vector<uint8_t> &sessionId) {
    if (mSource != NULL && mDescrambler == NULL && descrambler != NULL) {
        signalDiscontinuity(DISCONTINUITY_FORMAT_ONLY, NULL);
        mDescrambler = descrambler;
        if (mQueue->isScrambled()) {
            mQueue->setCasInfo(systemId, sessionId);
        }
    }
}

////////////////////////////////////////////////////////////////////////////////

ATSParser::ATSParser(uint32_t flags)
    : mFlags(flags),
      mAbsoluteTimeAnchorUs(-1LL),
      mTimeOffsetValid(false),
      mTimeOffsetUs(0LL),
      mLastRecoveredPTS(-1LL),
      mNumTSPacketsParsed(0),
      mNumPCRs(0) {
    mPSISections.add(0 /* PID */, new PSISection);
    mCasManager = new CasManager();
}

ATSParser::~ATSParser() {
}

status_t ATSParser::feedTSPacket(const void *data, size_t size,
        SyncEvent *event) {
    if (size != kTSPacketSize) {
        ALOGE("Wrong TS packet size");
        return BAD_VALUE;
    }

    ABitReader br((const uint8_t *)data, kTSPacketSize);
    return parseTS(&br, event);
}

status_t ATSParser::setMediaCas(const sp<ICas> &cas) {
    status_t err = mCasManager->setMediaCas(cas);
    if (err != OK) {
        return err;
    }
    for (size_t i = 0; i < mPrograms.size(); ++i) {
        mPrograms.editItemAt(i)->updateCasSessions();
    }
    return OK;
}

void ATSParser::signalDiscontinuity(
        DiscontinuityType type, const sp<AMessage> &extra) {
    int64_t mediaTimeUs;
    if ((type & DISCONTINUITY_TIME) && extra != NULL) {
        if (extra->findInt64(kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
            mAbsoluteTimeAnchorUs = mediaTimeUs;
        }
        if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)
                && extra->findInt64(
                    kATSParserKeyRecentMediaTimeUs, &mediaTimeUs)) {
            if (mAbsoluteTimeAnchorUs >= 0LL) {
                mediaTimeUs -= mAbsoluteTimeAnchorUs;
            }
            if (mTimeOffsetValid) {
                mediaTimeUs -= mTimeOffsetUs;
            }
            mLastRecoveredPTS = (mediaTimeUs * 9) / 100;
        }
    } else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
        int64_t timeUs;
        if (!extra->findInt64("timeUs", &timeUs)) {
            ALOGE("timeUs not found");
            return;
        }

        if (!mPrograms.empty()) {
            ALOGE("mPrograms is not empty");
            return;
        }
        mAbsoluteTimeAnchorUs = timeUs;
        return;
    } else if (type == DISCONTINUITY_TIME_OFFSET) {
        int64_t offset;
        if (!extra->findInt64("offset", &offset)) {
            ALOGE("offset not found");
            return;
        }

        mTimeOffsetValid = true;
        mTimeOffsetUs = offset;
        return;
    }

    for (size_t i = 0; i < mPrograms.size(); ++i) {
        mPrograms.editItemAt(i)->signalDiscontinuity(type, extra);
    }
}

void ATSParser::signalEOS(status_t finalResult) {
    if (finalResult == (status_t) OK) {
        ALOGE("finalResult not OK");
        return;
    }

    for (size_t i = 0; i < mPrograms.size(); ++i) {
        mPrograms.editItemAt(i)->signalEOS(finalResult);
    }
}

void ATSParser::parseProgramAssociationTable(ABitReader *br) {
    if (br->numBitsLeft() < 8) {
        ALOGE("Not enough data left in bitreader!");
        return;
    }
    unsigned table_id = br->getBits(8);
    ALOGV("  table_id = %u", table_id);
    if (table_id != 0x00u) {
        ALOGE("PAT data error!");
        return ;
    }
    if (br->numBitsLeft() < 56) {
        ALOGE("Not enough data left in bitreader!");
        return;
    }
    unsigned section_syntax_indictor = br->getBits(1);
    ALOGV("  section_syntax_indictor = %u", section_syntax_indictor);

    br->skipBits(1);  // '0'
    MY_LOGV("  reserved = %u", br->getBits(2));

    unsigned section_length = br->getBits(12);
    ALOGV("  section_length = %u", section_length);

    MY_LOGV("  transport_stream_id = %u", br->getBits(16));
    MY_LOGV("  reserved = %u", br->getBits(2));
    MY_LOGV("  version_number = %u", br->getBits(5));
    MY_LOGV("  current_next_indicator = %u", br->getBits(1));
    MY_LOGV("  section_number = %u", br->getBits(8));
    MY_LOGV("  last_section_number = %u", br->getBits(8));

    // check for unsigned integer overflow before assigning it to numProgramBytes
    if (section_length < 9) {
        return;
    }
    size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);

    for (size_t i = 0; i < numProgramBytes / 4; ++i) {
        if (br->numBitsLeft() < 32) {
            ALOGE("Not enough data left in bitreader!");
            return;
        }
        unsigned program_number = br->getBits(16);
        ALOGV("    program_number = %u", program_number);

        MY_LOGV("    reserved = %u", br->getBits(3));

        if (program_number == 0) {
            MY_LOGV("    network_PID = 0x%04x", br->getBits(13));
        } else {
            unsigned programMapPID = br->getBits(13);

            ALOGV("    program_map_PID = 0x%04x", programMapPID);

            bool found = false;
            for (size_t index = 0; index < mPrograms.size(); ++index) {
                const sp<Program> &program = mPrograms.itemAt(index);

                if (program->number() == program_number) {
                    program->updateProgramMapPID(programMapPID);
                    found = true;
                    break;
                }
            }

            if (!found) {
                mPrograms.push(
                        new Program(this, program_number, programMapPID, mLastRecoveredPTS));
                if (mSampleAesKeyItem != NULL) {
                    mPrograms.top()->signalNewSampleAesKey(mSampleAesKeyItem);
                }
            }

            if (mPSISections.indexOfKey(programMapPID) < 0) {
                mPSISections.add(programMapPID, new PSISection);
            }
        }
    }

    if (br->numBitsLeft() < 32) {
        ALOGE("Not enough data left in bitreader!");
        return;
    }
    MY_LOGV("  CRC = 0x%08x", br->getBits(32));
}

status_t ATSParser::parsePID(
        ABitReader *br, unsigned PID,
        unsigned continuity_counter,
        unsigned payload_unit_start_indicator,
        unsigned transport_scrambling_control,
        unsigned random_access_indicator,
        SyncEvent *event) {
    ssize_t sectionIndex = mPSISections.indexOfKey(PID);

    if (sectionIndex >= 0) {
        sp<PSISection> section = mPSISections.valueAt(sectionIndex);

        if (payload_unit_start_indicator) {
            if (!section->isEmpty()) {
                ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty");
                section->clear();
            }

            if (br->numBitsLeft() < 8) {
                ALOGE("Not enough data left in bitreader!");
                return ERROR_MALFORMED;
            }
            unsigned skip = br->getBits(8);
            section->setSkipBytes(skip + 1);  // skip filler bytes + pointer field itself
            if (!br->skipBits(skip * 8)) {
                ALOGE("Not enough data left in bitreader!");
                return ERROR_MALFORMED;
            }
        }

        if (br->numBitsLeft() % 8 != 0) {
            return ERROR_MALFORMED;
        }
        status_t err = section->append(br->data(), br->numBitsLeft() / 8);

        if (err != OK) {
            return err;
        }

        if (!section->isComplete()) {
            return OK;
        }

        if (!section->isCRCOkay()) {
            return BAD_VALUE;
        }
        ABitReader sectionBits(section->data(), section->size());

        if (PID == 0) {
            parseProgramAssociationTable(&sectionBits);
        } else {
            bool handled = false;
            for (size_t i = 0; i < mPrograms.size(); ++i) {
                status_t err;
                if (!mPrograms.editItemAt(i)->parsePSISection(
                            PID, &sectionBits, &err)) {
                    continue;
                }

                if (err != OK) {
                    return err;
                }

                handled = true;
                break;
            }

            if (!handled) {
                mPSISections.removeItem(PID);
                section.clear();
            }
        }

        if (section != NULL) {
            section->clear();
        }

        return OK;
    }

    bool handled = false;
    for (size_t i = 0; i < mPrograms.size(); ++i) {
        status_t err;
        if (mPrograms.editItemAt(i)->parsePID(
                    PID, continuity_counter,
                    payload_unit_start_indicator,
                    transport_scrambling_control,
                    random_access_indicator,
                    br, &err, event)) {
            if (err != OK) {
                return err;
            }

            handled = true;
            break;
        }
    }

    if (!handled) {
        handled = mCasManager->parsePID(br, PID);
    }

    if (!handled) {
        ALOGV("PID 0x%04x not handled.", PID);
    }

    return OK;
}

status_t ATSParser::parseAdaptationField(
        ABitReader *br, unsigned PID, unsigned *random_access_indicator) {
    *random_access_indicator = 0;
    if (br->numBitsLeft() < 8) {
        ALOGE("Not enough data left in bitreader!");
        return ERROR_MALFORMED;
    }
    unsigned adaptation_field_length = br->getBits(8);

    if (adaptation_field_length > 0) {
        if (adaptation_field_length * 8 > br->numBitsLeft()) {
            ALOGV("Adaptation field should be included in a single TS packet.");
            return ERROR_MALFORMED;
        }

        unsigned discontinuity_indicator = br->getBits(1);

        if (discontinuity_indicator) {
            ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID);
        }

        *random_access_indicator = br->getBits(1);
        if (*random_access_indicator) {
            ALOGV("PID 0x%04x: random_access_indicator = 1", PID);
        }

        unsigned elementary_stream_priority_indicator = br->getBits(1);
        if (elementary_stream_priority_indicator) {
            ALOGV("PID 0x%04x: elementary_stream_priority_indicator = 1", PID);
        }

        unsigned PCR_flag = br->getBits(1);

        size_t numBitsRead = 4;

        if (PCR_flag) {
            if (adaptation_field_length * 8 < 52) {
                return ERROR_MALFORMED;
            }
            br->skipBits(4);
            uint64_t PCR_base = br->getBits(32);
            PCR_base = (PCR_base << 1) | br->getBits(1);

            br->skipBits(6);
            unsigned PCR_ext = br->getBits(9);

            // The number of bytes from the start of the current
            // MPEG2 transport stream packet up and including
            // the final byte of this PCR_ext field.
            size_t byteOffsetFromStartOfTSPacket =
                (188 - br->numBitsLeft() / 8);

            uint64_t PCR = PCR_base * 300 + PCR_ext;

            ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)",
                  PID, PCR, PCR / 27E6);

            // The number of bytes received by this parser up to and
            // including the final byte of this PCR_ext field.
            uint64_t byteOffsetFromStart =
                uint64_t(mNumTSPacketsParsed) * 188 + byteOffsetFromStartOfTSPacket;

            for (size_t i = 0; i < mPrograms.size(); ++i) {
                updatePCR(PID, PCR, byteOffsetFromStart);
            }

            numBitsRead += 52;
        }

        br->skipBits(adaptation_field_length * 8 - numBitsRead);
    }
    return OK;
}

status_t ATSParser::parseTS(ABitReader *br, SyncEvent *event) {
    ALOGV("---");

    if (br->numBitsLeft() < 32) {
        ALOGE("Not enough data left in bitreader!");
        return ERROR_MALFORMED;
    }
    unsigned sync_byte = br->getBits(8);
    if (sync_byte != 0x47u) {
        ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte);
        return BAD_VALUE;
    }

    if (br->getBits(1)) {  // transport_error_indicator
        // silently ignore.
        return OK;
    }

    unsigned payload_unit_start_indicator = br->getBits(1);
    ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator);

    MY_LOGV("transport_priority = %u", br->getBits(1));

    unsigned PID = br->getBits(13);
    ALOGV("PID = 0x%04x", PID);

    unsigned transport_scrambling_control = br->getBits(2);
    ALOGV("transport_scrambling_control = %u", transport_scrambling_control);

    unsigned adaptation_field_control = br->getBits(2);
    ALOGV("adaptation_field_control = %u", adaptation_field_control);

    unsigned continuity_counter = br->getBits(4);
    ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);

    // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);

    status_t err = OK;

    unsigned random_access_indicator = 0;
    if (adaptation_field_control == 2 || adaptation_field_control == 3) {
        err = parseAdaptationField(br, PID, &random_access_indicator);
    }
    if (err == OK) {
        if (adaptation_field_control == 1 || adaptation_field_control == 3) {
            err = parsePID(br, PID, continuity_counter,
                    payload_unit_start_indicator,
                    transport_scrambling_control,
                    random_access_indicator,
                    event);
        }
    }

    ++mNumTSPacketsParsed;

    return err;
}

sp<AnotherPacketSource> ATSParser::getSource(SourceType type) {
    sp<AnotherPacketSource> firstSourceFound;
    for (size_t i = 0; i < mPrograms.size(); ++i) {
        const sp<Program> &program = mPrograms.editItemAt(i);
        sp<AnotherPacketSource> source = program->getSource(type);
        if (source == NULL) {
            continue;
        }
        if (firstSourceFound == NULL) {
            firstSourceFound = source;
        }
        // Prefer programs with both audio/video
        switch (type) {
            case VIDEO: {
                if (program->hasSource(AUDIO)) {
                    return source;
                }
                break;
            }

            case AUDIO: {
                if (program->hasSource(VIDEO)) {
                    return source;
                }
                break;
            }

            default:
                return source;
        }
    }

    return firstSourceFound;
}

bool ATSParser::hasSource(SourceType type) const {
    for (size_t i = 0; i < mPrograms.size(); ++i) {
        const sp<Program> &program = mPrograms.itemAt(i);
        if (program->hasSource(type)) {
            return true;
        }
    }

    return false;
}

bool ATSParser::PTSTimeDeltaEstablished() {
    if (mPrograms.isEmpty()) {
        return false;
    }

    return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished();
}

int64_t ATSParser::getFirstPTSTimeUs() {
    for (size_t i = 0; i < mPrograms.size(); ++i) {
        sp<ATSParser::Program> program = mPrograms.itemAt(i);
        if (program->PTSTimeDeltaEstablished()) {
            return (program->firstPTS() * 100) / 9;
        }
    }
    return -1;
}

__attribute__((no_sanitize("integer")))
void ATSParser::updatePCR(
        unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
    ALOGV("PCR 0x%016" PRIx64 " @ %" PRIx64, PCR, byteOffsetFromStart);

    if (mNumPCRs == 2) {
        mPCR[0] = mPCR[1];
        mPCRBytes[0] = mPCRBytes[1];
        mSystemTimeUs[0] = mSystemTimeUs[1];
        mNumPCRs = 1;
    }

    mPCR[mNumPCRs] = PCR;
    mPCRBytes[mNumPCRs] = byteOffsetFromStart;
    mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs();

    ++mNumPCRs;

    if (mNumPCRs == 2) {
        /* Unsigned overflow here */
        double transportRate =
            (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]);

        ALOGV("transportRate = %.2f bytes/sec", transportRate);
    }
}

////////////////////////////////////////////////////////////////////////////////


// CRC32 used for PSI section. The table was generated by following command:
// $ python pycrc.py --model crc-32-mpeg --algorithm table-driven --generate c
// Visit http://www.tty1.net/pycrc/index_en.html for more details.
uint32_t ATSParser::PSISection::CRC_TABLE[] = {
    0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
    0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
    0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
    0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
    0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
    0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
    0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
    0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
    0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
    0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
    0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
    0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
    0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
    0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
    0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
    0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
    0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
    0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
    0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
    0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
    0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
    0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
    0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
    0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
    0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
    0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
    0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
    0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
    0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
    0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
    0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
    0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
    0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
    0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
    0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
    0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
    0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
    0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
    0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
    0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
    0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
    0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
    0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
    0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
    0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
    0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
    0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
    0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
    0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
    0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
    0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
    0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
    0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
    0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
    0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
    0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
    0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
    0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
    0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
    0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
    0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
    0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
    };

ATSParser::PSISection::PSISection() :
    mSkipBytes(0) {
}

ATSParser::PSISection::~PSISection() {
}

status_t ATSParser::PSISection::append(const void *data, size_t size) {
    if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) {
        size_t newCapacity =
            (mBuffer == NULL) ? size : mBuffer->capacity() + size;

        newCapacity = (newCapacity + 1023) & ~1023;

        sp<ABuffer> newBuffer = new ABuffer(newCapacity);

        if (mBuffer != NULL) {
            memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
            newBuffer->setRange(0, mBuffer->size());
        } else {
            newBuffer->setRange(0, 0);
        }

        mBuffer = newBuffer;
    }

    memcpy(mBuffer->data() + mBuffer->size(), data, size);
    mBuffer->setRange(0, mBuffer->size() + size);

    return OK;
}

void ATSParser::PSISection::setSkipBytes(uint8_t skip) {
    mSkipBytes = skip;
}

void ATSParser::PSISection::clear() {
    if (mBuffer != NULL) {
        mBuffer->setRange(0, 0);
    }
    mSkipBytes = 0;
}

bool ATSParser::PSISection::isComplete() const {
    if (mBuffer == NULL || mBuffer->size() < 3) {
        return false;
    }

    unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff;
    return mBuffer->size() >= sectionLength + 3;
}

bool ATSParser::PSISection::isEmpty() const {
    return mBuffer == NULL || mBuffer->size() == 0;
}

const uint8_t *ATSParser::PSISection::data() const {
    return mBuffer == NULL ? NULL : mBuffer->data();
}

size_t ATSParser::PSISection::size() const {
    return mBuffer == NULL ? 0 : mBuffer->size();
}

bool ATSParser::PSISection::isCRCOkay() const {
    if (!isComplete()) {
        return false;
    }
    uint8_t* data = mBuffer->data();

    // Return true if section_syntax_indicator says no section follows the field section_length.
    if ((data[1] & 0x80) == 0) {
        return true;
    }

    unsigned sectionLength = U16_AT(data + 1) & 0xfff;
    ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes);


    if(sectionLength < mSkipBytes) {
        ALOGE("b/28333006");
        android_errorWriteLog(0x534e4554, "28333006");
        return false;
    }

    // Skip the preceding field present when payload start indicator is on.
    sectionLength -= mSkipBytes;

    uint32_t crc = 0xffffffff;
    for(unsigned i = 0; i < sectionLength + 4 /* crc */; i++) {
        uint8_t b = data[i];
        int index = ((crc >> 24) ^ (b & 0xff)) & 0xff;
        crc = CRC_TABLE[index] ^ (crc << 8);
    }
    ALOGV("crc: %08x\n", crc);
    return (crc == 0);
}

// SAMPLE_AES key handling
// TODO: Merge these to their respective class after Widevine-HLS
void ATSParser::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
    ALOGD("signalNewSampleAesKey: %p", keyItem.get());

    mSampleAesKeyItem = keyItem;

    // a NULL key item will propagate to existing ElementaryStreamQueues
    for (size_t i = 0; i < mPrograms.size(); ++i) {
        mPrograms[i]->signalNewSampleAesKey(keyItem);
    }
}

void ATSParser::Program::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
    ALOGD("Program::signalNewSampleAesKey: %p", keyItem.get());

    mSampleAesKeyItem = keyItem;

    // a NULL key item will propagate to existing ElementaryStreamQueues
    for (size_t i = 0; i < mStreams.size(); ++i) {
        mStreams[i]->signalNewSampleAesKey(keyItem);
    }
}

void ATSParser::Stream::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
    ALOGD("Stream::signalNewSampleAesKey: 0x%04x size = %zu keyItem: %p",
          mElementaryPID, mBuffer->size(), keyItem.get());

    // a NULL key item will propagate to existing ElementaryStreamQueues
    mSampleAesKeyItem = keyItem;

    flush(NULL);
    mQueue->signalNewSampleAesKey(keyItem);
}

}  // namespace android
