Merge "Add CTS tests for tl <-> fil conversion."
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index 027e00d..f2fb322 100644
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -62,12 +62,18 @@
     private static final int TEST_Y = 120;                  // YUV values for colored rect
     private static final int TEST_U = 160;
     private static final int TEST_V = 200;
-    private static final int TEST_R0 = 0;                   // RGB equivalent of {0,0,0}
+    private static final int TEST_R0 = 0;                   // RGB equivalent of {0,0,0} (BT.601)
     private static final int TEST_G0 = 136;
     private static final int TEST_B0 = 0;
-    private static final int TEST_R1 = 236;                 // RGB equivalent of {120,160,200}
+    private static final int TEST_R1 = 236;                 // RGB equivalent of {120,160,200} (BT.601)
     private static final int TEST_G1 = 50;
     private static final int TEST_B1 = 186;
+    private static final int TEST_R0_BT709 = 0;             // RGB equivalent of {0,0,0} (BT.709)
+    private static final int TEST_G0_BT709 = 77;
+    private static final int TEST_B0_BT709 = 0;
+    private static final int TEST_R1_BT709 = 250;           // RGB equivalent of {120,160,200} (BT.709)
+    private static final int TEST_G1_BT709 = 76;
+    private static final int TEST_B1_BT709 = 189;
 
     // size of a frame, in pixels
     private int mWidth = -1;
@@ -79,6 +85,9 @@
     // largest color component delta seen (i.e. actual vs. expected)
     private int mLargestColorDelta;
 
