hls.js 1.5.2-0.canary.9970 → 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.light.js CHANGED
@@ -525,7 +525,7 @@
525
525
  // Some browsers don't allow to use bind on console object anyway
526
526
  // fallback to default if needed
527
527
  try {
528
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.2-0.canary.9970");
528
+ newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.2-0.canary.9971");
529
529
  } catch (e) {
530
530
  /* log fn threw an exception. All logger methods are no-ops. */
531
531
  return createLogger();
@@ -14390,6 +14390,110 @@
14390
14390
  logger.log(VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug);
14391
14391
  }
14392
14392
  };
14393
+ _proto.parseNALu = function parseNALu(track, array) {
14394
+ var len = array.byteLength;
14395
+ var state = track.naluState || 0;
14396
+ var lastState = state;
14397
+ var units = [];
14398
+ var i = 0;
14399
+ var value;
14400
+ var overflow;
14401
+ var unitType;
14402
+ var lastUnitStart = -1;
14403
+ var lastUnitType = 0;
14404
+ // logger.log('PES:' + Hex.hexDump(array));
14405
+
14406
+ if (state === -1) {
14407
+ // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
14408
+ lastUnitStart = 0;
14409
+ // NALu type is value read from offset 0
14410
+ lastUnitType = this.getNALuType(array, 0);
14411
+ state = 0;
14412
+ i = 1;
14413
+ }
14414
+ while (i < len) {
14415
+ value = array[i++];
14416
+ // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
14417
+ if (!state) {
14418
+ state = value ? 0 : 1;
14419
+ continue;
14420
+ }
14421
+ if (state === 1) {
14422
+ state = value ? 0 : 2;
14423
+ continue;
14424
+ }
14425
+ // here we have state either equal to 2 or 3
14426
+ if (!value) {
14427
+ state = 3;
14428
+ } else if (value === 1) {
14429
+ overflow = i - state - 1;
14430
+ if (lastUnitStart >= 0) {
14431
+ var unit = {
14432
+ data: array.subarray(lastUnitStart, overflow),
14433
+ type: lastUnitType
14434
+ };
14435
+ // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
14436
+ units.push(unit);
14437
+ } else {
14438
+ // lastUnitStart is undefined => this is the first start code found in this PES packet
14439
+ // first check if start code delimiter is overlapping between 2 PES packets,
14440
+ // ie it started in last packet (lastState not zero)
14441
+ // and ended at the beginning of this PES packet (i <= 4 - lastState)
14442
+ var lastUnit = this.getLastNalUnit(track.samples);
14443
+ if (lastUnit) {
14444
+ if (lastState && i <= 4 - lastState) {
14445
+ // start delimiter overlapping between PES packets
14446
+ // strip start delimiter bytes from the end of last NAL unit
14447
+ // check if lastUnit had a state different from zero
14448
+ if (lastUnit.state) {
14449
+ // strip last bytes
14450
+ lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
14451
+ }
14452
+ }
14453
+ // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
14454
+
14455
+ if (overflow > 0) {
14456
+ // logger.log('first NALU found with overflow:' + overflow);
14457
+ lastUnit.data = appendUint8Array(lastUnit.data, array.subarray(0, overflow));
14458
+ lastUnit.state = 0;
14459
+ }
14460
+ }
14461
+ }
14462
+ // check if we can read unit type
14463
+ if (i < len) {
14464
+ unitType = this.getNALuType(array, i);
14465
+ // logger.log('find NALU @ offset:' + i + ',type:' + unitType);
14466
+ lastUnitStart = i;
14467
+ lastUnitType = unitType;
14468
+ state = 0;
14469
+ } else {
14470
+ // not enough byte to read unit type. let's read it on next PES parsing
14471
+ state = -1;
14472
+ }
14473
+ } else {
14474
+ state = 0;
14475
+ }
14476
+ }
14477
+ if (lastUnitStart >= 0 && state >= 0) {
14478
+ var _unit = {
14479
+ data: array.subarray(lastUnitStart, len),
14480
+ type: lastUnitType,
14481
+ state: state
14482
+ };
14483
+ units.push(_unit);
14484
+ // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
14485
+ }
14486
+ // no NALu found
14487
+ if (units.length === 0) {
14488
+ // append pes.data to previous NAL unit
14489
+ var _lastUnit = this.getLastNalUnit(track.samples);
14490
+ if (_lastUnit) {
14491
+ _lastUnit.data = appendUint8Array(_lastUnit.data, array);
14492
+ }
14493
+ }
14494
+ track.naluState = state;
14495
+ return units;
14496
+ };
14393
14497
  return BaseVideoParser;
14394
14498
  }();
14395
14499
 
@@ -14544,22 +14648,179 @@
14544
14648
  ;
