Skip to content

Commit 3071bf9

Browse files
committed
refactor(transmuxer): 统一 reader 导出并替换 VVC StreamReader
1 parent c8f6c33 commit 3071bf9

4 files changed

Lines changed: 64 additions & 97 deletions

File tree

packages/xgplayer-transmuxer/src/codec/vvc.js

Lines changed: 53 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11

22
// import { avc } from 'xgplayer-helper-codec'
3+
import { BitReader } from '../utils/bit-reader'
4+
import { ByteReader } from '../utils/byte-reader'
35
import ExpGolomb from './expGolomb'
46

57
// aligned(8) class VvcPTLRecord(num_sublayers) {
@@ -24,52 +26,9 @@ import ExpGolomb from './expGolomb'
2426
// }
2527

2628

27-
export class StreamReader {
28-
29-
constructor (uint8Arr) {
30-
this._buffer = uint8Arr
31-
this._offset = 0
32-
this._heldBits = 0
33-
this._numHeldBits = 0
34-
}
35-
36-
readUint8 () {
37-
return this._buffer[this._offset++]
38-
}
39-
40-
readUint16 () {
41-
return (this._buffer[this._offset++] << 8) | this._buffer[this._offset++]
42-
}
43-
44-
readUint32 () {
45-
return (this._buffer[this._offset++] << 24) |
46-
(this._buffer[this._offset++] << 16) |
47-
(this._buffer[this._offset++] << 8) |
48-
(this._buffer[this._offset++])
49-
}
50-
51-
readUint8Array (len) {
52-
const ret = this._buffer.slice(this._offset, this._offset + len)
53-
this._offset += len
54-
return ret
55-
}
56-
57-
streamRead1Bytes () {
58-
this._heldBits = this.readUint8()
59-
this._numHeldBits = 1 * 8
60-
}
61-
62-
streamRead2Bytes () {
63-
this._heldBits = this.readUint16()
64-
this._numHeldBits = 2 * 8
65-
}
66-
67-
extractBits (numBits) {
68-
const ret = (this._heldBits >> (this._numHeldBits - numBits)) & ((1 << numBits) - 1)
69-
this._numHeldBits -= numBits
70-
return ret
71-
}
72-
29+
function readUint8Array (reader, len) {
30+
if (!len) return new Uint8Array()
31+
return reader.readToUint8(len).slice()
7332
}
7433

7534
const VVC_NAL_TYPE_RASL = 3
@@ -162,11 +121,11 @@ export class VVC {
162121
payload = payload.subarray(4)
163122
}
164123

165-
const reader = new StreamReader(payload)
166-
reader.streamRead1Bytes()
167-
reader.extractBits(5) // reserved = '11111'b
168-
const lengthSizeMinusOne = reader.extractBits(2)
169-
const ptlPresentFlag = reader.extractBits(1)
124+
const reader = ByteReader.fromUint8(payload)
125+
const headerBits = BitReader.fromByte(reader, 1)
126+
headerBits.read(5) // reserved = '11111'b
127+
const lengthSizeMinusOne = headerBits.read(2)
128+
const ptlPresentFlag = headerBits.read(1)
170129

171130
let olsIdx
172131
let numSublayers = 1
@@ -179,21 +138,21 @@ export class VVC {
179138
let avgFrameRate
180139

181140
if (ptlPresentFlag) {
182-
reader.streamRead2Bytes()
183-
olsIdx = reader.extractBits(9)
184-
numSublayers = reader.extractBits(3)
185-
constantFrameRate = reader.extractBits(2)
186-
chromaFormatIdc = reader.extractBits(2)
141+
const olsBits = BitReader.fromByte(reader, 2)
142+
olsIdx = olsBits.read(9)
143+
numSublayers = olsBits.read(3)
144+
constantFrameRate = olsBits.read(2)
145+
chromaFormatIdc = olsBits.read(2)
187146

188-
reader.streamRead1Bytes()
189-
bitDepthLumaMinus8 = reader.extractBits(3)
190-
reader.extractBits(5) // reserved = '11111'b
147+
const depthBits = BitReader.fromByte(reader, 1)
148+
bitDepthLumaMinus8 = depthBits.read(3)
149+
depthBits.read(5) // reserved = '11111'b
191150

192151
ptlRecord = VVC.parseVVCPTLRecord(reader, numSublayers)
193152

194-
maxPictureWidth = reader.readUint16()
195-
maxPictureHeight = reader.readUint16()
196-
avgFrameRate = reader.readUint16()
153+
maxPictureWidth = reader.read(2)
154+
maxPictureHeight = reader.read(2)
155+
avgFrameRate = reader.read(2)
197156
}
198157

199158
const nalArrays = VVC._parseVVCNalArrays(reader)
@@ -230,44 +189,44 @@ export class VVC {
230189
const VVC_NALU_OPI = 12
231190
const VVC_NALU_DEC_PARAM = 13
232191

233-
const numOfArrays = reader.readUint8()
192+
const numOfArrays = reader.read(1)
234193
const vpsArr = []
235194
const spsArr = []
236195
const ppsArr = []
237196
let spsParsed = null
238197

239198
for (let i = 0; i < numOfArrays; i++) {
240-
reader.streamRead1Bytes()
241-
reader.extractBits(1) // array_completeness
242-
reader.extractBits(2) // reserved
243-
const naluType = reader.extractBits(5)
199+
const arrayBits = BitReader.fromByte(reader, 1)
200+
arrayBits.read(1) // array_completeness
201+
arrayBits.read(2) // reserved
202+
const naluType = arrayBits.read(5)
244203

245204
let numNalus = 1
246205
if (naluType !== VVC_NALU_DEC_PARAM && naluType !== VVC_NALU_OPI) {
247-
numNalus = reader.readUint16()
206+
numNalus = reader.read(2)
248207
}
249208

250209
for (let j = 0; j < numNalus; j++) {
251-
const len = reader.readUint16()
210+
const len = reader.read(2)
252211
switch (naluType) {
253212
case 14:
254-
vpsArr.push(reader.readUint8Array(len))
213+
vpsArr.push(readUint8Array(reader, len))
255214
break
256215
case 15: {
257-
const sps = reader.readUint8Array(len)
216+
const sps = readUint8Array(reader, len)
258217
if (!spsParsed) {
259218
try { spsParsed = VVC.parseSPS(VVC.removeEPB(sps)) } catch (e) { /* best-effort */ }
260219
}
261220
spsArr.push(sps)
262221
break
263222
}
264223
case 16:
265-
ppsArr.push(reader.readUint8Array(len))
224+
ppsArr.push(readUint8Array(reader, len))
266225
break
267226
default:
268227
// Skip unknown NAL types (APS, DCI, OPI, …) – we only care about
269228
// SPS/PPS/VPS for downstream remuxing.
270-
reader.readUint8Array(len)
229+
readUint8Array(reader, len)
271230
}
272231
}
273232
}
@@ -276,55 +235,55 @@ export class VVC {
276235
}
277236

278237
static parseVVCPTLRecord (reader, numSublayers) {
279-
reader.streamRead2Bytes()
280-
reader.extractBits(2)
281-
const numBytesConstraintInfo = reader.extractBits(6)
282-
const generalProfileIdc = reader.extractBits(7)
283-
const generalTierFlag = reader.extractBits(1)
284-
const generalLevelIdc = reader.readUint8()
285-
286-
reader.streamRead1Bytes()
287-
const ptlFrameOnlyConstraintFlag = reader.extractBits(1)
288-
const ptlMultilayerEnabledFlag = reader.extractBits(1)
238+
const ptlBits = BitReader.fromByte(reader, 2)
239+
ptlBits.read(2)
240+
const numBytesConstraintInfo = ptlBits.read(6)
241+
const generalProfileIdc = ptlBits.read(7)
242+
const generalTierFlag = ptlBits.read(1)
243+
const generalLevelIdc = reader.read(1)
244+
245+
let constraintBits = BitReader.fromByte(reader, 1)
246+
const ptlFrameOnlyConstraintFlag = constraintBits.read(1)
247+
const ptlMultilayerEnabledFlag = constraintBits.read(1)
289248
const generalConstraintInfo = new Uint8Array(numBytesConstraintInfo)
290249
if (numBytesConstraintInfo) {
291250
for (let i = 0; i < numBytesConstraintInfo - 1; i++) {
292-
const cnstr1 = reader.extractBits(6)
293-
reader.streamRead1Bytes()
294-
const cnstr2 = reader.extractBits(2)
251+
const cnstr1 = constraintBits.read(6)
252+
constraintBits = BitReader.fromByte(reader, 1)
253+
const cnstr2 = constraintBits.read(2)
295254
generalConstraintInfo[i] = ((cnstr1 << 2) | cnstr2)
296255
}
297-
generalConstraintInfo[numBytesConstraintInfo - 1] = reader.extractBits(6)
256+
generalConstraintInfo[numBytesConstraintInfo - 1] = constraintBits.read(6)
298257
} else {
299-
reader.extractBits(6)
258+
constraintBits.read(6)
300259
}
301260

302261
const subLayerLevelIdc = []
303262
if (numSublayers > 1) {
304-
reader.streamRead1Bytes()
263+
const subLayerBits = BitReader.fromByte(reader, 1)
305264
let ptlSublayerPresentMask = 0
306265

307266
for (let j = numSublayers - 2; j >= 0; --j) {
308-
const val = reader.extractBits(1)
267+
const val = subLayerBits.read(1)
309268
ptlSublayerPresentMask |= val << j
310269
}
311270

312271
for (let j = numSublayers; j <= 8 && numSublayers > 1; ++j) {
313-
reader.extractBits(1)
272+
subLayerBits.read(1)
314273
}
315274

316275
for (let j = numSublayers - 2; j >= 0; --j) {
317276
if (ptlSublayerPresentMask & (1 << j)) {
318-
subLayerLevelIdc[j] = reader.readUint8()
277+
subLayerLevelIdc[j] = reader.read(1)
319278
}
320279
}
321280
}
322281

323-
const ptlNumSubProfiles = reader.readUint8()
282+
const ptlNumSubProfiles = reader.read(1)
324283
const generalSubProfileIdc = []
325284
if (ptlNumSubProfiles) {
326285
for (let i = 0; i < ptlNumSubProfiles; i++) {
327-
generalSubProfileIdc.push(reader.readUint32())
286+
generalSubProfileIdc.push(reader.readInt(4))
328287
}
329288
}
330289

packages/xgplayer-transmuxer/src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@ export {
77
registerVideoCodec,
88
unregisterVideoCodec
99
} from './codec'
10-
export { Logger } from './utils'
10+
export {
11+
BitReader,
12+
ByteReader,
13+
Logger
14+
} from './utils'

packages/xgplayer-transmuxer/src/index.umd.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ import * as flv from './flv'
22
import * as mpegTs from './mpeg-ts'
33
import * as mp4 from './mp4'
44
import * as model from './model'
5-
import { Logger } from './utils'
5+
import { BitReader, ByteReader, Logger } from './utils'
66

77
export default {
88
...flv,
99
...mpegTs,
1010
...mp4,
1111
...model,
12-
Logger
12+
Logger,
13+
BitReader,
14+
ByteReader
1315
}

packages/xgplayer-transmuxer/src/utils/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/* c8 ignore next 4 */
22
export { ExpGolomb } from './exp-golomb'
3+
export { BitReader } from './bit-reader'
4+
export { ByteReader } from './byte-reader'
35
export { Logger } from './logger'
46
export { UTF8 } from './utf8'
57
export * from './env'

0 commit comments

Comments
 (0)