nal-helpers.js
3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.findH265Nal = exports.findH264Nal = exports.findNal = exports.discardEmulationPreventionBytes = exports.EMULATION_PREVENTION = exports.NAL_TYPE_TWO = exports.NAL_TYPE_ONE = void 0;
var _byteHelpers = require("./byte-helpers.js");
var NAL_TYPE_ONE = (0, _byteHelpers.toUint8)([0x00, 0x00, 0x00, 0x01]);
exports.NAL_TYPE_ONE = NAL_TYPE_ONE;
var NAL_TYPE_TWO = (0, _byteHelpers.toUint8)([0x00, 0x00, 0x01]);
exports.NAL_TYPE_TWO = NAL_TYPE_TWO;
var EMULATION_PREVENTION = (0, _byteHelpers.toUint8)([0x00, 0x00, 0x03]);
/**
* Expunge any "Emulation Prevention" bytes from a "Raw Byte
* Sequence Payload"
*
* @param data {Uint8Array} the bytes of a RBSP from a NAL
* unit
* @return {Uint8Array} the RBSP without any Emulation
* Prevention Bytes
*/
exports.EMULATION_PREVENTION = EMULATION_PREVENTION;
var discardEmulationPreventionBytes = function discardEmulationPreventionBytes(bytes) {
var positions = [];
var i = 1; // Find all `Emulation Prevention Bytes`
while (i < bytes.length - 2) {
if ((0, _byteHelpers.bytesMatch)(bytes.subarray(i, i + 3), EMULATION_PREVENTION)) {
positions.push(i + 2);
i++;
}
i++;
} // If no Emulation Prevention Bytes were found just return the original
// array
if (positions.length === 0) {
return bytes;
} // Create a new array to hold the NAL unit data
var newLength = bytes.length - positions.length;
var newData = new Uint8Array(newLength);
var sourceIndex = 0;
for (i = 0; i < newLength; sourceIndex++, i++) {
if (sourceIndex === positions[0]) {
// Skip this byte
sourceIndex++; // Remove this position index
positions.shift();
}
newData[i] = bytes[sourceIndex];
}
return newData;
};
exports.discardEmulationPreventionBytes = discardEmulationPreventionBytes;
var findNal = function findNal(bytes, dataType, types, nalLimit) {
if (nalLimit === void 0) {
nalLimit = Infinity;
}
bytes = (0, _byteHelpers.toUint8)(bytes);
types = [].concat(types);
var i = 0;
var nalStart;
var nalsFound = 0; // keep searching until:
// we reach the end of bytes
// we reach the maximum number of nals they want to seach
// NOTE: that we disregard nalLimit when we have found the start
// of the nal we want so that we can find the end of the nal we want.
while (i < bytes.length && (nalsFound < nalLimit || nalStart)) {
var nalOffset = void 0;
if ((0, _byteHelpers.bytesMatch)(bytes.subarray(i), NAL_TYPE_ONE)) {
nalOffset = 4;
} else if ((0, _byteHelpers.bytesMatch)(bytes.subarray(i), NAL_TYPE_TWO)) {
nalOffset = 3;
} // we are unsynced,
// find the next nal unit
if (!nalOffset) {
i++;
continue;
}
nalsFound++;
if (nalStart) {
return discardEmulationPreventionBytes(bytes.subarray(nalStart, i));
}
var nalType = void 0;
if (dataType === 'h264') {
nalType = bytes[i + nalOffset] & 0x1f;
} else if (dataType === 'h265') {
nalType = bytes[i + nalOffset] >> 1 & 0x3f;
}
if (types.indexOf(nalType) !== -1) {
nalStart = i + nalOffset;
} // nal header is 1 length for h264, and 2 for h265
i += nalOffset + (dataType === 'h264' ? 1 : 2);
}
return bytes.subarray(0, 0);
};
exports.findNal = findNal;
var findH264Nal = function findH264Nal(bytes, type, nalLimit) {
return findNal(bytes, 'h264', type, nalLimit);
};
exports.findH264Nal = findH264Nal;
var findH265Nal = function findH265Nal(bytes, type, nalLimit) {
return findNal(bytes, 'h265', type, nalLimit);
};
exports.findH265Nal = findH265Nal;