hls.js 1.5.2-0.canary.9969 → 1.5.2-0.canary.9971

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/hls.js CHANGED
@@ -556,7 +556,7 @@
556
556
  // Some browsers don't allow to use bind on console object anyway
557
557
  // fallback to default if needed
558
558
  try {
559
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.2-0.canary.9969");
559
+ newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.2-0.canary.9971");
560
560
  } catch (e) {
561
561
  /* log fn threw an exception. All logger methods are no-ops. */
562
562
  return createLogger();
@@ -9547,6 +9547,7 @@
9547
9547
  _this.startFragRequested = false;
9548
9548
  _this.decrypter = void 0;
9549
9549
  _this.initPTS = [];
9550
+ _this.buffering = true;
9550
9551
  _this.onMediaSeeking = function () {
9551
9552
  var _assertThisInitialize = _assertThisInitialized(_this),
9552
9553
  config = _assertThisInitialize.config,
@@ -9650,6 +9651,12 @@
9650
9651
  this.clearNextTick();
9651
9652
  this.state = State.STOPPED;
9652
9653
  };
9654
+ _proto.pauseBuffering = function pauseBuffering() {
9655
+ this.buffering = false;
9656
+ };
9657
+ _proto.resumeBuffering = function resumeBuffering() {
9658
+ this.buffering = true;
9659
+ };
9653
9660
  _proto._streamEnded = function _streamEnded(bufferInfo, levelDetails) {
9654
9661
  // If playlist is live, there is another buffered range after the current range, nothing buffered, media is detached,
9655
9662
  // of nothing loading/loaded return false
@@ -11763,6 +11770,110 @@
11763
11770
  logger.log(VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug);
11764
11771
  }
11765
11772
  };
11773
+ _proto.parseNALu = function parseNALu(track, array) {
11774
+ var len = array.byteLength;
11775
+ var state = track.naluState || 0;
11776
+ var lastState = state;
11777
+ var units = [];
11778
+ var i = 0;
11779
+ var value;
11780
+ var overflow;
11781
+ var unitType;
11782
+ var lastUnitStart = -1;
11783
+ var lastUnitType = 0;
11784
+ // logger.log('PES:' + Hex.hexDump(array));
11785
+
11786
+ if (state === -1) {
11787
+ // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
11788
+ lastUnitStart = 0;
11789
+ // NALu type is value read from offset 0
11790
+ lastUnitType = this.getNALuType(array, 0);
11791
+ state = 0;
11792
+ i = 1;
11793
+ }
11794
+ while (i < len) {
11795
+ value = array[i++];
11796
+ // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
11797
+ if (!state) {
11798
+ state = value ? 0 : 1;
11799
+ continue;
11800
+ }
11801
+ if (state === 1) {
11802
+ state = value ? 0 : 2;
11803
+ continue;
11804
+ }
11805
+ // here we have state either equal to 2 or 3
11806
+ if (!value) {
11807
+ state = 3;
11808
+ } else if (value === 1) {
11809
+ overflow = i - state - 1;
11810
+ if (lastUnitStart >= 0) {
11811
+ var unit = {
11812
+ data: array.subarray(lastUnitStart, overflow),
11813
+ type: lastUnitType
11814
+ };
11815
+ // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
11816
+ units.push(unit);
11817
+ } else {
11818
+ // lastUnitStart is undefined => this is the first start code found in this PES packet
11819
+ // first check if start code delimiter is overlapping between 2 PES packets,
11820
+ // ie it started in last packet (lastState not zero)
11821
+ // and ended at the beginning of this PES packet (i <= 4 - lastState)
11822
+ var lastUnit = this.getLastNalUnit(track.samples);
11823
+ if (lastUnit) {
11824
+ if (lastState && i <= 4 - lastState) {
11825
+ // start delimiter overlapping between PES packets
11826
+ // strip start delimiter bytes from the end of last NAL unit
11827
+ // check if lastUnit had a state different from zero
11828
+ if (lastUnit.state) {
11829
+ // strip last bytes
11830
+ lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
11831
+ }
11832
+ }
11833
+ // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
11834
+
11835
+ if (overflow > 0) {
11836
+ // logger.log('first NALU found with overflow:' + overflow);
11837
+ lastUnit.data = appendUint8Array(lastUnit.data, array.subarray(0, overflow));
11838
+ lastUnit.state = 0;
11839
+ }
11840
+ }
11841
+ }
11842
+ // check if we can read unit type
11843
+ if (i < len) {
11844
+ unitType = this.getNALuType(array, i);
11845
+ // logger.log('find NALU @ offset:' + i + ',type:' + unitType);
11846
+ lastUnitStart = i;
11847
+ lastUnitType = unitType;
11848
+ state = 0;
11849
+ } else {
11850
+ // not enough byte to read unit type. let's read it on next PES parsing
11851
+ state = -1;
11852
+ }
11853
+ } else {
11854
+ state = 0;
11855
+ }
11856
+ }
11857
+ if (lastUnitStart >= 0 && state >= 0) {
11858
+ var _unit = {
11859
+ data: array.subarray(lastUnitStart, len),
11860
+ type: lastUnitType,
11861
+ state: state
11862
+ };
11863
+ units.push(_unit);
11864
+ // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
11865
+ }
11866
+ // no NALu found
11867
+ if (units.length === 0) {
11868
+ // append pes.data to previous NAL unit
11869
+ var _lastUnit = this.getLastNalUnit(track.samples);
11870
+ if (_lastUnit) {
11871
+ _lastUnit.data = appendUint8Array(_lastUnit.data, array);
11872
+ }
11873
+ }
11874
+ track.naluState = state;
11875
+ return units;
11876
+ };
11766
11877
  return BaseVideoParser;
11767
11878
  }();
11768
11879
 
@@ -11917,22 +12028,179 @@
11917
12028
  ;
