Quellcode durchsuchen

Faster YCrCbToRGBA conversion

Dominic Szablewski vor 12 Jahren
Ursprung
Commit
1307634805
1 geänderte Dateien mit 68 neuen und 55 gelöschten Zeilen
  1. 68 55
      jsmpg.js

+ 68 - 55
jsmpg.js Datei anzeigen

@@ -241,8 +241,8 @@ jsmpeg.prototype.decodeSequenceHeader = function() {
241 241
 	this.canvas.width = this.width;
242 242
 	this.canvas.height = this.height;
243 243
 	
244
-	this.currentRGB = this.canvasContext.getImageData(0, 0, this.width, this.height);
245
-	this.fillArray(this.currentRGB.data, 255);
244
+	this.currentRGBA = this.canvasContext.getImageData(0, 0, this.width, this.height);
245
+	this.fillArray(this.currentRGBA.data, 255);
246 246
 };
247 247
 
248 248
 
@@ -255,7 +255,7 @@ jsmpeg.prototype.currentY = null;
255 255
 jsmpeg.prototype.currentCr = null;
256 256
 jsmpeg.prototype.currentCb = null;
257 257
 
258
-jsmpeg.prototype.currentRGB = null;
258
+jsmpeg.prototype.currentRGBA = null;
259 259
 
260 260
 jsmpeg.prototype.pictureCodingType = 0;
261 261
 