14545
14649
  _proto.readUInt = function readUInt() {
14546
14650
  return this.readBits(32);
14651
+ };
14652
+ return ExpGolomb;
14653
+ }();
14654
+
14655
+ var AvcVideoParser = /*#__PURE__*/function (_BaseVideoParser) {
14656
+ _inheritsLoose(AvcVideoParser, _BaseVideoParser);
14657
+ function AvcVideoParser() {
14658
+ return _BaseVideoParser.apply(this, arguments) || this;
14659
+ }
14660
+ var _proto = AvcVideoParser.prototype;
14661
+ _proto.parsePES = function parsePES(track, textTrack, pes, last, duration) {
14662
+ var _this = this;
14663
+ var units = this.parseNALu(track, pes.data);
14664
+ var VideoSample = this.VideoSample;
14665
+ var push;
14666
+ var spsfound = false;
14667
+ // free pes.data to save up some memory
14668
+ pes.data = null;
14669
+
14670
+ // if new NAL units found and last sample still there, let's push ...
14671
+ // this helps parsing streams with missing AUD (only do this if AUD never found)
14672
+ if (VideoSample && units.length && !track.audFound) {
14673
+ this.pushAccessUnit(VideoSample, track);
14674
+ VideoSample = this.VideoSample = this.createVideoSample(false, pes.pts, pes.dts, '');
14675
+ }
14676
+ units.forEach(function (unit) {
14677
+ var _VideoSample2;
14678
+ switch (unit.type) {
14679
+ // NDR
14680
+ case 1:
14681
+ {
14682
+ var iskey = false;
14683
+ push = true;
14684
+ var data = unit.data;
14685
+ // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
14686
+ if (spsfound && data.length > 4) {
14687
+ // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
14688
+ var sliceType = _this.readSliceType(data);
14689
+ // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
14690
+ // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
14691
+ // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
14692
+ // I slice: A slice that is not an SI slice that is decoded using intra prediction only.
14693
+ // if (sliceType === 2 || sliceType === 7) {
14694
+ if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
14695
+ iskey = true;
14696
+ }
14697
+ }
14698
+ if (iskey) {
14699
+ var _VideoSample;
14700
+ // if we have non-keyframe data already, that cannot belong to the same frame as a keyframe, so force a push
14701
+ if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
14702
+ _this.pushAccessUnit(VideoSample, track);
14703
+ VideoSample = _this.VideoSample = null;
14704
+ }
14705
+ }
14706
+ if (!VideoSample) {
14707
+ VideoSample = _this.VideoSample = _this.createVideoSample(true, pes.pts, pes.dts, '');
14708
+ }
14709
+ VideoSample.frame = true;
14710
+ VideoSample.key = iskey;
14711
+ break;
14712
+ // IDR
14713
+ }
14714
+ case 5:
14715
+ push = true;
14716
+ // handle PES not starting with AUD
14717
+ // if we have frame data already, that cannot belong to the same frame, so force a push
14718
+ if ((_VideoSample2 = VideoSample) != null && _VideoSample2.frame && !VideoSample.key) {
14719
+ _this.pushAccessUnit(VideoSample, track);
14720
+ VideoSample = _this.VideoSample = null;
14721
+ }
14722
+ if (!VideoSample) {
14723
+ VideoSample = _this.VideoSample = _this.createVideoSample(true, pes.pts, pes.dts, '');
14724
+ }
14725
+ VideoSample.key = true;
14726
+ VideoSample.frame = true;
14727
+ break;
14728
+ // SEI
14729
+ case 6:
14730
+ {
14731
+ push = true;
14732
+ parseSEIMessageFromNALu(unit.data, 1, pes.pts, textTrack.samples);
14733
+ break;
14734
+ // SPS
14735
+ }
14736
+ case 7:
14737
+ {
14738
+ var _track$pixelRatio, _track$pixelRatio2;
14739
+ push = true;
14740
+ spsfound = true;
14741
+ var sps = unit.data;
14742
+ var config = _this.readSPS(sps);
14743
+ 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]) {
14744
+ track.width = config.width;
14745
+ track.height = config.height;
14746
+ track.pixelRatio = config.pixelRatio;
14747
+ track.sps = [sps];
14748
+ track.duration = duration;
14749
+ var codecarray = sps.subarray(1, 4);
14750
+ var codecstring = 'avc1.';
14751
+ for (var i = 0; i < 3; i++) {
14752
+ var h = codecarray[i].toString(16);
14753
+ if (h.length < 2) {
14754
+ h = '0' + h;
14755
+ }
14756
+ codecstring += h;
14757
+ }
14758
+ track.codec = codecstring;
14759
+ }
14760
+ break;
14761
+ }
14762
+ // PPS
14763
+ case 8:
14764
+ push = true;
14765
+ track.pps = [unit.data];
14766
+ break;
14767
+ // AUD
14768
+ case 9:
14769
+ push = true;
14770
+ track.audFound = true;
14771
+ if (VideoSample) {
14772
+ _this.pushAccessUnit(VideoSample, track);
14773
+ }
14774
+ VideoSample = _this.VideoSample = _this.createVideoSample(false, pes.pts, pes.dts, '');
14775
+ break;
14776
+ // Filler Data
14777
+ case 12:
14778
+ push = true;
14779
+ break;
14780
+ default:
14781
+ push = false;
14782
+ if (VideoSample) {
14783
+ VideoSample.debug += 'unknown NAL ' + unit.type + ' ';
14784
+ }
14785
+ break;
14786
+ }
14787
+ if (VideoSample && push) {
14788
+ var _units = VideoSample.units;
14789
+ _units.push(unit);
14790
+ }
14791
+ });
14792
+ // if last PES packet, push samples
14793
+ if (last && VideoSample) {
14794
+ this.pushAccessUnit(VideoSample, track);
14795
+ this.VideoSample = null;
14796
+ }
14797
+ };
14798
+ _proto.getNALuType = function getNALuType(data, offset) {
14799
+ return data[offset] & 0x1f;
14800
+ };
14801
+ _proto.readSliceType = function readSliceType(data) {
14802
+ var eg = new ExpGolomb(data);
14803
+ // skip NALu type
14804
+ eg.readUByte();
14805
+ // discard first_mb_in_slice
14806
+ eg.readUEG();
14807
+ // return slice_type
14808
+ return eg.readUEG();
14547
14809
  }
14548
14810
 
14549
14811
  /**
14550
- * Advance the ExpGolomb decoder past a scaling list. The scaling
14551
- * list is optionally transmitted as part of a sequence parameter
14812
+ * The scaling list is optionally transmitted as part of a sequence parameter
14552
14813
  * set and is not relevant to transmuxing.
14553
14814
  * @param count the number of entries in this scaling list
14554
14815
  * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
14555
14816
  */;
14556
- _proto.skipScalingList = function skipScalingList(count) {
14817
+ _proto.skipScalingList = function skipScalingList(count, reader) {
14557
14818
  var lastScale = 8;
14558
14819
  var nextScale = 8;
14559
14820
  var deltaScale;
14560
14821
  for (var j = 0; j < count; j++) {
14561
14822
  if (nextScale !== 0) {
14562
- deltaScale = this.readEG();
14823
+ deltaScale = reader.readEG();
14563
14824
  nextScale = (lastScale + deltaScale + 256) % 256;
14564
14825
  }
14565
14826
  lastScale = nextScale === 0 ? lastScale : nextScale;
@@ -14574,7 +14835,8 @@
14574
14835
  * sequence parameter set, including the dimensions of the
14575
14836
  * associated video frames.
14576
14837
  */;
14577
- _proto.readSPS = function readSPS() {
14838
+ _proto.readSPS = function readSPS(sps) {
14839
+ var eg = new ExpGolomb(sps);
14578
14840
  var frameCropLeftOffset = 0;
14579
14841
  var frameCropRightOffset = 0;
14580
14842
  var frameCropTopOffset = 0;
@@ -14582,13 +14844,13 @@
14582
14844
  var numRefFramesInPicOrderCntCycle;
14583
14845
  var scalingListCount;
14584
14846
  var i;
14585
- var readUByte = this.readUByte.bind(this);
14586
- var readBits = this.readBits.bind(this);
14587
- var readUEG = this.readUEG.bind(this);
14588
- var readBoolean = this.readBoolean.bind(this);
14589
- var skipBits = this.skipBits.bind(this);
14590
- var skipEG = this.skipEG.bind(this);
14591
- var skipUEG = this.skipUEG.bind(this);
14847
+ var readUByte = eg.readUByte.bind(eg);
14848
+ var readBits = eg.readBits.bind(eg);
14849
+ var readUEG = eg.readUEG.bind(eg);
14850
+ var readBoolean = eg.readBoolean.bind(eg);
14851
+ var skipBits = eg.skipBits.bind(eg);
14852
+ var skipEG = eg.skipEG.bind(eg);
14853
+ var skipUEG = eg.skipUEG.bind(eg);
14592
14854
  var skipScalingList = this.skipScalingList.bind(this);
14593
14855
  readUByte();
14594
14856
  var profileIdc = readUByte(); // profile_idc
@@ -14613,9 +14875,9 @@
14613
14875
  if (readBoolean()) {
14614
14876
  // seq_scaling_list_present_flag[ i ]
14615
14877
  if (i < 6) {
14616
- skipScalingList(16);
14878
+ skipScalingList(16, eg);
14617
14879
  } else {
14618
- skipScalingList(64);
14880
+ skipScalingList(64, eg);
14619
14881
  }
14620
14882
  }
14621
14883
  }
@@ -14720,26 +14982,24 @@
14720
14982
  pixelRatio: pixelRatio
14721
14983
  };
14722
14984
  };
14723
- _proto.readSliceType = function readSliceType() {
14724
- // skip NALu type
14725
- this.readUByte();
14726
- // discard first_mb_in_slice
14727
- this.readUEG();
14728
- // return slice_type
14729
- return this.readUEG();
14730
- };
14731
- return ExpGolomb;
14732
- }();
14985
+ return AvcVideoParser;
14986
+ }(BaseVideoParser);
14733
14987
 
