@alessmicrosystems/mpegts.js 1.8.1

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.
Files changed (121) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +158 -0
  3. package/README_ja.md +153 -0
  4. package/README_zh.md +157 -0
  5. package/d.ts/mpegts.d.ts +524 -0
  6. package/d.ts/src/core/mse-events.d.ts +9 -0
  7. package/d.ts/src/core/transmuxing-events.d.ts +24 -0
  8. package/d.ts/src/demux/aac.d.ts +44 -0
  9. package/d.ts/src/demux/ac3.d.ts +70 -0
  10. package/d.ts/src/demux/av1-parser.d.ts +77 -0
  11. package/d.ts/src/demux/av1.d.ts +11 -0
  12. package/d.ts/src/demux/base-demuxer.d.ts +55 -0
  13. package/d.ts/src/demux/h264.d.ts +40 -0
  14. package/d.ts/src/demux/h265.d.ts +65 -0
  15. package/d.ts/src/demux/klv.d.ts +17 -0
  16. package/d.ts/src/demux/mp3.d.ts +6 -0
  17. package/d.ts/src/demux/mpeg4-audio.d.ts +28 -0
  18. package/d.ts/src/demux/pat-pmt-pes.d.ts +106 -0
  19. package/d.ts/src/demux/patpmt.d.ts +40 -0
  20. package/d.ts/src/demux/pes-private-data.d.ts +14 -0
  21. package/d.ts/src/demux/pgs-data.d.ts +9 -0
  22. package/d.ts/src/demux/scte35.d.ts +250 -0
  23. package/d.ts/src/demux/sei.d.ts +8 -0
  24. package/d.ts/src/demux/smpte2038.d.ts +22 -0
  25. package/d.ts/src/demux/ts-demuxer.d.ts +124 -0
  26. package/d.ts/src/player/live-latency-chaser.d.ts +10 -0
  27. package/d.ts/src/player/live-latency-synchronizer.d.ts +10 -0
  28. package/d.ts/src/player/loading-controller.d.ts +19 -0
  29. package/d.ts/src/player/mse-player.d.ts +30 -0
  30. package/d.ts/src/player/player-engine-dedicated-thread-worker.d.ts +2 -0
  31. package/d.ts/src/player/player-engine-dedicated-thread.d.ts +48 -0
  32. package/d.ts/src/player/player-engine-main-thread.d.ts +50 -0
  33. package/d.ts/src/player/player-engine-worker-cmd-def.d.ts +25 -0
  34. package/d.ts/src/player/player-engine-worker-msg-def.d.ts +54 -0
  35. package/d.ts/src/player/player-engine-worker.d.ts +2 -0
  36. package/d.ts/src/player/player-engine.d.ts +16 -0
  37. package/d.ts/src/player/player-events.d.ts +21 -0
  38. package/d.ts/src/player/seeking-handler.d.ts +22 -0
  39. package/d.ts/src/player/startup-stall-jumper.d.ts +14 -0
  40. package/d.ts/src/utils/typedarray-equality.d.ts +2 -0
  41. package/dist/mpegts.js +3 -0
  42. package/dist/mpegts.js.LICENSE.txt +7 -0
  43. package/dist/mpegts.js.map +1 -0
  44. package/package.json +53 -0
  45. package/src/config.js +67 -0
  46. package/src/core/features.js +88 -0
  47. package/src/core/media-info.js +127 -0
  48. package/src/core/media-segment-info.js +230 -0
  49. package/src/core/mse-controller.js +599 -0
  50. package/src/core/mse-events.ts +28 -0
  51. package/src/core/transmuxer.js +346 -0
  52. package/src/core/transmuxing-controller.js +628 -0
  53. package/src/core/transmuxing-events.ts +43 -0
  54. package/src/core/transmuxing-worker.js +286 -0
  55. package/src/demux/aac.ts +397 -0
  56. package/src/demux/ac3.ts +335 -0
  57. package/src/demux/amf-parser.js +243 -0
  58. package/src/demux/av1-parser.ts +629 -0
  59. package/src/demux/av1.ts +103 -0
  60. package/src/demux/base-demuxer.ts +69 -0
  61. package/src/demux/demux-errors.js +26 -0
  62. package/src/demux/exp-golomb.js +116 -0
  63. package/src/demux/flv-demuxer.js +1854 -0
  64. package/src/demux/h264.ts +187 -0
  65. package/src/demux/h265-parser.js +501 -0
  66. package/src/demux/h265.ts +214 -0
  67. package/src/demux/klv.ts +40 -0
  68. package/src/demux/mp3.ts +7 -0
  69. package/src/demux/mpeg4-audio.ts +45 -0
  70. package/src/demux/pat-pmt-pes.ts +132 -0
  71. package/src/demux/pes-private-data.ts +16 -0
  72. package/src/demux/pgs-data.ts +11 -0
  73. package/src/demux/scte35.ts +723 -0
  74. package/src/demux/sei.ts +99 -0
  75. package/src/demux/smpte2038.ts +89 -0
  76. package/src/demux/sps-parser.js +298 -0
  77. package/src/demux/ts-demuxer.ts +2405 -0
  78. package/src/index.js +4 -0
  79. package/src/io/fetch-stream-loader.js +266 -0
  80. package/src/io/io-controller.js +647 -0
  81. package/src/io/loader.js +134 -0
  82. package/src/io/param-seek-handler.js +85 -0
  83. package/src/io/range-seek-handler.js +52 -0
  84. package/src/io/speed-sampler.js +93 -0
  85. package/src/io/websocket-loader.js +151 -0
  86. package/src/io/xhr-moz-chunked-loader.js +211 -0
  87. package/src/io/xhr-msstream-loader.js +307 -0
  88. package/src/io/xhr-range-loader.js +366 -0
  89. package/src/mpegts.js +95 -0
  90. package/src/player/live-latency-chaser.ts +66 -0
  91. package/src/player/live-latency-synchronizer.ts +79 -0
  92. package/src/player/loading-controller.ts +142 -0
  93. package/src/player/mse-player.ts +150 -0
  94. package/src/player/native-player.js +262 -0
  95. package/src/player/player-engine-dedicated-thread.ts +479 -0
  96. package/src/player/player-engine-main-thread.ts +463 -0
  97. package/src/player/player-engine-worker-cmd-def.ts +62 -0
  98. package/src/player/player-engine-worker-msg-def.ts +102 -0
  99. package/src/player/player-engine-worker.ts +370 -0
  100. package/src/player/player-engine.ts +35 -0
  101. package/src/player/player-errors.js +39 -0
  102. package/src/player/player-events.ts +40 -0
  103. package/src/player/seeking-handler.ts +205 -0
  104. package/src/player/startup-stall-jumper.ts +86 -0
  105. package/src/remux/aac-silent.js +56 -0
  106. package/src/remux/mp4-generator.js +866 -0
  107. package/src/remux/mp4-remuxer.js +778 -0
  108. package/src/utils/browser.js +128 -0
  109. package/src/utils/exception.js +73 -0
  110. package/src/utils/logger.js +140 -0
  111. package/src/utils/logging-control.js +165 -0
  112. package/src/utils/polyfill.js +68 -0
  113. package/src/utils/typedarray-equality.ts +69 -0
  114. package/src/utils/utf8-conv.js +84 -0
  115. package/src/utils/webworkify-webpack.js +202 -0
  116. package/tsconfig.json +16 -0
  117. package/tslint.json +1 -0
  118. package/types/index.d.ts +3 -0
  119. package/types/test-flv.ts +8 -0
  120. package/types/tsconfig.json +24 -0
  121. package/webpack.config.js +55 -0