+    // validate YUV->RGB decoded frames against BT.601 and/or BT.709
+    private boolean mAllowBT601 = true;
+    private boolean mAllowBT709 = false;
 
     /**
      * Tests streaming of AVC video through the encoder and decoder.  Data is encoded from
@@ -86,15 +95,15 @@
      * validity.
      */
     public void testEncodeDecodeVideoFromBufferToBufferQCIF() throws Exception {
-        setParameters(176, 144, 1000000, MIME_TYPE_AVC);
+        setParameters(176, 144, 1000000, MIME_TYPE_AVC, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
     public void testEncodeDecodeVideoFromBufferToBufferQVGA() throws Exception {
-        setParameters(320, 240, 2000000, MIME_TYPE_AVC);
+        setParameters(320, 240, 2000000, MIME_TYPE_AVC, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
     public void testEncodeDecodeVideoFromBufferToBuffer720p() throws Exception {
-        setParameters(1280, 720, 6000000, MIME_TYPE_AVC);
+        setParameters(1280, 720, 6000000, MIME_TYPE_AVC, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
 
@@ -104,15 +113,15 @@
      * validity.
      */
     public void testVP8EncodeDecodeVideoFromBufferToBufferQCIF() throws Exception {
-        setParameters(176, 144, 1000000, MIME_TYPE_VP8);
+        setParameters(176, 144, 1000000, MIME_TYPE_VP8, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
     public void testVP8EncodeDecodeVideoFromBufferToBufferQVGA() throws Exception {
-        setParameters(320, 240, 2000000, MIME_TYPE_VP8);
+        setParameters(320, 240, 2000000, MIME_TYPE_VP8, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
     public void testVP8EncodeDecodeVideoFromBufferToBuffer720p() throws Exception {
-        setParameters(1280, 720, 6000000, MIME_TYPE_VP8);
+        setParameters(1280, 720, 6000000, MIME_TYPE_VP8, true, false);
         encodeDecodeVideoFromBuffer(false);
     }
 
@@ -129,15 +138,15 @@
      * the test.
      */
     public void testEncodeDecodeVideoFromBufferToSurfaceQCIF() throws Throwable {
-        setParameters(176, 144, 1000000, MIME_TYPE_AVC);
+        setParameters(176, 144, 1000000, MIME_TYPE_AVC, true, false);
         BufferToSurfaceWrapper.runTest(this);
     }
     public void testEncodeDecodeVideoFromBufferToSurfaceQVGA() throws Throwable {
-        setParameters(320, 240, 2000000, MIME_TYPE_AVC);
+        setParameters(320, 240, 2000000, MIME_TYPE_AVC, true, false);
         BufferToSurfaceWrapper.runTest(this);
     }
     public void testEncodeDecodeVideoFromBufferToSurface720p() throws Throwable {
-        setParameters(1280, 720, 6000000, MIME_TYPE_AVC);
+        setParameters(1280, 720, 6000000, MIME_TYPE_AVC, true, true);
         BufferToSurfaceWrapper.runTest(this);
     }
 
@@ -147,15 +156,15 @@
      * validity.
      */
     public void testVP8EncodeDecodeVideoFromBufferToSurfaceQCIF() throws Throwable {
-        setParameters(176, 144, 1000000, MIME_TYPE_VP8);
+        setParameters(176, 144, 1000000, MIME_TYPE_VP8, true, false);
         BufferToSurfaceWrapper.runTest(this);
     }
     public void testVP8EncodeDecodeVideoFromBufferToSurfaceQVGA() throws Throwable {
-        setParameters(320, 240, 2000000, MIME_TYPE_VP8);
+        setParameters(320, 240, 2000000, MIME_TYPE_VP8, true, false);
         BufferToSurfaceWrapper.runTest(this);
     }
     public void testVP8EncodeDecodeVideoFromBufferToSurface720p() throws Throwable {
-        setParameters(1280, 720, 6000000, MIME_TYPE_VP8);
+        setParameters(1280, 720, 6000000, MIME_TYPE_VP8, true, true);
         BufferToSurfaceWrapper.runTest(this);
     }
 
@@ -196,15 +205,15 @@
      * a Surface and decoded onto a Surface.  The output is checked for validity.
      */
     public void testEncodeDecodeVideoFromSurfaceToSurfaceQCIF() throws Throwable {
-        setParameters(176, 144, 1000000, MIME_TYPE_AVC);
+        setParameters(176, 144, 1000000, MIME_TYPE_AVC, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
     public void testEncodeDecodeVideoFromSurfaceToSurfaceQVGA() throws Throwable {
-        setParameters(320, 240, 2000000, MIME_TYPE_AVC);
+        setParameters(320, 240, 2000000, MIME_TYPE_AVC, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
     public void testEncodeDecodeVideoFromSurfaceToSurface720p() throws Throwable {
-        setParameters(1280, 720, 6000000, MIME_TYPE_AVC);
+        setParameters(1280, 720, 6000000, MIME_TYPE_AVC, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
 
@@ -213,15 +222,15 @@
      * a Surface and decoded onto a Surface.  The output is checked for validity.
      */
     public void testVP8EncodeDecodeVideoFromSurfaceToSurfaceQCIF() throws Throwable {
-        setParameters(176, 144, 1000000, MIME_TYPE_VP8);
+        setParameters(176, 144, 1000000, MIME_TYPE_VP8, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
     public void testVP8EncodeDecodeVideoFromSurfaceToSurfaceQVGA() throws Throwable {
-        setParameters(320, 240, 2000000, MIME_TYPE_VP8);
+        setParameters(320, 240, 2000000, MIME_TYPE_VP8, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
     public void testVP8EncodeDecodeVideoFromSurfaceToSurface720p() throws Throwable {
-        setParameters(1280, 720, 6000000, MIME_TYPE_VP8);
+        setParameters(1280, 720, 6000000, MIME_TYPE_VP8, true, false);
         SurfaceToSurfaceWrapper.runTest(this);
     }
 
@@ -260,7 +269,8 @@
     /**
      * Sets the desired frame size and bit rate.
      */
-    private void setParameters(int width, int height, int bitRate, String mimeType) {
+    private void setParameters(int width, int height, int bitRate, String mimeType,
+	        boolean allowBT601, boolean allowBT709) {
         if ((width % 16) != 0 || (height % 16) != 0) {
             Log.w(TAG, "WARNING: width or height not multiple of 16");
         }
@@ -268,6 +278,8 @@
         mHeight = height;
         mBitRate = bitRate;
         mMimeType = mimeType;
+        mAllowBT601 = allowBT601;
+        mAllowBT709 = allowBT709;
     }
 
     /**
@@ -1149,22 +1161,41 @@
             int b = pixelBuf.get(2) & 0xff;
             //Log.d(TAG, "GOT(" + frameIndex + "/" + i + "): r=" + r + " g=" + g + " b=" + b);
 
-            int expR, expG, expB;
+            int expR, expG, expB, expR_bt709, expG_bt709, expB_bt709;
             if (i == frameIndex % 8) {
                 // colored rect
                 expR = TEST_R1;
                 expG = TEST_G1;
                 expB = TEST_B1;
+                expR_bt709 = TEST_R1_BT709;
+                expG_bt709 = TEST_G1_BT709;
+                expB_bt709 = TEST_B1_BT709;
             } else {
                 // zero background color
                 expR = TEST_R0;
                 expG = TEST_G0;
                 expB = TEST_B0;
+                expR_bt709 = TEST_R0_BT709;
+                expG_bt709 = TEST_G0_BT709;
+                expB_bt709 = TEST_B0_BT709;
             }
-            if (!isColorClose(r, expR) ||
-                    !isColorClose(g, expG) ||
-                    !isColorClose(b, expB)) {
-                Log.w(TAG, "Bad frame " + frameIndex + " (rect=" + i + ": rgb=" + r +
+
+            // Some decoders use BT.709 when converting HD (i.e. >= 720p)
+            // frames from YUV to RGB, so check against both BT.601 and BT.709
+            if (mAllowBT601 &&
+                    isColorClose(r, expR) &&
+                    isColorClose(g, expG) &&
+                    isColorClose(b, expB)) {
+                // frame OK on BT.601
+                mAllowBT709 = false;
+            } else if (mAllowBT709 &&
+                           isColorClose(r, expR_bt709) &&
+                           isColorClose(g, expG_bt709) &&
+                           isColorClose(b, expB_bt709)) {
+                // frame OK on BT.709
+                mAllowBT601 = false;
+            } else {
+                Log.w(TAG, "Bad frame " + frameIndex + " (rect=" + i + " @ " + x + " " + y + ": rgb=" + r +
                         "," + g + "," + b + " vs. expected " + expR + "," + expG +
                         "," + expB + ")");
                 frameFailed = true;