ATSParser.cpp revision c9fa35cf7c9c11a8acb77128db1a6a13f1befe3c
1cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber/* 2cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 4cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * you may not use this file except in compliance with the License. 6cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * You may obtain a copy of the License at 7cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 8cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 10cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Unless required by applicable law or agreed to in writing, software 11cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * See the License for the specific language governing permissions and 14cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * limitations under the License. 15cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber */ 16cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0 186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "ATSParser" 196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h> 206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber 21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ATSParser.h" 22cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "AnotherPacketSource.h" 246a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber#include "ESQueue.h" 2585f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include "include/avc_utils.h" 26cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2785f12e9b9062402d6110df3f7099707912040edbAndreas Huber#include <media/stagefright/foundation/ABitReader.h> 28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/ABuffer.h> 29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/ADebug.h> 30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/AMessage.h> 31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/hexdump.h> 32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaDefs.h> 33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MediaErrors.h> 34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/MetaData.h> 358dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber#include <media/stagefright/Utils.h> 3632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber#include <media/IStreamSource.h> 37cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <utils/KeyedVector.h> 389bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang#include <utils/Vector.h> 39cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 40b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross#include <inttypes.h> 41b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross 42cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android { 43cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 446e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber// I want the expression "y" evaluated even if verbose logging is off. 456e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define MY_LOGV(x, y) \ 463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block do { unsigned tmp = y; ALOGV(x, tmp); } while (0) 476e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber 48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstatic const size_t kTSPacketSize = 188; 49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct ATSParser::Program : public RefBase { 51d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID, 52d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang int64_t lastRecoveredPTS); 53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber bool parsePSISection( 558dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber unsigned pid, ABitReader *br, status_t *err); 568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 57540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Pass to appropriate stream according to pid, and set event if it's a PES 58540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // with a sync frame. 59540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Note that the method itself does not touch event. 60cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool parsePID( 6187f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned pid, unsigned continuity_counter, 6287f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned payload_unit_start_indicator, 63540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ABitReader *br, status_t *err, SyncEvent *event); 64cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 6532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber void signalDiscontinuity( 6632f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber DiscontinuityType type, const sp<AMessage> &extra); 6732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void signalEOS(status_t finalResult); 692a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber 70cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MediaSource> getSource(SourceType type); 71bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih bool hasSource(SourceType type) const; 72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 73bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber int64_t convertPTSToTimestamp(uint64_t PTS); 74bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 7543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber bool PTSTimeDeltaEstablished() const { 7643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber return mFirstPTSValid; 7743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 7843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 79386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned number() const { return mProgramNumber; } 80386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 81386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber void updateProgramMapPID(unsigned programMapPID) { 82386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mProgramMapPID = programMapPID; 83386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 84386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 858dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber unsigned programMapPID() const { 868dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return mProgramMapPID; 878dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 888dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 8987f2a558dd12043631e12c361abef301bf603140Andreas Huber uint32_t parserFlags() const { 9087f2a558dd12043631e12c361abef301bf603140Andreas Huber return mParser->mFlags; 9187f2a558dd12043631e12c361abef301bf603140Andreas Huber } 9287f2a558dd12043631e12c361abef301bf603140Andreas Huber 93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate: 949bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang struct StreamInfo { 959bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang unsigned mType; 969bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang unsigned mPID; 979bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang }; 989bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ATSParser *mParser; 100386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber unsigned mProgramNumber; 101cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned mProgramMapPID; 102cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber KeyedVector<unsigned, sp<Stream> > mStreams; 103bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber bool mFirstPTSValid; 104bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber uint64_t mFirstPTS; 105799c9682b3776a55d234396aee4a302437150c26Chong Zhang int64_t mLastRecoveredPTS; 106cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 10706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber status_t parseProgramMap(ABitReader *br); 108799c9682b3776a55d234396aee4a302437150c26Chong Zhang int64_t recoverPTS(uint64_t PTS_33bit); 1099bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang bool switchPIDs(const Vector<StreamInfo> &infos); 110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(Program); 112cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}; 113cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 114cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberstruct ATSParser::Stream : public RefBase { 11587f2a558dd12043631e12c361abef301bf603140Andreas Huber Stream(Program *program, 11687f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned elementaryPID, 11787f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned streamType, 11887f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned PCR_PID); 119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 120bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber unsigned type() const { return mStreamType; } 121bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber unsigned pid() const { return mElementaryPID; } 122bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber void setPID(unsigned pid) { mElementaryPID = pid; } 123bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 124540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Parse the payload and set event when PES with a sync frame is detected. 125540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // This method knows when a PES starts; so record mPesStartOffset in that 126540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // case. 1275403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber status_t parse( 12887f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned continuity_counter, 129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned payload_unit_start_indicator, 130540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ABitReader *br, 131540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim SyncEvent *event); 132cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 13332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber void signalDiscontinuity( 13432f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber DiscontinuityType type, const sp<AMessage> &extra); 13532f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber void signalEOS(status_t finalResult); 1372a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber 138cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MediaSource> getSource(SourceType type); 139cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 140bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih bool isAudio() const; 141bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih bool isVideo() const; 1420852843d304006e3ab333081fddda13b07193de8Robert Shih bool isMeta() const; 143bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih 144cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprotected: 145cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber virtual ~Stream(); 146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberprivate: 148bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber Program *mProgram; 149cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned mElementaryPID; 150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned mStreamType; 15187f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned mPCR_PID; 15287f2a558dd12043631e12c361abef301bf603140Andreas Huber int32_t mExpectedContinuityCounter; 153cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 154cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<ABuffer> mBuffer; 155cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<AnotherPacketSource> mSource; 156cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool mPayloadStarted; 157be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen bool mEOSReached; 158cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 15990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint64_t mPrevPTS; 160540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim off64_t mPesStartOffset; 16190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 162386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ElementaryStreamQueue *mQueue; 1636a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber 164540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Flush accumulated payload if necessary --- i.e. at EOS or at the start of 165540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // another payload. event is set if the flushed payload is PES with a sync 166540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // frame. 167540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t flush(SyncEvent *event); 168540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Strip and parse PES headers and pass remaining payload into onPayload 169540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // with parsed metadata. event is set if the PES contains a sync frame. 170540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t parsePES(ABitReader *br, SyncEvent *event); 171540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 172540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // Feed the payload into mQueue and if a packet is identified, queue it 173540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // into mSource. If the packet is a sync frame. set event with start offset 174540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim // and timestamp of the packet. 175cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber void onPayloadData( 176cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS, 177540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const uint8_t *data, size_t size, SyncEvent *event); 17882f7321b03eec1e40af9d681370f754ee0279582Andreas Huber 179cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(Stream); 180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}; 181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1828dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberstruct ATSParser::PSISection : public RefBase { 1838dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber PSISection(); 1848dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 1858dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber status_t append(const void *data, size_t size); 1869ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim void setSkipBytes(uint8_t skip); 1878dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber void clear(); 1888dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 1898dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber bool isComplete() const; 1908dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber bool isEmpty() const; 1919ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim bool isCRCOkay() const; 1928dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 1938dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber const uint8_t *data() const; 1948dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber size_t size() const; 1958dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 1968dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberprotected: 1978dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber virtual ~PSISection(); 1988dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 1998dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberprivate: 2008dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber sp<ABuffer> mBuffer; 2019ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim uint8_t mSkipBytes; 2029ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim static uint32_t CRC_TABLE[]; 2038dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 2048dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(PSISection); 2058dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber}; 2068dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 207540006666b4191cd78391378f1c66c21bcf0c4cdWonsik KimATSParser::SyncEvent::SyncEvent(off64_t offset) 208540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim : mInit(false), mOffset(offset), mTimeUs(0) {} 209540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 210540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimvoid ATSParser::SyncEvent::init(off64_t offset, const sp<MediaSource> &source, 211540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t timeUs) { 212540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mInit = true; 213540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mOffset = offset; 214540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mMediaSource = source; 215540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mTimeUs = timeUs; 216540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim} 217540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 218cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 219cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 220386d609dc513e838c7e7c4c46c604493ccd560beAndreas HuberATSParser::Program::Program( 221d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang ATSParser *parser, unsigned programNumber, unsigned programMapPID, 222d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang int64_t lastRecoveredPTS) 223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber : mParser(parser), 224386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mProgramNumber(programNumber), 225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mProgramMapPID(programMapPID), 226bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber mFirstPTSValid(false), 227799c9682b3776a55d234396aee4a302437150c26Chong Zhang mFirstPTS(0), 228d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mLastRecoveredPTS(lastRecoveredPTS) { 2293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("new program number %u", programNumber); 230cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 231cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2328dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::Program::parsePSISection( 2338dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber unsigned pid, ABitReader *br, status_t *err) { 23406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber *err = OK; 23506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 2368dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (pid != mProgramMapPID) { 2378dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return false; 2388dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 239cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2408dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber *err = parseProgramMap(br); 24106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 2428dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return true; 2438dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 2448dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 2458dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::Program::parsePID( 24687f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned pid, unsigned continuity_counter, 24787f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned payload_unit_start_indicator, 248540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim ABitReader *br, status_t *err, SyncEvent *event) { 2498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber *err = OK; 250cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 251cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ssize_t index = mStreams.indexOfKey(pid); 252cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (index < 0) { 253cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return false; 254cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 255cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 2565403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber *err = mStreams.editValueAt(index)->parse( 257540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim continuity_counter, payload_unit_start_indicator, br, event); 258cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 259cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return true; 260cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 261cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 26232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::Program::signalDiscontinuity( 26332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber DiscontinuityType type, const sp<AMessage> &extra) { 264b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber int64_t mediaTimeUs; 265b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber if ((type & DISCONTINUITY_TIME) 266b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber && extra != NULL 267b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber && extra->findInt64( 268b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) { 269b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber mFirstPTSValid = false; 270b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber } 271b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber 2722a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber for (size_t i = 0; i < mStreams.size(); ++i) { 27332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mStreams.editValueAt(i)->signalDiscontinuity(type, extra); 274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 277f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::Program::signalEOS(status_t finalResult) { 278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < mStreams.size(); ++i) { 279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mStreams.editValueAt(i)->signalEOS(finalResult); 2802a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber } 2812a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber} 2822a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber 2839bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhangbool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) { 2849bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang bool success = false; 2859bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 2869bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang if (mStreams.size() == infos.size()) { 2879bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // build type->PIDs map for old and new mapping 2889bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang size_t i; 2899bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs; 2909bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang for (i = 0; i < mStreams.size(); ++i) { 2919bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type()); 2929bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang if (index < 0) { 2939bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>()); 2949bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 2959bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid()); 2969bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 2979bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang for (i = 0; i < infos.size(); ++i) { 2989bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang ssize_t index = newType2PIDs.indexOfKey(infos[i].mType); 2999bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang if (index < 0) { 3009bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang newType2PIDs.add(infos[i].mType, Vector<int32_t>()); 3019bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3029bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID); 3039bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3049bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 3059bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // we can recover if the number of streams for each type hasn't changed 3069bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang if (oldType2PIDs.size() == newType2PIDs.size()) { 3079bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang success = true; 3089bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang for (i = 0; i < oldType2PIDs.size(); ++i) { 3099bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // KeyedVector is sorted, we just compare key and size of each index 3109bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i) 3119bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang || oldType2PIDs[i].size() != newType2PIDs[i].size()) { 3129bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang success = false; 3139bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang break; 3149bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3159bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3169bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3179bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 3189bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang if (success) { 3199bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // save current streams to temp 3209bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang KeyedVector<int32_t, sp<Stream> > temp; 3219bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang for (i = 0; i < mStreams.size(); ++i) { 3229bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang temp.add(mStreams.keyAt(i), mStreams.editValueAt(i)); 3239bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3249bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 3259bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang mStreams.clear(); 3269bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang for (i = 0; i < temp.size(); ++i) { 3279bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // The two checks below shouldn't happen, 3289bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // we already checked above the stream count matches 3299bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang ssize_t index = newType2PIDs.indexOfKey(temp[i]->type()); 330e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (index < 0) { 331e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return false; 332e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 3339bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index); 334e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (newPIDs.isEmpty()) { 335e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return false; 336e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 3379bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 3389bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // get the next PID for temp[i]->type() in the new PID map 3399bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang Vector<int32_t>::iterator it = newPIDs.begin(); 3409bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 3419bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // change the PID of the stream, and add it back 3429bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang temp.editValueAt(i)->setPID(*it); 3439bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang mStreams.add(temp[i]->pid(), temp.editValueAt(i)); 3449bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 3459bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // removed the used PID 3469bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang newPIDs.erase(it); 3479bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3489bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3499bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 3509bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang return success; 3519bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang} 352bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 35306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huberstatus_t ATSParser::Program::parseProgramMap(ABitReader *br) { 354cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned table_id = br->getBits(8); 3553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" table_id = %u", table_id); 3566456ae745e919085c5024f784aaa2703f9695f98David Yeh if (table_id != 0x02u) { 3576456ae745e919085c5024f784aaa2703f9695f98David Yeh ALOGE("PMT data error!"); 3586456ae745e919085c5024f784aaa2703f9695f98David Yeh return ERROR_MALFORMED; 3596456ae745e919085c5024f784aaa2703f9695f98David Yeh } 3606e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber unsigned section_syntax_indicator = br->getBits(1); 3613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" section_syntax_indicator = %u", section_syntax_indicator); 3626456ae745e919085c5024f784aaa2703f9695f98David Yeh if (section_syntax_indicator != 1u) { 3636456ae745e919085c5024f784aaa2703f9695f98David Yeh ALOGE("PMT data error!"); 3646456ae745e919085c5024f784aaa2703f9695f98David Yeh return ERROR_MALFORMED; 3656456ae745e919085c5024f784aaa2703f9695f98David Yeh } 366cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 367e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim br->skipBits(1); // '0' 3686e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(2)); 369cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 370cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned section_length = br->getBits(12); 3713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" section_length = %u", section_length); 372cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 3736e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" program_number = %u", br->getBits(16)); 3746e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(2)); 3756e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" version_number = %u", br->getBits(5)); 3766e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" current_next_indicator = %u", br->getBits(1)); 3776e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" section_number = %u", br->getBits(8)); 3786e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" last_section_number = %u", br->getBits(8)); 3796e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(3)); 38087f2a558dd12043631e12c361abef301bf603140Andreas Huber 38187f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned PCR_PID = br->getBits(13); 38287f2a558dd12043631e12c361abef301bf603140Andreas Huber ALOGV(" PCR_PID = 0x%04x", PCR_PID); 38387f2a558dd12043631e12c361abef301bf603140Andreas Huber 3846e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(4)); 385cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 386cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned program_info_length = br->getBits(12); 3873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" program_info_length = %u", program_info_length); 388cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 389cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->skipBits(program_info_length * 8); // skip descriptors 390cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 391bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber Vector<StreamInfo> infos; 392bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 393cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // infoBytesRemaining is the number of bytes that make up the 394cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // variable length section of ES_infos. It does not include the 395cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // final CRC. 396cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber size_t infoBytesRemaining = section_length - 9 - program_info_length - 4; 397cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 398e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim while (infoBytesRemaining >= 5) { 399cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 400cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned streamType = br->getBits(8); 4013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" stream_type = 0x%02x", streamType); 402cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 4036e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(3)); 404cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 405cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned elementaryPID = br->getBits(13); 4063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" elementary_PID = 0x%04x", elementaryPID); 407cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 4086e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(4)); 409cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 410cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned ES_info_length = br->getBits(12); 4113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" ES_info_length = %u", ES_info_length); 412cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 413cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#if 0 414cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->skipBits(ES_info_length * 8); // skip descriptors 415cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#else 416cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned info_bytes_remaining = ES_info_length; 417cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber while (info_bytes_remaining >= 2) { 4186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" tag = 0x%02x", br->getBits(8)); 419cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 420cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned descLength = br->getBits(8); 4213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" len = %u", descLength); 422cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 423e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (info_bytes_remaining < descLength) { 424e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 425e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 426cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->skipBits(descLength * 8); 427cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 428cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber info_bytes_remaining -= descLength + 2; 429cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 430cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#endif 431cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 432bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber StreamInfo info; 433bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber info.mType = streamType; 434bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber info.mPID = elementaryPID; 435bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber infos.push(info); 436cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 437cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber infoBytesRemaining -= 5 + ES_info_length; 438cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 439cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 440e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (infoBytesRemaining != 0) { 441e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim ALOGW("Section data remains unconsumed"); 442e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 4436e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" CRC = 0x%08x", br->getBits(32)); 444bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 445bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber bool PIDsChanged = false; 446bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber for (size_t i = 0; i < infos.size(); ++i) { 447bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber StreamInfo &info = infos.editItemAt(i); 448bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 449bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber ssize_t index = mStreams.indexOfKey(info.mPID); 450bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 451bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) { 452df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("uh oh. stream PIDs have changed."); 453bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber PIDsChanged = true; 454bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber break; 455bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 456bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 457bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 458bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber if (PIDsChanged) { 45906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber#if 0 460df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("before:"); 46106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber for (size_t i = 0; i < mStreams.size(); ++i) { 46206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber sp<Stream> stream = mStreams.editValueAt(i); 46306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 464df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type()); 46506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber } 46606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 467df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("after:"); 46806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber for (size_t i = 0; i < infos.size(); ++i) { 46906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber StreamInfo &info = infos.editItemAt(i); 47006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 471df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType); 47206528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber } 47306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber#endif 47406528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 4759bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // we can recover if number of streams for each type remain the same 4769bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang bool success = switchPIDs(infos); 47706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 47806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber if (!success) { 479df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Stream PIDs changed and we cannot recover."); 48006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber return ERROR_MALFORMED; 48106528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber } 482bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 483bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 484bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber for (size_t i = 0; i < infos.size(); ++i) { 485bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber StreamInfo &info = infos.editItemAt(i); 486bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 487bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber ssize_t index = mStreams.indexOfKey(info.mPID); 488bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber 489bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber if (index < 0) { 49087f2a558dd12043631e12c361abef301bf603140Andreas Huber sp<Stream> stream = new Stream( 49187f2a558dd12043631e12c361abef301bf603140Andreas Huber this, info.mPID, info.mType, PCR_PID); 49287f2a558dd12043631e12c361abef301bf603140Andreas Huber 493bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber mStreams.add(info.mPID, stream); 494bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 495bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber } 49606528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 49706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber return OK; 498cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 499cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 500799c9682b3776a55d234396aee4a302437150c26Chong Zhangint64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) { 501799c9682b3776a55d234396aee4a302437150c26Chong Zhang // We only have the lower 33-bit of the PTS. It could overflow within a 502799c9682b3776a55d234396aee4a302437150c26Chong Zhang // reasonable amount of time. To handle the wrap-around, use fancy math 503799c9682b3776a55d234396aee4a302437150c26Chong Zhang // to get an extended PTS that is within [-0xffffffff, 0xffffffff] 504799c9682b3776a55d234396aee4a302437150c26Chong Zhang // of the latest recovered PTS. 5059bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang if (mLastRecoveredPTS < 0ll) { 5069bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // Use the original 33bit number for 1st frame, the reason is that 5079bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // if 1st frame wraps to negative that's far away from 0, we could 5089bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // never start. Only start wrapping around from 2nd frame. 5099bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit); 5109bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } else { 5119bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang mLastRecoveredPTS = static_cast<int64_t>( 5123728ba367f1e23e652c5539d9488aa0d0d4ec9d7Chad Brubaker ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000ll) 5139bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang & 0xfffffffe00000000ull) | PTS_33bit); 5149bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // We start from 0, but recovered PTS could be slightly below 0. 5159bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // Clamp it to 0 as rest of the pipeline doesn't take negative pts. 5169bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0) 5179bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang if (mLastRecoveredPTS < 0ll) { 5185c9054bc6efc080b265e028f2ebb1abd2a2e3953Chih-Hung Hsieh ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS); 5199bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang mLastRecoveredPTS = 0ll; 5209bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 5219bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang } 5229bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang 5239bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang return mLastRecoveredPTS; 524799c9682b3776a55d234396aee4a302437150c26Chong Zhang} 525799c9682b3776a55d234396aee4a302437150c26Chong Zhang 526cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> ATSParser::Program::getSource(SourceType type) { 527386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber size_t index = (type == AUDIO) ? 0 : 0; 528decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber 529cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber for (size_t i = 0; i < mStreams.size(); ++i) { 530cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber sp<MediaSource> source = mStreams.editValueAt(i)->getSource(type); 531cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (source != NULL) { 532decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber if (index == 0) { 533decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber return source; 534decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber } 535decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber --index; 536cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 537cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 538cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 539cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return NULL; 540cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 541cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 542bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shihbool ATSParser::Program::hasSource(SourceType type) const { 543bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih for (size_t i = 0; i < mStreams.size(); ++i) { 544bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih const sp<Stream> &stream = mStreams.valueAt(i); 545bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih if (type == AUDIO && stream->isAudio()) { 546bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih return true; 547bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih } else if (type == VIDEO && stream->isVideo()) { 548bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih return true; 549bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih } 550bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih } 551bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih 552bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih return false; 553bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih} 554bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih 555bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huberint64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) { 556799c9682b3776a55d234396aee4a302437150c26Chong Zhang PTS = recoverPTS(PTS); 557799c9682b3776a55d234396aee4a302437150c26Chong Zhang 558c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) { 559c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber if (!mFirstPTSValid) { 560c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber mFirstPTSValid = true; 561c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber mFirstPTS = PTS; 562c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber PTS = 0; 563c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber } else if (PTS < mFirstPTS) { 564c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber PTS = 0; 565c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber } else { 566c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber PTS -= mFirstPTS; 567c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas Huber } 568bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber } 569bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 57087f2a558dd12043631e12c361abef301bf603140Andreas Huber int64_t timeUs = (PTS * 100) / 9; 57187f2a558dd12043631e12c361abef301bf603140Andreas Huber 57287f2a558dd12043631e12c361abef301bf603140Andreas Huber if (mParser->mAbsoluteTimeAnchorUs >= 0ll) { 57387f2a558dd12043631e12c361abef301bf603140Andreas Huber timeUs += mParser->mAbsoluteTimeAnchorUs; 57487f2a558dd12043631e12c361abef301bf603140Andreas Huber } 57587f2a558dd12043631e12c361abef301bf603140Andreas Huber 576d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber if (mParser->mTimeOffsetValid) { 577d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber timeUs += mParser->mTimeOffsetUs; 578d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } 579d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber 58087f2a558dd12043631e12c361abef301bf603140Andreas Huber return timeUs; 581bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber} 582bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 583cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 584cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 585bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas HuberATSParser::Stream::Stream( 58687f2a558dd12043631e12c361abef301bf603140Andreas Huber Program *program, 58787f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned elementaryPID, 58887f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned streamType, 58987f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned PCR_PID) 590bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber : mProgram(program), 591bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber mElementaryPID(elementaryPID), 592cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mStreamType(streamType), 59387f2a558dd12043631e12c361abef301bf603140Andreas Huber mPCR_PID(PCR_PID), 59487f2a558dd12043631e12c361abef301bf603140Andreas Huber mExpectedContinuityCounter(-1), 5956a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber mPayloadStarted(false), 596be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen mEOSReached(false), 59790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mPrevPTS(0), 598386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mQueue(NULL) { 599386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber switch (mStreamType) { 600386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber case STREAMTYPE_H264: 60187f2a558dd12043631e12c361abef301bf603140Andreas Huber mQueue = new ElementaryStreamQueue( 60287f2a558dd12043631e12c361abef301bf603140Andreas Huber ElementaryStreamQueue::H264, 60387f2a558dd12043631e12c361abef301bf603140Andreas Huber (mProgram->parserFlags() & ALIGNED_VIDEO_DATA) 60487f2a558dd12043631e12c361abef301bf603140Andreas Huber ? ElementaryStreamQueue::kFlag_AlignedData : 0); 605386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 6066e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber case STREAMTYPE_MPEG2_AUDIO_ADTS: 607386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mQueue = new ElementaryStreamQueue(ElementaryStreamQueue::AAC); 608386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 609386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber case STREAMTYPE_MPEG1_AUDIO: 610386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber case STREAMTYPE_MPEG2_AUDIO: 611386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mQueue = new ElementaryStreamQueue( 612386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ElementaryStreamQueue::MPEG_AUDIO); 613386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 614386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 615386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber case STREAMTYPE_MPEG1_VIDEO: 616386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber case STREAMTYPE_MPEG2_VIDEO: 617386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mQueue = new ElementaryStreamQueue( 618386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ElementaryStreamQueue::MPEG_VIDEO); 619386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 620386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 621386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber case STREAMTYPE_MPEG4_VIDEO: 622386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mQueue = new ElementaryStreamQueue( 623386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber ElementaryStreamQueue::MPEG4_VIDEO); 624386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 625386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 6269bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang case STREAMTYPE_LPCM_AC3: 627d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu case STREAMTYPE_AC3: 628d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu mQueue = new ElementaryStreamQueue( 629d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu ElementaryStreamQueue::AC3); 630d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu break; 631d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu 6320852843d304006e3ab333081fddda13b07193de8Robert Shih case STREAMTYPE_METADATA: 6330852843d304006e3ab333081fddda13b07193de8Robert Shih mQueue = new ElementaryStreamQueue( 6340852843d304006e3ab333081fddda13b07193de8Robert Shih ElementaryStreamQueue::METADATA); 6350852843d304006e3ab333081fddda13b07193de8Robert Shih break; 6360852843d304006e3ab333081fddda13b07193de8Robert Shih 637386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber default: 638386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 639386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 640386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 6413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("new stream PID 0x%02x, type 0x%02x", elementaryPID, streamType); 64218ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber 64318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber if (mQueue != NULL) { 64418ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber mBuffer = new ABuffer(192 * 1024); 64518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber mBuffer->setRange(0, 0); 64618ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber } 647cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 648cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 649cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberATSParser::Stream::~Stream() { 650386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber delete mQueue; 651386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mQueue = NULL; 652cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 653cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 6545403129e2a2f44620f2ac8109889e5a61be08732Andreas Huberstatus_t ATSParser::Stream::parse( 65587f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned continuity_counter, 656540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim unsigned payload_unit_start_indicator, ABitReader *br, 657540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim SyncEvent *event) { 65818ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber if (mQueue == NULL) { 6595403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber return OK; 66018ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber } 66118ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber 66287f2a558dd12043631e12c361abef301bf603140Andreas Huber if (mExpectedContinuityCounter >= 0 66387f2a558dd12043631e12c361abef301bf603140Andreas Huber && (unsigned)mExpectedContinuityCounter != continuity_counter) { 66487f2a558dd12043631e12c361abef301bf603140Andreas Huber ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID); 66587f2a558dd12043631e12c361abef301bf603140Andreas Huber 66687f2a558dd12043631e12c361abef301bf603140Andreas Huber mPayloadStarted = false; 66787f2a558dd12043631e12c361abef301bf603140Andreas Huber mBuffer->setRange(0, 0); 66887f2a558dd12043631e12c361abef301bf603140Andreas Huber mExpectedContinuityCounter = -1; 66987f2a558dd12043631e12c361abef301bf603140Andreas Huber 67094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#if 0 67194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber // Uncomment this if you'd rather see no corruption whatsoever on 67294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber // screen and suspend updates until we come across another IDR frame. 67394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber 67494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber if (mStreamType == STREAMTYPE_H264) { 67594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber ALOGI("clearing video queue"); 67694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber mQueue->clear(true /* clearFormat */); 67794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber } 67894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber#endif 67994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber 68066830855846db5c211c2da6c055ca9b4167e8974Chong Zhang if (!payload_unit_start_indicator) { 68166830855846db5c211c2da6c055ca9b4167e8974Chong Zhang return OK; 68266830855846db5c211c2da6c055ca9b4167e8974Chong Zhang } 68387f2a558dd12043631e12c361abef301bf603140Andreas Huber } 68487f2a558dd12043631e12c361abef301bf603140Andreas Huber 68587f2a558dd12043631e12c361abef301bf603140Andreas Huber mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f; 68687f2a558dd12043631e12c361abef301bf603140Andreas Huber 687cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (payload_unit_start_indicator) { 688540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim off64_t offset = (event != NULL) ? event->getOffset() : 0; 689cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (mPayloadStarted) { 690cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // Otherwise we run the danger of receiving the trailing bytes 691cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // of a PES packet that we never saw the start of and assuming 692cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // we have a a complete PES packet. 693cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 694540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = flush(event); 6955403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber 6965403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber if (err != OK) { 69765959d34fdab8319dbf765be5fbf7ff8051eedf1Wonsik Kim ALOGW("Error (%08x) happened while flushing; we simply discard " 69865959d34fdab8319dbf765be5fbf7ff8051eedf1Wonsik Kim "the PES packet and continue.", err); 6995403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber } 700cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 701cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 702cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mPayloadStarted = true; 703540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim mPesStartOffset = offset; 704cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 705cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 706cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (!mPayloadStarted) { 7075403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber return OK; 708cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 709cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 710cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber size_t payloadSizeBits = br->numBitsLeft(); 711e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (payloadSizeBits % 8 != 0u) { 712e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim ALOGE("Wrong value"); 713e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return BAD_VALUE; 714e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 715cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 7163e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber size_t neededSize = mBuffer->size() + payloadSizeBits / 8; 7173e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber if (mBuffer->capacity() < neededSize) { 7183e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber // Increment in multiples of 64K. 7193e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber neededSize = (neededSize + 65535) & ~65535; 7203e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber 721b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGI("resizing buffer to %zu bytes", neededSize); 7223e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber 7233e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber sp<ABuffer> newBuffer = new ABuffer(neededSize); 7243e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 7253e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber newBuffer->setRange(0, mBuffer->size()); 7263e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber mBuffer = newBuffer; 7273e57322b332214e3cb1874e67a5704c9b2b5f6ecAndreas Huber } 728cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 729cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8); 730cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8); 7315403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber 7325403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber return OK; 733cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 734cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 7356e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huberbool ATSParser::Stream::isVideo() const { 7366e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber switch (mStreamType) { 7376e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber case STREAMTYPE_H264: 7386e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber case STREAMTYPE_MPEG1_VIDEO: 7396e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber case STREAMTYPE_MPEG2_VIDEO: 7406e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber case STREAMTYPE_MPEG4_VIDEO: 7416e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber return true; 7426e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7436e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber default: 7446e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber return false; 7456e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 7466e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber} 7476e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7486e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huberbool ATSParser::Stream::isAudio() const { 7496e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber switch (mStreamType) { 7506e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber case STREAMTYPE_MPEG1_AUDIO: 7516e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber case STREAMTYPE_MPEG2_AUDIO: 7526e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber case STREAMTYPE_MPEG2_AUDIO_ADTS: 7539bf32f06e8971c1d3eb4fc5edd74b69557f97212Chong Zhang case STREAMTYPE_LPCM_AC3: 754d3c079ae9859011d118f94616d0069c2987013edChangwan Ryu case STREAMTYPE_AC3: 7556e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber return true; 7566e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7576e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber default: 7586e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber return false; 7596e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 7606e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber} 7616e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber 7620852843d304006e3ab333081fddda13b07193de8Robert Shihbool ATSParser::Stream::isMeta() const { 7630852843d304006e3ab333081fddda13b07193de8Robert Shih if (mStreamType == STREAMTYPE_METADATA) { 7640852843d304006e3ab333081fddda13b07193de8Robert Shih return true; 7650852843d304006e3ab333081fddda13b07193de8Robert Shih } 7660852843d304006e3ab333081fddda13b07193de8Robert Shih return false; 7670852843d304006e3ab333081fddda13b07193de8Robert Shih} 7680852843d304006e3ab333081fddda13b07193de8Robert Shih 76932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::Stream::signalDiscontinuity( 77032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber DiscontinuityType type, const sp<AMessage> &extra) { 7710389cc09f7b90f155a8942a0d2e1925cad1dbe2dMarco Nelissen mExpectedContinuityCounter = -1; 7720389cc09f7b90f155a8942a0d2e1925cad1dbe2dMarco Nelissen 77318ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber if (mQueue == NULL) { 77418ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber return; 77518ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber } 77618ac5407da14dad9731f40ffc9a56bee73830019Andreas Huber 7772a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber mPayloadStarted = false; 778aabbdc7401ae24a4199f12a283985deb648673c0Robert Shih mEOSReached = false; 7792a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber mBuffer->setRange(0, 0); 7802a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber 7816e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber bool clearFormat = false; 7826e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (isAudio()) { 7836e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (type & DISCONTINUITY_AUDIO_FORMAT) { 7846e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber clearFormat = true; 7856e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 7866e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } else { 7876e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (type & DISCONTINUITY_VIDEO_FORMAT) { 7886e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber clearFormat = true; 7896e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 7906e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 7926e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mQueue->clear(clearFormat); 79332f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 7946e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (type & DISCONTINUITY_TIME) { 7956e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber uint64_t resumeAtPTS; 7966e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (extra != NULL 7976e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber && extra->findInt64( 7986e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber IStreamListener::kKeyResumeAtPTS, 7996e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber (int64_t *)&resumeAtPTS)) { 8006e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber int64_t resumeAtMediaTimeUs = 8016e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber mProgram->convertPTSToTimestamp(resumeAtPTS); 80232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 803c6cfd70f24a11b946859485ce398a189c301a4e2Wei Jia extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs); 804e332a9181cf6a3155ed1a0fd2afc212ccb1f2753Andreas Huber } 8056e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 8076e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (mSource != NULL) { 808632740c58119a132ce19f6d498e39c5c3773971aChong Zhang mSource->queueDiscontinuity(type, extra, true); 809bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber } 810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 811bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber 812f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::Stream::signalEOS(status_t finalResult) { 813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (mSource != NULL) { 814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mSource->signalEOS(finalResult); 8152a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber } 816be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen mEOSReached = true; 817540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim flush(NULL); 8182a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber} 8192a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber 820540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::Stream::parsePES(ABitReader *br, SyncEvent *event) { 821cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned packet_startcode_prefix = br->getBits(24); 822cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 8233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix); 824cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 825386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (packet_startcode_prefix != 1) { 8263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Supposedly payload_unit_start=1 unit does not start " 827386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber "with startcode."); 8285403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber 8295403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber return ERROR_MALFORMED; 830386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 831386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 832cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned stream_id = br->getBits(8); 8333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stream_id = 0x%02x", stream_id); 834cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 835cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned PES_packet_length = br->getBits(16); 8363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PES_packet_length = %u", PES_packet_length); 837cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 838cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (stream_id != 0xbc // program_stream_map 839cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber && stream_id != 0xbe // padding_stream 840cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber && stream_id != 0xbf // private_stream_2 841cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber && stream_id != 0xf0 // ECM 842cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber && stream_id != 0xf1 // EMM 843cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber && stream_id != 0xff // program_stream_directory 844cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber && stream_id != 0xf2 // DSMCC 845cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber && stream_id != 0xf8) { // H.222.1 type E 846e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(2) != 2u) { 847e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 848e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 849cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 8506e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("PES_scrambling_control = %u", br->getBits(2)); 8516e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("PES_priority = %u", br->getBits(1)); 8526e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("data_alignment_indicator = %u", br->getBits(1)); 8536e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("copyright = %u", br->getBits(1)); 8546e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("original_or_copy = %u", br->getBits(1)); 855cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 856cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned PTS_DTS_flags = br->getBits(2); 8573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags); 858cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 859cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned ESCR_flag = br->getBits(1); 8603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("ESCR_flag = %u", ESCR_flag); 861cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 862cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned ES_rate_flag = br->getBits(1); 8633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("ES_rate_flag = %u", ES_rate_flag); 864cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 865cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned DSM_trick_mode_flag = br->getBits(1); 8663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag); 867cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 868cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned additional_copy_info_flag = br->getBits(1); 8693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag); 870cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 8716e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("PES_CRC_flag = %u", br->getBits(1)); 8726e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("PES_extension_flag = %u", br->getBits(1)); 873cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 874cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned PES_header_data_length = br->getBits(8); 8753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PES_header_data_length = %u", PES_header_data_length); 876cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 877cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned optional_bytes_remaining = PES_header_data_length; 878cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 879cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber uint64_t PTS = 0, DTS = 0; 880cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 881cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) { 882e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (optional_bytes_remaining < 5u) { 883e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 884e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 885cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 8866456ae745e919085c5024f784aaa2703f9695f98David Yeh if (br->getBits(4) != PTS_DTS_flags) { 8876456ae745e919085c5024f784aaa2703f9695f98David Yeh return ERROR_MALFORMED; 8886456ae745e919085c5024f784aaa2703f9695f98David Yeh } 889cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber PTS = ((uint64_t)br->getBits(3)) << 30; 890e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 891e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 892e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 893cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber PTS |= ((uint64_t)br->getBits(15)) << 15; 894e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 895e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 896e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 897cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber PTS |= br->getBits(15); 898e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 899e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 900e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 901cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 902b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0); 903cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 904cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber optional_bytes_remaining -= 5; 905cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 906cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (PTS_DTS_flags == 3) { 907e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (optional_bytes_remaining < 5u) { 908e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 909e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 910cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 911e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(4) != 1u) { 912e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 913e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 914cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 915cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber DTS = ((uint64_t)br->getBits(3)) << 30; 916e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 917e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 918e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 919cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber DTS |= ((uint64_t)br->getBits(15)) << 15; 920e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 921e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 922e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 923cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber DTS |= br->getBits(15); 924e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 925e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 926e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 927cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 928b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("DTS = %" PRIu64, DTS); 929cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 930cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber optional_bytes_remaining -= 5; 931cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 932cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 933cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 934cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (ESCR_flag) { 935e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (optional_bytes_remaining < 6u) { 936e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 937e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 938cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 939cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->getBits(2); 940cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 941cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30; 942e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 943e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 944e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 945cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ESCR |= ((uint64_t)br->getBits(15)) << 15; 946e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 947e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 948e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 949cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ESCR |= br->getBits(15); 950e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 951e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 952e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 953cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 954b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("ESCR = %" PRIu64, ESCR); 9556e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("ESCR_extension = %u", br->getBits(9)); 956cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 957e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 958e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 959e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 960cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 961cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber optional_bytes_remaining -= 6; 962cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 963cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 964cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (ES_rate_flag) { 965e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (optional_bytes_remaining < 3u) { 966e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 967e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 968cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 969e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 970e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 971e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 9726e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("ES_rate = %u", br->getBits(22)); 973e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->getBits(1) != 1u) { 974e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 975e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 976cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 977cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber optional_bytes_remaining -= 3; 978cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 979cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 980cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->skipBits(optional_bytes_remaining * 8); 981cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 982cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // ES data follows. 983cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 984cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (PES_packet_length != 0) { 985e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (PES_packet_length < PES_header_data_length + 3) { 986e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 987e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 988cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 989cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned dataLength = 990cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber PES_packet_length - 3 - PES_header_data_length; 991cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 9925403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber if (br->numBitsLeft() < dataLength * 8) { 99329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("PES packet does not carry enough data to contain " 994b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross "payload. (numBitsLeft = %zu, required = %u)", 9955403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber br->numBitsLeft(), dataLength * 8); 9965403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber 9975403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber return ERROR_MALFORMED; 9985403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber } 9995403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber 10000da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber onPayloadData( 1001540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim PTS_DTS_flags, PTS, DTS, br->data(), dataLength, event); 1002cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1003cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->skipBits(dataLength * 8); 1004cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } else { 10050da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber onPayloadData( 10060da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber PTS_DTS_flags, PTS, DTS, 1007540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim br->data(), br->numBitsLeft() / 8, event); 10080da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1009cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber size_t payloadSizeBits = br->numBitsLeft(); 1010e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (payloadSizeBits % 8 != 0u) { 1011e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 1012e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 1013cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1014b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("There's %zu bytes of payload.", payloadSizeBits / 8); 1015cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1016cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } else if (stream_id == 0xbe) { // padding_stream 1017e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (PES_packet_length == 0u) { 1018e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 1019e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 1020cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->skipBits(PES_packet_length * 8); 1021cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } else { 1022e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (PES_packet_length == 0u) { 1023e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 1024e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 1025cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->skipBits(PES_packet_length * 8); 1026cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 10275403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber 10285403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber return OK; 1029cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1030cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1031540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::Stream::flush(SyncEvent *event) { 1032f2cecd570c35d3b6422396dd51c0b4202732bceaJaesung Chung if (mBuffer == NULL || mBuffer->size() == 0) { 10335403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber return OK; 1034cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1035cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1036b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size()); 1037cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1038cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ABitReader br(mBuffer->data(), mBuffer->size()); 10395403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber 1040540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim status_t err = parsePES(&br, event); 1041cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1042cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mBuffer->setRange(0, 0); 10435403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber 10445403129e2a2f44620f2ac8109889e5a61be08732Andreas Huber return err; 1045cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1046cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1047cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid ATSParser::Stream::onPayloadData( 104884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */, 1049540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim const uint8_t *data, size_t size, SyncEvent *event) { 105090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if 0 105190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld", 105290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mStreamType, 105390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber PTS, 105490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber (int64_t)PTS - mPrevPTS); 105590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mPrevPTS = PTS; 105690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif 105790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 10583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("onPayloadData mStreamType=0x%02x", mStreamType); 1059cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 106098a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber int64_t timeUs = 0ll; // no presentation timestamp available. 106198a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) { 106298a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber timeUs = mProgram->convertPTSToTimestamp(PTS); 106398a46cf165d8de3779874eba01803bbc485f45b9Andreas Huber } 106482f7321b03eec1e40af9d681370f754ee0279582Andreas Huber 1065386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber status_t err = mQueue->appendData(data, size, timeUs); 1066decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber 1067be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen if (mEOSReached) { 1068be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen mQueue->signalEOS(); 1069be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen } 1070be9634d071e79b72a42a4504f64eda9e2a0bceb8Marco Nelissen 1071decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber if (err != OK) { 1072decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber return; 1073decd96988e495133e4a1728f612d4c9fdb4d218eAndreas Huber } 107482f7321b03eec1e40af9d681370f754ee0279582Andreas Huber 10756a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber sp<ABuffer> accessUnit; 1076540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim bool found = false; 1077386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) { 10786a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber if (mSource == NULL) { 1079386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber sp<MetaData> meta = mQueue->getFormat(); 108082f7321b03eec1e40af9d681370f754ee0279582Andreas Huber 10816a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber if (meta != NULL) { 10823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Stream PID 0x%08x of type 0x%02x now has data.", 1083386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mElementaryPID, mStreamType); 1084386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 1085309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih const char *mime; 1086309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih if (meta->findCString(kKeyMIMEType, &mime) 1087309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) 1088309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih && !IsIDR(accessUnit)) { 1089309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih continue; 1090309aa8bf5e4cd66fe988adf2654cac3fadc2a1c3Robert Shih } 10916a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber mSource = new AnotherPacketSource(meta); 10926a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber mSource->queueAccessUnit(accessUnit); 109382f7321b03eec1e40af9d681370f754ee0279582Andreas Huber } 1094386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } else if (mQueue->getFormat() != NULL) { 10952a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber // After a discontinuity we invalidate the queue's format 10962a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber // and won't enqueue any access units to the source until 10972a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber // the queue has reestablished the new format. 10985bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 10995bc087c573c70c84c6a39946457590b42d392a33Andreas Huber if (mSource->getFormat() == NULL) { 1100386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mSource->setFormat(mQueue->getFormat()); 11015bc087c573c70c84c6a39946457590b42d392a33Andreas Huber } 11026a63a939601645404fd98f58c19cc38ca818d99eAndreas Huber mSource->queueAccessUnit(accessUnit); 110382f7321b03eec1e40af9d681370f754ee0279582Andreas Huber } 1104540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim 1105540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if ((event != NULL) && !found && mQueue->getFormat() != NULL) { 1106540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int32_t sync = 0; 1107540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (accessUnit->meta()->findInt32("isSync", &sync) && sync) { 1108540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim int64_t timeUs; 1109540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim if (accessUnit->meta()->findInt64("timeUs", &timeUs)) { 1110540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim found = true; 1111540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim event->init(mPesStartOffset, mSource, timeUs); 1112540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 1113540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 1114540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim } 111582f7321b03eec1e40af9d681370f754ee0279582Andreas Huber } 111682f7321b03eec1e40af9d681370f754ee0279582Andreas Huber} 111782f7321b03eec1e40af9d681370f754ee0279582Andreas Huber 1118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> ATSParser::Stream::getSource(SourceType type) { 1119386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber switch (type) { 1120386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber case VIDEO: 1121386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber { 11226e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (isVideo()) { 1123386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return mSource; 1124386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 1125386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 1126386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 1127386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 1128386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber case AUDIO: 1129386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber { 11306e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber if (isAudio()) { 1131386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber return mSource; 1132386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 1133386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 1134386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 1135386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 11360852843d304006e3ab333081fddda13b07193de8Robert Shih case META: 11370852843d304006e3ab333081fddda13b07193de8Robert Shih { 11380852843d304006e3ab333081fddda13b07193de8Robert Shih if (isMeta()) { 11390852843d304006e3ab333081fddda13b07193de8Robert Shih return mSource; 11400852843d304006e3ab333081fddda13b07193de8Robert Shih } 11410852843d304006e3ab333081fddda13b07193de8Robert Shih break; 11420852843d304006e3ab333081fddda13b07193de8Robert Shih } 11430852843d304006e3ab333081fddda13b07193de8Robert Shih 1144386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber default: 1145386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 1146cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1147cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1148cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return NULL; 1149cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1150cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1151cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber//////////////////////////////////////////////////////////////////////////////// 1152cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1153c4c17d47b674b425fb6c399822c0ab3258543c0aAndreas HuberATSParser::ATSParser(uint32_t flags) 115487f2a558dd12043631e12c361abef301bf603140Andreas Huber : mFlags(flags), 115587f2a558dd12043631e12c361abef301bf603140Andreas Huber mAbsoluteTimeAnchorUs(-1ll), 1156d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber mTimeOffsetValid(false), 1157d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber mTimeOffsetUs(0ll), 1158d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mLastRecoveredPTS(-1ll), 115987f2a558dd12043631e12c361abef301bf603140Andreas Huber mNumTSPacketsParsed(0), 116087f2a558dd12043631e12c361abef301bf603140Andreas Huber mNumPCRs(0) { 11618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber mPSISections.add(0 /* PID */, new PSISection); 1162cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1163cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1164cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberATSParser::~ATSParser() { 1165cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1166cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1167540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::feedTSPacket(const void *data, size_t size, 1168540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim SyncEvent *event) { 1169e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (size != kTSPacketSize) { 1170e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim ALOGE("Wrong TS packet size"); 1171e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return BAD_VALUE; 1172e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 1173cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1174cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ABitReader br((const uint8_t *)data, kTSPacketSize); 1175540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim return parseTS(&br, event); 1176cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1177cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 117832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Hubervoid ATSParser::signalDiscontinuity( 117932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber DiscontinuityType type, const sp<AMessage> &extra) { 1180b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber int64_t mediaTimeUs; 1181d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if ((type & DISCONTINUITY_TIME) && extra != NULL) { 1182d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if (extra->findInt64(IStreamListener::kKeyMediaTimeUs, &mediaTimeUs)) { 1183d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mAbsoluteTimeAnchorUs = mediaTimeUs; 1184d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 1185d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE) 1186d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang && extra->findInt64( 1187d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang IStreamListener::kKeyRecentMediaTimeUs, &mediaTimeUs)) { 1188d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if (mAbsoluteTimeAnchorUs >= 0ll) { 1189d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mediaTimeUs -= mAbsoluteTimeAnchorUs; 1190d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 1191d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang if (mTimeOffsetValid) { 1192d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mediaTimeUs -= mTimeOffsetUs; 1193d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 1194d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang mLastRecoveredPTS = (mediaTimeUs * 9) / 100; 1195d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang } 1196b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber } else if (type == DISCONTINUITY_ABSOLUTE_TIME) { 119787f2a558dd12043631e12c361abef301bf603140Andreas Huber int64_t timeUs; 1198e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (!extra->findInt64("timeUs", &timeUs)) { 1199e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim ALOGE("timeUs not found"); 1200e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return; 1201e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 120287f2a558dd12043631e12c361abef301bf603140Andreas Huber 1203e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (!mPrograms.empty()) { 1204e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim ALOGE("mPrograms is not empty"); 1205e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return; 1206e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 120787f2a558dd12043631e12c361abef301bf603140Andreas Huber mAbsoluteTimeAnchorUs = timeUs; 120887f2a558dd12043631e12c361abef301bf603140Andreas Huber return; 1209d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber } else if (type == DISCONTINUITY_TIME_OFFSET) { 1210d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber int64_t offset; 1211e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (!extra->findInt64("offset", &offset)) { 1212e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim ALOGE("offset not found"); 1213e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return; 1214e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 1215d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber 1216d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber mTimeOffsetValid = true; 1217d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber mTimeOffsetUs = offset; 1218d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber return; 121987f2a558dd12043631e12c361abef301bf603140Andreas Huber } 122087f2a558dd12043631e12c361abef301bf603140Andreas Huber 1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (size_t i = 0; i < mPrograms.size(); ++i) { 122232f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber mPrograms.editItemAt(i)->signalDiscontinuity(type, extra); 1223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} 1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 1226f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ATSParser::signalEOS(status_t finalResult) { 1227e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (finalResult == (status_t) OK) { 1228e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim ALOGE("finalResult not OK"); 1229e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return; 1230e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 12322a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber for (size_t i = 0; i < mPrograms.size(); ++i) { 1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mPrograms.editItemAt(i)->signalEOS(finalResult); 12342a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber } 12352a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber} 12362a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber 1237cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid ATSParser::parseProgramAssociationTable(ABitReader *br) { 1238cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned table_id = br->getBits(8); 12393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" table_id = %u", table_id); 12406456ae745e919085c5024f784aaa2703f9695f98David Yeh if (table_id != 0x00u) { 12416456ae745e919085c5024f784aaa2703f9695f98David Yeh ALOGE("PAT data error!"); 12426456ae745e919085c5024f784aaa2703f9695f98David Yeh return ; 12436456ae745e919085c5024f784aaa2703f9695f98David Yeh } 1244cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned section_syntax_indictor = br->getBits(1); 12453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" section_syntax_indictor = %u", section_syntax_indictor); 1246cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1247e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim br->skipBits(1); // '0' 12486e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(2)); 1249cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1250cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned section_length = br->getBits(12); 12513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" section_length = %u", section_length); 1252cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 12536e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" transport_stream_id = %u", br->getBits(16)); 12546e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(2)); 12556e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" version_number = %u", br->getBits(5)); 12566e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" current_next_indicator = %u", br->getBits(1)); 12576e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" section_number = %u", br->getBits(8)); 12586e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" last_section_number = %u", br->getBits(8)); 1259cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1260cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */); 1261cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1262cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber for (size_t i = 0; i < numProgramBytes / 4; ++i) { 1263cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned program_number = br->getBits(16); 12643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" program_number = %u", program_number); 1265cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 12666e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" reserved = %u", br->getBits(3)); 1267cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1268cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (program_number == 0) { 12696e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" network_PID = 0x%04x", br->getBits(13)); 1270cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } else { 1271cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned programMapPID = br->getBits(13); 1272cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 12733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV(" program_map_PID = 0x%04x", programMapPID); 1274cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1275386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber bool found = false; 1276386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber for (size_t index = 0; index < mPrograms.size(); ++index) { 1277386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber const sp<Program> &program = mPrograms.itemAt(index); 1278386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 1279386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (program->number() == program_number) { 1280386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber program->updateProgramMapPID(programMapPID); 1281386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber found = true; 1282386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber break; 1283386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 1284386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 1285386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 1286386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (!found) { 1287386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber mPrograms.push( 1288d47dfcb5a2e5901c96fc92662cec7aa30f7f8843Chong Zhang new Program(this, program_number, programMapPID, mLastRecoveredPTS)); 1289386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 12908dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 12918dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (mPSISections.indexOfKey(programMapPID) < 0) { 12928dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber mPSISections.add(programMapPID, new PSISection); 12938dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 1294cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1295cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1296cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 12976e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV(" CRC = 0x%08x", br->getBits(32)); 1298cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1299cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 130006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huberstatus_t ATSParser::parsePID( 1301cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ABitReader *br, unsigned PID, 130287f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned continuity_counter, 1303540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim unsigned payload_unit_start_indicator, 1304540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim SyncEvent *event) { 13058dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber ssize_t sectionIndex = mPSISections.indexOfKey(PID); 13068dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13078dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (sectionIndex >= 0) { 13084b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber sp<PSISection> section = mPSISections.valueAt(sectionIndex); 13098dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 1310cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (payload_unit_start_indicator) { 13116456ae745e919085c5024f784aaa2703f9695f98David Yeh if (!section->isEmpty()) { 13129bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty"); 13139bcf3ae6c9a413afc7accb5b48db3e5c3c829785Chong Zhang section->clear(); 13146456ae745e919085c5024f784aaa2703f9695f98David Yeh } 13158dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 1316cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned skip = br->getBits(8); 13179ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim section->setSkipBytes(skip + 1); // skip filler bytes + pointer field itself 1318cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber br->skipBits(skip * 8); 1319cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 13208dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 1321e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (br->numBitsLeft() % 8 != 0) { 1322e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 1323e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 13248dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber status_t err = section->append(br->data(), br->numBitsLeft() / 8); 13258dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13268dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (err != OK) { 13278dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return err; 13288dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 13298dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13308dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (!section->isComplete()) { 13318dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return OK; 13328dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 13338dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13349ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim if (!section->isCRCOkay()) { 13359ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim return BAD_VALUE; 13369ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim } 13378dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber ABitReader sectionBits(section->data(), section->size()); 13388dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13398dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (PID == 0) { 13408dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber parseProgramAssociationTable(§ionBits); 13418dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } else { 13428dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber bool handled = false; 13438dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber for (size_t i = 0; i < mPrograms.size(); ++i) { 13448dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber status_t err; 13458dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (!mPrograms.editItemAt(i)->parsePSISection( 13468dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber PID, §ionBits, &err)) { 13478dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber continue; 13488dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 13498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13508dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (err != OK) { 13518dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return err; 13528dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 13538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber handled = true; 13558dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber break; 13568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 13578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13588dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (!handled) { 13598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber mPSISections.removeItem(PID); 13604b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber section.clear(); 13618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 13628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 13638dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 13644b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber if (section != NULL) { 13654b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber section->clear(); 13664b4bb11b8747adeb2efe56c7df4ab6803dd7db41Andreas Huber } 13678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 136806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber return OK; 1369cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1370cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1371cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber bool handled = false; 1372cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber for (size_t i = 0; i < mPrograms.size(); ++i) { 137306528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber status_t err; 1374cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (mPrograms.editItemAt(i)->parsePID( 137587f2a558dd12043631e12c361abef301bf603140Andreas Huber PID, continuity_counter, payload_unit_start_indicator, 1376540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim br, &err, event)) { 137706528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber if (err != OK) { 137806528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber return err; 137906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber } 138006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 1381cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber handled = true; 1382cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber break; 1383cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1384cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1385cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1386cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (!handled) { 13873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PID 0x%04x not handled.", PID); 1388cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 138906528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 139006528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber return OK; 1391cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1392cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1393e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kimstatus_t ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) { 1394cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned adaptation_field_length = br->getBits(8); 139587f2a558dd12043631e12c361abef301bf603140Andreas Huber 1396cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (adaptation_field_length > 0) { 13978a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung if (adaptation_field_length * 8 > br->numBitsLeft()) { 13988a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung ALOGV("Adaptation field should be included in a single TS packet."); 13998a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung return ERROR_MALFORMED; 14008a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung } 14018a1fa1ebc2375c9dcaca2b78918c6740fff2ca74Jaesung Chung 140287f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned discontinuity_indicator = br->getBits(1); 140387f2a558dd12043631e12c361abef301bf603140Andreas Huber 140487f2a558dd12043631e12c361abef301bf603140Andreas Huber if (discontinuity_indicator) { 140587f2a558dd12043631e12c361abef301bf603140Andreas Huber ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID); 140687f2a558dd12043631e12c361abef301bf603140Andreas Huber } 140787f2a558dd12043631e12c361abef301bf603140Andreas Huber 140887f2a558dd12043631e12c361abef301bf603140Andreas Huber br->skipBits(2); 140987f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned PCR_flag = br->getBits(1); 141087f2a558dd12043631e12c361abef301bf603140Andreas Huber 141187f2a558dd12043631e12c361abef301bf603140Andreas Huber size_t numBitsRead = 4; 141287f2a558dd12043631e12c361abef301bf603140Andreas Huber 141387f2a558dd12043631e12c361abef301bf603140Andreas Huber if (PCR_flag) { 1414e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (adaptation_field_length * 8 < 52) { 1415e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return ERROR_MALFORMED; 1416e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 141787f2a558dd12043631e12c361abef301bf603140Andreas Huber br->skipBits(4); 141887f2a558dd12043631e12c361abef301bf603140Andreas Huber uint64_t PCR_base = br->getBits(32); 141987f2a558dd12043631e12c361abef301bf603140Andreas Huber PCR_base = (PCR_base << 1) | br->getBits(1); 142087f2a558dd12043631e12c361abef301bf603140Andreas Huber 142187f2a558dd12043631e12c361abef301bf603140Andreas Huber br->skipBits(6); 142287f2a558dd12043631e12c361abef301bf603140Andreas Huber unsigned PCR_ext = br->getBits(9); 142387f2a558dd12043631e12c361abef301bf603140Andreas Huber 142487f2a558dd12043631e12c361abef301bf603140Andreas Huber // The number of bytes from the start of the current 142587f2a558dd12043631e12c361abef301bf603140Andreas Huber // MPEG2 transport stream packet up and including 142687f2a558dd12043631e12c361abef301bf603140Andreas Huber // the final byte of this PCR_ext field. 142787f2a558dd12043631e12c361abef301bf603140Andreas Huber size_t byteOffsetFromStartOfTSPacket = 142887f2a558dd12043631e12c361abef301bf603140Andreas Huber (188 - br->numBitsLeft() / 8); 142987f2a558dd12043631e12c361abef301bf603140Andreas Huber 143087f2a558dd12043631e12c361abef301bf603140Andreas Huber uint64_t PCR = PCR_base * 300 + PCR_ext; 143187f2a558dd12043631e12c361abef301bf603140Andreas Huber 1432b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)", 143387f2a558dd12043631e12c361abef301bf603140Andreas Huber PID, PCR, PCR / 27E6); 143487f2a558dd12043631e12c361abef301bf603140Andreas Huber 143587f2a558dd12043631e12c361abef301bf603140Andreas Huber // The number of bytes received by this parser up to and 143687f2a558dd12043631e12c361abef301bf603140Andreas Huber // including the final byte of this PCR_ext field. 143787f2a558dd12043631e12c361abef301bf603140Andreas Huber size_t byteOffsetFromStart = 143887f2a558dd12043631e12c361abef301bf603140Andreas Huber mNumTSPacketsParsed * 188 + byteOffsetFromStartOfTSPacket; 143987f2a558dd12043631e12c361abef301bf603140Andreas Huber 144087f2a558dd12043631e12c361abef301bf603140Andreas Huber for (size_t i = 0; i < mPrograms.size(); ++i) { 144187f2a558dd12043631e12c361abef301bf603140Andreas Huber updatePCR(PID, PCR, byteOffsetFromStart); 144287f2a558dd12043631e12c361abef301bf603140Andreas Huber } 144387f2a558dd12043631e12c361abef301bf603140Andreas Huber 144487f2a558dd12043631e12c361abef301bf603140Andreas Huber numBitsRead += 52; 144587f2a558dd12043631e12c361abef301bf603140Andreas Huber } 144687f2a558dd12043631e12c361abef301bf603140Andreas Huber 144787f2a558dd12043631e12c361abef301bf603140Andreas Huber br->skipBits(adaptation_field_length * 8 - numBitsRead); 1448cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1449e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim return OK; 1450cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1451cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1452540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kimstatus_t ATSParser::parseTS(ABitReader *br, SyncEvent *event) { 14533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("---"); 1454cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1455cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned sync_byte = br->getBits(8); 14566456ae745e919085c5024f784aaa2703f9695f98David Yeh if (sync_byte != 0x47u) { 14576456ae745e919085c5024f784aaa2703f9695f98David Yeh ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte); 14586456ae745e919085c5024f784aaa2703f9695f98David Yeh return BAD_VALUE; 14596456ae745e919085c5024f784aaa2703f9695f98David Yeh } 1460cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 146152668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber if (br->getBits(1)) { // transport_error_indicator 146252668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber // silently ignore. 146352668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber return OK; 146452668ca838e1869676ff95e7388f93ec1858b1e9Andreas Huber } 1465cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1466cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned payload_unit_start_indicator = br->getBits(1); 14673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator); 1468cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 14696e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("transport_priority = %u", br->getBits(1)); 1470cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1471cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned PID = br->getBits(13); 14723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("PID = 0x%04x", PID); 1473cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 14746e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber MY_LOGV("transport_scrambling_control = %u", br->getBits(2)); 1475cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1476cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber unsigned adaptation_field_control = br->getBits(2); 14773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("adaptation_field_control = %u", adaptation_field_control); 1478cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 14790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber unsigned continuity_counter = br->getBits(4); 148087f2a558dd12043631e12c361abef301bf603140Andreas Huber ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter); 14810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber 1482df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter); 1483cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 148487f2a558dd12043631e12c361abef301bf603140Andreas Huber status_t err = OK; 148587f2a558dd12043631e12c361abef301bf603140Andreas Huber 1486e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (adaptation_field_control == 2 || adaptation_field_control == 3) { 1487e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim err = parseAdaptationField(br, PID); 1488e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 1489e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (err == OK) { 1490e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim if (adaptation_field_control == 1 || adaptation_field_control == 3) { 1491540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim err = parsePID(br, PID, continuity_counter, 1492540006666b4191cd78391378f1c66c21bcf0c4cdWonsik Kim payload_unit_start_indicator, event); 1493e314c678ea0b53dd9296ba6b5c3272c702433b47Jinsuk Kim } 1494cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 149506528d7f18ad01377357d337eaa3e875a242bd2dAndreas Huber 149687f2a558dd12043631e12c361abef301bf603140Andreas Huber ++mNumTSPacketsParsed; 149787f2a558dd12043631e12c361abef301bf603140Andreas Huber 149887f2a558dd12043631e12c361abef301bf603140Andreas Huber return err; 1499cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1500cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1501cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersp<MediaSource> ATSParser::getSource(SourceType type) { 1502386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber int which = -1; // any 1503386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 1504cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber for (size_t i = 0; i < mPrograms.size(); ++i) { 1505386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber const sp<Program> &program = mPrograms.editItemAt(i); 1506386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 1507386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber if (which >= 0 && (int)program->number() != which) { 1508386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber continue; 1509386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber } 1510386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber 1511386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber sp<MediaSource> source = program->getSource(type); 1512cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1513cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (source != NULL) { 1514cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return source; 1515cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1516cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1517cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1518cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber return NULL; 1519cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} 1520cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 1521bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shihbool ATSParser::hasSource(SourceType type) const { 1522bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih for (size_t i = 0; i < mPrograms.size(); ++i) { 1523bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih const sp<Program> &program = mPrograms.itemAt(i); 1524bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih if (program->hasSource(type)) { 1525bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih return true; 1526bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih } 1527bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih } 1528bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih 1529bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih return false; 1530bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih} 1531bf20727f0aaf609bc3b495b07b45822b137d21baRobert Shih 153243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huberbool ATSParser::PTSTimeDeltaEstablished() { 153343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber if (mPrograms.isEmpty()) { 153443c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber return false; 153543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 153643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 153743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished(); 153843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber} 153943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber 1540c9fa35cf7c9c11a8acb77128db1a6a13f1befe3cChad Brubaker__attribute__((no_sanitize("integer"))) 154187f2a558dd12043631e12c361abef301bf603140Andreas Hubervoid ATSParser::updatePCR( 154284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber unsigned /* PID */, uint64_t PCR, size_t byteOffsetFromStart) { 1543b4a7a2df4c28c3f32b5d877b54831d2cc5d78f81Colin Cross ALOGV("PCR 0x%016" PRIx64 " @ %zu", PCR, byteOffsetFromStart); 154487f2a558dd12043631e12c361abef301bf603140Andreas Huber 154587f2a558dd12043631e12c361abef301bf603140Andreas Huber if (mNumPCRs == 2) { 154687f2a558dd12043631e12c361abef301bf603140Andreas Huber mPCR[0] = mPCR[1]; 154787f2a558dd12043631e12c361abef301bf603140Andreas Huber mPCRBytes[0] = mPCRBytes[1]; 154887f2a558dd12043631e12c361abef301bf603140Andreas Huber mSystemTimeUs[0] = mSystemTimeUs[1]; 154987f2a558dd12043631e12c361abef301bf603140Andreas Huber mNumPCRs = 1; 155087f2a558dd12043631e12c361abef301bf603140Andreas Huber } 155187f2a558dd12043631e12c361abef301bf603140Andreas Huber 155287f2a558dd12043631e12c361abef301bf603140Andreas Huber mPCR[mNumPCRs] = PCR; 155387f2a558dd12043631e12c361abef301bf603140Andreas Huber mPCRBytes[mNumPCRs] = byteOffsetFromStart; 155487f2a558dd12043631e12c361abef301bf603140Andreas Huber mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs(); 155587f2a558dd12043631e12c361abef301bf603140Andreas Huber 155687f2a558dd12043631e12c361abef301bf603140Andreas Huber ++mNumPCRs; 155787f2a558dd12043631e12c361abef301bf603140Andreas Huber 155887f2a558dd12043631e12c361abef301bf603140Andreas Huber if (mNumPCRs == 2) { 1559c9fa35cf7c9c11a8acb77128db1a6a13f1befe3cChad Brubaker /* Unsigned overflow here */ 156087f2a558dd12043631e12c361abef301bf603140Andreas Huber double transportRate = 156187f2a558dd12043631e12c361abef301bf603140Andreas Huber (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]); 156287f2a558dd12043631e12c361abef301bf603140Andreas Huber 156387f2a558dd12043631e12c361abef301bf603140Andreas Huber ALOGV("transportRate = %.2f bytes/sec", transportRate); 156487f2a558dd12043631e12c361abef301bf603140Andreas Huber } 156587f2a558dd12043631e12c361abef301bf603140Andreas Huber} 156687f2a558dd12043631e12c361abef301bf603140Andreas Huber 15678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber//////////////////////////////////////////////////////////////////////////////// 15688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 15699ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 15709ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// CRC32 used for PSI section. The table was generated by following command: 15719ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// $ python pycrc.py --model crc-32-mpeg --algorithm table-driven --generate c 15729ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim// Visit http://www.tty1.net/pycrc/index_en.html for more details. 15739ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimuint32_t ATSParser::PSISection::CRC_TABLE[] = { 15749ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 15759ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 15769ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 15779ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 15789ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 15799ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 15809ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 15819ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 15829ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 15839ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 15849ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 15859ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 15869ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 15879ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 15889ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 15899ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 15909ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 15919ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 15929ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 15939ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 15949ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 15959ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 15969ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 15979ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 15989ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 15999ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 16009ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 16019ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 16029ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 16039ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 16049ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 16059ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 16069ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 16079ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 16089ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 16099ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 16109ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 16119ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 16129ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 16139ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 16149ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 16159ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 16169ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 16179ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 16189ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 16199ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 16209ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 16219ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 16229ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 16239ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 16249ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 16259ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 16269ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 16279ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 16289ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 16299ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 16309ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 16319ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 16329ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 16339ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 16349ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 16359ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 16369ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 16379ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 16389ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim }; 16399ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 16409ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk KimATSParser::PSISection::PSISection() : 16419ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim mSkipBytes(0) { 16428dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 16438dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16448dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas HuberATSParser::PSISection::~PSISection() { 16458dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 16468dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16478dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberstatus_t ATSParser::PSISection::append(const void *data, size_t size) { 16488dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) { 16498dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber size_t newCapacity = 16508dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber (mBuffer == NULL) ? size : mBuffer->capacity() + size; 16518dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16528dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber newCapacity = (newCapacity + 1023) & ~1023; 16538dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16548dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber sp<ABuffer> newBuffer = new ABuffer(newCapacity); 16558dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16568dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (mBuffer != NULL) { 16578dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size()); 16588dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber newBuffer->setRange(0, mBuffer->size()); 16598dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } else { 16608dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber newBuffer->setRange(0, 0); 16618dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 16628dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16638dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber mBuffer = newBuffer; 16648dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 16658dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16668dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber memcpy(mBuffer->data() + mBuffer->size(), data, size); 16678dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber mBuffer->setRange(0, mBuffer->size() + size); 16688dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16698dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return OK; 16708dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 16718dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16729ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimvoid ATSParser::PSISection::setSkipBytes(uint8_t skip) { 16739ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim mSkipBytes = skip; 16749ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim} 16759ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 16768dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Hubervoid ATSParser::PSISection::clear() { 16778dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (mBuffer != NULL) { 16788dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber mBuffer->setRange(0, 0); 16798dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 16809ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim mSkipBytes = 0; 16818dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 16828dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16838dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::PSISection::isComplete() const { 16848dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber if (mBuffer == NULL || mBuffer->size() < 3) { 16858dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return false; 16868dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber } 16878dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16888dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff; 16898dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return mBuffer->size() >= sectionLength + 3; 16908dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 16918dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16928dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberbool ATSParser::PSISection::isEmpty() const { 16938dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return mBuffer == NULL || mBuffer->size() == 0; 16948dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 16958dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 16968dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huberconst uint8_t *ATSParser::PSISection::data() const { 16978dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return mBuffer == NULL ? NULL : mBuffer->data(); 16988dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 16998dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 17008dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Hubersize_t ATSParser::PSISection::size() const { 17018dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber return mBuffer == NULL ? 0 : mBuffer->size(); 17028dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber} 17038dfa228201131da0bf3ba1d74c819c27c0500f6bAndreas Huber 17049ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kimbool ATSParser::PSISection::isCRCOkay() const { 17059ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim if (!isComplete()) { 17069ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim return false; 17079ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim } 17089ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim uint8_t* data = mBuffer->data(); 17099ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 17109ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim // Return true if section_syntax_indicator says no section follows the field section_length. 17119ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim if ((data[1] & 0x80) == 0) { 17129ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim return true; 17139ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim } 17149ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 17159ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim unsigned sectionLength = U16_AT(data + 1) & 0xfff; 17169ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes); 17179ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 17189ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim // Skip the preceding field present when payload start indicator is on. 17199ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim sectionLength -= mSkipBytes; 17209ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim 17219ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim uint32_t crc = 0xffffffff; 17229ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim for(unsigned i = 0; i < sectionLength + 4 /* crc */; i++) { 17239ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim uint8_t b = data[i]; 17249ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim int index = ((crc >> 24) ^ (b & 0xff)) & 0xff; 17259ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim crc = CRC_TABLE[index] ^ (crc << 8); 17269ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim } 17279ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim ALOGV("crc: %08x\n", crc); 17289ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim return (crc == 0); 17299ca7b9c74e882526ee5810ff62f203bf75cd3f1aJinsuk Kim} 1730cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber} // namespace android 1731