11918
12029
  _proto.readUInt = function readUInt() {
11919
12030
  return this.readBits(32);
12031
+ };
12032
+ return ExpGolomb;
12033
+ }();
12034
+
12035
+ var AvcVideoParser = /*#__PURE__*/function (_BaseVideoParser) {
12036
+ _inheritsLoose(AvcVideoParser, _BaseVideoParser);
12037
+ function AvcVideoParser() {
12038
+ return _BaseVideoParser.apply(this, arguments) || this;
12039
+ }
12040
+ var _proto = AvcVideoParser.prototype;
12041
+ _proto.parsePES = function parsePES(track, textTrack, pes, last, duration) {
12042
+ var _this = this;
12043
+ var units = this.parseNALu(track, pes.data);
12044
+ var VideoSample = this.VideoSample;
12045
+ var push;
12046
+ var spsfound = false;
12047
+ // free pes.data to save up some memory
12048
+ pes.data = null;
12049
+
12050
+ // if new NAL units found and last sample still there, let's push ...
12051
+ // this helps parsing streams with missing AUD (only do this if AUD never found)
12052
+ if (VideoSample && units.length && !track.audFound) {
12053
+ this.pushAccessUnit(VideoSample, track);
12054
+ VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
12055
+ }
12056
+ units.forEach(function (unit) {
12057
+ var _VideoSample2;
12058
+ switch (unit.type) {
12059
+ // NDR
12060
+ case 1:
12061
+ {
12062
+ var iskey = false;
12063
+ push = true;
12064
+ var data = unit.data;
12065
+ // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
12066
+ if (spsfound && data.length > 4) {
12067
+ // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
12068
+ var sliceType = _this.readSliceType(data);
12069
+ // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
12070
+ // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
12071
+ // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
12072
+ // I slice: A slice that is not an SI slice that is decoded using intra prediction only.
12073
+ // if (sliceType === 2 || sliceType === 7) {
12074
+ if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
12075
+ iskey = true;
12076
+ }
12077
+ }
12078
+ if (iskey) {
12079
+ var _VideoSample;
12080
+ // if we have non-keyframe data already, that cannot belong to the same frame as a keyframe, so force a push
12081
+ if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
12082
+ _this.pushAccessUnit(VideoSample, track);
12083
+ VideoSample = _this.VideoSample = null;
12084
+ }
12085
+ }
12086
+ if (!VideoSample) {
12087
+ VideoSample = _this.VideoSample = _this.createVideoSample(true, pes.pts, pes.dts, '');
12088
+ }
12089
+ VideoSample.frame = true;
12090
+ VideoSample.key = iskey;
12091
+ break;
12092
+ // IDR
12093
+ }
12094
+ case 5:
12095
+ push = true;
12096
+ // handle PES not starting with AUD
12097
+ // if we have frame data already, that cannot belong to the same frame, so force a push
12098
+ if ((_VideoSample2 = VideoSample) != null && _VideoSample2.frame && !VideoSample.key) {
12099
+ _this.pushAccessUnit(VideoSample, track);
12100
+ VideoSample = _this.VideoSample = null;
12101
+ }
12102
+ if (!VideoSample) {
12103
+ VideoSample = _this.VideoSample = _this.createVideoSample(true, pes.pts, pes.dts, '');
12104
+ }
12105
+ VideoSample.key = true;
12106
+ VideoSample.frame = true;
12107
+ break;
12108
+ // SEI
12109
+ case 6:
12110
+ {
12111
+ push = true;
12112
+ parseSEIMessageFromNALu(unit.data, 1, pes.pts, textTrack.samples);
12113
+ break;
12114
+ // SPS
12115
+ }
12116
+ case 7:
12117
+ {
12118
+ var _track$pixelRatio, _track$pixelRatio2;
12119
+ push = true;
12120
+ spsfound = true;
12121
+ var sps = unit.data;
12122
+ var config = _this.readSPS(sps);
12123
+ if (!track.sps || track.width !== config.width || track.height !== config.height || ((_track$pixelRatio = track.pixelRatio) == null ? void 0 : _track$pixelRatio[0]) !== config.pixelRatio[0] || ((_track$pixelRatio2 = track.pixelRatio) == null ? void 0 : _track$pixelRatio2[1]) !== config.pixelRatio[1]) {
12124
+ track.width = config.width;
12125
+ track.height = config.height;
12126
+ track.pixelRatio = config.pixelRatio;
12127
+ track.sps = [sps];
12128
+ track.duration = duration;
12129
+ var codecarray = sps.subarray(1, 4);
12130
+ var codecstring = 'avc1.';
12131
+ for (var i = 0; i < 3; i++) {
12132
+ var h = codecarray[i].toString(16);
12133
+ if (h.length < 2) {
12134
+ h = '0' + h;
12135
+ }
12136
+ codecstring += h;
12137
+ }
12138
+ track.codec = codecstring;
12139
+ }
12140
+ break;
12141
+ }
12142
+ // PPS
12143
+ case 8:
12144
+ push = true;
12145
+ track.pps = [unit.data];
12146
+ break;
12147
+ // AUD
12148
+ case 9:
12149
+ push = true;
12150
+ track.audFound = true;
12151
+ if (VideoSample) {
12152
+ _this.pushAccessUnit(VideoSample, track);
12153
+ }
12154
+ VideoSample = _this.VideoSample = _this.createVideoSample(false, pes.pts, pes.dts, '');
12155
+ break;
12156
+ // Filler Data
12157
+ case 12:
12158
+ push = true;
12159
+ break;
12160
+ default:
12161
+ push = false;
12162
+ if (VideoSample) {
12163
+ VideoSample.debug += 'unknown NAL ' + unit.type + ' ';
12164
+ }
12165
+ break;
12166
+ }
12167
+ if (VideoSample && push) {
12168
+ var _units = VideoSample.units;
12169
+ _units.push(unit);
12170
+ }
12171
+ });
12172
+ // if last PES packet, push samples
12173
+ if (last && VideoSample) {
12174
+ this.pushAccessUnit(VideoSample, track);
12175
+ this.VideoSample = null;
12176
+ }
12177
+ };
12178
+ _proto.getNALuType = function getNALuType(data, offset) {
12179
+ return data[offset] & 0x1f;
12180
+ };
12181
+ _proto.readSliceType = function readSliceType(data) {
12182
+ var eg = new ExpGolomb(data);
12183
+ // skip NALu type
12184
+ eg.readUByte();
12185
+ // discard first_mb_in_slice
12186
+ eg.readUEG();
12187
+ // return slice_type
12188
+ return eg.readUEG();
11920
12189
  }
11921
12190
 
11922
12191
  /**
11923
- * Advance the ExpGolomb decoder past a scaling list. The scaling
11924
- * list is optionally transmitted as part of a sequence parameter
12192
+ * The scaling list is optionally transmitted as part of a sequence parameter
11925
12193
  * set and is not relevant to transmuxing.
11926
12194
  * @param count the number of entries in this scaling list
11927
12195
  * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
11928
12196
  */;
11929
- _proto.skipScalingList = function skipScalingList(count) {
12197
+ _proto.skipScalingList = function skipScalingList(count, reader) {
11930
12198
  var lastScale = 8;
11931
12199
  var nextScale = 8;
11932
12200
  var deltaScale;
11933
12201
  for (var j = 0; j < count; j++) {
11934
12202
  if (nextScale !== 0) {
11935
- deltaScale = this.readEG();
12203
+ deltaScale = reader.readEG();
11936
12204
  nextScale = (lastScale + deltaScale + 256) % 256;
11937
12205
  }
11938
12206
  lastScale = nextScale === 0 ? lastScale : nextScale;
@@ -11947,7 +12215,8 @@
11947
12215
  * sequence parameter set, including the dimensions of the
11948
12216
  * associated video frames.
11949
12217
  */;
11950
- _proto.readSPS = function readSPS() {
12218
+ _proto.readSPS = function readSPS(sps) {
12219
+ var eg = new ExpGolomb(sps);
11951
12220
  var frameCropLeftOffset = 0;
11952
12221
  var frameCropRightOffset = 0;
11953
12222
  var frameCropTopOffset = 0;
@@ -11955,13 +12224,13 @@
11955
12224
  var numRefFramesInPicOrderCntCycle;
11956
12225
  var scalingListCount;
11957
12226
  var i;
11958
- var readUByte = this.readUByte.bind(this);
11959
- var readBits = this.readBits.bind(this);
11960
- var readUEG = this.readUEG.bind(this);
11961
- var readBoolean = this.readBoolean.bind(this);
11962
- var skipBits = this.skipBits.bind(this);
11963
- var skipEG = this.skipEG.bind(this);
11964
- var skipUEG = this.skipUEG.bind(this);
12227
+ var readUByte = eg.readUByte.bind(eg);
12228
+ var readBits = eg.readBits.bind(eg);
12229
+ var readUEG = eg.readUEG.bind(eg);
12230
+ var readBoolean = eg.readBoolean.bind(eg);
12231
+ var skipBits = eg.skipBits.bind(eg);
12232
+ var skipEG = eg.skipEG.bind(eg);
12233
+ var skipUEG = eg.skipUEG.bind(eg);
11965
12234
  var skipScalingList = this.skipScalingList.bind(this);
11966
12235
  readUByte();
11967
12236
  var profileIdc = readUByte(); // profile_idc
@@ -11986,9 +12255,9 @@
11986
12255
  if (readBoolean()) {
11987
12256
  // seq_scaling_list_present_flag[ i ]
11988
12257
  if (i < 6) {
11989
- skipScalingList(16);
12258
+ skipScalingList(16, eg);
11990
12259
  } else {
11991
- skipScalingList(64);
12260
+ skipScalingList(64, eg);
11992
12261
  }
11993
12262
  }
11994
12263
  }
@@ -12093,26 +12362,24 @@
12093
12362
  pixelRatio: pixelRatio
12094
12363
  };
12095
12364
  };
12096
- _proto.readSliceType = function readSliceType() {
12097
- // skip NALu type
12098
- this.readUByte();
12099
- // discard first_mb_in_slice
12100
- this.readUEG();
12101
- // return slice_type
12102
- return this.readUEG();
12103
- };
12104
- return ExpGolomb;
12105
- }();
12365
+ return AvcVideoParser;
12366
+ }(BaseVideoParser);
12106
12367
 
