init commit

This commit is contained in:
Carlos
2026-02-21 10:33:18 +01:00
parent c863a943ed
commit 9d955bf338
9512 changed files with 2015317 additions and 1305 deletions

View File

@@ -0,0 +1,2 @@
import type { AvcProfileInfo } from './parse-avc';
export declare const getCodecStringFromSpsAndPps: (sps: AvcProfileInfo) => string;

View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCodecStringFromSpsAndPps = void 0;
const getCodecStringFromSpsAndPps = (sps) => {
return `avc1.${sps.spsData.profile.toString(16).padStart(2, '0')}${sps.spsData.compatibility.toString(16).padStart(2, '0')}${sps.spsData.level.toString(16).padStart(2, '0')}`;
};
exports.getCodecStringFromSpsAndPps = getCodecStringFromSpsAndPps;

View File

@@ -0,0 +1,6 @@
export type MediaParserMatrixCoefficients = 'rgb' | 'bt709' | 'bt470bg' | 'smpte170m' | 'bt2020-ncl';
export declare const getMatrixCoefficientsFromIndex: (index: number) => MediaParserMatrixCoefficients | null;
export type MediaParserTransferCharacteristics = 'bt709' | 'smpte170m' | 'iec61966-2-1' | 'linear' | 'pq' | 'hlg';
export declare const getTransferCharacteristicsFromIndex: (index: number) => MediaParserTransferCharacteristics | null;
export type MediaParserPrimaries = 'bt709' | 'bt470bg' | 'smpte170m' | 'bt2020' | 'smpte432' | null;
export declare const getPrimariesFromIndex: (index: number) => MediaParserPrimaries | null;

View File

@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPrimariesFromIndex = exports.getTransferCharacteristicsFromIndex = exports.getMatrixCoefficientsFromIndex = void 0;
const getMatrixCoefficientsFromIndex = (index) => {
if (index === 0) {
return 'rgb';
}
if (index === 1) {
return 'bt709';
}
if (index === 5) {
return 'bt470bg';
}
if (index === 6) {
return 'smpte170m';
}
if (index === 9) {
return 'bt2020-ncl';
}
return null;
};
exports.getMatrixCoefficientsFromIndex = getMatrixCoefficientsFromIndex;
// https://w3c.github.io/webcodecs/#videotransfercharacteristics
// But we may support more than that
const getTransferCharacteristicsFromIndex = (index) => {
if (index === 1) {
return 'bt709';
}
if (index === 6) {
return 'smpte170m';
}
if (index === 8) {
return 'linear';
}
if (index === 13) {
return 'iec61966-2-1';
}
if (index === 16) {
return 'pq';
}
if (index === 18) {
return 'hlg';
}
return null;
};
exports.getTransferCharacteristicsFromIndex = getTransferCharacteristicsFromIndex;
const getPrimariesFromIndex = (index) => {
if (index === 1) {
return 'bt709';
}
if (index === 5) {
return 'bt470bg';
}
if (index === 6) {
return 'smpte170m';
}
if (index === 9) {
return 'bt2020';
}
if (index === 12) {
return 'smpte432';
}
return null;
};
exports.getPrimariesFromIndex = getPrimariesFromIndex;

View File

@@ -0,0 +1,2 @@
import type { SpsAndPps } from '../../state/parser-state';
export declare const createSpsPpsData: (avc1Profile: SpsAndPps) => Uint8Array<ArrayBufferLike>;

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSpsPpsData = void 0;
const combine_uint8_arrays_1 = require("../../combine-uint8-arrays");
const truthy_1 = require("../../truthy");
function serializeUint16(value) {
const buffer = new ArrayBuffer(2);
const view = new DataView(buffer);
view.setUint16(0, value);
return new Uint8Array(buffer);
}
const createSpsPpsData = (avc1Profile) => {
return (0, combine_uint8_arrays_1.combineUint8Arrays)([
new Uint8Array([
// https://gist.github.com/uupaa/8493378ec15f644a3d2b
1, // version
avc1Profile.sps.spsData.profile,
avc1Profile.sps.spsData.compatibility,
avc1Profile.sps.spsData.level,
0xff,
0xe1,
]),
// sequence parameter set length
serializeUint16(avc1Profile.sps.sps.length),
// sequence parameter set
avc1Profile.sps.sps,
// num of PPS
new Uint8Array([0x01]),
// picture parameter set length
serializeUint16(avc1Profile.pps.pps.length),
// PPS
avc1Profile.pps.pps,
// if AVCProfileIndication != 66 && AVCProfileIndication != 77 && AVCProfileIndication != 88
[66, 77, 88].some((b) => avc1Profile.sps.spsData.profile === b)
? null
: /**
* reserved 63 (0x3F)
chroma_format 1, '4:2:0'
reserved 31 (0x1F)
bit_depth_luma_minus8 0
reserved 31 (0x1F)
bit_depth_chroma_minus8 0
numOfSequenceParameterSetExt 0
*/
new Uint8Array([0xfd, 0xf8, 0xf8, 0]),
].filter(truthy_1.truthy));
};
exports.createSpsPpsData = createSpsPpsData;

