@yume-chan/scrcpy 0.0.19 → 0.0.21
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/CHANGELOG.json +30 -0
- package/CHANGELOG.md +17 -1
- package/README.md +76 -266
- package/esm/codec/av1.js +2 -2
- package/esm/codec/av1.js.map +1 -1
- package/esm/codec/h264.d.ts +1 -21
- package/esm/codec/h264.d.ts.map +1 -1
- package/esm/codec/h264.js +15 -236
- package/esm/codec/h264.js.map +1 -1
- package/esm/codec/h265.d.ts +454 -0
- package/esm/codec/h265.d.ts.map +1 -1
- package/esm/codec/h265.js +1062 -2
- package/esm/codec/h265.js.map +1 -1
- package/esm/codec/index.d.ts +1 -0
- package/esm/codec/index.d.ts.map +1 -1
- package/esm/codec/index.js +1 -0
- package/esm/codec/index.js.map +1 -1
- package/esm/codec/nalu.d.ts +37 -0
- package/esm/codec/nalu.d.ts.map +1 -0
- package/esm/codec/nalu.js +323 -0
- package/esm/codec/nalu.js.map +1 -0
- package/esm/control/back-or-screen-on.d.ts +1 -1
- package/esm/control/back-or-screen-on.d.ts.map +1 -1
- package/esm/control/hover-helper.d.ts +1 -1
- package/esm/control/hover-helper.d.ts.map +1 -1
- package/esm/control/hover-helper.js +8 -9
- package/esm/control/hover-helper.js.map +1 -1
- package/esm/control/index.d.ts +2 -0
- package/esm/control/index.d.ts.map +1 -1
- package/esm/control/index.js +2 -0
- package/esm/control/index.js.map +1 -1
- package/esm/control/inject-keycode.d.ts +1 -2
- package/esm/control/inject-keycode.d.ts.map +1 -1
- package/esm/control/inject-keycode.js +4 -5
- package/esm/control/inject-keycode.js.map +1 -1
- package/esm/control/inject-text.d.ts +1 -2
- package/esm/control/inject-text.d.ts.map +1 -1
- package/esm/control/inject-text.js +1 -2
- package/esm/control/inject-text.js.map +1 -1
- package/esm/control/inject-touch.d.ts +15 -20
- package/esm/control/inject-touch.d.ts.map +1 -1
- package/esm/control/inject-touch.js +16 -43
- package/esm/control/inject-touch.js.map +1 -1
- package/esm/control/rotate-device.d.ts +2 -4
- package/esm/control/rotate-device.d.ts.map +1 -1
- package/esm/control/rotate-device.js +2 -3
- package/esm/control/rotate-device.js.map +1 -1
- package/esm/control/serializer.d.ts +11 -23
- package/esm/control/serializer.d.ts.map +1 -1
- package/esm/control/serializer.js +23 -52
- package/esm/control/serializer.js.map +1 -1
- package/esm/control/set-screen-power-mode.d.ts +1 -2
- package/esm/control/set-screen-power-mode.d.ts.map +1 -1
- package/esm/control/set-screen-power-mode.js +2 -3
- package/esm/control/set-screen-power-mode.js.map +1 -1
- package/esm/control/type.d.ts +14 -0
- package/esm/control/type.d.ts.map +1 -1
- package/esm/control/type.js +23 -1
- package/esm/control/type.js.map +1 -1
- package/esm/control/writer.d.ts +26 -0
- package/esm/control/writer.d.ts.map +1 -0
- package/esm/control/writer.js +53 -0
- package/esm/control/writer.js.map +1 -0
- package/esm/device-message/stream.d.ts.map +1 -1
- package/esm/device-message/stream.js +23 -8
- package/esm/device-message/stream.js.map +1 -1
- package/esm/device-message/type.js +1 -1
- package/esm/device-message/type.js.map +1 -1
- package/esm/index.d.ts +1 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -2
- package/esm/index.js.map +1 -1
- package/esm/options/1_16/codec-options.d.ts +2 -3
- package/esm/options/1_16/codec-options.d.ts.map +1 -1
- package/esm/options/1_16/codec-options.js.map +1 -1
- package/esm/options/1_16/index.d.ts +3 -1
- package/esm/options/1_16/index.d.ts.map +1 -1
- package/esm/options/1_16/index.js +3 -1
- package/esm/options/1_16/index.js.map +1 -1
- package/esm/options/1_16/init.js +2 -2
- package/esm/options/1_16/init.js.map +1 -1
- package/esm/options/1_16/options.d.ts +42 -96
- package/esm/options/1_16/options.d.ts.map +1 -1
- package/esm/options/1_16/options.js +104 -142
- package/esm/options/1_16/options.js.map +1 -1
- package/esm/options/1_16/scroll.d.ts +2 -4
- package/esm/options/1_16/scroll.d.ts.map +1 -1
- package/esm/options/1_16/scroll.js +13 -14
- package/esm/options/1_16/scroll.js.map +1 -1
- package/esm/options/1_17.d.ts +1 -0
- package/esm/options/1_17.d.ts.map +1 -1
- package/esm/options/1_17.js +8 -3
- package/esm/options/1_17.js.map +1 -1
- package/esm/options/1_18.d.ts +49 -11
- package/esm/options/1_18.d.ts.map +1 -1
- package/esm/options/1_18.js +64 -32
- package/esm/options/1_18.js.map +1 -1
- package/esm/options/1_21.d.ts +26 -7
- package/esm/options/1_21.d.ts.map +1 -1
- package/esm/options/1_21.js +34 -20
- package/esm/options/1_21.js.map +1 -1
- package/esm/options/1_22/index.d.ts +1 -0
- package/esm/options/1_22/index.d.ts.map +1 -1
- package/esm/options/1_22/index.js +1 -0
- package/esm/options/1_22/index.js.map +1 -1
- package/esm/options/1_22/options.d.ts +32 -26
- package/esm/options/1_22/options.d.ts.map +1 -1
- package/esm/options/1_22/options.js +26 -16
- package/esm/options/1_22/options.js.map +1 -1
- package/esm/options/1_22/scroll.d.ts +1 -1
- package/esm/options/1_22/scroll.d.ts.map +1 -1
- package/esm/options/1_22/scroll.js +1 -1
- package/esm/options/1_22/scroll.js.map +1 -1
- package/esm/options/1_23.d.ts +32 -8
- package/esm/options/1_23.d.ts.map +1 -1
- package/esm/options/1_23.js +23 -14
- package/esm/options/1_23.js.map +1 -1
- package/esm/options/1_24.d.ts +29 -4
- package/esm/options/1_24.d.ts.map +1 -1
- package/esm/options/1_24.js +16 -7
- package/esm/options/1_24.js.map +1 -1
- package/esm/options/1_25/options.d.ts +6 -2
- package/esm/options/1_25/options.d.ts.map +1 -1
- package/esm/options/1_25/options.js +16 -2
- package/esm/options/1_25/options.js.map +1 -1
- package/esm/options/1_25/scroll.d.ts.map +1 -1
- package/esm/options/1_25/scroll.js +2 -1
- package/esm/options/1_25/scroll.js.map +1 -1
- package/esm/options/2_0.d.ts +12 -8
- package/esm/options/2_0.d.ts.map +1 -1
- package/esm/options/2_0.js +82 -15
- package/esm/options/2_0.js.map +1 -1
- package/esm/options/2_1.d.ts +48 -0
- package/esm/options/2_1.d.ts.map +1 -0
- package/esm/options/2_1.js +23 -0
- package/esm/options/2_1.js.map +1 -0
- package/esm/options/codec.d.ts +4 -4
- package/esm/options/codec.d.ts.map +1 -1
- package/esm/options/codec.js +5 -6
- package/esm/options/codec.js.map +1 -1
- package/esm/options/index.d.ts +5 -0
- package/esm/options/index.d.ts.map +1 -1
- package/esm/options/index.js +5 -0
- package/esm/options/index.js.map +1 -1
- package/esm/options/latest.d.ts +4 -5
- package/esm/options/latest.d.ts.map +1 -1
- package/esm/options/latest.js +2 -3
- package/esm/options/latest.js.map +1 -1
- package/esm/options/types.d.ts +74 -33
- package/esm/options/types.d.ts.map +1 -1
- package/esm/options/types.js +62 -0
- package/esm/options/types.js.map +1 -1
- package/package.json +9 -19
- package/src/codec/av1.ts +33 -0
- package/src/codec/h264.ts +317 -0
- package/src/codec/h265.ts +1375 -0
- package/src/codec/index.ts +4 -0
- package/src/codec/nalu.ts +391 -0
- package/src/control/back-or-screen-on.ts +1 -1
- package/{esm/control/simple.js → src/control/basic.ts} +3 -3
- package/src/control/hover-helper.ts +10 -11
- package/src/control/index.ts +2 -0
- package/src/control/inject-keycode.ts +1 -3
- package/src/control/inject-text.ts +1 -3
- package/src/control/inject-touch.ts +16 -55
- package/src/control/rotate-device.ts +2 -7
- package/src/control/serializer.ts +50 -113
- package/src/control/set-screen-power-mode.ts +1 -3
- package/src/control/type.ts +32 -0
- package/src/control/writer.ts +85 -0
- package/src/device-message/stream.ts +32 -12
- package/src/index.ts +1 -2
- package/src/options/1_16/codec-options.ts +6 -7
- package/src/options/1_16/float-to-uint16.ts +33 -0
- package/src/options/1_16/index.ts +3 -1
- package/src/options/1_16/init.ts +80 -0
- package/src/options/1_16/message.ts +55 -0
- package/src/options/1_16/options.ts +147 -260
- package/src/options/1_16/scroll.ts +17 -18
- package/src/options/1_17.ts +66 -0
- package/src/options/1_18.ts +103 -39
- package/src/options/1_21.ts +49 -27
- package/src/options/1_22/index.ts +1 -0
- package/src/options/1_22/init.ts +19 -0
- package/src/options/1_22/options.ts +38 -45
- package/src/options/1_22/scroll.ts +3 -3
- package/src/options/1_23.ts +34 -22
- package/src/options/1_24.ts +23 -11
- package/src/options/1_25/options.ts +22 -4
- package/src/options/1_25/scroll.ts +4 -3
- package/src/options/2_0.ts +342 -0
- package/src/options/2_1.ts +35 -0
- package/src/options/codec.ts +98 -0
- package/src/options/index.ts +5 -0
- package/src/options/latest.ts +12 -0
- package/src/options/types.ts +164 -43
- package/tsconfig.build.json +9 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/bin/scrcpy-server +0 -0
- package/bin/version.d.ts +0 -1
- package/bin/version.js +0 -1
- package/esm/adb/client.d.ts +0 -41
- package/esm/adb/client.d.ts.map +0 -1
- package/esm/adb/client.js +0 -224
- package/esm/adb/client.js.map +0 -1
- package/esm/adb/connection.d.ts +0 -49
- package/esm/adb/connection.d.ts.map +0 -1
- package/esm/adb/connection.js +0 -122
- package/esm/adb/connection.js.map +0 -1
- package/esm/adb/index.d.ts +0 -4
- package/esm/adb/index.d.ts.map +0 -1
- package/esm/adb/index.js +0 -4
- package/esm/adb/index.js.map +0 -1
- package/esm/adb/options/1_16.d.ts +0 -8
- package/esm/adb/options/1_16.d.ts.map +0 -1
- package/esm/adb/options/1_16.js +0 -20
- package/esm/adb/options/1_16.js.map +0 -1
- package/esm/adb/options/1_22.d.ts +0 -8
- package/esm/adb/options/1_22.d.ts.map +0 -1
- package/esm/adb/options/1_22.js +0 -17
- package/esm/adb/options/1_22.js.map +0 -1
- package/esm/adb/options/1_26.d.ts +0 -9
- package/esm/adb/options/1_26.d.ts.map +0 -1
- package/esm/adb/options/1_26.js +0 -11
- package/esm/adb/options/1_26.js.map +0 -1
- package/esm/adb/options/2_0.d.ts +0 -8
- package/esm/adb/options/2_0.d.ts.map +0 -1
- package/esm/adb/options/2_0.js +0 -13
- package/esm/adb/options/2_0.js.map +0 -1
- package/esm/adb/options/index.d.ts +0 -4
- package/esm/adb/options/index.d.ts.map +0 -1
- package/esm/adb/options/index.js +0 -4
- package/esm/adb/options/index.js.map +0 -1
- package/esm/adb/options/types.d.ts +0 -24
- package/esm/adb/options/types.d.ts.map +0 -1
- package/esm/adb/options/types.js +0 -37
- package/esm/adb/options/types.js.map +0 -1
- package/esm/codec.d.ts +0 -34
- package/esm/codec.d.ts.map +0 -1
- package/esm/codec.js +0 -37
- package/esm/codec.js.map +0 -1
- package/esm/control/simple.d.ts +0 -5
- package/esm/control/simple.d.ts.map +0 -1
- package/esm/control/simple.js.map +0 -1
- package/esm/decoder.d.ts +0 -2
- package/esm/decoder.d.ts.map +0 -1
- package/esm/decoder.js +0 -2
- package/esm/decoder.js.map +0 -1
- package/esm/options/1.17.d.ts +0 -3
- package/esm/options/1.17.d.ts.map +0 -1
- package/esm/options/1.17.js +0 -2
- package/esm/options/1.17.js.map +0 -1
- package/esm/options/1_16/h264-configuration.d.ts +0 -49
- package/esm/options/1_16/h264-configuration.d.ts.map +0 -1
- package/esm/options/1_16/h264-configuration.js +0 -414
- package/esm/options/1_16/h264-configuration.js.map +0 -1
- package/esm/options/1_16/sps.d.ts +0 -22
- package/esm/options/1_16/sps.d.ts.map +0 -1
- package/esm/options/1_16/sps.js +0 -263
- package/esm/options/1_16/sps.js.map +0 -1
- package/esm/options/1_26.d.ts +0 -57
- package/esm/options/1_26.d.ts.map +0 -1
- package/esm/options/1_26.js +0 -67
- package/esm/options/1_26.js.map +0 -1
- package/esm/options/2.d.ts +0 -57
- package/esm/options/2.d.ts.map +0 -1
- package/esm/options/2.js +0 -67
- package/esm/options/2.js.map +0 -1
- package/scripts/fetch-server.cjs +0 -38
- package/src/adb/client.ts +0 -329
- package/src/adb/connection.ts +0 -209
- package/src/adb/index.ts +0 -3
- package/src/adb/options/1_16.ts +0 -32
- package/src/adb/options/1_22.ts +0 -26
- package/src/adb/options/index.ts +0 -3
- package/src/adb/options/types.ts +0 -75
- package/src/codec.ts +0 -35
- package/src/options/1_16/h264-configuration.ts +0 -485
package/src/codec.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
// From https://developer.android.com/reference/android/media/MediaCodecInfo.CodecProfileLevel
|
|
2
|
-
export enum AndroidCodecProfile {
|
|
3
|
-
Baseline = 0x01,
|
|
4
|
-
Main = 0x02,
|
|
5
|
-
Extended = 0x04,
|
|
6
|
-
High = 0x08,
|
|
7
|
-
High10 = 0x10,
|
|
8
|
-
High422 = 0x20,
|
|
9
|
-
High444 = 0x40,
|
|
10
|
-
ConstrainedBaseline = 0x10000,
|
|
11
|
-
ConstrainedHigh = 0x80000,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export enum AndroidCodecLevel {
|
|
15
|
-
Level1 = 0x01,
|
|
16
|
-
Level1b = 0x02,
|
|
17
|
-
Level11 = 0x04,
|
|
18
|
-
Level12 = 0x08,
|
|
19
|
-
Level13 = 0x10,
|
|
20
|
-
Level2 = 0x20,
|
|
21
|
-
Level21 = 0x40,
|
|
22
|
-
Level22 = 0x80,
|
|
23
|
-
Level3 = 0x100,
|
|
24
|
-
Level31 = 0x200,
|
|
25
|
-
Level32 = 0x400,
|
|
26
|
-
Level4 = 0x800,
|
|
27
|
-
Level41 = 0x1000,
|
|
28
|
-
Level42 = 0x2000,
|
|
29
|
-
Level5 = 0x4000,
|
|
30
|
-
Level51 = 0x8000,
|
|
31
|
-
Level52 = 0x10000,
|
|
32
|
-
Level6 = 0x20000,
|
|
33
|
-
Level61 = 0x40000,
|
|
34
|
-
Level62 = 0x80000,
|
|
35
|
-
}
|
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
// cspell: ignore golomb
|
|
2
|
-
// cspell: ignore qpprime
|
|
3
|
-
// cspell: ignore colour
|
|
4
|
-
|
|
5
|
-
// H.264 has two standards: ITU-T H.264 and ISO/IEC 14496-10
|
|
6
|
-
// they have the same content, and refer themselves as "H.264".
|
|
7
|
-
// The name "AVC" (Advanced Video Coding) is only used in ISO spec name,
|
|
8
|
-
// and other ISO specs referring to H.264.
|
|
9
|
-
// Because this module parses H.264 Annex B format,
|
|
10
|
-
// it's named "h264" instead of "avc".
|
|
11
|
-
|
|
12
|
-
class BitReader {
|
|
13
|
-
private buffer: Uint8Array;
|
|
14
|
-
|
|
15
|
-
private bytePosition = 0;
|
|
16
|
-
|
|
17
|
-
private bitPosition = 0;
|
|
18
|
-
|
|
19
|
-
public constructor(buffer: Uint8Array) {
|
|
20
|
-
this.buffer = buffer;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
public read(length: number): number {
|
|
24
|
-
let result = 0;
|
|
25
|
-
for (let i = 0; i < length; i += 1) {
|
|
26
|
-
result = (result << 1) | this.next();
|
|
27
|
-
}
|
|
28
|
-
return result;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
public next(): number {
|
|
32
|
-
const value =
|
|
33
|
-
(this.buffer[this.bytePosition]! >> (7 - this.bitPosition)) & 1;
|
|
34
|
-
this.bitPosition += 1;
|
|
35
|
-
if (this.bitPosition === 8) {
|
|
36
|
-
this.bytePosition += 1;
|
|
37
|
-
this.bitPosition = 0;
|
|
38
|
-
}
|
|
39
|
-
return value;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
public decodeExponentialGolombNumber(): number {
|
|
43
|
-
let length = 0;
|
|
44
|
-
while (this.next() === 0) {
|
|
45
|
-
length += 1;
|
|
46
|
-
}
|
|
47
|
-
if (length === 0) {
|
|
48
|
-
return 0;
|
|
49
|
-
}
|
|
50
|
-
return ((1 << length) | this.read(length)) - 1;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Split NAL units from a H.264 Annex B stream.
|
|
56
|
-
*
|
|
57
|
-
* The input is not modified.
|
|
58
|
-
* The returned NAL units are views of the input (no memory allocation nor copy),
|
|
59
|
-
* and still contains emulation prevention bytes.
|
|
60
|
-
*
|
|
61
|
-
* This methods returns a generator, so it can be stopped immediately
|
|
62
|
-
* after the interested NAL unit is found.
|
|
63
|
-
*/
|
|
64
|
-
export function* splitH264Stream(buffer: Uint8Array): Generator<Uint8Array> {
|
|
65
|
-
// -1 means we haven't found the first start code
|
|
66
|
-
let start = -1;
|
|
67
|
-
// How many `0x00`s in a row we have counted
|
|
68
|
-
let zeroCount = 0;
|
|
69
|
-
let inEmulation = false;
|
|
70
|
-
|
|
71
|
-
for (let i = 0; i < buffer.length; i += 1) {
|
|
72
|
-
const byte = buffer[i]!;
|
|
73
|
-
|
|
74
|
-
if (inEmulation) {
|
|
75
|
-
if (byte > 0x03) {
|
|
76
|
-
// `0x00000304` or larger are invalid
|
|
77
|
-
throw new Error("Invalid data");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
inEmulation = false;
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (byte === 0x00) {
|
|
85
|
-
zeroCount += 1;
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const prevZeroCount = zeroCount;
|
|
90
|
-
zeroCount = 0;
|
|
91
|
-
|
|
92
|
-
if (start === -1) {
|
|
93
|
-
// 0x000001 is the start code
|
|
94
|
-
// But it can be preceded by any number of zeros
|
|
95
|
-
// So 2 is the minimal
|
|
96
|
-
if (prevZeroCount >= 2 && byte === 0x01) {
|
|
97
|
-
// Found start of first NAL unit
|
|
98
|
-
start = i + 1;
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Not begin with start code
|
|
103
|
-
throw new Error("Invalid data");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (prevZeroCount < 2) {
|
|
107
|
-
// zero or one `0x00`s are acceptable
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (byte === 0x01) {
|
|
112
|
-
// Found another NAL unit
|
|
113
|
-
yield buffer.subarray(start, i - prevZeroCount);
|
|
114
|
-
|
|
115
|
-
start = i + 1;
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (prevZeroCount > 2) {
|
|
120
|
-
// Too much `0x00`s
|
|
121
|
-
throw new Error("Invalid data");
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
switch (byte) {
|
|
125
|
-
case 0x02:
|
|
126
|
-
// Didn't find why, but 7.4.1 NAL unit semantics forbids `0x000002` appearing in NAL units
|
|
127
|
-
throw new Error("Invalid data");
|
|
128
|
-
case 0x03:
|
|
129
|
-
// `0x000003` is the "emulation_prevention_three_byte"
|
|
130
|
-
// `0x00000300`, `0x00000301`, `0x00000302` and `0x00000303` represent
|
|
131
|
-
// `0x000000`, `0x000001`, `0x000002` and `0x000003` respectively
|
|
132
|
-
inEmulation = true;
|
|
133
|
-
break;
|
|
134
|
-
default:
|
|
135
|
-
// `0x000004` or larger are as-is
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (inEmulation) {
|
|
141
|
-
throw new Error("Invalid data");
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
yield buffer.subarray(start, buffer.length);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Remove emulation prevention bytes from a H.264 NAL Unit.
|
|
149
|
-
*
|
|
150
|
-
* The input is not modified.
|
|
151
|
-
* If the input doesn't contain any emulation prevention bytes,
|
|
152
|
-
* the input is returned as-is.
|
|
153
|
-
* Otherwise, a new `Uint8Array` is created and returned.
|
|
154
|
-
*/
|
|
155
|
-
export function removeH264Emulation(buffer: Uint8Array) {
|
|
156
|
-
// output will be created when first emulation prevention byte is found
|
|
157
|
-
let output: Uint8Array | undefined;
|
|
158
|
-
let outputOffset = 0;
|
|
159
|
-
|
|
160
|
-
let zeroCount = 0;
|
|
161
|
-
let inEmulation = false;
|
|
162
|
-
|
|
163
|
-
let i = 0;
|
|
164
|
-
scan: for (; i < buffer.length; i += 1) {
|
|
165
|
-
const byte = buffer[i]!;
|
|
166
|
-
|
|
167
|
-
if (byte === 0x00) {
|
|
168
|
-
zeroCount += 1;
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Current byte is not zero
|
|
173
|
-
const prevZeroCount = zeroCount;
|
|
174
|
-
zeroCount = 0;
|
|
175
|
-
|
|
176
|
-
if (prevZeroCount < 2) {
|
|
177
|
-
// zero or one `0x00`s are acceptable
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (byte === 0x01) {
|
|
182
|
-
// Unexpected start code
|
|
183
|
-
throw new Error("Invalid data");
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (prevZeroCount > 2) {
|
|
187
|
-
// Too much `0x00`s
|
|
188
|
-
throw new Error("Invalid data");
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
switch (byte) {
|
|
192
|
-
case 0x02:
|
|
193
|
-
// Didn't find why, but 7.4.1 NAL unit semantics forbids `0x000002` appearing in NAL units
|
|
194
|
-
throw new Error("Invalid data");
|
|
195
|
-
case 0x03:
|
|
196
|
-
// `0x000003` is the "emulation_prevention_three_byte"
|
|
197
|
-
// `0x00000300`, `0x00000301`, `0x00000302` and `0x00000303` represent
|
|
198
|
-
// `0x000000`, `0x000001`, `0x000002` and `0x000003` respectively
|
|
199
|
-
inEmulation = true;
|
|
200
|
-
|
|
201
|
-
// Create output and copy the data before the emulation prevention byte
|
|
202
|
-
// Output size is unknown, so we use the input size as an upper bound
|
|
203
|
-
output = new Uint8Array(buffer.length - 1);
|
|
204
|
-
output.set(buffer.subarray(0, i - prevZeroCount));
|
|
205
|
-
outputOffset = i - prevZeroCount + 1;
|
|
206
|
-
break scan;
|
|
207
|
-
default:
|
|
208
|
-
// `0x000004` or larger are as-is
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (!output) {
|
|
214
|
-
return buffer;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Continue at the byte after the emulation prevention byte
|
|
218
|
-
for (; i < buffer.length; i += 1) {
|
|
219
|
-
const byte = buffer[i]!;
|
|
220
|
-
|
|
221
|
-
output[outputOffset] = byte;
|
|
222
|
-
outputOffset += 1;
|
|
223
|
-
|
|
224
|
-
if (inEmulation) {
|
|
225
|
-
if (byte > 0x03) {
|
|
226
|
-
// `0x00000304` or larger are invalid
|
|
227
|
-
throw new Error("Invalid data");
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
inEmulation = false;
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (byte === 0x00) {
|
|
235
|
-
zeroCount += 1;
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const prevZeroCount = zeroCount;
|
|
240
|
-
zeroCount = 0;
|
|
241
|
-
|
|
242
|
-
if (prevZeroCount < 2) {
|
|
243
|
-
// zero or one `0x00`s are acceptable
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (byte === 0x01) {
|
|
248
|
-
// Unexpected start code
|
|
249
|
-
throw new Error("Invalid data");
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (prevZeroCount > 2) {
|
|
253
|
-
// Too much `0x00`s
|
|
254
|
-
throw new Error("Invalid data");
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
switch (byte) {
|
|
258
|
-
case 0x02:
|
|
259
|
-
// Didn't find why, but 7.4.1 NAL unit semantics forbids `0x000002` appearing in NAL units
|
|
260
|
-
throw new Error("Invalid data");
|
|
261
|
-
case 0x03:
|
|
262
|
-
// `0x000003` is the "emulation_prevention_three_byte"
|
|
263
|
-
// `0x00000300`, `0x00000301`, `0x00000302` and `0x00000303` represent
|
|
264
|
-
// `0x000000`, `0x000001`, `0x000002` and `0x000003` respectively
|
|
265
|
-
inEmulation = true;
|
|
266
|
-
|
|
267
|
-
// Remove the emulation prevention byte
|
|
268
|
-
outputOffset -= 1;
|
|
269
|
-
break;
|
|
270
|
-
default:
|
|
271
|
-
// `0x000004` or larger are as-is
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return output.subarray(0, outputOffset);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// 7.3.2.1.1 Sequence parameter set data syntax
|
|
280
|
-
// Variable names in this method uses the snake_case convention as in the spec for easier referencing.
|
|
281
|
-
export function parseSequenceParameterSet(buffer: Uint8Array) {
|
|
282
|
-
const reader = new BitReader(buffer);
|
|
283
|
-
if (reader.next() !== 0) {
|
|
284
|
-
throw new Error("Invalid data");
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const nal_ref_idc = reader.read(2);
|
|
288
|
-
const nal_unit_type = reader.read(5);
|
|
289
|
-
|
|
290
|
-
if (nal_unit_type !== 7) {
|
|
291
|
-
throw new Error("Invalid data");
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (nal_ref_idc === 0) {
|
|
295
|
-
throw new Error("Invalid data");
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const profile_idc = reader.read(8);
|
|
299
|
-
const constraint_set = reader.read(8);
|
|
300
|
-
|
|
301
|
-
const constraint_set_reader = new BitReader(
|
|
302
|
-
new Uint8Array([constraint_set])
|
|
303
|
-
);
|
|
304
|
-
const constraint_set0_flag = !!constraint_set_reader.next();
|
|
305
|
-
const constraint_set1_flag = !!constraint_set_reader.next();
|
|
306
|
-
const constraint_set2_flag = !!constraint_set_reader.next();
|
|
307
|
-
const constraint_set3_flag = !!constraint_set_reader.next();
|
|
308
|
-
const constraint_set4_flag = !!constraint_set_reader.next();
|
|
309
|
-
const constraint_set5_flag = !!constraint_set_reader.next();
|
|
310
|
-
|
|
311
|
-
// reserved_zero_2bits
|
|
312
|
-
if (constraint_set_reader.read(2) !== 0) {
|
|
313
|
-
throw new Error("Invalid data");
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const level_idc = reader.read(8);
|
|
317
|
-
const seq_parameter_set_id = reader.decodeExponentialGolombNumber();
|
|
318
|
-
|
|
319
|
-
if (
|
|
320
|
-
profile_idc === 100 ||
|
|
321
|
-
profile_idc === 110 ||
|
|
322
|
-
profile_idc === 122 ||
|
|
323
|
-
profile_idc === 244 ||
|
|
324
|
-
profile_idc === 44 ||
|
|
325
|
-
profile_idc === 83 ||
|
|
326
|
-
profile_idc === 86 ||
|
|
327
|
-
profile_idc === 118 ||
|
|
328
|
-
profile_idc === 128 ||
|
|
329
|
-
profile_idc === 138 ||
|
|
330
|
-
profile_idc === 139 ||
|
|
331
|
-
profile_idc === 134
|
|
332
|
-
) {
|
|
333
|
-
const chroma_format_idc = reader.decodeExponentialGolombNumber();
|
|
334
|
-
if (chroma_format_idc === 3) {
|
|
335
|
-
// separate_colour_plane_flag
|
|
336
|
-
reader.next();
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// bit_depth_luma_minus8
|
|
340
|
-
reader.decodeExponentialGolombNumber();
|
|
341
|
-
// bit_depth_chroma_minus8
|
|
342
|
-
reader.decodeExponentialGolombNumber();
|
|
343
|
-
|
|
344
|
-
// qpprime_y_zero_transform_bypass_flag
|
|
345
|
-
reader.next();
|
|
346
|
-
|
|
347
|
-
const seq_scaling_matrix_present_flag = !!reader.next();
|
|
348
|
-
if (seq_scaling_matrix_present_flag) {
|
|
349
|
-
const seq_scaling_list_present_flag: boolean[] = [];
|
|
350
|
-
for (let i = 0; i < (chroma_format_idc !== 3 ? 8 : 12); i += 1) {
|
|
351
|
-
seq_scaling_list_present_flag[i] = !!reader.next();
|
|
352
|
-
if (seq_scaling_list_present_flag[i])
|
|
353
|
-
if (i < 6) {
|
|
354
|
-
// TODO
|
|
355
|
-
// scaling_list( ScalingList4x4[ i ], 16,
|
|
356
|
-
// UseDefaultScalingMatrix4x4Flag[ i ])
|
|
357
|
-
} else {
|
|
358
|
-
// TODO
|
|
359
|
-
// scaling_list( ScalingList8x8[ i − 6 ], 64,
|
|
360
|
-
// UseDefaultScalingMatrix8x8Flag[ i − 6 ] )
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// log2_max_frame_num_minus4
|
|
367
|
-
reader.decodeExponentialGolombNumber();
|
|
368
|
-
const pic_order_cnt_type = reader.decodeExponentialGolombNumber();
|
|
369
|
-
if (pic_order_cnt_type === 0) {
|
|
370
|
-
// log2_max_pic_order_cnt_lsb_minus4
|
|
371
|
-
reader.decodeExponentialGolombNumber();
|
|
372
|
-
} else if (pic_order_cnt_type === 1) {
|
|
373
|
-
// delta_pic_order_always_zero_flag
|
|
374
|
-
reader.next();
|
|
375
|
-
// offset_for_non_ref_pic
|
|
376
|
-
reader.decodeExponentialGolombNumber();
|
|
377
|
-
// offset_for_top_to_bottom_field
|
|
378
|
-
reader.decodeExponentialGolombNumber();
|
|
379
|
-
const num_ref_frames_in_pic_order_cnt_cycle =
|
|
380
|
-
reader.decodeExponentialGolombNumber();
|
|
381
|
-
const offset_for_ref_frame: number[] = [];
|
|
382
|
-
for (let i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i += 1) {
|
|
383
|
-
offset_for_ref_frame[i] = reader.decodeExponentialGolombNumber();
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// max_num_ref_frames
|
|
388
|
-
reader.decodeExponentialGolombNumber();
|
|
389
|
-
// gaps_in_frame_num_value_allowed_flag
|
|
390
|
-
reader.next();
|
|
391
|
-
const pic_width_in_mbs_minus1 = reader.decodeExponentialGolombNumber();
|
|
392
|
-
const pic_height_in_map_units_minus1 =
|
|
393
|
-
reader.decodeExponentialGolombNumber();
|
|
394
|
-
|
|
395
|
-
const frame_mbs_only_flag = reader.next();
|
|
396
|
-
if (!frame_mbs_only_flag) {
|
|
397
|
-
// mb_adaptive_frame_field_flag
|
|
398
|
-
reader.next();
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// direct_8x8_inference_flag
|
|
402
|
-
reader.next();
|
|
403
|
-
|
|
404
|
-
const frame_cropping_flag = !!reader.next();
|
|
405
|
-
let frame_crop_left_offset: number;
|
|
406
|
-
let frame_crop_right_offset: number;
|
|
407
|
-
let frame_crop_top_offset: number;
|
|
408
|
-
let frame_crop_bottom_offset: number;
|
|
409
|
-
if (frame_cropping_flag) {
|
|
410
|
-
frame_crop_left_offset = reader.decodeExponentialGolombNumber();
|
|
411
|
-
frame_crop_right_offset = reader.decodeExponentialGolombNumber();
|
|
412
|
-
frame_crop_top_offset = reader.decodeExponentialGolombNumber();
|
|
413
|
-
frame_crop_bottom_offset = reader.decodeExponentialGolombNumber();
|
|
414
|
-
} else {
|
|
415
|
-
frame_crop_left_offset = 0;
|
|
416
|
-
frame_crop_right_offset = 0;
|
|
417
|
-
frame_crop_top_offset = 0;
|
|
418
|
-
frame_crop_bottom_offset = 0;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
const vui_parameters_present_flag = !!reader.next();
|
|
422
|
-
if (vui_parameters_present_flag) {
|
|
423
|
-
// TODO
|
|
424
|
-
// vui_parameters( )
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return {
|
|
428
|
-
profile_idc,
|
|
429
|
-
constraint_set,
|
|
430
|
-
constraint_set0_flag,
|
|
431
|
-
constraint_set1_flag,
|
|
432
|
-
constraint_set2_flag,
|
|
433
|
-
constraint_set3_flag,
|
|
434
|
-
constraint_set4_flag,
|
|
435
|
-
constraint_set5_flag,
|
|
436
|
-
level_idc,
|
|
437
|
-
seq_parameter_set_id,
|
|
438
|
-
pic_width_in_mbs_minus1,
|
|
439
|
-
pic_height_in_map_units_minus1,
|
|
440
|
-
frame_mbs_only_flag,
|
|
441
|
-
frame_cropping_flag,
|
|
442
|
-
frame_crop_left_offset,
|
|
443
|
-
frame_crop_right_offset,
|
|
444
|
-
frame_crop_top_offset,
|
|
445
|
-
frame_crop_bottom_offset,
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Find Sequence Parameter Set (SPS) and Picture Parameter Set (PPS)
|
|
451
|
-
* from H.264 Annex B formatted data.
|
|
452
|
-
*/
|
|
453
|
-
export function parseH264Configuration(buffer: Uint8Array) {
|
|
454
|
-
let sequenceParameterSet: Uint8Array | undefined;
|
|
455
|
-
let pictureParameterSet: Uint8Array | undefined;
|
|
456
|
-
|
|
457
|
-
for (const nalu of splitH264Stream(buffer)) {
|
|
458
|
-
const naluType = nalu[0]! & 0x1f;
|
|
459
|
-
switch (naluType) {
|
|
460
|
-
case 7: // Sequence parameter set
|
|
461
|
-
sequenceParameterSet = nalu;
|
|
462
|
-
if (pictureParameterSet) {
|
|
463
|
-
return {
|
|
464
|
-
sequenceParameterSet,
|
|
465
|
-
pictureParameterSet,
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
break;
|
|
469
|
-
case 8: // Picture parameter set
|
|
470
|
-
pictureParameterSet = nalu;
|
|
471
|
-
if (sequenceParameterSet) {
|
|
472
|
-
return {
|
|
473
|
-
sequenceParameterSet,
|
|
474
|
-
pictureParameterSet,
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
break;
|
|
478
|
-
default:
|
|
479
|
-
// ignore
|
|
480
|
-
break;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
throw new Error("Invalid data");
|
|
485
|
-
}
|