12107
- var AvcVideoParser = /*#__PURE__*/function (_BaseVideoParser) {
12108
- _inheritsLoose(AvcVideoParser, _BaseVideoParser);
12109
- function AvcVideoParser() {
12110
- return _BaseVideoParser.apply(this, arguments) || this;
12368
+ var HevcVideoParser = /*#__PURE__*/function (_BaseVideoParser) {
12369
+ _inheritsLoose(HevcVideoParser, _BaseVideoParser);
12370
+ function HevcVideoParser() {
12371
+ var _this;
12372
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
12373
+ args[_key] = arguments[_key];
12374
+ }
12375
+ _this = _BaseVideoParser.call.apply(_BaseVideoParser, [this].concat(args)) || this;
12376
+ _this.initVPS = null;
12377
+ return _this;
12111
12378
  }
12112
- var _proto = AvcVideoParser.prototype;
12113
- _proto.parseAVCPES = function parseAVCPES(track, textTrack, pes, last, duration) {
12114
- var _this = this;
12115
- var units = this.parseAVCNALu(track, pes.data);
12379
+ var _proto = HevcVideoParser.prototype;
12380
+ _proto.parsePES = function parsePES(track, textTrack, pes, last, duration) {
12381
+ var _this2 = this;
12382
+ var units = this.parseNALu(track, pes.data);
12116
12383
  var VideoSample = this.VideoSample;
12117
12384
  var push;
12118
12385
  var spsfound = false;
@@ -12128,112 +12395,143 @@
12128
12395
  units.forEach(function (unit) {
12129
12396
  var _VideoSample2;
12130
12397
  switch (unit.type) {
12131
- // NDR
12398
+ // NON-IDR, NON RANDOM ACCESS SLICE
12399
+ case 0:
12132
12400
  case 1:
12133
- {
12134
- var iskey = false;
12135
- push = true;
12136
- var data = unit.data;
12137
- // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
12138
- if (spsfound && data.length > 4) {
12139
- // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
12140
- var sliceType = new ExpGolomb(data).readSliceType();
12141
- // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
12142
- // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
12143
- // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
12144
- // I slice: A slice that is not an SI slice that is decoded using intra prediction only.
12145
- // if (sliceType === 2 || sliceType === 7) {
12146
- if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
12147
- iskey = true;
12148
- }
12149
- }
12150
- if (iskey) {
12151
- var _VideoSample;
12152
- // if we have non-keyframe data already, that cannot belong to the same frame as a keyframe, so force a push
12153
- if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
12154
- _this.pushAccessUnit(VideoSample, track);
12155
- VideoSample = _this.VideoSample = null;
12156
- }
12157
- }
12158
- if (!VideoSample) {
12159
- VideoSample = _this.VideoSample = _this.createVideoSample(true, pes.pts, pes.dts, '');
12401
+ case 2:
12402
+ case 3:
12403
+ case 4:
12404
+ case 5:
12405
+ case 6:
12406
+ case 7:
12407
+ case 8:
12408
+ case 9:
12409
+ if (!VideoSample) {
12410
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(false, pes.pts, pes.dts, '');
12411
+ }
12412
+ VideoSample.frame = true;
12413
+ push = true;
12414
+ break;
12415
+
12416
+ // CRA, BLA (random access picture)
12417
+ case 16:
12418
+ case 17:
12419
+ case 18:
12420
+ case 21:
12421
+ push = true;
12422
+ if (spsfound) {
12423
+ var _VideoSample;
12424
+ // handle PES not starting with AUD
12425
+ // if we have frame data already, that cannot belong to the same frame, so force a push
12426
+ if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
12427
+ _this2.pushAccessUnit(VideoSample, track);
12428
+ VideoSample = _this2.VideoSample = null;
12160
12429
  }
12161
- VideoSample.frame = true;
12162
- VideoSample.key = iskey;
12163
- break;
12164
- // IDR
12165
12430
  }
12166
- case 5:
12431
+ if (!VideoSample) {
12432
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(true, pes.pts, pes.dts, '');
12433
+ }
12434
+ VideoSample.key = true;
12435
+ VideoSample.frame = true;
12436
+ break;
12437
+
12438
+ // IDR
12439
+ case 19:
12440
+ case 20:
12167
12441
  push = true;
12168
12442
  // handle PES not starting with AUD
12169
12443
  // if we have frame data already, that cannot belong to the same frame, so force a push
12170
12444
  if ((_VideoSample2 = VideoSample) != null && _VideoSample2.frame && !VideoSample.key) {
12171
- _this.pushAccessUnit(VideoSample, track);
12172
- VideoSample = _this.VideoSample = null;
12445
+ _this2.pushAccessUnit(VideoSample, track);
12446
+ VideoSample = _this2.VideoSample = null;
12173
12447
  }
12174
12448
  if (!VideoSample) {
12175
- VideoSample = _this.VideoSample = _this.createVideoSample(true, pes.pts, pes.dts, '');
12449
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(true, pes.pts, pes.dts, '');
12176
12450
  }
12177
12451
  VideoSample.key = true;
12178
12452
  VideoSample.frame = true;
12179
12453
  break;
12454
+
12180
12455
  // SEI
12181
- case 6:
12182
- {
12183
- push = true;
12184
- parseSEIMessageFromNALu(unit.data, 1, pes.pts, textTrack.samples);
12185
- break;
12186
- // SPS
12456
+ case 39:
12457
+ push = true;
12458
+ parseSEIMessageFromNALu(unit.data, 2,
12459
+ // NALu header size
12460
+ pes.pts, textTrack.samples);
12461
+ break;
12462
+
12463
+ // VPS
12464
+ case 32:
12465
+ push = true;
12466
+ if (!track.vps) {
12467
+ var config = _this2.readVPS(unit.data);
12468
+ track.params = _objectSpread2({}, config);
12469
+ _this2.initVPS = unit.data;
12187
12470
  }
12188
- case 7:
12189
- {
12190
- var _track$pixelRatio, _track$pixelRatio2;
12191
- push = true;
12192
- spsfound = true;
12193
- var sps = unit.data;
12194
- var expGolombDecoder = new ExpGolomb(sps);
12195
- var config = expGolombDecoder.readSPS();
12196
- if (!track.sps || track.width !== config.width || track.height !== config.height || ((_track$pixelRatio = track.pixelRatio) == null ? void 0 : _track$pixelRatio[0]) !== config.pixelRatio[0] || ((_track$pixelRatio2 = track.pixelRatio) == null ? void 0 : _track$pixelRatio2[1]) !== config.pixelRatio[1]) {
12197
- track.width = config.width;
12198
- track.height = config.height;
12199
- track.pixelRatio = config.pixelRatio;
12200
- track.sps = [sps];
12471
+ track.vps = [unit.data];
12472
+ break;
12473
+
12474
+ // SPS
12475
+ case 33:
12476
+ push = true;
12477
+ spsfound = true;
12478
+ if (typeof track.params === 'object') {
12479
+ if (track.vps !== undefined && track.vps[0] !== _this2.initVPS && track.sps !== undefined && !_this2.matchSPS(track.sps[0], unit.data)) {
12480
+ _this2.initVPS = track.vps[0];
12481
+ track.sps = track.pps = undefined;
12482
+ }
12483
+ if (!track.sps) {
12484
+ var _config = _this2.readSPS(unit.data);
12485
+ track.width = _config.width;
12486
+ track.height = _config.height;
12487
+ track.pixelRatio = _config.pixelRatio;
12201
12488
  track.duration = duration;
12202
- var codecarray = sps.subarray(1, 4);
12203
- var codecstring = 'avc1.';
12204
- for (var i = 0; i < 3; i++) {
12205
- var h = codecarray[i].toString(16);
12206
- if (h.length < 2) {
12207
- h = '0' + h;
12208
- }
12209
- codecstring += h;
12489
+ track.codec = _config.codecString;
12490
+ track.sps = [];
12491
+ for (var prop in _config.params) {
12492
+ track.params[prop] = _config.params[prop];
12210
12493
  }
12211
- track.codec = codecstring;
12212
12494
  }
12213
- break;
12495
+ if (track.vps !== undefined && track.vps[0] === _this2.initVPS) {
12496
+ track.sps.push(unit.data);
12497
+ }
12498
+ }
12499
+ if (!VideoSample) {
12500
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(true, pes.pts, pes.dts, '');
12214
12501
  }
12502
+ VideoSample.key = true;
12503
+ break;
12504
+
12215
12505
  // PPS
12216
- case 8:
12506
+ case 34:
12217
12507
  push = true;
12218
- track.pps = [unit.data];
12508
+ if (typeof track.params === 'object') {
12509
+ if (!track.pps) {
12510
+ track.pps = [];
12511
+ var _config2 = _this2.readPPS(unit.data);
12512
+ for (var _prop in _config2) {
12513
+ track.params[_prop] = _config2[_prop];
12514
+ }
12515
+ }
12516
+ if (_this2.initVPS !== null || track.pps.length === 0) {
12517
+ track.pps.push(unit.data);
12518
+ }
12519
+ }
12219
12520
  break;
12220
- // AUD
12221
- case 9:
12521
+
12522
+ // ACCESS UNIT DELIMITER
12523
+ case 35:
12222
12524
  push = true;
12223
12525
  track.audFound = true;
12224
12526
  if (VideoSample) {
12225
- _this.pushAccessUnit(VideoSample, track);
12527
+ _this2.pushAccessUnit(VideoSample, track);
12226
12528
  }
12227
- VideoSample = _this.VideoSample = _this.createVideoSample(false, pes.pts, pes.dts, '');
12228
- break;
12229
- // Filler Data
12230
- case 12:
12231
- push = true;
12529
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(false, pes.pts, pes.dts, '');
12232
12530
  break;
12233
12531
  default:
12234
12532
  push = false;
12235
12533
  if (VideoSample) {
12236
- VideoSample.debug += 'unknown NAL ' + unit.type + ' ';
12534
+ VideoSample.debug += 'unknown or irrelevant NAL ' + unit.type + ' ';
12237
12535
  }
12238
12536
  break;
12239
12537
  }
@@ -12248,111 +12546,425 @@
12248
12546
  this.VideoSample = null;
12249
12547
  }
12250
12548
  };
12251
- _proto.parseAVCNALu = function parseAVCNALu(track, array) {
12252
- var len = array.byteLength;
12253
- var state = track.naluState || 0;
12254
- var lastState = state;
12255
- var units = [];
12256
- var i = 0;
12257
- var value;
12258
- var overflow;
12259
- var unitType;
12260
- var lastUnitStart = -1;
12261
- var lastUnitType = 0;
12262
- // logger.log('PES:' + Hex.hexDump(array));
12263
-
12264
- if (state === -1) {
12265
- // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
12266
- lastUnitStart = 0;
12267
- // NALu type is value read from offset 0
12268
- lastUnitType = array[0] & 0x1f;
12269
- state = 0;
12270
- i = 1;
12271
- }
12272
- while (i < len) {
12273
- value = array[i++];
12274
- // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
12275
- if (!state) {
12276
- state = value ? 0 : 1;
12277
- continue;
12278
- }
12279
- if (state === 1) {
12280
- state = value ? 0 : 2;
12281
- continue;
12549
+ _proto.getNALuType = function getNALuType(data, offset) {
12550
+ return (data[offset] & 0x7e) >>> 1;
12551
+ };
12552
+ _proto.ebsp2rbsp = function ebsp2rbsp(arr) {
12553
+ var dst = new Uint8Array(arr.byteLength);
12554
+ var dstIdx = 0;
12555
+ for (var i = 0; i < arr.byteLength; i++) {
12556
+ if (i >= 2) {
12557
+ // Unescape: Skip 0x03 after 00 00
12558
+ if (arr[i] === 0x03 && arr[i - 1] === 0x00 && arr[i - 2] === 0x00) {
12559
+ continue;
12560
+ }
12282
12561
  }
12283
- // here we have state either equal to 2 or 3
12284
- if (!value) {
12285
- state = 3;
12286
- } else if (value === 1) {
12287
- overflow = i - state - 1;
12288
- if (lastUnitStart >= 0) {
12289
- var unit = {
12290
- data: array.subarray(lastUnitStart, overflow),
12291
- type: lastUnitType
12292
- };
12293
- // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
12294
- units.push(unit);
12295
- } else {
12296
- // lastUnitStart is undefined => this is the first start code found in this PES packet
12297
- // first check if start code delimiter is overlapping between 2 PES packets,
12298
- // ie it started in last packet (lastState not zero)
12299
- // and ended at the beginning of this PES packet (i <= 4 - lastState)
12300
- var lastUnit = this.getLastNalUnit(track.samples);
12301
- if (lastUnit) {
12302
- if (lastState && i <= 4 - lastState) {
12303
- // start delimiter overlapping between PES packets
12304
- // strip start delimiter bytes from the end of last NAL unit
12305
- // check if lastUnit had a state different from zero
12306
- if (lastUnit.state) {
12307
- // strip last bytes
12308
- lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
12309
- }
12310
- }
12311
- // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
12562
+ dst[dstIdx] = arr[i];
12563
+ dstIdx++;
12564
+ }
12565
+ return new Uint8Array(dst.buffer, 0, dstIdx);
12566
+ };
12567
+ _proto.readVPS = function readVPS(vps) {
12568
+ var eg = new ExpGolomb(vps);
12569
+ // remove header
12570
+ eg.readUByte();
12571
+ eg.readUByte();
12572
+ eg.readBits(4); // video_parameter_set_id
12573
+ eg.skipBits(2);
12574
+ eg.readBits(6); // max_layers_minus1
12575
+ var max_sub_layers_minus1 = eg.readBits(3);
12576
+ var temporal_id_nesting_flag = eg.readBoolean();
12577
+ // ...vui fps can be here, but empty fps value is not critical for metadata
12312
12578
 
12313
- if (overflow > 0) {
12314
- // logger.log('first NALU found with overflow:' + overflow);
12315
- lastUnit.data = appendUint8Array(lastUnit.data, array.subarray(0, overflow));
12316
- lastUnit.state = 0;
12579
+ return {
12580
+ numTemporalLayers: max_sub_layers_minus1 + 1,
12581
+ temporalIdNested: temporal_id_nesting_flag
12582
+ };
12583
+ };
12584
+ _proto.readSPS = function readSPS(sps) {
12585
+ var eg = new ExpGolomb(this.ebsp2rbsp(sps));
12586
+ eg.readUByte();
12587
+ eg.readUByte();
12588
+ eg.readBits(4); //video_parameter_set_id
12589
+ var max_sub_layers_minus1 = eg.readBits(3);
12590
+ eg.readBoolean(); // temporal_id_nesting_flag
12591
+
12592
+ // profile_tier_level
12593
+ var general_profile_space = eg.readBits(2);
12594
+ var general_tier_flag = eg.readBoolean();
12595
+ var general_profile_idc = eg.readBits(5);
12596
+ var general_profile_compatibility_flags_1 = eg.readUByte();
12597
+ var general_profile_compatibility_flags_2 = eg.readUByte();
12598
+ var general_profile_compatibility_flags_3 = eg.readUByte();
12599
+ var general_profile_compatibility_flags_4 = eg.readUByte();
12600
+ var general_constraint_indicator_flags_1 = eg.readUByte();
12601
+ var general_constraint_indicator_flags_2 = eg.readUByte();
12602
+ var general_constraint_indicator_flags_3 = eg.readUByte();
12603
+ var general_constraint_indicator_flags_4 = eg.readUByte();
12604
+ var general_constraint_indicator_flags_5 = eg.readUByte();
12605
+ var general_constraint_indicator_flags_6 = eg.readUByte();
12606
+ var general_level_idc = eg.readUByte();
12607
+ var sub_layer_profile_present_flags = [];
12608
+ var sub_layer_level_present_flags = [];
12609
+ for (var i = 0; i < max_sub_layers_minus1; i++) {
12610
+ sub_layer_profile_present_flags.push(eg.readBoolean());
12611
+ sub_layer_level_present_flags.push(eg.readBoolean());
12612
+ }
12613
+ if (max_sub_layers_minus1 > 0) {
12614
+ for (var _i = max_sub_layers_minus1; _i < 8; _i++) {
12615
+ eg.readBits(2);
12616
+ }
12617
+ }
12618
+ for (var _i2 = 0; _i2 < max_sub_layers_minus1; _i2++) {
12619
+ if (sub_layer_profile_present_flags[_i2]) {
12620
+ eg.readUByte(); // sub_layer_profile_space, sub_layer_tier_flag, sub_layer_profile_idc
12621
+ eg.readUByte();
12622
+ eg.readUByte();
12623
+ eg.readUByte();
12624
+ eg.readUByte(); // sub_layer_profile_compatibility_flag
12625
+ eg.readUByte();
12626
+ eg.readUByte();
12627
+ eg.readUByte();
12628
+ eg.readUByte();
12629
+ eg.readUByte();
12630
+ eg.readUByte();
12631
+ }
12632
+ if (sub_layer_level_present_flags[_i2]) {
12633
+ eg.readUByte();
12634
+ }
12635
+ }
12636
+ eg.readUEG(); // seq_parameter_set_id
12637
+ var chroma_format_idc = eg.readUEG();
12638
+ if (chroma_format_idc == 3) {
12639
+ eg.skipBits(1); //separate_colour_plane_flag
12640
+ }
12641
+ var pic_width_in_luma_samples = eg.readUEG();
12642
+ var pic_height_in_luma_samples = eg.readUEG();
12643
+ var conformance_window_flag = eg.readBoolean();
12644
+ var pic_left_offset = 0,
12645
+ pic_right_offset = 0,
12646
+ pic_top_offset = 0,
12647
+ pic_bottom_offset = 0;
12648
+ if (conformance_window_flag) {
12649
+ pic_left_offset += eg.readUEG();
12650
+ pic_right_offset += eg.readUEG();
12651
+ pic_top_offset += eg.readUEG();
12652
+ pic_bottom_offset += eg.readUEG();
12653
+ }
12654
+ var bit_depth_luma_minus8 = eg.readUEG();
12655
+ var bit_depth_chroma_minus8 = eg.readUEG();
12656
+ var log2_max_pic_order_cnt_lsb_minus4 = eg.readUEG();
12657
+ var sub_layer_ordering_info_present_flag = eg.readBoolean();
12658
+ for (var _i3 = sub_layer_ordering_info_present_flag ? 0 : max_sub_layers_minus1; _i3 <= max_sub_layers_minus1; _i3++) {
12659
+ eg.skipUEG(); // max_dec_pic_buffering_minus1[i]
12660
+ eg.skipUEG(); // max_num_reorder_pics[i]
12661
+ eg.skipUEG(); // max_latency_increase_plus1[i]
12662
+ }
12663
+ eg.skipUEG(); // log2_min_luma_coding_block_size_minus3
12664
+ eg.skipUEG(); // log2_diff_max_min_luma_coding_block_size
12665
+ eg.skipUEG(); // log2_min_transform_block_size_minus2
12666
+ eg.skipUEG(); // log2_diff_max_min_transform_block_size
12667
+ eg.skipUEG(); // max_transform_hierarchy_depth_inter
12668
+ eg.skipUEG(); // max_transform_hierarchy_depth_intra
12669
+ var scaling_list_enabled_flag = eg.readBoolean();
12670
+ if (scaling_list_enabled_flag) {
12671
+ var sps_scaling_list_data_present_flag = eg.readBoolean();
12672
+ if (sps_scaling_list_data_present_flag) {
12673
+ for (var sizeId = 0; sizeId < 4; sizeId++) {
12674
+ for (var matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {
12675
+ var scaling_list_pred_mode_flag = eg.readBoolean();
12676
+ if (!scaling_list_pred_mode_flag) {
12677
+ eg.readUEG(); // scaling_list_pred_matrix_id_delta
12678
+ } else {
12679
+ var coefNum = Math.min(64, 1 << 4 + (sizeId << 1));
12680
+ if (sizeId > 1) {
12681
+ eg.readEG();
12682
+ }
12683
+ for (var _i4 = 0; _i4 < coefNum; _i4++) {
12684
+ eg.readEG();
12685
+ }
12317
12686
  }
12318
12687
  }
12319
12688
  }
12320
- // check if we can read unit type
12321
- if (i < len) {
12322
- unitType = array[i] & 0x1f;
12323
- // logger.log('find NALU @ offset:' + i + ',type:' + unitType);
12324
- lastUnitStart = i;
12325
- lastUnitType = unitType;
12326
- state = 0;
12327
- } else {
12328
- // not enough byte to read unit type. let's read it on next PES parsing
12329
- state = -1;
12330
- }
12331
- } else {
12332
- state = 0;
12333
12689
  }
12334
12690
  }
12335
- if (lastUnitStart >= 0 && state >= 0) {
12336
- var _unit = {
12337
- data: array.subarray(lastUnitStart, len),
12338
- type: lastUnitType,
12339
- state: state
12340
- };
12341
- units.push(_unit);
12342
- // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
12343
- }
12344
- // no NALu found
12345
- if (units.length === 0) {
12346
- // append pes.data to previous NAL unit
12347
- var _lastUnit = this.getLastNalUnit(track.samples);
12348
- if (_lastUnit) {
12349
- _lastUnit.data = appendUint8Array(_lastUnit.data, array);
12691
+ eg.readBoolean(); // amp_enabled_flag
12692
+ eg.readBoolean(); // sample_adaptive_offset_enabled_flag
12693
+ var pcm_enabled_flag = eg.readBoolean();
12694
+ if (pcm_enabled_flag) {
12695
+ eg.readUByte();
12696
+ eg.skipUEG();
12697
+ eg.skipUEG();
12698
+ eg.readBoolean();
12699
+ }
12700
+ var num_short_term_ref_pic_sets = eg.readUEG();
12701
+ var num_delta_pocs = 0;
12702
+ for (var _i5 = 0; _i5 < num_short_term_ref_pic_sets; _i5++) {
12703
+ var inter_ref_pic_set_prediction_flag = false;
12704
+ if (_i5 !== 0) {
12705
+ inter_ref_pic_set_prediction_flag = eg.readBoolean();
12706
+ }
12707
+ if (inter_ref_pic_set_prediction_flag) {
12708
+ if (_i5 === num_short_term_ref_pic_sets) {
12709
+ eg.readUEG();
12710
+ }
12711
+ eg.readBoolean();
12712
+ eg.readUEG();
12713
+ var next_num_delta_pocs = 0;
12714
+ for (var j = 0; j <= num_delta_pocs; j++) {
12715
+ var used_by_curr_pic_flag = eg.readBoolean();
12716
+ var use_delta_flag = false;
12717
+ if (!used_by_curr_pic_flag) {
12718
+ use_delta_flag = eg.readBoolean();
12719
+ }
12720
+ if (used_by_curr_pic_flag || use_delta_flag) {
12721
+ next_num_delta_pocs++;
12722
+ }
12723
+ }
12724
+ num_delta_pocs = next_num_delta_pocs;
12725
+ } else {
12726
+ var num_negative_pics = eg.readUEG();
12727
+ var num_positive_pics = eg.readUEG();
12728
+ num_delta_pocs = num_negative_pics + num_positive_pics;
12729
+ for (var _j = 0; _j < num_negative_pics; _j++) {
12730
+ eg.readUEG();
12731
+ eg.readBoolean();
12732
+ }
12733
+ for (var _j2 = 0; _j2 < num_positive_pics; _j2++) {
12734
+ eg.readUEG();
12735
+ eg.readBoolean();
12736
+ }
12737
+ }
12738
+ }
12739
+ var long_term_ref_pics_present_flag = eg.readBoolean();
12740
+ if (long_term_ref_pics_present_flag) {
12741
+ var num_long_term_ref_pics_sps = eg.readUEG();
12742
+ for (var _i6 = 0; _i6 < num_long_term_ref_pics_sps; _i6++) {
12743
+ for (var _j3 = 0; _j3 < log2_max_pic_order_cnt_lsb_minus4 + 4; _j3++) {
12744
+ eg.readBits(1);
12745
+ }
12746
+ eg.readBits(1);
12747
+ }
12748
+ }
12749
+ var min_spatial_segmentation_idc = 0;
12750
+ var sar_width = 1,
12751
+ sar_height = 1;
12752
+ var fps_fixed = true,
12753
+ fps_den = 1,
12754
+ fps_num = 0;
12755
+ eg.readBoolean(); // sps_temporal_mvp_enabled_flag
12756
+ eg.readBoolean(); // strong_intra_smoothing_enabled_flag
12757
+ var default_display_window_flag = false;
12758
+ var vui_parameters_present_flag = eg.readBoolean();
12759
+ if (vui_parameters_present_flag) {
12760
+ var aspect_ratio_info_present_flag = eg.readBoolean();
12761
+ if (aspect_ratio_info_present_flag) {
12762
+ var aspect_ratio_idc = eg.readUByte();
12763
+ var sar_width_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];
12764
+ var sar_height_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];
12765
+ if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
12766
+ sar_width = sar_width_table[aspect_ratio_idc - 1];
12767
+ sar_height = sar_height_table[aspect_ratio_idc - 1];
12768
+ } else if (aspect_ratio_idc === 255) {
12769
+ sar_width = eg.readBits(16);
12770
+ sar_height = eg.readBits(16);
12771
+ }
12772
+ }
12773
+ var overscan_info_present_flag = eg.readBoolean();
12774
+ if (overscan_info_present_flag) {
12775
+ eg.readBoolean();
12776
+ }
12777
+ var video_signal_type_present_flag = eg.readBoolean();
12778
+ if (video_signal_type_present_flag) {
12779
+ eg.readBits(3);
12780
+ eg.readBoolean();
12781
+ var colour_description_present_flag = eg.readBoolean();
12782
+ if (colour_description_present_flag) {
12783
+ eg.readUByte();
12784
+ eg.readUByte();
12785
+ eg.readUByte();
12786
+ }
12787
+ }
12788
+ var chroma_loc_info_present_flag = eg.readBoolean();
12789
+ if (chroma_loc_info_present_flag) {
12790
+ eg.readUEG();
12791
+ eg.readUEG();
12792
+ }
12793
+ eg.readBoolean(); // neutral_chroma_indication_flag
12794
+ eg.readBoolean(); // field_seq_flag
12795
+ eg.readBoolean(); // frame_field_info_present_flag
12796
+ default_display_window_flag = eg.readBoolean();
12797
+ if (default_display_window_flag) {
12798
+ pic_left_offset += eg.readUEG();
12799
+ pic_right_offset += eg.readUEG();
12800
+ pic_top_offset += eg.readUEG();
12801
+ pic_bottom_offset += eg.readUEG();
12802
+ }
12803
+ var vui_timing_info_present_flag = eg.readBoolean();
12804
+ if (vui_timing_info_present_flag) {
12805
+ fps_den = eg.readBits(32);
12806
+ fps_num = eg.readBits(32);
12807
+ var vui_poc_proportional_to_timing_flag = eg.readBoolean();
12808
+ if (vui_poc_proportional_to_timing_flag) {
12809
+ eg.readUEG();
12810
+ }
12811
+ var vui_hrd_parameters_present_flag = eg.readBoolean();
12812
+ if (vui_hrd_parameters_present_flag) {
12813
+ //const commonInfPresentFlag = true;
12814
+ //if (commonInfPresentFlag) {
12815
+ var nal_hrd_parameters_present_flag = eg.readBoolean();
12816
+ var vcl_hrd_parameters_present_flag = eg.readBoolean();
12817
+ var sub_pic_hrd_params_present_flag = false;
12818
+ if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
12819
+ sub_pic_hrd_params_present_flag = eg.readBoolean();
12820
+ if (sub_pic_hrd_params_present_flag) {
12821
+ eg.readUByte();
12822
+ eg.readBits(5);
12823
+ eg.readBoolean();
12824
+ eg.readBits(5);
12825
+ }
12826
+ eg.readBits(4); // bit_rate_scale
12827
+ eg.readBits(4); // cpb_size_scale
12828
+ if (sub_pic_hrd_params_present_flag) {
12829
+ eg.readBits(4);
12830
+ }
12831
+ eg.readBits(5);
12832
+ eg.readBits(5);
12833
+ eg.readBits(5);
12834
+ }
12835
+ //}
12836
+ for (var _i7 = 0; _i7 <= max_sub_layers_minus1; _i7++) {
12837
+ fps_fixed = eg.readBoolean(); // fixed_pic_rate_general_flag
12838
+ var fixed_pic_rate_within_cvs_flag = fps_fixed || eg.readBoolean();
12839
+ var low_delay_hrd_flag = false;
12840
+ if (fixed_pic_rate_within_cvs_flag) {
12841
+ eg.readEG();
12842
+ } else {
12843
+ low_delay_hrd_flag = eg.readBoolean();
12844
+ }
12845
+ var cpb_cnt = low_delay_hrd_flag ? 1 : eg.readUEG() + 1;
12846
+ if (nal_hrd_parameters_present_flag) {
12847
+ for (var _j4 = 0; _j4 < cpb_cnt; _j4++) {
12848
+ eg.readUEG();
12849
+ eg.readUEG();
12850
+ if (sub_pic_hrd_params_present_flag) {
12851
+ eg.readUEG();
12852
+ eg.readUEG();
12853
+ }
12854
+ eg.skipBits(1);
12855
+ }
12856
+ }
12857
+ if (vcl_hrd_parameters_present_flag) {
12858
+ for (var _j5 = 0; _j5 < cpb_cnt; _j5++) {
12859
+ eg.readUEG();
12860
+ eg.readUEG();
12861
+ if (sub_pic_hrd_params_present_flag) {
12862
+ eg.readUEG();
12863
+ eg.readUEG();
12864
+ }
12865
+ eg.skipBits(1);
12866
+ }
12867
+ }
12868
+ }
12869
+ }
12350
12870
  }
12871
+ var bitstream_restriction_flag = eg.readBoolean();
12872
+ if (bitstream_restriction_flag) {
12873
+ eg.readBoolean(); // tiles_fixed_structure_flag
12874
+ eg.readBoolean(); // motion_vectors_over_pic_boundaries_flag
12875
+ eg.readBoolean(); // restricted_ref_pic_lists_flag
12876
+ min_spatial_segmentation_idc = eg.readUEG();
12877
+ }
12878
+ }
12879
+ var width = pic_width_in_luma_samples,
12880
+ height = pic_height_in_luma_samples;
12881
+ if (conformance_window_flag || default_display_window_flag) {
12882
+ var chroma_scale_w = 1,
12883
+ chroma_scale_h = 1;
12884
+ if (chroma_format_idc === 1) {
12885
+ // YUV 420
12886
+ chroma_scale_w = chroma_scale_h = 2;
12887
+ } else if (chroma_format_idc == 2) {
12888
+ // YUV 422
12889
+ chroma_scale_w = 2;
12890
+ }
12891
+ width = pic_width_in_luma_samples - chroma_scale_w * pic_right_offset - chroma_scale_w * pic_left_offset;
12892
+ height = pic_height_in_luma_samples - chroma_scale_h * pic_bottom_offset - chroma_scale_h * pic_top_offset;
12893
+ }
12894
+ var profile_space_string = general_profile_space ? ['A', 'B', 'C'][general_profile_space] : '';
12895
+ var profile_compatibility_buf = general_profile_compatibility_flags_1 << 24 | general_profile_compatibility_flags_2 << 16 | general_profile_compatibility_flags_3 << 8 | general_profile_compatibility_flags_4;
12896
+ var profile_compatibility_rev = 0;
12897
+ for (var _i8 = 0; _i8 < 32; _i8++) {
12898
+ profile_compatibility_rev = (profile_compatibility_rev | (profile_compatibility_buf >> _i8 & 1) << 31 - _i8) >>> 0; // reverse bit position (and cast as UInt32)
12899
+ }
12900
+ var profile_compatibility_flags_string = profile_compatibility_rev.toString(16);
12901
+ if (general_profile_idc === 1 && profile_compatibility_flags_string === '2') {
12902
+ profile_compatibility_flags_string = '6';
12903
+ }
12904
+ var tier_flag_string = general_tier_flag ? 'H' : 'L';
12905
+ return {
12906
+ codecString: "hvc1." + profile_space_string + general_profile_idc + "." + profile_compatibility_flags_string + "." + tier_flag_string + general_level_idc + ".B0",
12907
+ params: {
12908
+ general_tier_flag: general_tier_flag,
12909
+ general_profile_idc: general_profile_idc,
12910
+ general_profile_space: general_profile_space,
12911
+ general_profile_compatibility_flags: [general_profile_compatibility_flags_1, general_profile_compatibility_flags_2, general_profile_compatibility_flags_3, general_profile_compatibility_flags_4],
12912
+ general_constraint_indicator_flags: [general_constraint_indicator_flags_1, general_constraint_indicator_flags_2, general_constraint_indicator_flags_3, general_constraint_indicator_flags_4, general_constraint_indicator_flags_5, general_constraint_indicator_flags_6],
12913
+ general_level_idc: general_level_idc,
12914
+ bit_depth: bit_depth_luma_minus8 + 8,
12915
+ bit_depth_luma_minus8: bit_depth_luma_minus8,
12916
+ bit_depth_chroma_minus8: bit_depth_chroma_minus8,
12917
+ min_spatial_segmentation_idc: min_spatial_segmentation_idc,
12918
+ chroma_format_idc: chroma_format_idc,
12919
+ frame_rate: {
12920
+ fixed: fps_fixed,
12921
+ fps: fps_num / fps_den
12922
+ }
12923
+ },
12924
+ width: width,
12925
+ height: height,
12926
+ pixelRatio: [sar_width, sar_height]
12927
+ };
12928
+ };
12929
+ _proto.readPPS = function readPPS(pps) {
12930
+ var eg = new ExpGolomb(this.ebsp2rbsp(pps));
12931
+ eg.readUByte();
12932
+ eg.readUByte();
12933
+ eg.skipUEG(); // pic_parameter_set_id
12934
+ eg.skipUEG(); // seq_parameter_set_id
12935
+ eg.skipBits(2); // dependent_slice_segments_enabled_flag, output_flag_present_flag
12936
+ eg.skipBits(3); // num_extra_slice_header_bits
12937
+ eg.skipBits(2); // sign_data_hiding_enabled_flag, cabac_init_present_flag
12938
+ eg.skipUEG();
12939
+ eg.skipUEG();
12940
+ eg.skipEG(); // init_qp_minus26
12941
+ eg.skipBits(2); // constrained_intra_pred_flag, transform_skip_enabled_flag
12942
+ var cu_qp_delta_enabled_flag = eg.readBoolean();
12943
+ if (cu_qp_delta_enabled_flag) {
12944
+ eg.skipUEG();
12945
+ }
12946
+ eg.skipEG(); // cb_qp_offset
12947
+ eg.skipEG(); // cr_qp_offset
12948
+ eg.skipBits(4); // pps_slice_chroma_qp_offsets_present_flag, weighted_pred_flag, weighted_bipred_flag, transquant_bypass_enabled_flag
12949
+ var tiles_enabled_flag = eg.readBoolean();
12950
+ var entropy_coding_sync_enabled_flag = eg.readBoolean();
12951
+ var parallelismType = 1; // slice-based parallel decoding
12952
+ if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) {
12953
+ parallelismType = 0; // mixed-type parallel decoding
12954
+ } else if (entropy_coding_sync_enabled_flag) {
12955
+ parallelismType = 3; // wavefront-based parallel decoding
12956
+ } else if (tiles_enabled_flag) {
12957
+ parallelismType = 2; // tile-based parallel decoding
12351
12958
  }
12352
- track.naluState = state;
12353
- return units;
12959
+ return {
12960
+ parallelismType: parallelismType
12961
+ };
12354
12962
  };
12355
- return AvcVideoParser;
12963
+ _proto.matchSPS = function matchSPS(sps1, sps2) {
12964
+ // compare without headers and VPS related params
12965
+ return String.fromCharCode.apply(null, sps1).substr(3) === String.fromCharCode.apply(null, sps2).substr(3);
12966
+ };
12967
+ return HevcVideoParser;
12356
12968
  }(BaseVideoParser);
12357
12969
 
12358
12970
  /**
@@ -12489,7 +13101,7 @@
12489
13101
  this.observer = observer;
12490
13102
  this.config = config;
12491
13103
  this.typeSupported = typeSupported;
12492
- this.videoParser = new AvcVideoParser();
13104
+ this.videoParser = null;
12493
13105
  }
12494
13106
  TSDemuxer.probe = function probe(data) {
12495
13107
  var syncOffset = TSDemuxer.syncOffset(data);
@@ -12659,7 +13271,19 @@
12659
13271
  case videoPid:
12660
13272
  if (stt) {
12661
13273
  if (videoData && (pes = parsePES(videoData))) {
12662
- this.videoParser.parseAVCPES(videoTrack, textTrack, pes, false, this._duration);
13274
+ if (this.videoParser === null) {
13275
+ switch (videoTrack.segmentCodec) {
13276
+ case 'avc':
13277
+ this.videoParser = new AvcVideoParser();
13278
+ break;
13279
+ case 'hevc':
13280
+ this.videoParser = new HevcVideoParser();
13281
+ break;
13282
+ }
13283
+ }
13284
+ if (this.videoParser !== null) {
13285
+ this.videoParser.parsePES(videoTrack, textTrack, pes, false, this._duration);
13286
+ }
12663
13287
  }
12664
13288
  videoData = {
12665
13289
  data: [],
@@ -12822,8 +13446,20 @@
12822
13446
  // try to parse last PES packets
12823
13447
  var pes;
12824
13448
  if (videoData && (pes = parsePES(videoData))) {
12825
- this.videoParser.parseAVCPES(videoTrack, textTrack, pes, true, this._duration);
12826
- videoTrack.pesData = null;
13449
+ if (this.videoParser === null) {
13450
+ switch (videoTrack.segmentCodec) {
13451
+ case 'avc':
13452
+ this.videoParser = new AvcVideoParser();
13453
+ break;
13454
+ case 'hevc':
13455
+ this.videoParser = new HevcVideoParser();
13456
+ break;
13457
+ }
13458
+ }
13459
+ if (this.videoParser !== null) {
13460
+ this.videoParser.parsePES(videoTrack, textTrack, pes, true, this._duration);
13461
+ videoTrack.pesData = null;
13462
+ }
12827
13463
  } else {
12828
13464
  // either avcData null or PES truncated, keep it for next frag parsing
12829
13465
  videoTrack.pesData = videoData;
@@ -13155,7 +13791,12 @@
13155
13791
  logger.warn('Unsupported EC-3 in M2TS found');
13156
13792
  break;
13157
13793
  case 0x24:
13158
- logger.warn('Unsupported HEVC in M2TS found');
13794
+ // ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
13795
+ if (result.videoPid === -1) {
13796
+ result.videoPid = pid;
13797
+ result.segmentVideoCodec = 'hevc';
13798
+ logger.log('HEVC in M2TS found');
13799
+ }
13159
13800
  break;
13160
13801
  }
13161
13802
  // move to the next table entry
@@ -13383,6 +14024,8 @@
13383
14024
  avc1: [],
13384
14025
  // codingname
13385
14026
  avcC: [],
14027
+ hvc1: [],
14028
+ hvcC: [],
13386
14029
  btrt: [],
13387
14030
  dinf: [],
13388
14031
  dref: [],
@@ -13810,8 +14453,10 @@
13810
14453
  return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track));
13811
14454
  }
13812
14455
  return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
13813
- } else {
14456
+ } else if (track.segmentCodec === 'avc') {
13814
14457
  return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
14458
+ } else {
14459
+ return MP4.box(MP4.types.stsd, MP4.STSD, MP4.hvc1(track));
13815
14460
  }
13816
14461
  };
13817
14462
  MP4.tkhd = function tkhd(track) {
@@ -13949,6 +14594,84 @@
13949
14594
  var result = appendUint8Array(MP4.FTYP, movie);
13950
14595
  return result;
13951
14596
  };
14597
+ MP4.hvc1 = function hvc1(track) {
14598
+ var ps = track.params;
14599
+ var units = [track.vps, track.sps, track.pps];
14600
+ var NALuLengthSize = 4;
14601
+ var config = new Uint8Array([0x01, ps.general_profile_space << 6 | (ps.general_tier_flag ? 32 : 0) | ps.general_profile_idc, ps.general_profile_compatibility_flags[0], ps.general_profile_compatibility_flags[1], ps.general_profile_compatibility_flags[2], ps.general_profile_compatibility_flags[3], ps.general_constraint_indicator_flags[0], ps.general_constraint_indicator_flags[1], ps.general_constraint_indicator_flags[2], ps.general_constraint_indicator_flags[3], ps.general_constraint_indicator_flags[4], ps.general_constraint_indicator_flags[5], ps.general_level_idc, 240 | ps.min_spatial_segmentation_idc >> 8, 255 & ps.min_spatial_segmentation_idc, 252 | ps.parallelismType, 252 | ps.chroma_format_idc, 248 | ps.bit_depth_luma_minus8, 248 | ps.bit_depth_chroma_minus8, 0x00, parseInt(ps.frame_rate.fps), NALuLengthSize - 1 | ps.temporal_id_nested << 2 | ps.num_temporal_layers << 3 | (ps.frame_rate.fixed ? 64 : 0), units.length]);
14602
+
14603
+ // compute hvcC size in bytes
14604
+ var length = config.length;
14605
+ for (var i = 0; i < units.length; i += 1) {
14606
+ length += 3;
14607
+ for (var j = 0; j < units[i].length; j += 1) {
14608
+ length += 2 + units[i][j].length;
14609
+ }
14610
+ }
14611
+ var hvcC = new Uint8Array(length);
14612
+ hvcC.set(config, 0);
14613
+ length = config.length;
14614
+ // append parameter set units: one vps, one or more sps and pps
14615
+ var iMax = units.length - 1;
14616
+ for (var _i = 0; _i < units.length; _i += 1) {
14617
+ hvcC.set(new Uint8Array([32 + _i | (_i === iMax ? 128 : 0), 0x00, units[_i].length]), length);
14618
+ length += 3;
14619
+ for (var _j = 0; _j < units[_i].length; _j += 1) {
14620
+ hvcC.set(new Uint8Array([units[_i][_j].length >> 8, units[_i][_j].length & 255]), length);
14621
+ length += 2;
14622
+ hvcC.set(units[_i][_j], length);
14623
+ length += units[_i][_j].length;
14624
+ }
14625
+ }
14626
+ var hvcc = MP4.box(MP4.types.hvcC, hvcC);
14627
+ var width = track.width;
14628
+ var height = track.height;
14629
+ var hSpacing = track.pixelRatio[0];
14630
+ var vSpacing = track.pixelRatio[1];
14631
+ return MP4.box(MP4.types.hvc1, new Uint8Array([0x00, 0x00, 0x00,
14632
+ // reserved
14633
+ 0x00, 0x00, 0x00,
14634
+ // reserved
14635
+ 0x00, 0x01,
14636
+ // data_reference_index
14637
+ 0x00, 0x00,
14638
+ // pre_defined
14639
+ 0x00, 0x00,
14640
+ // reserved
14641
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14642
+ // pre_defined
14643
+ width >> 8 & 0xff, width & 0xff,
14644
+ // width
14645
+ height >> 8 & 0xff, height & 0xff,
14646
+ // height
14647
+ 0x00, 0x48, 0x00, 0x00,
14648
+ // horizresolution
14649
+ 0x00, 0x48, 0x00, 0x00,
14650
+ // vertresolution
14651
+ 0x00, 0x00, 0x00, 0x00,
14652
+ // reserved
14653
+ 0x00, 0x01,
14654
+ // frame_count
14655
+ 0x12, 0x64, 0x61, 0x69, 0x6c,
14656
+ // dailymotion/hls.js
14657
+ 0x79, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x68, 0x6c, 0x73, 0x2e, 0x6a, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14658
+ // compressorname
14659
+ 0x00, 0x18,
14660
+ // depth = 24
14661
+ 0x11, 0x11]),
14662
+ // pre_defined = -1
14663
+ hvcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80,
14664
+ // bufferSizeDB
14665
+ 0x00, 0x2d, 0xc6, 0xc0,
14666
+ // maxBitrate
14667
+ 0x00, 0x2d, 0xc6, 0xc0])),
14668
+ // avgBitrate
14669
+ MP4.box(MP4.types.pasp, new Uint8Array([hSpacing >> 24,
14670
+ // hSpacing
14671
+ hSpacing >> 16 & 0xff, hSpacing >> 8 & 0xff, hSpacing & 0xff, vSpacing >> 24,
14672
+ // vSpacing
14673
+ vSpacing >> 16 & 0xff, vSpacing >> 8 & 0xff, vSpacing & 0xff])));
14674
+ };
13952
14675
  return MP4;
13953
14676
  }();
13954
14677
  MP4.types = void 0;
@@ -14350,9 +15073,9 @@
14350
15073
  var foundOverlap = delta < -1;
14351
15074
  if (foundHole || foundOverlap) {
14352
15075
  if (foundHole) {
14353
- logger.warn("AVC: " + toMsFromMpegTsClock(delta, true) + " ms (" + delta + "dts) hole between fragments detected at " + timeOffset.toFixed(3));
15076
+ logger.warn((track.segmentCodec || '').toUpperCase() + ": " + toMsFromMpegTsClock(delta, true) + " ms (" + delta + "dts) hole between fragments detected at " + timeOffset.toFixed(3));
14354
15077
  } else {
14355
- logger.warn("AVC: " + toMsFromMpegTsClock(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected at " + timeOffset.toFixed(3));
15078
+ logger.warn((track.segmentCodec || '').toUpperCase() + ": " + toMsFromMpegTsClock(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected at " + timeOffset.toFixed(3));
14356
15079
  }
14357
15080
  if (!foundOverlap || nextAvcDts >= inputSamples[0].pts || chromeVersion) {
14358
15081
  firstDTS = nextAvcDts;
@@ -14526,7 +15249,7 @@
14526
15249
  }
14527
15250
  }
14528
15251
  }
14529
- // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
15252
+ // next AVC/HEVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
14530
15253
  mp4SampleDuration = stretchedLastFrame || !mp4SampleDuration ? averageSampleDuration : mp4SampleDuration;
14531
15254
  this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration;
14532
15255
  this.videoSampleDuration = mp4SampleDuration;
@@ -16505,12 +17228,13 @@
16505
17228
  trackId = this.trackId;
16506
17229
  var config = hls.config;
16507
17230
 
16508
- // 1. if video not attached AND
17231
+ // 1. if buffering is suspended
17232
+ // 2. if video not attached AND
16509
17233
  // start fragment already requested OR start frag prefetch not enabled
16510
- // 2. if tracks or track not loaded and selected
17234
+ // 3. if tracks or track not loaded and selected
16511
17235
  // then exit loop
16512
17236
  // => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
16513
- if (!media && (this.startFragRequested || !config.startFragPrefetch) || !(levels != null && levels[trackId])) {
17237
+ if (!this.buffering || !media && (this.startFragRequested || !config.startFragPrefetch) || !(levels != null && levels[trackId])) {
16514
17238
  return;
16515
17239
  }
16516
17240
  var levelInfo = levels[trackId];
@@ -18536,6 +19260,7 @@
18536
19260
  _this2.resetBuffer(type);
18537
19261
  });
18538
19262
  this._initSourceBuffer();
19263
+ this.hls.resumeBuffering();
18539
19264
  };
18540
19265
  _proto.resetBuffer = function resetBuffer(type) {
18541
19266
  var sb = this.sourceBuffer[type];
@@ -27494,7 +28219,7 @@
27494
28219
  if (this.altAudio && this.audioOnly) {
27495
28220
  return;
27496
28221
  }
27497
- if (!(levels != null && levels[level])) {
28222
+ if (!this.buffering || !(levels != null && levels[level])) {
27498
28223
  return;
27499
28224
  }
27500
28225
  var levelInfo = levels[level];
@@ -28472,7 +29197,6 @@
28472
29197
  this.logger = void 0;
28473
29198
  this.coreComponents = void 0;
28474
29199
  this.networkControllers = void 0;
28475
- this.started = false;
28476
29200
  this._emitter = new EventEmitter();
28477
29201
  this._autoLevelCapping = -1;
28478
29202
  this._maxHdcpLevel = null;
@@ -28703,7 +29427,6 @@
28703
29427
  startPosition = -1;
28704
29428
  }
28705
29429
  this.logger.log("startLoad(" + startPosition + ")");
28706
- this.started = true;
28707
29430
  this.networkControllers.forEach(function (controller) {
28708
29431
  controller.startLoad(startPosition);
28709
29432
  });
@@ -28714,33 +29437,30 @@
28714
29437
  */;
28715
29438
  _proto.stopLoad = function stopLoad() {
28716
29439
  this.logger.log('stopLoad');
28717
- this.started = false;
28718
29440
  this.networkControllers.forEach(function (controller) {
28719
29441
  controller.stopLoad();
28720
29442
  });
28721
29443
  }
28722
29444
 
28723
29445
  /**
28724
- * Resumes stream controller segment loading if previously started.
29446
+ * Resumes stream controller segment loading after `pauseBuffering` has been called.
28725
29447
  */;
28726
29448
  _proto.resumeBuffering = function resumeBuffering() {
28727
- if (this.started) {
28728
- this.networkControllers.forEach(function (controller) {
28729
- if ('fragmentLoader' in controller) {
28730
- controller.startLoad(-1);
28731
- }
28732
- });
28733
- }
29449
+ this.networkControllers.forEach(function (controller) {
29450
+ if (controller.resumeBuffering) {
29451
+ controller.resumeBuffering();
29452
+ }
29453
+ });
28734
29454
  }
28735
29455
 
28736
29456
  /**
28737
- * Stops stream controller segment loading without changing 'started' state like stopLoad().
29457
+ * Prevents stream controller from loading new segments until `resumeBuffering` is called.
28738
29458
  * This allows for media buffering to be paused without interupting playlist loading.
28739
29459
  */;
28740
29460
  _proto.pauseBuffering = function pauseBuffering() {
28741
29461
  this.networkControllers.forEach(function (controller) {
28742
- if ('fragmentLoader' in controller) {
28743
- controller.stopLoad();
29462
+ if (controller.pauseBuffering) {
29463
+ controller.pauseBuffering();
28744
29464
  }
28745
29465
  });
28746
29466
  }
@@ -29297,7 +30017,7 @@
29297
30017
  * Get the video-dev/hls.js package version.
29298
30018
  */
29299
30019
  function get() {
29300
- return "1.5.2-0.canary.9969";
30020
+ return "1.5.2-0.canary.9971";
29301
30021
  }
29302
30022
  }, {
29303
30023
  key: "Events",