blob: 88c3cc20c71ebbac9d84c221b674430fa89b5801 [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) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000443 if (br->numBitsLeft() < 16) {
444 ALOGE("Not enough data left in bitreader");
445 return false;
446 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800447 unsigned descriptor_tag = br->getBits(8);
448 ALOGV(" tag = 0x%02x", descriptor_tag);
449
450 unsigned descriptor_length = br->getBits(8);
451 ALOGV(" len = %u", descriptor_length);
452
453 infoLength -= 2;
454 if (descriptor_length > infoLength) {
455 break;
456 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800457 if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
Chong Zhang3b2847f2017-01-18 17:43:03 -0800458 found = true;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000459 if (br->numBitsLeft() < 32) {
460 ALOGE("Not enough data left in bitreader");
461 return false;
462 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800463 caDescriptor->mSystemID = br->getBits(16);
464 caDescriptor->mPID = br->getBits(16) & 0x1fff;
465 infoLength -= 4;
466 caDescriptor->mPrivateData.assign(
467 br->data(), br->data() + descriptor_length - 4);
468 break;
469 } else {
470 infoLength -= descriptor_length;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000471 if (!br->skipBits(descriptor_length * 8)) {
472 ALOGE("Not enough data left in bitreader");
473 return false;
474 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800475 }
476 }
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000477 if (!br->skipBits(infoLength * 8)) {
478 ALOGE("Not enough data left in bitreader");
479 return false;
480 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800481 return found;
482}
483
Andreas Huber06528d72011-08-31 16:29:05 -0700484status_t ATSParser::Program::parseProgramMap(ABitReader *br) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000485 if (br->numBitsLeft() < 10) {
486 ALOGE("Not enough data left in bitreader!");
487 return ERROR_MALFORMED;
488 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700489 unsigned table_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +0100490 ALOGV(" table_id = %u", table_id);
David Yeh6456ae72014-09-03 11:14:48 +0800491 if (table_id != 0x02u) {
492 ALOGE("PMT data error!");
493 return ERROR_MALFORMED;
494 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700495 unsigned section_syntax_indicator = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +0100496 ALOGV(" section_syntax_indicator = %u", section_syntax_indicator);
David Yeh6456ae72014-09-03 11:14:48 +0800497 if (section_syntax_indicator != 1u) {
498 ALOGE("PMT data error!");
499 return ERROR_MALFORMED;
500 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700501
Jinsuk Kime314c672015-04-22 11:08:28 +0900502 br->skipBits(1); // '0'
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000503 if (br->numBitsLeft() < 86) {
504 ALOGE("Not enough data left in bitreader!");
505 return ERROR_MALFORMED;
506 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700507 MY_LOGV(" reserved = %u", br->getBits(2));
Andreas Hubercda17c62010-06-07 13:05:37 -0700508
509 unsigned section_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100510 ALOGV(" section_length = %u", section_length);
Andreas Hubercda17c62010-06-07 13:05:37 -0700511
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700512 MY_LOGV(" program_number = %u", br->getBits(16));
513 MY_LOGV(" reserved = %u", br->getBits(2));
Sampath Shetty142598f2018-12-10 13:52:30 +1100514 bool audioPresentationsChanged = false;
515 unsigned pmtVersion = br->getBits(5);
516 if (pmtVersion != mPMTVersion) {
517 audioPresentationsChanged = true;
518 mPMTVersion = pmtVersion;
519 }
520 MY_LOGV(" version_number = %u", pmtVersion);
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700521 MY_LOGV(" current_next_indicator = %u", br->getBits(1));
522 MY_LOGV(" section_number = %u", br->getBits(8));
523 MY_LOGV(" last_section_number = %u", br->getBits(8));
524 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Huber87f2a552012-08-31 13:55:24 -0700525
526 unsigned PCR_PID = br->getBits(13);
527 ALOGV(" PCR_PID = 0x%04x", PCR_PID);
528
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700529 MY_LOGV(" reserved = %u", br->getBits(4));
Andreas Hubercda17c62010-06-07 13:05:37 -0700530
531 unsigned program_info_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100532 ALOGV(" program_info_length = %u", program_info_length);
Andreas Hubercda17c62010-06-07 13:05:37 -0700533
Chong Zhang3b2847f2017-01-18 17:43:03 -0800534 // descriptors
535 CADescriptor programCA;
536 bool hasProgramCA = findCADescriptor(br, program_info_length, &programCA);
537 if (hasProgramCA && !mParser->mCasManager->addProgram(
538 mProgramNumber, programCA)) {
539 return ERROR_MALFORMED;
540 }
Andreas Hubercda17c62010-06-07 13:05:37 -0700541
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800542 Vector<StreamInfo> infos;
543
Andreas Hubercda17c62010-06-07 13:05:37 -0700544 // infoBytesRemaining is the number of bytes that make up the
545 // variable length section of ES_infos. It does not include the
546 // final CRC.
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800547 int32_t infoBytesRemaining = section_length - 9 - program_info_length - 4;
Andreas Hubercda17c62010-06-07 13:05:37 -0700548
Jinsuk Kime314c672015-04-22 11:08:28 +0900549 while (infoBytesRemaining >= 5) {
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800550 StreamInfo info;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000551 if (br->numBitsLeft() < 40) {
552 ALOGE("Not enough data left in bitreader!");
553 return ERROR_MALFORMED;
554 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800555 info.mType = br->getBits(8);
556 ALOGV(" stream_type = 0x%02x", info.mType);
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700557 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Hubercda17c62010-06-07 13:05:37 -0700558
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800559 info.mPID = br->getBits(13);
560 ALOGV(" elementary_PID = 0x%04x", info.mPID);
Andreas Hubercda17c62010-06-07 13:05:37 -0700561
Andreas Huber6e4c5c42010-09-21 13:13:15 -0700562 MY_LOGV(" reserved = %u", br->getBits(4));
Andreas Hubercda17c62010-06-07 13:05:37 -0700563
564 unsigned ES_info_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +0100565 ALOGV(" ES_info_length = %u", ES_info_length);
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800566 infoBytesRemaining -= 5 + ES_info_length;
Andreas Hubercda17c62010-06-07 13:05:37 -0700567
Chong Zhang3b2847f2017-01-18 17:43:03 -0800568 CADescriptor streamCA;
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800569 info.mTypeExt = EXT_DESCRIPTOR_DVB_RESERVED_MAX;
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100570
571 info.mAudioPresentations.clear();
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800572 bool hasStreamCA = false;
573 while (ES_info_length > 2 && infoBytesRemaining >= 0) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000574 if (br->numBitsLeft() < 16) {
575 ALOGE("Not enough data left in bitreader!");
576 return ERROR_MALFORMED;
577 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800578 unsigned descriptor_tag = br->getBits(8);
579 ALOGV(" tag = 0x%02x", descriptor_tag);
580
581 unsigned descriptor_length = br->getBits(8);
582 ALOGV(" len = %u", descriptor_length);
583
584 ES_info_length -= 2;
585 if (descriptor_length > ES_info_length) {
586 return ERROR_MALFORMED;
587 }
Rahul3beba382023-02-03 20:36:55 +0000588
589 // The DTS descriptor is used in the PSI PMT to identify streams which carry
590 // DTS audio(core only). If a DTS descriptor is present, a DTS-HD or DTS-UHD
591 // descriptors shall not be present in the same ES_info descriptor loop.
592 if (descriptor_tag == DESCRIPTOR_DTS) {
593 info.mType = STREAMTYPE_DTS;
594 ES_info_length -= descriptor_length;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000595 if (!br->skipBits(descriptor_length * 8)) {
596 ALOGE("Not enough data left in bitreader!");
597 return ERROR_MALFORMED;
598 }
Rahul3beba382023-02-03 20:36:55 +0000599 } else if (descriptor_tag == DESCRIPTOR_CA && descriptor_length >= 4) {
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800600 hasStreamCA = true;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000601 if (br->numBitsLeft() < 32) {
602 ALOGE("Not enough data left in bitreader!");
603 return ERROR_MALFORMED;
604 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800605 streamCA.mSystemID = br->getBits(16);
606 streamCA.mPID = br->getBits(16) & 0x1fff;
Vasily Tarasov7e736a42018-11-01 10:51:08 -0700607 ES_info_length -= descriptor_length;
608 descriptor_length -= 4;
609 streamCA.mPrivateData.assign(br->data(), br->data() + descriptor_length);
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000610 if (!br->skipBits(descriptor_length * 8)) {
611 ALOGE("Not enough data left in bitreader!");
612 return ERROR_MALFORMED;
613 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800614 } else if (info.mType == STREAMTYPE_PES_PRIVATE_DATA &&
615 descriptor_tag == DESCRIPTOR_DVB_EXTENSION && descriptor_length >= 1) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000616 if (br->numBitsLeft() < 8) {
617 ALOGE("Not enough data left in bitreader!");
618 return ERROR_MALFORMED;
619 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800620 unsigned descTagExt = br->getBits(8);
621 ALOGV(" tag_ext = 0x%02x", descTagExt);
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800622 ES_info_length -= descriptor_length;
623 descriptor_length--;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000624 if (br->numBitsLeft() < (descriptor_length * 8)) {
625 ALOGE("Not enough data left in bitreader!");
626 return ERROR_MALFORMED;
627 }
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100628 // The AC4 descriptor is used in the PSI PMT to identify streams which carry AC4
629 // audio.
630 if (descTagExt == EXT_DESCRIPTOR_DVB_AC4) {
631 info.mTypeExt = EXT_DESCRIPTOR_DVB_AC4;
632 br->skipBits(descriptor_length * 8);
Rahul3beba382023-02-03 20:36:55 +0000633 } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
634 // DTS HD extended descriptor which can accommodate core only formats
635 // as well as extension only and core + extension combinations.
636 info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_HD;
637 br->skipBits(descriptor_length * 8);
638 } else if (descTagExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
639 // The DTS-UHD descriptor is used in the PSI PMT to identify streams
640 // which carry DTS-UHD audio
641 info.mTypeExt = EXT_DESCRIPTOR_DVB_DTS_UHD;
642 br->skipBits(descriptor_length * 8);
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100643 } else if (descTagExt == EXT_DESCRIPTOR_DVB_AUDIO_PRESELECTION &&
644 descriptor_length >= 1) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000645 if (br->numBitsLeft() < 8) {
646 ALOGE("Not enough data left in bitreader!");
647 return ERROR_MALFORMED;
648 }
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100649 // DVB BlueBook A038 Table 110
650 unsigned num_preselections = br->getBits(5);
651 br->skipBits(3); // reserved
652 for (unsigned i = 0; i < num_preselections; ++i) {
653 if (br->numBitsLeft() < 16) {
654 ALOGE("Not enough data left in bitreader!");
655 return ERROR_MALFORMED;
656 }
657 AudioPresentationV1 ap;
658 ap.mPresentationId = br->getBits(5); // preselection_id
659
660 // audio_rendering_indication
661 ap.mMasteringIndication = static_cast<MasteringIndication>(br->getBits(3));
662 ap.mAudioDescriptionAvailable = (br->getBits(1) == 1);
663 ap.mSpokenSubtitlesAvailable = (br->getBits(1) == 1);
664 ap.mDialogueEnhancementAvailable = (br->getBits(1) == 1);
665
666 bool interactivity_enabled = (br->getBits(1) == 1);
667 MY_LOGV(" interactivity_enabled = %d", interactivity_enabled);
668
669 bool language_code_present = (br->getBits(1) == 1);
670 bool text_label_present = (br->getBits(1) == 1);
671
672 bool multi_stream_info_present = (br->getBits(1) == 1);
673 bool future_extension = (br->getBits(1) == 1);
674 if (language_code_present) {
675 if (br->numBitsLeft() < 24) {
676 ALOGE("Not enough data left in bitreader!");
677 return ERROR_MALFORMED;
678 }
679 char language[4];
680 language[0] = br->getBits(8);
681 language[1] = br->getBits(8);
682 language[2] = br->getBits(8);
683 language[3] = 0;
684 ap.mLanguage = String8(language);
685 }
686
687 // This maps the presentation id to the message id in the
688 // EXT_DESCRIPTOR_DVB_MESSAGE so that we can get the presentation label.
689 if (text_label_present) {
690 if (br->numBitsLeft() < 8) {
691 ALOGE("Not enough data left in bitreader!");
692 return ERROR_MALFORMED;
693 }
694 unsigned message_id = br->getBits(8);
695 MY_LOGV(" message_id = %u", message_id);
696 }
697
698 if (multi_stream_info_present) {
699 if (br->numBitsLeft() < 8) {
700 ALOGE("Not enough data left in bitreader!");
701 return ERROR_MALFORMED;
702 }
703 unsigned num_aux_components = br->getBits(3);
704 br->skipBits(5); // reserved
705 if (br->numBitsLeft() < (num_aux_components * 8)) {
706 ALOGE("Not enough data left in bitreader!");
707 return ERROR_MALFORMED;
708 }
709 br->skipBits(num_aux_components * 8); // component_tag
710 }
711 if (future_extension) {
712 if (br->numBitsLeft() < 8) {
713 return ERROR_MALFORMED;
714 }
715 br->skipBits(3); // reserved
716 unsigned future_extension_length = br->getBits(5);
717 if (br->numBitsLeft() < (future_extension_length * 8)) {
718 ALOGE("Not enough data left in bitreader!");
719 return ERROR_MALFORMED;
720 }
721 br->skipBits(future_extension_length * 8); // future_extension_byte
722 }
723 info.mAudioPresentations.push_back(std::move(ap));
724 }
725 } else {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000726 if (!br->skipBits(descriptor_length * 8)) {
727 ALOGE("Not enough data left in bitreader!");
728 return ERROR_MALFORMED;
729 }
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100730 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800731 } else {
732 ES_info_length -= descriptor_length;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000733 if (!br->skipBits(descriptor_length * 8)) {
734 ALOGE("Not enough data left in bitreader!");
735 return ERROR_MALFORMED;
736 }
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800737 }
738 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800739 if (hasStreamCA && !mParser->mCasManager->addStream(
Previr Rangroo7e6ac732017-11-13 20:20:20 -0800740 mProgramNumber, info.mPID, streamCA)) {
Chong Zhang3b2847f2017-01-18 17:43:03 -0800741 return ERROR_MALFORMED;
Andreas Hubercda17c62010-06-07 13:05:37 -0700742 }
Chong Zhang7e986a82018-11-07 13:01:08 -0800743 if (hasProgramCA) {
744 info.mCADescriptor = programCA;
745 } else if (hasStreamCA) {
746 info.mCADescriptor = streamCA;
747 }
748
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800749 infos.push(info);
Andreas Hubercda17c62010-06-07 13:05:37 -0700750 }
751
Jinsuk Kime314c672015-04-22 11:08:28 +0900752 if (infoBytesRemaining != 0) {
753 ALOGW("Section data remains unconsumed");
754 }
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +0000755 if (br->numBitsLeft() < 32) {
756 ALOGE("Not enough data left in bitreader!");
757 return ERROR_MALFORMED;
758 }
Sampath Shetty142598f2018-12-10 13:52:30 +1100759 unsigned crc = br->getBits(32);
760 if (crc != mPMT_CRC) {
761 audioPresentationsChanged = true;
762 mPMT_CRC = crc;
763 }
764 MY_LOGV(" CRC = 0x%08x", crc);
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800765
766 bool PIDsChanged = false;
767 for (size_t i = 0; i < infos.size(); ++i) {
768 StreamInfo &info = infos.editItemAt(i);
769
770 ssize_t index = mStreams.indexOfKey(info.mPID);
771
772 if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
Steve Blockdf64d152012-01-04 20:05:49 +0000773 ALOGI("uh oh. stream PIDs have changed.");
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800774 PIDsChanged = true;
775 break;
776 }
777 }
778
779 if (PIDsChanged) {
Andreas Huber06528d72011-08-31 16:29:05 -0700780#if 0
Steve Blockdf64d152012-01-04 20:05:49 +0000781 ALOGI("before:");
Andreas Huber06528d72011-08-31 16:29:05 -0700782 for (size_t i = 0; i < mStreams.size(); ++i) {
783 sp<Stream> stream = mStreams.editValueAt(i);
784
Steve Blockdf64d152012-01-04 20:05:49 +0000785 ALOGI("PID 0x%08x => type 0x%02x", stream->pid(), stream->type());
Andreas Huber06528d72011-08-31 16:29:05 -0700786 }
787
Steve Blockdf64d152012-01-04 20:05:49 +0000788 ALOGI("after:");
Andreas Huber06528d72011-08-31 16:29:05 -0700789 for (size_t i = 0; i < infos.size(); ++i) {
790 StreamInfo &info = infos.editItemAt(i);
791
Steve Blockdf64d152012-01-04 20:05:49 +0000792 ALOGI("PID 0x%08x => type 0x%02x", info.mPID, info.mType);
Andreas Huber06528d72011-08-31 16:29:05 -0700793 }
794#endif
795
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700796 // we can recover if number of streams for each type remain the same
797 bool success = switchPIDs(infos);
Andreas Huber06528d72011-08-31 16:29:05 -0700798
799 if (!success) {
Steve Blockdf64d152012-01-04 20:05:49 +0000800 ALOGI("Stream PIDs changed and we cannot recover.");
Andreas Huber06528d72011-08-31 16:29:05 -0700801 return ERROR_MALFORMED;
802 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800803 }
804
Chong Zhang3b2847f2017-01-18 17:43:03 -0800805 bool isAddingScrambledStream = false;
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800806 for (size_t i = 0; i < infos.size(); ++i) {
807 StreamInfo &info = infos.editItemAt(i);
808
Chong Zhang3b2847f2017-01-18 17:43:03 -0800809 if (mParser->mCasManager->isCAPid(info.mPID)) {
810 // skip CA streams (EMM/ECM)
811 continue;
812 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800813 ssize_t index = mStreams.indexOfKey(info.mPID);
814
815 if (index < 0) {
Chong Zhang7e986a82018-11-07 13:01:08 -0800816 sp<Stream> stream = new Stream(this, PCR_PID, info);
Andreas Huber87f2a552012-08-31 13:55:24 -0700817
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700818 if (mSampleAesKeyItem != NULL) {
819 stream->signalNewSampleAesKey(mSampleAesKeyItem);
820 }
821
Chong Zhang7e986a82018-11-07 13:01:08 -0800822 isAddingScrambledStream |= info.mCADescriptor.mSystemID >= 0;
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800823 mStreams.add(info.mPID, stream);
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800824 }
Sampath Shetty142598f2018-12-10 13:52:30 +1100825 else if (index >= 0 && mStreams.editValueAt(index)->isAudio()
826 && audioPresentationsChanged) {
827 mStreams.editValueAt(index)->setAudioPresentations(info.mAudioPresentations);
828 }
Andreas Huberbc7f5b22011-01-21 10:15:23 -0800829 }
Andreas Huber06528d72011-08-31 16:29:05 -0700830
Chong Zhang3b2847f2017-01-18 17:43:03 -0800831 if (isAddingScrambledStream) {
832 ALOGI("Receiving scrambled streams without descrambler!");
833 return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED;
834 }
Andreas Huber06528d72011-08-31 16:29:05 -0700835 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -0700836}
837
Chong Zhang799c9682015-03-02 23:42:38 -0800838int64_t ATSParser::Program::recoverPTS(uint64_t PTS_33bit) {
839 // We only have the lower 33-bit of the PTS. It could overflow within a
840 // reasonable amount of time. To handle the wrap-around, use fancy math
841 // to get an extended PTS that is within [-0xffffffff, 0xffffffff]
842 // of the latest recovered PTS.
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800843 if (mLastRecoveredPTS < 0LL) {
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700844 // Use the original 33bit number for 1st frame, the reason is that
845 // if 1st frame wraps to negative that's far away from 0, we could
846 // never start. Only start wrapping around from 2nd frame.
847 mLastRecoveredPTS = static_cast<int64_t>(PTS_33bit);
848 } else {
849 mLastRecoveredPTS = static_cast<int64_t>(
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800850 ((mLastRecoveredPTS - static_cast<int64_t>(PTS_33bit) + 0x100000000LL)
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700851 & 0xfffffffe00000000ull) | PTS_33bit);
852 // We start from 0, but recovered PTS could be slightly below 0.
853 // Clamp it to 0 as rest of the pipeline doesn't take negative pts.
854 // (eg. video is read first and starts at 0, but audio starts at 0xfffffff0)
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800855 if (mLastRecoveredPTS < 0LL) {
Chih-Hung Hsieh5c9054b2015-03-12 13:24:12 -0700856 ALOGI("Clamping negative recovered PTS (%" PRId64 ") to 0", mLastRecoveredPTS);
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800857 mLastRecoveredPTS = 0LL;
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700858 }
859 }
Chong Zhang799c9682015-03-02 23:42:38 -0800860
Chong Zhang9bcf3ae2015-03-08 15:59:01 -0700861 return mLastRecoveredPTS;
Chong Zhang799c9682015-03-02 23:42:38 -0800862}
863
Marco Nelissen45d54c62018-01-26 10:04:22 -0800864sp<AnotherPacketSource> ATSParser::Program::getSource(SourceType type) {
Andreas Hubercda17c62010-06-07 13:05:37 -0700865 for (size_t i = 0; i < mStreams.size(); ++i) {
Marco Nelissen45d54c62018-01-26 10:04:22 -0800866 sp<AnotherPacketSource> source = mStreams.editValueAt(i)->getSource(type);
Andreas Hubercda17c62010-06-07 13:05:37 -0700867 if (source != NULL) {
Robert Shih9ff1e722015-10-20 16:29:58 -0700868 return source;
Andreas Hubercda17c62010-06-07 13:05:37 -0700869 }
870 }
871
872 return NULL;
873}
874
Robert Shihbf207272014-10-30 17:22:11 -0700875bool ATSParser::Program::hasSource(SourceType type) const {
876 for (size_t i = 0; i < mStreams.size(); ++i) {
877 const sp<Stream> &stream = mStreams.valueAt(i);
878 if (type == AUDIO && stream->isAudio()) {
879 return true;
880 } else if (type == VIDEO && stream->isVideo()) {
881 return true;
Robert Shih9ff1e722015-10-20 16:29:58 -0700882 } else if (type == META && stream->isMeta()) {
883 return true;
Robert Shihbf207272014-10-30 17:22:11 -0700884 }
885 }
886
887 return false;
888}
889
Andreas Huberbff07d02010-10-12 11:34:37 -0700890int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
Chong Zhang799c9682015-03-02 23:42:38 -0800891 PTS = recoverPTS(PTS);
892
Andreas Huberc4c17d42011-08-30 16:06:28 -0700893 if (!(mParser->mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)) {
894 if (!mFirstPTSValid) {
895 mFirstPTSValid = true;
896 mFirstPTS = PTS;
897 PTS = 0;
898 } else if (PTS < mFirstPTS) {
899 PTS = 0;
900 } else {
901 PTS -= mFirstPTS;
902 }
Andreas Huberbff07d02010-10-12 11:34:37 -0700903 }
904
Andreas Huber87f2a552012-08-31 13:55:24 -0700905 int64_t timeUs = (PTS * 100) / 9;
906
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -0800907 if (mParser->mAbsoluteTimeAnchorUs >= 0LL) {
Andreas Huber87f2a552012-08-31 13:55:24 -0700908 timeUs += mParser->mAbsoluteTimeAnchorUs;
909 }
910
Andreas Huberd5e56232013-03-12 11:01:43 -0700911 if (mParser->mTimeOffsetValid) {
912 timeUs += mParser->mTimeOffsetUs;
913 }
914
Andreas Huber87f2a552012-08-31 13:55:24 -0700915 return timeUs;
Andreas Huberbff07d02010-10-12 11:34:37 -0700916}
917
Chong Zhang3b2847f2017-01-18 17:43:03 -0800918void ATSParser::Program::updateCasSessions() {
919 for (size_t i = 0; i < mStreams.size(); ++i) {
920 sp<Stream> &stream = mStreams.editValueAt(i);
921 sp<IDescrambler> descrambler;
922 std::vector<uint8_t> sessionId;
Chong Zhangbc7aae42017-03-31 14:53:19 -0700923 int32_t systemId;
924 if (mParser->mCasManager->getCasInfo(mProgramNumber, stream->pid(),
925 &systemId, &descrambler, &sessionId)) {
926 stream->setCasInfo(systemId, descrambler, sessionId);
Chong Zhang3b2847f2017-01-18 17:43:03 -0800927 }
928 }
929}
930
Andreas Hubercda17c62010-06-07 13:05:37 -0700931////////////////////////////////////////////////////////////////////////////////
Chong Zhang3b2847f2017-01-18 17:43:03 -0800932static const size_t kInitialStreamBufferSize = 192 * 1024;
Andreas Hubercda17c62010-06-07 13:05:37 -0700933
Andreas Huberbff07d02010-10-12 11:34:37 -0700934ATSParser::Stream::Stream(
Chong Zhang7e986a82018-11-07 13:01:08 -0800935 Program *program, unsigned PCR_PID, const StreamInfo &info)
Andreas Huberbff07d02010-10-12 11:34:37 -0700936 : mProgram(program),
Chong Zhang7e986a82018-11-07 13:01:08 -0800937 mElementaryPID(info.mPID),
938 mStreamType(info.mType),
939 mStreamTypeExt(info.mTypeExt),
Andreas Huber87f2a552012-08-31 13:55:24 -0700940 mPCR_PID(PCR_PID),
941 mExpectedContinuityCounter(-1),
Andreas Huber6a63a932010-10-01 10:51:41 -0700942 mPayloadStarted(false),
Marco Nelissenbe9634d2015-04-15 14:33:39 -0700943 mEOSReached(false),
Andreas Huber90a92052012-10-30 15:53:03 -0700944 mPrevPTS(0),
Chong Zhang3b2847f2017-01-18 17:43:03 -0800945 mQueue(NULL),
Sampath Shetty0ac73a52018-03-27 15:16:35 +1100946 mScrambled(info.mCADescriptor.mSystemID >= 0),
947 mAudioPresentations(info.mAudioPresentations) {
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700948 mSampleEncrypted =
949 mStreamType == STREAMTYPE_H264_ENCRYPTED ||
950 mStreamType == STREAMTYPE_AAC_ENCRYPTED ||
951 mStreamType == STREAMTYPE_AC3_ENCRYPTED;
952
953 ALOGV("new stream PID 0x%02x, type 0x%02x, scrambled %d, SampleEncrypted: %d",
Chong Zhang7e986a82018-11-07 13:01:08 -0800954 info.mPID, info.mType, mScrambled, mSampleEncrypted);
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700955
Chong Zhange32a4132018-07-23 14:17:38 -0700956 uint32_t flags = 0;
957 if (((isVideo() || isAudio()) && mScrambled)) {
958 flags = ElementaryStreamQueue::kFlag_ScrambledData;
959 } else if (mSampleEncrypted) {
960 flags = ElementaryStreamQueue::kFlag_SampleEncryptedData;
961 }
Chong Zhang3b2847f2017-01-18 17:43:03 -0800962
963 ElementaryStreamQueue::Mode mode = ElementaryStreamQueue::INVALID;
964
Andreas Huber386d6092011-05-19 08:37:39 -0700965 switch (mStreamType) {
966 case STREAMTYPE_H264:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700967 case STREAMTYPE_H264_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800968 mode = ElementaryStreamQueue::H264;
969 flags |= (mProgram->parserFlags() & ALIGNED_VIDEO_DATA) ?
970 ElementaryStreamQueue::kFlag_AlignedData : 0;
Andreas Huber386d6092011-05-19 08:37:39 -0700971 break;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800972
Andreas Huber6e3d3112011-11-28 12:36:11 -0800973 case STREAMTYPE_MPEG2_AUDIO_ADTS:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700974 case STREAMTYPE_AAC_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800975 mode = ElementaryStreamQueue::AAC;
Andreas Huber386d6092011-05-19 08:37:39 -0700976 break;
Chong Zhang3b2847f2017-01-18 17:43:03 -0800977
Andreas Huber386d6092011-05-19 08:37:39 -0700978 case STREAMTYPE_MPEG1_AUDIO:
979 case STREAMTYPE_MPEG2_AUDIO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800980 mode = ElementaryStreamQueue::MPEG_AUDIO;
Andreas Huber386d6092011-05-19 08:37:39 -0700981 break;
982
983 case STREAMTYPE_MPEG1_VIDEO:
984 case STREAMTYPE_MPEG2_VIDEO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800985 mode = ElementaryStreamQueue::MPEG_VIDEO;
Andreas Huber386d6092011-05-19 08:37:39 -0700986 break;
987
988 case STREAMTYPE_MPEG4_VIDEO:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800989 mode = ElementaryStreamQueue::MPEG4_VIDEO;
Andreas Huber386d6092011-05-19 08:37:39 -0700990 break;
991
Chong Zhang9bf32f02014-07-30 15:40:31 -0700992 case STREAMTYPE_LPCM_AC3:
Changwan Ryud3c079a2013-10-28 11:08:44 +0900993 case STREAMTYPE_AC3:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -0700994 case STREAMTYPE_AC3_ENCRYPTED:
Chong Zhang3b2847f2017-01-18 17:43:03 -0800995 mode = ElementaryStreamQueue::AC3;
Changwan Ryud3c079a2013-10-28 11:08:44 +0900996 break;
997
Previr Rangroo68e6fe12017-11-30 20:02:13 -0800998 case STREAMTYPE_EAC3:
999 mode = ElementaryStreamQueue::EAC3;
1000 break;
1001
Rahul3beba382023-02-03 20:36:55 +00001002 case STREAMTYPE_DTS:
1003 mode = ElementaryStreamQueue::DTS;
1004 break;
1005
Previr Rangroo7e6ac732017-11-13 20:20:20 -08001006 case STREAMTYPE_PES_PRIVATE_DATA:
1007 if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4) {
1008 mode = ElementaryStreamQueue::AC4;
Rahul3beba382023-02-03 20:36:55 +00001009 } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD) {
1010 mode = ElementaryStreamQueue::DTS_HD;
1011 } else if (mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD) {
1012 mode = ElementaryStreamQueue::DTS_UHD;
Previr Rangroo7e6ac732017-11-13 20:20:20 -08001013 }
1014 break;
1015
Robert Shih08528432015-04-08 09:06:54 -07001016 case STREAMTYPE_METADATA:
Chong Zhang3b2847f2017-01-18 17:43:03 -08001017 mode = ElementaryStreamQueue::METADATA;
Robert Shih08528432015-04-08 09:06:54 -07001018 break;
1019
Andreas Huber386d6092011-05-19 08:37:39 -07001020 default:
Chong Zhang3b2847f2017-01-18 17:43:03 -08001021 ALOGE("stream PID 0x%02x has invalid stream type 0x%02x",
Chong Zhang7e986a82018-11-07 13:01:08 -08001022 info.mPID, info.mType);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001023 return;
Andreas Huber386d6092011-05-19 08:37:39 -07001024 }
1025
Chong Zhang3b2847f2017-01-18 17:43:03 -08001026 mQueue = new ElementaryStreamQueue(mode, flags);
Andreas Huber18ac5402011-08-31 15:04:25 -07001027
1028 if (mQueue != NULL) {
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001029 if (mSampleAesKeyItem != NULL) {
1030 mQueue->signalNewSampleAesKey(mSampleAesKeyItem);
1031 }
1032
Chong Zhang3b2847f2017-01-18 17:43:03 -08001033 ensureBufferCapacity(kInitialStreamBufferSize);
1034
1035 if (mScrambled && (isAudio() || isVideo())) {
1036 // Set initial format to scrambled
1037 sp<MetaData> meta = new MetaData();
1038 meta->setCString(kKeyMIMEType,
1039 isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
1040 : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
Chong Zhangbc7aae42017-03-31 14:53:19 -07001041 // for MediaExtractor.CasInfo
Chong Zhang7e986a82018-11-07 13:01:08 -08001042 const CADescriptor &descriptor = info.mCADescriptor;
1043 meta->setInt32(kKeyCASystemID, descriptor.mSystemID);
1044
1045 meta->setData(kKeyCAPrivateData, 0,
1046 descriptor.mPrivateData.data(),
1047 descriptor.mPrivateData.size());
1048
Chong Zhang3b2847f2017-01-18 17:43:03 -08001049 mSource = new AnotherPacketSource(meta);
1050 }
Andreas Huber18ac5402011-08-31 15:04:25 -07001051 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001052}
1053
1054ATSParser::Stream::~Stream() {
Andreas Huber386d6092011-05-19 08:37:39 -07001055 delete mQueue;
1056 mQueue = NULL;
Andreas Hubercda17c62010-06-07 13:05:37 -07001057}
1058
Chong Zhangd5a416a2017-05-16 11:16:34 -07001059bool ATSParser::Stream::ensureBufferCapacity(size_t neededSize) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001060 if (mBuffer != NULL && mBuffer->capacity() >= neededSize) {
Chong Zhangd5a416a2017-05-16 11:16:34 -07001061 return true;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001062 }
1063
1064 ALOGV("ensureBufferCapacity: current size %zu, new size %zu, scrambled %d",
1065 mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);
1066
1067 sp<ABuffer> newBuffer, newScrambledBuffer;
Chong Zhang00c5c052018-12-17 14:15:58 -08001068 sp<TMemory> newMem;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001069 if (mScrambled) {
Devin Moore6482a5b2023-11-08 17:53:52 +00001070 int fd = ashmem_create_region("mediaATS", neededSize);
1071 if (fd < 0) {
1072 ALOGE("[stream %d] create_ashmem_region failed for size %zu. FD returned: %d",
1073 mElementaryPID, neededSize, fd);
1074 return false;
1075 }
1076
1077 native_handle_t* handle = native_handle_create(1 /*numFds*/, 0/*numInts*/);
1078 if (handle == nullptr) {
1079 ALOGE("[stream %d] failed to create a native_handle_t", mElementaryPID);
1080 if (close(fd)) {
1081 ALOGE("[stream %d] failed to close ashmem fd. errno: %s", mElementaryPID,
1082 strerror(errno));
Chong Zhang00c5c052018-12-17 14:15:58 -08001083 }
Chong Zhang00c5c052018-12-17 14:15:58 -08001084
Chong Zhang00c5c052018-12-17 14:15:58 -08001085 return false;
1086 }
Devin Moore6482a5b2023-11-08 17:53:52 +00001087
1088 handle->data[0] = fd;
1089 hidl_handle memHandle;
1090 memHandle.setTo(handle, true /*shouldOwn*/);
1091 hidl_memory hidlMemToken("ashmem", memHandle, neededSize);
1092
Chong Zhang00c5c052018-12-17 14:15:58 -08001093 newMem = mapMemory(hidlMemToken);
1094 if (newMem == nullptr || newMem->getPointer() == nullptr) {
1095 ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
1096 return false;
1097 }
1098
1099 newScrambledBuffer = new ABuffer(newMem->getPointer(), newMem->getSize());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001100
1101 if (mDescrambledBuffer != NULL) {
1102 memcpy(newScrambledBuffer->data(),
1103 mDescrambledBuffer->data(), mDescrambledBuffer->size());
1104 newScrambledBuffer->setRange(0, mDescrambledBuffer->size());
1105 } else {
1106 newScrambledBuffer->setRange(0, 0);
1107 }
Chong Zhang00c5c052018-12-17 14:15:58 -08001108 mHidlMemory = newMem;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001109 mDescrambledBuffer = newScrambledBuffer;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001110
Chong Zhang00c5c052018-12-17 14:15:58 -08001111 mDescramblerSrcBuffer.heapBase = hidlMemToken;
1112 mDescramblerSrcBuffer.offset = 0ULL;
1113 mDescramblerSrcBuffer.size = (uint64_t)neededSize;
Chong Zhang58ddee32018-02-13 17:52:39 -08001114
Chong Zhang00c5c052018-12-17 14:15:58 -08001115 ALOGD("[stream %d] created shared buffer for descrambling, size %zu",
1116 mElementaryPID, neededSize);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001117 } else {
1118 // Align to multiples of 64K.
1119 neededSize = (neededSize + 65535) & ~65535;
1120 }
1121
1122 newBuffer = new ABuffer(neededSize);
1123 if (mBuffer != NULL) {
1124 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
1125 newBuffer->setRange(0, mBuffer->size());
1126 } else {
1127 newBuffer->setRange(0, 0);
1128 }
1129 mBuffer = newBuffer;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001130 return true;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001131}
1132
Andreas Huber54031292011-09-01 11:04:43 -07001133status_t ATSParser::Stream::parse(
Andreas Huber87f2a552012-08-31 13:55:24 -07001134 unsigned continuity_counter,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001135 unsigned payload_unit_start_indicator,
1136 unsigned transport_scrambling_control,
1137 unsigned random_access_indicator,
1138 ABitReader *br, SyncEvent *event) {
Andreas Huber18ac5402011-08-31 15:04:25 -07001139 if (mQueue == NULL) {
Andreas Huber54031292011-09-01 11:04:43 -07001140 return OK;
Andreas Huber18ac5402011-08-31 15:04:25 -07001141 }
1142
Andreas Huber87f2a552012-08-31 13:55:24 -07001143 if (mExpectedContinuityCounter >= 0
1144 && (unsigned)mExpectedContinuityCounter != continuity_counter) {
1145 ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
1146
1147 mPayloadStarted = false;
Wei Jia9558f6d2016-03-08 17:31:16 -08001148 mPesStartOffsets.clear();
Andreas Huber87f2a552012-08-31 13:55:24 -07001149 mBuffer->setRange(0, 0);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001150 mSubSamples.clear();
Andreas Huber87f2a552012-08-31 13:55:24 -07001151 mExpectedContinuityCounter = -1;
1152
Andreas Huber94a483b2013-01-29 09:22:16 -08001153#if 0
1154 // Uncomment this if you'd rather see no corruption whatsoever on
1155 // screen and suspend updates until we come across another IDR frame.
1156
1157 if (mStreamType == STREAMTYPE_H264) {
1158 ALOGI("clearing video queue");
1159 mQueue->clear(true /* clearFormat */);
1160 }
1161#endif
1162
Chong Zhang66830852014-06-05 14:44:03 -07001163 if (!payload_unit_start_indicator) {
1164 return OK;
1165 }
Andreas Huber87f2a552012-08-31 13:55:24 -07001166 }
1167
1168 mExpectedContinuityCounter = (continuity_counter + 1) & 0x0f;
1169
Andreas Hubercda17c62010-06-07 13:05:37 -07001170 if (payload_unit_start_indicator) {
Wonsik Kim54000662015-04-13 10:59:06 +09001171 off64_t offset = (event != NULL) ? event->getOffset() : 0;
Andreas Hubercda17c62010-06-07 13:05:37 -07001172 if (mPayloadStarted) {
1173 // Otherwise we run the danger of receiving the trailing bytes
1174 // of a PES packet that we never saw the start of and assuming
1175 // we have a a complete PES packet.
1176
Wonsik Kim54000662015-04-13 10:59:06 +09001177 status_t err = flush(event);
Andreas Huber54031292011-09-01 11:04:43 -07001178
1179 if (err != OK) {
Wonsik Kim65959d32015-06-10 16:17:45 +09001180 ALOGW("Error (%08x) happened while flushing; we simply discard "
1181 "the PES packet and continue.", err);
Andreas Huber54031292011-09-01 11:04:43 -07001182 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001183 }
1184
1185 mPayloadStarted = true;
Wei Jiab08d83e2016-09-30 17:39:30 -07001186 // There should be at most 2 elements in |mPesStartOffsets|.
1187 while (mPesStartOffsets.size() >= 2) {
1188 mPesStartOffsets.erase(mPesStartOffsets.begin());
1189 }
Wei Jia9558f6d2016-03-08 17:31:16 -08001190 mPesStartOffsets.push_back(offset);
Andreas Hubercda17c62010-06-07 13:05:37 -07001191 }
1192
1193 if (!mPayloadStarted) {
Andreas Huber54031292011-09-01 11:04:43 -07001194 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001195 }
1196
1197 size_t payloadSizeBits = br->numBitsLeft();
Jinsuk Kime314c672015-04-22 11:08:28 +09001198 if (payloadSizeBits % 8 != 0u) {
1199 ALOGE("Wrong value");
1200 return BAD_VALUE;
1201 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001202
Andreas Huber3e573222011-03-02 16:18:33 -08001203 size_t neededSize = mBuffer->size() + payloadSizeBits / 8;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001204 if (!ensureBufferCapacity(neededSize)) {
1205 return NO_MEMORY;
1206 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001207
1208 memcpy(mBuffer->data() + mBuffer->size(), br->data(), payloadSizeBits / 8);
1209 mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
Andreas Huber54031292011-09-01 11:04:43 -07001210
Chong Zhang3b2847f2017-01-18 17:43:03 -08001211 if (mScrambled) {
1212 mSubSamples.push_back({payloadSizeBits / 8,
1213 transport_scrambling_control, random_access_indicator});
1214 }
1215
Andreas Huber54031292011-09-01 11:04:43 -07001216 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001217}
1218
Andreas Huber6e3d3112011-11-28 12:36:11 -08001219bool ATSParser::Stream::isVideo() const {
1220 switch (mStreamType) {
1221 case STREAMTYPE_H264:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001222 case STREAMTYPE_H264_ENCRYPTED:
Andreas Huber6e3d3112011-11-28 12:36:11 -08001223 case STREAMTYPE_MPEG1_VIDEO:
1224 case STREAMTYPE_MPEG2_VIDEO:
1225 case STREAMTYPE_MPEG4_VIDEO:
1226 return true;
1227
1228 default:
1229 return false;
1230 }
1231}
1232
1233bool ATSParser::Stream::isAudio() const {
1234 switch (mStreamType) {
1235 case STREAMTYPE_MPEG1_AUDIO:
1236 case STREAMTYPE_MPEG2_AUDIO:
1237 case STREAMTYPE_MPEG2_AUDIO_ADTS:
Chong Zhang9bf32f02014-07-30 15:40:31 -07001238 case STREAMTYPE_LPCM_AC3:
Changwan Ryud3c079a2013-10-28 11:08:44 +09001239 case STREAMTYPE_AC3:
Previr Rangroo68e6fe12017-11-30 20:02:13 -08001240 case STREAMTYPE_EAC3:
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001241 case STREAMTYPE_AAC_ENCRYPTED:
1242 case STREAMTYPE_AC3_ENCRYPTED:
Rahul3beba382023-02-03 20:36:55 +00001243 case STREAMTYPE_DTS:
Andreas Huber6e3d3112011-11-28 12:36:11 -08001244 return true;
Previr Rangroo7e6ac732017-11-13 20:20:20 -08001245 case STREAMTYPE_PES_PRIVATE_DATA:
Rahul3beba382023-02-03 20:36:55 +00001246 return (mStreamTypeExt == EXT_DESCRIPTOR_DVB_AC4
1247 || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_HD
1248 || mStreamTypeExt == EXT_DESCRIPTOR_DVB_DTS_UHD);
Andreas Huber6e3d3112011-11-28 12:36:11 -08001249
1250 default:
1251 return false;
1252 }
1253}
1254
Robert Shih08528432015-04-08 09:06:54 -07001255bool ATSParser::Stream::isMeta() const {
1256 if (mStreamType == STREAMTYPE_METADATA) {
1257 return true;
1258 }
1259 return false;
1260}
1261
Andreas Huber32f3cef2011-03-02 15:34:46 -08001262void ATSParser::Stream::signalDiscontinuity(
1263 DiscontinuityType type, const sp<AMessage> &extra) {
Marco Nelissen0389cc02012-10-02 10:47:39 -07001264 mExpectedContinuityCounter = -1;
1265
Andreas Huber18ac5402011-08-31 15:04:25 -07001266 if (mQueue == NULL) {
1267 return;
1268 }
1269
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001270 mPayloadStarted = false;
Wei Jia9558f6d2016-03-08 17:31:16 -08001271 mPesStartOffsets.clear();
Robert Shihaabbdc72015-05-08 17:39:40 -07001272 mEOSReached = false;
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001273 mBuffer->setRange(0, 0);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001274 mSubSamples.clear();
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001275
Andreas Huber6e3d3112011-11-28 12:36:11 -08001276 bool clearFormat = false;
1277 if (isAudio()) {
1278 if (type & DISCONTINUITY_AUDIO_FORMAT) {
1279 clearFormat = true;
Andreas Huberf9334412010-12-15 15:17:42 -08001280 }
Andreas Huber6e3d3112011-11-28 12:36:11 -08001281 } else {
1282 if (type & DISCONTINUITY_VIDEO_FORMAT) {
1283 clearFormat = true;
1284 }
1285 }
Andreas Huberf9334412010-12-15 15:17:42 -08001286
Andreas Huber6e3d3112011-11-28 12:36:11 -08001287 mQueue->clear(clearFormat);
1288
1289 if (type & DISCONTINUITY_TIME) {
1290 uint64_t resumeAtPTS;
1291 if (extra != NULL
1292 && extra->findInt64(
Dongwon Kang15d02f82017-12-14 16:32:18 -08001293 kATSParserKeyResumeAtPTS,
Andreas Huber6e3d3112011-11-28 12:36:11 -08001294 (int64_t *)&resumeAtPTS)) {
1295 int64_t resumeAtMediaTimeUs =
1296 mProgram->convertPTSToTimestamp(resumeAtPTS);
1297
Wei Jiac6cfd702014-11-11 16:33:20 -08001298 extra->setInt64("resume-at-mediaTimeUs", resumeAtMediaTimeUs);
Andreas Huber6e3d3112011-11-28 12:36:11 -08001299 }
1300 }
1301
1302 if (mSource != NULL) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001303 sp<MetaData> meta = mSource->getFormat();
1304 const char* mime;
1305 if (clearFormat && meta != NULL && meta->findCString(kKeyMIMEType, &mime)
1306 && (!strncasecmp(mime, MEDIA_MIMETYPE_AUDIO_SCRAMBLED, 15)
1307 || !strncasecmp(mime, MEDIA_MIMETYPE_VIDEO_SCRAMBLED, 15))){
1308 mSource->clear();
1309 } else {
1310 mSource->queueDiscontinuity(type, extra, true);
1311 }
Andreas Huberf9334412010-12-15 15:17:42 -08001312 }
1313}
1314
1315void ATSParser::Stream::signalEOS(status_t finalResult) {
1316 if (mSource != NULL) {
1317 mSource->signalEOS(finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001318 }
Marco Nelissenbe9634d2015-04-15 14:33:39 -07001319 mEOSReached = true;
Wonsik Kim54000662015-04-13 10:59:06 +09001320 flush(NULL);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001321}
1322
Wonsik Kim54000662015-04-13 10:59:06 +09001323status_t ATSParser::Stream::parsePES(ABitReader *br, SyncEvent *event) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001324 const uint8_t *basePtr = br->data();
1325
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001326 if (br->numBitsLeft() < 48) {
1327 ALOGE("Not enough data left in bitreader!");
1328 return ERROR_MALFORMED;
1329 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001330 unsigned packet_startcode_prefix = br->getBits(24);
1331
Steve Block3856b092011-10-20 11:56:00 +01001332 ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
Andreas Hubercda17c62010-06-07 13:05:37 -07001333
Andreas Huber386d6092011-05-19 08:37:39 -07001334 if (packet_startcode_prefix != 1) {
Steve Block3856b092011-10-20 11:56:00 +01001335 ALOGV("Supposedly payload_unit_start=1 unit does not start "
Andreas Huber386d6092011-05-19 08:37:39 -07001336 "with startcode.");
Andreas Huber54031292011-09-01 11:04:43 -07001337
1338 return ERROR_MALFORMED;
Andreas Huber386d6092011-05-19 08:37:39 -07001339 }
1340
Andreas Hubercda17c62010-06-07 13:05:37 -07001341 unsigned stream_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01001342 ALOGV("stream_id = 0x%02x", stream_id);
Andreas Hubercda17c62010-06-07 13:05:37 -07001343
1344 unsigned PES_packet_length = br->getBits(16);
Steve Block3856b092011-10-20 11:56:00 +01001345 ALOGV("PES_packet_length = %u", PES_packet_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07001346
1347 if (stream_id != 0xbc // program_stream_map
1348 && stream_id != 0xbe // padding_stream
1349 && stream_id != 0xbf // private_stream_2
1350 && stream_id != 0xf0 // ECM
1351 && stream_id != 0xf1 // EMM
1352 && stream_id != 0xff // program_stream_directory
1353 && stream_id != 0xf2 // DSMCC
1354 && stream_id != 0xf8) { // H.222.1 type E
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001355 if (br->numBitsLeft() < 2 || br->getBits(2) != 2u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001356 return ERROR_MALFORMED;
1357 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001358
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001359 if (br->numBitsLeft() < 22) {
1360 ALOGE("Not enough data left in bitreader!");
1361 return ERROR_MALFORMED;
1362 }
Chong Zhang3b2847f2017-01-18 17:43:03 -08001363 unsigned PES_scrambling_control = br->getBits(2);
1364 ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
1365
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001366 MY_LOGV("PES_priority = %u", br->getBits(1));
1367 MY_LOGV("data_alignment_indicator = %u", br->getBits(1));
1368 MY_LOGV("copyright = %u", br->getBits(1));
1369 MY_LOGV("original_or_copy = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07001370
1371 unsigned PTS_DTS_flags = br->getBits(2);
Steve Block3856b092011-10-20 11:56:00 +01001372 ALOGV("PTS_DTS_flags = %u", PTS_DTS_flags);
Andreas Hubercda17c62010-06-07 13:05:37 -07001373
1374 unsigned ESCR_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001375 ALOGV("ESCR_flag = %u", ESCR_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001376
1377 unsigned ES_rate_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001378 ALOGV("ES_rate_flag = %u", ES_rate_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001379
1380 unsigned DSM_trick_mode_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001381 ALOGV("DSM_trick_mode_flag = %u", DSM_trick_mode_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001382
1383 unsigned additional_copy_info_flag = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01001384 ALOGV("additional_copy_info_flag = %u", additional_copy_info_flag);
Andreas Hubercda17c62010-06-07 13:05:37 -07001385
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001386 MY_LOGV("PES_CRC_flag = %u", br->getBits(1));
1387 MY_LOGV("PES_extension_flag = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07001388
1389 unsigned PES_header_data_length = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01001390 ALOGV("PES_header_data_length = %u", PES_header_data_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07001391
1392 unsigned optional_bytes_remaining = PES_header_data_length;
1393
1394 uint64_t PTS = 0, DTS = 0;
1395
1396 if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001397 if (optional_bytes_remaining < 5u) {
1398 return ERROR_MALFORMED;
1399 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001400
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001401 if (br->numBitsLeft() < 7 || br->getBits(4) != PTS_DTS_flags) {
David Yeh6456ae72014-09-03 11:14:48 +08001402 return ERROR_MALFORMED;
1403 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001404 PTS = ((uint64_t)br->getBits(3)) << 30;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001405 if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001406 return ERROR_MALFORMED;
1407 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001408 PTS |= ((uint64_t)br->getBits(15)) << 15;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001409 if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001410 return ERROR_MALFORMED;
1411 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001412 PTS |= br->getBits(15);
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001413 if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001414 return ERROR_MALFORMED;
1415 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001416
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001417 ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);
Andreas Hubercda17c62010-06-07 13:05:37 -07001418
1419 optional_bytes_remaining -= 5;
1420
1421 if (PTS_DTS_flags == 3) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001422 if (optional_bytes_remaining < 5u) {
1423 return ERROR_MALFORMED;
1424 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001425
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001426 if (br->numBitsLeft() < 7 || br->getBits(4) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001427 return ERROR_MALFORMED;
1428 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001429
1430 DTS = ((uint64_t)br->getBits(3)) << 30;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001431 if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001432 return ERROR_MALFORMED;
1433 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001434 DTS |= ((uint64_t)br->getBits(15)) << 15;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001435 if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001436 return ERROR_MALFORMED;
1437 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001438 DTS |= br->getBits(15);
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001439 if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001440 return ERROR_MALFORMED;
1441 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001442
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001443 ALOGV("DTS = %" PRIu64, DTS);
Andreas Hubercda17c62010-06-07 13:05:37 -07001444
1445 optional_bytes_remaining -= 5;
1446 }
1447 }
1448
1449 if (ESCR_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001450 if (optional_bytes_remaining < 6u) {
1451 return ERROR_MALFORMED;
1452 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001453
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001454 if (br->numBitsLeft() < 5) {
1455 ALOGE("Not enough data left in bitreader!");
1456 return ERROR_MALFORMED;
1457 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001458 br->getBits(2);
1459
1460 uint64_t ESCR = ((uint64_t)br->getBits(3)) << 30;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001461 if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001462 return ERROR_MALFORMED;
1463 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001464 ESCR |= ((uint64_t)br->getBits(15)) << 15;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001465 if (br->numBitsLeft() < 16 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001466 return ERROR_MALFORMED;
1467 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001468 ESCR |= br->getBits(15);
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001469 if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001470 return ERROR_MALFORMED;
1471 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001472
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001473 ALOGV("ESCR = %" PRIu64, ESCR);
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001474 if (br->numBitsLeft() < 10) {
1475 ALOGE("Not enough data left in bitreader!");
1476 return ERROR_MALFORMED;
1477 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001478 MY_LOGV("ESCR_extension = %u", br->getBits(9));
Andreas Hubercda17c62010-06-07 13:05:37 -07001479
Jinsuk Kime314c672015-04-22 11:08:28 +09001480 if (br->getBits(1) != 1u) {
1481 return ERROR_MALFORMED;
1482 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001483
1484 optional_bytes_remaining -= 6;
1485 }
1486
1487 if (ES_rate_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001488 if (optional_bytes_remaining < 3u) {
1489 return ERROR_MALFORMED;
1490 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001491
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001492 if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
1493 return ERROR_MALFORMED;
1494 }
1495 if (br->numBitsLeft() < 22) {
1496 ALOGE("Not enough data left in bitreader!");
Jinsuk Kime314c672015-04-22 11:08:28 +09001497 return ERROR_MALFORMED;
1498 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -07001499 MY_LOGV("ES_rate = %u", br->getBits(22));
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001500 if (br->numBitsLeft() < 1 || br->getBits(1) != 1u) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001501 return ERROR_MALFORMED;
1502 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001503
1504 optional_bytes_remaining -= 3;
1505 }
1506
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001507 if (!br->skipBits(optional_bytes_remaining * 8)) {
1508 ALOGE("Not enough data left in bitreader!");
1509 return ERROR_MALFORMED;
1510 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001511
1512 // ES data follows.
Chong Zhang3b2847f2017-01-18 17:43:03 -08001513 int32_t pesOffset = br->data() - basePtr;
Andreas Hubercda17c62010-06-07 13:05:37 -07001514
Andreas Hubercda17c62010-06-07 13:05:37 -07001515 if (PES_packet_length != 0) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001516 if (PES_packet_length < PES_header_data_length + 3) {
1517 return ERROR_MALFORMED;
1518 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001519
1520 unsigned dataLength =
1521 PES_packet_length - 3 - PES_header_data_length;
1522
Andreas Huber54031292011-09-01 11:04:43 -07001523 if (br->numBitsLeft() < dataLength * 8) {
Steve Block29357bc2012-01-06 19:20:56 +00001524 ALOGE("PES packet does not carry enough data to contain "
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001525 "payload. (numBitsLeft = %zu, required = %u)",
Andreas Huber54031292011-09-01 11:04:43 -07001526 br->numBitsLeft(), dataLength * 8);
1527
1528 return ERROR_MALFORMED;
1529 }
1530
Chong Zhang3b2847f2017-01-18 17:43:03 -08001531 ALOGV("There's %u bytes of payload, PES_packet_length=%u, offset=%d",
1532 dataLength, PES_packet_length, pesOffset);
1533
Andreas Huber0da4dab2010-09-27 12:04:43 -07001534 onPayloadData(
Chong Zhang3b2847f2017-01-18 17:43:03 -08001535 PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
1536 br->data(), dataLength, pesOffset, event);
Andreas Hubercda17c62010-06-07 13:05:37 -07001537
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001538 if (!br->skipBits(dataLength * 8)) {
1539 ALOGE("Not enough data left in bitreader!");
1540 return ERROR_MALFORMED;
1541 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001542 } else {
Andreas Huber0da4dab2010-09-27 12:04:43 -07001543 onPayloadData(
Chong Zhang3b2847f2017-01-18 17:43:03 -08001544 PTS_DTS_flags, PTS, DTS, PES_scrambling_control,
1545 br->data(), br->numBitsLeft() / 8, pesOffset, event);
Andreas Huber0da4dab2010-09-27 12:04:43 -07001546
Andreas Hubercda17c62010-06-07 13:05:37 -07001547 size_t payloadSizeBits = br->numBitsLeft();
Jinsuk Kime314c672015-04-22 11:08:28 +09001548 if (payloadSizeBits % 8 != 0u) {
1549 return ERROR_MALFORMED;
1550 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001551
Chong Zhang3b2847f2017-01-18 17:43:03 -08001552 ALOGV("There's %zu bytes of payload, offset=%d",
1553 payloadSizeBits / 8, pesOffset);
Andreas Hubercda17c62010-06-07 13:05:37 -07001554 }
1555 } else if (stream_id == 0xbe) { // padding_stream
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001556 if (PES_packet_length == 0u || !br->skipBits(PES_packet_length * 8)) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001557 return ERROR_MALFORMED;
1558 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001559 } else {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001560 if (PES_packet_length == 0u || !br->skipBits(PES_packet_length * 8)) {
Jinsuk Kime314c672015-04-22 11:08:28 +09001561 return ERROR_MALFORMED;
1562 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001563 }
Andreas Huber54031292011-09-01 11:04:43 -07001564
1565 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001566}
1567
Chong Zhang3b2847f2017-01-18 17:43:03 -08001568uint32_t ATSParser::Stream::getPesScramblingControl(
1569 ABitReader *br, int32_t *pesOffset) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001570 if (br->numBitsLeft() < 24) {
1571 ALOGE("Not enough data left in bitreader!");
1572 return 0;
1573 }
Chong Zhang3b2847f2017-01-18 17:43:03 -08001574 unsigned packet_startcode_prefix = br->getBits(24);
1575
1576 ALOGV("packet_startcode_prefix = 0x%08x", packet_startcode_prefix);
1577
1578 if (packet_startcode_prefix != 1) {
1579 ALOGV("unit does not start with startcode.");
1580 return 0;
1581 }
1582
1583 if (br->numBitsLeft() < 48) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00001584 ALOGE("Not enough data left in bitreader!");
Chong Zhang3b2847f2017-01-18 17:43:03 -08001585 return 0;
1586 }
1587
1588 unsigned stream_id = br->getBits(8);
1589 ALOGV("stream_id = 0x%02x", stream_id);
1590
1591 br->skipBits(16); // PES_packet_length
1592
1593 if (stream_id != 0xbc // program_stream_map
1594 && stream_id != 0xbe // padding_stream
1595 && stream_id != 0xbf // private_stream_2
1596 && stream_id != 0xf0 // ECM
1597 && stream_id != 0xf1 // EMM
1598 && stream_id != 0xff // program_stream_directory
1599 && stream_id != 0xf2 // DSMCC
1600 && stream_id != 0xf8) { // H.222.1 type E
1601 if (br->getBits(2) != 2u) {
1602 return 0;
1603 }
1604
1605 unsigned PES_scrambling_control = br->getBits(2);
1606 ALOGV("PES_scrambling_control = %u", PES_scrambling_control);
1607
1608 if (PES_scrambling_control == 0) {
1609 return 0;
1610 }
1611
1612 br->skipBits(12); // don't care
1613
1614 unsigned PES_header_data_length = br->getBits(8);
1615 ALOGV("PES_header_data_length = %u", PES_header_data_length);
1616
1617 if (PES_header_data_length * 8 > br->numBitsLeft()) {
1618 return 0;
1619 }
1620
1621 *pesOffset = 9 + PES_header_data_length;
1622 ALOGD("found PES_scrambling_control=%d, PES offset=%d",
1623 PES_scrambling_control, *pesOffset);
1624 return PES_scrambling_control;
1625 }
1626
1627 return 0;
1628}
1629
1630status_t ATSParser::Stream::flushScrambled(SyncEvent *event) {
1631 if (mDescrambler == NULL) {
1632 ALOGE("received scrambled packets without descrambler!");
1633 return UNKNOWN_ERROR;
1634 }
1635
Chong Zhang00c5c052018-12-17 14:15:58 -08001636 if (mDescrambledBuffer == NULL || mHidlMemory == NULL) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001637 ALOGE("received scrambled packets without shared memory!");
1638
1639 return UNKNOWN_ERROR;
1640 }
1641
1642 int32_t pesOffset = 0;
1643 int32_t descrambleSubSamples = 0, descrambleBytes = 0;
1644 uint32_t tsScramblingControl = 0, pesScramblingControl = 0;
1645
1646 // First, go over subsamples to find TS-level scrambling key id, and
1647 // calculate how many subsample we need to descramble (assuming we don't
1648 // have PES-level scrambling).
1649 for (auto it = mSubSamples.begin(); it != mSubSamples.end(); it++) {
1650 if (it->transport_scrambling_mode != 0) {
1651 // TODO: handle keyId change, use the first non-zero keyId for now.
1652 if (tsScramblingControl == 0) {
1653 tsScramblingControl = it->transport_scrambling_mode;
1654 }
1655 }
1656 if (tsScramblingControl == 0 || descrambleSubSamples == 0
1657 || !mQueue->isScrambled()) {
1658 descrambleSubSamples++;
1659 descrambleBytes += it->subSampleSize;
1660 }
1661 }
1662 // If not scrambled at TS-level, check PES-level scrambling
1663 if (tsScramblingControl == 0) {
1664 ABitReader br(mBuffer->data(), mBuffer->size());
1665 pesScramblingControl = getPesScramblingControl(&br, &pesOffset);
1666 // If not scrambled at PES-level either, or scrambled at PES-level but
1667 // requires output to remain scrambled, we don't need to descramble
1668 // anything.
1669 if (pesScramblingControl == 0 || mQueue->isScrambled()) {
1670 descrambleSubSamples = 0;
1671 descrambleBytes = 0;
1672 }
1673 }
1674
1675 uint32_t sctrl = tsScramblingControl != 0 ?
1676 tsScramblingControl : pesScramblingControl;
Chong Zhangd1af6412018-02-20 10:59:37 -08001677 if (mQueue->isScrambled()) {
1678 sctrl |= DescramblerPlugin::kScrambling_Flag_PesHeader;
1679 }
Chong Zhang3b2847f2017-01-18 17:43:03 -08001680
1681 // Perform the 1st pass descrambling if needed
1682 if (descrambleBytes > 0) {
1683 memcpy(mDescrambledBuffer->data(), mBuffer->data(), descrambleBytes);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001684 mDescrambledBuffer->setRange(0, mBuffer->size());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001685
Chong Zhangd5a416a2017-05-16 11:16:34 -07001686 hidl_vec<SubSample> subSamples;
1687 subSamples.resize(descrambleSubSamples);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001688
1689 int32_t i = 0;
1690 for (auto it = mSubSamples.begin();
1691 it != mSubSamples.end() && i < descrambleSubSamples; it++, i++) {
1692 if (it->transport_scrambling_mode != 0 || pesScramblingControl != 0) {
Chong Zhangd5a416a2017-05-16 11:16:34 -07001693 subSamples[i].numBytesOfClearData = 0;
1694 subSamples[i].numBytesOfEncryptedData = it->subSampleSize;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001695 } else {
Chong Zhangd5a416a2017-05-16 11:16:34 -07001696 subSamples[i].numBytesOfClearData = it->subSampleSize;
1697 subSamples[i].numBytesOfEncryptedData = 0;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001698 }
1699 }
Chong Zhangd5a416a2017-05-16 11:16:34 -07001700
Chong Zhangb2451bb2018-07-12 12:19:12 -07001701 // If scrambled at PES-level, PES header is in the clear
Chong Zhang3b2847f2017-01-18 17:43:03 -08001702 if (pesScramblingControl != 0) {
Chong Zhangb2451bb2018-07-12 12:19:12 -07001703 subSamples[0].numBytesOfClearData = pesOffset;
Chong Zhangd5a416a2017-05-16 11:16:34 -07001704 subSamples[0].numBytesOfEncryptedData -= pesOffset;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001705 }
1706
Chong Zhangd5a416a2017-05-16 11:16:34 -07001707 Status status = Status::OK;
1708 uint32_t bytesWritten = 0;
1709 hidl_string detailedError;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001710
Chong Zhangd5a416a2017-05-16 11:16:34 -07001711 DestinationBuffer dstBuffer;
1712 dstBuffer.type = BufferType::SHARED_MEMORY;
1713 dstBuffer.nonsecureMemory = mDescramblerSrcBuffer;
1714
1715 auto returnVoid = mDescrambler->descramble(
1716 (ScramblingControl) sctrl,
1717 subSamples,
1718 mDescramblerSrcBuffer,
Chong Zhangb2451bb2018-07-12 12:19:12 -07001719 0 /*srcOffset*/,
Chong Zhangd5a416a2017-05-16 11:16:34 -07001720 dstBuffer,
Chong Zhangb2451bb2018-07-12 12:19:12 -07001721 0 /*dstOffset*/,
Chong Zhangd5a416a2017-05-16 11:16:34 -07001722 [&status, &bytesWritten, &detailedError] (
1723 Status _status, uint32_t _bytesWritten,
1724 const hidl_string& _detailedError) {
1725 status = _status;
1726 bytesWritten = _bytesWritten;
1727 detailedError = _detailedError;
1728 });
1729
Chong Zhangf03d9352019-01-04 11:24:47 -08001730 if (!returnVoid.isOk() || status != Status::OK) {
1731 ALOGE("[stream %d] descramble failed, trans=%s, status=%d",
1732 mElementaryPID, returnVoid.description().c_str(), status);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001733 return UNKNOWN_ERROR;
1734 }
1735
1736 ALOGV("[stream %d] descramble succeeded, %d bytes",
Chong Zhangd5a416a2017-05-16 11:16:34 -07001737 mElementaryPID, bytesWritten);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001738
1739 // Set descrambleBytes to the returned result.
1740 // Note that this might be smaller than the total length of input data.
1741 // (eg. when we're descrambling the PES header portion of a secure stream,
1742 // the plugin might cut it off right after the PES header.)
1743 descrambleBytes = bytesWritten;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001744 }
1745
Chong Zhange32a4132018-07-23 14:17:38 -07001746 // |buffer| points to the buffer from which we'd parse the PES header.
1747 // When the output stream is scrambled, it points to mDescrambledBuffer
1748 // (unless all packets in this PES are actually clear, in which case,
1749 // it points to mBuffer since we never copied into mDescrambledBuffer).
1750 // When the output stream is clear, it points to mBuffer, and we'll
1751 // copy all descrambled data back to mBuffer.
1752 sp<ABuffer> buffer = mBuffer;
Chong Zhang3b2847f2017-01-18 17:43:03 -08001753 if (mQueue->isScrambled()) {
1754 // Queue subSample info for scrambled queue
1755 sp<ABuffer> clearSizesBuffer = new ABuffer(mSubSamples.size() * 4);
1756 sp<ABuffer> encSizesBuffer = new ABuffer(mSubSamples.size() * 4);
1757 int32_t *clearSizePtr = (int32_t*)clearSizesBuffer->data();
1758 int32_t *encSizePtr = (int32_t*)encSizesBuffer->data();
1759 int32_t isSync = 0;
1760 int32_t i = 0;
1761 for (auto it = mSubSamples.begin();
1762 it != mSubSamples.end(); it++, i++) {
1763 if ((it->transport_scrambling_mode == 0
Chong Zhangb2451bb2018-07-12 12:19:12 -07001764 && pesScramblingControl == 0)) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08001765 clearSizePtr[i] = it->subSampleSize;
1766 encSizePtr[i] = 0;
1767 } else {
1768 clearSizePtr[i] = 0;
1769 encSizePtr[i] = it->subSampleSize;
1770 }
1771 isSync |= it->random_access_indicator;
1772 }
Chong Zhangb2451bb2018-07-12 12:19:12 -07001773
1774 // If scrambled at PES-level, PES header is in the clear
1775 if (pesScramblingControl != 0) {
1776 clearSizePtr[0] = pesOffset;
1777 encSizePtr[0] -= pesOffset;
1778 }
Chong Zhang3b2847f2017-01-18 17:43:03 -08001779 // Pass the original TS subsample size now. The PES header adjust
1780 // will be applied when the scrambled AU is dequeued.
Chong Zhange32a4132018-07-23 14:17:38 -07001781 // Note that if descrambleBytes is 0, it means this PES contains only
1782 // all ts packets, leadingClearBytes is entire buffer size.
Chong Zhang3b2847f2017-01-18 17:43:03 -08001783 mQueue->appendScrambledData(
Chong Zhange32a4132018-07-23 14:17:38 -07001784 mBuffer->data(), mBuffer->size(),
1785 (descrambleBytes > 0) ? descrambleBytes : mBuffer->size(),
1786 sctrl, isSync, clearSizesBuffer, encSizesBuffer);
Chong Zhangb2451bb2018-07-12 12:19:12 -07001787
Chong Zhange32a4132018-07-23 14:17:38 -07001788 if (descrambleBytes > 0) {
1789 buffer = mDescrambledBuffer;
1790 }
Chong Zhangb2451bb2018-07-12 12:19:12 -07001791 } else {
1792 memcpy(mBuffer->data(), mDescrambledBuffer->data(), descrambleBytes);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001793 }
1794
Chong Zhangb2451bb2018-07-12 12:19:12 -07001795 ABitReader br(buffer->data(), buffer->size());
Chong Zhang3b2847f2017-01-18 17:43:03 -08001796 status_t err = parsePES(&br, event);
1797
1798 if (err != OK) {
1799 ALOGE("[stream %d] failed to parse descrambled PES, err=%d",
1800 mElementaryPID, err);
1801 }
1802
1803 return err;
1804}
1805
1806
Wonsik Kim54000662015-04-13 10:59:06 +09001807status_t ATSParser::Stream::flush(SyncEvent *event) {
Jaesung Chungf2cecd52015-05-21 14:23:07 +09001808 if (mBuffer == NULL || mBuffer->size() == 0) {
Andreas Huber54031292011-09-01 11:04:43 -07001809 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07001810 }
1811
Colin Crossb4a7a2d2014-03-19 16:59:00 -07001812 ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size());
Andreas Hubercda17c62010-06-07 13:05:37 -07001813
Chong Zhang3b2847f2017-01-18 17:43:03 -08001814 status_t err = OK;
1815 if (mScrambled) {
1816 err = flushScrambled(event);
1817 mSubSamples.clear();
1818 } else {
1819 ABitReader br(mBuffer->data(), mBuffer->size());
1820 err = parsePES(&br, event);
1821 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001822
1823 mBuffer->setRange(0, 0);
Andreas Huber54031292011-09-01 11:04:43 -07001824
1825 return err;
Andreas Hubercda17c62010-06-07 13:05:37 -07001826}
1827
Sampath Shettyc6148a62018-12-18 15:50:43 +11001828void ATSParser::Stream::addAudioPresentations(const sp<ABuffer> &buffer) {
1829 std::ostringstream outStream(std::ios::out);
1830 serializeAudioPresentations(mAudioPresentations, &outStream);
1831 sp<ABuffer> ap = ABuffer::CreateAsCopy(outStream.str().data(), outStream.str().size());
1832 buffer->meta()->setBuffer("audio-presentation-info", ap);
1833}
1834
Andreas Hubercda17c62010-06-07 13:05:37 -07001835void ATSParser::Stream::onPayloadData(
Andreas Huber84333e02014-02-07 15:36:10 -08001836 unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001837 unsigned PES_scrambling_control,
1838 const uint8_t *data, size_t size,
1839 int32_t payloadOffset, SyncEvent *event) {
Andreas Huber90a92052012-10-30 15:53:03 -07001840#if 0
1841 ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
1842 mStreamType,
1843 PTS,
1844 (int64_t)PTS - mPrevPTS);
1845 mPrevPTS = PTS;
1846#endif
1847
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001848 ALOGV("onPayloadData mStreamType=0x%02x size: %zu", mStreamType, size);
Andreas Hubercda17c62010-06-07 13:05:37 -07001849
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001850 int64_t timeUs = 0LL; // no presentation timestamp available.
Andreas Huber98a46cf2011-10-12 12:14:23 -07001851 if (PTS_DTS_flags == 2 || PTS_DTS_flags == 3) {
1852 timeUs = mProgram->convertPTSToTimestamp(PTS);
1853 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001854
Chong Zhang3b2847f2017-01-18 17:43:03 -08001855 status_t err = mQueue->appendData(
1856 data, size, timeUs, payloadOffset, PES_scrambling_control);
Andreas Huberdecd9692010-12-02 13:27:47 -08001857
Marco Nelissenbe9634d2015-04-15 14:33:39 -07001858 if (mEOSReached) {
1859 mQueue->signalEOS();
1860 }
1861
Andreas Huberdecd9692010-12-02 13:27:47 -08001862 if (err != OK) {
1863 return;
1864 }
Andreas Hubercda17c62010-06-07 13:05:37 -07001865
Andreas Huber6a63a932010-10-01 10:51:41 -07001866 sp<ABuffer> accessUnit;
Wonsik Kim54000662015-04-13 10:59:06 +09001867 bool found = false;
Andreas Huber386d6092011-05-19 08:37:39 -07001868 while ((accessUnit = mQueue->dequeueAccessUnit()) != NULL) {
Andreas Huber6a63a932010-10-01 10:51:41 -07001869 if (mSource == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07001870 sp<MetaData> meta = mQueue->getFormat();
Andreas Hubercda17c62010-06-07 13:05:37 -07001871
Andreas Huber6a63a932010-10-01 10:51:41 -07001872 if (meta != NULL) {
Steve Block3856b092011-10-20 11:56:00 +01001873 ALOGV("Stream PID 0x%08x of type 0x%02x now has data.",
Andreas Huber386d6092011-05-19 08:37:39 -07001874 mElementaryPID, mStreamType);
1875
Robert Shih309aa8b2014-07-29 18:34:36 -07001876 const char *mime;
1877 if (meta->findCString(kKeyMIMEType, &mime)
Chong Zhang3b2847f2017-01-18 17:43:03 -08001878 && !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1879 int32_t sync = 0;
1880 if (!accessUnit->meta()->findInt32("isSync", &sync) || !sync) {
1881 continue;
1882 }
Robert Shih309aa8b2014-07-29 18:34:36 -07001883 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001884 mSource = new AnotherPacketSource(meta);
Sampath Shettyc6148a62018-12-18 15:50:43 +11001885 if (mAudioPresentations.size() > 0) {
1886 addAudioPresentations(accessUnit);
1887 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001888 mSource->queueAccessUnit(accessUnit);
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07001889 ALOGV("onPayloadData: created AnotherPacketSource PID 0x%08x of type 0x%02x",
1890 mElementaryPID, mStreamType);
Andreas Huber82f73212010-09-01 12:22:36 -07001891 }
Andreas Huber386d6092011-05-19 08:37:39 -07001892 } else if (mQueue->getFormat() != NULL) {
Andreas Huber2a4d22d2010-09-08 14:32:20 -07001893 // After a discontinuity we invalidate the queue's format
1894 // and won't enqueue any access units to the source until
1895 // the queue has reestablished the new format.
Andreas Huber5bc087c2010-12-23 10:27:40 -08001896
1897 if (mSource->getFormat() == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07001898 mSource->setFormat(mQueue->getFormat());
Andreas Huber5bc087c2010-12-23 10:27:40 -08001899 }
Sampath Shettyc6148a62018-12-18 15:50:43 +11001900 if (mAudioPresentations.size() > 0) {
1901 addAudioPresentations(accessUnit);
1902 }
Andreas Huber6a63a932010-10-01 10:51:41 -07001903 mSource->queueAccessUnit(accessUnit);
Andreas Huber82f73212010-09-01 12:22:36 -07001904 }
Wonsik Kim54000662015-04-13 10:59:06 +09001905
Wei Jiab08d83e2016-09-30 17:39:30 -07001906 // Every access unit has a pesStartOffset queued in |mPesStartOffsets|.
1907 off64_t pesStartOffset = -1;
1908 if (!mPesStartOffsets.empty()) {
1909 pesStartOffset = *mPesStartOffsets.begin();
1910 mPesStartOffsets.erase(mPesStartOffsets.begin());
1911 }
1912
1913 if (pesStartOffset >= 0 && (event != NULL) && !found && mQueue->getFormat() != NULL) {
Wonsik Kim54000662015-04-13 10:59:06 +09001914 int32_t sync = 0;
1915 if (accessUnit->meta()->findInt32("isSync", &sync) && sync) {
1916 int64_t timeUs;
1917 if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
1918 found = true;
Robert Shih82e14702016-11-17 11:24:29 -08001919 event->init(pesStartOffset, mSource, timeUs, getSourceType());
Wonsik Kim54000662015-04-13 10:59:06 +09001920 }
1921 }
1922 }
Andreas Huber82f73212010-09-01 12:22:36 -07001923 }
Andreas Huber82f73212010-09-01 12:22:36 -07001924}
1925
Robert Shih82e14702016-11-17 11:24:29 -08001926ATSParser::SourceType ATSParser::Stream::getSourceType() {
1927 if (isVideo()) {
1928 return VIDEO;
1929 } else if (isAudio()) {
1930 return AUDIO;
1931 } else if (isMeta()) {
1932 return META;
1933 }
1934 return NUM_SOURCE_TYPES;
1935}
1936
Marco Nelissen45d54c62018-01-26 10:04:22 -08001937sp<AnotherPacketSource> ATSParser::Stream::getSource(SourceType type) {
Andreas Huber386d6092011-05-19 08:37:39 -07001938 switch (type) {
1939 case VIDEO:
1940 {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001941 if (isVideo()) {
Andreas Huber386d6092011-05-19 08:37:39 -07001942 return mSource;
1943 }
1944 break;
1945 }
1946
1947 case AUDIO:
1948 {
Andreas Huber6e3d3112011-11-28 12:36:11 -08001949 if (isAudio()) {
Andreas Huber386d6092011-05-19 08:37:39 -07001950 return mSource;
1951 }
1952 break;
1953 }
1954
Robert Shih08528432015-04-08 09:06:54 -07001955 case META:
1956 {
1957 if (isMeta()) {
1958 return mSource;
1959 }
1960 break;
1961 }
1962
Andreas Huber386d6092011-05-19 08:37:39 -07001963 default:
1964 break;
Andreas Hubercda17c62010-06-07 13:05:37 -07001965 }
1966
1967 return NULL;
1968}
1969
Chong Zhangbc7aae42017-03-31 14:53:19 -07001970void ATSParser::Stream::setCasInfo(
1971 int32_t systemId, const sp<IDescrambler> &descrambler,
Chong Zhang3b2847f2017-01-18 17:43:03 -08001972 const std::vector<uint8_t> &sessionId) {
1973 if (mSource != NULL && mDescrambler == NULL && descrambler != NULL) {
1974 signalDiscontinuity(DISCONTINUITY_FORMAT_ONLY, NULL);
1975 mDescrambler = descrambler;
1976 if (mQueue->isScrambled()) {
Chong Zhangbc7aae42017-03-31 14:53:19 -07001977 mQueue->setCasInfo(systemId, sessionId);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001978 }
1979 }
1980}
1981
Andreas Hubercda17c62010-06-07 13:05:37 -07001982////////////////////////////////////////////////////////////////////////////////
1983
Andreas Huberc4c17d42011-08-30 16:06:28 -07001984ATSParser::ATSParser(uint32_t flags)
Andreas Huber87f2a552012-08-31 13:55:24 -07001985 : mFlags(flags),
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001986 mAbsoluteTimeAnchorUs(-1LL),
Andreas Huberd5e56232013-03-12 11:01:43 -07001987 mTimeOffsetValid(false),
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08001988 mTimeOffsetUs(0LL),
1989 mLastRecoveredPTS(-1LL),
Andreas Huber87f2a552012-08-31 13:55:24 -07001990 mNumTSPacketsParsed(0),
1991 mNumPCRs(0) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07001992 mPSISections.add(0 /* PID */, new PSISection);
Chong Zhang3b2847f2017-01-18 17:43:03 -08001993 mCasManager = new CasManager();
Andreas Hubercda17c62010-06-07 13:05:37 -07001994}
1995
1996ATSParser::~ATSParser() {
1997}
1998
Wonsik Kim54000662015-04-13 10:59:06 +09001999status_t ATSParser::feedTSPacket(const void *data, size_t size,
2000 SyncEvent *event) {
Jinsuk Kime314c672015-04-22 11:08:28 +09002001 if (size != kTSPacketSize) {
2002 ALOGE("Wrong TS packet size");
2003 return BAD_VALUE;
2004 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002005
2006 ABitReader br((const uint8_t *)data, kTSPacketSize);
Wonsik Kim54000662015-04-13 10:59:06 +09002007 return parseTS(&br, event);
Andreas Hubercda17c62010-06-07 13:05:37 -07002008}
2009
Chong Zhang3b2847f2017-01-18 17:43:03 -08002010status_t ATSParser::setMediaCas(const sp<ICas> &cas) {
2011 status_t err = mCasManager->setMediaCas(cas);
2012 if (err != OK) {
2013 return err;
2014 }
2015 for (size_t i = 0; i < mPrograms.size(); ++i) {
2016 mPrograms.editItemAt(i)->updateCasSessions();
2017 }
2018 return OK;
2019}
2020
Andreas Huber32f3cef2011-03-02 15:34:46 -08002021void ATSParser::signalDiscontinuity(
2022 DiscontinuityType type, const sp<AMessage> &extra) {
Andreas Huberb7c8e912012-11-27 15:02:53 -08002023 int64_t mediaTimeUs;
Chong Zhangd47dfcb2015-03-27 15:53:45 -07002024 if ((type & DISCONTINUITY_TIME) && extra != NULL) {
Dongwon Kang15d02f82017-12-14 16:32:18 -08002025 if (extra->findInt64(kATSParserKeyMediaTimeUs, &mediaTimeUs)) {
Chong Zhangd47dfcb2015-03-27 15:53:45 -07002026 mAbsoluteTimeAnchorUs = mediaTimeUs;
2027 }
2028 if ((mFlags & TS_TIMESTAMPS_ARE_ABSOLUTE)
2029 && extra->findInt64(
Dongwon Kang15d02f82017-12-14 16:32:18 -08002030 kATSParserKeyRecentMediaTimeUs, &mediaTimeUs)) {
Chih-Hung Hsieh3794b242018-12-11 13:55:06 -08002031 if (mAbsoluteTimeAnchorUs >= 0LL) {
Chong Zhangd47dfcb2015-03-27 15:53:45 -07002032 mediaTimeUs -= mAbsoluteTimeAnchorUs;
2033 }
2034 if (mTimeOffsetValid) {
2035 mediaTimeUs -= mTimeOffsetUs;
2036 }
2037 mLastRecoveredPTS = (mediaTimeUs * 9) / 100;
2038 }
Andreas Huberb7c8e912012-11-27 15:02:53 -08002039 } else if (type == DISCONTINUITY_ABSOLUTE_TIME) {
Andreas Huber87f2a552012-08-31 13:55:24 -07002040 int64_t timeUs;
Jinsuk Kime314c672015-04-22 11:08:28 +09002041 if (!extra->findInt64("timeUs", &timeUs)) {
2042 ALOGE("timeUs not found");
2043 return;
2044 }
Andreas Huber87f2a552012-08-31 13:55:24 -07002045
Jinsuk Kime314c672015-04-22 11:08:28 +09002046 if (!mPrograms.empty()) {
2047 ALOGE("mPrograms is not empty");
2048 return;
2049 }
Andreas Huber87f2a552012-08-31 13:55:24 -07002050 mAbsoluteTimeAnchorUs = timeUs;
2051 return;
Andreas Huberd5e56232013-03-12 11:01:43 -07002052 } else if (type == DISCONTINUITY_TIME_OFFSET) {
2053 int64_t offset;
Jinsuk Kime314c672015-04-22 11:08:28 +09002054 if (!extra->findInt64("offset", &offset)) {
2055 ALOGE("offset not found");
2056 return;
2057 }
Andreas Huberd5e56232013-03-12 11:01:43 -07002058
2059 mTimeOffsetValid = true;
2060 mTimeOffsetUs = offset;
2061 return;
Andreas Huber87f2a552012-08-31 13:55:24 -07002062 }
2063
Andreas Huber2a4d22d2010-09-08 14:32:20 -07002064 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber32f3cef2011-03-02 15:34:46 -08002065 mPrograms.editItemAt(i)->signalDiscontinuity(type, extra);
Andreas Huberf9334412010-12-15 15:17:42 -08002066 }
2067}
2068
2069void ATSParser::signalEOS(status_t finalResult) {
Jinsuk Kime314c672015-04-22 11:08:28 +09002070 if (finalResult == (status_t) OK) {
2071 ALOGE("finalResult not OK");
2072 return;
2073 }
Andreas Huberf9334412010-12-15 15:17:42 -08002074
2075 for (size_t i = 0; i < mPrograms.size(); ++i) {
2076 mPrograms.editItemAt(i)->signalEOS(finalResult);
Andreas Huber2a4d22d2010-09-08 14:32:20 -07002077 }
2078}
2079
Andreas Hubercda17c62010-06-07 13:05:37 -07002080void ATSParser::parseProgramAssociationTable(ABitReader *br) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002081 if (br->numBitsLeft() < 8) {
2082 ALOGE("Not enough data left in bitreader!");
2083 return;
2084 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002085 unsigned table_id = br->getBits(8);
Steve Block3856b092011-10-20 11:56:00 +01002086 ALOGV(" table_id = %u", table_id);
David Yeh6456ae72014-09-03 11:14:48 +08002087 if (table_id != 0x00u) {
2088 ALOGE("PAT data error!");
2089 return ;
2090 }
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002091 if (br->numBitsLeft() < 56) {
2092 ALOGE("Not enough data left in bitreader!");
2093 return;
2094 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002095 unsigned section_syntax_indictor = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01002096 ALOGV(" section_syntax_indictor = %u", section_syntax_indictor);
Andreas Hubercda17c62010-06-07 13:05:37 -07002097
Jinsuk Kime314c672015-04-22 11:08:28 +09002098 br->skipBits(1); // '0'
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002099 MY_LOGV(" reserved = %u", br->getBits(2));
Andreas Hubercda17c62010-06-07 13:05:37 -07002100
2101 unsigned section_length = br->getBits(12);
Steve Block3856b092011-10-20 11:56:00 +01002102 ALOGV(" section_length = %u", section_length);
Andreas Hubercda17c62010-06-07 13:05:37 -07002103
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002104 MY_LOGV(" transport_stream_id = %u", br->getBits(16));
2105 MY_LOGV(" reserved = %u", br->getBits(2));
2106 MY_LOGV(" version_number = %u", br->getBits(5));
2107 MY_LOGV(" current_next_indicator = %u", br->getBits(1));
2108 MY_LOGV(" section_number = %u", br->getBits(8));
2109 MY_LOGV(" last_section_number = %u", br->getBits(8));
Andreas Hubercda17c62010-06-07 13:05:37 -07002110
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002111 // check for unsigned integer overflow before assigning it to numProgramBytes
2112 if (section_length < 9) {
2113 return;
2114 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002115 size_t numProgramBytes = (section_length - 5 /* header */ - 4 /* crc */);
Andreas Hubercda17c62010-06-07 13:05:37 -07002116
2117 for (size_t i = 0; i < numProgramBytes / 4; ++i) {
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002118 if (br->numBitsLeft() < 32) {
2119 ALOGE("Not enough data left in bitreader!");
2120 return;
2121 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002122 unsigned program_number = br->getBits(16);
Steve Block3856b092011-10-20 11:56:00 +01002123 ALOGV(" program_number = %u", program_number);
Andreas Hubercda17c62010-06-07 13:05:37 -07002124
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002125 MY_LOGV(" reserved = %u", br->getBits(3));
Andreas Hubercda17c62010-06-07 13:05:37 -07002126
2127 if (program_number == 0) {
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002128 MY_LOGV(" network_PID = 0x%04x", br->getBits(13));
Andreas Hubercda17c62010-06-07 13:05:37 -07002129 } else {
2130 unsigned programMapPID = br->getBits(13);
2131
Steve Block3856b092011-10-20 11:56:00 +01002132 ALOGV(" program_map_PID = 0x%04x", programMapPID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002133
Andreas Huber386d6092011-05-19 08:37:39 -07002134 bool found = false;
2135 for (size_t index = 0; index < mPrograms.size(); ++index) {
2136 const sp<Program> &program = mPrograms.itemAt(index);
2137
2138 if (program->number() == program_number) {
2139 program->updateProgramMapPID(programMapPID);
2140 found = true;
2141 break;
2142 }
2143 }
2144
2145 if (!found) {
2146 mPrograms.push(
Chong Zhangd47dfcb2015-03-27 15:53:45 -07002147 new Program(this, program_number, programMapPID, mLastRecoveredPTS));
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07002148 if (mSampleAesKeyItem != NULL) {
2149 mPrograms.top()->signalNewSampleAesKey(mSampleAesKeyItem);
2150 }
Andreas Huber386d6092011-05-19 08:37:39 -07002151 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002152
2153 if (mPSISections.indexOfKey(programMapPID) < 0) {
2154 mPSISections.add(programMapPID, new PSISection);
2155 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002156 }
2157 }
2158
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002159 if (br->numBitsLeft() < 32) {
2160 ALOGE("Not enough data left in bitreader!");
2161 return;
2162 }
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002163 MY_LOGV(" CRC = 0x%08x", br->getBits(32));
Andreas Hubercda17c62010-06-07 13:05:37 -07002164}
2165
Andreas Huber06528d72011-08-31 16:29:05 -07002166status_t ATSParser::parsePID(
Andreas Hubercda17c62010-06-07 13:05:37 -07002167 ABitReader *br, unsigned PID,
Andreas Huber87f2a552012-08-31 13:55:24 -07002168 unsigned continuity_counter,
Wonsik Kim54000662015-04-13 10:59:06 +09002169 unsigned payload_unit_start_indicator,
Chong Zhang3b2847f2017-01-18 17:43:03 -08002170 unsigned transport_scrambling_control,
2171 unsigned random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +09002172 SyncEvent *event) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07002173 ssize_t sectionIndex = mPSISections.indexOfKey(PID);
2174
2175 if (sectionIndex >= 0) {
Andreas Huber4b4bb112013-04-29 13:17:50 -07002176 sp<PSISection> section = mPSISections.valueAt(sectionIndex);
Andreas Huber8dfa2282012-05-15 12:37:29 -07002177
Andreas Hubercda17c62010-06-07 13:05:37 -07002178 if (payload_unit_start_indicator) {
David Yeh6456ae72014-09-03 11:14:48 +08002179 if (!section->isEmpty()) {
Chong Zhang9bcf3ae2015-03-08 15:59:01 -07002180 ALOGW("parsePID encounters payload_unit_start_indicator when section is not empty");
2181 section->clear();
David Yeh6456ae72014-09-03 11:14:48 +08002182 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002183
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002184 if (br->numBitsLeft() < 8) {
2185 ALOGE("Not enough data left in bitreader!");
2186 return ERROR_MALFORMED;
2187 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002188 unsigned skip = br->getBits(8);
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002189 section->setSkipBytes(skip + 1); // skip filler bytes + pointer field itself
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002190 if (!br->skipBits(skip * 8)) {
2191 ALOGE("Not enough data left in bitreader!");
2192 return ERROR_MALFORMED;
2193 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002194 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002195
Jinsuk Kime314c672015-04-22 11:08:28 +09002196 if (br->numBitsLeft() % 8 != 0) {
2197 return ERROR_MALFORMED;
2198 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002199 status_t err = section->append(br->data(), br->numBitsLeft() / 8);
2200
2201 if (err != OK) {
2202 return err;
2203 }
2204
2205 if (!section->isComplete()) {
2206 return OK;
2207 }
2208
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002209 if (!section->isCRCOkay()) {
2210 return BAD_VALUE;
2211 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002212 ABitReader sectionBits(section->data(), section->size());
2213
2214 if (PID == 0) {
2215 parseProgramAssociationTable(&sectionBits);
2216 } else {
2217 bool handled = false;
2218 for (size_t i = 0; i < mPrograms.size(); ++i) {
2219 status_t err;
2220 if (!mPrograms.editItemAt(i)->parsePSISection(
2221 PID, &sectionBits, &err)) {
2222 continue;
2223 }
2224
2225 if (err != OK) {
2226 return err;
2227 }
2228
2229 handled = true;
2230 break;
2231 }
2232
2233 if (!handled) {
2234 mPSISections.removeItem(PID);
Andreas Huber4b4bb112013-04-29 13:17:50 -07002235 section.clear();
Andreas Huber8dfa2282012-05-15 12:37:29 -07002236 }
2237 }
2238
Andreas Huber4b4bb112013-04-29 13:17:50 -07002239 if (section != NULL) {
2240 section->clear();
2241 }
Andreas Huber8dfa2282012-05-15 12:37:29 -07002242
Andreas Huber06528d72011-08-31 16:29:05 -07002243 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002244 }
2245
2246 bool handled = false;
2247 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber06528d72011-08-31 16:29:05 -07002248 status_t err;
Andreas Hubercda17c62010-06-07 13:05:37 -07002249 if (mPrograms.editItemAt(i)->parsePID(
Chong Zhang3b2847f2017-01-18 17:43:03 -08002250 PID, continuity_counter,
2251 payload_unit_start_indicator,
2252 transport_scrambling_control,
2253 random_access_indicator,
Wonsik Kim54000662015-04-13 10:59:06 +09002254 br, &err, event)) {
Andreas Huber06528d72011-08-31 16:29:05 -07002255 if (err != OK) {
2256 return err;
2257 }
2258
Andreas Hubercda17c62010-06-07 13:05:37 -07002259 handled = true;
2260 break;
2261 }
2262 }
2263
2264 if (!handled) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08002265 handled = mCasManager->parsePID(br, PID);
2266 }
2267
2268 if (!handled) {
Steve Block3856b092011-10-20 11:56:00 +01002269 ALOGV("PID 0x%04x not handled.", PID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002270 }
Andreas Huber06528d72011-08-31 16:29:05 -07002271
2272 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002273}
2274
Chong Zhang3b2847f2017-01-18 17:43:03 -08002275status_t ATSParser::parseAdaptationField(
2276 ABitReader *br, unsigned PID, unsigned *random_access_indicator) {
2277 *random_access_indicator = 0;
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002278 if (br->numBitsLeft() < 8) {
2279 ALOGE("Not enough data left in bitreader!");
2280 return ERROR_MALFORMED;
2281 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002282 unsigned adaptation_field_length = br->getBits(8);
Andreas Huber87f2a552012-08-31 13:55:24 -07002283
Andreas Hubercda17c62010-06-07 13:05:37 -07002284 if (adaptation_field_length > 0) {
Jaesung Chung8a1fa1e2015-05-15 14:19:14 +09002285 if (adaptation_field_length * 8 > br->numBitsLeft()) {
2286 ALOGV("Adaptation field should be included in a single TS packet.");
2287 return ERROR_MALFORMED;
2288 }
2289
Andreas Huber87f2a552012-08-31 13:55:24 -07002290 unsigned discontinuity_indicator = br->getBits(1);
2291
2292 if (discontinuity_indicator) {
2293 ALOGV("PID 0x%04x: discontinuity_indicator = 1 (!!!)", PID);
2294 }
2295
Chong Zhang3b2847f2017-01-18 17:43:03 -08002296 *random_access_indicator = br->getBits(1);
2297 if (*random_access_indicator) {
2298 ALOGV("PID 0x%04x: random_access_indicator = 1", PID);
2299 }
2300
2301 unsigned elementary_stream_priority_indicator = br->getBits(1);
2302 if (elementary_stream_priority_indicator) {
2303 ALOGV("PID 0x%04x: elementary_stream_priority_indicator = 1", PID);
2304 }
2305
Andreas Huber87f2a552012-08-31 13:55:24 -07002306 unsigned PCR_flag = br->getBits(1);
2307
2308 size_t numBitsRead = 4;
2309
2310 if (PCR_flag) {
Jinsuk Kime314c672015-04-22 11:08:28 +09002311 if (adaptation_field_length * 8 < 52) {
2312 return ERROR_MALFORMED;
2313 }
Andreas Huber87f2a552012-08-31 13:55:24 -07002314 br->skipBits(4);
2315 uint64_t PCR_base = br->getBits(32);
2316 PCR_base = (PCR_base << 1) | br->getBits(1);
2317
2318 br->skipBits(6);
2319 unsigned PCR_ext = br->getBits(9);
2320
2321 // The number of bytes from the start of the current
2322 // MPEG2 transport stream packet up and including
2323 // the final byte of this PCR_ext field.
2324 size_t byteOffsetFromStartOfTSPacket =
2325 (188 - br->numBitsLeft() / 8);
2326
2327 uint64_t PCR = PCR_base * 300 + PCR_ext;
2328
Colin Crossb4a7a2d2014-03-19 16:59:00 -07002329 ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)",
Andreas Huber87f2a552012-08-31 13:55:24 -07002330 PID, PCR, PCR / 27E6);
2331
2332 // The number of bytes received by this parser up to and
2333 // including the final byte of this PCR_ext field.
Marco Nelissen19cec892016-04-20 15:56:53 -07002334 uint64_t byteOffsetFromStart =
2335 uint64_t(mNumTSPacketsParsed) * 188 + byteOffsetFromStartOfTSPacket;
Andreas Huber87f2a552012-08-31 13:55:24 -07002336
2337 for (size_t i = 0; i < mPrograms.size(); ++i) {
2338 updatePCR(PID, PCR, byteOffsetFromStart);
2339 }
2340
2341 numBitsRead += 52;
2342 }
2343
Andreas Huber87f2a552012-08-31 13:55:24 -07002344 br->skipBits(adaptation_field_length * 8 - numBitsRead);
Andreas Hubercda17c62010-06-07 13:05:37 -07002345 }
Jinsuk Kime314c672015-04-22 11:08:28 +09002346 return OK;
Andreas Hubercda17c62010-06-07 13:05:37 -07002347}
2348
Wonsik Kim54000662015-04-13 10:59:06 +09002349status_t ATSParser::parseTS(ABitReader *br, SyncEvent *event) {
Steve Block3856b092011-10-20 11:56:00 +01002350 ALOGV("---");
Andreas Hubercda17c62010-06-07 13:05:37 -07002351
Sohail Nagarajcfe4e5a2024-01-18 11:44:07 +00002352 if (br->numBitsLeft() < 32) {
2353 ALOGE("Not enough data left in bitreader!");
2354 return ERROR_MALFORMED;
2355 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002356 unsigned sync_byte = br->getBits(8);
David Yeh6456ae72014-09-03 11:14:48 +08002357 if (sync_byte != 0x47u) {
2358 ALOGE("[error] parseTS: return error as sync_byte=0x%x", sync_byte);
2359 return BAD_VALUE;
2360 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002361
Andreas Huber52668ca2013-11-11 13:35:39 -08002362 if (br->getBits(1)) { // transport_error_indicator
2363 // silently ignore.
2364 return OK;
2365 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002366
2367 unsigned payload_unit_start_indicator = br->getBits(1);
Steve Block3856b092011-10-20 11:56:00 +01002368 ALOGV("payload_unit_start_indicator = %u", payload_unit_start_indicator);
Andreas Hubercda17c62010-06-07 13:05:37 -07002369
Andreas Huber6e4c5c42010-09-21 13:13:15 -07002370 MY_LOGV("transport_priority = %u", br->getBits(1));
Andreas Hubercda17c62010-06-07 13:05:37 -07002371
2372 unsigned PID = br->getBits(13);
Steve Block3856b092011-10-20 11:56:00 +01002373 ALOGV("PID = 0x%04x", PID);
Andreas Hubercda17c62010-06-07 13:05:37 -07002374
Chong Zhang3b2847f2017-01-18 17:43:03 -08002375 unsigned transport_scrambling_control = br->getBits(2);
2376 ALOGV("transport_scrambling_control = %u", transport_scrambling_control);
Andreas Hubercda17c62010-06-07 13:05:37 -07002377
2378 unsigned adaptation_field_control = br->getBits(2);
Steve Block3856b092011-10-20 11:56:00 +01002379 ALOGV("adaptation_field_control = %u", adaptation_field_control);
Andreas Hubercda17c62010-06-07 13:05:37 -07002380
Andreas Huber0da4dab2010-09-27 12:04:43 -07002381 unsigned continuity_counter = br->getBits(4);
Andreas Huber87f2a552012-08-31 13:55:24 -07002382 ALOGV("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
Andreas Huber0da4dab2010-09-27 12:04:43 -07002383
Steve Blockdf64d152012-01-04 20:05:49 +00002384 // ALOGI("PID = 0x%04x, continuity_counter = %u", PID, continuity_counter);
Andreas Hubercda17c62010-06-07 13:05:37 -07002385
Andreas Huber87f2a552012-08-31 13:55:24 -07002386 status_t err = OK;
2387
Chong Zhang3b2847f2017-01-18 17:43:03 -08002388 unsigned random_access_indicator = 0;
Jinsuk Kime314c672015-04-22 11:08:28 +09002389 if (adaptation_field_control == 2 || adaptation_field_control == 3) {
Chong Zhang3b2847f2017-01-18 17:43:03 -08002390 err = parseAdaptationField(br, PID, &random_access_indicator);
Jinsuk Kime314c672015-04-22 11:08:28 +09002391 }
2392 if (err == OK) {
2393 if (adaptation_field_control == 1 || adaptation_field_control == 3) {
Wonsik Kim54000662015-04-13 10:59:06 +09002394 err = parsePID(br, PID, continuity_counter,
Chong Zhang3b2847f2017-01-18 17:43:03 -08002395 payload_unit_start_indicator,
2396 transport_scrambling_control,
2397 random_access_indicator,
2398 event);
Jinsuk Kime314c672015-04-22 11:08:28 +09002399 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002400 }
Andreas Huber06528d72011-08-31 16:29:05 -07002401
Andreas Huber87f2a552012-08-31 13:55:24 -07002402 ++mNumTSPacketsParsed;
2403
2404 return err;
Andreas Hubercda17c62010-06-07 13:05:37 -07002405}
2406
Marco Nelissen45d54c62018-01-26 10:04:22 -08002407sp<AnotherPacketSource> ATSParser::getSource(SourceType type) {
2408 sp<AnotherPacketSource> firstSourceFound;
Andreas Hubercda17c62010-06-07 13:05:37 -07002409 for (size_t i = 0; i < mPrograms.size(); ++i) {
Andreas Huber386d6092011-05-19 08:37:39 -07002410 const sp<Program> &program = mPrograms.editItemAt(i);
Marco Nelissen45d54c62018-01-26 10:04:22 -08002411 sp<AnotherPacketSource> source = program->getSource(type);
Robert Shih9ff1e722015-10-20 16:29:58 -07002412 if (source == NULL) {
Andreas Huber386d6092011-05-19 08:37:39 -07002413 continue;
2414 }
Robert Shih9ff1e722015-10-20 16:29:58 -07002415 if (firstSourceFound == NULL) {
2416 firstSourceFound = source;
2417 }
2418 // Prefer programs with both audio/video
2419 switch (type) {
2420 case VIDEO: {
2421 if (program->hasSource(AUDIO)) {
2422 return source;
2423 }
2424 break;
2425 }
Andreas Huber386d6092011-05-19 08:37:39 -07002426
Robert Shih9ff1e722015-10-20 16:29:58 -07002427 case AUDIO: {
2428 if (program->hasSource(VIDEO)) {
2429 return source;
2430 }
2431 break;
2432 }
Andreas Hubercda17c62010-06-07 13:05:37 -07002433
Robert Shih9ff1e722015-10-20 16:29:58 -07002434 default:
2435 return source;
Andreas Hubercda17c62010-06-07 13:05:37 -07002436 }
2437 }
2438
Robert Shih9ff1e722015-10-20 16:29:58 -07002439 return firstSourceFound;
Andreas Hubercda17c62010-06-07 13:05:37 -07002440}
2441
Robert Shihbf207272014-10-30 17:22:11 -07002442bool ATSParser::hasSource(SourceType type) const {
2443 for (size_t i = 0; i < mPrograms.size(); ++i) {
2444 const sp<Program> &program = mPrograms.itemAt(i);
2445 if (program->hasSource(type)) {
2446 return true;
2447 }
2448 }
2449
2450 return false;
2451}
2452
Andreas Huber43c3e6c2011-01-05 12:17:08 -08002453bool ATSParser::PTSTimeDeltaEstablished() {
2454 if (mPrograms.isEmpty()) {
2455 return false;
2456 }
2457
2458 return mPrograms.editItemAt(0)->PTSTimeDeltaEstablished();
2459}
2460
Robert Shih82e14702016-11-17 11:24:29 -08002461int64_t ATSParser::getFirstPTSTimeUs() {
2462 for (size_t i = 0; i < mPrograms.size(); ++i) {
2463 sp<ATSParser::Program> program = mPrograms.itemAt(i);
2464 if (program->PTSTimeDeltaEstablished()) {
2465 return (program->firstPTS() * 100) / 9;
2466 }
2467 }
2468 return -1;
2469}
2470
Chad Brubakerc9fa35c2015-08-18 16:52:40 -07002471__attribute__((no_sanitize("integer")))
Andreas Huber87f2a552012-08-31 13:55:24 -07002472void ATSParser::updatePCR(
Marco Nelissen19cec892016-04-20 15:56:53 -07002473 unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
2474 ALOGV("PCR 0x%016" PRIx64 " @ %" PRIx64, PCR, byteOffsetFromStart);
Andreas Huber87f2a552012-08-31 13:55:24 -07002475
2476 if (mNumPCRs == 2) {
2477 mPCR[0] = mPCR[1];
2478 mPCRBytes[0] = mPCRBytes[1];
2479 mSystemTimeUs[0] = mSystemTimeUs[1];
2480 mNumPCRs = 1;
2481 }
2482
2483 mPCR[mNumPCRs] = PCR;
2484 mPCRBytes[mNumPCRs] = byteOffsetFromStart;
2485 mSystemTimeUs[mNumPCRs] = ALooper::GetNowUs();
2486
2487 ++mNumPCRs;
2488
2489 if (mNumPCRs == 2) {
Chad Brubakerc9fa35c2015-08-18 16:52:40 -07002490 /* Unsigned overflow here */
Andreas Huber87f2a552012-08-31 13:55:24 -07002491 double transportRate =
2492 (mPCRBytes[1] - mPCRBytes[0]) * 27E6 / (mPCR[1] - mPCR[0]);
2493
2494 ALOGV("transportRate = %.2f bytes/sec", transportRate);
2495 }
2496}
2497
Andreas Huber8dfa2282012-05-15 12:37:29 -07002498////////////////////////////////////////////////////////////////////////////////
2499
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002500
2501// CRC32 used for PSI section. The table was generated by following command:
2502// $ python pycrc.py --model crc-32-mpeg --algorithm table-driven --generate c
2503// Visit http://www.tty1.net/pycrc/index_en.html for more details.
2504uint32_t ATSParser::PSISection::CRC_TABLE[] = {
2505 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
2506 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
2507 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
2508 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
2509 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
2510 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
2511 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
2512 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
2513 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
2514 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
2515 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
2516 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
2517 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
2518 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
2519 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
2520 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
2521 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
2522 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
2523 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
2524 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
2525 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
2526 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
2527 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
2528 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
2529 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
2530 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
2531 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
2532 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
2533 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
2534 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
2535 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
2536 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
2537 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
2538 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
2539 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
2540 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
2541 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
2542 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
2543 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
2544 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
2545 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
2546 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
2547 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
2548 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
2549 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
2550 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
2551 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
2552 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
2553 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
2554 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
2555 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
2556 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
2557 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
2558 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
2559 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
2560 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
2561 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
2562 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
2563 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
2564 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
2565 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
2566 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
2567 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
2568 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
2569 };
2570
2571ATSParser::PSISection::PSISection() :
2572 mSkipBytes(0) {
Andreas Huber8dfa2282012-05-15 12:37:29 -07002573}
2574
2575ATSParser::PSISection::~PSISection() {
2576}
2577
2578status_t ATSParser::PSISection::append(const void *data, size_t size) {
2579 if (mBuffer == NULL || mBuffer->size() + size > mBuffer->capacity()) {
2580 size_t newCapacity =
2581 (mBuffer == NULL) ? size : mBuffer->capacity() + size;
2582
2583 newCapacity = (newCapacity + 1023) & ~1023;
2584
2585 sp<ABuffer> newBuffer = new ABuffer(newCapacity);
2586
2587 if (mBuffer != NULL) {
2588 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
2589 newBuffer->setRange(0, mBuffer->size());
2590 } else {
2591 newBuffer->setRange(0, 0);
2592 }
2593
2594 mBuffer = newBuffer;
2595 }
2596
2597 memcpy(mBuffer->data() + mBuffer->size(), data, size);
2598 mBuffer->setRange(0, mBuffer->size() + size);
2599
2600 return OK;
2601}
2602
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002603void ATSParser::PSISection::setSkipBytes(uint8_t skip) {
2604 mSkipBytes = skip;
2605}
2606
Andreas Huber8dfa2282012-05-15 12:37:29 -07002607void ATSParser::PSISection::clear() {
2608 if (mBuffer != NULL) {
2609 mBuffer->setRange(0, 0);
2610 }
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002611 mSkipBytes = 0;
Andreas Huber8dfa2282012-05-15 12:37:29 -07002612}
2613
2614bool ATSParser::PSISection::isComplete() const {
2615 if (mBuffer == NULL || mBuffer->size() < 3) {
2616 return false;
2617 }
2618
2619 unsigned sectionLength = U16_AT(mBuffer->data() + 1) & 0xfff;
2620 return mBuffer->size() >= sectionLength + 3;
2621}
2622
2623bool ATSParser::PSISection::isEmpty() const {
2624 return mBuffer == NULL || mBuffer->size() == 0;
2625}
2626
2627const uint8_t *ATSParser::PSISection::data() const {
2628 return mBuffer == NULL ? NULL : mBuffer->data();
2629}
2630
2631size_t ATSParser::PSISection::size() const {
2632 return mBuffer == NULL ? 0 : mBuffer->size();
2633}
2634
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002635bool ATSParser::PSISection::isCRCOkay() const {
2636 if (!isComplete()) {
2637 return false;
2638 }
2639 uint8_t* data = mBuffer->data();
2640
2641 // Return true if section_syntax_indicator says no section follows the field section_length.
2642 if ((data[1] & 0x80) == 0) {
2643 return true;
2644 }
2645
2646 unsigned sectionLength = U16_AT(data + 1) & 0xfff;
2647 ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes);
2648
Marco Nelissenc0c9f502016-04-28 13:32:41 -07002649
2650 if(sectionLength < mSkipBytes) {
2651 ALOGE("b/28333006");
2652 android_errorWriteLog(0x534e4554, "28333006");
2653 return false;
2654 }
2655
Jinsuk Kim9ca7b9c2015-03-20 09:23:18 +09002656 // Skip the preceding field present when payload start indicator is on.
2657 sectionLength -= mSkipBytes;
2658
2659 uint32_t crc = 0xffffffff;
2660 for(unsigned i = 0; i < sectionLength + 4 /* crc */; i++) {
2661 uint8_t b = data[i];
2662 int index = ((crc >> 24) ^ (b & 0xff)) & 0xff;
2663 crc = CRC_TABLE[index] ^ (crc << 8);
2664 }
2665 ALOGV("crc: %08x\n", crc);
2666 return (crc == 0);
2667}
Hassan Shojania3a37f3e2017-04-19 14:29:42 -07002668
2669// SAMPLE_AES key handling
2670// TODO: Merge these to their respective class after Widevine-HLS
2671void ATSParser::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2672 ALOGD("signalNewSampleAesKey: %p", keyItem.get());
2673
2674 mSampleAesKeyItem = keyItem;
2675
2676 // a NULL key item will propagate to existing ElementaryStreamQueues
2677 for (size_t i = 0; i < mPrograms.size(); ++i) {
2678 mPrograms[i]->signalNewSampleAesKey(keyItem);
2679 }
2680}
2681
2682void ATSParser::Program::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2683 ALOGD("Program::signalNewSampleAesKey: %p", keyItem.get());
2684
2685 mSampleAesKeyItem = keyItem;
2686
2687 // a NULL key item will propagate to existing ElementaryStreamQueues
2688 for (size_t i = 0; i < mStreams.size(); ++i) {
2689 mStreams[i]->signalNewSampleAesKey(keyItem);
2690 }
2691}
2692
2693void ATSParser::Stream::signalNewSampleAesKey(const sp<AMessage> &keyItem) {
2694 ALOGD("Stream::signalNewSampleAesKey: 0x%04x size = %zu keyItem: %p",
2695 mElementaryPID, mBuffer->size(), keyItem.get());
2696
2697 // a NULL key item will propagate to existing ElementaryStreamQueues
2698 mSampleAesKeyItem = keyItem;
2699
2700 flush(NULL);
2701 mQueue->signalNewSampleAesKey(keyItem);
2702}
2703
Andreas Hubercda17c62010-06-07 13:05:37 -07002704} // namespace android