pdk: Fix pink callback frames in TestingCamera.

Bug: 11862185
Change-Id: I41ff99758f1997ed9726e7aafc700fca67563bea
(cherry picked from commit c1480a9318b601dfe016a48ba37abeaffe6d23cc)
diff --git a/apps/TestingCamera/src/com/android/testingcamera/CallbackProcessor.java b/apps/TestingCamera/src/com/android/testingcamera/CallbackProcessor.java
index 0dfd1e3..3edd78f 100644
--- a/apps/TestingCamera/src/com/android/testingcamera/CallbackProcessor.java
+++ b/apps/TestingCamera/src/com/android/testingcamera/CallbackProcessor.java
@@ -44,17 +44,6 @@
     private boolean mDone = false;
     private boolean mTaskInProgress = false;
 
-     /**
-      * JFIF standard YCbCr <-> RGB conversion matrix,
-      * column-major order.
-      */
-    static final private float[] kJpegYuv2Rgb = new float[] {
-            1.f,     1.f,      1.f,     0.f,
-            0.f,    -0.34414f, 1.772f,  0.f,
-            1.402f, -0.71414f, 0.f,     0.f,
-           -0.701f,  0.529f,  -0.886f, 1.0f
-    };
-
     static final private int kStopTimeout = 2000; // ms
 
     private static final String TAG = "CallbackProcessor";
@@ -87,6 +76,7 @@
         swizzleScript.invoke_init_convert(mWidth, mHeight,
             mFormat, viewWidth, viewHeight);
         Script.KernelID swizzleId;
+
         switch (mFormat) {
         case ImageFormat.NV21:
             swizzleId = swizzleScript.getKernelID_convert_semiplanar();
@@ -102,20 +92,11 @@
             swizzleId = swizzleScript.getKernelID_convert_unknown();
         }
 
-        ScriptIntrinsicColorMatrix colorMatrix =
-                ScriptIntrinsicColorMatrix.create(rs, Element.U8_4(mRS));
-
-        Matrix4f yuv2rgb = new Matrix4f(kJpegYuv2Rgb);
-        colorMatrix.setColorMatrix(yuv2rgb);
-
         ScriptGroup.Builder b = new ScriptGroup.Builder(rs);
         b.addKernel(swizzleId);
-        b.addKernel(colorMatrix.getKernelID());
-        b.addConnection(outType, swizzleId,
-                colorMatrix.getKernelID());
         mConverter = b.create();
 
-        mConverter.setOutput(colorMatrix.getKernelID(), mAllocationOut);
+        mConverter.setOutput(swizzleId, mAllocationOut);
     }
 
     public boolean stop() {
diff --git a/apps/TestingCamera/src/com/android/testingcamera/callback.rs b/apps/TestingCamera/src/com/android/testingcamera/callback.rs
index ba7b891..1dc2fa2 100644
--- a/apps/TestingCamera/src/com/android/testingcamera/callback.rs
+++ b/apps/TestingCamera/src/com/android/testingcamera/callback.rs
@@ -17,6 +17,21 @@
 float x_scale;
 float y_scale;
 
+static const float CLAMP_MIN = 0;
+static const float CLAMP_MAX = 255;
+
+/**
+ * JFIF standard YCbCr <-> RGB conversion matrix,
+ * column-major order.
+ */
+static const float YUV2RGB[] = {
+    1.0f, 1.0f, 1.0f, 0.0f,
+    0.0f, -0.34414f, 1.772f, 0.0f,
+    1.402f, -0.71414f, 0.0f, 0.0f,
+    -0.701f, 0.529f, -0.886f, 1.0f
+};
+rs_matrix4x4 yuv2rgb_matrix;
+
 enum ImageFormat {
     NV16 = 16,
     NV21 = 17,
@@ -33,6 +48,7 @@
     yuv_width = yw;
     out_width = ow;
     out_height = oh;
+    rsMatrixLoad(&yuv2rgb_matrix, YUV2RGB);
 
     x_scale = (float)yuv_width / out_width;
     y_scale = (float)yuv_height / out_height;
@@ -68,6 +84,14 @@
     }
 }
 
+// Multiply by color matrix and clamp to range [0, 255]
+static inline uchar4 multiply_and_clamp(const rs_matrix4x4* mat, uchar4 input) {
+    float4 intermediate = convert_float4(input);
+    intermediate = rsMatrixMultiply(mat, intermediate);
+    intermediate = clamp(intermediate, CLAMP_MIN, CLAMP_MAX);
+    return convert_uchar4(intermediate);
+}
+
 // Makes up a conversion for unknown YUV types to try to display something
 // Asssumes that there's at least 1bpp in input YUV data
 uchar4 __attribute__((kernel)) convert_unknown(uint32_t x, uint32_t y) {
@@ -79,7 +103,9 @@
     out.g = 128;
     out.b = 128;
     out.a = 255; // For affine transform later
-    return out;
+
+    // Apply yuv->rgb color transform
+    return multiply_and_clamp(&yuv2rgb_matrix, out);
 }
 
 // Converts semiplanar YVU to interleaved YUV, nearest neighbor
@@ -96,7 +122,9 @@
     out.g = yuv_in[u_start + vu_pixel];
     out.b = yuv_in[v_start + vu_pixel];
     out.a = 255; // For affine transform later
-    return out;
+
+    // Apply yuv->rgb color transform
+    return multiply_and_clamp(&yuv2rgb_matrix, out);
 }
 
 // Converts planar YVU to interleaved YUV, nearest neighbor
@@ -112,7 +140,9 @@
     out.g = yuv_in[u_start + vu_pixel];
     out.b = yuv_in[v_start + vu_pixel];
     out.a = 255; // For affine transform later
-    return out;
+
+    // Apply yuv->rgb color transform
+    return multiply_and_clamp(&yuv2rgb_matrix, out);
 }
 
 // Converts interleaved 4:2:2 YUV to interleaved YUV, nearest neighbor
@@ -128,5 +158,7 @@
     out.g = yuv_in[u_start + vu_pixel];
     out.b = yuv_in[v_start + vu_pixel];
     out.a = 255; // For affine transform later
-    return out;
+
+    // Apply yuv->rgb color transform
+    return multiply_and_clamp(&yuv2rgb_matrix, out);
 }