Loading media/libstagefright/mpeg2ts/ATSParser.cpp +155 −13 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> #include <media/stagefright/Utils.h> #include <media/IStreamSource.h> #include <utils/KeyedVector.h> Loading @@ -46,6 +47,9 @@ static const size_t kTSPacketSize = 188; struct ATSParser::Program : public RefBase { Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID); bool parsePSISection( unsigned pid, ABitReader *br, status_t *err); bool parsePID( unsigned pid, unsigned payload_unit_start_indicator, ABitReader *br, status_t *err); Loading @@ -69,6 +73,10 @@ struct ATSParser::Program : public RefBase { mProgramMapPID = programMapPID; } unsigned programMapPID() const { return mProgramMapPID; } private: ATSParser *mParser; unsigned mProgramNumber; Loading Loading @@ -129,6 +137,27 @@ private: DISALLOW_EVIL_CONSTRUCTORS(Stream); }; struct ATSParser::PSISection : public RefBase { PSISection(); status_t append(const void *data, size_t size); void clear(); bool isComplete() const; bool isEmpty() const; const uint8_t *data() const; size_t size() const; protected: virtual ~PSISection(); private: sp<ABuffer> mBuffer; DISALLOW_EVIL_CONSTRUCTORS(PSISection); }; //////////////////////////////////////////////////////////////////////////////// ATSParser::Program::Program( Loading @@ -141,15 +170,12 @@ ATSParser::Program::Program( ALOGV("new program number %u", programNumber); } bool ATSParser::Program::parsePID( unsigned pid, unsigned payload_unit_start_indicator, ABitReader *br, status_t *err) { bool ATSParser::Program::parsePSISection( unsigned pid, ABitReader *br, status_t *err) { *err = OK; if (pid == mProgramMapPID) { if (payload_unit_start_indicator) { unsigned skip = br->getBits(8); br->skipBits(skip * 8); if (pid != mProgramMapPID) { return false; } *err = parseProgramMap(br); Loading @@ -157,6 +183,11 @@ bool ATSParser::Program::parsePID( return true; } bool ATSParser::Program::parsePID( unsigned pid, unsigned payload_unit_start_indicator, ABitReader *br, status_t *err) { *err = OK; ssize_t index = mStreams.indexOfKey(pid); if (index < 0) { return false; Loading Loading @@ -817,6 +848,7 @@ sp<MediaSource> ATSParser::Stream::getSource(SourceType type) { ATSParser::ATSParser(uint32_t flags) : mFlags(flags) { mPSISections.add(0 /* PID */, new PSISection); } ATSParser::~ATSParser() { Loading Loading @@ -898,6 +930,10 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) { mPrograms.push( new Program(this, program_number, programMapPID)); } if (mPSISections.indexOfKey(programMapPID) < 0) { mPSISections.add(programMapPID, new PSISection); } } } Loading @@ -907,12 +943,58 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) { status_t ATSParser::parsePID( ABitReader *br, unsigned PID, unsigned payload_unit_start_indicator) { if (PID == 0) { ssize_t sectionIndex = mPSISections.indexOfKey(PID); if (sectionIndex >= 0) { const sp<PSISection> §ion = mPSISections.valueAt(sectionIndex); if (payload_unit_start_indicator) { CHECK(section->isEmpty()); unsigned skip = br->getBits(8); br->skipBits(skip * 8); } parseProgramAssociationTable(br); CHECK((br->numBitsLeft() % 8) == 0); status_t err = section->append(br->data(), br->numBitsLeft() / 8); if (err != OK) { return err; } if (!section->isComplete()) { return OK; } ABitReader sectionBits(section->data(), section->size()); if (PID == 0) { parseProgramAssociationTable(§ionBits); } else { bool handled = false; for (size_t i = 0; i < mPrograms.size(); ++i) { status_t err; if (!mPrograms.editItemAt(i)->parsePSISection( PID, §ionBits, &err)) { continue; } if (err != OK) { return err; } handled = true; break; } if (!handled) { mPSISections.removeItem(PID); } } section->clear(); return OK; } Loading Loading @@ -1009,4 +1091,64 @@ bool ATSParser::PTSTimeDeltaEstablished() { return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished(); } //////////////////////////////////////////////////////////////////////////////// ATSParser::PSISection::PSISection() { } 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::clear() { if (mBuffer != NULL) { mBuffer->setRange(0, 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(); } } // namespace android media/libstagefright/mpeg2ts/ATSParser.h +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <media/stagefright/foundation/ABase.h> #include <media/stagefright/foundation/AMessage.h> #include <utils/KeyedVector.h> #include <utils/Vector.h> #include <utils/RefBase.h> Loading Loading @@ -91,10 +92,14 @@ protected: private: struct Program; struct Stream; struct PSISection; uint32_t mFlags; Vector<sp<Program> > mPrograms; // Keyed by PID KeyedVector<unsigned, sp<PSISection> > mPSISections; void parseProgramAssociationTable(ABitReader *br); void parseProgramMap(ABitReader *br); void parsePES(ABitReader *br); Loading Loading
media/libstagefright/mpeg2ts/ATSParser.cpp +155 −13 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <media/stagefright/MetaData.h> #include <media/stagefright/Utils.h> #include <media/IStreamSource.h> #include <utils/KeyedVector.h> Loading @@ -46,6 +47,9 @@ static const size_t kTSPacketSize = 188; struct ATSParser::Program : public RefBase { Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID); bool parsePSISection( unsigned pid, ABitReader *br, status_t *err); bool parsePID( unsigned pid, unsigned payload_unit_start_indicator, ABitReader *br, status_t *err); Loading @@ -69,6 +73,10 @@ struct ATSParser::Program : public RefBase { mProgramMapPID = programMapPID; } unsigned programMapPID() const { return mProgramMapPID; } private: ATSParser *mParser; unsigned mProgramNumber; Loading Loading @@ -129,6 +137,27 @@ private: DISALLOW_EVIL_CONSTRUCTORS(Stream); }; struct ATSParser::PSISection : public RefBase { PSISection(); status_t append(const void *data, size_t size); void clear(); bool isComplete() const; bool isEmpty() const; const uint8_t *data() const; size_t size() const; protected: virtual ~PSISection(); private: sp<ABuffer> mBuffer; DISALLOW_EVIL_CONSTRUCTORS(PSISection); }; //////////////////////////////////////////////////////////////////////////////// ATSParser::Program::Program( Loading @@ -141,15 +170,12 @@ ATSParser::Program::Program( ALOGV("new program number %u", programNumber); } bool ATSParser::Program::parsePID( unsigned pid, unsigned payload_unit_start_indicator, ABitReader *br, status_t *err) { bool ATSParser::Program::parsePSISection( unsigned pid, ABitReader *br, status_t *err) { *err = OK; if (pid == mProgramMapPID) { if (payload_unit_start_indicator) { unsigned skip = br->getBits(8); br->skipBits(skip * 8); if (pid != mProgramMapPID) { return false; } *err = parseProgramMap(br); Loading @@ -157,6 +183,11 @@ bool ATSParser::Program::parsePID( return true; } bool ATSParser::Program::parsePID( unsigned pid, unsigned payload_unit_start_indicator, ABitReader *br, status_t *err) { *err = OK; ssize_t index = mStreams.indexOfKey(pid); if (index < 0) { return false; Loading Loading @@ -817,6 +848,7 @@ sp<MediaSource> ATSParser::Stream::getSource(SourceType type) { ATSParser::ATSParser(uint32_t flags) : mFlags(flags) { mPSISections.add(0 /* PID */, new PSISection); } ATSParser::~ATSParser() { Loading Loading @@ -898,6 +930,10 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) { mPrograms.push( new Program(this, program_number, programMapPID)); } if (mPSISections.indexOfKey(programMapPID) < 0) { mPSISections.add(programMapPID, new PSISection); } } } Loading @@ -907,12 +943,58 @@ void ATSParser::parseProgramAssociationTable(ABitReader *br) { status_t ATSParser::parsePID( ABitReader *br, unsigned PID, unsigned payload_unit_start_indicator) { if (PID == 0) { ssize_t sectionIndex = mPSISections.indexOfKey(PID); if (sectionIndex >= 0) { const sp<PSISection> §ion = mPSISections.valueAt(sectionIndex); if (payload_unit_start_indicator) { CHECK(section->isEmpty()); unsigned skip = br->getBits(8); br->skipBits(skip * 8); } parseProgramAssociationTable(br); CHECK((br->numBitsLeft() % 8) == 0); status_t err = section->append(br->data(), br->numBitsLeft() / 8); if (err != OK) { return err; } if (!section->isComplete()) { return OK; } ABitReader sectionBits(section->data(), section->size()); if (PID == 0) { parseProgramAssociationTable(§ionBits); } else { bool handled = false; for (size_t i = 0; i < mPrograms.size(); ++i) { status_t err; if (!mPrograms.editItemAt(i)->parsePSISection( PID, §ionBits, &err)) { continue; } if (err != OK) { return err; } handled = true; break; } if (!handled) { mPSISections.removeItem(PID); } } section->clear(); return OK; } Loading Loading @@ -1009,4 +1091,64 @@ bool ATSParser::PTSTimeDeltaEstablished() { return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished(); } //////////////////////////////////////////////////////////////////////////////// ATSParser::PSISection::PSISection() { } 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::clear() { if (mBuffer != NULL) { mBuffer->setRange(0, 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(); } } // namespace android
media/libstagefright/mpeg2ts/ATSParser.h +5 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <media/stagefright/foundation/ABase.h> #include <media/stagefright/foundation/AMessage.h> #include <utils/KeyedVector.h> #include <utils/Vector.h> #include <utils/RefBase.h> Loading Loading @@ -91,10 +92,14 @@ protected: private: struct Program; struct Stream; struct PSISection; uint32_t mFlags; Vector<sp<Program> > mPrograms; // Keyed by PID KeyedVector<unsigned, sp<PSISection> > mPSISections; void parseProgramAssociationTable(ABitReader *br); void parseProgramMap(ABitReader *br); void parsePES(ABitReader *br); Loading