hls.js 1.5.13-0.canary.10411 → 1.5.13
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/README.md +3 -4
- package/dist/hls-demo.js +38 -41
- package/dist/hls-demo.js.map +1 -1
- package/dist/hls.js +2702 -4247
- package/dist/hls.js.d.ts +110 -179
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +1994 -2914
- package/dist/hls.light.js.map +1 -1
- package/dist/hls.light.min.js +1 -1
- package/dist/hls.light.min.js.map +1 -1
- package/dist/hls.light.mjs +3458 -4388
- package/dist/hls.light.mjs.map +1 -1
- package/dist/hls.min.js +1 -1
- package/dist/hls.min.js.map +1 -1
- package/dist/hls.mjs +4504 -6059
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/dist/hls.worker.js.map +1 -1
- package/package.json +38 -38
- package/src/config.ts +2 -5
- package/src/controller/abr-controller.ts +25 -39
- package/src/controller/audio-stream-controller.ts +136 -156
- package/src/controller/audio-track-controller.ts +1 -1
- package/src/controller/base-playlist-controller.ts +10 -27
- package/src/controller/base-stream-controller.ts +91 -235
- package/src/controller/buffer-controller.ts +97 -250
- package/src/controller/buffer-operation-queue.ts +19 -16
- package/src/controller/cap-level-controller.ts +2 -3
- package/src/controller/cmcd-controller.ts +14 -51
- package/src/controller/content-steering-controller.ts +15 -29
- package/src/controller/eme-controller.ts +23 -10
- package/src/controller/error-controller.ts +22 -28
- package/src/controller/fps-controller.ts +3 -8
- package/src/controller/fragment-finders.ts +16 -44
- package/src/controller/fragment-tracker.ts +25 -58
- package/src/controller/gap-controller.ts +16 -43
- package/src/controller/id3-track-controller.ts +35 -45
- package/src/controller/latency-controller.ts +13 -18
- package/src/controller/level-controller.ts +19 -37
- package/src/controller/stream-controller.ts +83 -100
- package/src/controller/subtitle-stream-controller.ts +47 -35
- package/src/controller/subtitle-track-controller.ts +3 -5
- package/src/controller/timeline-controller.ts +22 -20
- package/src/crypt/aes-crypto.ts +2 -21
- package/src/crypt/decrypter.ts +16 -32
- package/src/crypt/fast-aes-key.ts +5 -28
- package/src/demux/audio/aacdemuxer.ts +2 -2
- package/src/demux/audio/ac3-demuxer.ts +3 -4
- package/src/demux/audio/adts.ts +4 -9
- package/src/demux/audio/base-audio-demuxer.ts +14 -16
- package/src/demux/audio/mp3demuxer.ts +3 -4
- package/src/demux/audio/mpegaudio.ts +1 -1
- package/src/demux/id3.ts +411 -0
- package/src/demux/mp4demuxer.ts +7 -7
- package/src/demux/sample-aes.ts +0 -2
- package/src/demux/transmuxer-interface.ts +16 -8
- package/src/demux/transmuxer-worker.ts +4 -4
- package/src/demux/transmuxer.ts +3 -16
- package/src/demux/tsdemuxer.ts +38 -75
- package/src/demux/video/avc-video-parser.ts +121 -210
- package/src/demux/video/base-video-parser.ts +2 -135
- package/src/demux/video/exp-golomb.ts +208 -0
- package/src/events.ts +1 -8
- package/src/exports-named.ts +1 -1
- package/src/hls.ts +47 -84
- package/src/loader/date-range.ts +5 -71
- package/src/loader/fragment-loader.ts +21 -23
- package/src/loader/fragment.ts +4 -8
- package/src/loader/key-loader.ts +1 -3
- package/src/loader/level-details.ts +6 -6
- package/src/loader/level-key.ts +9 -10
- package/src/loader/m3u8-parser.ts +144 -138
- package/src/loader/playlist-loader.ts +7 -5
- package/src/remux/mp4-generator.ts +1 -196
- package/src/remux/mp4-remuxer.ts +62 -32
- package/src/remux/passthrough-remuxer.ts +1 -1
- package/src/task-loop.ts +2 -5
- package/src/types/component-api.ts +1 -3
- package/src/types/demuxer.ts +0 -3
- package/src/types/events.ts +6 -19
- package/src/types/fragment-tracker.ts +2 -2
- package/src/types/general.ts +6 -0
- package/src/types/media-playlist.ts +1 -9
- package/src/types/remuxer.ts +1 -1
- package/src/utils/attr-list.ts +9 -96
- package/src/utils/buffer-helper.ts +31 -12
- package/src/utils/cea-608-parser.ts +3 -1
- package/src/utils/codecs.ts +5 -34
- package/src/utils/fetch-loader.ts +1 -1
- package/src/utils/hdr.ts +7 -4
- package/src/utils/imsc1-ttml-parser.ts +1 -1
- package/src/utils/keysystem-util.ts +6 -1
- package/src/utils/level-helper.ts +44 -71
- package/src/utils/logger.ts +23 -58
- package/src/utils/mp4-tools.ts +3 -5
- package/src/utils/rendition-helper.ts +74 -100
- package/src/utils/variable-substitution.ts +19 -0
- package/src/utils/webvtt-parser.ts +12 -2
- package/src/crypt/decrypter-aes-mode.ts +0 -4
- package/src/demux/video/hevc-video-parser.ts +0 -749
- package/src/utils/encryption-methods-util.ts +0 -21
- package/src/utils/hash.ts +0 -10
- package/src/utils/utf8-utils.ts +0 -18
package/src/demux/tsdemuxer.ts
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
* highly optimized TS demuxer:
|
3
3
|
* parse PAT, PMT
|
4
4
|
* extract PES packet from audio and video PIDs
|
5
|
-
* extract AVC/H264
|
5
|
+
* extract AVC/H264 NAL units and AAC/ADTS samples from PES packet
|
6
6
|
* trigger the remuxer upon parsing completion
|
7
7
|
* it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.
|
8
8
|
* it also controls the remuxing process :
|
@@ -12,9 +12,7 @@
|
|
12
12
|
import * as ADTS from './audio/adts';
|
13
13
|
import * as MpegAudio from './audio/mpegaudio';
|
14
14
|
import * as AC3 from './audio/ac3-demuxer';
|
15
|
-
import BaseVideoParser from './video/base-video-parser';
|
16
15
|
import AvcVideoParser from './video/avc-video-parser';
|
17
|
-
import HevcVideoParser from './video/hevc-video-parser';
|
18
16
|
import SampleAesDecrypter from './sample-aes';
|
19
17
|
import { Events } from '../events';
|
20
18
|
import { appendUint8Array, RemuxerTrackIdConfig } from '../utils/mp4-tools';
|
@@ -22,21 +20,20 @@ import { logger } from '../utils/logger';
|
|
22
20
|
import { ErrorTypes, ErrorDetails } from '../errors';
|
23
21
|
import type { HlsConfig } from '../config';
|
24
22
|
import type { HlsEventEmitter } from '../events';
|
25
|
-
import type { TypeSupported } from '../utils/codecs';
|
26
23
|
import {
|
24
|
+
DemuxedVideoTrack,
|
25
|
+
DemuxedAudioTrack,
|
26
|
+
DemuxedTrack,
|
27
|
+
Demuxer,
|
28
|
+
DemuxerResult,
|
29
|
+
VideoSample,
|
30
|
+
DemuxedMetadataTrack,
|
31
|
+
DemuxedUserdataTrack,
|
32
|
+
ElementaryStreamData,
|
33
|
+
KeyData,
|
27
34
|
MetadataSchema,
|
28
|
-
type DemuxedVideoTrack,
|
29
|
-
type DemuxedAudioTrack,
|
30
|
-
type DemuxedTrack,
|
31
|
-
type Demuxer,
|
32
|
-
type DemuxerResult,
|
33
|
-
type VideoSample,
|
34
|
-
type DemuxedMetadataTrack,
|
35
|
-
type DemuxedUserdataTrack,
|
36
|
-
type ElementaryStreamData,
|
37
|
-
type KeyData,
|
38
35
|
} from '../types/demuxer';
|
39
|
-
import
|
36
|
+
import { AudioFrame } from '../types/demuxer';
|
40
37
|
|
41
38
|
export type ParsedTimestamp = {
|
42
39
|
pts?: number;
|
@@ -51,6 +48,12 @@ export type PES = ParsedTimestamp & {
|
|
51
48
|
export type ParsedVideoSample = ParsedTimestamp &
|
52
49
|
Omit<VideoSample, 'pts' | 'dts'>;
|
53
50
|
|
51
|
+
export interface TypeSupported {
|
52
|
+
mpeg: boolean;
|
53
|
+
mp3: boolean;
|
54
|
+
ac3: boolean;
|
55
|
+
}
|
56
|
+
|
54
57
|
const PACKET_LENGTH = 188;
|
55
58
|
|
56
59
|
class TSDemuxer implements Demuxer {
|
@@ -71,7 +74,7 @@ class TSDemuxer implements Demuxer {
|
|
71
74
|
private _txtTrack?: DemuxedUserdataTrack;
|
72
75
|
private aacOverFlow: AudioFrame | null = null;
|
73
76
|
private remainderData: Uint8Array | null = null;
|
74
|
-
private videoParser:
|
77
|
+
private videoParser: AvcVideoParser;
|
75
78
|
|
76
79
|
constructor(
|
77
80
|
observer: HlsEventEmitter,
|
@@ -81,7 +84,7 @@ class TSDemuxer implements Demuxer {
|
|
81
84
|
this.observer = observer;
|
82
85
|
this.config = config;
|
83
86
|
this.typeSupported = typeSupported;
|
84
|
-
this.videoParser =
|
87
|
+
this.videoParser = new AvcVideoParser();
|
85
88
|
}
|
86
89
|
|
87
90
|
static probe(data: Uint8Array) {
|
@@ -289,27 +292,13 @@ class TSDemuxer implements Demuxer {
|
|
289
292
|
case videoPid:
|
290
293
|
if (stt) {
|
291
294
|
if (videoData && (pes = parsePES(videoData))) {
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
this.videoParser = new HevcVideoParser();
|
300
|
-
}
|
301
|
-
break;
|
302
|
-
}
|
303
|
-
}
|
304
|
-
if (this.videoParser !== null) {
|
305
|
-
this.videoParser.parsePES(
|
306
|
-
videoTrack,
|
307
|
-
textTrack,
|
308
|
-
pes,
|
309
|
-
false,
|
310
|
-
this._duration,
|
311
|
-
);
|
312
|
-
}
|
295
|
+
this.videoParser.parseAVCPES(
|
296
|
+
videoTrack,
|
297
|
+
textTrack,
|
298
|
+
pes,
|
299
|
+
false,
|
300
|
+
this._duration,
|
301
|
+
);
|
313
302
|
}
|
314
303
|
|
315
304
|
videoData = { data: [], size: 0 };
|
@@ -478,28 +467,14 @@ class TSDemuxer implements Demuxer {
|
|
478
467
|
// try to parse last PES packets
|
479
468
|
let pes: PES | null;
|
480
469
|
if (videoData && (pes = parsePES(videoData))) {
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
}
|
490
|
-
break;
|
491
|
-
}
|
492
|
-
}
|
493
|
-
if (this.videoParser !== null) {
|
494
|
-
this.videoParser.parsePES(
|
495
|
-
videoTrack as DemuxedVideoTrack,
|
496
|
-
textTrack as DemuxedUserdataTrack,
|
497
|
-
pes,
|
498
|
-
true,
|
499
|
-
this._duration,
|
500
|
-
);
|
501
|
-
videoTrack.pesData = null;
|
502
|
-
}
|
470
|
+
this.videoParser.parseAVCPES(
|
471
|
+
videoTrack as DemuxedVideoTrack,
|
472
|
+
textTrack as DemuxedUserdataTrack,
|
473
|
+
pes,
|
474
|
+
true,
|
475
|
+
this._duration,
|
476
|
+
);
|
477
|
+
videoTrack.pesData = null;
|
503
478
|
} else {
|
504
479
|
// either avcData null or PES truncated, keep it for next frag parsing
|
505
480
|
videoTrack.pesData = videoData;
|
@@ -889,21 +864,9 @@ function parsePMT(
|
|
889
864
|
emitParsingError(observer, new Error('Unsupported EC-3 in M2TS found'));
|
890
865
|
return result;
|
891
866
|
|
892
|
-
case 0x24:
|
893
|
-
|
894
|
-
|
895
|
-
result.videoPid = pid;
|
896
|
-
result.segmentVideoCodec = 'hevc';
|
897
|
-
logger.log('HEVC in M2TS found');
|
898
|
-
}
|
899
|
-
} else {
|
900
|
-
emitParsingError(
|
901
|
-
observer,
|
902
|
-
new Error('Unsupported HEVC in M2TS found'),
|
903
|
-
);
|
904
|
-
return result;
|
905
|
-
}
|
906
|
-
break;
|
867
|
+
case 0x24:
|
868
|
+
emitParsingError(observer, new Error('Unsupported HEVC in M2TS found'));
|
869
|
+
return result;
|
907
870
|
|
908
871
|
default:
|
909
872
|
// logger.log('unknown stream type:' + data[offset]);
|
@@ -1,23 +1,25 @@
|
|
1
1
|
import BaseVideoParser from './base-video-parser';
|
2
|
-
import
|
2
|
+
import {
|
3
3
|
DemuxedVideoTrack,
|
4
4
|
DemuxedUserdataTrack,
|
5
|
+
VideoSampleUnit,
|
5
6
|
} from '../../types/demuxer';
|
6
|
-
import {
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
import {
|
8
|
+
appendUint8Array,
|
9
|
+
parseSEIMessageFromNALu,
|
10
|
+
} from '../../utils/mp4-tools';
|
10
11
|
import ExpGolomb from './exp-golomb';
|
12
|
+
import type { PES } from '../tsdemuxer';
|
11
13
|
|
12
14
|
class AvcVideoParser extends BaseVideoParser {
|
13
|
-
public
|
15
|
+
public parseAVCPES(
|
14
16
|
track: DemuxedVideoTrack,
|
15
17
|
textTrack: DemuxedUserdataTrack,
|
16
18
|
pes: PES,
|
17
|
-
|
19
|
+
last: boolean,
|
18
20
|
duration: number,
|
19
21
|
) {
|
20
|
-
const units = this.
|
22
|
+
const units = this.parseAVCNALu(track, pes.data);
|
21
23
|
const debug = false;
|
22
24
|
let VideoSample = this.VideoSample;
|
23
25
|
let push: boolean;
|
@@ -47,7 +49,7 @@ class AvcVideoParser extends BaseVideoParser {
|
|
47
49
|
// only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
|
48
50
|
if (spsfound && data.length > 4) {
|
49
51
|
// retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
|
50
|
-
const sliceType =
|
52
|
+
const sliceType = new ExpGolomb(data).readSliceType();
|
51
53
|
// 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
|
52
54
|
// SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
|
53
55
|
// An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
|
@@ -136,7 +138,9 @@ class AvcVideoParser extends BaseVideoParser {
|
|
136
138
|
VideoSample.debug += 'SPS ';
|
137
139
|
}
|
138
140
|
const sps = unit.data;
|
139
|
-
const
|
141
|
+
const expGolombDecoder = new ExpGolomb(sps);
|
142
|
+
const config = expGolombDecoder.readSPS();
|
143
|
+
|
140
144
|
if (
|
141
145
|
!track.sps ||
|
142
146
|
track.width !== config.width ||
|
@@ -161,6 +165,7 @@ class AvcVideoParser extends BaseVideoParser {
|
|
161
165
|
}
|
162
166
|
track.codec = codecstring;
|
163
167
|
}
|
168
|
+
|
164
169
|
break;
|
165
170
|
}
|
166
171
|
// PPS
|
@@ -206,223 +211,129 @@ class AvcVideoParser extends BaseVideoParser {
|
|
206
211
|
}
|
207
212
|
});
|
208
213
|
// if last PES packet, push samples
|
209
|
-
if (
|
214
|
+
if (last && VideoSample) {
|
210
215
|
this.pushAccessUnit(VideoSample, track);
|
211
216
|
this.VideoSample = null;
|
212
217
|
}
|
213
218
|
}
|
214
219
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
220
|
+
private parseAVCNALu(
|
221
|
+
track: DemuxedVideoTrack,
|
222
|
+
array: Uint8Array,
|
223
|
+
): Array<{
|
224
|
+
data: Uint8Array;
|
225
|
+
type: number;
|
226
|
+
state?: number;
|
227
|
+
}> {
|
228
|
+
const len = array.byteLength;
|
229
|
+
let state = track.naluState || 0;
|
230
|
+
const lastState = state;
|
231
|
+
const units: VideoSampleUnit[] = [];
|
232
|
+
let i = 0;
|
233
|
+
let value: number;
|
234
|
+
let overflow: number;
|
235
|
+
let unitType: number;
|
236
|
+
let lastUnitStart = -1;
|
237
|
+
let lastUnitType: number = 0;
|
238
|
+
// logger.log('PES:' + Hex.hexDump(array));
|
228
239
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
let lastScale = 8;
|
237
|
-
let nextScale = 8;
|
238
|
-
let deltaScale;
|
239
|
-
for (let j = 0; j < count; j++) {
|
240
|
-
if (nextScale !== 0) {
|
241
|
-
deltaScale = reader.readEG();
|
242
|
-
nextScale = (lastScale + deltaScale + 256) % 256;
|
243
|
-
}
|
244
|
-
lastScale = nextScale === 0 ? lastScale : nextScale;
|
240
|
+
if (state === -1) {
|
241
|
+
// special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
|
242
|
+
lastUnitStart = 0;
|
243
|
+
// NALu type is value read from offset 0
|
244
|
+
lastUnitType = array[0] & 0x1f;
|
245
|
+
state = 0;
|
246
|
+
i = 1;
|
245
247
|
}
|
246
|
-
}
|
247
|
-
|
248
|
-
/**
|
249
|
-
* Read a sequence parameter set and return some interesting video
|
250
|
-
* properties. A sequence parameter set is the H264 metadata that
|
251
|
-
* describes the properties of upcoming video frames.
|
252
|
-
* @returns an object with configuration parsed from the
|
253
|
-
* sequence parameter set, including the dimensions of the
|
254
|
-
* associated video frames.
|
255
|
-
*/
|
256
|
-
readSPS(sps: Uint8Array): {
|
257
|
-
width: number;
|
258
|
-
height: number;
|
259
|
-
pixelRatio: [number, number];
|
260
|
-
} {
|
261
|
-
const eg = new ExpGolomb(sps);
|
262
|
-
let frameCropLeftOffset = 0;
|
263
|
-
let frameCropRightOffset = 0;
|
264
|
-
let frameCropTopOffset = 0;
|
265
|
-
let frameCropBottomOffset = 0;
|
266
|
-
let numRefFramesInPicOrderCntCycle;
|
267
|
-
let scalingListCount;
|
268
|
-
let i;
|
269
|
-
const readUByte = eg.readUByte.bind(eg);
|
270
|
-
const readBits = eg.readBits.bind(eg);
|
271
|
-
const readUEG = eg.readUEG.bind(eg);
|
272
|
-
const readBoolean = eg.readBoolean.bind(eg);
|
273
|
-
const skipBits = eg.skipBits.bind(eg);
|
274
|
-
const skipEG = eg.skipEG.bind(eg);
|
275
|
-
const skipUEG = eg.skipUEG.bind(eg);
|
276
|
-
const skipScalingList = this.skipScalingList.bind(this);
|
277
248
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
249
|
+
while (i < len) {
|
250
|
+
value = array[i++];
|
251
|
+
// optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
|
252
|
+
if (!state) {
|
253
|
+
state = value ? 0 : 1;
|
254
|
+
continue;
|
255
|
+
}
|
256
|
+
if (state === 1) {
|
257
|
+
state = value ? 0 : 2;
|
258
|
+
continue;
|
259
|
+
}
|
260
|
+
// here we have state either equal to 2 or 3
|
261
|
+
if (!value) {
|
262
|
+
state = 3;
|
263
|
+
} else if (value === 1) {
|
264
|
+
overflow = i - state - 1;
|
265
|
+
if (lastUnitStart >= 0) {
|
266
|
+
const unit: VideoSampleUnit = {
|
267
|
+
data: array.subarray(lastUnitStart, overflow),
|
268
|
+
type: lastUnitType,
|
269
|
+
};
|
270
|
+
// logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
271
|
+
units.push(unit);
|
272
|
+
} else {
|
273
|
+
// lastUnitStart is undefined => this is the first start code found in this PES packet
|
274
|
+
// first check if start code delimiter is overlapping between 2 PES packets,
|
275
|
+
// ie it started in last packet (lastState not zero)
|
276
|
+
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
277
|
+
const lastUnit = this.getLastNalUnit(track.samples);
|
278
|
+
if (lastUnit) {
|
279
|
+
if (lastState && i <= 4 - lastState) {
|
280
|
+
// start delimiter overlapping between PES packets
|
281
|
+
// strip start delimiter bytes from the end of last NAL unit
|
282
|
+
// check if lastUnit had a state different from zero
|
283
|
+
if (lastUnit.state) {
|
284
|
+
// strip last bytes
|
285
|
+
lastUnit.data = lastUnit.data.subarray(
|
286
|
+
0,
|
287
|
+
lastUnit.data.byteLength - lastState,
|
288
|
+
);
|
289
|
+
}
|
290
|
+
}
|
291
|
+
// If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
|
300
292
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
if (readBoolean()) {
|
309
|
-
// seq_scaling_list_present_flag[ i ]
|
310
|
-
if (i < 6) {
|
311
|
-
skipScalingList(16, eg);
|
312
|
-
} else {
|
313
|
-
skipScalingList(64, eg);
|
293
|
+
if (overflow > 0) {
|
294
|
+
// logger.log('first NALU found with overflow:' + overflow);
|
295
|
+
lastUnit.data = appendUint8Array(
|
296
|
+
lastUnit.data,
|
297
|
+
array.subarray(0, overflow),
|
298
|
+
);
|
299
|
+
lastUnit.state = 0;
|
314
300
|
}
|
315
301
|
}
|
316
302
|
}
|
303
|
+
// check if we can read unit type
|
304
|
+
if (i < len) {
|
305
|
+
unitType = array[i] & 0x1f;
|
306
|
+
// logger.log('find NALU @ offset:' + i + ',type:' + unitType);
|
307
|
+
lastUnitStart = i;
|
308
|
+
lastUnitType = unitType;
|
309
|
+
state = 0;
|
310
|
+
} else {
|
311
|
+
// not enough byte to read unit type. let's read it on next PES parsing
|
312
|
+
state = -1;
|
313
|
+
}
|
314
|
+
} else {
|
315
|
+
state = 0;
|
317
316
|
}
|
318
317
|
}
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
numRefFramesInPicOrderCntCycle = readUEG();
|
328
|
-
for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
|
329
|
-
skipEG();
|
330
|
-
} // offset_for_ref_frame[ i ]
|
331
|
-
}
|
332
|
-
skipUEG(); // max_num_ref_frames
|
333
|
-
skipBits(1); // gaps_in_frame_num_value_allowed_flag
|
334
|
-
const picWidthInMbsMinus1 = readUEG();
|
335
|
-
const picHeightInMapUnitsMinus1 = readUEG();
|
336
|
-
const frameMbsOnlyFlag = readBits(1);
|
337
|
-
if (frameMbsOnlyFlag === 0) {
|
338
|
-
skipBits(1);
|
339
|
-
} // mb_adaptive_frame_field_flag
|
340
|
-
|
341
|
-
skipBits(1); // direct_8x8_inference_flag
|
342
|
-
if (readBoolean()) {
|
343
|
-
// frame_cropping_flag
|
344
|
-
frameCropLeftOffset = readUEG();
|
345
|
-
frameCropRightOffset = readUEG();
|
346
|
-
frameCropTopOffset = readUEG();
|
347
|
-
frameCropBottomOffset = readUEG();
|
318
|
+
if (lastUnitStart >= 0 && state >= 0) {
|
319
|
+
const unit: VideoSampleUnit = {
|
320
|
+
data: array.subarray(lastUnitStart, len),
|
321
|
+
type: lastUnitType,
|
322
|
+
state: state,
|
323
|
+
};
|
324
|
+
units.push(unit);
|
325
|
+
// logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
|
348
326
|
}
|
349
|
-
|
350
|
-
if (
|
351
|
-
//
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
switch (aspectRatioIdc) {
|
356
|
-
case 1:
|
357
|
-
pixelRatio = [1, 1];
|
358
|
-
break;
|
359
|
-
case 2:
|
360
|
-
pixelRatio = [12, 11];
|
361
|
-
break;
|
362
|
-
case 3:
|
363
|
-
pixelRatio = [10, 11];
|
364
|
-
break;
|
365
|
-
case 4:
|
366
|
-
pixelRatio = [16, 11];
|
367
|
-
break;
|
368
|
-
case 5:
|
369
|
-
pixelRatio = [40, 33];
|
370
|
-
break;
|
371
|
-
case 6:
|
372
|
-
pixelRatio = [24, 11];
|
373
|
-
break;
|
374
|
-
case 7:
|
375
|
-
pixelRatio = [20, 11];
|
376
|
-
break;
|
377
|
-
case 8:
|
378
|
-
pixelRatio = [32, 11];
|
379
|
-
break;
|
380
|
-
case 9:
|
381
|
-
pixelRatio = [80, 33];
|
382
|
-
break;
|
383
|
-
case 10:
|
384
|
-
pixelRatio = [18, 11];
|
385
|
-
break;
|
386
|
-
case 11:
|
387
|
-
pixelRatio = [15, 11];
|
388
|
-
break;
|
389
|
-
case 12:
|
390
|
-
pixelRatio = [64, 33];
|
391
|
-
break;
|
392
|
-
case 13:
|
393
|
-
pixelRatio = [160, 99];
|
394
|
-
break;
|
395
|
-
case 14:
|
396
|
-
pixelRatio = [4, 3];
|
397
|
-
break;
|
398
|
-
case 15:
|
399
|
-
pixelRatio = [3, 2];
|
400
|
-
break;
|
401
|
-
case 16:
|
402
|
-
pixelRatio = [2, 1];
|
403
|
-
break;
|
404
|
-
case 255: {
|
405
|
-
pixelRatio = [
|
406
|
-
(readUByte() << 8) | readUByte(),
|
407
|
-
(readUByte() << 8) | readUByte(),
|
408
|
-
];
|
409
|
-
break;
|
410
|
-
}
|
411
|
-
}
|
327
|
+
// no NALu found
|
328
|
+
if (units.length === 0) {
|
329
|
+
// append pes.data to previous NAL unit
|
330
|
+
const lastUnit = this.getLastNalUnit(track.samples);
|
331
|
+
if (lastUnit) {
|
332
|
+
lastUnit.data = appendUint8Array(lastUnit.data, array);
|
412
333
|
}
|
413
334
|
}
|
414
|
-
|
415
|
-
|
416
|
-
(picWidthInMbsMinus1 + 1) * 16 -
|
417
|
-
frameCropLeftOffset * 2 -
|
418
|
-
frameCropRightOffset * 2,
|
419
|
-
),
|
420
|
-
height:
|
421
|
-
(2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 -
|
422
|
-
(frameMbsOnlyFlag ? 2 : 4) *
|
423
|
-
(frameCropTopOffset + frameCropBottomOffset),
|
424
|
-
pixelRatio: pixelRatio,
|
425
|
-
};
|
335
|
+
track.naluState = state;
|
336
|
+
return units;
|
426
337
|
}
|
427
338
|
}
|
428
339
|
|