View File

@@ -0,0 +1,11 @@
import type { MediaParserAdvancedColor } from '../../get-tracks';
import type { SpsInfo } from './parse-avc';
export declare const getDimensionsFromSps: (sps: SpsInfo) => {
height: number;
width: number;
};
export declare const getSampleAspectRatioFromSps: (sps: SpsInfo) => {
width: number;
height: number;
};
export declare const getVideoColorFromSps: (sps: SpsInfo) => MediaParserAdvancedColor;

View File

@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getVideoColorFromSps = exports.getSampleAspectRatioFromSps = exports.getDimensionsFromSps = void 0;
const color_1 = require("./color");
const getDimensionsFromSps = (sps) => {
var _a, _b, _c, _d;
const height = sps.pic_height_in_map_units_minus1;
const width = sps.pic_width_in_mbs_minus1;
// https://stackoverflow.com/questions/12018535/get-the-width-height-of-the-video-from-h-264-nalu
return {
height: (height + 1) * 16 -
((_a = sps.frame_crop_bottom_offset) !== null && _a !== void 0 ? _a : 0) * 2 -
((_b = sps.frame_crop_top_offset) !== null && _b !== void 0 ? _b : 0) * 2,
width: (width + 1) * 16 -
((_c = sps.frame_crop_right_offset) !== null && _c !== void 0 ? _c : 0) * 2 -
((_d = sps.frame_crop_left_offset) !== null && _d !== void 0 ? _d : 0) * 2,
};
};
exports.getDimensionsFromSps = getDimensionsFromSps;
const getSampleAspectRatioFromSps = (sps) => {
var _a;
if (((_a = sps.vui_parameters) === null || _a === void 0 ? void 0 : _a.sar_height) && sps.vui_parameters.sar_width) {
return {
width: sps.vui_parameters.sar_width,
height: sps.vui_parameters.sar_height,
};
}
return {
width: 1,
height: 1,
};
};
exports.getSampleAspectRatioFromSps = getSampleAspectRatioFromSps;
const getVideoColorFromSps = (sps) => {
var _a, _b, _c, _d, _e;
const matrixCoefficients = (_a = sps.vui_parameters) === null || _a === void 0 ? void 0 : _a.matrix_coefficients;
const transferCharacteristics = (_b = sps.vui_parameters) === null || _b === void 0 ? void 0 : _b.transfer_characteristics;
const colorPrimaries = (_c = sps.vui_parameters) === null || _c === void 0 ? void 0 : _c.colour_primaries;
return {
matrix: matrixCoefficients
? (0, color_1.getMatrixCoefficientsFromIndex)(matrixCoefficients)
: null,
transfer: transferCharacteristics
? (0, color_1.getTransferCharacteristicsFromIndex)(transferCharacteristics)
: null,
primaries: colorPrimaries ? (0, color_1.getPrimariesFromIndex)(colorPrimaries) : null,
fullRange: (_e = (_d = sps.vui_parameters) === null || _d === void 0 ? void 0 : _d.video_full_range_flag) !== null && _e !== void 0 ? _e : null,
};
};
exports.getVideoColorFromSps = getVideoColorFromSps;

View File

