blob: 6aeea3b8ad73793a90e3b6dd8d26b4b92d4db1d8 [file] [log] [blame]
Andreas Hubercda17c62010-06-07 13:05:37 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber6e4c5c42010-09-21 13:13:15 -070017//#define LOG_NDEBUG 0
18#define LOG_TAG "ATSParser"
19#include <utils/Log.h>
Andreas Hubercda17c62010-06-07 13:05:37 -070020#include "ATSParser.h"
Andreas Hubercda17c62010-06-07 13:05:37 -070021#include "AnotherPacketSource.h"
Chong Zhang3b2847f2017-01-18 17:43:03 -080022#include "CasManager.h"
Andreas Huber6a63a932010-10-01 10:51:41 -070023#include "ESQueue.h"
Andreas Hubercda17c62010-06-07 13:05:37 -070024
Chong Zhangd5a416a2017-05-16 11:16:34 -070025#include <android/hardware/cas/native/1.0/IDescrambler.h>
Chong Zhang00c5c052018-12-17 14:15:58 -080026#include <android/hidl/allocator/1.0/IAllocator.h>
27#include <android/hidl/memory/1.0/IMemory.h>
Chong Zhangd5a416a2017-05-16 11:16:34 -070028#include <cutils/native_handle.h>
Chong Zhang00c5c052018-12-17 14:15:58 -080029#include <hidlmemory/mapping.h>
Chong Zhangd1af6412018-02-20 10:59:37 -080030#include <media/cas/DescramblerAPI.h>
Andreas Huber85f12e92010-08-19 10:39:47 -070031#include <media/stagefright/foundation/ABitReader.h>
Andreas Hubercda17c62010-06-07 13:05:37 -070032#include <media/stagefright/foundation/ABuffer.h>
33#include <media/stagefright/foundation/ADebug.h>
34#include <media/stagefright/foundation/AMessage.h>
Dongwon Kang60761282017-10-09 11:16:48 -070035#include <media/stagefright/foundation/ByteUtils.h>
Dongwon Kang15d02f82017-12-14 16:32:18 -080036#include <media/stagefright/foundation/MediaKeys.h>
Dongwon Kangd91dc5a2017-10-10 00:07:09 -070037#include <media/stagefright/foundation/avc_utils.h>
Andreas Hubercda17c62010-06-07 13:05:37 -070038#include <media/stagefright/foundation/hexdump.h>
39#include <media/stagefright/MediaDefs.h>
40#include <media/stagefright/MediaErrors.h>
41#include <media/stagefright/MetaData.h>
Andreas Huber32f3cef2011-03-02 15:34:46 -080042#include <media/IStreamSource.h>
Andreas Hubercda17c62010-06-07 13:05:37 -070043#include <utils/KeyedVector.h>
Chong Zhang9bcf3ae2015-03-08 15:59:01 -070044#include <utils/Vector.h>
Andreas Hubercda17c62010-06-07 13:05:37 -070045
Colin Crossb4a7a2d2014-03-19 16:59:00 -070046#include <inttypes.h>
47
Andreas Hubercda17c62010-06-07 13:05:37 -070048namespace android {
Chong Zhangd5a416a2017-05-16 11:16:34 -070049using hardware::hidl_string;
50using hardware::hidl_vec;
Chong Zhang00c5c052018-12-17 14:15:58 -080051using hardware::hidl_memory;
Chong Zhangd5a416a2017-05-16 11:16:34 -070052using namespace hardware::cas::V1_0;
53using namespace hardware::cas::native::V1_0;
Chong Zhang00c5c052018-12-17 14:15:58 -080054typedef hidl::allocator::V1_0::IAllocator TAllocator;
55typedef hidl::memory::V1_0::IMemory TMemory;
Andreas Hubercda17c62010-06-07 13:05:37 -070056
Andreas Huber6e4c5c42010-09-21 13:13:15 -070057// I want the expression "y" evaluated even if verbose logging is off.
58#define MY_LOGV(x, y) \
Steve Block3856b092011-10-20 11:56:00 +010059 do { unsigned tmp = y; ALOGV(x, tmp); } while (0)
Andreas Huber6e4c5c42010-09-21 13:13:15 -070060
Andreas Hubercda17c62010-06-07 13:05:37 -070061static const size_t kTSPacketSize = 188;
62
63struct ATSParser::Program : public RefBase {
Chong Zhangd47dfcb2015-03-27 15:53:45 -070064 Program(ATSParser *parser, unsigned programNumber, unsigned programMapPID,
65 int64_t lastRecoveredPTS);
Andreas Hubercda17c62010-06-07 13:05:37 -070066
Andreas Huber8dfa2282012-05-15 12:37:29 -070067 bool parsePSISection(
68 unsigned pid, ABitReader *br, status_t *err);
69
Wonsik Kim54000662015-04-13 10:59:06 +090070 // Pass to appropriate stream according to pid, and set event if it's a PES
71 // with a sync frame.
72 // Note that the method itself does not touch event.
Andreas Hubercda17c62010-06-07 13:05:37 -070073 bool parsePID(
Andreas Huber87f2a552012-08-31 13:55:24 -070074 unsigned pid, unsigned continuity_counter,
75 unsigned payload_unit_start_indicator,
Chong Zhang3b2847f2017-01-18 17:43:03 -080076 unsigned transport_scrambling_control,
77 unsigned random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +090078 ABitReader *br, status_t *err, SyncEvent *event);
Andreas Hubercda17c62010-06-07 13:05:37 -070079
Andreas Huber32f3cef2011-03-02 15:34:46 -080080 void signalDiscontinuity(
81 DiscontinuityType type, const sp<AMessage> &extra);
82
Andreas Huberf9334412010-12-15 15:17:42 -080083 void signalEOS(status_t finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -070084
Marco Nelissen45d54c62018-01-26 10:04:22 -080085 sp<AnotherPacketSource> getSource(SourceType type);
Robert Shihbf207272014-10-30 17:22:11 -070086 bool hasSource(SourceType type) const;
Andreas Hubercda17c62010-06-07 13:05:37 -070087
Andreas Huberbff07d02010-10-12 11:34:37 -070088 int64_t convertPTSToTimestamp(uint64_t PTS);
89
Andreas Huber43c3e6c2011-01-05 12:17:08 -080090 bool PTSTimeDeltaEstablished() const {
91 return mFirstPTSValid;
92 }
93
Andreas Huber386d6092011-05-19 08:37:39 -070094 unsigned number() const { return mProgramNumber; }
95
96 void updateProgramMapPID(unsigned programMapPID) {
97 mProgramMapPID = programMapPID;
98 }
99
Andreas Huber8dfa2282012-05-15 12:37:29 -0700100 unsigned programMapPID() const {
101 return mProgramMapPID;
102 }
103
Andreas Huber87f2a552012-08-31 13:55:24 -0700104 uint32_t parserFlags() const {
105 return mParser->mFlags;
106 }
107
Chong Zhang3b2847f2017-01-18 17:43:03 -0800108 sp<CasManager> casManager() const {
109 return mParser->mCasManager;
110 }
111
Robert Shih82e14702016-11-17 11:24:29 -0800112 uint64_t firstPTS() const {
113 return mFirstPTS;
114 }
115
Chong Zhang3b2847f2017-01-18 17:43:03 -0800116 void updateCasSessions();
117
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700118 void signalNewSampleAesKey(const sp<AMessage> &keyItem);
119
Andreas Hubercda17c62010-06-07 13:05:37 -0700120private:
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700121
Andreas Huberf9334412010-12-15 15:17:42 -0800122 ATSParser *mParser;
Andreas Huber386d6092011-05-19 08:37:39 -0700123 unsigned mProgramNumber;
Andreas Hubercda17c62010-06-07 13:05:37 -0700124 unsigned mProgramMapPID;
Sampath Shetty142598f2018-12-10 13:52:30 +1100125 uint32_t mPMTVersion;
126 uint32_t mPMT_CRC;
Andreas Hubercda17c62010-06-07 13:05:37 -0700127 KeyedVector<unsigned, sp<Stream> > mStreams;
Andreas Huberbff07d02010-10-12 11:34:37 -0700128 bool mFirstPTSValid;
129 uint64_t mFirstPTS;
Chong Zhang799c9682015-03-02 23:42:38 -0800130 int64_t mLastRecoveredPTS;
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700131 sp<AMessage> mSampleAesKeyItem;
Andreas Hubercda17c62010-06-07 13:05:37 -0700132
Andreas Huber06528d72011-08-31 16:29:05 -0700133 status_t parseProgramMap(ABitReader *br);
Chong Zhang799c9682015-03-02 23:42:38 -0800134 int64_t recoverPTS(uint64_t PTS_33bit);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800135 bool findCADescriptor(
136 ABitReader *br, unsigned infoLength, CADescriptor *caDescriptor);
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700137 bool switchPIDs(const Vector<StreamInfo> &infos);
Andreas Hubercda17c62010-06-07 13:05:37 -0700138
139 DISALLOW_EVIL_CONSTRUCTORS(Program);
140};
141
142struct ATSParser::Stream : public RefBase {
Chong Zhang7e986a82018-11-07 13:01:08 -0800143 Stream(Program *program, unsigned PCR_PID, const StreamInfo &info);
Andreas Hubercda17c62010-06-07 13:05:37 -0700144
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800145 unsigned type() const { return mStreamType; }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800146 unsigned typeExt() const { return mStreamTypeExt; }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800147 unsigned pid() const { return mElementaryPID; }
148 void setPID(unsigned pid) { mElementaryPID = pid; }
Sampath Shetty142598f2018-12-10 13:52:30 +1100149 void setAudioPresentations(AudioPresentationCollection audioPresentations) {
150 mAudioPresentations = audioPresentations;
151 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800152
Chong Zhangbc7aae42017-03-31 14:53:19 -0700153 void setCasInfo(
154 int32_t systemId,
Chong Zhang3b2847f2017-01-18 17:43:03 -0800155 const sp<IDescrambler> &descrambler,
156 const std::vector<uint8_t> &sessionId);
157
Wonsik Kim54000662015-04-13 10:59:06 +0900158 // Parse the payload and set event when PES with a sync frame is detected.
Wei Jia9558f6d2016-03-08 17:31:16 -0800159 // This method knows when a PES starts; so record mPesStartOffsets in that
Wonsik Kim54000662015-04-13 10:59:06 +0900160 // case.
Andreas Huber54031292011-09-01 11:04:43 -0700161 status_t parse(
Andreas Huber87f2a552012-08-31 13:55:24 -0700162 unsigned continuity_counter,
Andreas Hubercda17c62010-06-07 13:05:37 -0700163 unsigned payload_unit_start_indicator,
Chong Zhang3b2847f2017-01-18 17:43:03 -0800164 unsigned transport_scrambling_control,
165 unsigned random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +0900166 ABitReader *br,
167 SyncEvent *event);
Andreas Hubercda17c62010-06-07 13:05:37 -0700168
Andreas Huber32f3cef2011-03-02 15:34:46 -0800169 void signalDiscontinuity(
170 DiscontinuityType type, const sp<AMessage> &extra);
171
Andreas Huberf9334412010-12-15 15:17:42 -0800172 void signalEOS(status_t finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700173
Robert Shih82e14702016-11-17 11:24:29 -0800174 SourceType getSourceType();
Marco Nelissen45d54c62018-01-26 10:04:22 -0800175 sp<AnotherPacketSource> getSource(SourceType type);
Andreas Hubercda17c62010-06-07 13:05:37 -0700176
Robert Shihbf207272014-10-30 17:22:11 -0700177 bool isAudio() const;
178 bool isVideo() const;
Robert Shih08528432015-04-08 09:06:54 -0700179 bool isMeta() const;
Robert Shihbf207272014-10-30 17:22:11 -0700180
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700181 void signalNewSampleAesKey(const sp<AMessage> &keyItem);
182
Andreas Hubercda17c62010-06-07 13:05:37 -0700183protected:
184 virtual ~Stream();
185
186private:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800187 struct SubSampleInfo {
188 size_t subSampleSize;
189 unsigned transport_scrambling_mode;
190 unsigned random_access_indicator;
191 };
Andreas Huberbff07d02010-10-12 11:34:37 -0700192 Program *mProgram;
Andreas Hubercda17c62010-06-07 13:05:37 -0700193 unsigned mElementaryPID;
194 unsigned mStreamType;
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800195 unsigned mStreamTypeExt;
Andreas Huber87f2a552012-08-31 13:55:24 -0700196 unsigned mPCR_PID;
197 int32_t mExpectedContinuityCounter;
Andreas Hubercda17c62010-06-07 13:05:37 -0700198
199 sp<ABuffer> mBuffer;
200 sp<AnotherPacketSource> mSource;
201 bool mPayloadStarted;
Marco Nelissenbe9634d2015-04-15 14:33:39 -0700202 bool mEOSReached;
Andreas Hubercda17c62010-06-07 13:05:37 -0700203
Andreas Huber90a92052012-10-30 15:53:03 -0700204 uint64_t mPrevPTS;
Wei Jia9558f6d2016-03-08 17:31:16 -0800205 List<off64_t> mPesStartOffsets;
Andreas Huber90a92052012-10-30 15:53:03 -0700206
Andreas Huber386d6092011-05-19 08:37:39 -0700207 ElementaryStreamQueue *mQueue;
Andreas Huber6a63a932010-10-01 10:51:41 -0700208
Chong Zhang3b2847f2017-01-18 17:43:03 -0800209 bool mScrambled;
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700210 bool mSampleEncrypted;
211 sp<AMessage> mSampleAesKeyItem;
Chong Zhang00c5c052018-12-17 14:15:58 -0800212 sp<TMemory> mHidlMemory;
213 sp<TAllocator> mHidlAllocator;
Chong Zhangd5a416a2017-05-16 11:16:34 -0700214 hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800215 sp<ABuffer> mDescrambledBuffer;
216 List<SubSampleInfo> mSubSamples;
217 sp<IDescrambler> mDescrambler;
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100218 AudioPresentationCollection mAudioPresentations;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800219
Sampath Shettyc6148a62018-12-18 15:50:43 +1100220 // Send audio presentations along with access units.
221 void addAudioPresentations(const sp<ABuffer> &buffer);
222
Wonsik Kim54000662015-04-13 10:59:06 +0900223 // Flush accumulated payload if necessary --- i.e. at EOS or at the start of
224 // another payload. event is set if the flushed payload is PES with a sync
225 // frame.
226 status_t flush(SyncEvent *event);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800227
228 // Flush accumulated payload for scrambled streams if necessary --- i.e. at
229 // EOS or at the start of another payload. event is set if the flushed
230 // payload is PES with a sync frame.
231 status_t flushScrambled(SyncEvent *event);
232
233 // Check if a PES packet is scrambled at PES level.
234 uint32_t getPesScramblingControl(ABitReader *br, int32_t *pesOffset);
235
Wonsik Kim54000662015-04-13 10:59:06 +0900236 // Strip and parse PES headers and pass remaining payload into onPayload
237 // with parsed metadata. event is set if the PES contains a sync frame.
238 status_t parsePES(ABitReader *br, SyncEvent *event);
Andreas Hubercda17c62010-06-07 13:05:37 -0700239
Wonsik Kim54000662015-04-13 10:59:06 +0900240 // Feed the payload into mQueue and if a packet is identified, queue it
241 // into mSource. If the packet is a sync frame. set event with start offset
242 // and timestamp of the packet.
Andreas Hubercda17c62010-06-07 13:05:37 -0700243 void onPayloadData(
244 unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
Chong Zhang3b2847f2017-01-18 17:43:03 -0800245 unsigned PES_scrambling_control,
246 const uint8_t *data, size_t size,
247 int32_t payloadOffset, SyncEvent *event);
248
249 // Ensure internal buffers can hold specified size, and will re-allocate
250 // as needed.
Chong Zhangd5a416a2017-05-16 11:16:34 -0700251 bool ensureBufferCapacity(size_t size);
Andreas Huber82f73212010-09-01 12:22:36 -0700252
Andreas Hubercda17c62010-06-07 13:05:37 -0700253 DISALLOW_EVIL_CONSTRUCTORS(Stream);
254};
255
Andreas Huber8dfa2282012-05-15 12:37:29 -0700256struct ATSParser::PSISection : public RefBase {
257 PSISection();
258
259 status_t append(const void *data, size_t size);
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +0900260 void setSkipBytes(uint8_t skip);
Andreas Huber8dfa2282012-05-15 12:37:29 -0700261 void clear();
262
263 bool isComplete() const;
264 bool isEmpty() const;
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +0900265 bool isCRCOkay() const;
Andreas Huber8dfa2282012-05-15 12:37:29 -0700266
267 const uint8_t *data() const;
268 size_t size() const;
269
270protected:
271 virtual ~PSISection();
272
273private:
274 sp<ABuffer> mBuffer;
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +0900275 uint8_t mSkipBytes;
276 static uint32_t CRC_TABLE[];
Andreas Huber8dfa2282012-05-15 12:37:29 -0700277
278 DISALLOW_EVIL_CONSTRUCTORS(PSISection);
279};
280
Wonsik Kim54000662015-04-13 10:59:06 +0900281ATSParser::SyncEvent::SyncEvent(off64_t offset)
Wei Jia9558f6d2016-03-08 17:31:16 -0800282 : mHasReturnedData(false), mOffset(offset), mTimeUs(0) {}
Wonsik Kim54000662015-04-13 10:59:06 +0900283
Marco Nelissen45d54c62018-01-26 10:04:22 -0800284void ATSParser::SyncEvent::init(off64_t offset, const sp<AnotherPacketSource> &source,
Robert Shih82e14702016-11-17 11:24:29 -0800285 int64_t timeUs, SourceType type) {
Wei Jia9558f6d2016-03-08 17:31:16 -0800286 mHasReturnedData = true;
Wonsik Kim54000662015-04-13 10:59:06 +0900287 mOffset = offset;
288 mMediaSource = source;
289 mTimeUs = timeUs;
Robert Shih82e14702016-11-17 11:24:29 -0800290 mType = type;
Wonsik Kim54000662015-04-13 10:59:06 +0900291}
292
Wei Jia9558f6d2016-03-08 17:31:16 -0800293void ATSParser::SyncEvent::reset() {
294 mHasReturnedData = false;
295}
Andreas Hubercda17c62010-06-07 13:05:37 -0700296////////////////////////////////////////////////////////////////////////////////
297
Andreas Huber386d6092011-05-19 08:37:39 -0700298ATSParser::Program::Program(
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700299 ATSParser *parser, unsigned programNumber, unsigned programMapPID,
300 int64_t lastRecoveredPTS)
Andreas Huberf9334412010-12-15 15:17:42 -0800301 : mParser(parser),
Andreas Huber386d6092011-05-19 08:37:39 -0700302 mProgramNumber(programNumber),
Andreas Huberf9334412010-12-15 15:17:42 -0800303 mProgramMapPID(programMapPID),
Sampath Shetty142598f2018-12-10 13:52:30 +1100304 mPMTVersion(0xffffffff),
305 mPMT_CRC(0xffffffff),
Andreas Huberbff07d02010-10-12 11:34:37 -0700306 mFirstPTSValid(false),
Chong Zhang799c9682015-03-02 23:42:38 -0800307 mFirstPTS(0),
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700308 mLastRecoveredPTS(lastRecoveredPTS) {
Steve Block3856b092011-10-20 11:56:00 +0100309 ALOGV("new program number %u", programNumber);
Andreas Hubercda17c62010-06-07 13:05:37 -0700310}
311
Andreas Huber8dfa2282012-05-15 12:37:29 -0700312bool ATSParser::Program::parsePSISection(
313 unsigned pid, ABitReader *br, status_t *err) {
314 *err = OK;
315
316 if (pid != mProgramMapPID) {
317 return false;
318 }
319
320 *err = parseProgramMap(br);
321
322 return true;
323}
324
Andreas Hubercda17c62010-06-07 13:05:37 -0700325bool ATSParser::Program::parsePID(
Andreas Huber87f2a552012-08-31 13:55:24 -0700326 unsigned pid, unsigned continuity_counter,
327 unsigned payload_unit_start_indicator,
Chong Zhang3b2847f2017-01-18 17:43:03 -0800328 unsigned transport_scrambling_control,
329 unsigned random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +0900330 ABitReader *br, status_t *err, SyncEvent *event) {
Andreas Huber06528d72011-08-31 16:29:05 -0700331 *err = OK;
332
Andreas Hubercda17c62010-06-07 13:05:37 -0700333 ssize_t index = mStreams.indexOfKey(pid);
334 if (index < 0) {
335 return false;
336 }
337
Andreas Huber54031292011-09-01 11:04:43 -0700338 *err = mStreams.editValueAt(index)->parse(
Chong Zhang3b2847f2017-01-18 17:43:03 -0800339 continuity_counter,
340 payload_unit_start_indicator,
341 transport_scrambling_control,
342 random_access_indicator,
343 br, event);
Andreas Hubercda17c62010-06-07 13:05:37 -0700344
345 return true;
346}
347
Andreas Huber32f3cef2011-03-02 15:34:46 -0800348void ATSParser::Program::signalDiscontinuity(
349 DiscontinuityType type, const sp<AMessage> &extra) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800350 int64_t mediaTimeUs;
351 if ((type & DISCONTINUITY_TIME)
352 && extra != NULL
353 && extra->findInt64(
Dongwon Kang15d02f82017-12-14 16:32:18 -0800354 kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800355 mFirstPTSValid = false;
356 }
357
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700358 for (size_t i = 0; i < mStreams.size(); ++i) {
Andreas Huber32f3cef2011-03-02 15:34:46 -0800359 mStreams.editValueAt(i)->signalDiscontinuity(type, extra);
Andreas Huberf9334412010-12-15 15:17:42 -0800360 }
361}
362
363void ATSParser::Program::signalEOS(status_t finalResult) {
364 for (size_t i = 0; i < mStreams.size(); ++i) {
365 mStreams.editValueAt(i)->signalEOS(finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700366 }
367}
368
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700369bool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) {
370 bool success = false;
371
372 if (mStreams.size() == infos.size()) {
373 // build type->PIDs map for old and new mapping
374 size_t i;
375 KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs;
376 for (i = 0; i < mStreams.size(); ++i) {
377 ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type());
378 if (index < 0) {
379 oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>());
380 }
381 oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid());
382 }
383 for (i = 0; i < infos.size(); ++i) {
384 ssize_t index = newType2PIDs.indexOfKey(infos[i].mType);
385 if (index < 0) {
386 newType2PIDs.add(infos[i].mType, Vector<int32_t>());
387 }
388 newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID);
389 }
390
391 // we can recover if the number of streams for each type hasn't changed
392 if (oldType2PIDs.size() == newType2PIDs.size()) {
393 success = true;
394 for (i = 0; i < oldType2PIDs.size(); ++i) {
395 // KeyedVector is sorted, we just compare key and size of each index
396 if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i)
397 || oldType2PIDs[i].size() != newType2PIDs[i].size()) {
398 success = false;
399 break;
400 }
401 }
402 }
403
404 if (success) {
405 // save current streams to temp
406 KeyedVector<int32_t, sp<Stream> > temp;
407 for (i = 0; i < mStreams.size(); ++i) {
408 temp.add(mStreams.keyAt(i), mStreams.editValueAt(i));
409 }
410
411 mStreams.clear();
412 for (i = 0; i < temp.size(); ++i) {
413 // The two checks below shouldn't happen,
414 // we already checked above the stream count matches
415 ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
Jinsuk Kime314c672015-04-22 11:08:28 +0900416 if (index < 0) {
417 return false;
418 }
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700419 Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
Jinsuk Kime314c672015-04-22 11:08:28 +0900420 if (newPIDs.isEmpty()) {
421 return false;
422 }
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700423
424 // get the next PID for temp[i]->type() in the new PID map
425 Vector<int32_t>::iterator it = newPIDs.begin();
426
427 // change the PID of the stream, and add it back
428 temp.editValueAt(i)->setPID(*it);
429 mStreams.add(temp[i]->pid(), temp.editValueAt(i));
430
431 // removed the used PID
432 newPIDs.erase(it);
433 }
434 }
435 }
436 return success;
437}
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800438
Chong Zhang3b2847f2017-01-18 17:43:03 -0800439bool ATSParser::Program::findCADescriptor(
440 ABitReader *br, unsigned infoLength,
441 ATSParser::CADescriptor *caDescriptor) {
442 bool found = false;
443 while (infoLength > 2) {
444 unsigned descriptor_tag = br->getBits(8);
445 ALOGV(" tag = 0x%02x", descriptor_tag);
446
447 unsigned descriptor_length = br->getBits(8);
448 ALOGV(" len = %u", descriptor_length);
449
450 infoLength -= 2;
451 if (descriptor_length > infoLength) {
452 break;
453 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800454 if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
Chong Zhang3b2847f2017-01-18 17:43:03 -0800455 found = true;
456 caDescriptor->mSystemID = br->getBits(16);
457 caDescriptor->mPID = br->getBits(16) & 0x1fff;
458 infoLength -= 4;
459 caDescriptor->mPrivateData.assign(
460 br->data(), br->data() + descriptor_length - 4);
461 break;
462 } else {
463 infoLength -= descriptor_length;
464 br->skipBits(descriptor_length * 8);
465 }
466 }
467 br->skipBits(infoLength * 8);
468 return found;
469}
470
Andreas Huber06528d72011-08-31 16:29:05 -0700471status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
Andreas Hubercda17c62010-06-07 13:05:37 -0700472 unsigned table_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +0100473 ALOGV(" table_id = %u", table_id);
David Yeh6456ae72014-09-03 11:14:48 +0800474 if (table_id != 0x02u) {
475 ALOGE("PMT data error!");
476 return ERROR_MALFORMED;
477 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700478 unsigned section_syntax_indicator = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +0100479 ALOGV(" section_syntax_indicator = %u", section_syntax_indicator);
David Yeh6456ae72014-09-03 11:14:48 +0800480 if (section_syntax_indicator != 1u) {
481 ALOGE("PMT data error!");
482 return ERROR_MALFORMED;
483 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700484
Jinsuk Kime314c672015-04-22 11:08:28 +0900485 br->skipBits(1); // '0'
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700486 MY_LOGV(" reserved = %u", br->getBits(2));
Andreas Hubercda17c62010-06-07 13:05:37 -0700487
488 unsigned section_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100489 ALOGV(" section_length = %u", section_length);
Andreas Hubercda17c62010-06-07 13:05:37 -0700490
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700491 MY_LOGV(" program_number = %u", br->getBits(16));
492 MY_LOGV(" reserved = %u", br->getBits(2));
Sampath Shetty142598f2018-12-10 13:52:30 +1100493 bool audioPresentationsChanged = false;
494 unsigned pmtVersion = br->getBits(5);
495 if (pmtVersion != mPMTVersion) {
496 audioPresentationsChanged = true;
497 mPMTVersion = pmtVersion;
498 }
499 MY_LOGV(" version_number = %u", pmtVersion);
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700500 MY_LOGV(" current_next_indicator = %u", br->getBits(1));
501 MY_LOGV(" section_number = %u", br->getBits(8));
502 MY_LOGV(" last_section_number = %u", br->getBits(8));
503 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Huber87f2a552012-08-31 13:55:24 -0700504
505 unsigned PCR_PID = br->getBits(13);
506 ALOGV(" PCR_PID = 0x%04x", PCR_PID);
507
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700508 MY_LOGV(" reserved = %u", br->getBits(4));
Andreas Hubercda17c62010-06-07 13:05:37 -0700509
510 unsigned program_info_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100511 ALOGV(" program_info_length = %u", program_info_length);
Andreas Hubercda17c62010-06-07 13:05:37 -0700512
Chong Zhang3b2847f2017-01-18 17:43:03 -0800513 // descriptors
514 CADescriptor programCA;
515 bool hasProgramCA = findCADescriptor(br, program_info_length, &programCA);
516 if (hasProgramCA && !mParser->mCasManager->addProgram(
517 mProgramNumber, programCA)) {
518 return ERROR_MALFORMED;
519 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700520
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800521 Vector<StreamInfo> infos;
522
Andreas Hubercda17c62010-06-07 13:05:37 -0700523 // infoBytesRemaining is the number of bytes that make up the
524 // variable length section of ES_infos. It does not include the
525 // final CRC.
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800526 int32_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
Andreas Hubercda17c62010-06-07 13:05:37 -0700527
Jinsuk Kime314c672015-04-22 11:08:28 +0900528 while (infoBytesRemaining >= 5) {
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800529 StreamInfo info;
530 info.mType = br->getBits(8);
531 ALOGV(" stream_type = 0x%02x", info.mType);
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700532 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Hubercda17c62010-06-07 13:05:37 -0700533
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800534 info.mPID = br->getBits(13);
535 ALOGV(" elementary_PID = 0x%04x", info.mPID);
Andreas Hubercda17c62010-06-07 13:05:37 -0700536
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700537 MY_LOGV(" reserved = %u", br->getBits(4));
Andreas Hubercda17c62010-06-07 13:05:37 -0700538
539 unsigned ES_info_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100540 ALOGV(" ES_info_length = %u", ES_info_length);
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800541 infoBytesRemaining -= 5 + ES_info_length;
Andreas Hubercda17c62010-06-07 13:05:37 -0700542
Chong Zhang3b2847f2017-01-18 17:43:03 -0800543 CADescriptor streamCA;
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800544 info.mTypeExt = EXT_DESCRIPTOR_DVB_RESERVED_MAX;
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100545
546 info.mAudioPresentations.clear();
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800547 bool hasStreamCA = false;
548 while (ES_info_length > 2 && infoBytesRemaining >= 0) {
549 unsigned descriptor_tag = br->getBits(8);
550 ALOGV(" tag = 0x%02x", descriptor_tag);
551
552 unsigned descriptor_length = br->getBits(8);
553 ALOGV(" len = %u", descriptor_length);
554
555 ES_info_length -= 2;
556 if (descriptor_length > ES_info_length) {
557 return ERROR_MALFORMED;
558 }
Rahul3beba382023-02-03 20:36:55 +0000559
560 // The DTS descriptor is used in the PSI PMT to identify streams which carry
561 // DTS audio(core only). If a DTS descriptor is present, a DTS-HD or DTS-UHD
562 // descriptors shall not be present in the same ES_info descriptor loop.
563 if (descriptor_tag == DESCRIPTOR_DTS) {
564 info.mType = STREAMTYPE_DTS;
565 ES_info_length -= descriptor_length;
566 br->skipBits(descriptor_length * 8);
567 } else if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800568 hasStreamCA = true;
569 streamCA.mSystemID = br->getBits(16);
570 streamCA.mPID = br->getBits(16) & 0x1fff;
Vasily Tarasov7e736a42018-11-01 10:51:08 -0700571 ES_info_length -= descriptor_length;
572 descriptor_length -= 4;
573 streamCA.mPrivateData.assign(br->data(), br->data() + descriptor_length);
574 br->skipBits(descriptor_length * 8);
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800575 } else if (info.mType == STREAMTYPE_PES_PRIVATE_DATA &&
576 descriptor_tag == DESCRIPTOR_DVB_EXTENSION && descriptor_length >= 1) {
577 unsigned descTagExt = br->getBits(8);
578 ALOGV(" tag_ext = 0x%02x", descTagExt);
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800579 ES_info_length -= descriptor_length;
580 descriptor_length--;
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100581 // The AC4 descriptor is used in the PSI PMT to identify streams which carry AC4
582 // audio.
583 if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
584 info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
585 br->skipBits(descriptor_length * 8);
Rahul3beba382023-02-03 20:36:55 +0000586 } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
587 // DTS HD extended descriptor which can accommodate core only formats
588 // as well as extension only and core + extension combinations.
589 info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_HD;
590 br->skipBits(descriptor_length * 8);
591 } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
592 // The DTS-UHD descriptor is used in the PSI PMT to identify streams
593 // which carry DTS-UHD audio
594 info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_UHD;
595 br->skipBits(descriptor_length * 8);
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100596 } else if (descTagExt == EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION &&
597 descriptor_length >= 1) {
598 // DVB BlueBook A038 Table 110
599 unsigned num_preselections = br->getBits(5);
600 br->skipBits(3); // reserved
601 for (unsigned i = 0; i < num_preselections; ++i) {
602 if (br->numBitsLeft() < 16) {
603 ALOGE("Not enough data left in bitreader!");
604 return ERROR_MALFORMED;
605 }
606 AudioPresentationV1 ap;
607 ap.mPresentationId = br->getBits(5); // preselection_id
608
609 // audio_rendering_indication
610 ap.mMasteringIndication = static_cast<MasteringIndication>(br->getBits(3));
611 ap.mAudioDescriptionAvailable = (br->getBits(1) == 1);
612 ap.mSpokenSubtitlesAvailable = (br->getBits(1) == 1);
613 ap.mDialogueEnhancementAvailable = (br->getBits(1) == 1);
614
615 bool interactivity_enabled = (br->getBits(1) == 1);
616 MY_LOGV(" interactivity_enabled = %d", interactivity_enabled);
617
618 bool language_code_present = (br->getBits(1) == 1);
619 bool text_label_present = (br->getBits(1) == 1);
620
621 bool multi_stream_info_present = (br->getBits(1) == 1);
622 bool future_extension = (br->getBits(1) == 1);
623 if (language_code_present) {
624 if (br->numBitsLeft() < 24) {
625 ALOGE("Not enough data left in bitreader!");
626 return ERROR_MALFORMED;
627 }
628 char language[4];
629 language[0] = br->getBits(8);
630 language[1] = br->getBits(8);
631 language[2] = br->getBits(8);
632 language[3] = 0;
633 ap.mLanguage = String8(language);
634 }
635
636 // This maps the presentation id to the message id in the
637 // EXT_DESCRIPTOR_DVB_MESSAGE so that we can get the presentation label.
638 if (text_label_present) {
639 if (br->numBitsLeft() < 8) {
640 ALOGE("Not enough data left in bitreader!");
641 return ERROR_MALFORMED;
642 }
643 unsigned message_id = br->getBits(8);
644 MY_LOGV(" message_id = %u", message_id);
645 }
646
647 if (multi_stream_info_present) {
648 if (br->numBitsLeft() < 8) {
649 ALOGE("Not enough data left in bitreader!");
650 return ERROR_MALFORMED;
651 }
652 unsigned num_aux_components = br->getBits(3);
653 br->skipBits(5); // reserved
654 if (br->numBitsLeft() < (num_aux_components * 8)) {
655 ALOGE("Not enough data left in bitreader!");
656 return ERROR_MALFORMED;
657 }
658 br->skipBits(num_aux_components * 8); // component_tag
659 }
660 if (future_extension) {
661 if (br->numBitsLeft() < 8) {
662 return ERROR_MALFORMED;
663 }
664 br->skipBits(3); // reserved
665 unsigned future_extension_length = br->getBits(5);
666 if (br->numBitsLeft() < (future_extension_length * 8)) {
667 ALOGE("Not enough data left in bitreader!");
668 return ERROR_MALFORMED;
669 }
670 br->skipBits(future_extension_length * 8); // future_extension_byte
671 }
672 info.mAudioPresentations.push_back(std::move(ap));
673 }
674 } else {
675 br->skipBits(descriptor_length * 8);
676 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800677 } else {
678 ES_info_length -= descriptor_length;
679 br->skipBits(descriptor_length * 8);
680 }
681 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800682 if (hasStreamCA && !mParser->mCasManager->addStream(
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800683 mProgramNumber, info.mPID, streamCA)) {
Chong Zhang3b2847f2017-01-18 17:43:03 -0800684 return ERROR_MALFORMED;
Andreas Hubercda17c62010-06-07 13:05:37 -0700685 }
Chong Zhang7e986a82018-11-07 13:01:08 -0800686 if (hasProgramCA) {
687 info.mCADescriptor = programCA;
688 } else if (hasStreamCA) {
689 info.mCADescriptor = streamCA;
690 }
691
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800692 infos.push(info);
Andreas Hubercda17c62010-06-07 13:05:37 -0700693 }
694
Jinsuk Kime314c672015-04-22 11:08:28 +0900695 if (infoBytesRemaining != 0) {
696 ALOGW("Section data remains unconsumed");
697 }
Sampath Shetty142598f2018-12-10 13:52:30 +1100698 unsigned crc = br->getBits(32);
699 if (crc != mPMT_CRC) {
700 audioPresentationsChanged = true;
701 mPMT_CRC = crc;
702 }
703 MY_LOGV(" CRC = 0x%08x", crc);
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800704
705 bool PIDsChanged = false;
706 for (size_t i = 0; i < infos.size(); ++i) {
707 StreamInfo &info = infos.editItemAt(i);
708
709 ssize_t index = mStreams.indexOfKey(info.mPID);
710
711 if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
Steve Blockdf64d152012-01-04 20:05:49 +0000712 ALOGI("uh oh. stream PIDs have changed.");
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800713 PIDsChanged = true;
714 break;
715 }
716 }
717
718 if (PIDsChanged) {
Andreas Huber06528d72011-08-31 16:29:05 -0700719#if 0
Steve Blockdf64d152012-01-04 20:05:49 +0000720 ALOGI("before:");
Andreas Huber06528d72011-08-31 16:29:05 -0700721 for (size_t i = 0; i < mStreams.size(); ++i) {
722 sp<Stream> stream = mStreams.editValueAt(i);
723
Steve Blockdf64d152012-01-04 20:05:49 +0000724 ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type());
Andreas Huber06528d72011-08-31 16:29:05 -0700725 }
726
Steve Blockdf64d152012-01-04 20:05:49 +0000727 ALOGI("after:");
Andreas Huber06528d72011-08-31 16:29:05 -0700728 for (size_t i = 0; i < infos.size(); ++i) {
729 StreamInfo &info = infos.editItemAt(i);
730
Steve Blockdf64d152012-01-04 20:05:49 +0000731 ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType);
Andreas Huber06528d72011-08-31 16:29:05 -0700732 }
733#endif
734
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700735 // we can recover if number of streams for each type remain the same
736 bool success = switchPIDs(infos);
Andreas Huber06528d72011-08-31 16:29:05 -0700737
738 if (!success) {
Steve Blockdf64d152012-01-04 20:05:49 +0000739 ALOGI("Stream PIDs changed and we cannot recover.");
Andreas Huber06528d72011-08-31 16:29:05 -0700740 return ERROR_MALFORMED;
741 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800742 }
743
Chong Zhang3b2847f2017-01-18 17:43:03 -0800744 bool isAddingScrambledStream = false;
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800745 for (size_t i = 0; i < infos.size(); ++i) {
746 StreamInfo &info = infos.editItemAt(i);
747
Chong Zhang3b2847f2017-01-18 17:43:03 -0800748 if (mParser->mCasManager->isCAPid(info.mPID)) {
749 // skip CA streams (EMM/ECM)
750 continue;
751 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800752 ssize_t index = mStreams.indexOfKey(info.mPID);
753
754 if (index < 0) {
Chong Zhang7e986a82018-11-07 13:01:08 -0800755 sp<Stream> stream = new Stream(this, PCR_PID, info);
Andreas Huber87f2a552012-08-31 13:55:24 -0700756
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700757 if (mSampleAesKeyItem != NULL) {
758 stream->signalNewSampleAesKey(mSampleAesKeyItem);
759 }
760
Chong Zhang7e986a82018-11-07 13:01:08 -0800761 isAddingScrambledStream |= info.mCADescriptor.mSystemID >= 0;
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800762 mStreams.add(info.mPID, stream);
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800763 }
Sampath Shetty142598f2018-12-10 13:52:30 +1100764 else if (index >= 0 && mStreams.editValueAt(index)->isAudio()
765 && audioPresentationsChanged) {
766 mStreams.editValueAt(index)->setAudioPresentations(info.mAudioPresentations);
767 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800768 }
Andreas Huber06528d72011-08-31 16:29:05 -0700769
Chong Zhang3b2847f2017-01-18 17:43:03 -0800770 if (isAddingScrambledStream) {
771 ALOGI("Receiving scrambled streams without descrambler!");
772 return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
773 }
Andreas Huber06528d72011-08-31 16:29:05 -0700774 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -0700775}
776
Chong Zhang799c9682015-03-02 23:42:38 -0800777int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
778 // We only have the lower 33-bit of the PTS. It could overflow within a
779 // reasonable amount of time. To handle the wrap-around, use fancy math
780 // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
781 // of the latest recovered PTS.
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800782 if (mLastRecoveredPTS < 0LL) {
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700783 // Use the original 33bit number for 1st frame, the reason is that
784 // if 1st frame wraps to negative that's far away from 0, we could
785 // never start. Only start wrapping around from 2nd frame.
786 mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
787 } else {
788 mLastRecoveredPTS = static_cast<int64_t>(
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800789 ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000LL)
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700790 & 0xfffffffe00000000ull) | PTS_33bit);
791 // We start from 0, but recovered PTS could be slightly below 0.
792 // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
793 // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800794 if (mLastRecoveredPTS < 0LL) {
Chih-Hung Hsieh5c9054b2015-03-12 13:24:12 -0700795 ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS);
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800796 mLastRecoveredPTS = 0LL;
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700797 }
798 }
Chong Zhang799c9682015-03-02 23:42:38 -0800799
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700800 return mLastRecoveredPTS;
Chong Zhang799c9682015-03-02 23:42:38 -0800801}
802
Marco Nelissen45d54c62018-01-26 10:04:22 -0800803sp<AnotherPacketSource> ATSParser::Program::getSource(SourceType type) {
Andreas Hubercda17c62010-06-07 13:05:37 -0700804 for (size_t i = 0; i < mStreams.size(); ++i) {
Marco Nelissen45d54c62018-01-26 10:04:22 -0800805 sp<AnotherPacketSource> source = mStreams.editValueAt(i)->getSource(type);
Andreas Hubercda17c62010-06-07 13:05:37 -0700806 if (source != NULL) {
Robert Shih9ff1e722015-10-20 16:29:58 -0700807 return source;
Andreas Hubercda17c62010-06-07 13:05:37 -0700808 }
809 }
810
811 return NULL;
812}
813
Robert Shihbf207272014-10-30 17:22:11 -0700814bool ATSParser::Program::hasSource(SourceType type) const {
815 for (size_t i = 0; i < mStreams.size(); ++i) {
816 const sp<Stream> &stream = mStreams.valueAt(i);
817 if (type == AUDIO && stream->isAudio()) {
818 return true;
819 } else if (type == VIDEO && stream->isVideo()) {
820 return true;
Robert Shih9ff1e722015-10-20 16:29:58 -0700821 } else if (type == META && stream->isMeta()) {
822 return true;
Robert Shihbf207272014-10-30 17:22:11 -0700823 }
824 }
825
826 return false;
827}
828
Andreas Huberbff07d02010-10-12 11:34:37 -0700829int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
Chong Zhang799c9682015-03-02 23:42:38 -0800830 PTS = recoverPTS(PTS);
831
Andreas Huberc4c17d42011-08-30 16:06:28 -0700832 if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
833 if (!mFirstPTSValid) {
834 mFirstPTSValid = true;
835 mFirstPTS = PTS;
836 PTS = 0;
837 } else if (PTS < mFirstPTS) {
838 PTS = 0;
839 } else {
840 PTS -= mFirstPTS;
841 }
Andreas Huberbff07d02010-10-12 11:34:37 -0700842 }
843
Andreas Huber87f2a552012-08-31 13:55:24 -0700844 int64_t timeUs = (PTS * 100) / 9;
845
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800846 if (mParser->mAbsoluteTimeAnchorUs >= 0LL) {
Andreas Huber87f2a552012-08-31 13:55:24 -0700847 timeUs += mParser->mAbsoluteTimeAnchorUs;
848 }
849
Andreas Huberd5e56232013-03-12 11:01:43 -0700850 if (mParser->mTimeOffsetValid) {
851 timeUs += mParser->mTimeOffsetUs;
852 }
853
Andreas Huber87f2a552012-08-31 13:55:24 -0700854 return timeUs;
Andreas Huberbff07d02010-10-12 11:34:37 -0700855}
856
Chong Zhang3b2847f2017-01-18 17:43:03 -0800857void ATSParser::Program::updateCasSessions() {
858 for (size_t i = 0; i < mStreams.size(); ++i) {
859 sp<Stream> &stream = mStreams.editValueAt(i);
860 sp<IDescrambler> descrambler;
861 std::vector<uint8_t> sessionId;
Chong Zhangbc7aae42017-03-31 14:53:19 -0700862 int32_t systemId;
863 if (mParser->mCasManager->getCasInfo(mProgramNumber, stream->pid(),
864 &systemId, &descrambler, &sessionId)) {
865 stream->setCasInfo(systemId, descrambler, sessionId);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800866 }
867 }
868}
869
Andreas Hubercda17c62010-06-07 13:05:37 -0700870////////////////////////////////////////////////////////////////////////////////
Chong Zhang3b2847f2017-01-18 17:43:03 -0800871static const size_t kInitialStreamBufferSize = 192 * 1024;
Andreas Hubercda17c62010-06-07 13:05:37 -0700872
Andreas Huberbff07d02010-10-12 11:34:37 -0700873ATSParser::Stream::Stream(
Chong Zhang7e986a82018-11-07 13:01:08 -0800874 Program *program, unsigned PCR_PID, const StreamInfo &info)
Andreas Huberbff07d02010-10-12 11:34:37 -0700875 : mProgram(program),
Chong Zhang7e986a82018-11-07 13:01:08 -0800876 mElementaryPID(info.mPID),
877 mStreamType(info.mType),
878 mStreamTypeExt(info.mTypeExt),
Andreas Huber87f2a552012-08-31 13:55:24 -0700879 mPCR_PID(PCR_PID),
880 mExpectedContinuityCounter(-1),
Andreas Huber6a63a932010-10-01 10:51:41 -0700881 mPayloadStarted(false),
Marco Nelissenbe9634d2015-04-15 14:33:39 -0700882 mEOSReached(false),
Andreas Huber90a92052012-10-30 15:53:03 -0700883 mPrevPTS(0),
Chong Zhang3b2847f2017-01-18 17:43:03 -0800884 mQueue(NULL),
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100885 mScrambled(info.mCADescriptor.mSystemID >= 0),
886 mAudioPresentations(info.mAudioPresentations) {
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700887 mSampleEncrypted =
888 mStreamType == STREAMTYPE_H264_ENCRYPTED ||
889 mStreamType == STREAMTYPE_AAC_ENCRYPTED ||
890 mStreamType == STREAMTYPE_AC3_ENCRYPTED;
891
892 ALOGV("new stream PID 0x%02x, type 0x%02x, scrambled %d, SampleEncrypted: %d",
Chong Zhang7e986a82018-11-07 13:01:08 -0800893 info.mPID, info.mType, mScrambled, mSampleEncrypted);
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700894
Chong Zhange32a4132018-07-23 14:17:38 -0700895 uint32_t flags = 0;
896 if (((isVideo() || isAudio()) && mScrambled)) {
897 flags = ElementaryStreamQueue::kFlag_ScrambledData;
898 } else if (mSampleEncrypted) {
899 flags = ElementaryStreamQueue::kFlag_SampleEncryptedData;
900 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800901
902 ElementaryStreamQueue::Mode mode = ElementaryStreamQueue::INVALID;
903
Andreas Huber386d6092011-05-19 08:37:39 -0700904 switch (mStreamType) {
905 case STREAMTYPE_H264:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700906 case STREAMTYPE_H264_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800907 mode = ElementaryStreamQueue::H264;
908 flags |= (mProgram->parserFlags() & ALIGNED_VIDEO_DATA) ?
909 ElementaryStreamQueue::kFlag_AlignedData : 0;
Andreas Huber386d6092011-05-19 08:37:39 -0700910 break;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800911
Andreas Huber6e3d3112011-11-28 12:36:11 -0800912 case STREAMTYPE_MPEG2_AUDIO_ADTS:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700913 case STREAMTYPE_AAC_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800914 mode = ElementaryStreamQueue::AAC;
Andreas Huber386d6092011-05-19 08:37:39 -0700915 break;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800916
Andreas Huber386d6092011-05-19 08:37:39 -0700917 case STREAMTYPE_MPEG1_AUDIO:
918 case STREAMTYPE_MPEG2_AUDIO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800919 mode = ElementaryStreamQueue::MPEG_AUDIO;
Andreas Huber386d6092011-05-19 08:37:39 -0700920 break;
921
922 case STREAMTYPE_MPEG1_VIDEO:
923 case STREAMTYPE_MPEG2_VIDEO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800924 mode = ElementaryStreamQueue::MPEG_VIDEO;
Andreas Huber386d6092011-05-19 08:37:39 -0700925 break;
926
927 case STREAMTYPE_MPEG4_VIDEO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800928 mode = ElementaryStreamQueue::MPEG4_VIDEO;
Andreas Huber386d6092011-05-19 08:37:39 -0700929 break;
930
Chong Zhang9bf32f02014-07-30 15:40:31 -0700931 case STREAMTYPE_LPCM_AC3:
Changwan Ryud3c079a2013-10-28 11:08:44 +0900932 case STREAMTYPE_AC3:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700933 case STREAMTYPE_AC3_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800934 mode = ElementaryStreamQueue::AC3;
Changwan Ryud3c079a2013-10-28 11:08:44 +0900935 break;
936
Previr Rangroo68e6fe12017-11-30 20:02:13 -0800937 case STREAMTYPE_EAC3:
938 mode = ElementaryStreamQueue::EAC3;
939 break;
940
Rahul3beba382023-02-03 20:36:55 +0000941 case STREAMTYPE_DTS:
942 mode = ElementaryStreamQueue::DTS;
943 break;
944
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800945 case STREAMTYPE_PES_PRIVATE_DATA:
946 if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) {
947 mode = ElementaryStreamQueue::AC4;
Rahul3beba382023-02-03 20:36:55 +0000948 } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
949 mode = ElementaryStreamQueue::DTS_HD;
950 } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
951 mode = ElementaryStreamQueue::DTS_UHD;
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800952 }
953 break;
954
Robert Shih08528432015-04-08 09:06:54 -0700955 case STREAMTYPE_METADATA:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800956 mode = ElementaryStreamQueue::METADATA;
Robert Shih08528432015-04-08 09:06:54 -0700957 break;
958
Andreas Huber386d6092011-05-19 08:37:39 -0700959 default:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800960 ALOGE("stream PID 0x%02x has invalid stream type 0x%02x",
Chong Zhang7e986a82018-11-07 13:01:08 -0800961 info.mPID, info.mType);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800962 return;
Andreas Huber386d6092011-05-19 08:37:39 -0700963 }
964
Chong Zhang3b2847f2017-01-18 17:43:03 -0800965 mQueue = new ElementaryStreamQueue(mode, flags);
Andreas Huber18ac5402011-08-31 15:04:25 -0700966
967 if (mQueue != NULL) {
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700968 if (mSampleAesKeyItem != NULL) {
969 mQueue->signalNewSampleAesKey(mSampleAesKeyItem);
970 }
971
Chong Zhang3b2847f2017-01-18 17:43:03 -0800972 ensureBufferCapacity(kInitialStreamBufferSize);
973
974 if (mScrambled && (isAudio() || isVideo())) {
975 // Set initial format to scrambled
976 sp<MetaData> meta = new MetaData();
977 meta->setCString(kKeyMIMEType,
978 isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
979 : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
Chong Zhangbc7aae42017-03-31 14:53:19 -0700980 // for MediaExtractor.CasInfo
Chong Zhang7e986a82018-11-07 13:01:08 -0800981 const CADescriptor &descriptor = info.mCADescriptor;
982 meta->setInt32(kKeyCASystemID, descriptor.mSystemID);
983
984 meta->setData(kKeyCAPrivateData, 0,
985 descriptor.mPrivateData.data(),
986 descriptor.mPrivateData.size());
987
Chong Zhang3b2847f2017-01-18 17:43:03 -0800988 mSource = new AnotherPacketSource(meta);
989 }
Andreas Huber18ac5402011-08-31 15:04:25 -0700990 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700991}
992
993ATSParser::Stream::~Stream() {
Andreas Huber386d6092011-05-19 08:37:39 -0700994 delete mQueue;
995 mQueue = NULL;
Andreas Hubercda17c62010-06-07 13:05:37 -0700996}
997
Chong Zhangd5a416a2017-05-16 11:16:34 -0700998bool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
Chong Zhang3b2847f2017-01-18 17:43:03 -0800999 if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
Chong Zhangd5a416a2017-05-16 11:16:34 -07001000 return true;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001001 }
1002
1003 ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
1004 mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);
1005
1006 sp<ABuffer> newBuffer, newScrambledBuffer;
Chong Zhang00c5c052018-12-17 14:15:58 -08001007 sp<TMemory> newMem;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001008 if (mScrambled) {
Chong Zhang00c5c052018-12-17 14:15:58 -08001009 if (mHidlAllocator == nullptr) {
1010 mHidlAllocator = TAllocator::getService("ashmem");
1011 if (mHidlAllocator == nullptr) {
1012 ALOGE("[stream %d] can't get hidl allocator", mElementaryPID);
1013 return false;
1014 }
1015 }
1016
1017 hidl_memory hidlMemToken;
1018 bool success;
1019 auto transStatus = mHidlAllocator->allocate(
1020 neededSize,
1021 [&success, &hidlMemToken](
1022 bool s,
1023 hidl_memory const& m) {
1024 success = s;
1025 hidlMemToken = m;
1026 });
1027
1028 if (!transStatus.isOk()) {
1029 ALOGE("[stream %d] hidl allocator failed at the transport: %s",
1030 mElementaryPID, transStatus.description().c_str());
1031 return false;
1032 }
1033 if (!success) {
1034 ALOGE("[stream %d] hidl allocator failed", mElementaryPID);
1035 return false;
1036 }
1037 newMem = mapMemory(hidlMemToken);
1038 if (newMem == nullptr || newMem->getPointer() == nullptr) {
1039 ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
1040 return false;
1041 }
1042
1043 newScrambledBuffer = new ABuffer(newMem->getPointer(), newMem->getSize());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001044
1045 if (mDescrambledBuffer != NULL) {
1046 memcpy(newScrambledBuffer->data(),
1047 mDescrambledBuffer->data(), mDescrambledBuffer->size());
1048 newScrambledBuffer->setRange(0, mDescrambledBuffer->size());
1049 } else {
1050 newScrambledBuffer->setRange(0, 0);
1051 }
Chong Zhang00c5c052018-12-17 14:15:58 -08001052 mHidlMemory = newMem;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001053 mDescrambledBuffer = newScrambledBuffer;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001054
Chong Zhang00c5c052018-12-17 14:15:58 -08001055 mDescramblerSrcBuffer.heapBase = hidlMemToken;
1056 mDescramblerSrcBuffer.offset = 0ULL;
1057 mDescramblerSrcBuffer.size = (uint64_t)neededSize;
Chong Zhang58ddee32018-02-13 17:52:39 -08001058
Chong Zhang00c5c052018-12-17 14:15:58 -08001059 ALOGD("[stream %d] created shared buffer for descrambling, size %zu",
1060 mElementaryPID, neededSize);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001061 } else {
1062 // Align to multiples of 64K.
1063 neededSize = (neededSize + 65535) & ~65535;
1064 }
1065
1066 newBuffer = new ABuffer(neededSize);
1067 if (mBuffer != NULL) {
1068 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
1069 newBuffer->setRange(0, mBuffer->size());
1070 } else {
1071 newBuffer->setRange(0, 0);
1072 }
1073 mBuffer = newBuffer;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001074 return true;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001075}
1076
Andreas Huber54031292011-09-01 11:04:43 -07001077status_t ATSParser::Stream::parse(
Andreas Huber87f2a552012-08-31 13:55:24 -07001078 unsigned continuity_counter,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001079 unsigned payload_unit_start_indicator,
1080 unsigned transport_scrambling_control,
1081 unsigned random_access_indicator,
1082 ABitReader *br, SyncEvent *event) {
Andreas Huber18ac5402011-08-31 15:04:25 -07001083 if (mQueue == NULL) {
Andreas Huber54031292011-09-01 11:04:43 -07001084 return OK;
Andreas Huber18ac5402011-08-31 15:04:25 -07001085 }
1086
Andreas Huber87f2a552012-08-31 13:55:24 -07001087 if (mExpectedContinuityCounter >= 0
1088 && (unsigned)mExpectedContinuityCounter != continuity_counter) {
1089 ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
1090
1091 mPayloadStarted = false;
Wei Jia9558f6d2016-03-08 17:31:16 -08001092 mPesStartOffsets.clear();
Andreas Huber87f2a552012-08-31 13:55:24 -07001093 mBuffer->setRange(0, 0);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001094 mSubSamples.clear();
Andreas Huber87f2a552012-08-31 13:55:24 -07001095 mExpectedContinuityCounter = -1;
1096
Andreas Huber94a483b2013-01-29 09:22:16 -08001097#if 0
1098 // Uncomment this if you'd rather see no corruption whatsoever on
1099 // screen and suspend updates until we come across another IDR frame.
1100
1101 if (mStreamType == STREAMTYPE_H264) {
1102 ALOGI("clearing video queue");
1103 mQueue->clear(true /* clearFormat */);
1104 }
1105#endif
1106
Chong Zhang66830852014-06-05 14:44:03 -07001107 if (!payload_unit_start_indicator) {
1108 return OK;
1109 }
Andreas Huber87f2a552012-08-31 13:55:24 -07001110 }
1111
1112 mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f;
1113
Andreas Hubercda17c62010-06-07 13:05:37 -07001114 if (payload_unit_start_indicator) {
Wonsik Kim54000662015-04-13 10:59:06 +09001115 off64_t offset = (event != NULL) ? event->getOffset() : 0;
Andreas Hubercda17c62010-06-07 13:05:37 -07001116 if (mPayloadStarted) {
1117 // Otherwise we run the danger of receiving the trailing bytes
1118 // of a PES packet that we never saw the start of and assuming
1119 // we have a a complete PES packet.
1120
Wonsik Kim54000662015-04-13 10:59:06 +09001121 status_t err = flush(event);
Andreas Huber54031292011-09-01 11:04:43 -07001122
1123 if (err != OK) {
Wonsik Kim65959d32015-06-10 16:17:45 +09001124 ALOGW("Error (%08x) happened while flushing; we simply discard "
1125 "the PES packet and continue.", err);
Andreas Huber54031292011-09-01 11:04:43 -07001126 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001127 }
1128
1129 mPayloadStarted = true;
Wei Jiab08d83e2016-09-30 17:39:30 -07001130 // There should be at most 2 elements in |mPesStartOffsets|.
1131 while (mPesStartOffsets.size() >= 2) {
1132 mPesStartOffsets.erase(mPesStartOffsets.begin());
1133 }
Wei Jia9558f6d2016-03-08 17:31:16 -08001134 mPesStartOffsets.push_back(offset);
Andreas Hubercda17c62010-06-07 13:05:37 -07001135 }
1136
1137 if (!mPayloadStarted) {
Andreas Huber54031292011-09-01 11:04:43 -07001138 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001139 }
1140
1141 size_t payloadSizeBits = br->numBitsLeft();
Jinsuk Kime314c672015-04-22 11:08:28 +09001142 if (payloadSizeBits % 8 != 0u) {
1143 ALOGE("Wrong value");
1144 return BAD_VALUE;
1145 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001146
Andreas Huber3e573222011-03-02 16:18:33 -08001147 size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001148 if (!ensureBufferCapacity(neededSize)) {
1149 return NO_MEMORY;
1150 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001151
1152 memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
1153 mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
Andreas Huber54031292011-09-01 11:04:43 -07001154
Chong Zhang3b2847f2017-01-18 17:43:03 -08001155 if (mScrambled) {
1156 mSubSamples.push_back({payloadSizeBits / 8,
1157 transport_scrambling_control, random_access_indicator});
1158 }
1159
Andreas Huber54031292011-09-01 11:04:43 -07001160 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001161}
1162
Andreas Huber6e3d3112011-11-28 12:36:11 -08001163bool ATSParser::Stream::isVideo() const {
1164 switch (mStreamType) {
1165 case STREAMTYPE_H264:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001166 case STREAMTYPE_H264_ENCRYPTED:
Andreas Huber6e3d3112011-11-28 12:36:11 -08001167 case STREAMTYPE_MPEG1_VIDEO:
1168 case STREAMTYPE_MPEG2_VIDEO:
1169 case STREAMTYPE_MPEG4_VIDEO:
1170 return true;
1171
1172 default:
1173 return false;
1174 }
1175}
1176
1177bool ATSParser::Stream::isAudio() const {
1178 switch (mStreamType) {
1179 case STREAMTYPE_MPEG1_AUDIO:
1180 case STREAMTYPE_MPEG2_AUDIO:
1181 case STREAMTYPE_MPEG2_AUDIO_ADTS:
Chong Zhang9bf32f02014-07-30 15:40:31 -07001182 case STREAMTYPE_LPCM_AC3:
Changwan Ryud3c079a2013-10-28 11:08:44 +09001183 case STREAMTYPE_AC3:
Previr Rangroo68e6fe12017-11-30 20:02:13 -08001184 case STREAMTYPE_EAC3:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001185 case STREAMTYPE_AAC_ENCRYPTED:
1186 case STREAMTYPE_AC3_ENCRYPTED:
Rahul3beba382023-02-03 20:36:55 +00001187 case STREAMTYPE_DTS:
Andreas Huber6e3d3112011-11-28 12:36:11 -08001188 return true;
Previr Rangroo7e6ac732017-11-13 20:20:20 -08001189 case STREAMTYPE_PES_PRIVATE_DATA:
Rahul3beba382023-02-03 20:36:55 +00001190 return (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4
1191 || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD
1192 || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD);
Andreas Huber6e3d3112011-11-28 12:36:11 -08001193
1194 default:
1195 return false;
1196 }
1197}
1198
Robert Shih08528432015-04-08 09:06:54 -07001199bool ATSParser::Stream::isMeta() const {
1200 if (mStreamType == STREAMTYPE_METADATA) {
1201 return true;
1202 }
1203 return false;
1204}
1205
Andreas Huber32f3cef2011-03-02 15:34:46 -08001206void ATSParser::Stream::signalDiscontinuity(
1207 DiscontinuityType type, const sp<AMessage> &extra) {
Marco Nelissen0389cc02012-10-02 10:47:39 -07001208 mExpectedContinuityCounter = -1;
1209
Andreas Huber18ac5402011-08-31 15:04:25 -07001210 if (mQueue == NULL) {
1211 return;
1212 }
1213
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001214 mPayloadStarted = false;
Wei Jia9558f6d2016-03-08 17:31:16 -08001215 mPesStartOffsets.clear();
Robert Shihaabbdc72015-05-08 17:39:40 -07001216 mEOSReached = false;
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001217 mBuffer->setRange(0, 0);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001218 mSubSamples.clear();
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001219
Andreas Huber6e3d3112011-11-28 12:36:11 -08001220 bool clearFormat = false;
1221 if (isAudio()) {
1222 if (type & DISCONTINUITY_AUDIO_FORMAT) {
1223 clearFormat = true;
Andreas Huberf9334412010-12-15 15:17:42 -08001224 }
Andreas Huber6e3d3112011-11-28 12:36:11 -08001225 } else {
1226 if (type & DISCONTINUITY_VIDEO_FORMAT) {
1227 clearFormat = true;
1228 }
1229 }
Andreas Huberf9334412010-12-15 15:17:42 -08001230
Andreas Huber6e3d3112011-11-28 12:36:11 -08001231 mQueue->clear(clearFormat);
1232
1233 if (type & DISCONTINUITY_TIME) {
1234 uint64_t resumeAtPTS;
1235 if (extra != NULL
1236 && extra->findInt64(
Dongwon Kang15d02f82017-12-14 16:32:18 -08001237 kATSParserKeyResumeAtPTS,
Andreas Huber6e3d3112011-11-28 12:36:11 -08001238 (int64_t *)&resumeAtPTS)) {
1239 int64_t resumeAtMediaTimeUs =
1240 mProgram->convertPTSToTimestamp(resumeAtPTS);
1241
Wei Jiac6cfd702014-11-11 16:33:20 -08001242 extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs);
Andreas Huber6e3d3112011-11-28 12:36:11 -08001243 }
1244 }
1245
1246 if (mSource != NULL) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001247 sp<MetaData> meta = mSource->getFormat();
1248 const char* mime;
1249 if (clearFormat && meta != NULL && meta->findCString(kKeyMIMEType, &mime)
1250 && (!strncasecmp(mime, MEDIA_MIMETYPE_AUDIO_SCRAMBLED, 15)
1251 || !strncasecmp(mime, MEDIA_MIMETYPE_VIDEO_SCRAMBLED, 15))){
1252 mSource->clear();
1253 } else {
1254 mSource->queueDiscontinuity(type, extra, true);
1255 }
Andreas Huberf9334412010-12-15 15:17:42 -08001256 }
1257}
1258
1259void ATSParser::Stream::signalEOS(status_t finalResult) {
1260 if (mSource != NULL) {
1261 mSource->signalEOS(finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001262 }
Marco Nelissenbe9634d2015-04-15 14:33:39 -07001263 mEOSReached = true;
Wonsik Kim54000662015-04-13 10:59:06 +09001264 flush(NULL);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001265}
1266
Wonsik Kim54000662015-04-13 10:59:06 +09001267status_t ATSParser::Stream::parsePES(ABitReader *br, SyncEvent *event) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001268 const uint8_t *basePtr = br->data();
1269
Andreas Hubercda17c62010-06-07 13:05:37 -07001270 unsigned packet_startcode_prefix = br->getBits(24);
1271
Steve Block3856b092011-10-20 11:56:00 +01001272 ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
Andreas Hubercda17c62010-06-07 13:05:37 -07001273
Andreas Huber386d6092011-05-19 08:37:39 -07001274 if (packet_startcode_prefix != 1) {
Steve Block3856b092011-10-20 11:56:00 +01001275 ALOGV("Supposedly payload_unit_start=1 unit does not start "
Andreas Huber386d6092011-05-19 08:37:39 -07001276 "with startcode.");
Andreas Huber54031292011-09-01 11:04:43 -07001277
1278 return ERROR_MALFORMED;
Andreas Huber386d6092011-05-19 08:37:39 -07001279 }
1280
Andreas Hubercda17c62010-06-07 13:05:37 -07001281 unsigned stream_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01001282 ALOGV("stream_id = 0x%02x", stream_id);
Andreas Hubercda17c62010-06-07 13:05:37 -07001283
1284 unsigned PES_packet_length = br->getBits(16);
Steve Block3856b092011-10-20 11:56:00 +01001285 ALOGV("PES_packet_length = %u", PES_packet_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07001286
1287 if (stream_id != 0xbc // program_stream_map
1288 && stream_id != 0xbe // padding_stream
1289 && stream_id != 0xbf // private_stream_2
1290 && stream_id != 0xf0 // ECM
1291 && stream_id != 0xf1 // EMM
1292 && stream_id != 0xff // program_stream_directory
1293 && stream_id != 0xf2 // DSMCC
1294 && stream_id != 0xf8) { // H.222.1 type E
Jinsuk Kime314c672015-04-22 11:08:28 +09001295 if (br->getBits(2) != 2u) {
1296 return ERROR_MALFORMED;
1297 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001298
Chong Zhang3b2847f2017-01-18 17:43:03 -08001299 unsigned PES_scrambling_control = br->getBits(2);
1300 ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
1301
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001302 MY_LOGV("PES_priority = %u", br->getBits(1));
1303 MY_LOGV("data_alignment_indicator = %u", br->getBits(1));
1304 MY_LOGV("copyright = %u", br->getBits(1));
1305 MY_LOGV("original_or_copy = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07001306
1307 unsigned PTS_DTS_flags = br->getBits(2);
Steve Block3856b092011-10-20 11:56:00 +01001308 ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags);
Andreas Hubercda17c62010-06-07 13:05:37 -07001309
1310 unsigned ESCR_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001311 ALOGV("ESCR_flag = %u", ESCR_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001312
1313 unsigned ES_rate_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001314 ALOGV("ES_rate_flag = %u", ES_rate_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001315
1316 unsigned DSM_trick_mode_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001317 ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001318
1319 unsigned additional_copy_info_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001320 ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001321
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001322 MY_LOGV("PES_CRC_flag = %u", br->getBits(1));
1323 MY_LOGV("PES_extension_flag = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07001324
1325 unsigned PES_header_data_length = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01001326 ALOGV("PES_header_data_length = %u", PES_header_data_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07001327
1328 unsigned optional_bytes_remaining = PES_header_data_length;
1329
1330 uint64_t PTS = 0, DTS = 0;
1331
1332 if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001333 if (optional_bytes_remaining < 5u) {
1334 return ERROR_MALFORMED;
1335 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001336
David Yeh6456ae72014-09-03 11:14:48 +08001337 if (br->getBits(4) != PTS_DTS_flags) {
David Yeh6456ae72014-09-03 11:14:48 +08001338 return ERROR_MALFORMED;
1339 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001340 PTS = ((uint64_t)br->getBits(3)) << 30;
Jinsuk Kime314c672015-04-22 11:08:28 +09001341 if (br->getBits(1) != 1u) {
1342 return ERROR_MALFORMED;
1343 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001344 PTS |= ((uint64_t)br->getBits(15)) << 15;
Jinsuk Kime314c672015-04-22 11:08:28 +09001345 if (br->getBits(1) != 1u) {
1346 return ERROR_MALFORMED;
1347 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001348 PTS |= br->getBits(15);
Jinsuk Kime314c672015-04-22 11:08:28 +09001349 if (br->getBits(1) != 1u) {
1350 return ERROR_MALFORMED;
1351 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001352
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001353 ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);
Andreas Hubercda17c62010-06-07 13:05:37 -07001354
1355 optional_bytes_remaining -= 5;
1356
1357 if (PTS_DTS_flags == 3) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001358 if (optional_bytes_remaining < 5u) {
1359 return ERROR_MALFORMED;
1360 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001361
Jinsuk Kime314c672015-04-22 11:08:28 +09001362 if (br->getBits(4) != 1u) {
1363 return ERROR_MALFORMED;
1364 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001365
1366 DTS = ((uint64_t)br->getBits(3)) << 30;
Jinsuk Kime314c672015-04-22 11:08:28 +09001367 if (br->getBits(1) != 1u) {
1368 return ERROR_MALFORMED;
1369 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001370 DTS |= ((uint64_t)br->getBits(15)) << 15;
Jinsuk Kime314c672015-04-22 11:08:28 +09001371 if (br->getBits(1) != 1u) {
1372 return ERROR_MALFORMED;
1373 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001374 DTS |= br->getBits(15);
Jinsuk Kime314c672015-04-22 11:08:28 +09001375 if (br->getBits(1) != 1u) {
1376 return ERROR_MALFORMED;
1377 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001378
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001379 ALOGV("DTS = %" PRIu64, DTS);
Andreas Hubercda17c62010-06-07 13:05:37 -07001380
1381 optional_bytes_remaining -= 5;
1382 }
1383 }
1384
1385 if (ESCR_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001386 if (optional_bytes_remaining < 6u) {
1387 return ERROR_MALFORMED;
1388 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001389
1390 br->getBits(2);
1391
1392 uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
Jinsuk Kime314c672015-04-22 11:08:28 +09001393 if (br->getBits(1) != 1u) {
1394 return ERROR_MALFORMED;
1395 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001396 ESCR |= ((uint64_t)br->getBits(15)) << 15;
Jinsuk Kime314c672015-04-22 11:08:28 +09001397 if (br->getBits(1) != 1u) {
1398 return ERROR_MALFORMED;
1399 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001400 ESCR |= br->getBits(15);
Jinsuk Kime314c672015-04-22 11:08:28 +09001401 if (br->getBits(1) != 1u) {
1402 return ERROR_MALFORMED;
1403 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001404
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001405 ALOGV("ESCR = %" PRIu64, ESCR);
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001406 MY_LOGV("ESCR_extension = %u", br->getBits(9));
Andreas Hubercda17c62010-06-07 13:05:37 -07001407
Jinsuk Kime314c672015-04-22 11:08:28 +09001408 if (br->getBits(1) != 1u) {
1409 return ERROR_MALFORMED;
1410 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001411
1412 optional_bytes_remaining -= 6;
1413 }
1414
1415 if (ES_rate_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001416 if (optional_bytes_remaining < 3u) {
1417 return ERROR_MALFORMED;
1418 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001419
Jinsuk Kime314c672015-04-22 11:08:28 +09001420 if (br->getBits(1) != 1u) {
1421 return ERROR_MALFORMED;
1422 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001423 MY_LOGV("ES_rate = %u", br->getBits(22));
Jinsuk Kime314c672015-04-22 11:08:28 +09001424 if (br->getBits(1) != 1u) {
1425 return ERROR_MALFORMED;
1426 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001427
1428 optional_bytes_remaining -= 3;
1429 }
1430
1431 br->skipBits(optional_bytes_remaining * 8);
1432
1433 // ES data follows.
Chong Zhang3b2847f2017-01-18 17:43:03 -08001434 int32_t pesOffset = br->data() - basePtr;
Andreas Hubercda17c62010-06-07 13:05:37 -07001435
Andreas Hubercda17c62010-06-07 13:05:37 -07001436 if (PES_packet_length != 0) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001437 if (PES_packet_length < PES_header_data_length + 3) {
1438 return ERROR_MALFORMED;
1439 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001440
1441 unsigned dataLength =
1442 PES_packet_length - 3 - PES_header_data_length;
1443
Andreas Huber54031292011-09-01 11:04:43 -07001444 if (br->numBitsLeft() < dataLength * 8) {
Steve Block29357bc2012-01-06 19:20:56 +00001445 ALOGE("PES packet does not carry enough data to contain "
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001446 "payload. (numBitsLeft = %zu, required = %u)",
Andreas Huber54031292011-09-01 11:04:43 -07001447 br->numBitsLeft(), dataLength * 8);
1448
1449 return ERROR_MALFORMED;
1450 }
1451
Chong Zhang3b2847f2017-01-18 17:43:03 -08001452 ALOGV("There's %u bytes of payload, PES_packet_length=%u, offset=%d",
1453 dataLength, PES_packet_length, pesOffset);
1454
Andreas Huber0da4dab2010-09-27 12:04:43 -07001455 onPayloadData(
Chong Zhang3b2847f2017-01-18 17:43:03 -08001456 PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
1457 br->data(), dataLength, pesOffset, event);
Andreas Hubercda17c62010-06-07 13:05:37 -07001458
1459 br->skipBits(dataLength * 8);
1460 } else {
Andreas Huber0da4dab2010-09-27 12:04:43 -07001461 onPayloadData(
Chong Zhang3b2847f2017-01-18 17:43:03 -08001462 PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
1463 br->data(), br->numBitsLeft() / 8, pesOffset, event);
Andreas Huber0da4dab2010-09-27 12:04:43 -07001464
Andreas Hubercda17c62010-06-07 13:05:37 -07001465 size_t payloadSizeBits = br->numBitsLeft();
Jinsuk Kime314c672015-04-22 11:08:28 +09001466 if (payloadSizeBits % 8 != 0u) {
1467 return ERROR_MALFORMED;
1468 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001469
Chong Zhang3b2847f2017-01-18 17:43:03 -08001470 ALOGV("There's %zu bytes of payload, offset=%d",
1471 payloadSizeBits / 8, pesOffset);
Andreas Hubercda17c62010-06-07 13:05:37 -07001472 }
1473 } else if (stream_id == 0xbe) { // padding_stream
Jinsuk Kime314c672015-04-22 11:08:28 +09001474 if (PES_packet_length == 0u) {
1475 return ERROR_MALFORMED;
1476 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001477 br->skipBits(PES_packet_length * 8);
1478 } else {
Jinsuk Kime314c672015-04-22 11:08:28 +09001479 if (PES_packet_length == 0u) {
1480 return ERROR_MALFORMED;
1481 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001482 br->skipBits(PES_packet_length * 8);
1483 }
Andreas Huber54031292011-09-01 11:04:43 -07001484
1485 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001486}
1487
Chong Zhang3b2847f2017-01-18 17:43:03 -08001488uint32_t ATSParser::Stream::getPesScramblingControl(
1489 ABitReader *br, int32_t *pesOffset) {
1490 unsigned packet_startcode_prefix = br->getBits(24);
1491
1492 ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
1493
1494 if (packet_startcode_prefix != 1) {
1495 ALOGV("unit does not start with startcode.");
1496 return 0;
1497 }
1498
1499 if (br->numBitsLeft() < 48) {
1500 return 0;
1501 }
1502
1503 unsigned stream_id = br->getBits(8);
1504 ALOGV("stream_id = 0x%02x", stream_id);
1505
1506 br->skipBits(16); // PES_packet_length
1507
1508 if (stream_id != 0xbc // program_stream_map
1509 && stream_id != 0xbe // padding_stream
1510 && stream_id != 0xbf // private_stream_2
1511 && stream_id != 0xf0 // ECM
1512 && stream_id != 0xf1 // EMM
1513 && stream_id != 0xff // program_stream_directory
1514 && stream_id != 0xf2 // DSMCC
1515 && stream_id != 0xf8) { // H.222.1 type E
1516 if (br->getBits(2) != 2u) {
1517 return 0;
1518 }
1519
1520 unsigned PES_scrambling_control = br->getBits(2);
1521 ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
1522
1523 if (PES_scrambling_control == 0) {
1524 return 0;
1525 }
1526
1527 br->skipBits(12); // don't care
1528
1529 unsigned PES_header_data_length = br->getBits(8);
1530 ALOGV("PES_header_data_length = %u", PES_header_data_length);
1531
1532 if (PES_header_data_length * 8 > br->numBitsLeft()) {
1533 return 0;
1534 }
1535
1536 *pesOffset = 9 + PES_header_data_length;
1537 ALOGD("found PES_scrambling_control=%d, PES offset=%d",
1538 PES_scrambling_control, *pesOffset);
1539 return PES_scrambling_control;
1540 }
1541
1542 return 0;
1543}
1544
1545status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
1546 if (mDescrambler == NULL) {
1547 ALOGE("received scrambled packets without descrambler!");
1548 return UNKNOWN_ERROR;
1549 }
1550
Chong Zhang00c5c052018-12-17 14:15:58 -08001551 if (mDescrambledBuffer == NULL || mHidlMemory == NULL) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001552 ALOGE("received scrambled packets without shared memory!");
1553
1554 return UNKNOWN_ERROR;
1555 }
1556
1557 int32_t pesOffset = 0;
1558 int32_t descrambleSubSamples = 0, descrambleBytes = 0;
1559 uint32_t tsScramblingControl = 0, pesScramblingControl = 0;
1560
1561 // First, go over subsamples to find TS-level scrambling key id, and
1562 // calculate how many subsample we need to descramble (assuming we don't
1563 // have PES-level scrambling).
1564 for (auto it = mSubSamples.begin(); it != mSubSamples.end(); it++) {
1565 if (it->transport_scrambling_mode != 0) {
1566 // TODO: handle keyId change, use the first non-zero keyId for now.
1567 if (tsScramblingControl == 0) {
1568 tsScramblingControl = it->transport_scrambling_mode;
1569 }
1570 }
1571 if (tsScramblingControl == 0 || descrambleSubSamples == 0
1572 || !mQueue->isScrambled()) {
1573 descrambleSubSamples++;
1574 descrambleBytes += it->subSampleSize;
1575 }
1576 }
1577 // If not scrambled at TS-level, check PES-level scrambling
1578 if (tsScramblingControl == 0) {
1579 ABitReader br(mBuffer->data(), mBuffer->size());
1580 pesScramblingControl = getPesScramblingControl(&br, &pesOffset);
1581 // If not scrambled at PES-level either, or scrambled at PES-level but
1582 // requires output to remain scrambled, we don't need to descramble
1583 // anything.
1584 if (pesScramblingControl == 0 || mQueue->isScrambled()) {
1585 descrambleSubSamples = 0;
1586 descrambleBytes = 0;
1587 }
1588 }
1589
1590 uint32_t sctrl = tsScramblingControl != 0 ?
1591 tsScramblingControl : pesScramblingControl;
Chong Zhangd1af6412018-02-20 10:59:37 -08001592 if (mQueue->isScrambled()) {
1593 sctrl |= DescramblerPlugin::kScrambling_Flag_PesHeader;
1594 }
Chong Zhang3b2847f2017-01-18 17:43:03 -08001595
1596 // Perform the 1st pass descrambling if needed
1597 if (descrambleBytes > 0) {
1598 memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001599 mDescrambledBuffer->setRange(0, mBuffer->size());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001600
Chong Zhangd5a416a2017-05-16 11:16:34 -07001601 hidl_vec<SubSample> subSamples;
1602 subSamples.resize(descrambleSubSamples);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001603
1604 int32_t i = 0;
1605 for (auto it = mSubSamples.begin();
1606 it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
1607 if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
Chong Zhangd5a416a2017-05-16 11:16:34 -07001608 subSamples[i].numBytesOfClearData = 0;
1609 subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001610 } else {
Chong Zhangd5a416a2017-05-16 11:16:34 -07001611 subSamples[i].numBytesOfClearData = it->subSampleSize;
1612 subSamples[i].numBytesOfEncryptedData = 0;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001613 }
1614 }
Chong Zhangd5a416a2017-05-16 11:16:34 -07001615
Chong Zhangb2451bb2018-07-12 12:19:12 -07001616 // If scrambled at PES-level, PES header is in the clear
Chong Zhang3b2847f2017-01-18 17:43:03 -08001617 if (pesScramblingControl != 0) {
Chong Zhangb2451bb2018-07-12 12:19:12 -07001618 subSamples[0].numBytesOfClearData = pesOffset;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001619 subSamples[0].numBytesOfEncryptedData -= pesOffset;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001620 }
1621
Chong Zhangd5a416a2017-05-16 11:16:34 -07001622 Status status = Status::OK;
1623 uint32_t bytesWritten = 0;
1624 hidl_string detailedError;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001625
Chong Zhangd5a416a2017-05-16 11:16:34 -07001626 DestinationBuffer dstBuffer;
1627 dstBuffer.type = BufferType::SHARED_MEMORY;
1628 dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;
1629
1630 auto returnVoid = mDescrambler->descramble(
1631 (ScramblingControl) sctrl,
1632 subSamples,
1633 mDescramblerSrcBuffer,
Chong Zhangb2451bb2018-07-12 12:19:12 -07001634 0 /*srcOffset*/,
Chong Zhangd5a416a2017-05-16 11:16:34 -07001635 dstBuffer,
Chong Zhangb2451bb2018-07-12 12:19:12 -07001636 0 /*dstOffset*/,
Chong Zhangd5a416a2017-05-16 11:16:34 -07001637 [&status, &bytesWritten, &detailedError] (
1638 Status _status, uint32_t _bytesWritten,
1639 const hidl_string& _detailedError) {
1640 status = _status;
1641 bytesWritten = _bytesWritten;
1642 detailedError = _detailedError;
1643 });
1644
Chong Zhangf03d9352019-01-04 11:24:47 -08001645 if (!returnVoid.isOk() || status != Status::OK) {
1646 ALOGE("[stream %d] descramble failed, trans=%s, status=%d",
1647 mElementaryPID, returnVoid.description().c_str(), status);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001648 return UNKNOWN_ERROR;
1649 }
1650
1651 ALOGV("[stream %d] descramble succeeded, %d bytes",
Chong Zhangd5a416a2017-05-16 11:16:34 -07001652 mElementaryPID, bytesWritten);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001653
1654 // Set descrambleBytes to the returned result.
1655 // Note that this might be smaller than the total length of input data.
1656 // (eg. when we're descrambling the PES header portion of a secure stream,
1657 // the plugin might cut it off right after the PES header.)
1658 descrambleBytes = bytesWritten;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001659 }
1660
Chong Zhange32a4132018-07-23 14:17:38 -07001661 // |buffer| points to the buffer from which we'd parse the PES header.
1662 // When the output stream is scrambled, it points to mDescrambledBuffer
1663 // (unless all packets in this PES are actually clear, in which case,
1664 // it points to mBuffer since we never copied into mDescrambledBuffer).
1665 // When the output stream is clear, it points to mBuffer, and we'll
1666 // copy all descrambled data back to mBuffer.
1667 sp<ABuffer> buffer = mBuffer;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001668 if (mQueue->isScrambled()) {
1669 // Queue subSample info for scrambled queue
1670 sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
1671 sp<ABuffer> encSizesBuffer = new ABuffer(mSubSamples.size() * 4);
1672 int32_t *clearSizePtr = (int32_t*)clearSizesBuffer->data();
1673 int32_t *encSizePtr = (int32_t*)encSizesBuffer->data();
1674 int32_t isSync = 0;
1675 int32_t i = 0;
1676 for (auto it = mSubSamples.begin();
1677 it != mSubSamples.end(); it++, i++) {
1678 if ((it->transport_scrambling_mode == 0
Chong Zhangb2451bb2018-07-12 12:19:12 -07001679 && pesScramblingControl == 0)) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001680 clearSizePtr[i] = it->subSampleSize;
1681 encSizePtr[i] = 0;
1682 } else {
1683 clearSizePtr[i] = 0;
1684 encSizePtr[i] = it->subSampleSize;
1685 }
1686 isSync |= it->random_access_indicator;
1687 }
Chong Zhangb2451bb2018-07-12 12:19:12 -07001688
1689 // If scrambled at PES-level, PES header is in the clear
1690 if (pesScramblingControl != 0) {
1691 clearSizePtr[0] = pesOffset;
1692 encSizePtr[0] -= pesOffset;
1693 }
Chong Zhang3b2847f2017-01-18 17:43:03 -08001694 // Pass the original TS subsample size now. The PES header adjust
1695 // will be applied when the scrambled AU is dequeued.
Chong Zhange32a4132018-07-23 14:17:38 -07001696 // Note that if descrambleBytes is 0, it means this PES contains only
1697 // all ts packets, leadingClearBytes is entire buffer size.
Chong Zhang3b2847f2017-01-18 17:43:03 -08001698 mQueue->appendScrambledData(
Chong Zhange32a4132018-07-23 14:17:38 -07001699 mBuffer->data(), mBuffer->size(),
1700 (descrambleBytes > 0) ? descrambleBytes : mBuffer->size(),
1701 sctrl, isSync, clearSizesBuffer, encSizesBuffer);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001702
Chong Zhange32a4132018-07-23 14:17:38 -07001703 if (descrambleBytes > 0) {
1704 buffer = mDescrambledBuffer;
1705 }
Chong Zhangb2451bb2018-07-12 12:19:12 -07001706 } else {
1707 memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001708 }
1709
Chong Zhangb2451bb2018-07-12 12:19:12 -07001710 ABitReader br(buffer->data(), buffer->size());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001711 status_t err = parsePES(&br, event);
1712
1713 if (err != OK) {
1714 ALOGE("[stream %d] failed to parse descrambled PES, err=%d",
1715 mElementaryPID, err);
1716 }
1717
1718 return err;
1719}
1720
1721
Wonsik Kim54000662015-04-13 10:59:06 +09001722status_t ATSParser::Stream::flush(SyncEvent *event) {
Jaesung Chungf2cecd52015-05-21 14:23:07 +09001723 if (mBuffer == NULL || mBuffer->size() == 0) {
Andreas Huber54031292011-09-01 11:04:43 -07001724 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001725 }
1726
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001727 ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size());
Andreas Hubercda17c62010-06-07 13:05:37 -07001728
Chong Zhang3b2847f2017-01-18 17:43:03 -08001729 status_t err = OK;
1730 if (mScrambled) {
1731 err = flushScrambled(event);
1732 mSubSamples.clear();
1733 } else {
1734 ABitReader br(mBuffer->data(), mBuffer->size());
1735 err = parsePES(&br, event);
1736 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001737
1738 mBuffer->setRange(0, 0);
Andreas Huber54031292011-09-01 11:04:43 -07001739
1740 return err;
Andreas Hubercda17c62010-06-07 13:05:37 -07001741}
1742
Sampath Shettyc6148a62018-12-18 15:50:43 +11001743void ATSParser::Stream::addAudioPresentations(const sp<ABuffer> &buffer) {
1744 std::ostringstream outStream(std::ios::out);
1745 serializeAudioPresentations(mAudioPresentations, &outStream);
1746 sp<ABuffer> ap = ABuffer::CreateAsCopy(outStream.str().data(), outStream.str().size());
1747 buffer->meta()->setBuffer("audio-presentation-info", ap);
1748}
1749
Andreas Hubercda17c62010-06-07 13:05:37 -07001750void ATSParser::Stream::onPayloadData(
Andreas Huber84333e02014-02-07 15:36:10 -08001751 unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001752 unsigned PES_scrambling_control,
1753 const uint8_t *data, size_t size,
1754 int32_t payloadOffset, SyncEvent *event) {
Andreas Huber90a92052012-10-30 15:53:03 -07001755#if 0
1756 ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
1757 mStreamType,
1758 PTS,
1759 (int64_t)PTS - mPrevPTS);
1760 mPrevPTS = PTS;
1761#endif
1762
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001763 ALOGV("onPayloadData mStreamType=0x%02x size: %zu", mStreamType, size);
Andreas Hubercda17c62010-06-07 13:05:37 -07001764
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001765 int64_t timeUs = 0LL; // no presentation timestamp available.
Andreas Huber98a46cf2011-10-12 12:14:23 -07001766 if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
1767 timeUs = mProgram->convertPTSToTimestamp(PTS);
1768 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001769
Chong Zhang3b2847f2017-01-18 17:43:03 -08001770 status_t err = mQueue->appendData(
1771 data, size, timeUs, payloadOffset, PES_scrambling_control);
Andreas Huberdecd9692010-12-02 13:27:47 -08001772
Marco Nelissenbe9634d2015-04-15 14:33:39 -07001773 if (mEOSReached) {
1774 mQueue->signalEOS();
1775 }
1776
Andreas Huberdecd9692010-12-02 13:27:47 -08001777 if (err != OK) {
1778 return;
1779 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001780
Andreas Huber6a63a932010-10-01 10:51:41 -07001781 sp<ABuffer> accessUnit;
Wonsik Kim54000662015-04-13 10:59:06 +09001782 bool found = false;
Andreas Huber386d6092011-05-19 08:37:39 -07001783 while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
Andreas Huber6a63a932010-10-01 10:51:41 -07001784 if (mSource == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07001785 sp<MetaData> meta = mQueue->getFormat();
Andreas Hubercda17c62010-06-07 13:05:37 -07001786
Andreas Huber6a63a932010-10-01 10:51:41 -07001787 if (meta != NULL) {
Steve Block3856b092011-10-20 11:56:00 +01001788 ALOGV("Stream PID 0x%08x of type 0x%02x now has data.",
Andreas Huber386d6092011-05-19 08:37:39 -07001789 mElementaryPID, mStreamType);
1790
Robert Shih309aa8b2014-07-29 18:34:36 -07001791 const char *mime;
1792 if (meta->findCString(kKeyMIMEType, &mime)
Chong Zhang3b2847f2017-01-18 17:43:03 -08001793 && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1794 int32_t sync = 0;
1795 if (!accessUnit->meta()->findInt32("isSync", &sync) || !sync) {
1796 continue;
1797 }
Robert Shih309aa8b2014-07-29 18:34:36 -07001798 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001799 mSource = new AnotherPacketSource(meta);
Sampath Shettyc6148a62018-12-18 15:50:43 +11001800 if (mAudioPresentations.size() > 0) {
1801 addAudioPresentations(accessUnit);
1802 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001803 mSource->queueAccessUnit(accessUnit);
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001804 ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
1805 mElementaryPID, mStreamType);
Andreas Huber82f73212010-09-01 12:22:36 -07001806 }
Andreas Huber386d6092011-05-19 08:37:39 -07001807 } else if (mQueue->getFormat() != NULL) {
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001808 // After a discontinuity we invalidate the queue's format
1809 // and won't enqueue any access units to the source until
1810 // the queue has reestablished the new format.
Andreas Huber5bc087c2010-12-23 10:27:40 -08001811
1812 if (mSource->getFormat() == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07001813 mSource->setFormat(mQueue->getFormat());
Andreas Huber5bc087c2010-12-23 10:27:40 -08001814 }
Sampath Shettyc6148a62018-12-18 15:50:43 +11001815 if (mAudioPresentations.size() > 0) {
1816 addAudioPresentations(accessUnit);
1817 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001818 mSource->queueAccessUnit(accessUnit);
Andreas Huber82f73212010-09-01 12:22:36 -07001819 }
Wonsik Kim54000662015-04-13 10:59:06 +09001820
Wei Jiab08d83e2016-09-30 17:39:30 -07001821 // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
1822 off64_t pesStartOffset = -1;
1823 if (!mPesStartOffsets.empty()) {
1824 pesStartOffset = *mPesStartOffsets.begin();
1825 mPesStartOffsets.erase(mPesStartOffsets.begin());
1826 }
1827
1828 if (pesStartOffset >= 0 && (event != NULL) && !found && mQueue->getFormat() != NULL) {
Wonsik Kim54000662015-04-13 10:59:06 +09001829 int32_t sync = 0;
1830 if (accessUnit->meta()->findInt32("isSync", &sync) && sync) {
1831 int64_t timeUs;
1832 if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
1833 found = true;
Robert Shih82e14702016-11-17 11:24:29 -08001834 event->init(pesStartOffset, mSource, timeUs, getSourceType());
Wonsik Kim54000662015-04-13 10:59:06 +09001835 }
1836 }
1837 }
Andreas Huber82f73212010-09-01 12:22:36 -07001838 }
Andreas Huber82f73212010-09-01 12:22:36 -07001839}
1840
Robert Shih82e14702016-11-17 11:24:29 -08001841ATSParser::SourceType ATSParser::Stream::getSourceType() {
1842 if (isVideo()) {
1843 return VIDEO;
1844 } else if (isAudio()) {
1845 return AUDIO;
1846 } else if (isMeta()) {
1847 return META;
1848 }
1849 return NUM_SOURCE_TYPES;
1850}
1851
Marco Nelissen45d54c62018-01-26 10:04:22 -08001852sp<AnotherPacketSource> ATSParser::Stream::getSource(SourceType type) {
Andreas Huber386d6092011-05-19 08:37:39 -07001853 switch (type) {
1854 case VIDEO:
1855 {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001856 if (isVideo()) {
Andreas Huber386d6092011-05-19 08:37:39 -07001857 return mSource;
1858 }
1859 break;
1860 }
1861
1862 case AUDIO:
1863 {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001864 if (isAudio()) {
Andreas Huber386d6092011-05-19 08:37:39 -07001865 return mSource;
1866 }
1867 break;
1868 }
1869
Robert Shih08528432015-04-08 09:06:54 -07001870 case META:
1871 {
1872 if (isMeta()) {
1873 return mSource;
1874 }
1875 break;
1876 }
1877
Andreas Huber386d6092011-05-19 08:37:39 -07001878 default:
1879 break;
Andreas Hubercda17c62010-06-07 13:05:37 -07001880 }
1881
1882 return NULL;
1883}
1884
Chong Zhangbc7aae42017-03-31 14:53:19 -07001885void ATSParser::Stream::setCasInfo(
1886 int32_t systemId, const sp<IDescrambler> &descrambler,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001887 const std::vector<uint8_t> &sessionId) {
1888 if (mSource != NULL && mDescrambler == NULL && descrambler != NULL) {
1889 signalDiscontinuity(DISCONTINUITY_FORMAT_ONLY, NULL);
1890 mDescrambler = descrambler;
1891 if (mQueue->isScrambled()) {
Chong Zhangbc7aae42017-03-31 14:53:19 -07001892 mQueue->setCasInfo(systemId, sessionId);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001893 }
1894 }
1895}
1896
Andreas Hubercda17c62010-06-07 13:05:37 -07001897////////////////////////////////////////////////////////////////////////////////
1898
Andreas Huberc4c17d42011-08-30 16:06:28 -07001899ATSParser::ATSParser(uint32_t flags)
Andreas Huber87f2a552012-08-31 13:55:24 -07001900 : mFlags(flags),
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001901 mAbsoluteTimeAnchorUs(-1LL),
Andreas Huberd5e56232013-03-12 11:01:43 -07001902 mTimeOffsetValid(false),
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001903 mTimeOffsetUs(0LL),
1904 mLastRecoveredPTS(-1LL),
Andreas Huber87f2a552012-08-31 13:55:24 -07001905 mNumTSPacketsParsed(0),
1906 mNumPCRs(0) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07001907 mPSISections.add(0 /* PID */, new PSISection);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001908 mCasManager = new CasManager();
Andreas Hubercda17c62010-06-07 13:05:37 -07001909}
1910
1911ATSParser::~ATSParser() {
1912}
1913
Wonsik Kim54000662015-04-13 10:59:06 +09001914status_t ATSParser::feedTSPacket(const void *data, size_t size,
1915 SyncEvent *event) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001916 if (size != kTSPacketSize) {
1917 ALOGE("Wrong TS packet size");
1918 return BAD_VALUE;
1919 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001920
1921 ABitReader br((const uint8_t *)data, kTSPacketSize);
Wonsik Kim54000662015-04-13 10:59:06 +09001922 return parseTS(&br, event);
Andreas Hubercda17c62010-06-07 13:05:37 -07001923}
1924
Chong Zhang3b2847f2017-01-18 17:43:03 -08001925status_t ATSParser::setMediaCas(const sp<ICas> &cas) {
1926 status_t err = mCasManager->setMediaCas(cas);
1927 if (err != OK) {
1928 return err;
1929 }
1930 for (size_t i = 0; i < mPrograms.size(); ++i) {
1931 mPrograms.editItemAt(i)->updateCasSessions();
1932 }
1933 return OK;
1934}
1935
Andreas Huber32f3cef2011-03-02 15:34:46 -08001936void ATSParser::signalDiscontinuity(
1937 DiscontinuityType type, const sp<AMessage> &extra) {
Andreas Huberb7c8e912012-11-27 15:02:53 -08001938 int64_t mediaTimeUs;
Chong Zhangd47dfcb2015-03-27 15:53:45 -07001939 if ((type & DISCONTINUITY_TIME) && extra != NULL) {
Dongwon Kang15d02f82017-12-14 16:32:18 -08001940 if (extra->findInt64(kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
Chong Zhangd47dfcb2015-03-27 15:53:45 -07001941 mAbsoluteTimeAnchorUs = mediaTimeUs;
1942 }
1943 if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)
1944 && extra->findInt64(
Dongwon Kang15d02f82017-12-14 16:32:18 -08001945 kATSParserKeyRecentMediaTimeUs, &mediaTimeUs)) {
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001946 if (mAbsoluteTimeAnchorUs >= 0LL) {
Chong Zhangd47dfcb2015-03-27 15:53:45 -07001947 mediaTimeUs -= mAbsoluteTimeAnchorUs;
1948 }
1949 if (mTimeOffsetValid) {
1950 mediaTimeUs -= mTimeOffsetUs;
1951 }
1952 mLastRecoveredPTS = (mediaTimeUs * 9) / 100;
1953 }
Andreas Huberb7c8e912012-11-27 15:02:53 -08001954 } else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
Andreas Huber87f2a552012-08-31 13:55:24 -07001955 int64_t timeUs;
Jinsuk Kime314c672015-04-22 11:08:28 +09001956 if (!extra->findInt64("timeUs", &timeUs)) {
1957 ALOGE("timeUs not found");
1958 return;
1959 }
Andreas Huber87f2a552012-08-31 13:55:24 -07001960
Jinsuk Kime314c672015-04-22 11:08:28 +09001961 if (!mPrograms.empty()) {
1962 ALOGE("mPrograms is not empty");
1963 return;
1964 }
Andreas Huber87f2a552012-08-31 13:55:24 -07001965 mAbsoluteTimeAnchorUs = timeUs;
1966 return;
Andreas Huberd5e56232013-03-12 11:01:43 -07001967 } else if (type == DISCONTINUITY_TIME_OFFSET) {
1968 int64_t offset;
Jinsuk Kime314c672015-04-22 11:08:28 +09001969 if (!extra->findInt64("offset", &offset)) {
1970 ALOGE("offset not found");
1971 return;
1972 }
Andreas Huberd5e56232013-03-12 11:01:43 -07001973
1974 mTimeOffsetValid = true;
1975 mTimeOffsetUs = offset;
1976 return;
Andreas Huber87f2a552012-08-31 13:55:24 -07001977 }
1978
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001979 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber32f3cef2011-03-02 15:34:46 -08001980 mPrograms.editItemAt(i)->signalDiscontinuity(type, extra);
Andreas Huberf9334412010-12-15 15:17:42 -08001981 }
1982}
1983
1984void ATSParser::signalEOS(status_t finalResult) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001985 if (finalResult == (status_t) OK) {
1986 ALOGE("finalResult not OK");
1987 return;
1988 }
Andreas Huberf9334412010-12-15 15:17:42 -08001989
1990 for (size_t i = 0; i < mPrograms.size(); ++i) {
1991 mPrograms.editItemAt(i)->signalEOS(finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001992 }
1993}
1994
Andreas Hubercda17c62010-06-07 13:05:37 -07001995void ATSParser::parseProgramAssociationTable(ABitReader *br) {
1996 unsigned table_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01001997 ALOGV(" table_id = %u", table_id);
David Yeh6456ae72014-09-03 11:14:48 +08001998 if (table_id != 0x00u) {
1999 ALOGE("PAT data error!");
2000 return ;
2001 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002002 unsigned section_syntax_indictor = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01002003 ALOGV(" section_syntax_indictor = %u", section_syntax_indictor);
Andreas Hubercda17c62010-06-07 13:05:37 -07002004
Jinsuk Kime314c672015-04-22 11:08:28 +09002005 br->skipBits(1); // '0'
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002006 MY_LOGV(" reserved = %u", br->getBits(2));
Andreas Hubercda17c62010-06-07 13:05:37 -07002007
2008 unsigned section_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +01002009 ALOGV(" section_length = %u", section_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07002010
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002011 MY_LOGV(" transport_stream_id = %u", br->getBits(16));
2012 MY_LOGV(" reserved = %u", br->getBits(2));
2013 MY_LOGV(" version_number = %u", br->getBits(5));
2014 MY_LOGV(" current_next_indicator = %u", br->getBits(1));
2015 MY_LOGV(" section_number = %u", br->getBits(8));
2016 MY_LOGV(" last_section_number = %u", br->getBits(8));
Andreas Hubercda17c62010-06-07 13:05:37 -07002017
2018 size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);
Andreas Hubercda17c62010-06-07 13:05:37 -07002019
2020 for (size_t i = 0; i < numProgramBytes / 4; ++i) {
2021 unsigned program_number = br->getBits(16);
Steve Block3856b092011-10-20 11:56:00 +01002022 ALOGV(" program_number = %u", program_number);
Andreas Hubercda17c62010-06-07 13:05:37 -07002023
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002024 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Hubercda17c62010-06-07 13:05:37 -07002025
2026 if (program_number == 0) {
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002027 MY_LOGV(" network_PID = 0x%04x", br->getBits(13));
Andreas Hubercda17c62010-06-07 13:05:37 -07002028 } else {
2029 unsigned programMapPID = br->getBits(13);
2030
Steve Block3856b092011-10-20 11:56:00 +01002031 ALOGV(" program_map_PID = 0x%04x", programMapPID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002032
Andreas Huber386d6092011-05-19 08:37:39 -07002033 bool found = false;
2034 for (size_t index = 0; index < mPrograms.size(); ++index) {
2035 const sp<Program> &program = mPrograms.itemAt(index);
2036
2037 if (program->number() == program_number) {
2038 program->updateProgramMapPID(programMapPID);
2039 found = true;
2040 break;
2041 }
2042 }
2043
2044 if (!found) {
2045 mPrograms.push(
Chong Zhangd47dfcb2015-03-27 15:53:45 -07002046 new Program(this, program_number, programMapPID, mLastRecoveredPTS));
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07002047 if (mSampleAesKeyItem != NULL) {
2048 mPrograms.top()->signalNewSampleAesKey(mSampleAesKeyItem);
2049 }
Andreas Huber386d6092011-05-19 08:37:39 -07002050 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002051
2052 if (mPSISections.indexOfKey(programMapPID) < 0) {
2053 mPSISections.add(programMapPID, new PSISection);
2054 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002055 }
2056 }
2057
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002058 MY_LOGV(" CRC = 0x%08x", br->getBits(32));
Andreas Hubercda17c62010-06-07 13:05:37 -07002059}
2060
Andreas Huber06528d72011-08-31 16:29:05 -07002061status_t ATSParser::parsePID(
Andreas Hubercda17c62010-06-07 13:05:37 -07002062 ABitReader *br, unsigned PID,
Andreas Huber87f2a552012-08-31 13:55:24 -07002063 unsigned continuity_counter,
Wonsik Kim54000662015-04-13 10:59:06 +09002064 unsigned payload_unit_start_indicator,
Chong Zhang3b2847f2017-01-18 17:43:03 -08002065 unsigned transport_scrambling_control,
2066 unsigned random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +09002067 SyncEvent *event) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07002068 ssize_t sectionIndex = mPSISections.indexOfKey(PID);
2069
2070 if (sectionIndex >= 0) {
Andreas Huber4b4bb112013-04-29 13:17:50 -07002071 sp<PSISection> section = mPSISections.valueAt(sectionIndex);
Andreas Huber8dfa2282012-05-15 12:37:29 -07002072
Andreas Hubercda17c62010-06-07 13:05:37 -07002073 if (payload_unit_start_indicator) {
David Yeh6456ae72014-09-03 11:14:48 +08002074 if (!section->isEmpty()) {
Chong Zhang9bcf3ae2015-03-08 15:59:01 -07002075 ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty");
2076 section->clear();
David Yeh6456ae72014-09-03 11:14:48 +08002077 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002078
Andreas Hubercda17c62010-06-07 13:05:37 -07002079 unsigned skip = br->getBits(8);
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002080 section->setSkipBytes(skip + 1); // skip filler bytes + pointer field itself
Andreas Hubercda17c62010-06-07 13:05:37 -07002081 br->skipBits(skip * 8);
2082 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002083
Jinsuk Kime314c672015-04-22 11:08:28 +09002084 if (br->numBitsLeft() % 8 != 0) {
2085 return ERROR_MALFORMED;
2086 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002087 status_t err = section->append(br->data(), br->numBitsLeft() / 8);
2088
2089 if (err != OK) {
2090 return err;
2091 }
2092
2093 if (!section->isComplete()) {
2094 return OK;
2095 }
2096
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002097 if (!section->isCRCOkay()) {
2098 return BAD_VALUE;
2099 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002100 ABitReader sectionBits(section->data(), section->size());
2101
2102 if (PID == 0) {
2103 parseProgramAssociationTable(&sectionBits);
2104 } else {
2105 bool handled = false;
2106 for (size_t i = 0; i < mPrograms.size(); ++i) {
2107 status_t err;
2108 if (!mPrograms.editItemAt(i)->parsePSISection(
2109 PID, &sectionBits, &err)) {
2110 continue;
2111 }
2112
2113 if (err != OK) {
2114 return err;
2115 }
2116
2117 handled = true;
2118 break;
2119 }
2120
2121 if (!handled) {
2122 mPSISections.removeItem(PID);
Andreas Huber4b4bb112013-04-29 13:17:50 -07002123 section.clear();
Andreas Huber8dfa2282012-05-15 12:37:29 -07002124 }
2125 }
2126
Andreas Huber4b4bb112013-04-29 13:17:50 -07002127 if (section != NULL) {
2128 section->clear();
2129 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002130
Andreas Huber06528d72011-08-31 16:29:05 -07002131 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002132 }
2133
2134 bool handled = false;
2135 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber06528d72011-08-31 16:29:05 -07002136 status_t err;
Andreas Hubercda17c62010-06-07 13:05:37 -07002137 if (mPrograms.editItemAt(i)->parsePID(
Chong Zhang3b2847f2017-01-18 17:43:03 -08002138 PID, continuity_counter,
2139 payload_unit_start_indicator,
2140 transport_scrambling_control,
2141 random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +09002142 br, &err, event)) {
Andreas Huber06528d72011-08-31 16:29:05 -07002143 if (err != OK) {
2144 return err;
2145 }
2146
Andreas Hubercda17c62010-06-07 13:05:37 -07002147 handled = true;
2148 break;
2149 }
2150 }
2151
2152 if (!handled) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08002153 handled = mCasManager->parsePID(br, PID);
2154 }
2155
2156 if (!handled) {
Steve Block3856b092011-10-20 11:56:00 +01002157 ALOGV("PID 0x%04x not handled.", PID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002158 }
Andreas Huber06528d72011-08-31 16:29:05 -07002159
2160 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002161}
2162
Chong Zhang3b2847f2017-01-18 17:43:03 -08002163status_t ATSParser::parseAdaptationField(
2164 ABitReader *br, unsigned PID, unsigned *random_access_indicator) {
2165 *random_access_indicator = 0;
Andreas Hubercda17c62010-06-07 13:05:37 -07002166 unsigned adaptation_field_length = br->getBits(8);
Andreas Huber87f2a552012-08-31 13:55:24 -07002167
Andreas Hubercda17c62010-06-07 13:05:37 -07002168 if (adaptation_field_length > 0) {
Jaesung Chung8a1fa1e2015-05-15 14:19:14 +09002169 if (adaptation_field_length * 8 > br->numBitsLeft()) {
2170 ALOGV("Adaptation field should be included in a single TS packet.");
2171 return ERROR_MALFORMED;
2172 }
2173
Andreas Huber87f2a552012-08-31 13:55:24 -07002174 unsigned discontinuity_indicator = br->getBits(1);
2175
2176 if (discontinuity_indicator) {
2177 ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID);
2178 }
2179
Chong Zhang3b2847f2017-01-18 17:43:03 -08002180 *random_access_indicator = br->getBits(1);
2181 if (*random_access_indicator) {
2182 ALOGV("PID 0x%04x: random_access_indicator = 1", PID);
2183 }
2184
2185 unsigned elementary_stream_priority_indicator = br->getBits(1);
2186 if (elementary_stream_priority_indicator) {
2187 ALOGV("PID 0x%04x: elementary_stream_priority_indicator = 1", PID);
2188 }
2189
Andreas Huber87f2a552012-08-31 13:55:24 -07002190 unsigned PCR_flag = br->getBits(1);
2191
2192 size_t numBitsRead = 4;
2193
2194 if (PCR_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09002195 if (adaptation_field_length * 8 < 52) {
2196 return ERROR_MALFORMED;
2197 }
Andreas Huber87f2a552012-08-31 13:55:24 -07002198 br->skipBits(4);
2199 uint64_t PCR_base = br->getBits(32);
2200 PCR_base = (PCR_base << 1) | br->getBits(1);
2201
2202 br->skipBits(6);
2203 unsigned PCR_ext = br->getBits(9);
2204
2205 // The number of bytes from the start of the current
2206 // MPEG2 transport stream packet up and including
2207 // the final byte of this PCR_ext field.
2208 size_t byteOffsetFromStartOfTSPacket =
2209 (188 - br->numBitsLeft() / 8);
2210
2211 uint64_t PCR = PCR_base * 300 + PCR_ext;
2212
Colin Crossb4a7a2d2014-03-19 16:59:00 -07002213 ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)",
Andreas Huber87f2a552012-08-31 13:55:24 -07002214 PID, PCR, PCR / 27E6);
2215
2216 // The number of bytes received by this parser up to and
2217 // including the final byte of this PCR_ext field.
Marco Nelissen19cec892016-04-20 15:56:53 -07002218 uint64_t byteOffsetFromStart =
2219 uint64_t(mNumTSPacketsParsed) * 188 + byteOffsetFromStartOfTSPacket;
Andreas Huber87f2a552012-08-31 13:55:24 -07002220
2221 for (size_t i = 0; i < mPrograms.size(); ++i) {
2222 updatePCR(PID, PCR, byteOffsetFromStart);
2223 }
2224
2225 numBitsRead += 52;
2226 }
2227
Andreas Huber87f2a552012-08-31 13:55:24 -07002228 br->skipBits(adaptation_field_length * 8 - numBitsRead);
Andreas Hubercda17c62010-06-07 13:05:37 -07002229 }
Jinsuk Kime314c672015-04-22 11:08:28 +09002230 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002231}
2232
Wonsik Kim54000662015-04-13 10:59:06 +09002233status_t ATSParser::parseTS(ABitReader *br, SyncEvent *event) {
Steve Block3856b092011-10-20 11:56:00 +01002234 ALOGV("---");
Andreas Hubercda17c62010-06-07 13:05:37 -07002235
2236 unsigned sync_byte = br->getBits(8);
David Yeh6456ae72014-09-03 11:14:48 +08002237 if (sync_byte != 0x47u) {
2238 ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte);
2239 return BAD_VALUE;
2240 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002241
Andreas Huber52668ca2013-11-11 13:35:39 -08002242 if (br->getBits(1)) { // transport_error_indicator
2243 // silently ignore.
2244 return OK;
2245 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002246
2247 unsigned payload_unit_start_indicator = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01002248 ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator);
Andreas Hubercda17c62010-06-07 13:05:37 -07002249
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002250 MY_LOGV("transport_priority = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07002251
2252 unsigned PID = br->getBits(13);
Steve Block3856b092011-10-20 11:56:00 +01002253 ALOGV("PID = 0x%04x", PID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002254
Chong Zhang3b2847f2017-01-18 17:43:03 -08002255 unsigned transport_scrambling_control = br->getBits(2);
2256 ALOGV("transport_scrambling_control = %u", transport_scrambling_control);
Andreas Hubercda17c62010-06-07 13:05:37 -07002257
2258 unsigned adaptation_field_control = br->getBits(2);
Steve Block3856b092011-10-20 11:56:00 +01002259 ALOGV("adaptation_field_control = %u", adaptation_field_control);
Andreas Hubercda17c62010-06-07 13:05:37 -07002260
Andreas Huber0da4dab2010-09-27 12:04:43 -07002261 unsigned continuity_counter = br->getBits(4);
Andreas Huber87f2a552012-08-31 13:55:24 -07002262 ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
Andreas Huber0da4dab2010-09-27 12:04:43 -07002263
Steve Blockdf64d152012-01-04 20:05:49 +00002264 // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
Andreas Hubercda17c62010-06-07 13:05:37 -07002265
Andreas Huber87f2a552012-08-31 13:55:24 -07002266 status_t err = OK;
2267
Chong Zhang3b2847f2017-01-18 17:43:03 -08002268 unsigned random_access_indicator = 0;
Jinsuk Kime314c672015-04-22 11:08:28 +09002269 if (adaptation_field_control == 2 || adaptation_field_control == 3) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08002270 err = parseAdaptationField(br, PID, &random_access_indicator);
Jinsuk Kime314c672015-04-22 11:08:28 +09002271 }
2272 if (err == OK) {
2273 if (adaptation_field_control == 1 || adaptation_field_control == 3) {
Wonsik Kim54000662015-04-13 10:59:06 +09002274 err = parsePID(br, PID, continuity_counter,
Chong Zhang3b2847f2017-01-18 17:43:03 -08002275 payload_unit_start_indicator,
2276 transport_scrambling_control,
2277 random_access_indicator,
2278 event);
Jinsuk Kime314c672015-04-22 11:08:28 +09002279 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002280 }
Andreas Huber06528d72011-08-31 16:29:05 -07002281
Andreas Huber87f2a552012-08-31 13:55:24 -07002282 ++mNumTSPacketsParsed;
2283
2284 return err;
Andreas Hubercda17c62010-06-07 13:05:37 -07002285}
2286
Marco Nelissen45d54c62018-01-26 10:04:22 -08002287sp<AnotherPacketSource> ATSParser::getSource(SourceType type) {
2288 sp<AnotherPacketSource> firstSourceFound;
Andreas Hubercda17c62010-06-07 13:05:37 -07002289 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber386d6092011-05-19 08:37:39 -07002290 const sp<Program> &program = mPrograms.editItemAt(i);
Marco Nelissen45d54c62018-01-26 10:04:22 -08002291 sp<AnotherPacketSource> source = program->getSource(type);
Robert Shih9ff1e722015-10-20 16:29:58 -07002292 if (source == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07002293 continue;
2294 }
Robert Shih9ff1e722015-10-20 16:29:58 -07002295 if (firstSourceFound == NULL) {
2296 firstSourceFound = source;
2297 }
2298 // Prefer programs with both audio/video
2299 switch (type) {
2300 case VIDEO: {
2301 if (program->hasSource(AUDIO)) {
2302 return source;
2303 }
2304 break;
2305 }
Andreas Huber386d6092011-05-19 08:37:39 -07002306
Robert Shih9ff1e722015-10-20 16:29:58 -07002307 case AUDIO: {
2308 if (program->hasSource(VIDEO)) {
2309 return source;
2310 }
2311 break;
2312 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002313
Robert Shih9ff1e722015-10-20 16:29:58 -07002314 default:
2315 return source;
Andreas Hubercda17c62010-06-07 13:05:37 -07002316 }
2317 }
2318
Robert Shih9ff1e722015-10-20 16:29:58 -07002319 return firstSourceFound;
Andreas Hubercda17c62010-06-07 13:05:37 -07002320}
2321
Robert Shihbf207272014-10-30 17:22:11 -07002322bool ATSParser::hasSource(SourceType type) const {
2323 for (size_t i = 0; i < mPrograms.size(); ++i) {
2324 const sp<Program> &program = mPrograms.itemAt(i);
2325 if (program->hasSource(type)) {
2326 return true;
2327 }
2328 }
2329
2330 return false;
2331}
2332
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002333bool ATSParser::PTSTimeDeltaEstablished() {
2334 if (mPrograms.isEmpty()) {
2335 return false;
2336 }
2337
2338 return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished();
2339}
2340
Robert Shih82e14702016-11-17 11:24:29 -08002341int64_t ATSParser::getFirstPTSTimeUs() {
2342 for (size_t i = 0; i < mPrograms.size(); ++i) {
2343 sp<ATSParser::Program> program = mPrograms.itemAt(i);
2344 if (program->PTSTimeDeltaEstablished()) {
2345 return (program->firstPTS() * 100) / 9;
2346 }
2347 }
2348 return -1;
2349}
2350
Chad Brubakerc9fa35c2015-08-18 16:52:40 -07002351__attribute__((no_sanitize("integer")))
Andreas Huber87f2a552012-08-31 13:55:24 -07002352void ATSParser::updatePCR(
Marco Nelissen19cec892016-04-20 15:56:53 -07002353 unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
2354 ALOGV("PCR 0x%016" PRIx64 " @ %" PRIx64, PCR, byteOffsetFromStart);
Andreas Huber87f2a552012-08-31 13:55:24 -07002355
2356 if (mNumPCRs == 2) {
2357 mPCR[0] = mPCR[1];
2358 mPCRBytes[0] = mPCRBytes[1];
2359 mSystemTimeUs[0] = mSystemTimeUs[1];
2360 mNumPCRs = 1;
2361 }
2362
2363 mPCR[mNumPCRs] = PCR;
2364 mPCRBytes[mNumPCRs] = byteOffsetFromStart;
2365 mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs();
2366
2367 ++mNumPCRs;
2368
2369 if (mNumPCRs == 2) {
Chad Brubakerc9fa35c2015-08-18 16:52:40 -07002370 /* Unsigned overflow here */
Andreas Huber87f2a552012-08-31 13:55:24 -07002371 double transportRate =
2372 (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]);
2373
2374 ALOGV("transportRate = %.2f bytes/sec", transportRate);
2375 }
2376}
2377
Andreas Huber8dfa2282012-05-15 12:37:29 -07002378////////////////////////////////////////////////////////////////////////////////
2379
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002380
2381// CRC32 used for PSI section. The table was generated by following command:
2382// $ python pycrc.py --model crc-32-mpeg --algorithm table-driven --generate c
2383// Visit http://www.tty1.net/pycrc/index_en.html for more details.
2384uint32_t ATSParser::PSISection::CRC_TABLE[] = {
2385 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
2386 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
2387 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
2388 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
2389 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
2390 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
2391 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
2392 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
2393 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
2394 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
2395 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
2396 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
2397 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
2398 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
2399 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
2400 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
2401 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
2402 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
2403 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
2404 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
2405 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
2406 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
2407 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
2408 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
2409 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
2410 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
2411 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
2412 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
2413 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
2414 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
2415 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
2416 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
2417 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
2418 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
2419 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
2420 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
2421 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
2422 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
2423 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
2424 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
2425 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
2426 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
2427 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
2428 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
2429 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
2430 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
2431 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
2432 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
2433 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
2434 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
2435 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
2436 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
2437 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
2438 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
2439 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
2440 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
2441 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
2442 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
2443 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
2444 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
2445 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
2446 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
2447 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
2448 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
2449 };
2450
2451ATSParser::PSISection::PSISection() :
2452 mSkipBytes(0) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07002453}
2454
2455ATSParser::PSISection::~PSISection() {
2456}
2457
2458status_t ATSParser::PSISection::append(const void *data, size_t size) {
2459 if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) {
2460 size_t newCapacity =
2461 (mBuffer == NULL) ? size : mBuffer->capacity() + size;
2462
2463 newCapacity = (newCapacity + 1023) & ~1023;
2464
2465 sp<ABuffer> newBuffer = new ABuffer(newCapacity);
2466
2467 if (mBuffer != NULL) {
2468 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
2469 newBuffer->setRange(0, mBuffer->size());
2470 } else {
2471 newBuffer->setRange(0, 0);
2472 }
2473
2474 mBuffer = newBuffer;
2475 }
2476
2477 memcpy(mBuffer->data() + mBuffer->size(), data, size);
2478 mBuffer->setRange(0, mBuffer->size() + size);
2479
2480 return OK;
2481}
2482
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002483void ATSParser::PSISection::setSkipBytes(uint8_t skip) {
2484 mSkipBytes = skip;
2485}
2486
Andreas Huber8dfa2282012-05-15 12:37:29 -07002487void ATSParser::PSISection::clear() {
2488 if (mBuffer != NULL) {
2489 mBuffer->setRange(0, 0);
2490 }
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002491 mSkipBytes = 0;
Andreas Huber8dfa2282012-05-15 12:37:29 -07002492}
2493
2494bool ATSParser::PSISection::isComplete() const {
2495 if (mBuffer == NULL || mBuffer->size() < 3) {
2496 return false;
2497 }
2498
2499 unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff;
2500 return mBuffer->size() >= sectionLength + 3;
2501}
2502
2503bool ATSParser::PSISection::isEmpty() const {
2504 return mBuffer == NULL || mBuffer->size() == 0;
2505}
2506
2507const uint8_t *ATSParser::PSISection::data() const {
2508 return mBuffer == NULL ? NULL : mBuffer->data();
2509}
2510
2511size_t ATSParser::PSISection::size() const {
2512 return mBuffer == NULL ? 0 : mBuffer->size();
2513}
2514
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002515bool ATSParser::PSISection::isCRCOkay() const {
2516 if (!isComplete()) {
2517 return false;
2518 }
2519 uint8_t* data = mBuffer->data();
2520
2521 // Return true if section_syntax_indicator says no section follows the field section_length.
2522 if ((data[1] & 0x80) == 0) {
2523 return true;
2524 }
2525
2526 unsigned sectionLength = U16_AT(data + 1) & 0xfff;
2527 ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes);
2528
Marco Nelissenc0c9f502016-04-28 13:32:41 -07002529
2530 if(sectionLength < mSkipBytes) {
2531 ALOGE("b/28333006");
2532 android_errorWriteLog(0x534e4554, "28333006");
2533 return false;
2534 }
2535
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002536 // Skip the preceding field present when payload start indicator is on.
2537 sectionLength -= mSkipBytes;
2538
2539 uint32_t crc = 0xffffffff;
2540 for(unsigned i = 0; i < sectionLength + 4 /* crc */; i++) {
2541 uint8_t b = data[i];
2542 int index = ((crc >> 24) ^ (b & 0xff)) & 0xff;
2543 crc = CRC_TABLE[index] ^ (crc << 8);
2544 }
2545 ALOGV("crc: %08x\n", crc);
2546 return (crc == 0);
2547}
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07002548
2549// SAMPLE_AES key handling
2550// TODO: Merge these to their respective class after Widevine-HLS
2551void ATSParser::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2552 ALOGD("signalNewSampleAesKey: %p", keyItem.get());
2553
2554 mSampleAesKeyItem = keyItem;
2555
2556 // a NULL key item will propagate to existing ElementaryStreamQueues
2557 for (size_t i = 0; i < mPrograms.size(); ++i) {
2558 mPrograms[i]->signalNewSampleAesKey(keyItem);
2559 }
2560}
2561
2562void ATSParser::Program::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2563 ALOGD("Program::signalNewSampleAesKey: %p", keyItem.get());
2564
2565 mSampleAesKeyItem = keyItem;
2566
2567 // a NULL key item will propagate to existing ElementaryStreamQueues
2568 for (size_t i = 0; i < mStreams.size(); ++i) {
2569 mStreams[i]->signalNewSampleAesKey(keyItem);
2570 }
2571}
2572
2573void ATSParser::Stream::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2574 ALOGD("Stream::signalNewSampleAesKey: 0x%04x size = %zu keyItem: %p",
2575 mElementaryPID, mBuffer->size(), keyItem.get());
2576
2577 // a NULL key item will propagate to existing ElementaryStreamQueues
2578 mSampleAesKeyItem = keyItem;
2579
2580 flush(NULL);
2581 mQueue->signalNewSampleAesKey(keyItem);
2582}
2583
Andreas Hubercda17c62010-06-07 13:05:37 -07002584} // namespace android