ref: 2cbf64119c40de4896f033ac1fbfa63f406d1f14
parent: 66b48e63192e40f61cf52e2100b13315357ece4e
author: Sam Leitch <sam.leitch@calgaryscientific.com>
date: Tue Mar 18 12:23:01 EDT 2014
First attempt at a faster yuv conversion in flex. Failed.
--- a/flex/src/h264bsd/Decoder.as
+++ b/flex/src/h264bsd/Decoder.as
@@ -3,8 +3,10 @@
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.EventDispatcher;
+ import flash.filters.ColorMatrixFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
+ import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
import flash.utils.Endian;
@@ -152,11 +154,63 @@
public function drawNextOutputPicture(target:Bitmap, transform:Matrix = null):void
{
- var rgbBytes:ByteArray = getNextOutputPictureBytesBGRA();
-
+ var i420Bytes:ByteArray = getNextOutputPictureBytes();
var cinfo:CroppingInfo = getCroppingInfo();
- var outputPicture:BitmapData = new BitmapData(cinfo.uncroppedWidth, cinfo.uncroppedHeight);
- outputPicture.setPixels(new Rectangle(0,0, cinfo.uncroppedWidth, cinfo.uncroppedHeight), rgbBytes);
+
+ var width:int = cinfo.uncroppedWidth;
+ var height:int = cinfo.uncroppedHeight;
+
+ var yPtr:int = 0;
+ var cbPtr:int = width * height;
+ var crPtr:int = cbPtr + width / 2 * height / 2;
+
+ var yuvVector:Vector.<uint> = new Vector.<uint>(width * height);
+ var yuvPtr:int = 0;
+
+ var y:int = 0;
+ var x:int = 0;
+
+ while(y < height)
+ {
+ var yuv:uint = 0xff;
+ yuv = (yuv << 8) + i420Bytes[yPtr];
+ yuv = (yuv << 8) + i420Bytes[cbPtr];
+ yuv = (yuv << 8) + i420Bytes[crPtr];
+
+ i420Bytes[yuvPtr] = yuv;
+
+ ++x;
+ ++yPtr;
+ ++yuvPtr;
+
+ if((x & 1) == 0)
+ {
+ ++cbPtr;
+ ++crPtr;
+ }
+
+ if(x < width) continue;
+
+ ++y;
+ x = 0;
+
+ if((y & 1) > 0)
+ {
+ cbPtr -= width / 2;
+ crPtr -= width / 2;
+ }
+ }
+
+ var outputPicture:BitmapData = new BitmapData(width, height);
+ outputPicture.setVector(new Rectangle(0,0, width, height), yuvVector);
+
+ var yuvFilter:ColorMatrixFilter = new ColorMatrixFilter(
+ [1.1643828125, 0, 1.59602734375, -.87078515625, 0,
+ 1.1643828125, -.39176171875, -.81296875, .52959375, 0,
+ 1.1643828125, 2.017234375, 0, -1.081390625, 0,
+ 0, 0, 0, 1, 0]);
+
+ outputPicture.applyFilter(outputPicture, outputPicture.rect, new Point(0,0), yuvFilter);
target.bitmapData.lock();
target.bitmapData.draw(outputPicture, transform, null, null, new Rectangle(0,0, cinfo.width, cinfo.height), true);