@@ -0,0 +1,2 @@
import type { AvcInfo } from './parse-avc';
export declare const getKeyFrameOrDeltaFromAvcInfo: (infos: AvcInfo[]) => "key" | "delta" | "bidirectional";

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getKeyFrameOrDeltaFromAvcInfo = void 0;
const getKeyFrameOrDeltaFromAvcInfo = (infos) => {
const keyOrDelta = infos.find((i) => i.type === 'keyframe' || i.type === 'delta-frame');
if (!keyOrDelta) {
throw new Error('expected avc to contain info about key or delta');
}
return keyOrDelta.type === 'keyframe'
? 'key'
: keyOrDelta.isBidirectionalFrame
? 'bidirectional'
: 'delta';
};
exports.getKeyFrameOrDeltaFromAvcInfo = getKeyFrameOrDeltaFromAvcInfo;

View File

@@ -0,0 +1,3 @@
import type { SpsInfo } from './parse-avc';
export declare const macroBlocksPerFrame: (sps: SpsInfo) => number;
export declare const maxMacroblockBufferSize: (sps: SpsInfo) => number;

View File

@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.maxMacroblockBufferSize = exports.macroBlocksPerFrame = void 0;
// https://www.itu.int/rec/T-REC-H.264-202408-I
// Table A-1 – Level limits
const maxMacroblocksByLevel = {
10: 396, // Level 1.0
11: 900, // Level 1.1
12: 2376, // Level 1.2
13: 2376, // Level 1.3
20: 2376, // Level 2.0
21: 4752, // Level 2.1
22: 8100, // Level 2.2
30: 8100, // Level 3.0
31: 18000, // Level 3.1
32: 20480, // Level 3.2
40: 32768, // Level 4.0
41: 32768, // Level 4.1
42: 34816, // Level 4.2
50: 110400, // Level 5.0
51: 184320, // Level 5.1
52: 184320, // Level 5.2
60: 696320, // Level 6.0
61: 696320, // Level 6.1
62: 696320, // Level 6.2
};
const macroBlocksPerFrame = (sps) => {
const { pic_width_in_mbs_minus1, pic_height_in_map_units_minus1 } = sps;
return (pic_width_in_mbs_minus1 + 1) * (pic_height_in_map_units_minus1 + 1);
};
exports.macroBlocksPerFrame = macroBlocksPerFrame;
const maxMacroblockBufferSize = (sps) => {
const { level } = sps;
const maxMacroblocks = maxMacroblocksByLevel[level];
if (maxMacroblocks === undefined) {
throw new Error(`Unsupported level: ${level.toString(16)}`);
}
return maxMacroblocks;
};
exports.maxMacroblockBufferSize = maxMacroblockBufferSize;

View File

@@ -0,0 +1,50 @@
import type { AvcState } from '../../state/avc/avc-state';
import type { MediaParserAvcDeltaFrameInfo, MediaParserAvcKeyframeInfo } from '../../webcodec-sample-types';
type VuiParameters = {
sar_width: number | null;
sar_height: number | null;
overscan_appropriate_flag: number | null;
video_format: number | null;
video_full_range_flag: boolean | null;
colour_primaries: number | null;
transfer_characteristics: number | null;
matrix_coefficients: number | null;
chroma_sample_loc_type_top_field: number | null;
chroma_sample_loc_type_bottom_field: number | null;
};
export type SpsInfo = {
profile: number;
compatibility: number;
level: number;
seq_parameter_set_id: number;
separate_colour_plane_flag: number | null;
bit_depth_luma_minus8: number | null;
bit_depth_chroma_minus8: number | null;
qpprime_y_zero_transform_bypass_flag: number | null;
log2_max_frame_num_minus4: number;
log2_max_pic_order_cnt_lsb_minus4: number | null;
max_num_ref_frames: number | null;
gaps_in_frame_num_value_allowed_flag: number | null;
pic_width_in_mbs_minus1: number;
pic_height_in_map_units_minus1: number;
mb_adaptive_frame_field_flag: number | null;
direct_8x8_inference_flag: number | null;
frame_crop_left_offset: number | null;
frame_crop_right_offset: number | null;
frame_crop_top_offset: number | null;
frame_crop_bottom_offset: number | null;
vui_parameters: VuiParameters | null;
pic_order_cnt_type: number;
};
export type AvcProfileInfo = {
spsData: SpsInfo;
sps: Uint8Array;
type: 'avc-profile';
};
export type AvcPPs = {
type: 'avc-pps';
pps: Uint8Array;
};
export type AvcInfo = AvcProfileInfo | AvcPPs | MediaParserAvcKeyframeInfo | MediaParserAvcDeltaFrameInfo;
export declare const parseAvc: (buffer: Uint8Array, avcState: AvcState) => AvcInfo[];
export {};

