blob: 86187bda05418cb18da5fcfcccd2b75c9e9707bb [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/memory/1.0/IMemory.h>
Devin Moore6482a5b2023-11-08 17:53:52 +000027#include <cutils/ashmem.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 {
Devin Moore6482a5b2023-11-08 17:53:52 +000049using hardware::hidl_handle;
Chong Zhangd5a416a2017-05-16 11:16:34 -070050using hardware::hidl_string;
51using hardware::hidl_vec;
Chong Zhang00c5c052018-12-17 14:15:58 -080052using hardware::hidl_memory;
Chong Zhangd5a416a2017-05-16 11:16:34 -070053using namespace hardware::cas::V1_0;
54using namespace hardware::cas::native::V1_0;
Chong Zhang00c5c052018-12-17 14:15:58 -080055typedef 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;
Chong Zhangd5a416a2017-05-16 11:16:34 -0700213 hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800214 sp<ABuffer> mDescrambledBuffer;
215 List<SubSampleInfo> mSubSamples;
216 sp<IDescrambler> mDescrambler;
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100217 AudioPresentationCollection mAudioPresentations;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800218
Sampath Shettyc6148a62018-12-18 15:50:43 +1100219 // Send audio presentations along with access units.
220 void addAudioPresentations(const sp<ABuffer> &buffer);
221
Wonsik Kim54000662015-04-13 10:59:06 +0900222 // Flush accumulated payload if necessary --- i.e. at EOS or at the start of
223 // another payload. event is set if the flushed payload is PES with a sync
224 // frame.
225 status_t flush(SyncEvent *event);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800226
227 // Flush accumulated payload for scrambled streams if necessary --- i.e. at
228 // EOS or at the start of another payload. event is set if the flushed
229 // payload is PES with a sync frame.
230 status_t flushScrambled(SyncEvent *event);
231
232 // Check if a PES packet is scrambled at PES level.
233 uint32_t getPesScramblingControl(ABitReader *br, int32_t *pesOffset);
234
Wonsik Kim54000662015-04-13 10:59:06 +0900235 // Strip and parse PES headers and pass remaining payload into onPayload
236 // with parsed metadata. event is set if the PES contains a sync frame.
237 status_t parsePES(ABitReader *br, SyncEvent *event);
Andreas Hubercda17c62010-06-07 13:05:37 -0700238
Wonsik Kim54000662015-04-13 10:59:06 +0900239 // Feed the payload into mQueue and if a packet is identified, queue it
240 // into mSource. If the packet is a sync frame. set event with start offset
241 // and timestamp of the packet.
Andreas Hubercda17c62010-06-07 13:05:37 -0700242 void onPayloadData(
243 unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
Chong Zhang3b2847f2017-01-18 17:43:03 -0800244 unsigned PES_scrambling_control,
245 const uint8_t *data, size_t size,
246 int32_t payloadOffset, SyncEvent *event);
247
248 // Ensure internal buffers can hold specified size, and will re-allocate
249 // as needed.
Chong Zhangd5a416a2017-05-16 11:16:34 -0700250 bool ensureBufferCapacity(size_t size);
Andreas Huber82f73212010-09-01 12:22:36 -0700251
Andreas Hubercda17c62010-06-07 13:05:37 -0700252 DISALLOW_EVIL_CONSTRUCTORS(Stream);
253};
254
Andreas Huber8dfa2282012-05-15 12:37:29 -0700255struct ATSParser::PSISection : public RefBase {
256 PSISection();
257
258 status_t append(const void *data, size_t size);
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +0900259 void setSkipBytes(uint8_t skip);
Andreas Huber8dfa2282012-05-15 12:37:29 -0700260 void clear();
261
262 bool isComplete() const;
263 bool isEmpty() const;
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +0900264 bool isCRCOkay() const;
Andreas Huber8dfa2282012-05-15 12:37:29 -0700265
266 const uint8_t *data() const;
267 size_t size() const;
268
269protected:
270 virtual ~PSISection();
271
272private:
273 sp<ABuffer> mBuffer;
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +0900274 uint8_t mSkipBytes;
275 static uint32_t CRC_TABLE[];
Andreas Huber8dfa2282012-05-15 12:37:29 -0700276
277 DISALLOW_EVIL_CONSTRUCTORS(PSISection);
278};
279
Wonsik Kim54000662015-04-13 10:59:06 +0900280ATSParser::SyncEvent::SyncEvent(off64_t offset)
Wei Jia9558f6d2016-03-08 17:31:16 -0800281 : mHasReturnedData(false), mOffset(offset), mTimeUs(0) {}
Wonsik Kim54000662015-04-13 10:59:06 +0900282
Marco Nelissen45d54c62018-01-26 10:04:22 -0800283void ATSParser::SyncEvent::init(off64_t offset, const sp<AnotherPacketSource> &source,
Robert Shih82e14702016-11-17 11:24:29 -0800284 int64_t timeUs, SourceType type) {
Wei Jia9558f6d2016-03-08 17:31:16 -0800285 mHasReturnedData = true;
Wonsik Kim54000662015-04-13 10:59:06 +0900286 mOffset = offset;
287 mMediaSource = source;
288 mTimeUs = timeUs;
Robert Shih82e14702016-11-17 11:24:29 -0800289 mType = type;
Wonsik Kim54000662015-04-13 10:59:06 +0900290}
291
Wei Jia9558f6d2016-03-08 17:31:16 -0800292void ATSParser::SyncEvent::reset() {
293 mHasReturnedData = false;
294}
Andreas Hubercda17c62010-06-07 13:05:37 -0700295////////////////////////////////////////////////////////////////////////////////
296
Andreas Huber386d6092011-05-19 08:37:39 -0700297ATSParser::Program::Program(
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700298 ATSParser *parser, unsigned programNumber, unsigned programMapPID,
299 int64_t lastRecoveredPTS)
Andreas Huberf9334412010-12-15 15:17:42 -0800300 : mParser(parser),
Andreas Huber386d6092011-05-19 08:37:39 -0700301 mProgramNumber(programNumber),
Andreas Huberf9334412010-12-15 15:17:42 -0800302 mProgramMapPID(programMapPID),
Sampath Shetty142598f2018-12-10 13:52:30 +1100303 mPMTVersion(0xffffffff),
304 mPMT_CRC(0xffffffff),
Andreas Huberbff07d02010-10-12 11:34:37 -0700305 mFirstPTSValid(false),
Chong Zhang799c9682015-03-02 23:42:38 -0800306 mFirstPTS(0),
Chong Zhangd47dfcb2015-03-27 15:53:45 -0700307 mLastRecoveredPTS(lastRecoveredPTS) {
Steve Block3856b092011-10-20 11:56:00 +0100308 ALOGV("new program number %u", programNumber);
Andreas Hubercda17c62010-06-07 13:05:37 -0700309}
310
Andreas Huber8dfa2282012-05-15 12:37:29 -0700311bool ATSParser::Program::parsePSISection(
312 unsigned pid, ABitReader *br, status_t *err) {
313 *err = OK;
314
315 if (pid != mProgramMapPID) {
316 return false;
317 }
318
319 *err = parseProgramMap(br);
320
321 return true;
322}
323
Andreas Hubercda17c62010-06-07 13:05:37 -0700324bool ATSParser::Program::parsePID(
Andreas Huber87f2a552012-08-31 13:55:24 -0700325 unsigned pid, unsigned continuity_counter,
326 unsigned payload_unit_start_indicator,
Chong Zhang3b2847f2017-01-18 17:43:03 -0800327 unsigned transport_scrambling_control,
328 unsigned random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +0900329 ABitReader *br, status_t *err, SyncEvent *event) {
Andreas Huber06528d72011-08-31 16:29:05 -0700330 *err = OK;
331
Andreas Hubercda17c62010-06-07 13:05:37 -0700332 ssize_t index = mStreams.indexOfKey(pid);
333 if (index < 0) {
334 return false;
335 }
336
Andreas Huber54031292011-09-01 11:04:43 -0700337 *err = mStreams.editValueAt(index)->parse(
Chong Zhang3b2847f2017-01-18 17:43:03 -0800338 continuity_counter,
339 payload_unit_start_indicator,
340 transport_scrambling_control,
341 random_access_indicator,
342 br, event);
Andreas Hubercda17c62010-06-07 13:05:37 -0700343
344 return true;
345}
346
Andreas Huber32f3cef2011-03-02 15:34:46 -0800347void ATSParser::Program::signalDiscontinuity(
348 DiscontinuityType type, const sp<AMessage> &extra) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800349 int64_t mediaTimeUs;
350 if ((type & DISCONTINUITY_TIME)
351 && extra != NULL
352 && extra->findInt64(
Dongwon Kang15d02f82017-12-14 16:32:18 -0800353 kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
Andreas Huberb7c8e912012-11-27 15:02:53 -0800354 mFirstPTSValid = false;
355 }
356
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700357 for (size_t i = 0; i < mStreams.size(); ++i) {
Andreas Huber32f3cef2011-03-02 15:34:46 -0800358 mStreams.editValueAt(i)->signalDiscontinuity(type, extra);
Andreas Huberf9334412010-12-15 15:17:42 -0800359 }
360}
361
362void ATSParser::Program::signalEOS(status_t finalResult) {
363 for (size_t i = 0; i < mStreams.size(); ++i) {
364 mStreams.editValueAt(i)->signalEOS(finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -0700365 }
366}
367
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700368bool ATSParser::Program::switchPIDs(const Vector<StreamInfo> &infos) {
369 bool success = false;
370
371 if (mStreams.size() == infos.size()) {
372 // build type->PIDs map for old and new mapping
373 size_t i;
374 KeyedVector<int32_t, Vector<int32_t> > oldType2PIDs, newType2PIDs;
375 for (i = 0; i < mStreams.size(); ++i) {
376 ssize_t index = oldType2PIDs.indexOfKey(mStreams[i]->type());
377 if (index < 0) {
378 oldType2PIDs.add(mStreams[i]->type(), Vector<int32_t>());
379 }
380 oldType2PIDs.editValueFor(mStreams[i]->type()).push_back(mStreams[i]->pid());
381 }
382 for (i = 0; i < infos.size(); ++i) {
383 ssize_t index = newType2PIDs.indexOfKey(infos[i].mType);
384 if (index < 0) {
385 newType2PIDs.add(infos[i].mType, Vector<int32_t>());
386 }
387 newType2PIDs.editValueFor(infos[i].mType).push_back(infos[i].mPID);
388 }
389
390 // we can recover if the number of streams for each type hasn't changed
391 if (oldType2PIDs.size() == newType2PIDs.size()) {
392 success = true;
393 for (i = 0; i < oldType2PIDs.size(); ++i) {
394 // KeyedVector is sorted, we just compare key and size of each index
395 if (oldType2PIDs.keyAt(i) != newType2PIDs.keyAt(i)
396 || oldType2PIDs[i].size() != newType2PIDs[i].size()) {
397 success = false;
398 break;
399 }
400 }
401 }
402
403 if (success) {
404 // save current streams to temp
405 KeyedVector<int32_t, sp<Stream> > temp;
406 for (i = 0; i < mStreams.size(); ++i) {
407 temp.add(mStreams.keyAt(i), mStreams.editValueAt(i));
408 }
409
410 mStreams.clear();
411 for (i = 0; i < temp.size(); ++i) {
412 // The two checks below shouldn't happen,
413 // we already checked above the stream count matches
414 ssize_t index = newType2PIDs.indexOfKey(temp[i]->type());
Jinsuk Kime314c672015-04-22 11:08:28 +0900415 if (index < 0) {
416 return false;
417 }
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700418 Vector<int32_t> &newPIDs = newType2PIDs.editValueAt(index);
Jinsuk Kime314c672015-04-22 11:08:28 +0900419 if (newPIDs.isEmpty()) {
420 return false;
421 }
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700422
423 // get the next PID for temp[i]->type() in the new PID map
424 Vector<int32_t>::iterator it = newPIDs.begin();
425
426 // change the PID of the stream, and add it back
427 temp.editValueAt(i)->setPID(*it);
428 mStreams.add(temp[i]->pid(), temp.editValueAt(i));
429
430 // removed the used PID
431 newPIDs.erase(it);
432 }
433 }
434 }
435 return success;
436}
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800437
Chong Zhang3b2847f2017-01-18 17:43:03 -0800438bool ATSParser::Program::findCADescriptor(
439 ABitReader *br, unsigned infoLength,
440 ATSParser::CADescriptor *caDescriptor) {
441 bool found = false;
442 while (infoLength > 2) {
443 unsigned descriptor_tag = br->getBits(8);
444 ALOGV(" tag = 0x%02x", descriptor_tag);
445
446 unsigned descriptor_length = br->getBits(8);
447 ALOGV(" len = %u", descriptor_length);
448
449 infoLength -= 2;
450 if (descriptor_length > infoLength) {
451 break;
452 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800453 if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
Chong Zhang3b2847f2017-01-18 17:43:03 -0800454 found = true;
455 caDescriptor->mSystemID = br->getBits(16);
456 caDescriptor->mPID = br->getBits(16) & 0x1fff;
457 infoLength -= 4;
458 caDescriptor->mPrivateData.assign(
459 br->data(), br->data() + descriptor_length - 4);
460 break;
461 } else {
462 infoLength -= descriptor_length;
463 br->skipBits(descriptor_length * 8);
464 }
465 }
466 br->skipBits(infoLength * 8);
467 return found;
468}
469
Andreas Huber06528d72011-08-31 16:29:05 -0700470status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
Andreas Hubercda17c62010-06-07 13:05:37 -0700471 unsigned table_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +0100472 ALOGV(" table_id = %u", table_id);
David Yeh6456ae72014-09-03 11:14:48 +0800473 if (table_id != 0x02u) {
474 ALOGE("PMT data error!");
475 return ERROR_MALFORMED;
476 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700477 unsigned section_syntax_indicator = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +0100478 ALOGV(" section_syntax_indicator = %u", section_syntax_indicator);
David Yeh6456ae72014-09-03 11:14:48 +0800479 if (section_syntax_indicator != 1u) {
480 ALOGE("PMT data error!");
481 return ERROR_MALFORMED;
482 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700483
Jinsuk Kime314c672015-04-22 11:08:28 +0900484 br->skipBits(1); // '0'
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700485 MY_LOGV(" reserved = %u", br->getBits(2));
Andreas Hubercda17c62010-06-07 13:05:37 -0700486
487 unsigned section_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100488 ALOGV(" section_length = %u", section_length);
Andreas Hubercda17c62010-06-07 13:05:37 -0700489
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700490 MY_LOGV(" program_number = %u", br->getBits(16));
491 MY_LOGV(" reserved = %u", br->getBits(2));
Sampath Shetty142598f2018-12-10 13:52:30 +1100492 bool audioPresentationsChanged = false;
493 unsigned pmtVersion = br->getBits(5);
494 if (pmtVersion != mPMTVersion) {
495 audioPresentationsChanged = true;
496 mPMTVersion = pmtVersion;
497 }
498 MY_LOGV(" version_number = %u", pmtVersion);
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700499 MY_LOGV(" current_next_indicator = %u", br->getBits(1));
500 MY_LOGV(" section_number = %u", br->getBits(8));
501 MY_LOGV(" last_section_number = %u", br->getBits(8));
502 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Huber87f2a552012-08-31 13:55:24 -0700503
504 unsigned PCR_PID = br->getBits(13);
505 ALOGV(" PCR_PID = 0x%04x", PCR_PID);
506
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700507 MY_LOGV(" reserved = %u", br->getBits(4));
Andreas Hubercda17c62010-06-07 13:05:37 -0700508
509 unsigned program_info_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100510 ALOGV(" program_info_length = %u", program_info_length);
Andreas Hubercda17c62010-06-07 13:05:37 -0700511
Chong Zhang3b2847f2017-01-18 17:43:03 -0800512 // descriptors
513 CADescriptor programCA;
514 bool hasProgramCA = findCADescriptor(br, program_info_length, &programCA);
515 if (hasProgramCA && !mParser->mCasManager->addProgram(
516 mProgramNumber, programCA)) {
517 return ERROR_MALFORMED;
518 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700519
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800520 Vector<StreamInfo> infos;
521
Andreas Hubercda17c62010-06-07 13:05:37 -0700522 // infoBytesRemaining is the number of bytes that make up the
523 // variable length section of ES_infos. It does not include the
524 // final CRC.
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800525 int32_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
Andreas Hubercda17c62010-06-07 13:05:37 -0700526
Jinsuk Kime314c672015-04-22 11:08:28 +0900527 while (infoBytesRemaining >= 5) {
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800528 StreamInfo info;
529 info.mType = br->getBits(8);
530 ALOGV(" stream_type = 0x%02x", info.mType);
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700531 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Hubercda17c62010-06-07 13:05:37 -0700532
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800533 info.mPID = br->getBits(13);
534 ALOGV(" elementary_PID = 0x%04x", info.mPID);
Andreas Hubercda17c62010-06-07 13:05:37 -0700535
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700536 MY_LOGV(" reserved = %u", br->getBits(4));
Andreas Hubercda17c62010-06-07 13:05:37 -0700537
538 unsigned ES_info_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100539 ALOGV(" ES_info_length = %u", ES_info_length);
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800540 infoBytesRemaining -= 5 + ES_info_length;
Andreas Hubercda17c62010-06-07 13:05:37 -0700541
Chong Zhang3b2847f2017-01-18 17:43:03 -0800542 CADescriptor streamCA;
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800543 info.mTypeExt = EXT_DESCRIPTOR_DVB_RESERVED_MAX;
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100544
545 info.mAudioPresentations.clear();
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800546 bool hasStreamCA = false;
547 while (ES_info_length > 2 && infoBytesRemaining >= 0) {
548 unsigned descriptor_tag = br->getBits(8);
549 ALOGV(" tag = 0x%02x", descriptor_tag);
550
551 unsigned descriptor_length = br->getBits(8);
552 ALOGV(" len = %u", descriptor_length);
553
554 ES_info_length -= 2;
555 if (descriptor_length > ES_info_length) {
556 return ERROR_MALFORMED;
557 }
Rahul3beba382023-02-03 20:36:55 +0000558
559 // The DTS descriptor is used in the PSI PMT to identify streams which carry
560 // DTS audio(core only). If a DTS descriptor is present, a DTS-HD or DTS-UHD
561 // descriptors shall not be present in the same ES_info descriptor loop.
562 if (descriptor_tag == DESCRIPTOR_DTS) {
563 info.mType = STREAMTYPE_DTS;
564 ES_info_length -= descriptor_length;
565 br->skipBits(descriptor_length * 8);
566 } else if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800567 hasStreamCA = true;
568 streamCA.mSystemID = br->getBits(16);
569 streamCA.mPID = br->getBits(16) & 0x1fff;
Vasily Tarasov7e736a42018-11-01 10:51:08 -0700570 ES_info_length -= descriptor_length;
571 descriptor_length -= 4;
572 streamCA.mPrivateData.assign(br->data(), br->data() + descriptor_length);
573 br->skipBits(descriptor_length * 8);
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800574 } else if (info.mType == STREAMTYPE_PES_PRIVATE_DATA &&
575 descriptor_tag == DESCRIPTOR_DVB_EXTENSION && descriptor_length >= 1) {
576 unsigned descTagExt = br->getBits(8);
577 ALOGV(" tag_ext = 0x%02x", descTagExt);
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800578 ES_info_length -= descriptor_length;
579 descriptor_length--;
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100580 // The AC4 descriptor is used in the PSI PMT to identify streams which carry AC4
581 // audio.
582 if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
583 info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
584 br->skipBits(descriptor_length * 8);
Rahul3beba382023-02-03 20:36:55 +0000585 } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
586 // DTS HD extended descriptor which can accommodate core only formats
587 // as well as extension only and core + extension combinations.
588 info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_HD;
589 br->skipBits(descriptor_length * 8);
590 } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
591 // The DTS-UHD descriptor is used in the PSI PMT to identify streams
592 // which carry DTS-UHD audio
593 info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_UHD;
594 br->skipBits(descriptor_length * 8);
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100595 } else if (descTagExt == EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION &&
596 descriptor_length >= 1) {
597 // DVB BlueBook A038 Table 110
598 unsigned num_preselections = br->getBits(5);
599 br->skipBits(3); // reserved
600 for (unsigned i = 0; i < num_preselections; ++i) {
601 if (br->numBitsLeft() < 16) {
602 ALOGE("Not enough data left in bitreader!");
603 return ERROR_MALFORMED;
604 }
605 AudioPresentationV1 ap;
606 ap.mPresentationId = br->getBits(5); // preselection_id
607
608 // audio_rendering_indication
609 ap.mMasteringIndication = static_cast<MasteringIndication>(br->getBits(3));
610 ap.mAudioDescriptionAvailable = (br->getBits(1) == 1);
611 ap.mSpokenSubtitlesAvailable = (br->getBits(1) == 1);
612 ap.mDialogueEnhancementAvailable = (br->getBits(1) == 1);
613
614 bool interactivity_enabled = (br->getBits(1) == 1);
615 MY_LOGV(" interactivity_enabled = %d", interactivity_enabled);
616
617 bool language_code_present = (br->getBits(1) == 1);
618 bool text_label_present = (br->getBits(1) == 1);
619
620 bool multi_stream_info_present = (br->getBits(1) == 1);
621 bool future_extension = (br->getBits(1) == 1);
622 if (language_code_present) {
623 if (br->numBitsLeft() < 24) {
624 ALOGE("Not enough data left in bitreader!");
625 return ERROR_MALFORMED;
626 }
627 char language[4];
628 language[0] = br->getBits(8);
629 language[1] = br->getBits(8);
630 language[2] = br->getBits(8);
631 language[3] = 0;
632 ap.mLanguage = String8(language);
633 }
634
635 // This maps the presentation id to the message id in the
636 // EXT_DESCRIPTOR_DVB_MESSAGE so that we can get the presentation label.
637 if (text_label_present) {
638 if (br->numBitsLeft() < 8) {
639 ALOGE("Not enough data left in bitreader!");
640 return ERROR_MALFORMED;
641 }
642 unsigned message_id = br->getBits(8);
643 MY_LOGV(" message_id = %u", message_id);
644 }
645
646 if (multi_stream_info_present) {
647 if (br->numBitsLeft() < 8) {
648 ALOGE("Not enough data left in bitreader!");
649 return ERROR_MALFORMED;
650 }
651 unsigned num_aux_components = br->getBits(3);
652 br->skipBits(5); // reserved
653 if (br->numBitsLeft() < (num_aux_components * 8)) {
654 ALOGE("Not enough data left in bitreader!");
655 return ERROR_MALFORMED;
656 }
657 br->skipBits(num_aux_components * 8); // component_tag
658 }
659 if (future_extension) {
660 if (br->numBitsLeft() < 8) {
661 return ERROR_MALFORMED;
662 }
663 br->skipBits(3); // reserved
664 unsigned future_extension_length = br->getBits(5);
665 if (br->numBitsLeft() < (future_extension_length * 8)) {
666 ALOGE("Not enough data left in bitreader!");
667 return ERROR_MALFORMED;
668 }
669 br->skipBits(future_extension_length * 8); // future_extension_byte
670 }
671 info.mAudioPresentations.push_back(std::move(ap));
672 }
673 } else {
674 br->skipBits(descriptor_length * 8);
675 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800676 } else {
677 ES_info_length -= descriptor_length;
678 br->skipBits(descriptor_length * 8);
679 }
680 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800681 if (hasStreamCA && !mParser->mCasManager->addStream(
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800682 mProgramNumber, info.mPID, streamCA)) {
Chong Zhang3b2847f2017-01-18 17:43:03 -0800683 return ERROR_MALFORMED;
Andreas Hubercda17c62010-06-07 13:05:37 -0700684 }
Chong Zhang7e986a82018-11-07 13:01:08 -0800685 if (hasProgramCA) {
686 info.mCADescriptor = programCA;
687 } else if (hasStreamCA) {
688 info.mCADescriptor = streamCA;
689 }
690
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800691 infos.push(info);
Andreas Hubercda17c62010-06-07 13:05:37 -0700692 }
693
Jinsuk Kime314c672015-04-22 11:08:28 +0900694 if (infoBytesRemaining != 0) {
695 ALOGW("Section data remains unconsumed");
696 }
Sampath Shetty142598f2018-12-10 13:52:30 +1100697 unsigned crc = br->getBits(32);
698 if (crc != mPMT_CRC) {
699 audioPresentationsChanged = true;
700 mPMT_CRC = crc;
701 }
702 MY_LOGV(" CRC = 0x%08x", crc);
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800703
704 bool PIDsChanged = false;
705 for (size_t i = 0; i < infos.size(); ++i) {
706 StreamInfo &info = infos.editItemAt(i);
707
708 ssize_t index = mStreams.indexOfKey(info.mPID);
709
710 if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
Steve Blockdf64d152012-01-04 20:05:49 +0000711 ALOGI("uh oh. stream PIDs have changed.");
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800712 PIDsChanged = true;
713 break;
714 }
715 }
716
717 if (PIDsChanged) {
Andreas Huber06528d72011-08-31 16:29:05 -0700718#if 0
Steve Blockdf64d152012-01-04 20:05:49 +0000719 ALOGI("before:");
Andreas Huber06528d72011-08-31 16:29:05 -0700720 for (size_t i = 0; i < mStreams.size(); ++i) {
721 sp<Stream> stream = mStreams.editValueAt(i);
722
Steve Blockdf64d152012-01-04 20:05:49 +0000723 ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type());
Andreas Huber06528d72011-08-31 16:29:05 -0700724 }
725
Steve Blockdf64d152012-01-04 20:05:49 +0000726 ALOGI("after:");
Andreas Huber06528d72011-08-31 16:29:05 -0700727 for (size_t i = 0; i < infos.size(); ++i) {
728 StreamInfo &info = infos.editItemAt(i);
729
Steve Blockdf64d152012-01-04 20:05:49 +0000730 ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType);
Andreas Huber06528d72011-08-31 16:29:05 -0700731 }
732#endif
733
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700734 // we can recover if number of streams for each type remain the same
735 bool success = switchPIDs(infos);
Andreas Huber06528d72011-08-31 16:29:05 -0700736
737 if (!success) {
Steve Blockdf64d152012-01-04 20:05:49 +0000738 ALOGI("Stream PIDs changed and we cannot recover.");
Andreas Huber06528d72011-08-31 16:29:05 -0700739 return ERROR_MALFORMED;
740 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800741 }
742
Chong Zhang3b2847f2017-01-18 17:43:03 -0800743 bool isAddingScrambledStream = false;
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800744 for (size_t i = 0; i < infos.size(); ++i) {
745 StreamInfo &info = infos.editItemAt(i);
746
Chong Zhang3b2847f2017-01-18 17:43:03 -0800747 if (mParser->mCasManager->isCAPid(info.mPID)) {
748 // skip CA streams (EMM/ECM)
749 continue;
750 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800751 ssize_t index = mStreams.indexOfKey(info.mPID);
752
753 if (index < 0) {
Chong Zhang7e986a82018-11-07 13:01:08 -0800754 sp<Stream> stream = new Stream(this, PCR_PID, info);
Andreas Huber87f2a552012-08-31 13:55:24 -0700755
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700756 if (mSampleAesKeyItem != NULL) {
757 stream->signalNewSampleAesKey(mSampleAesKeyItem);
758 }
759
Chong Zhang7e986a82018-11-07 13:01:08 -0800760 isAddingScrambledStream |= info.mCADescriptor.mSystemID >= 0;
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800761 mStreams.add(info.mPID, stream);
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800762 }
Sampath Shetty142598f2018-12-10 13:52:30 +1100763 else if (index >= 0 && mStreams.editValueAt(index)->isAudio()
764 && audioPresentationsChanged) {
765 mStreams.editValueAt(index)->setAudioPresentations(info.mAudioPresentations);
766 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800767 }
Andreas Huber06528d72011-08-31 16:29:05 -0700768
Chong Zhang3b2847f2017-01-18 17:43:03 -0800769 if (isAddingScrambledStream) {
770 ALOGI("Receiving scrambled streams without descrambler!");
771 return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
772 }
Andreas Huber06528d72011-08-31 16:29:05 -0700773 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -0700774}
775
Chong Zhang799c9682015-03-02 23:42:38 -0800776int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
777 // We only have the lower 33-bit of the PTS. It could overflow within a
778 // reasonable amount of time. To handle the wrap-around, use fancy math
779 // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
780 // of the latest recovered PTS.
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800781 if (mLastRecoveredPTS < 0LL) {
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700782 // Use the original 33bit number for 1st frame, the reason is that
783 // if 1st frame wraps to negative that's far away from 0, we could
784 // never start. Only start wrapping around from 2nd frame.
785 mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
786 } else {
787 mLastRecoveredPTS = static_cast<int64_t>(
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800788 ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000LL)
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700789 & 0xfffffffe00000000ull) | PTS_33bit);
790 // We start from 0, but recovered PTS could be slightly below 0.
791 // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
792 // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800793 if (mLastRecoveredPTS < 0LL) {
Chih-Hung Hsieh5c9054b2015-03-12 13:24:12 -0700794 ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS);
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800795 mLastRecoveredPTS = 0LL;
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700796 }
797 }
Chong Zhang799c9682015-03-02 23:42:38 -0800798
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700799 return mLastRecoveredPTS;
Chong Zhang799c9682015-03-02 23:42:38 -0800800}
801
Marco Nelissen45d54c62018-01-26 10:04:22 -0800802sp<AnotherPacketSource> ATSParser::Program::getSource(SourceType type) {
Andreas Hubercda17c62010-06-07 13:05:37 -0700803 for (size_t i = 0; i < mStreams.size(); ++i) {
Marco Nelissen45d54c62018-01-26 10:04:22 -0800804 sp<AnotherPacketSource> source = mStreams.editValueAt(i)->getSource(type);
Andreas Hubercda17c62010-06-07 13:05:37 -0700805 if (source != NULL) {
Robert Shih9ff1e722015-10-20 16:29:58 -0700806 return source;
Andreas Hubercda17c62010-06-07 13:05:37 -0700807 }
808 }
809
810 return NULL;
811}
812
Robert Shihbf207272014-10-30 17:22:11 -0700813bool ATSParser::Program::hasSource(SourceType type) const {
814 for (size_t i = 0; i < mStreams.size(); ++i) {
815 const sp<Stream> &stream = mStreams.valueAt(i);
816 if (type == AUDIO && stream->isAudio()) {
817 return true;
818 } else if (type == VIDEO && stream->isVideo()) {
819 return true;
Robert Shih9ff1e722015-10-20 16:29:58 -0700820 } else if (type == META && stream->isMeta()) {
821 return true;
Robert Shihbf207272014-10-30 17:22:11 -0700822 }
823 }
824
825 return false;
826}
827
Andreas Huberbff07d02010-10-12 11:34:37 -0700828int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
Chong Zhang799c9682015-03-02 23:42:38 -0800829 PTS = recoverPTS(PTS);
830
Andreas Huberc4c17d42011-08-30 16:06:28 -0700831 if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
832 if (!mFirstPTSValid) {
833 mFirstPTSValid = true;
834 mFirstPTS = PTS;
835 PTS = 0;
836 } else if (PTS < mFirstPTS) {
837 PTS = 0;
838 } else {
839 PTS -= mFirstPTS;
840 }
Andreas Huberbff07d02010-10-12 11:34:37 -0700841 }
842
Andreas Huber87f2a552012-08-31 13:55:24 -0700843 int64_t timeUs = (PTS * 100) / 9;
844
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800845 if (mParser->mAbsoluteTimeAnchorUs >= 0LL) {
Andreas Huber87f2a552012-08-31 13:55:24 -0700846 timeUs += mParser->mAbsoluteTimeAnchorUs;
847 }
848
Andreas Huberd5e56232013-03-12 11:01:43 -0700849 if (mParser->mTimeOffsetValid) {
850 timeUs += mParser->mTimeOffsetUs;
851 }
852
Andreas Huber87f2a552012-08-31 13:55:24 -0700853 return timeUs;
Andreas Huberbff07d02010-10-12 11:34:37 -0700854}
855
Chong Zhang3b2847f2017-01-18 17:43:03 -0800856void ATSParser::Program::updateCasSessions() {
857 for (size_t i = 0; i < mStreams.size(); ++i) {
858 sp<Stream> &stream = mStreams.editValueAt(i);
859 sp<IDescrambler> descrambler;
860 std::vector<uint8_t> sessionId;
Chong Zhangbc7aae42017-03-31 14:53:19 -0700861 int32_t systemId;
862 if (mParser->mCasManager->getCasInfo(mProgramNumber, stream->pid(),
863 &systemId, &descrambler, &sessionId)) {
864 stream->setCasInfo(systemId, descrambler, sessionId);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800865 }
866 }
867}
868
Andreas Hubercda17c62010-06-07 13:05:37 -0700869////////////////////////////////////////////////////////////////////////////////
Chong Zhang3b2847f2017-01-18 17:43:03 -0800870static const size_t kInitialStreamBufferSize = 192 * 1024;
Andreas Hubercda17c62010-06-07 13:05:37 -0700871
Andreas Huberbff07d02010-10-12 11:34:37 -0700872ATSParser::Stream::Stream(
Chong Zhang7e986a82018-11-07 13:01:08 -0800873 Program *program, unsigned PCR_PID, const StreamInfo &info)
Andreas Huberbff07d02010-10-12 11:34:37 -0700874 : mProgram(program),
Chong Zhang7e986a82018-11-07 13:01:08 -0800875 mElementaryPID(info.mPID),
876 mStreamType(info.mType),
877 mStreamTypeExt(info.mTypeExt),
Andreas Huber87f2a552012-08-31 13:55:24 -0700878 mPCR_PID(PCR_PID),
879 mExpectedContinuityCounter(-1),
Andreas Huber6a63a932010-10-01 10:51:41 -0700880 mPayloadStarted(false),
Marco Nelissenbe9634d2015-04-15 14:33:39 -0700881 mEOSReached(false),
Andreas Huber90a92052012-10-30 15:53:03 -0700882 mPrevPTS(0),
Chong Zhang3b2847f2017-01-18 17:43:03 -0800883 mQueue(NULL),
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100884 mScrambled(info.mCADescriptor.mSystemID >= 0),
885 mAudioPresentations(info.mAudioPresentations) {
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700886 mSampleEncrypted =
887 mStreamType == STREAMTYPE_H264_ENCRYPTED ||
888 mStreamType == STREAMTYPE_AAC_ENCRYPTED ||
889 mStreamType == STREAMTYPE_AC3_ENCRYPTED;
890
891 ALOGV("new stream PID 0x%02x, type 0x%02x, scrambled %d, SampleEncrypted: %d",
Chong Zhang7e986a82018-11-07 13:01:08 -0800892 info.mPID, info.mType, mScrambled, mSampleEncrypted);
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700893
Chong Zhange32a4132018-07-23 14:17:38 -0700894 uint32_t flags = 0;
895 if (((isVideo() || isAudio()) && mScrambled)) {
896 flags = ElementaryStreamQueue::kFlag_ScrambledData;
897 } else if (mSampleEncrypted) {
898 flags = ElementaryStreamQueue::kFlag_SampleEncryptedData;
899 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800900
901 ElementaryStreamQueue::Mode mode = ElementaryStreamQueue::INVALID;
902
Andreas Huber386d6092011-05-19 08:37:39 -0700903 switch (mStreamType) {
904 case STREAMTYPE_H264:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700905 case STREAMTYPE_H264_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800906 mode = ElementaryStreamQueue::H264;
907 flags |= (mProgram->parserFlags() & ALIGNED_VIDEO_DATA) ?
908 ElementaryStreamQueue::kFlag_AlignedData : 0;
Andreas Huber386d6092011-05-19 08:37:39 -0700909 break;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800910
Andreas Huber6e3d3112011-11-28 12:36:11 -0800911 case STREAMTYPE_MPEG2_AUDIO_ADTS:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700912 case STREAMTYPE_AAC_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800913 mode = ElementaryStreamQueue::AAC;
Andreas Huber386d6092011-05-19 08:37:39 -0700914 break;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800915
Andreas Huber386d6092011-05-19 08:37:39 -0700916 case STREAMTYPE_MPEG1_AUDIO:
917 case STREAMTYPE_MPEG2_AUDIO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800918 mode = ElementaryStreamQueue::MPEG_AUDIO;
Andreas Huber386d6092011-05-19 08:37:39 -0700919 break;
920
921 case STREAMTYPE_MPEG1_VIDEO:
922 case STREAMTYPE_MPEG2_VIDEO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800923 mode = ElementaryStreamQueue::MPEG_VIDEO;
Andreas Huber386d6092011-05-19 08:37:39 -0700924 break;
925
926 case STREAMTYPE_MPEG4_VIDEO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800927 mode = ElementaryStreamQueue::MPEG4_VIDEO;
Andreas Huber386d6092011-05-19 08:37:39 -0700928 break;
929
Chong Zhang9bf32f02014-07-30 15:40:31 -0700930 case STREAMTYPE_LPCM_AC3:
Changwan Ryud3c079a2013-10-28 11:08:44 +0900931 case STREAMTYPE_AC3:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700932 case STREAMTYPE_AC3_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800933 mode = ElementaryStreamQueue::AC3;
Changwan Ryud3c079a2013-10-28 11:08:44 +0900934 break;
935
Previr Rangroo68e6fe12017-11-30 20:02:13 -0800936 case STREAMTYPE_EAC3:
937 mode = ElementaryStreamQueue::EAC3;
938 break;
939
Rahul3beba382023-02-03 20:36:55 +0000940 case STREAMTYPE_DTS:
941 mode = ElementaryStreamQueue::DTS;
942 break;
943
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800944 case STREAMTYPE_PES_PRIVATE_DATA:
945 if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) {
946 mode = ElementaryStreamQueue::AC4;
Rahul3beba382023-02-03 20:36:55 +0000947 } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
948 mode = ElementaryStreamQueue::DTS_HD;
949 } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
950 mode = ElementaryStreamQueue::DTS_UHD;
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800951 }
952 break;
953
Robert Shih08528432015-04-08 09:06:54 -0700954 case STREAMTYPE_METADATA:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800955 mode = ElementaryStreamQueue::METADATA;
Robert Shih08528432015-04-08 09:06:54 -0700956 break;
957
Andreas Huber386d6092011-05-19 08:37:39 -0700958 default:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800959 ALOGE("stream PID 0x%02x has invalid stream type 0x%02x",
Chong Zhang7e986a82018-11-07 13:01:08 -0800960 info.mPID, info.mType);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800961 return;
Andreas Huber386d6092011-05-19 08:37:39 -0700962 }
963
Chong Zhang3b2847f2017-01-18 17:43:03 -0800964 mQueue = new ElementaryStreamQueue(mode, flags);
Andreas Huber18ac5402011-08-31 15:04:25 -0700965
966 if (mQueue != NULL) {
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700967 if (mSampleAesKeyItem != NULL) {
968 mQueue->signalNewSampleAesKey(mSampleAesKeyItem);
969 }
970
Chong Zhang3b2847f2017-01-18 17:43:03 -0800971 ensureBufferCapacity(kInitialStreamBufferSize);
972
973 if (mScrambled && (isAudio() || isVideo())) {
974 // Set initial format to scrambled
975 sp<MetaData> meta = new MetaData();
976 meta->setCString(kKeyMIMEType,
977 isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
978 : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
Chong Zhangbc7aae42017-03-31 14:53:19 -0700979 // for MediaExtractor.CasInfo
Chong Zhang7e986a82018-11-07 13:01:08 -0800980 const CADescriptor &descriptor = info.mCADescriptor;
981 meta->setInt32(kKeyCASystemID, descriptor.mSystemID);
982
983 meta->setData(kKeyCAPrivateData, 0,
984 descriptor.mPrivateData.data(),
985 descriptor.mPrivateData.size());
986
Chong Zhang3b2847f2017-01-18 17:43:03 -0800987 mSource = new AnotherPacketSource(meta);
988 }
Andreas Huber18ac5402011-08-31 15:04:25 -0700989 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700990}
991
992ATSParser::Stream::~Stream() {
Andreas Huber386d6092011-05-19 08:37:39 -0700993 delete mQueue;
994 mQueue = NULL;
Andreas Hubercda17c62010-06-07 13:05:37 -0700995}
996
Chong Zhangd5a416a2017-05-16 11:16:34 -0700997bool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
Chong Zhang3b2847f2017-01-18 17:43:03 -0800998 if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
Chong Zhangd5a416a2017-05-16 11:16:34 -0700999 return true;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001000 }
1001
1002 ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
1003 mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);
1004
1005 sp<ABuffer> newBuffer, newScrambledBuffer;
Chong Zhang00c5c052018-12-17 14:15:58 -08001006 sp<TMemory> newMem;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001007 if (mScrambled) {
Devin Moore6482a5b2023-11-08 17:53:52 +00001008 int fd = ashmem_create_region("mediaATS", neededSize);
1009 if (fd < 0) {
1010 ALOGE("[stream %d] create_ashmem_region failed for size %zu. FD returned: %d",
1011 mElementaryPID, neededSize, fd);
1012 return false;
1013 }
1014
1015 native_handle_t* handle = native_handle_create(1 /*numFds*/, 0/*numInts*/);
1016 if (handle == nullptr) {
1017 ALOGE("[stream %d] failed to create a native_handle_t", mElementaryPID);
1018 if (close(fd)) {
1019 ALOGE("[stream %d] failed to close ashmem fd. errno: %s", mElementaryPID,
1020 strerror(errno));
Chong Zhang00c5c052018-12-17 14:15:58 -08001021 }
Chong Zhang00c5c052018-12-17 14:15:58 -08001022
Chong Zhang00c5c052018-12-17 14:15:58 -08001023 return false;
1024 }
Devin Moore6482a5b2023-11-08 17:53:52 +00001025
1026 handle->data[0] = fd;
1027 hidl_handle memHandle;
1028 memHandle.setTo(handle, true /*shouldOwn*/);
1029 hidl_memory hidlMemToken("ashmem", memHandle, neededSize);
1030
Chong Zhang00c5c052018-12-17 14:15:58 -08001031 newMem = mapMemory(hidlMemToken);
1032 if (newMem == nullptr || newMem->getPointer() == nullptr) {
1033 ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
1034 return false;
1035 }
1036
1037 newScrambledBuffer = new ABuffer(newMem->getPointer(), newMem->getSize());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001038
1039 if (mDescrambledBuffer != NULL) {
1040 memcpy(newScrambledBuffer->data(),
1041 mDescrambledBuffer->data(), mDescrambledBuffer->size());
1042 newScrambledBuffer->setRange(0, mDescrambledBuffer->size());
1043 } else {
1044 newScrambledBuffer->setRange(0, 0);
1045 }
Chong Zhang00c5c052018-12-17 14:15:58 -08001046 mHidlMemory = newMem;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001047 mDescrambledBuffer = newScrambledBuffer;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001048
Chong Zhang00c5c052018-12-17 14:15:58 -08001049 mDescramblerSrcBuffer.heapBase = hidlMemToken;
1050 mDescramblerSrcBuffer.offset = 0ULL;
1051 mDescramblerSrcBuffer.size = (uint64_t)neededSize;
Chong Zhang58ddee32018-02-13 17:52:39 -08001052
Chong Zhang00c5c052018-12-17 14:15:58 -08001053 ALOGD("[stream %d] created shared buffer for descrambling, size %zu",
1054 mElementaryPID, neededSize);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001055 } else {
1056 // Align to multiples of 64K.
1057 neededSize = (neededSize + 65535) & ~65535;
1058 }
1059
1060 newBuffer = new ABuffer(neededSize);
1061 if (mBuffer != NULL) {
1062 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
1063 newBuffer->setRange(0, mBuffer->size());
1064 } else {
1065 newBuffer->setRange(0, 0);
1066 }
1067 mBuffer = newBuffer;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001068 return true;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001069}
1070
Andreas Huber54031292011-09-01 11:04:43 -07001071status_t ATSParser::Stream::parse(
Andreas Huber87f2a552012-08-31 13:55:24 -07001072 unsigned continuity_counter,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001073 unsigned payload_unit_start_indicator,
1074 unsigned transport_scrambling_control,
1075 unsigned random_access_indicator,
1076 ABitReader *br, SyncEvent *event) {
Andreas Huber18ac5402011-08-31 15:04:25 -07001077 if (mQueue == NULL) {
Andreas Huber54031292011-09-01 11:04:43 -07001078 return OK;
Andreas Huber18ac5402011-08-31 15:04:25 -07001079 }
1080
Andreas Huber87f2a552012-08-31 13:55:24 -07001081 if (mExpectedContinuityCounter >= 0
1082 && (unsigned)mExpectedContinuityCounter != continuity_counter) {
1083 ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
1084
1085 mPayloadStarted = false;
Wei Jia9558f6d2016-03-08 17:31:16 -08001086 mPesStartOffsets.clear();
Andreas Huber87f2a552012-08-31 13:55:24 -07001087 mBuffer->setRange(0, 0);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001088 mSubSamples.clear();
Andreas Huber87f2a552012-08-31 13:55:24 -07001089 mExpectedContinuityCounter = -1;
1090
Andreas Huber94a483b2013-01-29 09:22:16 -08001091#if 0
1092 // Uncomment this if you'd rather see no corruption whatsoever on
1093 // screen and suspend updates until we come across another IDR frame.
1094
1095 if (mStreamType == STREAMTYPE_H264) {
1096 ALOGI("clearing video queue");
1097 mQueue->clear(true /* clearFormat */);
1098 }
1099#endif
1100
Chong Zhang66830852014-06-05 14:44:03 -07001101 if (!payload_unit_start_indicator) {
1102 return OK;
1103 }
Andreas Huber87f2a552012-08-31 13:55:24 -07001104 }
1105
1106 mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f;
1107
Andreas Hubercda17c62010-06-07 13:05:37 -07001108 if (payload_unit_start_indicator) {
Wonsik Kim54000662015-04-13 10:59:06 +09001109 off64_t offset = (event != NULL) ? event->getOffset() : 0;
Andreas Hubercda17c62010-06-07 13:05:37 -07001110 if (mPayloadStarted) {
1111 // Otherwise we run the danger of receiving the trailing bytes
1112 // of a PES packet that we never saw the start of and assuming
1113 // we have a a complete PES packet.
1114
Wonsik Kim54000662015-04-13 10:59:06 +09001115 status_t err = flush(event);
Andreas Huber54031292011-09-01 11:04:43 -07001116
1117 if (err != OK) {
Wonsik Kim65959d32015-06-10 16:17:45 +09001118 ALOGW("Error (%08x) happened while flushing; we simply discard "
1119 "the PES packet and continue.", err);
Andreas Huber54031292011-09-01 11:04:43 -07001120 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001121 }
1122
1123 mPayloadStarted = true;
Wei Jiab08d83e2016-09-30 17:39:30 -07001124 // There should be at most 2 elements in |mPesStartOffsets|.
1125 while (mPesStartOffsets.size() >= 2) {
1126 mPesStartOffsets.erase(mPesStartOffsets.begin());
1127 }
Wei Jia9558f6d2016-03-08 17:31:16 -08001128 mPesStartOffsets.push_back(offset);
Andreas Hubercda17c62010-06-07 13:05:37 -07001129 }
1130
1131 if (!mPayloadStarted) {
Andreas Huber54031292011-09-01 11:04:43 -07001132 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001133 }
1134
1135 size_t payloadSizeBits = br->numBitsLeft();
Jinsuk Kime314c672015-04-22 11:08:28 +09001136 if (payloadSizeBits % 8 != 0u) {
1137 ALOGE("Wrong value");
1138 return BAD_VALUE;
1139 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001140
Andreas Huber3e573222011-03-02 16:18:33 -08001141 size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001142 if (!ensureBufferCapacity(neededSize)) {
1143 return NO_MEMORY;
1144 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001145
1146 memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
1147 mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
Andreas Huber54031292011-09-01 11:04:43 -07001148
Chong Zhang3b2847f2017-01-18 17:43:03 -08001149 if (mScrambled) {
1150 mSubSamples.push_back({payloadSizeBits / 8,
1151 transport_scrambling_control, random_access_indicator});
1152 }
1153
Andreas Huber54031292011-09-01 11:04:43 -07001154 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001155}
1156
Andreas Huber6e3d3112011-11-28 12:36:11 -08001157bool ATSParser::Stream::isVideo() const {
1158 switch (mStreamType) {
1159 case STREAMTYPE_H264:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001160 case STREAMTYPE_H264_ENCRYPTED:
Andreas Huber6e3d3112011-11-28 12:36:11 -08001161 case STREAMTYPE_MPEG1_VIDEO:
1162 case STREAMTYPE_MPEG2_VIDEO:
1163 case STREAMTYPE_MPEG4_VIDEO:
1164 return true;
1165
1166 default:
1167 return false;
1168 }
1169}
1170
1171bool ATSParser::Stream::isAudio() const {
1172 switch (mStreamType) {
1173 case STREAMTYPE_MPEG1_AUDIO:
1174 case STREAMTYPE_MPEG2_AUDIO:
1175 case STREAMTYPE_MPEG2_AUDIO_ADTS:
Chong Zhang9bf32f02014-07-30 15:40:31 -07001176 case STREAMTYPE_LPCM_AC3:
Changwan Ryud3c079a2013-10-28 11:08:44 +09001177 case STREAMTYPE_AC3:
Previr Rangroo68e6fe12017-11-30 20:02:13 -08001178 case STREAMTYPE_EAC3:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001179 case STREAMTYPE_AAC_ENCRYPTED:
1180 case STREAMTYPE_AC3_ENCRYPTED:
Rahul3beba382023-02-03 20:36:55 +00001181 case STREAMTYPE_DTS:
Andreas Huber6e3d3112011-11-28 12:36:11 -08001182 return true;
Previr Rangroo7e6ac732017-11-13 20:20:20 -08001183 case STREAMTYPE_PES_PRIVATE_DATA:
Rahul3beba382023-02-03 20:36:55 +00001184 return (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4
1185 || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD
1186 || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD);
Andreas Huber6e3d3112011-11-28 12:36:11 -08001187
1188 default:
1189 return false;
1190 }
1191}
1192
Robert Shih08528432015-04-08 09:06:54 -07001193bool ATSParser::Stream::isMeta() const {
1194 if (mStreamType == STREAMTYPE_METADATA) {
1195 return true;
1196 }
1197 return false;
1198}
1199
Andreas Huber32f3cef2011-03-02 15:34:46 -08001200void ATSParser::Stream::signalDiscontinuity(
1201 DiscontinuityType type, const sp<AMessage> &extra) {
Marco Nelissen0389cc02012-10-02 10:47:39 -07001202 mExpectedContinuityCounter = -1;
1203
Andreas Huber18ac5402011-08-31 15:04:25 -07001204 if (mQueue == NULL) {
1205 return;
1206 }
1207
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001208 mPayloadStarted = false;
Wei Jia9558f6d2016-03-08 17:31:16 -08001209 mPesStartOffsets.clear();
Robert Shihaabbdc72015-05-08 17:39:40 -07001210 mEOSReached = false;
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001211 mBuffer->setRange(0, 0);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001212 mSubSamples.clear();
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001213
Andreas Huber6e3d3112011-11-28 12:36:11 -08001214 bool clearFormat = false;
1215 if (isAudio()) {
1216 if (type & DISCONTINUITY_AUDIO_FORMAT) {
1217 clearFormat = true;
Andreas Huberf9334412010-12-15 15:17:42 -08001218 }
Andreas Huber6e3d3112011-11-28 12:36:11 -08001219 } else {
1220 if (type & DISCONTINUITY_VIDEO_FORMAT) {
1221 clearFormat = true;
1222 }
1223 }
Andreas Huberf9334412010-12-15 15:17:42 -08001224
Andreas Huber6e3d3112011-11-28 12:36:11 -08001225 mQueue->clear(clearFormat);
1226
1227 if (type & DISCONTINUITY_TIME) {
1228 uint64_t resumeAtPTS;
1229 if (extra != NULL
1230 && extra->findInt64(
Dongwon Kang15d02f82017-12-14 16:32:18 -08001231 kATSParserKeyResumeAtPTS,
Andreas Huber6e3d3112011-11-28 12:36:11 -08001232 (int64_t *)&resumeAtPTS)) {
1233 int64_t resumeAtMediaTimeUs =
1234 mProgram->convertPTSToTimestamp(resumeAtPTS);
1235
Wei Jiac6cfd702014-11-11 16:33:20 -08001236 extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs);
Andreas Huber6e3d3112011-11-28 12:36:11 -08001237 }
1238 }
1239
1240 if (mSource != NULL) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001241 sp<MetaData> meta = mSource->getFormat();
1242 const char* mime;
1243 if (clearFormat && meta != NULL && meta->findCString(kKeyMIMEType, &mime)
1244 && (!strncasecmp(mime, MEDIA_MIMETYPE_AUDIO_SCRAMBLED, 15)
1245 || !strncasecmp(mime, MEDIA_MIMETYPE_VIDEO_SCRAMBLED, 15))){
1246 mSource->clear();
1247 } else {
1248 mSource->queueDiscontinuity(type, extra, true);
1249 }
Andreas Huberf9334412010-12-15 15:17:42 -08001250 }
1251}
1252
1253void ATSParser::Stream::signalEOS(status_t finalResult) {
1254 if (mSource != NULL) {
1255 mSource->signalEOS(finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001256 }
Marco Nelissenbe9634d2015-04-15 14:33:39 -07001257 mEOSReached = true;
Wonsik Kim54000662015-04-13 10:59:06 +09001258 flush(NULL);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001259}
1260
Wonsik Kim54000662015-04-13 10:59:06 +09001261status_t ATSParser::Stream::parsePES(ABitReader *br, SyncEvent *event) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001262 const uint8_t *basePtr = br->data();
1263
Andreas Hubercda17c62010-06-07 13:05:37 -07001264 unsigned packet_startcode_prefix = br->getBits(24);
1265
Steve Block3856b092011-10-20 11:56:00 +01001266 ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
Andreas Hubercda17c62010-06-07 13:05:37 -07001267
Andreas Huber386d6092011-05-19 08:37:39 -07001268 if (packet_startcode_prefix != 1) {
Steve Block3856b092011-10-20 11:56:00 +01001269 ALOGV("Supposedly payload_unit_start=1 unit does not start "
Andreas Huber386d6092011-05-19 08:37:39 -07001270 "with startcode.");
Andreas Huber54031292011-09-01 11:04:43 -07001271
1272 return ERROR_MALFORMED;
Andreas Huber386d6092011-05-19 08:37:39 -07001273 }
1274
Andreas Hubercda17c62010-06-07 13:05:37 -07001275 unsigned stream_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01001276 ALOGV("stream_id = 0x%02x", stream_id);
Andreas Hubercda17c62010-06-07 13:05:37 -07001277
1278 unsigned PES_packet_length = br->getBits(16);
Steve Block3856b092011-10-20 11:56:00 +01001279 ALOGV("PES_packet_length = %u", PES_packet_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07001280
1281 if (stream_id != 0xbc // program_stream_map
1282 && stream_id != 0xbe // padding_stream
1283 && stream_id != 0xbf // private_stream_2
1284 && stream_id != 0xf0 // ECM
1285 && stream_id != 0xf1 // EMM
1286 && stream_id != 0xff // program_stream_directory
1287 && stream_id != 0xf2 // DSMCC
1288 && stream_id != 0xf8) { // H.222.1 type E
Jinsuk Kime314c672015-04-22 11:08:28 +09001289 if (br->getBits(2) != 2u) {
1290 return ERROR_MALFORMED;
1291 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001292
Chong Zhang3b2847f2017-01-18 17:43:03 -08001293 unsigned PES_scrambling_control = br->getBits(2);
1294 ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
1295
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001296 MY_LOGV("PES_priority = %u", br->getBits(1));
1297 MY_LOGV("data_alignment_indicator = %u", br->getBits(1));
1298 MY_LOGV("copyright = %u", br->getBits(1));
1299 MY_LOGV("original_or_copy = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07001300
1301 unsigned PTS_DTS_flags = br->getBits(2);
Steve Block3856b092011-10-20 11:56:00 +01001302 ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags);
Andreas Hubercda17c62010-06-07 13:05:37 -07001303
1304 unsigned ESCR_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001305 ALOGV("ESCR_flag = %u", ESCR_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001306
1307 unsigned ES_rate_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001308 ALOGV("ES_rate_flag = %u", ES_rate_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001309
1310 unsigned DSM_trick_mode_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001311 ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001312
1313 unsigned additional_copy_info_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001314 ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001315
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001316 MY_LOGV("PES_CRC_flag = %u", br->getBits(1));
1317 MY_LOGV("PES_extension_flag = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07001318
1319 unsigned PES_header_data_length = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01001320 ALOGV("PES_header_data_length = %u", PES_header_data_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07001321
1322 unsigned optional_bytes_remaining = PES_header_data_length;
1323
1324 uint64_t PTS = 0, DTS = 0;
1325
1326 if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001327 if (optional_bytes_remaining < 5u) {
1328 return ERROR_MALFORMED;
1329 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001330
David Yeh6456ae72014-09-03 11:14:48 +08001331 if (br->getBits(4) != PTS_DTS_flags) {
David Yeh6456ae72014-09-03 11:14:48 +08001332 return ERROR_MALFORMED;
1333 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001334 PTS = ((uint64_t)br->getBits(3)) << 30;
Jinsuk Kime314c672015-04-22 11:08:28 +09001335 if (br->getBits(1) != 1u) {
1336 return ERROR_MALFORMED;
1337 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001338 PTS |= ((uint64_t)br->getBits(15)) << 15;
Jinsuk Kime314c672015-04-22 11:08:28 +09001339 if (br->getBits(1) != 1u) {
1340 return ERROR_MALFORMED;
1341 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001342 PTS |= br->getBits(15);
Jinsuk Kime314c672015-04-22 11:08:28 +09001343 if (br->getBits(1) != 1u) {
1344 return ERROR_MALFORMED;
1345 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001346
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001347 ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);
Andreas Hubercda17c62010-06-07 13:05:37 -07001348
1349 optional_bytes_remaining -= 5;
1350
1351 if (PTS_DTS_flags == 3) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001352 if (optional_bytes_remaining < 5u) {
1353 return ERROR_MALFORMED;
1354 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001355
Jinsuk Kime314c672015-04-22 11:08:28 +09001356 if (br->getBits(4) != 1u) {
1357 return ERROR_MALFORMED;
1358 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001359
1360 DTS = ((uint64_t)br->getBits(3)) << 30;
Jinsuk Kime314c672015-04-22 11:08:28 +09001361 if (br->getBits(1) != 1u) {
1362 return ERROR_MALFORMED;
1363 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001364 DTS |= ((uint64_t)br->getBits(15)) << 15;
Jinsuk Kime314c672015-04-22 11:08:28 +09001365 if (br->getBits(1) != 1u) {
1366 return ERROR_MALFORMED;
1367 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001368 DTS |= br->getBits(15);
Jinsuk Kime314c672015-04-22 11:08:28 +09001369 if (br->getBits(1) != 1u) {
1370 return ERROR_MALFORMED;
1371 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001372
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001373 ALOGV("DTS = %" PRIu64, DTS);
Andreas Hubercda17c62010-06-07 13:05:37 -07001374
1375 optional_bytes_remaining -= 5;
1376 }
1377 }
1378
1379 if (ESCR_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001380 if (optional_bytes_remaining < 6u) {
1381 return ERROR_MALFORMED;
1382 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001383
1384 br->getBits(2);
1385
1386 uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
Jinsuk Kime314c672015-04-22 11:08:28 +09001387 if (br->getBits(1) != 1u) {
1388 return ERROR_MALFORMED;
1389 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001390 ESCR |= ((uint64_t)br->getBits(15)) << 15;
Jinsuk Kime314c672015-04-22 11:08:28 +09001391 if (br->getBits(1) != 1u) {
1392 return ERROR_MALFORMED;
1393 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001394 ESCR |= br->getBits(15);
Jinsuk Kime314c672015-04-22 11:08:28 +09001395 if (br->getBits(1) != 1u) {
1396 return ERROR_MALFORMED;
1397 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001398
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001399 ALOGV("ESCR = %" PRIu64, ESCR);
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001400 MY_LOGV("ESCR_extension = %u", br->getBits(9));
Andreas Hubercda17c62010-06-07 13:05:37 -07001401
Jinsuk Kime314c672015-04-22 11:08:28 +09001402 if (br->getBits(1) != 1u) {
1403 return ERROR_MALFORMED;
1404 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001405
1406 optional_bytes_remaining -= 6;
1407 }
1408
1409 if (ES_rate_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001410 if (optional_bytes_remaining < 3u) {
1411 return ERROR_MALFORMED;
1412 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001413
Jinsuk Kime314c672015-04-22 11:08:28 +09001414 if (br->getBits(1) != 1u) {
1415 return ERROR_MALFORMED;
1416 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001417 MY_LOGV("ES_rate = %u", br->getBits(22));
Jinsuk Kime314c672015-04-22 11:08:28 +09001418 if (br->getBits(1) != 1u) {
1419 return ERROR_MALFORMED;
1420 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001421
1422 optional_bytes_remaining -= 3;
1423 }
1424
1425 br->skipBits(optional_bytes_remaining * 8);
1426
1427 // ES data follows.
Chong Zhang3b2847f2017-01-18 17:43:03 -08001428 int32_t pesOffset = br->data() - basePtr;
Andreas Hubercda17c62010-06-07 13:05:37 -07001429
Andreas Hubercda17c62010-06-07 13:05:37 -07001430 if (PES_packet_length != 0) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001431 if (PES_packet_length < PES_header_data_length + 3) {
1432 return ERROR_MALFORMED;
1433 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001434
1435 unsigned dataLength =
1436 PES_packet_length - 3 - PES_header_data_length;
1437
Andreas Huber54031292011-09-01 11:04:43 -07001438 if (br->numBitsLeft() < dataLength * 8) {
Steve Block29357bc2012-01-06 19:20:56 +00001439 ALOGE("PES packet does not carry enough data to contain "
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001440 "payload. (numBitsLeft = %zu, required = %u)",
Andreas Huber54031292011-09-01 11:04:43 -07001441 br->numBitsLeft(), dataLength * 8);
1442
1443 return ERROR_MALFORMED;
1444 }
1445
Chong Zhang3b2847f2017-01-18 17:43:03 -08001446 ALOGV("There's %u bytes of payload, PES_packet_length=%u, offset=%d",
1447 dataLength, PES_packet_length, pesOffset);
1448
Andreas Huber0da4dab2010-09-27 12:04:43 -07001449 onPayloadData(
Chong Zhang3b2847f2017-01-18 17:43:03 -08001450 PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
1451 br->data(), dataLength, pesOffset, event);
Andreas Hubercda17c62010-06-07 13:05:37 -07001452
1453 br->skipBits(dataLength * 8);
1454 } else {
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(), br->numBitsLeft() / 8, pesOffset, event);
Andreas Huber0da4dab2010-09-27 12:04:43 -07001458
Andreas Hubercda17c62010-06-07 13:05:37 -07001459 size_t payloadSizeBits = br->numBitsLeft();
Jinsuk Kime314c672015-04-22 11:08:28 +09001460 if (payloadSizeBits % 8 != 0u) {
1461 return ERROR_MALFORMED;
1462 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001463
Chong Zhang3b2847f2017-01-18 17:43:03 -08001464 ALOGV("There's %zu bytes of payload, offset=%d",
1465 payloadSizeBits / 8, pesOffset);
Andreas Hubercda17c62010-06-07 13:05:37 -07001466 }
1467 } else if (stream_id == 0xbe) { // padding_stream
Jinsuk Kime314c672015-04-22 11:08:28 +09001468 if (PES_packet_length == 0u) {
1469 return ERROR_MALFORMED;
1470 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001471 br->skipBits(PES_packet_length * 8);
1472 } else {
Jinsuk Kime314c672015-04-22 11:08:28 +09001473 if (PES_packet_length == 0u) {
1474 return ERROR_MALFORMED;
1475 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001476 br->skipBits(PES_packet_length * 8);
1477 }
Andreas Huber54031292011-09-01 11:04:43 -07001478
1479 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001480}
1481
Chong Zhang3b2847f2017-01-18 17:43:03 -08001482uint32_t ATSParser::Stream::getPesScramblingControl(
1483 ABitReader *br, int32_t *pesOffset) {
1484 unsigned packet_startcode_prefix = br->getBits(24);
1485
1486 ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
1487
1488 if (packet_startcode_prefix != 1) {
1489 ALOGV("unit does not start with startcode.");
1490 return 0;
1491 }
1492
1493 if (br->numBitsLeft() < 48) {
1494 return 0;
1495 }
1496
1497 unsigned stream_id = br->getBits(8);
1498 ALOGV("stream_id = 0x%02x", stream_id);
1499
1500 br->skipBits(16); // PES_packet_length
1501
1502 if (stream_id != 0xbc // program_stream_map
1503 && stream_id != 0xbe // padding_stream
1504 && stream_id != 0xbf // private_stream_2
1505 && stream_id != 0xf0 // ECM
1506 && stream_id != 0xf1 // EMM
1507 && stream_id != 0xff // program_stream_directory
1508 && stream_id != 0xf2 // DSMCC
1509 && stream_id != 0xf8) { // H.222.1 type E
1510 if (br->getBits(2) != 2u) {
1511 return 0;
1512 }
1513
1514 unsigned PES_scrambling_control = br->getBits(2);
1515 ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
1516
1517 if (PES_scrambling_control == 0) {
1518 return 0;
1519 }
1520
1521 br->skipBits(12); // don't care
1522
1523 unsigned PES_header_data_length = br->getBits(8);
1524 ALOGV("PES_header_data_length = %u", PES_header_data_length);
1525
1526 if (PES_header_data_length * 8 > br->numBitsLeft()) {
1527 return 0;
1528 }
1529
1530 *pesOffset = 9 + PES_header_data_length;
1531 ALOGD("found PES_scrambling_control=%d, PES offset=%d",
1532 PES_scrambling_control, *pesOffset);
1533 return PES_scrambling_control;
1534 }
1535
1536 return 0;
1537}
1538
1539status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
1540 if (mDescrambler == NULL) {
1541 ALOGE("received scrambled packets without descrambler!");
1542 return UNKNOWN_ERROR;
1543 }
1544
Chong Zhang00c5c052018-12-17 14:15:58 -08001545 if (mDescrambledBuffer == NULL || mHidlMemory == NULL) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001546 ALOGE("received scrambled packets without shared memory!");
1547
1548 return UNKNOWN_ERROR;
1549 }
1550
1551 int32_t pesOffset = 0;
1552 int32_t descrambleSubSamples = 0, descrambleBytes = 0;
1553 uint32_t tsScramblingControl = 0, pesScramblingControl = 0;
1554
1555 // First, go over subsamples to find TS-level scrambling key id, and
1556 // calculate how many subsample we need to descramble (assuming we don't
1557 // have PES-level scrambling).
1558 for (auto it = mSubSamples.begin(); it != mSubSamples.end(); it++) {
1559 if (it->transport_scrambling_mode != 0) {
1560 // TODO: handle keyId change, use the first non-zero keyId for now.
1561 if (tsScramblingControl == 0) {
1562 tsScramblingControl = it->transport_scrambling_mode;
1563 }
1564 }
1565 if (tsScramblingControl == 0 || descrambleSubSamples == 0
1566 || !mQueue->isScrambled()) {
1567 descrambleSubSamples++;
1568 descrambleBytes += it->subSampleSize;
1569 }
1570 }
1571 // If not scrambled at TS-level, check PES-level scrambling
1572 if (tsScramblingControl == 0) {
1573 ABitReader br(mBuffer->data(), mBuffer->size());
1574 pesScramblingControl = getPesScramblingControl(&br, &pesOffset);
1575 // If not scrambled at PES-level either, or scrambled at PES-level but
1576 // requires output to remain scrambled, we don't need to descramble
1577 // anything.
1578 if (pesScramblingControl == 0 || mQueue->isScrambled()) {
1579 descrambleSubSamples = 0;
1580 descrambleBytes = 0;
1581 }
1582 }
1583
1584 uint32_t sctrl = tsScramblingControl != 0 ?
1585 tsScramblingControl : pesScramblingControl;
Chong Zhangd1af6412018-02-20 10:59:37 -08001586 if (mQueue->isScrambled()) {
1587 sctrl |= DescramblerPlugin::kScrambling_Flag_PesHeader;
1588 }
Chong Zhang3b2847f2017-01-18 17:43:03 -08001589
1590 // Perform the 1st pass descrambling if needed
1591 if (descrambleBytes > 0) {
1592 memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001593 mDescrambledBuffer->setRange(0, mBuffer->size());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001594
Chong Zhangd5a416a2017-05-16 11:16:34 -07001595 hidl_vec<SubSample> subSamples;
1596 subSamples.resize(descrambleSubSamples);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001597
1598 int32_t i = 0;
1599 for (auto it = mSubSamples.begin();
1600 it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
1601 if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
Chong Zhangd5a416a2017-05-16 11:16:34 -07001602 subSamples[i].numBytesOfClearData = 0;
1603 subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001604 } else {
Chong Zhangd5a416a2017-05-16 11:16:34 -07001605 subSamples[i].numBytesOfClearData = it->subSampleSize;
1606 subSamples[i].numBytesOfEncryptedData = 0;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001607 }
1608 }
Chong Zhangd5a416a2017-05-16 11:16:34 -07001609
Chong Zhangb2451bb2018-07-12 12:19:12 -07001610 // If scrambled at PES-level, PES header is in the clear
Chong Zhang3b2847f2017-01-18 17:43:03 -08001611 if (pesScramblingControl != 0) {
Chong Zhangb2451bb2018-07-12 12:19:12 -07001612 subSamples[0].numBytesOfClearData = pesOffset;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001613 subSamples[0].numBytesOfEncryptedData -= pesOffset;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001614 }
1615
Chong Zhangd5a416a2017-05-16 11:16:34 -07001616 Status status = Status::OK;
1617 uint32_t bytesWritten = 0;
1618 hidl_string detailedError;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001619
Chong Zhangd5a416a2017-05-16 11:16:34 -07001620 DestinationBuffer dstBuffer;
1621 dstBuffer.type = BufferType::SHARED_MEMORY;
1622 dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;
1623
1624 auto returnVoid = mDescrambler->descramble(
1625 (ScramblingControl) sctrl,
1626 subSamples,
1627 mDescramblerSrcBuffer,
Chong Zhangb2451bb2018-07-12 12:19:12 -07001628 0 /*srcOffset*/,
Chong Zhangd5a416a2017-05-16 11:16:34 -07001629 dstBuffer,
Chong Zhangb2451bb2018-07-12 12:19:12 -07001630 0 /*dstOffset*/,
Chong Zhangd5a416a2017-05-16 11:16:34 -07001631 [&status, &bytesWritten, &detailedError] (
1632 Status _status, uint32_t _bytesWritten,
1633 const hidl_string& _detailedError) {
1634 status = _status;
1635 bytesWritten = _bytesWritten;
1636 detailedError = _detailedError;
1637 });
1638
Chong Zhangf03d9352019-01-04 11:24:47 -08001639 if (!returnVoid.isOk() || status != Status::OK) {
1640 ALOGE("[stream %d] descramble failed, trans=%s, status=%d",
1641 mElementaryPID, returnVoid.description().c_str(), status);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001642 return UNKNOWN_ERROR;
1643 }
1644
1645 ALOGV("[stream %d] descramble succeeded, %d bytes",
Chong Zhangd5a416a2017-05-16 11:16:34 -07001646 mElementaryPID, bytesWritten);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001647
1648 // Set descrambleBytes to the returned result.
1649 // Note that this might be smaller than the total length of input data.
1650 // (eg. when we're descrambling the PES header portion of a secure stream,
1651 // the plugin might cut it off right after the PES header.)
1652 descrambleBytes = bytesWritten;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001653 }
1654
Chong Zhange32a4132018-07-23 14:17:38 -07001655 // |buffer| points to the buffer from which we'd parse the PES header.
1656 // When the output stream is scrambled, it points to mDescrambledBuffer
1657 // (unless all packets in this PES are actually clear, in which case,
1658 // it points to mBuffer since we never copied into mDescrambledBuffer).
1659 // When the output stream is clear, it points to mBuffer, and we'll
1660 // copy all descrambled data back to mBuffer.
1661 sp<ABuffer> buffer = mBuffer;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001662 if (mQueue->isScrambled()) {
1663 // Queue subSample info for scrambled queue
1664 sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
1665 sp<ABuffer> encSizesBuffer = new ABuffer(mSubSamples.size() * 4);
1666 int32_t *clearSizePtr = (int32_t*)clearSizesBuffer->data();
1667 int32_t *encSizePtr = (int32_t*)encSizesBuffer->data();
1668 int32_t isSync = 0;
1669 int32_t i = 0;
1670 for (auto it = mSubSamples.begin();
1671 it != mSubSamples.end(); it++, i++) {
1672 if ((it->transport_scrambling_mode == 0
Chong Zhangb2451bb2018-07-12 12:19:12 -07001673 && pesScramblingControl == 0)) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001674 clearSizePtr[i] = it->subSampleSize;
1675 encSizePtr[i] = 0;
1676 } else {
1677 clearSizePtr[i] = 0;
1678 encSizePtr[i] = it->subSampleSize;
1679 }
1680 isSync |= it->random_access_indicator;
1681 }
Chong Zhangb2451bb2018-07-12 12:19:12 -07001682
1683 // If scrambled at PES-level, PES header is in the clear
1684 if (pesScramblingControl != 0) {
1685 clearSizePtr[0] = pesOffset;
1686 encSizePtr[0] -= pesOffset;
1687 }
Chong Zhang3b2847f2017-01-18 17:43:03 -08001688 // Pass the original TS subsample size now. The PES header adjust
1689 // will be applied when the scrambled AU is dequeued.
Chong Zhange32a4132018-07-23 14:17:38 -07001690 // Note that if descrambleBytes is 0, it means this PES contains only
1691 // all ts packets, leadingClearBytes is entire buffer size.
Chong Zhang3b2847f2017-01-18 17:43:03 -08001692 mQueue->appendScrambledData(
Chong Zhange32a4132018-07-23 14:17:38 -07001693 mBuffer->data(), mBuffer->size(),
1694 (descrambleBytes > 0) ? descrambleBytes : mBuffer->size(),
1695 sctrl, isSync, clearSizesBuffer, encSizesBuffer);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001696
Chong Zhange32a4132018-07-23 14:17:38 -07001697 if (descrambleBytes > 0) {
1698 buffer = mDescrambledBuffer;
1699 }
Chong Zhangb2451bb2018-07-12 12:19:12 -07001700 } else {
1701 memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001702 }
1703
Chong Zhangb2451bb2018-07-12 12:19:12 -07001704 ABitReader br(buffer->data(), buffer->size());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001705 status_t err = parsePES(&br, event);
1706
1707 if (err != OK) {
1708 ALOGE("[stream %d] failed to parse descrambled PES, err=%d",
1709 mElementaryPID, err);
1710 }
1711
1712 return err;
1713}
1714
1715
Wonsik Kim54000662015-04-13 10:59:06 +09001716status_t ATSParser::Stream::flush(SyncEvent *event) {
Jaesung Chungf2cecd52015-05-21 14:23:07 +09001717 if (mBuffer == NULL || mBuffer->size() == 0) {
Andreas Huber54031292011-09-01 11:04:43 -07001718 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001719 }
1720
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001721 ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size());
Andreas Hubercda17c62010-06-07 13:05:37 -07001722
Chong Zhang3b2847f2017-01-18 17:43:03 -08001723 status_t err = OK;
1724 if (mScrambled) {
1725 err = flushScrambled(event);
1726 mSubSamples.clear();
1727 } else {
1728 ABitReader br(mBuffer->data(), mBuffer->size());
1729 err = parsePES(&br, event);
1730 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001731
1732 mBuffer->setRange(0, 0);
Andreas Huber54031292011-09-01 11:04:43 -07001733
1734 return err;
Andreas Hubercda17c62010-06-07 13:05:37 -07001735}
1736
Sampath Shettyc6148a62018-12-18 15:50:43 +11001737void ATSParser::Stream::addAudioPresentations(const sp<ABuffer> &buffer) {
1738 std::ostringstream outStream(std::ios::out);
1739 serializeAudioPresentations(mAudioPresentations, &outStream);
1740 sp<ABuffer> ap = ABuffer::CreateAsCopy(outStream.str().data(), outStream.str().size());
1741 buffer->meta()->setBuffer("audio-presentation-info", ap);
1742}
1743
Andreas Hubercda17c62010-06-07 13:05:37 -07001744void ATSParser::Stream::onPayloadData(
Andreas Huber84333e02014-02-07 15:36:10 -08001745 unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001746 unsigned PES_scrambling_control,
1747 const uint8_t *data, size_t size,
1748 int32_t payloadOffset, SyncEvent *event) {
Andreas Huber90a92052012-10-30 15:53:03 -07001749#if 0
1750 ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
1751 mStreamType,
1752 PTS,
1753 (int64_t)PTS - mPrevPTS);
1754 mPrevPTS = PTS;
1755#endif
1756
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001757 ALOGV("onPayloadData mStreamType=0x%02x size: %zu", mStreamType, size);
Andreas Hubercda17c62010-06-07 13:05:37 -07001758
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001759 int64_t timeUs = 0LL; // no presentation timestamp available.
Andreas Huber98a46cf2011-10-12 12:14:23 -07001760 if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
1761 timeUs = mProgram->convertPTSToTimestamp(PTS);
1762 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001763
Chong Zhang3b2847f2017-01-18 17:43:03 -08001764 status_t err = mQueue->appendData(
1765 data, size, timeUs, payloadOffset, PES_scrambling_control);
Andreas Huberdecd9692010-12-02 13:27:47 -08001766
Marco Nelissenbe9634d2015-04-15 14:33:39 -07001767 if (mEOSReached) {
1768 mQueue->signalEOS();
1769 }
1770
Andreas Huberdecd9692010-12-02 13:27:47 -08001771 if (err != OK) {
1772 return;
1773 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001774
Andreas Huber6a63a932010-10-01 10:51:41 -07001775 sp<ABuffer> accessUnit;
Wonsik Kim54000662015-04-13 10:59:06 +09001776 bool found = false;
Andreas Huber386d6092011-05-19 08:37:39 -07001777 while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
Andreas Huber6a63a932010-10-01 10:51:41 -07001778 if (mSource == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07001779 sp<MetaData> meta = mQueue->getFormat();
Andreas Hubercda17c62010-06-07 13:05:37 -07001780
Andreas Huber6a63a932010-10-01 10:51:41 -07001781 if (meta != NULL) {
Steve Block3856b092011-10-20 11:56:00 +01001782 ALOGV("Stream PID 0x%08x of type 0x%02x now has data.",
Andreas Huber386d6092011-05-19 08:37:39 -07001783 mElementaryPID, mStreamType);
1784
Robert Shih309aa8b2014-07-29 18:34:36 -07001785 const char *mime;
1786 if (meta->findCString(kKeyMIMEType, &mime)
Chong Zhang3b2847f2017-01-18 17:43:03 -08001787 && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1788 int32_t sync = 0;
1789 if (!accessUnit->meta()->findInt32("isSync", &sync) || !sync) {
1790 continue;
1791 }
Robert Shih309aa8b2014-07-29 18:34:36 -07001792 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001793 mSource = new AnotherPacketSource(meta);
Sampath Shettyc6148a62018-12-18 15:50:43 +11001794 if (mAudioPresentations.size() > 0) {
1795 addAudioPresentations(accessUnit);
1796 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001797 mSource->queueAccessUnit(accessUnit);
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001798 ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
1799 mElementaryPID, mStreamType);
Andreas Huber82f73212010-09-01 12:22:36 -07001800 }
Andreas Huber386d6092011-05-19 08:37:39 -07001801 } else if (mQueue->getFormat() != NULL) {
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001802 // After a discontinuity we invalidate the queue's format
1803 // and won't enqueue any access units to the source until
1804 // the queue has reestablished the new format.
Andreas Huber5bc087c2010-12-23 10:27:40 -08001805
1806 if (mSource->getFormat() == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07001807 mSource->setFormat(mQueue->getFormat());
Andreas Huber5bc087c2010-12-23 10:27:40 -08001808 }
Sampath Shettyc6148a62018-12-18 15:50:43 +11001809 if (mAudioPresentations.size() > 0) {
1810 addAudioPresentations(accessUnit);
1811 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001812 mSource->queueAccessUnit(accessUnit);
Andreas Huber82f73212010-09-01 12:22:36 -07001813 }
Wonsik Kim54000662015-04-13 10:59:06 +09001814
Wei Jiab08d83e2016-09-30 17:39:30 -07001815 // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
1816 off64_t pesStartOffset = -1;
1817 if (!mPesStartOffsets.empty()) {
1818 pesStartOffset = *mPesStartOffsets.begin();
1819 mPesStartOffsets.erase(mPesStartOffsets.begin());
1820 }
1821
1822 if (pesStartOffset >= 0 && (event != NULL) && !found && mQueue->getFormat() != NULL) {
Wonsik Kim54000662015-04-13 10:59:06 +09001823 int32_t sync = 0;
1824 if (accessUnit->meta()->findInt32("isSync", &sync) && sync) {
1825 int64_t timeUs;
1826 if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
1827 found = true;
Robert Shih82e14702016-11-17 11:24:29 -08001828 event->init(pesStartOffset, mSource, timeUs, getSourceType());
Wonsik Kim54000662015-04-13 10:59:06 +09001829 }
1830 }
1831 }
Andreas Huber82f73212010-09-01 12:22:36 -07001832 }
Andreas Huber82f73212010-09-01 12:22:36 -07001833}
1834
Robert Shih82e14702016-11-17 11:24:29 -08001835ATSParser::SourceType ATSParser::Stream::getSourceType() {
1836 if (isVideo()) {
1837 return VIDEO;
1838 } else if (isAudio()) {
1839 return AUDIO;
1840 } else if (isMeta()) {
1841 return META;
1842 }
1843 return NUM_SOURCE_TYPES;
1844}
1845
Marco Nelissen45d54c62018-01-26 10:04:22 -08001846sp<AnotherPacketSource> ATSParser::Stream::getSource(SourceType type) {
Andreas Huber386d6092011-05-19 08:37:39 -07001847 switch (type) {
1848 case VIDEO:
1849 {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001850 if (isVideo()) {
Andreas Huber386d6092011-05-19 08:37:39 -07001851 return mSource;
1852 }
1853 break;
1854 }
1855
1856 case AUDIO:
1857 {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001858 if (isAudio()) {
Andreas Huber386d6092011-05-19 08:37:39 -07001859 return mSource;
1860 }
1861 break;
1862 }
1863
Robert Shih08528432015-04-08 09:06:54 -07001864 case META:
1865 {
1866 if (isMeta()) {
1867 return mSource;
1868 }
1869 break;
1870 }
1871
Andreas Huber386d6092011-05-19 08:37:39 -07001872 default:
1873 break;
Andreas Hubercda17c62010-06-07 13:05:37 -07001874 }
1875
1876 return NULL;
1877}
1878
Chong Zhangbc7aae42017-03-31 14:53:19 -07001879void ATSParser::Stream::setCasInfo(
1880 int32_t systemId, const sp<IDescrambler> &descrambler,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001881 const std::vector<uint8_t> &sessionId) {
1882 if (mSource != NULL && mDescrambler == NULL && descrambler != NULL) {
1883 signalDiscontinuity(DISCONTINUITY_FORMAT_ONLY, NULL);
1884 mDescrambler = descrambler;
1885 if (mQueue->isScrambled()) {
Chong Zhangbc7aae42017-03-31 14:53:19 -07001886 mQueue->setCasInfo(systemId, sessionId);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001887 }
1888 }
1889}
1890
Andreas Hubercda17c62010-06-07 13:05:37 -07001891////////////////////////////////////////////////////////////////////////////////
1892
Andreas Huberc4c17d42011-08-30 16:06:28 -07001893ATSParser::ATSParser(uint32_t flags)
Andreas Huber87f2a552012-08-31 13:55:24 -07001894 : mFlags(flags),
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001895 mAbsoluteTimeAnchorUs(-1LL),
Andreas Huberd5e56232013-03-12 11:01:43 -07001896 mTimeOffsetValid(false),
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001897 mTimeOffsetUs(0LL),
1898 mLastRecoveredPTS(-1LL),
Andreas Huber87f2a552012-08-31 13:55:24 -07001899 mNumTSPacketsParsed(0),
1900 mNumPCRs(0) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07001901 mPSISections.add(0 /* PID */, new PSISection);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001902 mCasManager = new CasManager();
Andreas Hubercda17c62010-06-07 13:05:37 -07001903}
1904
1905ATSParser::~ATSParser() {
1906}
1907
Wonsik Kim54000662015-04-13 10:59:06 +09001908status_t ATSParser::feedTSPacket(const void *data, size_t size,
1909 SyncEvent *event) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001910 if (size != kTSPacketSize) {
1911 ALOGE("Wrong TS packet size");
1912 return BAD_VALUE;
1913 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001914
1915 ABitReader br((const uint8_t *)data, kTSPacketSize);
Wonsik Kim54000662015-04-13 10:59:06 +09001916 return parseTS(&br, event);
Andreas Hubercda17c62010-06-07 13:05:37 -07001917}
1918
Chong Zhang3b2847f2017-01-18 17:43:03 -08001919status_t ATSParser::setMediaCas(const sp<ICas> &cas) {
1920 status_t err = mCasManager->setMediaCas(cas);
1921 if (err != OK) {
1922 return err;
1923 }
1924 for (size_t i = 0; i < mPrograms.size(); ++i) {
1925 mPrograms.editItemAt(i)->updateCasSessions();
1926 }
1927 return OK;
1928}
1929
Andreas Huber32f3cef2011-03-02 15:34:46 -08001930void ATSParser::signalDiscontinuity(
1931 DiscontinuityType type, const sp<AMessage> &extra) {
Andreas Huberb7c8e912012-11-27 15:02:53 -08001932 int64_t mediaTimeUs;
Chong Zhangd47dfcb2015-03-27 15:53:45 -07001933 if ((type & DISCONTINUITY_TIME) && extra != NULL) {
Dongwon Kang15d02f82017-12-14 16:32:18 -08001934 if (extra->findInt64(kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
Chong Zhangd47dfcb2015-03-27 15:53:45 -07001935 mAbsoluteTimeAnchorUs = mediaTimeUs;
1936 }
1937 if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)
1938 && extra->findInt64(
Dongwon Kang15d02f82017-12-14 16:32:18 -08001939 kATSParserKeyRecentMediaTimeUs, &mediaTimeUs)) {
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001940 if (mAbsoluteTimeAnchorUs >= 0LL) {
Chong Zhangd47dfcb2015-03-27 15:53:45 -07001941 mediaTimeUs -= mAbsoluteTimeAnchorUs;
1942 }
1943 if (mTimeOffsetValid) {
1944 mediaTimeUs -= mTimeOffsetUs;
1945 }
1946 mLastRecoveredPTS = (mediaTimeUs * 9) / 100;
1947 }
Andreas Huberb7c8e912012-11-27 15:02:53 -08001948 } else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
Andreas Huber87f2a552012-08-31 13:55:24 -07001949 int64_t timeUs;
Jinsuk Kime314c672015-04-22 11:08:28 +09001950 if (!extra->findInt64("timeUs", &timeUs)) {
1951 ALOGE("timeUs not found");
1952 return;
1953 }
Andreas Huber87f2a552012-08-31 13:55:24 -07001954
Jinsuk Kime314c672015-04-22 11:08:28 +09001955 if (!mPrograms.empty()) {
1956 ALOGE("mPrograms is not empty");
1957 return;
1958 }
Andreas Huber87f2a552012-08-31 13:55:24 -07001959 mAbsoluteTimeAnchorUs = timeUs;
1960 return;
Andreas Huberd5e56232013-03-12 11:01:43 -07001961 } else if (type == DISCONTINUITY_TIME_OFFSET) {
1962 int64_t offset;
Jinsuk Kime314c672015-04-22 11:08:28 +09001963 if (!extra->findInt64("offset", &offset)) {
1964 ALOGE("offset not found");
1965 return;
1966 }
Andreas Huberd5e56232013-03-12 11:01:43 -07001967
1968 mTimeOffsetValid = true;
1969 mTimeOffsetUs = offset;
1970 return;
Andreas Huber87f2a552012-08-31 13:55:24 -07001971 }
1972
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001973 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber32f3cef2011-03-02 15:34:46 -08001974 mPrograms.editItemAt(i)->signalDiscontinuity(type, extra);
Andreas Huberf9334412010-12-15 15:17:42 -08001975 }
1976}
1977
1978void ATSParser::signalEOS(status_t finalResult) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001979 if (finalResult == (status_t) OK) {
1980 ALOGE("finalResult not OK");
1981 return;
1982 }
Andreas Huberf9334412010-12-15 15:17:42 -08001983
1984 for (size_t i = 0; i < mPrograms.size(); ++i) {
1985 mPrograms.editItemAt(i)->signalEOS(finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001986 }
1987}
1988
Andreas Hubercda17c62010-06-07 13:05:37 -07001989void ATSParser::parseProgramAssociationTable(ABitReader *br) {
1990 unsigned table_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01001991 ALOGV(" table_id = %u", table_id);
David Yeh6456ae72014-09-03 11:14:48 +08001992 if (table_id != 0x00u) {
1993 ALOGE("PAT data error!");
1994 return ;
1995 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001996 unsigned section_syntax_indictor = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001997 ALOGV(" section_syntax_indictor = %u", section_syntax_indictor);
Andreas Hubercda17c62010-06-07 13:05:37 -07001998
Jinsuk Kime314c672015-04-22 11:08:28 +09001999 br->skipBits(1); // '0'
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002000 MY_LOGV(" reserved = %u", br->getBits(2));
Andreas Hubercda17c62010-06-07 13:05:37 -07002001
2002 unsigned section_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +01002003 ALOGV(" section_length = %u", section_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07002004
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002005 MY_LOGV(" transport_stream_id = %u", br->getBits(16));
2006 MY_LOGV(" reserved = %u", br->getBits(2));
2007 MY_LOGV(" version_number = %u", br->getBits(5));
2008 MY_LOGV(" current_next_indicator = %u", br->getBits(1));
2009 MY_LOGV(" section_number = %u", br->getBits(8));
2010 MY_LOGV(" last_section_number = %u", br->getBits(8));
Andreas Hubercda17c62010-06-07 13:05:37 -07002011
2012 size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);
Andreas Hubercda17c62010-06-07 13:05:37 -07002013
2014 for (size_t i = 0; i < numProgramBytes / 4; ++i) {
2015 unsigned program_number = br->getBits(16);
Steve Block3856b092011-10-20 11:56:00 +01002016 ALOGV(" program_number = %u", program_number);
Andreas Hubercda17c62010-06-07 13:05:37 -07002017
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002018 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Hubercda17c62010-06-07 13:05:37 -07002019
2020 if (program_number == 0) {
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002021 MY_LOGV(" network_PID = 0x%04x", br->getBits(13));
Andreas Hubercda17c62010-06-07 13:05:37 -07002022 } else {
2023 unsigned programMapPID = br->getBits(13);
2024
Steve Block3856b092011-10-20 11:56:00 +01002025 ALOGV(" program_map_PID = 0x%04x", programMapPID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002026
Andreas Huber386d6092011-05-19 08:37:39 -07002027 bool found = false;
2028 for (size_t index = 0; index < mPrograms.size(); ++index) {
2029 const sp<Program> &program = mPrograms.itemAt(index);
2030
2031 if (program->number() == program_number) {
2032 program->updateProgramMapPID(programMapPID);
2033 found = true;
2034 break;
2035 }
2036 }
2037
2038 if (!found) {
2039 mPrograms.push(
Chong Zhangd47dfcb2015-03-27 15:53:45 -07002040 new Program(this, program_number, programMapPID, mLastRecoveredPTS));
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07002041 if (mSampleAesKeyItem != NULL) {
2042 mPrograms.top()->signalNewSampleAesKey(mSampleAesKeyItem);
2043 }
Andreas Huber386d6092011-05-19 08:37:39 -07002044 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002045
2046 if (mPSISections.indexOfKey(programMapPID) < 0) {
2047 mPSISections.add(programMapPID, new PSISection);
2048 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002049 }
2050 }
2051
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002052 MY_LOGV(" CRC = 0x%08x", br->getBits(32));
Andreas Hubercda17c62010-06-07 13:05:37 -07002053}
2054
Andreas Huber06528d72011-08-31 16:29:05 -07002055status_t ATSParser::parsePID(
Andreas Hubercda17c62010-06-07 13:05:37 -07002056 ABitReader *br, unsigned PID,
Andreas Huber87f2a552012-08-31 13:55:24 -07002057 unsigned continuity_counter,
Wonsik Kim54000662015-04-13 10:59:06 +09002058 unsigned payload_unit_start_indicator,
Chong Zhang3b2847f2017-01-18 17:43:03 -08002059 unsigned transport_scrambling_control,
2060 unsigned random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +09002061 SyncEvent *event) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07002062 ssize_t sectionIndex = mPSISections.indexOfKey(PID);
2063
2064 if (sectionIndex >= 0) {
Andreas Huber4b4bb112013-04-29 13:17:50 -07002065 sp<PSISection> section = mPSISections.valueAt(sectionIndex);
Andreas Huber8dfa2282012-05-15 12:37:29 -07002066
Andreas Hubercda17c62010-06-07 13:05:37 -07002067 if (payload_unit_start_indicator) {
David Yeh6456ae72014-09-03 11:14:48 +08002068 if (!section->isEmpty()) {
Chong Zhang9bcf3ae2015-03-08 15:59:01 -07002069 ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty");
2070 section->clear();
David Yeh6456ae72014-09-03 11:14:48 +08002071 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002072
Andreas Hubercda17c62010-06-07 13:05:37 -07002073 unsigned skip = br->getBits(8);
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002074 section->setSkipBytes(skip + 1); // skip filler bytes + pointer field itself
Andreas Hubercda17c62010-06-07 13:05:37 -07002075 br->skipBits(skip * 8);
2076 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002077
Jinsuk Kime314c672015-04-22 11:08:28 +09002078 if (br->numBitsLeft() % 8 != 0) {
2079 return ERROR_MALFORMED;
2080 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002081 status_t err = section->append(br->data(), br->numBitsLeft() / 8);
2082
2083 if (err != OK) {
2084 return err;
2085 }
2086
2087 if (!section->isComplete()) {
2088 return OK;
2089 }
2090
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002091 if (!section->isCRCOkay()) {
2092 return BAD_VALUE;
2093 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002094 ABitReader sectionBits(section->data(), section->size());
2095
2096 if (PID == 0) {
2097 parseProgramAssociationTable(&sectionBits);
2098 } else {
2099 bool handled = false;
2100 for (size_t i = 0; i < mPrograms.size(); ++i) {
2101 status_t err;
2102 if (!mPrograms.editItemAt(i)->parsePSISection(
2103 PID, &sectionBits, &err)) {
2104 continue;
2105 }
2106
2107 if (err != OK) {
2108 return err;
2109 }
2110
2111 handled = true;
2112 break;
2113 }
2114
2115 if (!handled) {
2116 mPSISections.removeItem(PID);
Andreas Huber4b4bb112013-04-29 13:17:50 -07002117 section.clear();
Andreas Huber8dfa2282012-05-15 12:37:29 -07002118 }
2119 }
2120
Andreas Huber4b4bb112013-04-29 13:17:50 -07002121 if (section != NULL) {
2122 section->clear();
2123 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002124
Andreas Huber06528d72011-08-31 16:29:05 -07002125 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002126 }
2127
2128 bool handled = false;
2129 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber06528d72011-08-31 16:29:05 -07002130 status_t err;
Andreas Hubercda17c62010-06-07 13:05:37 -07002131 if (mPrograms.editItemAt(i)->parsePID(
Chong Zhang3b2847f2017-01-18 17:43:03 -08002132 PID, continuity_counter,
2133 payload_unit_start_indicator,
2134 transport_scrambling_control,
2135 random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +09002136 br, &err, event)) {
Andreas Huber06528d72011-08-31 16:29:05 -07002137 if (err != OK) {
2138 return err;
2139 }
2140
Andreas Hubercda17c62010-06-07 13:05:37 -07002141 handled = true;
2142 break;
2143 }
2144 }
2145
2146 if (!handled) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08002147 handled = mCasManager->parsePID(br, PID);
2148 }
2149
2150 if (!handled) {
Steve Block3856b092011-10-20 11:56:00 +01002151 ALOGV("PID 0x%04x not handled.", PID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002152 }
Andreas Huber06528d72011-08-31 16:29:05 -07002153
2154 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002155}
2156
Chong Zhang3b2847f2017-01-18 17:43:03 -08002157status_t ATSParser::parseAdaptationField(
2158 ABitReader *br, unsigned PID, unsigned *random_access_indicator) {
2159 *random_access_indicator = 0;
Andreas Hubercda17c62010-06-07 13:05:37 -07002160 unsigned adaptation_field_length = br->getBits(8);
Andreas Huber87f2a552012-08-31 13:55:24 -07002161
Andreas Hubercda17c62010-06-07 13:05:37 -07002162 if (adaptation_field_length > 0) {
Jaesung Chung8a1fa1e2015-05-15 14:19:14 +09002163 if (adaptation_field_length * 8 > br->numBitsLeft()) {
2164 ALOGV("Adaptation field should be included in a single TS packet.");
2165 return ERROR_MALFORMED;
2166 }
2167
Andreas Huber87f2a552012-08-31 13:55:24 -07002168 unsigned discontinuity_indicator = br->getBits(1);
2169
2170 if (discontinuity_indicator) {
2171 ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID);
2172 }
2173
Chong Zhang3b2847f2017-01-18 17:43:03 -08002174 *random_access_indicator = br->getBits(1);
2175 if (*random_access_indicator) {
2176 ALOGV("PID 0x%04x: random_access_indicator = 1", PID);
2177 }
2178
2179 unsigned elementary_stream_priority_indicator = br->getBits(1);
2180 if (elementary_stream_priority_indicator) {
2181 ALOGV("PID 0x%04x: elementary_stream_priority_indicator = 1", PID);
2182 }
2183
Andreas Huber87f2a552012-08-31 13:55:24 -07002184 unsigned PCR_flag = br->getBits(1);
2185
2186 size_t numBitsRead = 4;
2187
2188 if (PCR_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09002189 if (adaptation_field_length * 8 < 52) {
2190 return ERROR_MALFORMED;
2191 }
Andreas Huber87f2a552012-08-31 13:55:24 -07002192 br->skipBits(4);
2193 uint64_t PCR_base = br->getBits(32);
2194 PCR_base = (PCR_base << 1) | br->getBits(1);
2195
2196 br->skipBits(6);
2197 unsigned PCR_ext = br->getBits(9);
2198
2199 // The number of bytes from the start of the current
2200 // MPEG2 transport stream packet up and including
2201 // the final byte of this PCR_ext field.
2202 size_t byteOffsetFromStartOfTSPacket =
2203 (188 - br->numBitsLeft() / 8);
2204
2205 uint64_t PCR = PCR_base * 300 + PCR_ext;
2206
Colin Crossb4a7a2d2014-03-19 16:59:00 -07002207 ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)",
Andreas Huber87f2a552012-08-31 13:55:24 -07002208 PID, PCR, PCR / 27E6);
2209
2210 // The number of bytes received by this parser up to and
2211 // including the final byte of this PCR_ext field.
Marco Nelissen19cec892016-04-20 15:56:53 -07002212 uint64_t byteOffsetFromStart =
2213 uint64_t(mNumTSPacketsParsed) * 188 + byteOffsetFromStartOfTSPacket;
Andreas Huber87f2a552012-08-31 13:55:24 -07002214
2215 for (size_t i = 0; i < mPrograms.size(); ++i) {
2216 updatePCR(PID, PCR, byteOffsetFromStart);
2217 }
2218
2219 numBitsRead += 52;
2220 }
2221
Andreas Huber87f2a552012-08-31 13:55:24 -07002222 br->skipBits(adaptation_field_length * 8 - numBitsRead);
Andreas Hubercda17c62010-06-07 13:05:37 -07002223 }
Jinsuk Kime314c672015-04-22 11:08:28 +09002224 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002225}
2226
Wonsik Kim54000662015-04-13 10:59:06 +09002227status_t ATSParser::parseTS(ABitReader *br, SyncEvent *event) {
Steve Block3856b092011-10-20 11:56:00 +01002228 ALOGV("---");
Andreas Hubercda17c62010-06-07 13:05:37 -07002229
2230 unsigned sync_byte = br->getBits(8);
David Yeh6456ae72014-09-03 11:14:48 +08002231 if (sync_byte != 0x47u) {
2232 ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte);
2233 return BAD_VALUE;
2234 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002235
Andreas Huber52668ca2013-11-11 13:35:39 -08002236 if (br->getBits(1)) { // transport_error_indicator
2237 // silently ignore.
2238 return OK;
2239 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002240
2241 unsigned payload_unit_start_indicator = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01002242 ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator);
Andreas Hubercda17c62010-06-07 13:05:37 -07002243
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002244 MY_LOGV("transport_priority = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07002245
2246 unsigned PID = br->getBits(13);
Steve Block3856b092011-10-20 11:56:00 +01002247 ALOGV("PID = 0x%04x", PID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002248
Chong Zhang3b2847f2017-01-18 17:43:03 -08002249 unsigned transport_scrambling_control = br->getBits(2);
2250 ALOGV("transport_scrambling_control = %u", transport_scrambling_control);
Andreas Hubercda17c62010-06-07 13:05:37 -07002251
2252 unsigned adaptation_field_control = br->getBits(2);
Steve Block3856b092011-10-20 11:56:00 +01002253 ALOGV("adaptation_field_control = %u", adaptation_field_control);
Andreas Hubercda17c62010-06-07 13:05:37 -07002254
Andreas Huber0da4dab2010-09-27 12:04:43 -07002255 unsigned continuity_counter = br->getBits(4);
Andreas Huber87f2a552012-08-31 13:55:24 -07002256 ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
Andreas Huber0da4dab2010-09-27 12:04:43 -07002257
Steve Blockdf64d152012-01-04 20:05:49 +00002258 // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
Andreas Hubercda17c62010-06-07 13:05:37 -07002259
Andreas Huber87f2a552012-08-31 13:55:24 -07002260 status_t err = OK;
2261
Chong Zhang3b2847f2017-01-18 17:43:03 -08002262 unsigned random_access_indicator = 0;
Jinsuk Kime314c672015-04-22 11:08:28 +09002263 if (adaptation_field_control == 2 || adaptation_field_control == 3) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08002264 err = parseAdaptationField(br, PID, &random_access_indicator);
Jinsuk Kime314c672015-04-22 11:08:28 +09002265 }
2266 if (err == OK) {
2267 if (adaptation_field_control == 1 || adaptation_field_control == 3) {
Wonsik Kim54000662015-04-13 10:59:06 +09002268 err = parsePID(br, PID, continuity_counter,
Chong Zhang3b2847f2017-01-18 17:43:03 -08002269 payload_unit_start_indicator,
2270 transport_scrambling_control,
2271 random_access_indicator,
2272 event);
Jinsuk Kime314c672015-04-22 11:08:28 +09002273 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002274 }
Andreas Huber06528d72011-08-31 16:29:05 -07002275
Andreas Huber87f2a552012-08-31 13:55:24 -07002276 ++mNumTSPacketsParsed;
2277
2278 return err;
Andreas Hubercda17c62010-06-07 13:05:37 -07002279}
2280
Marco Nelissen45d54c62018-01-26 10:04:22 -08002281sp<AnotherPacketSource> ATSParser::getSource(SourceType type) {
2282 sp<AnotherPacketSource> firstSourceFound;
Andreas Hubercda17c62010-06-07 13:05:37 -07002283 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber386d6092011-05-19 08:37:39 -07002284 const sp<Program> &program = mPrograms.editItemAt(i);
Marco Nelissen45d54c62018-01-26 10:04:22 -08002285 sp<AnotherPacketSource> source = program->getSource(type);
Robert Shih9ff1e722015-10-20 16:29:58 -07002286 if (source == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07002287 continue;
2288 }
Robert Shih9ff1e722015-10-20 16:29:58 -07002289 if (firstSourceFound == NULL) {
2290 firstSourceFound = source;
2291 }
2292 // Prefer programs with both audio/video
2293 switch (type) {
2294 case VIDEO: {
2295 if (program->hasSource(AUDIO)) {
2296 return source;
2297 }
2298 break;
2299 }
Andreas Huber386d6092011-05-19 08:37:39 -07002300
Robert Shih9ff1e722015-10-20 16:29:58 -07002301 case AUDIO: {
2302 if (program->hasSource(VIDEO)) {
2303 return source;
2304 }
2305 break;
2306 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002307
Robert Shih9ff1e722015-10-20 16:29:58 -07002308 default:
2309 return source;
Andreas Hubercda17c62010-06-07 13:05:37 -07002310 }
2311 }
2312
Robert Shih9ff1e722015-10-20 16:29:58 -07002313 return firstSourceFound;
Andreas Hubercda17c62010-06-07 13:05:37 -07002314}
2315
Robert Shihbf207272014-10-30 17:22:11 -07002316bool ATSParser::hasSource(SourceType type) const {
2317 for (size_t i = 0; i < mPrograms.size(); ++i) {
2318 const sp<Program> &program = mPrograms.itemAt(i);
2319 if (program->hasSource(type)) {
2320 return true;
2321 }
2322 }
2323
2324 return false;
2325}
2326
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002327bool ATSParser::PTSTimeDeltaEstablished() {
2328 if (mPrograms.isEmpty()) {
2329 return false;
2330 }
2331
2332 return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished();
2333}
2334
Robert Shih82e14702016-11-17 11:24:29 -08002335int64_t ATSParser::getFirstPTSTimeUs() {
2336 for (size_t i = 0; i < mPrograms.size(); ++i) {
2337 sp<ATSParser::Program> program = mPrograms.itemAt(i);
2338 if (program->PTSTimeDeltaEstablished()) {
2339 return (program->firstPTS() * 100) / 9;
2340 }
2341 }
2342 return -1;
2343}
2344
Chad Brubakerc9fa35c2015-08-18 16:52:40 -07002345__attribute__((no_sanitize("integer")))
Andreas Huber87f2a552012-08-31 13:55:24 -07002346void ATSParser::updatePCR(
Marco Nelissen19cec892016-04-20 15:56:53 -07002347 unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
2348 ALOGV("PCR 0x%016" PRIx64 " @ %" PRIx64, PCR, byteOffsetFromStart);
Andreas Huber87f2a552012-08-31 13:55:24 -07002349
2350 if (mNumPCRs == 2) {
2351 mPCR[0] = mPCR[1];
2352 mPCRBytes[0] = mPCRBytes[1];
2353 mSystemTimeUs[0] = mSystemTimeUs[1];
2354 mNumPCRs = 1;
2355 }
2356
2357 mPCR[mNumPCRs] = PCR;
2358 mPCRBytes[mNumPCRs] = byteOffsetFromStart;
2359 mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs();
2360
2361 ++mNumPCRs;
2362
2363 if (mNumPCRs == 2) {
Chad Brubakerc9fa35c2015-08-18 16:52:40 -07002364 /* Unsigned overflow here */
Andreas Huber87f2a552012-08-31 13:55:24 -07002365 double transportRate =
2366 (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]);
2367
2368 ALOGV("transportRate = %.2f bytes/sec", transportRate);
2369 }
2370}
2371
Andreas Huber8dfa2282012-05-15 12:37:29 -07002372////////////////////////////////////////////////////////////////////////////////
2373
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002374
2375// CRC32 used for PSI section. The table was generated by following command:
2376// $ python pycrc.py --model crc-32-mpeg --algorithm table-driven --generate c
2377// Visit http://www.tty1.net/pycrc/index_en.html for more details.
2378uint32_t ATSParser::PSISection::CRC_TABLE[] = {
2379 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
2380 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
2381 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
2382 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
2383 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
2384 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
2385 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
2386 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
2387 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
2388 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
2389 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
2390 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
2391 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
2392 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
2393 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
2394 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
2395 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
2396 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
2397 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
2398 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
2399 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
2400 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
2401 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
2402 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
2403 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
2404 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
2405 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
2406 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
2407 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
2408 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
2409 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
2410 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
2411 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
2412 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
2413 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
2414 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
2415 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
2416 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
2417 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
2418 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
2419 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
2420 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
2421 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
2422 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
2423 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
2424 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
2425 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
2426 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
2427 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
2428 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
2429 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
2430 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
2431 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
2432 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
2433 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
2434 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
2435 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
2436 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
2437 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
2438 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
2439 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
2440 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
2441 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
2442 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
2443 };
2444
2445ATSParser::PSISection::PSISection() :
2446 mSkipBytes(0) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07002447}
2448
2449ATSParser::PSISection::~PSISection() {
2450}
2451
2452status_t ATSParser::PSISection::append(const void *data, size_t size) {
2453 if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) {
2454 size_t newCapacity =
2455 (mBuffer == NULL) ? size : mBuffer->capacity() + size;
2456
2457 newCapacity = (newCapacity + 1023) & ~1023;
2458
2459 sp<ABuffer> newBuffer = new ABuffer(newCapacity);
2460
2461 if (mBuffer != NULL) {
2462 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
2463 newBuffer->setRange(0, mBuffer->size());
2464 } else {
2465 newBuffer->setRange(0, 0);
2466 }
2467
2468 mBuffer = newBuffer;
2469 }
2470
2471 memcpy(mBuffer->data() + mBuffer->size(), data, size);
2472 mBuffer->setRange(0, mBuffer->size() + size);
2473
2474 return OK;
2475}
2476
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002477void ATSParser::PSISection::setSkipBytes(uint8_t skip) {
2478 mSkipBytes = skip;
2479}
2480
Andreas Huber8dfa2282012-05-15 12:37:29 -07002481void ATSParser::PSISection::clear() {
2482 if (mBuffer != NULL) {
2483 mBuffer->setRange(0, 0);
2484 }
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002485 mSkipBytes = 0;
Andreas Huber8dfa2282012-05-15 12:37:29 -07002486}
2487
2488bool ATSParser::PSISection::isComplete() const {
2489 if (mBuffer == NULL || mBuffer->size() < 3) {
2490 return false;
2491 }
2492
2493 unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff;
2494 return mBuffer->size() >= sectionLength + 3;
2495}
2496
2497bool ATSParser::PSISection::isEmpty() const {
2498 return mBuffer == NULL || mBuffer->size() == 0;
2499}
2500
2501const uint8_t *ATSParser::PSISection::data() const {
2502 return mBuffer == NULL ? NULL : mBuffer->data();
2503}
2504
2505size_t ATSParser::PSISection::size() const {
2506 return mBuffer == NULL ? 0 : mBuffer->size();
2507}
2508
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002509bool ATSParser::PSISection::isCRCOkay() const {
2510 if (!isComplete()) {
2511 return false;
2512 }
2513 uint8_t* data = mBuffer->data();
2514
2515 // Return true if section_syntax_indicator says no section follows the field section_length.
2516 if ((data[1] & 0x80) == 0) {
2517 return true;
2518 }
2519
2520 unsigned sectionLength = U16_AT(data + 1) & 0xfff;
2521 ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes);
2522
Marco Nelissenc0c9f502016-04-28 13:32:41 -07002523
2524 if(sectionLength < mSkipBytes) {
2525 ALOGE("b/28333006");
2526 android_errorWriteLog(0x534e4554, "28333006");
2527 return false;
2528 }
2529
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002530 // Skip the preceding field present when payload start indicator is on.
2531 sectionLength -= mSkipBytes;
2532
2533 uint32_t crc = 0xffffffff;
2534 for(unsigned i = 0; i < sectionLength + 4 /* crc */; i++) {
2535 uint8_t b = data[i];
2536 int index = ((crc >> 24) ^ (b & 0xff)) & 0xff;
2537 crc = CRC_TABLE[index] ^ (crc << 8);
2538 }
2539 ALOGV("crc: %08x\n", crc);
2540 return (crc == 0);
2541}
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07002542
2543// SAMPLE_AES key handling
2544// TODO: Merge these to their respective class after Widevine-HLS
2545void ATSParser::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2546 ALOGD("signalNewSampleAesKey: %p", keyItem.get());
2547
2548 mSampleAesKeyItem = keyItem;
2549
2550 // a NULL key item will propagate to existing ElementaryStreamQueues
2551 for (size_t i = 0; i < mPrograms.size(); ++i) {
2552 mPrograms[i]->signalNewSampleAesKey(keyItem);
2553 }
2554}
2555
2556void ATSParser::Program::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2557 ALOGD("Program::signalNewSampleAesKey: %p", keyItem.get());
2558
2559 mSampleAesKeyItem = keyItem;
2560
2561 // a NULL key item will propagate to existing ElementaryStreamQueues
2562 for (size_t i = 0; i < mStreams.size(); ++i) {
2563 mStreams[i]->signalNewSampleAesKey(keyItem);
2564 }
2565}
2566
2567void ATSParser::Stream::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2568 ALOGD("Stream::signalNewSampleAesKey: 0x%04x size = %zu keyItem: %p",
2569 mElementaryPID, mBuffer->size(), keyItem.get());
2570
2571 // a NULL key item will propagate to existing ElementaryStreamQueues
2572 mSampleAesKeyItem = keyItem;
2573
2574 flush(NULL);
2575 mQueue->signalNewSampleAesKey(keyItem);
2576}
2577
Andreas Hubercda17c62010-06-07 13:05:37 -07002578} // namespace android