@@ -339,8 +339,8 @@ jsmpeg.prototype.decodePicture = function() {
339 339
 	this.buffer.rewind(32);
340 340
 	
341 341
 	
342
-	this.YCrCbToRGB();
343
-	this.canvasContext.putImageData(this.currentRGB, 0, 0);
342
+	this.YCrCbToRGBA();
343
+	this.canvasContext.putImageData(this.currentRGBA, 0, 0);
344 344
 	
345 345
 	// If this is a reference picutre then rotate the prediction pointers
346 346
 	if( this.pictureCodingType == PICTURE_TYPE_I || this.pictureCodingType == PICTURE_TYPE_P ) {
@@ -353,61 +353,74 @@ jsmpeg.prototype.decodePicture = function() {
353 353
 	}
354 354
 };
355 355
 
356
-jsmpeg.prototype.YCrCbToRGB = function() {
357
-	// We process two lines at a time
358
-	var size = this.codedSize >> 2;
359
-
360
-	var index1 = 0;
361
-	var rgbIndex1 = 0;
362
-	var index2 = this.codedWidth;
363
-	var rgbIndex2 = this.width * 4;
364
-	
356
+jsmpeg.prototype.YCrCbToRGBA = function() {	
365 357
 	var pY = this.currentY;
366 358
 	var pCr = this.currentCr;
367 359
 	var pCb = this.currentCb;
368
-	var pRGB = this.currentRGB.data;
369
-	
370
-	var wrap = this.codedWidth + (this.codedWidth - this.width);
371
-	var chromaWrap = this.halfWidth - (this.width >> 1);
372
-	var rgbWrap = this.width * 4;
360
+	var pRGBA = this.currentRGBA.data;
361
+
362
+
363
+	// Chroma values are the same for each block of 4 pixels, so we proccess
364
+	// 2 lines at a time, 2 neighboring pixels each.
365
+
366
+	var yIndex1 = 0;
367
+	var yIndex2 = this.codedWidth;
368
+	var yNext2Lines = this.codedWidth + (this.codedWidth - this.width);
369
+
370
+	var cIndex = 0;
371
+	var cNextLine = this.halfWidth - (this.width >> 1);
372
+
373
+	var rgbaIndex1 = 0;
374
+	var rgbaIndex2 = this.width * 4;
375
+	var rgbaNext2Lines = this.width * 4;
373 376
 	
374
-	var y, cb, cr;
375
-	for( var i = 0; i < size; i++ ) {
376
-		cb = pCb[i] - 128;
377
-		cr = pCr[i] - 128;
378
-		
379
-		y = pY[index1++];
380
-		pRGB[rgbIndex1] = y + 1.4 * cr;
381
-		pRGB[rgbIndex1+1] = y + -0.343 * cb - 0.711 * cr;
382
-		pRGB[rgbIndex1+2] = y + 1.765 * cb;
383
-		rgbIndex1+=4;
384
-		
385
-		y = pY[index1++];
386
-		pRGB[rgbIndex1] = y + 1.4 * cr;
387
-		pRGB[rgbIndex1+1] = y + -0.343 * cb - 0.711 * cr;
388
-		pRGB[rgbIndex1+2] = y + 1.765 * cb;
389
-		rgbIndex1+=4;
390
-		
391
-		y = pY[index2++];
392
-		pRGB[rgbIndex2] = y + 1.4 * cr;
393
-		pRGB[rgbIndex2+1] = y + -0.343 * cb - 0.711 * cr;
394
-		pRGB[rgbIndex2+2] = y + 1.765 * cb;
395
-		rgbIndex2+=4;
396
-		
397
-		y = pY[index2++];
398
-		pRGB[rgbIndex2] = y + 1.4 * cr;
399
-		pRGB[rgbIndex2+1] = y + -0.343 * cb - 0.711 * cr;
400
-		pRGB[rgbIndex2+2] = y + 1.765 * cb;
401
-		rgbIndex2+=4;
402
-		
403
-		// Next two lines
404
-		if( rgbIndex1 % rgbWrap == 0 ) {
405
-			i += chromaWrap;
406
-			index1 += wrap;
407
-			index2 += wrap;
408
-			rgbIndex1 += rgbWrap;
409
-			rgbIndex2 += rgbWrap;
377
+	var cols = this.width >> 1;
378
+	var rows = this.height >> 1;
379
+
380
+	var y, cb, cr, r, g, b;
381
+
382
+	for( var row = 0; row < rows; row++ ) {
383
+		for( var col = 0; col < cols; col++ ) {
384
+			cb = pCb[cIndex];
385
+			cr = pCr[cIndex];
386
+			cIndex++;
387
+			
388
+			r = (cr + ((cr * 103) >> 8)) - 179;
389
+			g = ((cb * 88) >> 8) - 44 + ((cr * 183) >> 8) - 91;
390
+			b = (cb + ((cb * 198) >> 8)) - 227;
391
+			
392
+			// Line 1
393
+			y = pY[yIndex1++];
394
+			pRGBA[rgbaIndex1] = y + r;
395
+			pRGBA[rgbaIndex1+1] = y - g;
396
+			pRGBA[rgbaIndex1+2] = y + b;
397
+			rgbaIndex1 += 4;
398
+			
399
+			y = pY[yIndex1++];
400
+			pRGBA[rgbaIndex1] = y + r;
401
+			pRGBA[rgbaIndex1+1] = y - g;
402
+			pRGBA[rgbaIndex1+2] = y + b;
403
+			rgbaIndex1 += 4;
404
+			
405
+			// Line 2
406
+			y = pY[yIndex2++];
407
+			pRGBA[rgbaIndex2] = y + r;
408
+			pRGBA[rgbaIndex2+1] = y - g;
409
+			pRGBA[rgbaIndex2+2] = y + b;
410
+			rgbaIndex2 += 4;
411
+			
412
+			y = pY[yIndex2++];
413
+			pRGBA[rgbaIndex2] = y + r;
414
+			pRGBA[rgbaIndex2+1] = y - g;
415
+			pRGBA[rgbaIndex2+2] = y + b;
416
+			rgbaIndex2 += 4;
410 417
 		}
418
+		
419
+		yIndex1 += yNext2Lines;
420
+		yIndex2 += yNext2Lines;
421
+		rgbaIndex1 += rgbaNext2Lines;
422
+		rgbaIndex2 += rgbaNext2Lines;
423
+		cIndex += cNextLine;
411 424
 	}
412 425
 };
413 426