14734
- var AvcVideoParser = /*#__PURE__*/function (_BaseVideoParser) {
14735
- _inheritsLoose(AvcVideoParser, _BaseVideoParser);
14736
- function AvcVideoParser() {
14737
- return _BaseVideoParser.apply(this, arguments) || this;
14988
+ var HevcVideoParser = /*#__PURE__*/function (_BaseVideoParser) {
14989
+ _inheritsLoose(HevcVideoParser, _BaseVideoParser);
14990
+ function HevcVideoParser() {
14991
+ var _this;
14992
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
14993
+ args[_key] = arguments[_key];
14994
+ }
14995
+ _this = _BaseVideoParser.call.apply(_BaseVideoParser, [this].concat(args)) || this;
14996
+ _this.initVPS = null;
14997
+ return _this;
14738
14998
  }
14739
- var _proto = AvcVideoParser.prototype;
14740
- _proto.parseAVCPES = function parseAVCPES(track, textTrack, pes, last, duration) {
14741
- var _this = this;
14742
- var units = this.parseAVCNALu(track, pes.data);
14999
+ var _proto = HevcVideoParser.prototype;
15000
+ _proto.parsePES = function parsePES(track, textTrack, pes, last, duration) {
15001
+ var _this2 = this;
15002
+ var units = this.parseNALu(track, pes.data);
14743
15003
  var VideoSample = this.VideoSample;
14744
15004
  var push;
14745
15005
  var spsfound = false;
@@ -14755,112 +15015,143 @@
14755
15015
  units.forEach(function (unit) {
14756
15016
  var _VideoSample2;
14757
15017
  switch (unit.type) {
14758
- // NDR
15018
+ // NON-IDR, NON RANDOM ACCESS SLICE
15019
+ case 0:
14759
15020
  case 1:
14760
- {
14761
- var iskey = false;
14762
- push = true;
14763
- var data = unit.data;
14764
- // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
14765
- if (spsfound && data.length > 4) {
14766
- // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
14767
- var sliceType = new ExpGolomb(data).readSliceType();
14768
- // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
14769
- // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
14770
- // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
14771
- // I slice: A slice that is not an SI slice that is decoded using intra prediction only.
14772
- // if (sliceType === 2 || sliceType === 7) {
14773
- if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
14774
- iskey = true;
14775
- }
14776
- }
14777
- if (iskey) {
14778
- var _VideoSample;
14779
- // if we have non-keyframe data already, that cannot belong to the same frame as a keyframe, so force a push
14780
- if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
14781
- _this.pushAccessUnit(VideoSample, track);
14782
- VideoSample = _this.VideoSample = null;
14783
- }
14784
- }
14785
- if (!VideoSample) {
14786
- VideoSample = _this.VideoSample = _this.createVideoSample(true, pes.pts, pes.dts, '');
15021
+ case 2:
15022
+ case 3:
15023
+ case 4:
15024
+ case 5:
15025
+ case 6:
15026
+ case 7:
15027
+ case 8:
15028
+ case 9:
15029
+ if (!VideoSample) {
15030
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(false, pes.pts, pes.dts, '');
15031
+ }
15032
+ VideoSample.frame = true;
15033
+ push = true;
15034
+ break;
15035
+
15036
+ // CRA, BLA (random access picture)
15037
+ case 16:
15038
+ case 17:
15039
+ case 18:
15040
+ case 21:
15041
+ push = true;
15042
+ if (spsfound) {
15043
+ var _VideoSample;
15044
+ // handle PES not starting with AUD
15045
+ // if we have frame data already, that cannot belong to the same frame, so force a push
15046
+ if ((_VideoSample = VideoSample) != null && _VideoSample.frame && !VideoSample.key) {
15047
+ _this2.pushAccessUnit(VideoSample, track);
15048
+ VideoSample = _this2.VideoSample = null;
14787
15049
  }
14788
- VideoSample.frame = true;
14789
- VideoSample.key = iskey;
14790
- break;
14791
- // IDR
14792
15050
  }
14793
- case 5:
15051
+ if (!VideoSample) {
15052
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(true, pes.pts, pes.dts, '');
15053
+ }
15054
+ VideoSample.key = true;
15055
+ VideoSample.frame = true;
15056
+ break;
15057
+
15058
+ // IDR
15059
+ case 19:
15060
+ case 20:
14794
15061
  push = true;
14795
15062
  // handle PES not starting with AUD
14796
15063
  // if we have frame data already, that cannot belong to the same frame, so force a push
14797
15064
  if ((_VideoSample2 = VideoSample) != null && _VideoSample2.frame && !VideoSample.key) {
14798
- _this.pushAccessUnit(VideoSample, track);
14799
- VideoSample = _this.VideoSample = null;
15065
+ _this2.pushAccessUnit(VideoSample, track);
15066
+ VideoSample = _this2.VideoSample = null;
14800
15067
  }
14801
15068
  if (!VideoSample) {
14802
- VideoSample = _this.VideoSample = _this.createVideoSample(true, pes.pts, pes.dts, '');
15069
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(true, pes.pts, pes.dts, '');
14803
15070
  }
14804
15071
  VideoSample.key = true;
14805
15072
  VideoSample.frame = true;
14806
15073
  break;
15074
+
14807
15075
  // SEI
14808
- case 6:
14809
- {
14810
- push = true;
14811
- parseSEIMessageFromNALu(unit.data, 1, pes.pts, textTrack.samples);
14812
- break;
14813
- // SPS
15076
+ case 39:
15077
+ push = true;
15078
+ parseSEIMessageFromNALu(unit.data, 2,
15079
+ // NALu header size
15080
+ pes.pts, textTrack.samples);
15081
+ break;
15082
+
15083
+ // VPS
15084
+ case 32:
15085
+ push = true;
15086
+ if (!track.vps) {
15087
+ var config = _this2.readVPS(unit.data);
15088
+ track.params = _objectSpread2({}, config);
15089
+ _this2.initVPS = unit.data;
14814
15090
  }
14815
- case 7:
14816
- {
14817
- var _track$pixelRatio, _track$pixelRatio2;
14818
- push = true;
14819
- spsfound = true;
14820
- var sps = unit.data;
14821
- var expGolombDecoder = new ExpGolomb(sps);
14822
- var config = expGolombDecoder.readSPS();
14823
- 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]) {
14824
- track.width = config.width;
14825
- track.height = config.height;
14826
- track.pixelRatio = config.pixelRatio;
14827
- track.sps = [sps];
15091
+ track.vps = [unit.data];
15092
+ break;
15093
+
15094
+ // SPS
15095
+ case 33:
15096
+ push = true;
15097
+ spsfound = true;
15098
+ if (typeof track.params === 'object') {
15099
+ if (track.vps !== undefined && track.vps[0] !== _this2.initVPS && track.sps !== undefined && !_this2.matchSPS(track.sps[0], unit.data)) {
15100
+ _this2.initVPS = track.vps[0];
15101
+ track.sps = track.pps = undefined;
15102
+ }
15103
+ if (!track.sps) {
15104
+ var _config = _this2.readSPS(unit.data);
15105
+ track.width = _config.width;
15106
+ track.height = _config.height;
15107
+ track.pixelRatio = _config.pixelRatio;
14828
15108
  track.duration = duration;
14829
- var codecarray = sps.subarray(1, 4);
14830
- var codecstring = 'avc1.';
14831
- for (var i = 0; i < 3; i++) {
14832
- var h = codecarray[i].toString(16);
14833
- if (h.length < 2) {
14834
- h = '0' + h;
14835
- }
14836
- codecstring += h;
15109
+ track.codec = _config.codecString;
15110
+ track.sps = [];
15111
+ for (var prop in _config.params) {
15112
+ track.params[prop] = _config.params[prop];
14837
15113
  }
14838
- track.codec = codecstring;
14839
15114
  }
14840
- break;
15115
+ if (track.vps !== undefined && track.vps[0] === _this2.initVPS) {
15116
+ track.sps.push(unit.data);
15117
+ }
15118
+ }
15119
+ if (!VideoSample) {
15120
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(true, pes.pts, pes.dts, '');
14841
15121
  }
15122
+ VideoSample.key = true;
15123
+ break;
15124
+
14842
15125
  // PPS
14843
- case 8:
15126
+ case 34:
14844
15127
  push = true;
14845
- track.pps = [unit.data];
15128
+ if (typeof track.params === 'object') {
15129
+ if (!track.pps) {
15130
+ track.pps = [];
15131
+ var _config2 = _this2.readPPS(unit.data);
15132
+ for (var _prop in _config2) {
15133
+ track.params[_prop] = _config2[_prop];
15134
+ }
15135
+ }
15136
+ if (_this2.initVPS !== null || track.pps.length === 0) {
15137
+ track.pps.push(unit.data);
15138
+ }
15139
+ }
14846
15140
  break;
14847
- // AUD
14848
- case 9:
15141
+
15142
+ // ACCESS UNIT DELIMITER
15143
+ case 35:
14849
15144
  push = true;
14850
15145
  track.audFound = true;
14851
15146
  if (VideoSample) {
14852
- _this.pushAccessUnit(VideoSample, track);
15147
+ _this2.pushAccessUnit(VideoSample, track);
14853
15148
  }
14854
- VideoSample = _this.VideoSample = _this.createVideoSample(false, pes.pts, pes.dts, '');
14855
- break;
14856
- // Filler Data
14857
- case 12:
14858
- push = true;
15149
+ VideoSample = _this2.VideoSample = _this2.createVideoSample(false, pes.pts, pes.dts, '');
14859
15150
  break;
14860
15151
  default:
14861
15152
  push = false;
14862
15153
  if (VideoSample) {
14863
- VideoSample.debug += 'unknown NAL ' + unit.type + ' ';
15154
+ VideoSample.debug += 'unknown or irrelevant NAL ' + unit.type + ' ';
14864
15155
  }
14865
15156
  break;
14866
15157
  }
@@ -14875,111 +15166,425 @@
14875
15166
  this.VideoSample = null;
14876
15167
  }
14877
15168
  };
14878
- _proto.parseAVCNALu = function parseAVCNALu(track, array) {
14879
- var len = array.byteLength;
14880
- var state = track.naluState || 0;
14881
- var lastState = state;
14882
- var units = [];
14883
- var i = 0;
14884
- var value;
14885
- var overflow;
14886
- var unitType;
14887
- var lastUnitStart = -1;
14888
- var lastUnitType = 0;
14889
- // logger.log('PES:' + Hex.hexDump(array));
14890
-
14891
- if (state === -1) {
14892
- // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
14893
- lastUnitStart = 0;
14894
- // NALu type is value read from offset 0
14895
- lastUnitType = array[0] & 0x1f;
14896
- state = 0;
14897
- i = 1;
14898
- }
14899
- while (i < len) {
14900
- value = array[i++];
14901
- // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
14902
- if (!state) {
14903
- state = value ? 0 : 1;
14904
- continue;
14905
- }
14906
- if (state === 1) {
14907
- state = value ? 0 : 2;
14908
- continue;
15169
+ _proto.getNALuType = function getNALuType(data, offset) {
15170
+ return (data[offset] & 0x7e) >>> 1;
15171
+ };
15172
+ _proto.ebsp2rbsp = function ebsp2rbsp(arr) {
15173
+ var dst = new Uint8Array(arr.byteLength);
15174
+ var dstIdx = 0;
15175
+ for (var i = 0; i < arr.byteLength; i++) {
15176
+ if (i >= 2) {
15177
+ // Unescape: Skip 0x03 after 00 00
15178
+ if (arr[i] === 0x03 && arr[i - 1] === 0x00 && arr[i - 2] === 0x00) {
15179
+ continue;
15180
+ }
14909
15181
  }
14910
- // here we have state either equal to 2 or 3
14911
- if (!value) {
14912
- state = 3;
14913
- } else if (value === 1) {
14914
- overflow = i - state - 1;
14915
- if (lastUnitStart >= 0) {
14916
- var unit = {
14917
- data: array.subarray(lastUnitStart, overflow),
14918
- type: lastUnitType
14919
- };
14920
- // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
14921
- units.push(unit);
14922
- } else {
14923
- // lastUnitStart is undefined => this is the first start code found in this PES packet
14924
- // first check if start code delimiter is overlapping between 2 PES packets,
14925
- // ie it started in last packet (lastState not zero)
14926
- // and ended at the beginning of this PES packet (i <= 4 - lastState)
14927
- var lastUnit = this.getLastNalUnit(track.samples);
14928
- if (lastUnit) {
14929
- if (lastState && i <= 4 - lastState) {
14930
- // start delimiter overlapping between PES packets
14931
- // strip start delimiter bytes from the end of last NAL unit
14932
- // check if lastUnit had a state different from zero
14933
- if (lastUnit.state) {
14934
- // strip last bytes
14935
- lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
14936
- }
14937
- }
14938
- // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
15182
+ dst[dstIdx] = arr[i];
15183
+ dstIdx++;
15184
+ }
15185
+ return new Uint8Array(dst.buffer, 0, dstIdx);
15186
+ };
15187
+ _proto.readVPS = function readVPS(vps) {
15188
+ var eg = new ExpGolomb(vps);
15189
+ // remove header
15190
+ eg.readUByte();
15191
+ eg.readUByte();
15192
+ eg.readBits(4); // video_parameter_set_id
15193
+ eg.skipBits(2);
15194
+ eg.readBits(6); // max_layers_minus1
15195
+ var max_sub_layers_minus1 = eg.readBits(3);
15196
+ var temporal_id_nesting_flag = eg.readBoolean();
15197
+ // ...vui fps can be here, but empty fps value is not critical for metadata
14939
15198
 
14940
- if (overflow > 0) {
14941
- // logger.log('first NALU found with overflow:' + overflow);
14942
- lastUnit.data = appendUint8Array(lastUnit.data, array.subarray(0, overflow));
14943
- lastUnit.state = 0;
15199
+ return {
15200
+ numTemporalLayers: max_sub_layers_minus1 + 1,
15201
+ temporalIdNested: temporal_id_nesting_flag
15202
+ };
15203
+ };
15204
+ _proto.readSPS = function readSPS(sps) {
15205
+ var eg = new ExpGolomb(this.ebsp2rbsp(sps));
15206
+ eg.readUByte();
15207
+ eg.readUByte();
15208
+ eg.readBits(4); //video_parameter_set_id
15209
+ var max_sub_layers_minus1 = eg.readBits(3);
15210
+ eg.readBoolean(); // temporal_id_nesting_flag
15211
+
15212
+ // profile_tier_level
15213
+ var general_profile_space = eg.readBits(2);
15214
+ var general_tier_flag = eg.readBoolean();
15215
+ var general_profile_idc = eg.readBits(5);
15216
+ var general_profile_compatibility_flags_1 = eg.readUByte();
15217
+ var general_profile_compatibility_flags_2 = eg.readUByte();
15218
+ var general_profile_compatibility_flags_3 = eg.readUByte();
15219
+ var general_profile_compatibility_flags_4 = eg.readUByte();
15220
+ var general_constraint_indicator_flags_1 = eg.readUByte();
15221
+ var general_constraint_indicator_flags_2 = eg.readUByte();
15222
+ var general_constraint_indicator_flags_3 = eg.readUByte();
15223
+ var general_constraint_indicator_flags_4 = eg.readUByte();
15224
+ var general_constraint_indicator_flags_5 = eg.readUByte();
15225
+ var general_constraint_indicator_flags_6 = eg.readUByte();
15226
+ var general_level_idc = eg.readUByte();
15227
+ var sub_layer_profile_present_flags = [];
15228
+ var sub_layer_level_present_flags = [];
15229
+ for (var i = 0; i < max_sub_layers_minus1; i++) {
15230
+ sub_layer_profile_present_flags.push(eg.readBoolean());
15231
+ sub_layer_level_present_flags.push(eg.readBoolean());
15232
+ }
15233
+ if (max_sub_layers_minus1 > 0) {
15234
+ for (var _i = max_sub_layers_minus1; _i < 8; _i++) {
15235
+ eg.readBits(2);
15236
+ }
15237
+ }
15238
+ for (var _i2 = 0; _i2 < max_sub_layers_minus1; _i2++) {
15239
+ if (sub_layer_profile_present_flags[_i2]) {
15240
+ eg.readUByte(); // sub_layer_profile_space, sub_layer_tier_flag, sub_layer_profile_idc
15241
+ eg.readUByte();
15242
+ eg.readUByte();
15243
+ eg.readUByte();
15244
+ eg.readUByte(); // sub_layer_profile_compatibility_flag
15245
+ eg.readUByte();
15246
+ eg.readUByte();
15247
+ eg.readUByte();
15248
+ eg.readUByte();
15249
+ eg.readUByte();
15250
+ eg.readUByte();
15251
+ }
15252
+ if (sub_layer_level_present_flags[_i2]) {
15253
+ eg.readUByte();
15254
+ }
15255
+ }
15256
+ eg.readUEG(); // seq_parameter_set_id
15257
+ var chroma_format_idc = eg.readUEG();
15258
+ if (chroma_format_idc == 3) {
15259
+ eg.skipBits(1); //separate_colour_plane_flag
15260
+ }
15261
+ var pic_width_in_luma_samples = eg.readUEG();
15262
+ var pic_height_in_luma_samples = eg.readUEG();
15263
+ var conformance_window_flag = eg.readBoolean();
15264
+ var pic_left_offset = 0,
15265
+ pic_right_offset = 0,
15266
+ pic_top_offset = 0,
15267
+ pic_bottom_offset = 0;
15268
+ if (conformance_window_flag) {
15269
+ pic_left_offset += eg.readUEG();
15270
+ pic_right_offset += eg.readUEG();
15271
+ pic_top_offset += eg.readUEG();
15272
+ pic_bottom_offset += eg.readUEG();
15273
+ }
15274
+ var bit_depth_luma_minus8 = eg.readUEG();
15275
+ var bit_depth_chroma_minus8 = eg.readUEG();
15276
+ var log2_max_pic_order_cnt_lsb_minus4 = eg.readUEG();
15277
+ var sub_layer_ordering_info_present_flag = eg.readBoolean();
15278
+ for (var _i3 = sub_layer_ordering_info_present_flag ? 0 : max_sub_layers_minus1; _i3 <= max_sub_layers_minus1; _i3++) {
15279
+ eg.skipUEG(); // max_dec_pic_buffering_minus1[i]
15280
+ eg.skipUEG(); // max_num_reorder_pics[i]
15281
+ eg.skipUEG(); // max_latency_increase_plus1[i]
15282
+ }
15283
+ eg.skipUEG(); // log2_min_luma_coding_block_size_minus3
15284
+ eg.skipUEG(); // log2_diff_max_min_luma_coding_block_size
15285
+ eg.skipUEG(); // log2_min_transform_block_size_minus2
15286
+ eg.skipUEG(); // log2_diff_max_min_transform_block_size
15287
+ eg.skipUEG(); // max_transform_hierarchy_depth_inter
15288
+ eg.skipUEG(); // max_transform_hierarchy_depth_intra
15289
+ var scaling_list_enabled_flag = eg.readBoolean();
15290
+ if (scaling_list_enabled_flag) {
15291
+ var sps_scaling_list_data_present_flag = eg.readBoolean();
15292
+ if (sps_scaling_list_data_present_flag) {
15293
+ for (var sizeId = 0; sizeId < 4; sizeId++) {
15294
+ for (var matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {
15295
+ var scaling_list_pred_mode_flag = eg.readBoolean();
15296
+ if (!scaling_list_pred_mode_flag) {
15297
+ eg.readUEG(); // scaling_list_pred_matrix_id_delta
15298
+ } else {
15299
+ var coefNum = Math.min(64, 1 << 4 + (sizeId << 1));
15300
+ if (sizeId > 1) {
15301
+ eg.readEG();
15302
+ }
15303
+ for (var _i4 = 0; _i4 < coefNum; _i4++) {
15304
+ eg.readEG();
15305
+ }
14944
15306
  }
14945
15307
  }
14946
15308
  }
14947
- // check if we can read unit type
14948
- if (i < len) {
14949
- unitType = array[i] & 0x1f;
14950
- // logger.log('find NALU @ offset:' + i + ',type:' + unitType);
14951
- lastUnitStart = i;
14952
- lastUnitType = unitType;
14953
- state = 0;
14954
- } else {
14955
- // not enough byte to read unit type. let's read it on next PES parsing
14956
- state = -1;
15309
+ }
15310
+ }
15311
+ eg.readBoolean(); // amp_enabled_flag
15312
+ eg.readBoolean(); // sample_adaptive_offset_enabled_flag
15313
+ var pcm_enabled_flag = eg.readBoolean();
15314
+ if (pcm_enabled_flag) {
15315
+ eg.readUByte();
15316
+ eg.skipUEG();
15317
+ eg.skipUEG();
15318
+ eg.readBoolean();
15319
+ }
15320
+ var num_short_term_ref_pic_sets = eg.readUEG();
15321
+ var num_delta_pocs = 0;
15322
+ for (var _i5 = 0; _i5 < num_short_term_ref_pic_sets; _i5++) {
15323
+ var inter_ref_pic_set_prediction_flag = false;
15324
+ if (_i5 !== 0) {
15325
+ inter_ref_pic_set_prediction_flag = eg.readBoolean();
15326
+ }
15327
+ if (inter_ref_pic_set_prediction_flag) {
15328
+ if (_i5 === num_short_term_ref_pic_sets) {
15329
+ eg.readUEG();
15330
+ }
15331
+ eg.readBoolean();
15332
+ eg.readUEG();
15333
+ var next_num_delta_pocs = 0;
15334
+ for (var j = 0; j <= num_delta_pocs; j++) {
15335
+ var used_by_curr_pic_flag = eg.readBoolean();
15336
+ var use_delta_flag = false;
15337
+ if (!used_by_curr_pic_flag) {
15338
+ use_delta_flag = eg.readBoolean();
15339
+ }
15340
+ if (used_by_curr_pic_flag || use_delta_flag) {
15341
+ next_num_delta_pocs++;
15342
+ }
14957
15343
  }
15344
+ num_delta_pocs = next_num_delta_pocs;
14958
15345
  } else {
14959
- state = 0;
15346
+ var num_negative_pics = eg.readUEG();
15347
+ var num_positive_pics = eg.readUEG();
15348
+ num_delta_pocs = num_negative_pics + num_positive_pics;
15349
+ for (var _j = 0; _j < num_negative_pics; _j++) {
15350
+ eg.readUEG();
15351
+ eg.readBoolean();
15352
+ }
15353
+ for (var _j2 = 0; _j2 < num_positive_pics; _j2++) {
15354
+ eg.readUEG();
15355
+ eg.readBoolean();
15356
+ }
14960
15357
  }
14961
15358
  }
14962
- if (lastUnitStart >= 0 && state >= 0) {
14963
- var _unit = {
14964
- data: array.subarray(lastUnitStart, len),
14965
- type: lastUnitType,
14966
- state: state
14967
- };
14968
- units.push(_unit);
14969
- // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
14970
- }
14971
- // no NALu found
14972
- if (units.length === 0) {
14973
- // append pes.data to previous NAL unit
14974
- var _lastUnit = this.getLastNalUnit(track.samples);
14975
- if (_lastUnit) {
14976
- _lastUnit.data = appendUint8Array(_lastUnit.data, array);
15359
+ var long_term_ref_pics_present_flag = eg.readBoolean();
15360
+ if (long_term_ref_pics_present_flag) {
15361
+ var num_long_term_ref_pics_sps = eg.readUEG();
15362
+ for (var _i6 = 0; _i6 < num_long_term_ref_pics_sps; _i6++) {
15363
+ for (var _j3 = 0; _j3 < log2_max_pic_order_cnt_lsb_minus4 + 4; _j3++) {
15364
+ eg.readBits(1);
15365
+ }
15366
+ eg.readBits(1);
15367
+ }
15368
+ }
15369
+ var min_spatial_segmentation_idc = 0;
15370
+ var sar_width = 1,
15371
+ sar_height = 1;
15372
+ var fps_fixed = true,
15373
+ fps_den = 1,
15374
+ fps_num = 0;
15375
+ eg.readBoolean(); // sps_temporal_mvp_enabled_flag
15376
+ eg.readBoolean(); // strong_intra_smoothing_enabled_flag
15377
+ var default_display_window_flag = false;
15378
+ var vui_parameters_present_flag = eg.readBoolean();
15379
+ if (vui_parameters_present_flag) {
15380
+ var aspect_ratio_info_present_flag = eg.readBoolean();
15381
+ if (aspect_ratio_info_present_flag) {
15382
+ var aspect_ratio_idc = eg.readUByte();
15383
+ var sar_width_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];
15384
+ var sar_height_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];
15385
+ if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
15386
+ sar_width = sar_width_table[aspect_ratio_idc - 1];
15387
+ sar_height = sar_height_table[aspect_ratio_idc - 1];
15388
+ } else if (aspect_ratio_idc === 255) {
15389
+ sar_width = eg.readBits(16);
15390
+ sar_height = eg.readBits(16);
15391
+ }
15392
+ }
15393
+ var overscan_info_present_flag = eg.readBoolean();
15394
+ if (overscan_info_present_flag) {
15395
+ eg.readBoolean();
15396
+ }
15397
+ var video_signal_type_present_flag = eg.readBoolean();
15398
+ if (video_signal_type_present_flag) {
15399
+ eg.readBits(3);
15400
+ eg.readBoolean();
15401
+ var colour_description_present_flag = eg.readBoolean();
15402
+ if (colour_description_present_flag) {
15403
+ eg.readUByte();
15404
+ eg.readUByte();
15405
+ eg.readUByte();
15406
+ }
15407
+ }
15408
+ var chroma_loc_info_present_flag = eg.readBoolean();
15409
+ if (chroma_loc_info_present_flag) {
15410
+ eg.readUEG();
15411
+ eg.readUEG();
15412
+ }
15413
+ eg.readBoolean(); // neutral_chroma_indication_flag
15414
+ eg.readBoolean(); // field_seq_flag
15415
+ eg.readBoolean(); // frame_field_info_present_flag
15416
+ default_display_window_flag = eg.readBoolean();
15417
+ if (default_display_window_flag) {
15418
+ pic_left_offset += eg.readUEG();
15419
+ pic_right_offset += eg.readUEG();
15420
+ pic_top_offset += eg.readUEG();
15421
+ pic_bottom_offset += eg.readUEG();
15422
+ }
15423
+ var vui_timing_info_present_flag = eg.readBoolean();
15424
+ if (vui_timing_info_present_flag) {
15425
+ fps_den = eg.readBits(32);
15426
+ fps_num = eg.readBits(32);
15427
+ var vui_poc_proportional_to_timing_flag = eg.readBoolean();
15428
+ if (vui_poc_proportional_to_timing_flag) {
15429
+ eg.readUEG();
15430
+ }
15431
+ var vui_hrd_parameters_present_flag = eg.readBoolean();
15432
+ if (vui_hrd_parameters_present_flag) {
15433
+ //const commonInfPresentFlag = true;
15434
+ //if (commonInfPresentFlag) {
15435
+ var nal_hrd_parameters_present_flag = eg.readBoolean();
15436
+ var vcl_hrd_parameters_present_flag = eg.readBoolean();
15437
+ var sub_pic_hrd_params_present_flag = false;
15438
+ if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
15439
+ sub_pic_hrd_params_present_flag = eg.readBoolean();
15440
+ if (sub_pic_hrd_params_present_flag) {
15441
+ eg.readUByte();
15442
+ eg.readBits(5);
15443
+ eg.readBoolean();
15444
+ eg.readBits(5);
15445
+ }
15446
+ eg.readBits(4); // bit_rate_scale
15447
+ eg.readBits(4); // cpb_size_scale
15448
+ if (sub_pic_hrd_params_present_flag) {
15449
+ eg.readBits(4);
15450
+ }
15451
+ eg.readBits(5);
15452
+ eg.readBits(5);
15453
+ eg.readBits(5);
15454
+ }
15455
+ //}
15456
+ for (var _i7 = 0; _i7 <= max_sub_layers_minus1; _i7++) {
15457
+ fps_fixed = eg.readBoolean(); // fixed_pic_rate_general_flag
15458
+ var fixed_pic_rate_within_cvs_flag = fps_fixed || eg.readBoolean();
15459
+ var low_delay_hrd_flag = false;
15460
+ if (fixed_pic_rate_within_cvs_flag) {
15461
+ eg.readEG();
15462
+ } else {
15463
+ low_delay_hrd_flag = eg.readBoolean();
15464
+ }
15465
+ var cpb_cnt = low_delay_hrd_flag ? 1 : eg.readUEG() + 1;
15466
+ if (nal_hrd_parameters_present_flag) {
15467
+ for (var _j4 = 0; _j4 < cpb_cnt; _j4++) {
15468
+ eg.readUEG();
15469
+ eg.readUEG();
15470
+ if (sub_pic_hrd_params_present_flag) {
15471
+ eg.readUEG();
15472
+ eg.readUEG();
15473
+ }
15474
+ eg.skipBits(1);
15475
+ }
15476
+ }
15477
+ if (vcl_hrd_parameters_present_flag) {
15478
+ for (var _j5 = 0; _j5 < cpb_cnt; _j5++) {
15479
+ eg.readUEG();
15480
+ eg.readUEG();
15481
+ if (sub_pic_hrd_params_present_flag) {
15482
+ eg.readUEG();
15483
+ eg.readUEG();
15484
+ }
15485
+ eg.skipBits(1);
15486
+ }
15487
+ }
15488
+ }
15489
+ }
14977
15490
  }
15491
+ var bitstream_restriction_flag = eg.readBoolean();
15492
+ if (bitstream_restriction_flag) {
15493
+ eg.readBoolean(); // tiles_fixed_structure_flag
15494
+ eg.readBoolean(); // motion_vectors_over_pic_boundaries_flag
15495
+ eg.readBoolean(); // restricted_ref_pic_lists_flag
15496
+ min_spatial_segmentation_idc = eg.readUEG();
15497
+ }
15498
+ }
15499
+ var width = pic_width_in_luma_samples,
15500
+ height = pic_height_in_luma_samples;
15501
+ if (conformance_window_flag || default_display_window_flag) {
15502
+ var chroma_scale_w = 1,
15503
+ chroma_scale_h = 1;
15504
+ if (chroma_format_idc === 1) {
15505
+ // YUV 420
15506
+ chroma_scale_w = chroma_scale_h = 2;
15507
+ } else if (chroma_format_idc == 2) {
15508
+ // YUV 422
15509
+ chroma_scale_w = 2;
15510
+ }
15511
+ width = pic_width_in_luma_samples - chroma_scale_w * pic_right_offset - chroma_scale_w * pic_left_offset;
15512
+ height = pic_height_in_luma_samples - chroma_scale_h * pic_bottom_offset - chroma_scale_h * pic_top_offset;
15513
+ }
15514
+ var profile_space_string = general_profile_space ? ['A', 'B', 'C'][general_profile_space] : '';
15515
+ 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;
15516
+ var profile_compatibility_rev = 0;
15517
+ for (var _i8 = 0; _i8 < 32; _i8++) {
15518
+ profile_compatibility_rev = (profile_compatibility_rev | (profile_compatibility_buf >> _i8 & 1) << 31 - _i8) >>> 0; // reverse bit position (and cast as UInt32)
15519
+ }
15520
+ var profile_compatibility_flags_string = profile_compatibility_rev.toString(16);
15521
+ if (general_profile_idc === 1 && profile_compatibility_flags_string === '2') {
15522
+ profile_compatibility_flags_string = '6';
15523
+ }
15524
+ var tier_flag_string = general_tier_flag ? 'H' : 'L';
15525
+ return {
15526
+ codecString: "hvc1." + profile_space_string + general_profile_idc + "." + profile_compatibility_flags_string + "." + tier_flag_string + general_level_idc + ".B0",
15527
+ params: {
15528
+ general_tier_flag: general_tier_flag,
15529
+ general_profile_idc: general_profile_idc,
15530
+ general_profile_space: general_profile_space,
15531
+ general_profile_compatibility_flags: [general_profile_compatibility_flags_1, general_profile_compatibility_flags_2, general_profile_compatibility_flags_3, general_profile_compatibility_flags_4],
15532
+ 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],
15533
+ general_level_idc: general_level_idc,
15534
+ bit_depth: bit_depth_luma_minus8 + 8,
15535
+ bit_depth_luma_minus8: bit_depth_luma_minus8,
15536
+ bit_depth_chroma_minus8: bit_depth_chroma_minus8,
15537
+ min_spatial_segmentation_idc: min_spatial_segmentation_idc,
15538
+ chroma_format_idc: chroma_format_idc,
15539
+ frame_rate: {
15540
+ fixed: fps_fixed,
15541
+ fps: fps_num / fps_den
15542
+ }
15543
+ },
15544
+ width: width,
15545
+ height: height,
15546
+ pixelRatio: [sar_width, sar_height]
15547
+ };
15548
+ };
15549
+ _proto.readPPS = function readPPS(pps) {
15550
+ var eg = new ExpGolomb(this.ebsp2rbsp(pps));
15551
+ eg.readUByte();
15552
+ eg.readUByte();
15553
+ eg.skipUEG(); // pic_parameter_set_id
15554
+ eg.skipUEG(); // seq_parameter_set_id
15555
+ eg.skipBits(2); // dependent_slice_segments_enabled_flag, output_flag_present_flag
15556
+ eg.skipBits(3); // num_extra_slice_header_bits
15557
+ eg.skipBits(2); // sign_data_hiding_enabled_flag, cabac_init_present_flag
15558
+ eg.skipUEG();
15559
+ eg.skipUEG();
15560
+ eg.skipEG(); // init_qp_minus26
15561
+ eg.skipBits(2); // constrained_intra_pred_flag, transform_skip_enabled_flag
15562
+ var cu_qp_delta_enabled_flag = eg.readBoolean();
15563
+ if (cu_qp_delta_enabled_flag) {
15564
+ eg.skipUEG();
15565
+ }
15566
+ eg.skipEG(); // cb_qp_offset
15567
+ eg.skipEG(); // cr_qp_offset
15568
+ eg.skipBits(4); // pps_slice_chroma_qp_offsets_present_flag, weighted_pred_flag, weighted_bipred_flag, transquant_bypass_enabled_flag
15569
+ var tiles_enabled_flag = eg.readBoolean();
15570
+ var entropy_coding_sync_enabled_flag = eg.readBoolean();
15571
+ var parallelismType = 1; // slice-based parallel decoding
15572
+ if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) {
15573
+ parallelismType = 0; // mixed-type parallel decoding
15574
+ } else if (entropy_coding_sync_enabled_flag) {
15575
+ parallelismType = 3; // wavefront-based parallel decoding
15576
+ } else if (tiles_enabled_flag) {
15577
+ parallelismType = 2; // tile-based parallel decoding
14978
15578
  }
14979
- track.naluState = state;
14980
- return units;
15579
+ return {
15580
+ parallelismType: parallelismType
15581
+ };
14981
15582
  };
14982
- return AvcVideoParser;
15583
+ _proto.matchSPS = function matchSPS(sps1, sps2) {
15584
+ // compare without headers and VPS related params
15585
+ return String.fromCharCode.apply(null, sps1).substr(3) === String.fromCharCode.apply(null, sps2).substr(3);
15586
+ };
15587
+ return HevcVideoParser;
14983
15588
  }(BaseVideoParser);
14984
15589
 
14985
15590
  /**
@@ -15116,7 +15721,7 @@
15116
15721
  this.observer = observer;
15117
15722
  this.config = config;
15118
15723
  this.typeSupported = typeSupported;
15119
- this.videoParser = new AvcVideoParser();
15724
+ this.videoParser = null;
15120
15725
  }
15121
15726
  TSDemuxer.probe = function probe(data) {
15122
15727
  var syncOffset = TSDemuxer.syncOffset(data);
@@ -15286,7 +15891,19 @@
15286
15891
  case videoPid:
15287
15892
  if (stt) {
15288
15893
  if (videoData && (pes = parsePES(videoData))) {
15289
- this.videoParser.parseAVCPES(videoTrack, textTrack, pes, false, this._duration);
15894
+ if (this.videoParser === null) {
15895
+ switch (videoTrack.segmentCodec) {
15896
+ case 'avc':
15897
+ this.videoParser = new AvcVideoParser();
15898
+ break;
15899
+ case 'hevc':
15900
+ this.videoParser = new HevcVideoParser();
15901
+ break;
15902
+ }
15903
+ }
15904
+ if (this.videoParser !== null) {
15905
+ this.videoParser.parsePES(videoTrack, textTrack, pes, false, this._duration);
15906
+ }
15290
15907
  }
15291
15908
  videoData = {
15292
15909
  data: [],
@@ -15444,8 +16061,20 @@
15444
16061
  // try to parse last PES packets
15445
16062
  var pes;
15446
16063
  if (videoData && (pes = parsePES(videoData))) {
15447
- this.videoParser.parseAVCPES(videoTrack, textTrack, pes, true, this._duration);
15448
- videoTrack.pesData = null;
16064
+ if (this.videoParser === null) {
16065
+ switch (videoTrack.segmentCodec) {
16066
+ case 'avc':
16067
+ this.videoParser = new AvcVideoParser();
16068
+ break;
16069
+ case 'hevc':
16070
+ this.videoParser = new HevcVideoParser();
16071
+ break;
16072
+ }
16073
+ }
16074
+ if (this.videoParser !== null) {
16075
+ this.videoParser.parsePES(videoTrack, textTrack, pes, true, this._duration);
16076
+ videoTrack.pesData = null;
16077
+ }
15449
16078
  } else {
15450
16079
  // either avcData null or PES truncated, keep it for next frag parsing
15451
16080
  videoTrack.pesData = videoData;
@@ -15747,7 +16376,12 @@
15747
16376
  logger.warn('Unsupported EC-3 in M2TS found');
15748
16377
  break;
15749
16378
  case 0x24:
15750
- logger.warn('Unsupported HEVC in M2TS found');
16379
+ // ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)
16380
+ if (result.videoPid === -1) {
16381
+ result.videoPid = pid;
16382
+ result.segmentVideoCodec = 'hevc';
16383
+ logger.log('HEVC in M2TS found');
16384
+ }
15751
16385
  break;
15752
16386
  }
15753
16387
  // move to the next table entry
@@ -15975,6 +16609,8 @@
15975
16609
  avc1: [],
15976
16610
  // codingname
15977
16611
  avcC: [],
16612
+ hvc1: [],
16613
+ hvcC: [],
15978
16614
  btrt: [],
15979
16615
  dinf: [],
15980
16616
  dref: [],
@@ -16402,8 +17038,10 @@
16402
17038
  return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track));
16403
17039
  }
16404
17040
  return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
16405
- } else {
17041
+ } else if (track.segmentCodec === 'avc') {
16406
17042
  return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
17043
+ } else {
17044
+ return MP4.box(MP4.types.stsd, MP4.STSD, MP4.hvc1(track));
16407
17045
  }
16408
17046
  };
16409
17047
  MP4.tkhd = function tkhd(track) {
@@ -16541,6 +17179,84 @@
16541
17179
  var result = appendUint8Array(MP4.FTYP, movie);
16542
17180
  return result;
16543
17181
  };
17182
+ MP4.hvc1 = function hvc1(track) {
17183
+ var ps = track.params;
17184
+ var units = [track.vps, track.sps, track.pps];
17185
+ var NALuLengthSize = 4;
17186
+ 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]);
17187
+
17188
+ // compute hvcC size in bytes
17189
+ var length = config.length;
17190
+ for (var i = 0; i < units.length; i += 1) {
17191
+ length += 3;
17192
+ for (var j = 0; j < units[i].length; j += 1) {
17193
+ length += 2 + units[i][j].length;
17194
+ }
17195
+ }
17196
+ var hvcC = new Uint8Array(length);
17197
+ hvcC.set(config, 0);
17198
+ length = config.length;
17199
+ // append parameter set units: one vps, one or more sps and pps
17200
+ var iMax = units.length - 1;
17201
+ for (var _i = 0; _i < units.length; _i += 1) {
17202
+ hvcC.set(new Uint8Array([32 + _i | (_i === iMax ? 128 : 0), 0x00, units[_i].length]), length);
17203
+ length += 3;
17204
+ for (var _j = 0; _j < units[_i].length; _j += 1) {
17205
+ hvcC.set(new Uint8Array([units[_i][_j].length >> 8, units[_i][_j].length & 255]), length);
17206
+ length += 2;
17207
+ hvcC.set(units[_i][_j], length);
17208
+ length += units[_i][_j].length;
17209
+ }
17210
+ }
17211
+ var hvcc = MP4.box(MP4.types.hvcC, hvcC);
17212
+ var width = track.width;
17213
+ var height = track.height;
17214
+ var hSpacing = track.pixelRatio[0];
17215
+ var vSpacing = track.pixelRatio[1];
17216
+ return MP4.box(MP4.types.hvc1, new Uint8Array([0x00, 0x00, 0x00,
17217
+ // reserved
17218
+ 0x00, 0x00, 0x00,
17219
+ // reserved
17220
+ 0x00, 0x01,
17221
+ // data_reference_index
17222
+ 0x00, 0x00,
17223
+ // pre_defined
17224
+ 0x00, 0x00,
17225
+ // reserved
17226
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17227
+ // pre_defined
17228
+ width >> 8 & 0xff, width & 0xff,
17229
+ // width
17230
+ height >> 8 & 0xff, height & 0xff,
17231
+ // height
17232
+ 0x00, 0x48, 0x00, 0x00,
17233
+ // horizresolution
17234
+ 0x00, 0x48, 0x00, 0x00,
17235
+ // vertresolution
17236
+ 0x00, 0x00, 0x00, 0x00,
17237
+ // reserved
17238
+ 0x00, 0x01,
17239
+ // frame_count
17240
+ 0x12, 0x64, 0x61, 0x69, 0x6c,
17241
+ // dailymotion/hls.js
17242
+ 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,
17243
+ // compressorname
17244
+ 0x00, 0x18,
17245
+ // depth = 24
17246
+ 0x11, 0x11]),
17247
+ // pre_defined = -1
17248
+ hvcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80,
17249
+ // bufferSizeDB
17250
+ 0x00, 0x2d, 0xc6, 0xc0,
17251
+ // maxBitrate
17252
+ 0x00, 0x2d, 0xc6, 0xc0])),
17253
+ // avgBitrate
17254
+ MP4.box(MP4.types.pasp, new Uint8Array([hSpacing >> 24,
17255
+ // hSpacing
17256
+ hSpacing >> 16 & 0xff, hSpacing >> 8 & 0xff, hSpacing & 0xff, vSpacing >> 24,
17257
+ // vSpacing
17258
+ vSpacing >> 16 & 0xff, vSpacing >> 8 & 0xff, vSpacing & 0xff])));
17259
+ };
16544
17260
  return MP4;
16545
17261
  }();
16546
17262
  MP4.types = void 0;
@@ -16927,9 +17643,9 @@
16927
17643
  var foundOverlap = delta < -1;
16928
17644
  if (foundHole || foundOverlap) {
16929
17645
  if (foundHole) {
16930
- logger.warn("AVC: " + toMsFromMpegTsClock(delta, true) + " ms (" + delta + "dts) hole between fragments detected at " + timeOffset.toFixed(3));
17646
+ logger.warn((track.segmentCodec || '').toUpperCase() + ": " + toMsFromMpegTsClock(delta, true) + " ms (" + delta + "dts) hole between fragments detected at " + timeOffset.toFixed(3));
16931
17647
  } else {
16932
- logger.warn("AVC: " + toMsFromMpegTsClock(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected at " + timeOffset.toFixed(3));
17648
+ logger.warn((track.segmentCodec || '').toUpperCase() + ": " + toMsFromMpegTsClock(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected at " + timeOffset.toFixed(3));
16933
17649
  }
16934
17650
  if (!foundOverlap || nextAvcDts >= inputSamples[0].pts || chromeVersion) {
16935
17651
  firstDTS = nextAvcDts;
@@ -17103,7 +17819,7 @@
17103
17819
  }
17104
17820
  }
17105
17821
  }
17106
- // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
17822
+ // next AVC/HEVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
17107
17823
  mp4SampleDuration = stretchedLastFrame || !mp4SampleDuration ? averageSampleDuration : mp4SampleDuration;
17108
17824
  this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration;
17109
17825
  this.videoSampleDuration = mp4SampleDuration;
@@ -21151,7 +21867,7 @@
21151
21867
  * Get the video-dev/hls.js package version.
21152
21868
  */
21153
21869
  function get() {
21154
- return "1.5.2-0.canary.9970";
21870
+ return "1.5.2-0.canary.9971";
21155
21871
  }
21156
21872
  }, {
21157
21873
  key: "Events",