View File

@@ -0,0 +1,332 @@
"use strict";
// https://www.itu.int/rec/T-REC-H.264-202408-I/en
// Page 455
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseAvc = void 0;
const buffer_iterator_1 = require("../../iterator/buffer-iterator");
const Extended_SAR = 255;
const getPoc = (iterator, sps, avcState, isReferencePicture) => {
const { pic_order_cnt_type, log2_max_pic_order_cnt_lsb_minus4 } = sps;
if (pic_order_cnt_type !== 0) {
return null;
}
const prevPicOrderCntLsb = avcState.getPrevPicOrderCntLsb();
const prevPicOrderCntMsb = avcState.getPrevPicOrderCntMsb();
if (log2_max_pic_order_cnt_lsb_minus4 === null) {
throw new Error('log2_max_pic_order_cnt_lsb_minus4 is null');
}
const max_pic_order_cnt_lsb = 2 ** (log2_max_pic_order_cnt_lsb_minus4 + 4);
const pic_order_cnt_lsb = iterator.getBits(log2_max_pic_order_cnt_lsb_minus4 + 4);
let picOrderCntMsb;
if (pic_order_cnt_lsb < prevPicOrderCntLsb &&
prevPicOrderCntLsb - pic_order_cnt_lsb >= max_pic_order_cnt_lsb / 2) {
picOrderCntMsb = prevPicOrderCntMsb + max_pic_order_cnt_lsb;
}
else if (pic_order_cnt_lsb > prevPicOrderCntLsb &&
pic_order_cnt_lsb - prevPicOrderCntLsb > max_pic_order_cnt_lsb / 2) {
picOrderCntMsb = prevPicOrderCntMsb - max_pic_order_cnt_lsb;
}
else {
picOrderCntMsb = prevPicOrderCntMsb;
}
const poc = picOrderCntMsb + pic_order_cnt_lsb;
if (isReferencePicture) {
avcState.setPrevPicOrderCntLsb(pic_order_cnt_lsb);
avcState.setPrevPicOrderCntMsb(picOrderCntMsb);
}
return poc;
};
const readVuiParameters = (iterator) => {
let sar_width = null;
let sar_height = null;
let overscan_appropriate_flag = null;
let video_format = null;
let video_full_range_flag = null;
let colour_primaries = null;
let transfer_characteristics = null;
let matrix_coefficients = null;
let chroma_sample_loc_type_top_field = null;
let chroma_sample_loc_type_bottom_field = null;
const aspect_ratio_info_present_flag = iterator.getBits(1);
if (aspect_ratio_info_present_flag) {
const aspect_ratio_idc = iterator.getBits(8);
if (aspect_ratio_idc === Extended_SAR) {
sar_width = iterator.getBits(16);
sar_height = iterator.getBits(16);
}
}
const overscan_info_present_flag = iterator.getBits(1);
if (overscan_info_present_flag) {
overscan_appropriate_flag = iterator.getBits(1);
}
const video_signal_type_present_flag = iterator.getBits(1);
if (video_signal_type_present_flag) {
video_format = iterator.getBits(3);
video_full_range_flag = Boolean(iterator.getBits(1));
const colour_description_present_flag = iterator.getBits(1);
if (colour_description_present_flag) {
colour_primaries = iterator.getBits(8);
transfer_characteristics = iterator.getBits(8);
matrix_coefficients = iterator.getBits(8);
}
}
const chroma_loc_info_present_flag = iterator.getBits(1);
if (chroma_loc_info_present_flag) {
chroma_sample_loc_type_top_field = iterator.readExpGolomb();
chroma_sample_loc_type_bottom_field = iterator.readExpGolomb();
}
return {
sar_width,
sar_height,
overscan_appropriate_flag,
chroma_sample_loc_type_bottom_field,
chroma_sample_loc_type_top_field,
colour_primaries,
matrix_coefficients,
transfer_characteristics,
video_format,
video_full_range_flag,
};
};
const readSps = (iterator) => {
const profile = iterator.getUint8();
const compatibility = iterator.getUint8();
const level = iterator.getUint8();
iterator.startReadingBits();
const seq_parameter_set_id = iterator.readExpGolomb();
let separate_colour_plane_flag = null;
let bit_depth_luma_minus8 = null;
let bit_depth_chroma_minus8 = null;
let qpprime_y_zero_transform_bypass_flag = null;
let log2_max_frame_num_minus4 = null;
let log2_max_pic_order_cnt_lsb_minus4 = null;
let max_num_ref_frames = null;
let gaps_in_frame_num_value_allowed_flag = null;
let mb_adaptive_frame_field_flag = null;
let direct_8x8_inference_flag = null;
let frame_crop_left_offset = null;
let frame_crop_right_offset = null;
let frame_crop_top_offset = null;
let frame_crop_bottom_offset = null;
let vui_parameters = null;
// Page 71
if (profile === 100 ||
profile === 110 ||
profile === 122 ||
profile === 244 ||
profile === 44 ||
profile === 83 ||
profile === 86 ||
profile === 118 ||
profile === 128 ||
profile === 138 ||
profile === 139 ||
profile === 134 ||
profile === 135) {
const chromaFormat = iterator.readExpGolomb();
if (chromaFormat === 3) {
separate_colour_plane_flag = iterator.getBits(1);
}
bit_depth_luma_minus8 = iterator.readExpGolomb();
bit_depth_chroma_minus8 = iterator.readExpGolomb();
qpprime_y_zero_transform_bypass_flag = iterator.getBits(1);
const seq_scaling_matrix_present_flag = iterator.getBits(1);
const seq_scaling_list_present_flag = [];
if (seq_scaling_matrix_present_flag) {
for (let i = 0; i < (chromaFormat !== 3 ? 8 : 12); i++) {
seq_scaling_list_present_flag[i] = iterator.getBits(1);
if (seq_scaling_list_present_flag[i]) {
if (i < 6) {
// scaling_list not implemented
throw new Error('Not implemented');
}
else {
// scaling_list not implemented
throw new Error('Not implemented');
}
}
}
}
}
log2_max_frame_num_minus4 = iterator.readExpGolomb();
const pic_order_cnt_type = iterator.readExpGolomb();
if (pic_order_cnt_type === 0) {
log2_max_pic_order_cnt_lsb_minus4 = iterator.readExpGolomb();
}
else if (pic_order_cnt_type === 1) {
throw new Error('pic_order_cnt_type = 1 not implemented');
}
max_num_ref_frames = iterator.readExpGolomb();
gaps_in_frame_num_value_allowed_flag = iterator.getBits(1);
const pic_width_in_mbs_minus1 = iterator.readExpGolomb();
const pic_height_in_map_units_minus1 = iterator.readExpGolomb();
const frame_mbs_only_flag = iterator.getBits(1);
if (!frame_mbs_only_flag) {
mb_adaptive_frame_field_flag = iterator.getBits(1);
}
direct_8x8_inference_flag = iterator.getBits(1);
const frame_cropping_flag = iterator.getBits(1);
if (frame_cropping_flag) {
frame_crop_left_offset = iterator.readExpGolomb();
frame_crop_right_offset = iterator.readExpGolomb();
frame_crop_top_offset = iterator.readExpGolomb();
frame_crop_bottom_offset = iterator.readExpGolomb();
}
const vui_parameters_present_flag = iterator.getBits(1);
if (vui_parameters_present_flag) {
vui_parameters = readVuiParameters(iterator);
}
iterator.stopReadingBits();
return {
profile,
compatibility,
level,
bit_depth_chroma_minus8,
bit_depth_luma_minus8,
gaps_in_frame_num_value_allowed_flag,
log2_max_frame_num_minus4,
log2_max_pic_order_cnt_lsb_minus4,
max_num_ref_frames,
pic_height_in_map_units_minus1,
pic_width_in_mbs_minus1,
qpprime_y_zero_transform_bypass_flag,
separate_colour_plane_flag,
seq_parameter_set_id,
direct_8x8_inference_flag,
frame_crop_bottom_offset,
frame_crop_left_offset,
frame_crop_right_offset,
frame_crop_top_offset,
mb_adaptive_frame_field_flag,
vui_parameters,
pic_order_cnt_type,
};
};
const findEnd = (buffer) => {
let zeroesInARow = 0;
for (let i = 0; i < buffer.length; i++) {
const val = buffer[i];
if (val === 0) {
zeroesInARow++;
continue;
}
if (zeroesInARow >= 2 && val === 1) {
return i - zeroesInARow;
}
zeroesInARow = 0;
}
return null;
};
const inspect = (buffer, avcState) => {
const iterator = (0, buffer_iterator_1.getArrayBufferIterator)({
initialData: buffer,
maxBytes: buffer.byteLength,
logLevel: 'error',
});
iterator.startReadingBits();
iterator.getBits(1); // forbidden_zero_bit
const nal_ref_idc = iterator.getBits(2); // nal_ref_idc
const isReferencePicture = nal_ref_idc !== 0;
const type = iterator.getBits(5); // nal_unit_type
if (type === 7) {
iterator.stopReadingBits();
const end = findEnd(buffer);
const data = readSps(iterator);
const sps = buffer.slice(0, end === null ? Infinity : end);
avcState.setSps(data);
if (isReferencePicture) {
avcState.setPrevPicOrderCntLsb(0);
avcState.setPrevPicOrderCntMsb(0);
}
return {
spsData: data,
sps,
type: 'avc-profile',
};
}
if (type === 5) {
avcState.setPrevPicOrderCntLsb(0);
avcState.setPrevPicOrderCntMsb(0);
iterator.readExpGolomb(); // ignore first_mb_in_slice
iterator.readExpGolomb(); // slice_type
iterator.readExpGolomb(); // pic_parameter_set_id
const sps = avcState.getSps();
if (!sps) {
throw new Error('SPS not found');
}
const numberOfBitsForFrameNum = sps.log2_max_frame_num_minus4 + 4;
iterator.getBits(numberOfBitsForFrameNum); // frame_num
iterator.readExpGolomb(); // idr_pic_id
const { pic_order_cnt_type } = sps;
let poc = null;
if (pic_order_cnt_type === 0) {
poc = getPoc(iterator, sps, avcState, isReferencePicture);
}
iterator.stopReadingBits();
return {
type: 'keyframe',
poc,
};
}
if (type === 8) {
iterator.stopReadingBits();
const end = findEnd(buffer);
const pps = buffer.slice(0, end === null ? Infinity : end);
return {
type: 'avc-pps',
pps,
};
}
if (type === 1) {
iterator.readExpGolomb(); // ignore first_mb_in_slice
const slice_type = iterator.readExpGolomb();
const isBidirectionalFrame = slice_type === 6;
iterator.readExpGolomb(); // pic_parameter_set_id
const sps = avcState.getSps();
if (!sps) {
throw new Error('SPS not found');
}
const numberOfBitsForFrameNum = sps.log2_max_frame_num_minus4 + 4;
iterator.getBits(numberOfBitsForFrameNum); // frame_num
const { pic_order_cnt_type } = sps;
let poc = null;
if (pic_order_cnt_type === 0) {
poc = getPoc(iterator, sps, avcState, isReferencePicture);
}
iterator.stopReadingBits();
return {
type: 'delta-frame',
isBidirectionalFrame,
poc,
};
}
iterator.destroy();
return null;
};
// https://stackoverflow.com/questions/24884827/possible-locations-for-sequence-picture-parameter-sets-for-h-264-stream
const parseAvc = (buffer, avcState) => {
let zeroesInARow = 0;
const infos = [];
for (let i = 0; i < buffer.length; i++) {
const val = buffer[i];
if (val === 0) {
zeroesInARow++;
continue;
}
if (zeroesInARow >= 2 && val === 1) {
zeroesInARow = 0;
const info = inspect(buffer.slice(i + 1, i + 100), avcState);
if (info) {
infos.push(info);
if (info.type === 'keyframe' || info.type === 'delta-frame') {
break;
}
}
}
if (val !== 1) {
zeroesInARow = 0;
}
}
return infos;
};
exports.parseAvc = parseAvc;

View File

@@ -0,0 +1,3 @@
import type { SpsAndPps } from '../../state/parser-state';
import type { AvcInfo } from './parse-avc';
export declare const getSpsAndPps: (infos: AvcInfo[]) => SpsAndPps;

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSpsAndPps = void 0;
const getSpsAndPps = (infos) => {
const avcProfile = infos.find((i) => i.type === 'avc-profile');
const ppsProfile = infos.find((i) => i.type === 'avc-pps');
if (!avcProfile || !ppsProfile) {
throw new Error('Expected avcProfile and ppsProfile');
}
return { pps: ppsProfile, sps: avcProfile };
};
exports.getSpsAndPps = getSpsAndPps;