Skip to content

Commit

Permalink
perf: ts parser O(n^2) performance bug. (#6035)
Browse files Browse the repository at this point in the history
This caused high cpu usage when the ts file segments are large.
  • Loading branch information
wjywbs authored Jan 8, 2024
1 parent a70136d commit dd50028
Showing 1 changed file with 15 additions and 16 deletions.
31 changes: 15 additions & 16 deletions lib/util/ts_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ shaka.util.TsParser = class {
/** @private {?string} */
this.videoCodec_ = null;

/** @private {!Array.<Uint8Array>} */
/** @private {!Array.<!Array.<Uint8Array>>} */
this.videoData_ = [];

/** @private {!Array.<shaka.extern.MPEG_PES>} */
Expand All @@ -44,7 +44,7 @@ shaka.util.TsParser = class {
/** @private {?string} */
this.audioCodec_ = null;

/** @private {!Array.<Uint8Array>} */
/** @private {!Array.<!Array.<Uint8Array>>} */
this.audioData_ = [];

/** @private {!Array.<shaka.extern.MPEG_PES>} */
Expand All @@ -53,7 +53,7 @@ shaka.util.TsParser = class {
/** @private {?number} */
this.id3Pid_ = null;

/** @private {!Array.<Uint8Array>} */
/** @private {!Array.<!Array.<Uint8Array>>} */
this.id3Data_ = [];
}

Expand All @@ -79,7 +79,6 @@ shaka.util.TsParser = class {
*/
parse(data) {
const packetLength = shaka.util.TsParser.PacketLength_;
const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;

// A TS fragment should contain at least 3 TS packets, a PAT, a PMT, and
// one PID.
Expand Down Expand Up @@ -162,38 +161,35 @@ shaka.util.TsParser = class {
case this.videoPid_: {
const videoData = data.subarray(offset, start + packetLength);
if (payloadUnitStartIndicator) {
this.videoData_.push(videoData);
this.videoData_.push([videoData]);
} else if (this.videoData_.length) {
const prevVideoData = this.videoData_[this.videoData_.length - 1];
if (prevVideoData) {
this.videoData_[this.videoData_.length - 1] =
Uint8ArrayUtils.concat(prevVideoData, videoData);
this.videoData_[this.videoData_.length - 1].push(videoData);
}
}
break;
}
case this.audioPid_: {
const audioData = data.subarray(offset, start + packetLength);
if (payloadUnitStartIndicator) {
this.audioData_.push(audioData);
this.audioData_.push([audioData]);
} else if (this.audioData_.length) {
const prevAudioData = this.audioData_[this.audioData_.length - 1];
if (prevAudioData) {
this.audioData_[this.audioData_.length - 1] =
Uint8ArrayUtils.concat(prevAudioData, audioData);
this.audioData_[this.audioData_.length - 1].push(audioData);
}
}
break;
}
case this.id3Pid_: {
const id3Data = data.subarray(offset, start + packetLength);
if (payloadUnitStartIndicator) {
this.id3Data_.push(id3Data);
this.id3Data_.push([id3Data]);
} else if (this.id3Data_.length) {
const prevId3Data = this.id3Data_[this.id3Data_.length - 1];
if (prevId3Data) {
this.id3Data_[this.id3Data_.length - 1] =
Uint8ArrayUtils.concat(prevId3Data, id3Data);
this.id3Data_[this.id3Data_.length - 1].push(id3Data);
}
}
break;
Expand Down Expand Up @@ -588,7 +584,8 @@ shaka.util.TsParser = class {
getMetadata() {
const timescale = shaka.util.TsParser.Timescale;
const metadata = [];
for (const id3Data of this.id3Data_) {
for (const id3DataArray of this.id3Data_) {
const id3Data = shaka.util.Uint8ArrayUtils.concat(...id3DataArray);
const pes = this.parsePES_(id3Data);
if (pes) {
metadata.push({
Expand All @@ -612,7 +609,8 @@ shaka.util.TsParser = class {
getAudioData() {
if (this.audioData_.length && !this.audioPes_.length) {
let sort = false;
for (const audioData of this.audioData_) {
for (const audioDataArray of this.audioData_) {
const audioData = shaka.util.Uint8ArrayUtils.concat(...audioDataArray);
const pes = this.parsePES_(audioData);
let previousPes = this.audioPes_.length ?
this.audioPes_[this.audioPes_.length - 1] : null;
Expand Down Expand Up @@ -654,7 +652,8 @@ shaka.util.TsParser = class {
getVideoData(naluProcessing = true) {
if (this.videoData_.length && !this.videoPes_.length) {
let sort = false;
for (const videoData of this.videoData_) {
for (const videoDataArray of this.videoData_) {
const videoData = shaka.util.Uint8ArrayUtils.concat(...videoDataArray);
const pes = this.parsePES_(videoData);
let previousPes = this.videoPes_.length ?
this.videoPes_[this.videoPes_.length - 1] : null;
Expand Down

0 comments on commit dd50028

Please sign in to comment.