@@ -0,0 +1,99 @@
1
+
2
+ export class SEIData {
3
+ type: number;
4
+ size: number;
5
+ uuid: Uint8Array;
6
+ user_data: Uint8Array;
7
+ pts?: number;
8
+ }
9
+
10
+ function ebsp2rbsp(uint8array: Uint8Array): Uint8Array {
11
+ let src = uint8array;
12
+ let src_length = src.byteLength;
13
+ let dst = new Uint8Array(src_length);
14
+ let dst_idx = 0;
15
+
16
+ for (let i = 0; i < src_length; i++) {
17
+ if (i >= 2) {
18
+ // Unescape: Skip 0x03 after 00 00
19
+ if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {
20
+ continue;
21
+ }
22
+ }
23
+ dst[dst_idx] = src[i];
24
+ dst_idx++;
25
+ }
26
+
27
+ return new Uint8Array(dst.buffer, 0, dst_idx);
28
+ }
29
+
30
+ export function parseSEI(data: Uint8Array, pts?: number, codec?: 'h264' | 'h265'): SEIData | null {
31
+ if (!data || data.byteLength < 2) {
32
+ return null;
33
+ }
34
+
35
+ // Determine NALU header size based on codec
36
+ let naluHeaderSize = 1; // Default for H.264
37
+ if (codec === 'h265') {
38
+ naluHeaderSize = 2;
39
+ }
40
+
41
+ // Convert EBSP to RBSP (skip NALU header)
42
+ let rbsp_data = ebsp2rbsp(data.subarray(naluHeaderSize));
43
+ let offset = 0;
44
+
45
+ // Check for trailing bits (0x80)
46
+ if (offset === rbsp_data.byteLength - 1 && rbsp_data[offset] === 0x80) {
47
+ return null;
48
+ }
49
+
50
+ // Parse payload type (can be multiple bytes for extended types)
51
+ let payloadType = 0;
52
+ while (offset < rbsp_data.byteLength && rbsp_data[offset] === 0xFF) {
53
+ payloadType += 255;
54
+ offset++;
55
+ }
56
+ if (offset >= rbsp_data.byteLength) {
57
+ return null;
58
+ }
59
+ payloadType += rbsp_data[offset++];
60
+
61
+ // Parse payload size (can be multiple bytes for extended sizes)
62
+ let payloadSize = 0;
63
+ while (offset < rbsp_data.byteLength && rbsp_data[offset] === 0xFF) {
64
+ payloadSize += 255;
65
+ offset++;
66
+ }
67
+ if (offset >= rbsp_data.byteLength) {
68
+ return null;
69
+ }
70
+ payloadSize += rbsp_data[offset++];
71
+
72
+ // Check if we have enough data
73
+ if (offset + payloadSize > rbsp_data.byteLength) {
74
+ return null;
75
+ }
76
+
77
+ let sei_data = new SEIData();
78
+ sei_data.type = payloadType;
79
+ sei_data.size = payloadSize;
80
+
81
+ // Extract payload
82
+ let payload = rbsp_data.subarray(offset, offset + payloadSize);
83
+
84
+ // SEI payload type 5 is user_data_unregistered (with UUID)
85
+ // This is the same for both H.264 and H.265
86
+ if (payloadType === 5 && payloadSize >= 16) {
87
+ // First 16 bytes are UUID
88
+ sei_data.uuid = payload.subarray(0, 16);
89
+ sei_data.user_data = payload.subarray(16);
90
+ } else {
91
+ // ignore
92
+ }
93
+
94
+ if (pts !== undefined) {
95
+ sei_data.pts = pts;
96
+ }
97
+
98
+ return sei_data;
99
+ }
@@ -0,0 +1,89 @@
1
+ import ExpGolomb from "./exp-golomb";
2
+
3
+ export class SMPTE2038Data {
4
+ pid: number;
5
+ stream_id: number;
6
+ pts?: number;
7
+ dts?: number;
8
+ nearest_pts?: number;
9
+ ancillaries: AncillaryData[];
10
+ data: Uint8Array;
11
+ len: number;
12
+ }
13
+
14
+ type AncillaryData = {
15
+ yc_indicator: boolean;
16
+ line_number: number;
17
+ horizontal_offset: number;
18
+ did: number;
19
+ sdid: number;
20
+ user_data: Uint8Array;
21
+ description: string;
22
+ information: any;
23
+ }
24
+
25
+
26
+ export const smpte2038parse = (data: Uint8Array) => {
27
+ let gb = new ExpGolomb(data);
28
+ let readBits = 0;
29
+
30
+ let ancillaries: AncillaryData[] = [];
31
+ while (true) {
32
+ let zero = gb.readBits(6); readBits += 6;
33
+ if (zero !== 0) { break; }
34
+ let YC_indicator = gb.readBool(); readBits += 1;
35
+ let line_number = gb.readBits(11); readBits += 11;
36
+ let horizontal_offset = gb.readBits(12); readBits += 12;
37
+ let data_ID = gb.readBits(10) & 0xFF; readBits += 10;
38
+ let data_SDID = gb.readBits(10) & 0xFF; readBits += 10;
39
+ let data_count = gb.readBits(10) & 0xFF; readBits += 10;
40
+ let user_data = new Uint8Array(data_count);
41
+ for (let i = 0; i < data_count; i++) {
42
+ let user_data_word = gb.readBits(10) & 0xFF; readBits += 10;
43
+ user_data[i] = user_data_word;
44
+ }
45
+ let checksum_word = gb.readBits(10); readBits += 10;
46
+
47
+ let description = 'User Defined';
48
+ let information: any = {};
49
+ if (data_ID === 0x41) {
50
+ if (data_SDID === 0x07) {
51
+ description = 'SCTE-104'
52
+ }
53
+ } else if (data_ID === 0x5F) {
54
+ if (data_SDID === 0xDC) {
55
+ description = 'ARIB STD-B37 (1SEG)';
56
+ } else if (data_SDID === 0xDD) {
57
+ description = 'ARIB STD-B37 (ANALOG)';
58
+ } else if (data_SDID === 0xDE) {
59
+ description = 'ARIB STD-B37 (SD)';
60
+ } else if (data_SDID === 0xDF) {
61
+ description = 'ARIB STD-B37 (HD)';
62
+ }
63
+ } else if (data_ID === 0x61) {
64
+ if (data_SDID === 0x01) {
65
+ description = 'EIA-708';
66
+ } else if (data_SDID === 0x02) {
67
+ description = 'EIA-608';
68
+ }
69
+ }
70
+
71
+ ancillaries.push({
72
+ yc_indicator: YC_indicator,
73
+ line_number,
74
+ horizontal_offset,
75
+ did: data_ID,
76
+ sdid: data_SDID,
77
+ user_data,
78
+ description,
79
+ information
80
+ });
81
+ gb.readBits(8 - (readBits - Math.floor(readBits / 8)) % 8);
82
+ readBits += (8 - (readBits - Math.floor(readBits / 8))) % 8;
83
+ }
84
+
85
+ gb.destroy();
86
+ gb = null;
87
+
88
+ return ancillaries;
89
+ }
@@ -0,0 +1,298 @@
1
+ /*
2
+ * Copyright (C) 2016 Bilibili. All Rights Reserved.
3
+ *
4
+ * @author zheng qian <xqq@xqq.im>
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import ExpGolomb from './exp-golomb.js';
20
+
21
+ class SPSParser {
22
+
23
+ static _ebsp2rbsp(uint8array) {
24
+ let src = uint8array;
25
+ let src_length = src.byteLength;
26
+ let dst = new Uint8Array(src_length);
27
+ let dst_idx = 0;
28
+
29
+ for (let i = 0; i < src_length; i++) {
30
+ if (i >= 2) {
31
+ // Unescape: Skip 0x03 after 00 00
32
+ if (src[i] === 0x03 && src[i - 1] === 0x00 && src[i - 2] === 0x00) {
33
+ continue;
34
+ }
35
+ }
36
+ dst[dst_idx] = src[i];
37
+ dst_idx++;
38
+ }
39
+
40
+ return new Uint8Array(dst.buffer, 0, dst_idx);
41
+ }
42
+
43
+ static parseSPS(uint8array) {
44
+ let codec_array = uint8array.subarray(1, 4);
45
+ let codec_mimetype = 'avc1.';
46
+ for (let j = 0; j < 3; j++) {
47
+ let h = codec_array[j].toString(16);
48
+ if (h.length < 2) {
49
+ h = '0' + h;
50
+ }
51
+ codec_mimetype += h;
52
+ }
53
+
54
+ let rbsp = SPSParser._ebsp2rbsp(uint8array);
55
+ let gb = new ExpGolomb(rbsp);
56
+
57
+ gb.readByte();
58
+ let profile_idc = gb.readByte(); // profile_idc
59
+ gb.readByte(); // constraint_set_flags[5] + reserved_zero[3]
60
+ let level_idc = gb.readByte(); // level_idc
61
+ gb.readUEG(); // seq_parameter_set_id
62
+
63
+ let profile_string = SPSParser.getProfileString(profile_idc);
64
+ let level_string = SPSParser.getLevelString(level_idc);
65
+ let chroma_format_idc = 1;
66
+ let chroma_format = 420;
67
+ let chroma_format_table = [0, 420, 422, 444];
68
+ let bit_depth_luma = 8;
69
+ let bit_depth_chroma = 8;
70
+
71
+ if (profile_idc === 100 || profile_idc === 110 || profile_idc === 122 ||
72
+ profile_idc === 244 || profile_idc === 44 || profile_idc === 83 ||
73
+ profile_idc === 86 || profile_idc === 118 || profile_idc === 128 ||
74
+ profile_idc === 138 || profile_idc === 144) {
75
+
76
+ chroma_format_idc = gb.readUEG();
77
+ if (chroma_format_idc === 3) {
78
+ gb.readBits(1); // separate_colour_plane_flag
79
+ }
80
+ if (chroma_format_idc <= 3) {
81
+ chroma_format = chroma_format_table[chroma_format_idc];
82
+ }
83
+
84
+ bit_depth_luma = gb.readUEG() + 8; // bit_depth_luma_minus8
85
+ bit_depth_chroma = gb.readUEG() + 8; // bit_depth_chroma_minus8
86
+ gb.readBits(1); // qpprime_y_zero_transform_bypass_flag
87
+ if (gb.readBool()) { // seq_scaling_matrix_present_flag
88
+ let scaling_list_count = (chroma_format_idc !== 3) ? 8 : 12;
89
+ for (let i = 0; i < scaling_list_count; i++) {
90
+ if (gb.readBool()) { // seq_scaling_list_present_flag
91
+ if (i < 6) {
92
+ SPSParser._skipScalingList(gb, 16);
93
+ } else {
94
+ SPSParser._skipScalingList(gb, 64);
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ gb.readUEG(); // log2_max_frame_num_minus4
101
+ let pic_order_cnt_type = gb.readUEG();
102
+ if (pic_order_cnt_type === 0) {
103
+ gb.readUEG(); // log2_max_pic_order_cnt_lsb_minus_4
104
+ } else if (pic_order_cnt_type === 1) {
105
+ gb.readBits(1); // delta_pic_order_always_zero_flag
106
+ gb.readSEG(); // offset_for_non_ref_pic
107
+ gb.readSEG(); // offset_for_top_to_bottom_field
108
+ let num_ref_frames_in_pic_order_cnt_cycle = gb.readUEG();
109
+ for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {
110
+ gb.readSEG(); // offset_for_ref_frame
111
+ }
112
+ }
113
+ let ref_frames = gb.readUEG(); // max_num_ref_frames
114
+ gb.readBits(1); // gaps_in_frame_num_value_allowed_flag
115
+
116
+ let pic_width_in_mbs_minus1 = gb.readUEG();
117
+ let pic_height_in_map_units_minus1 = gb.readUEG();
118
+
119
+ let frame_mbs_only_flag = gb.readBits(1);
120
+ if (frame_mbs_only_flag === 0) {
121
+ gb.readBits(1); // mb_adaptive_frame_field_flag
122
+ }
123
+ gb.readBits(1); // direct_8x8_inference_flag
124
+
125
+ let frame_crop_left_offset = 0;
126
+ let frame_crop_right_offset = 0;
127
+ let frame_crop_top_offset = 0;
128
+ let frame_crop_bottom_offset = 0;
129
+
130
+ let frame_cropping_flag = gb.readBool();
131
+ if (frame_cropping_flag) {
132
+ frame_crop_left_offset = gb.readUEG();
133
+ frame_crop_right_offset = gb.readUEG();
134
+ frame_crop_top_offset = gb.readUEG();
135
+ frame_crop_bottom_offset = gb.readUEG();
136
+ }
137
+
138
+ let sar_width = 1, sar_height = 1;
139
+ let fps = 0, fps_fixed = true, fps_num = 0, fps_den = 0;
140
+
141
+ let vui_parameters_present_flag = gb.readBool();
142
+ if (vui_parameters_present_flag) {
143
+ if (gb.readBool()) { // aspect_ratio_info_present_flag
144
+ let aspect_ratio_idc = gb.readByte();
145
+ let sar_w_table = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2];
146
+ let sar_h_table = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1];
147
+
148
+ if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {
149
+ sar_width = sar_w_table[aspect_ratio_idc - 1];
150
+ sar_height = sar_h_table[aspect_ratio_idc - 1];
151
+ } else if (aspect_ratio_idc === 255) {
152
+ sar_width = gb.readByte() << 8 | gb.readByte();
153
+ sar_height = gb.readByte() << 8 | gb.readByte();
154
+ }
155
+ }
156
+
157
+ if (gb.readBool()) { // overscan_info_present_flag
158
+ gb.readBool(); // overscan_appropriate_flag
159
+ }
160
+ if (gb.readBool()) { // video_signal_type_present_flag
161
+ gb.readBits(4); // video_format & video_full_range_flag
162
+ if (gb.readBool()) { // colour_description_present_flag
163
+ gb.readBits(24); // colour_primaries & transfer_characteristics & matrix_coefficients
164
+ }
165
+ }
166
+ if (gb.readBool()) { // chroma_loc_info_present_flag
167
+ gb.readUEG(); // chroma_sample_loc_type_top_field
168
+ gb.readUEG(); // chroma_sample_loc_type_bottom_field
169
+ }
170
+ if (gb.readBool()) { // timing_info_present_flag
171
+ let num_units_in_tick = gb.readBits(32);
172
+ let time_scale = gb.readBits(32);
173
+ fps_fixed = gb.readBool(); // fixed_frame_rate_flag
174
+
175
+ fps_num = time_scale;
176
+ fps_den = num_units_in_tick * 2;
177
+ fps = fps_num / fps_den;
178
+ }
179
+ }
180
+
181
+ let sarScale = 1;
182
+ if (sar_width !== 1 || sar_height !== 1) {
183
+ sarScale = sar_width / sar_height;
184
+ }
185
+
186
+ let crop_unit_x = 0, crop_unit_y = 0;
187
+ if (chroma_format_idc === 0) {
188
+ crop_unit_x = 1;
189
+ crop_unit_y = 2 - frame_mbs_only_flag;
190
+ } else {
191
+ let sub_wc = (chroma_format_idc === 3) ? 1 : 2;
192
+ let sub_hc = (chroma_format_idc === 1) ? 2 : 1;
193
+ crop_unit_x = sub_wc;
194
+ crop_unit_y = sub_hc * (2 - frame_mbs_only_flag);
195
+ }
196
+
197
+ let codec_width = (pic_width_in_mbs_minus1 + 1) * 16;
198
+ let codec_height = (2 - frame_mbs_only_flag) * ((pic_height_in_map_units_minus1 + 1) * 16);
199
+
200
+ codec_width -= (frame_crop_left_offset + frame_crop_right_offset) * crop_unit_x;
201
+ codec_height -= (frame_crop_top_offset + frame_crop_bottom_offset) * crop_unit_y;
202
+
203
+ let present_width = Math.ceil(codec_width * sarScale);
204
+
205
+ gb.destroy();
206
+ gb = null;
207
+
208
+ return {
209
+ codec_mimetype,
210
+ profile_idc,
211
+ level_idc,
212
+ profile_string, // baseline, high, high10, ...
213
+ level_string, // 3, 3.1, 4, 4.1, 5, 5.1, ...
214
+ chroma_format_idc,
215
+ bit_depth: bit_depth_luma, // 8bit, 10bit, ...
216
+ bit_depth_luma,
217
+ bit_depth_chroma,
218
+ ref_frames,
219
+ chroma_format, // 4:2:0, 4:2:2, ...
220
+ chroma_format_string: SPSParser.getChromaFormatString(chroma_format),
221
+
222
+ frame_rate: {
223
+ fixed: fps_fixed,
224
+ fps: fps,
225
+ fps_den: fps_den,
226
+ fps_num: fps_num
227
+ },
228
+
229
+ sar_ratio: {
230
+ width: sar_width,
231
+ height: sar_height
232
+ },
233
+
234
+ codec_size: {
235
+ width: codec_width,
236
+ height: codec_height
237
+ },
238
+
239
+ present_size: {
240
+ width: present_width,
241
+ height: codec_height
242
+ }
243
+ };
244
+ }
245
+
246
+ static _skipScalingList(gb, count) {
247
+ let last_scale = 8, next_scale = 8;
248
+ let delta_scale = 0;
249
+ for (let i = 0; i < count; i++) {
250
+ if (next_scale !== 0) {
251
+ delta_scale = gb.readSEG();
252
+ next_scale = (last_scale + delta_scale + 256) % 256;
253
+ }
254
+ last_scale = (next_scale === 0) ? last_scale : next_scale;
255
+ }
256
+ }
257
+
258
+ static getProfileString(profile_idc) {
259
+ switch (profile_idc) {
260
+ case 66:
261
+ return 'Baseline';
262
+ case 77:
263
+ return 'Main';
264
+ case 88:
265
+ return 'Extended';
266
+ case 100:
267
+ return 'High';
268
+ case 110:
269
+ return 'High10';
270
+ case 122:
271
+ return 'High422';
272
+ case 244:
273
+ return 'High444';
274
+ default:
275
+ return 'Unknown';
276
+ }
277
+ }
278
+
279
+ static getLevelString(level_idc) {
280
+ return (level_idc / 10).toFixed(1);
281
+ }
282
+
283
+ static getChromaFormatString(chroma) {
284
+ switch (chroma) {
285
+ case 420:
286
+ return '4:2:0';
287
+ case 422:
288
+ return '4:2:2';
289
+ case 444:
290
+ return '4:4:4';
291
+ default:
292
+ return 'Unknown';
293
+ }
294
+ }
295
+
296
+ }
297
+
298
+ export default SPSParser;