@@ -6,7 +6,7 @@ type MVector = [number, number];
66
77interface Block {
88 index : number ,
9- data : Uint8Array ,
9+ data : Uint8ClampedArray ,
1010}
1111
1212interface Macroblock {
@@ -35,6 +35,9 @@ function reconstruct(level: number, quant: number) {
3535 return clip ( quant * ( 2 * level + lp ) + qe , - 2048 , 2047 ) ;
3636}
3737
38+ // @ts -ignore
39+ window . reconstruct = reconstruct ;
40+
3841function reconstructDC ( level : number ) : number {
3942 if ( level === 0 || level === 128 ) {
4043 throw "Invalid DC: 0 and 128 are not allowed" ;
@@ -46,48 +49,55 @@ function reconstructDC(level: number): number {
4649}
4750
4851const { SQRT2 , PI } = Math ;
52+ const ISQ2 = ( 1 / SQRT2 ) ;
53+
54+ function alpha ( x : number ) {
55+ return x === 0 ? ISQ2 : 1
56+ }
4957
50- function idct ( block : Uint8Array ) {
51- const result = new Uint8Array ( 64 ) ;
52-
53- // for (let x = 0; x < 8; x++) {
54- // for (let y = 0; y < 8; y++) {
55- // let sum = 0;
56- // for (let u = 0; u < 8; u++) {
57- // for (let v = 0; v < 8; v++) {
58- // const Cu = u === 0 ? 1 / SQRT2 : 1;
59- // const Cv = v === 0 ? 1 / SQRT2 : 1;
60- // const dctCoeff = block[u + v * 8];
61- // sum += Cu * Cv * dctCoeff *
62- // Math.cos(((2 * x + 1) * u * PI) / 16) *
63- // Math.cos(((2 * y + 1) * v * PI) / 16);
64- // }
65- // }
66- // result[x + y * 8] = (1 / 4) * sum;
67- // }
68- // }
58+ export function idct ( block : Int16Array ) {
59+ const result = new Uint8ClampedArray ( 64 ) ;
6960
7061 for ( let y = 0 ; y < 8 ; y ++ ) {
7162 for ( let x = 0 ; x < 8 ; x ++ ) {
7263 let sum = 0 ;
73- for ( let u = 0 ; u < 8 ; u ++ ) {
74- for ( let v = 0 ; v < 8 ; v ++ ) {
75- const Cu = u === 0 ? 1 / SQRT2 : 1 ;
76- const Cv = v === 0 ? 1 / SQRT2 : 1 ;
77- const index = u * 8 + v ;
78- const dctCoeff = block [ index ] ;
79- sum += Cu * Cv * dctCoeff *
80- Math . cos ( ( ( 2 * x + 1 ) * u * PI ) / 16 ) *
81- Math . cos ( ( ( 2 * y + 1 ) * v * PI ) / 16 ) ;
64+
65+ for ( let v = 0 ; v < 8 ; v ++ ) {
66+ for ( let u = 0 ; u < 8 ; u ++ ) {
67+
68+ sum += alpha ( u ) * alpha ( v ) * block [ u + v * 8 ] *
69+ Math . cos ( ( PI * ( 2 * x + 1 ) * u ) / 16 ) *
70+ Math . cos ( ( PI * ( 2 * y + 1 ) * v ) / 16 ) ;
8271 }
8372 }
84- const alpha = ( x === 0 ? 1 / SQRT2 : 1 ) * ( y === 0 ? 1 / SQRT2 : 1 ) ;
85- result [ x * 8 + y ] = ( 1 / 4 ) * alpha * sum ;
73+ result [ y * 8 + x ] = ( sum / 4 ) ;
8674 }
8775 }
8876 return result ;
8977}
9078
79+ export function dct ( block : Uint8Array ) {
80+ const result = new Int16Array ( 64 ) ;
81+ for ( let v = 0 ; v < 8 ; v ++ ) {
82+ for ( let u = 0 ; u < 8 ; u ++ ) {
83+ let sum = 0 ;
84+
85+ for ( let y = 0 ; y < 8 ; y ++ ) {
86+ for ( let x = 0 ; x < 8 ; x ++ ) {
87+ sum += block [ x + y * 8 ]
88+ * Math . cos ( ( PI * ( 2 * x + 1 ) * u ) / 16 )
89+ * Math . cos ( ( PI * ( 2 * y + 1 ) * v ) / 16 ) ;
90+ }
91+ }
92+
93+ result [ u + v * 8 ] = ( sum / 4 ) * alpha ( u ) * alpha ( v ) ;
94+ }
95+ }
96+
97+ return result ;
98+ }
99+
100+
91101function writeRgb ( dst : Uint8ClampedArray , index : number , y : number , u : number , v : number ) {
92102 // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion
93103 dst [ index + 0 ] = ( 298.082 * y + 408.583 * u ) / 256 - 222.921 ;
@@ -96,15 +106,16 @@ function writeRgb(dst: Uint8ClampedArray, index: number, y: number, u: number, v
96106 dst [ index + 3 ] = 255 ;
97107}
98108
99- function getMacroblockImageDataFromYuv ( data : Uint8Array [ ] ) {
100- const cCb = data [ 4 ] , cCr = data [ 5 ] ;
109+ function getMacroblockImageDataFromYuv ( data : Uint8ClampedArray [ ] ) {
110+ const cCb = data [ 5 ] , cCr = data [ 4 ] ;
101111
102112 const id = new ImageData ( 16 , 16 , { colorSpace : 'srgb' } ) ;
103113
104114 for ( let i = 0 ; i < 4 ; i ++ ) {
105115 const cY = data [ i ] ;
106116 const xa = i & 1 ? 8 : 0 ;
107117 const ya = i & 2 ? 8 : 0 ;
118+
108119 for ( let x = xa ; x < xa + 8 ; x ++ ) {
109120 for ( let y = ya ; y < ya + 8 ; y ++ ) {
110121 const cyi = ( x & 7 ) + 8 * ( y & 7 ) ;
@@ -172,7 +183,7 @@ export class Frame {
172183 }
173184
174185 const mtype = h261 . MTYPE [ this . br . countLeadingZeroes ( ) ] ;
175- console . log ( this . mba , h261 . getMtypeString ( mtype ) ) ;
186+ // console.log(this.mba, h261.getMtypeString(mtype));
176187
177188 const mb : Macroblock = {
178189 address : this . mba ,
@@ -195,13 +206,11 @@ export class Frame {
195206 }
196207
197208 const mvd1 = this . br . readVlcOr ( vlc . MVD_TREE , - 1 ) ;
198- /*
199- TODO(mbabnik): track motion vectors; and if we should do the diff
200- thing, since we then read an extra bit?
201- */
209+ //TODO(mbabnik): motion vectors
202210 const mvd2 = this . br . readVlcOr ( vlc . MVD_TREE , - 1 ) ;
203211
204- console . log ( { previousMv, mvd1, mvd2 } )
212+ void mvd1 ;
213+ void mvd2 ;
205214
206215 mb . mvd = [ 0 , 0 ] ;
207216 }
@@ -216,7 +225,7 @@ export class Frame {
216225 }
217226 mb . cbp = cbp ;
218227
219- const tmpBlock = new Uint8Array ( 64 ) ;
228+ const tmpBlock = new Int16Array ( 64 ) ;
220229
221230 // for each block (in a macroblock)
222231 block: for ( let i = 0 ; i < 6 ; i ++ ) {
@@ -226,10 +235,10 @@ export class Frame {
226235 const coded = ! ! ( cbp & ( 1 << ( 5 - i ) ) ) ;
227236
228237 if ( ! ( mtype . prediction & h261 . INTER_BIT ) ) { // INTRA
229- const dcCoefLvl = ( this . br . readInt ( 8 ) << 24 ) >> 24 ; // sign extend i8
238+ const dcCoefLvl = this . br . readInt ( 8 ) ;
230239 tmpBlock [ 0 ] = reconstructDC ( dcCoefLvl ) ;
231240 j = 1 ;
232- } else if ( coded ) {
241+ } else if ( coded ) {
233242 const check = this . br . peekInt ( 2 ) ;
234243 if ( check & 0x2 ) {
235244 this . br . readInt ( 2 ) ;
@@ -267,9 +276,9 @@ export class Frame {
267276 reconstruct ( level , mb . mquant ?? gquant ) ;
268277 }
269278 }
270-
271279 mb . blocks [ i ] = { data : idct ( tmpBlock ) , index : i } ;
272280 }
281+ // throw "time to throw pogchamp";
273282 }
274283 return mb ;
275284 }
@@ -289,7 +298,7 @@ export class Frame {
289298 console . log ( 'Discarding extra byte:' , this . br . readInt ( 8 ) )
290299 }
291300
292- console . groupCollapsed ( `GOB ${ groupNumber } ` )
301+ // console.groupCollapsed(`GOB ${groupNumber}`)
293302
294303 // console.log({ groupNumber, gquant, at: this.br.at.toString(16) })
295304 const macroblocks = [ ] ;
@@ -317,7 +326,7 @@ export class Frame {
317326 }
318327
319328 protected read ( ) {
320- console . groupCollapsed ( `frame ${ this . frameNumber } ` )
329+ // console.groupCollapsed(`frame ${this.frameNumber}`)
321330
322331 while ( this . br . peekInt ( 20 ) != h261 . PSC ) {
323332 this . br . readInt ( 1 ) ;
@@ -345,7 +354,7 @@ export class Frame {
345354 this . gobs [ i ] = this . readGob ( i ) ;
346355 }
347356
348- console . groupEnd ( ) ;
357+ // console.groupEnd();
349358 }
350359
351360
0 commit comments