Add H420 and H422 to ConvertToARGB()

H420/H422 are bt.720 variants

TBR=braveyao@chromium.org
BUG=libyuv:799
TESTED=try bots tested build on all platforms

Change-Id: I007d8981d91ca0748c59403759109bbcd88f286c
Reviewed-on: https://chromium-review.googlesource.com/1115719
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
diff --git a/README.chromium b/README.chromium
index 8fa5e00..e1a4ebd 100644
--- a/README.chromium
+++ b/README.chromium
@@ -1,6 +1,6 @@
 Name: libyuv
 URL: http://code.google.com/p/libyuv/
-Version: 1711
+Version: 1712
 License: BSD
 License File: LICENSE
 
diff --git a/docs/formats.md b/docs/formats.md
index f78f57b..97e8ce0 100644
--- a/docs/formats.md
+++ b/docs/formats.md
@@ -66,7 +66,7 @@
       // 1 Primary Compressed YUV format.
       FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'),
 
-      // 7 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias.
+      // 8 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias.
       FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'),
       FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'),
       FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'),
@@ -74,6 +74,7 @@
       FOURCC_J420 = FOURCC('J', '4', '2', '0'),
       FOURCC_J400 = FOURCC('J', '4', '0', '0'),  // unofficial fourcc
       FOURCC_H420 = FOURCC('H', '4', '2', '0'),  // unofficial fourcc
+      FOURCC_H422 = FOURCC('H', '4', '2', '2'),  // unofficial fourcc
 
       // 14 Auxiliary aliases.  CanonicalFourCC() maps these to canonical fourcc.
       FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'),  // Alias for I420.
diff --git a/include/libyuv/macros_msa.h b/include/libyuv/macros_msa.h
index bba0e8a..29997ce 100644
--- a/include/libyuv/macros_msa.h
+++ b/include/libyuv/macros_msa.h
@@ -16,25 +16,25 @@
 #include <stdint.h>
 
 #if (__mips_isa_rev >= 6)
-#define LW(psrc)                                        \
-  ({                                                    \
-    const uint8_t* psrc_lw_m = (const uint8_t*)(psrc);  \
-    uint32_t val_m;                                     \
-    asm volatile("lw  %[val_m],  %[psrc_lw_m]  \n"      \
-                 : [val_m] "=r"(val_m)                  \
-                 : [psrc_lw_m] "m"(*psrc_lw_m));        \
-    val_m;                                              \
+#define LW(psrc)                                       \
+  ({                                                   \
+    const uint8_t* psrc_lw_m = (const uint8_t*)(psrc); \
+    uint32_t val_m;                                    \
+    asm volatile("lw  %[val_m],  %[psrc_lw_m]  \n"     \
+                 : [val_m] "=r"(val_m)                 \
+                 : [psrc_lw_m] "m"(*psrc_lw_m));       \
+    val_m;                                             \
   })
 
 #if (__mips == 64)
-#define LD(psrc)                                        \
-  ({                                                    \
-    const uint8_t* psrc_ld_m = (const uint8_t*)(psrc);  \
-    uint64_t val_m = 0;                                 \
-    asm volatile("ld  %[val_m],  %[psrc_ld_m]  \n"      \
-                 : [val_m] "=r"(val_m)                  \
-                 : [psrc_ld_m] "m"(*psrc_ld_m));        \
-    val_m;                                              \
+#define LD(psrc)                                       \
+  ({                                                   \
+    const uint8_t* psrc_ld_m = (const uint8_t*)(psrc); \
+    uint64_t val_m = 0;                                \
+    asm volatile("ld  %[val_m],  %[psrc_ld_m]  \n"     \
+                 : [val_m] "=r"(val_m)                 \
+                 : [psrc_ld_m] "m"(*psrc_ld_m));       \
+    val_m;                                             \
   })
 #else  // !(__mips == 64)
 #define LD(psrc)                                                         \
@@ -81,25 +81,25 @@
   })
 #endif  // !(__mips == 64)
 #else   // !(__mips_isa_rev >= 6)
-#define LW(psrc)                                        \
-  ({                                                    \
-    const uint8_t* psrc_lw_m = (const uint8_t*)(psrc);  \
-    uint32_t val_m;                                     \
-    asm volatile("ulw  %[val_m],  %[psrc_lw_m]  \n"     \
-                 : [val_m] "=r"(val_m)                  \
-                 : [psrc_lw_m] "m"(*psrc_lw_m));        \
-    val_m;                                              \
+#define LW(psrc)                                       \
+  ({                                                   \
+    const uint8_t* psrc_lw_m = (const uint8_t*)(psrc); \
+    uint32_t val_m;                                    \
+    asm volatile("ulw  %[val_m],  %[psrc_lw_m]  \n"    \
+                 : [val_m] "=r"(val_m)                 \
+                 : [psrc_lw_m] "m"(*psrc_lw_m));       \
+    val_m;                                             \
   })
 
 #if (__mips == 64)
-#define LD(psrc)                                        \
-  ({                                                    \
-    const uint8_t* psrc_ld_m = (const uint8_t*)(psrc);  \
-    uint64_t val_m = 0;                                 \
-    asm volatile("uld  %[val_m],  %[psrc_ld_m]  \n"     \
-                 : [val_m] "=r"(val_m)                  \
-                 : [psrc_ld_m] "m"(*psrc_ld_m));        \
-    val_m;                                              \
+#define LD(psrc)                                       \
+  ({                                                   \
+    const uint8_t* psrc_ld_m = (const uint8_t*)(psrc); \
+    uint64_t val_m = 0;                                \
+    asm volatile("uld  %[val_m],  %[psrc_ld_m]  \n"    \
+                 : [val_m] "=r"(val_m)                 \
+                 : [psrc_ld_m] "m"(*psrc_ld_m));       \
+    val_m;                                             \
   })
 #else  // !(__mips == 64)
 #define LD(psrc)                                                         \
diff --git a/include/libyuv/version.h b/include/libyuv/version.h
index 7022785..f3cfeb6 100644
--- a/include/libyuv/version.h
+++ b/include/libyuv/version.h
@@ -11,6 +11,6 @@
 #ifndef INCLUDE_LIBYUV_VERSION_H_
 #define INCLUDE_LIBYUV_VERSION_H_
 
-#define LIBYUV_VERSION 1711
+#define LIBYUV_VERSION 1712
 
 #endif  // INCLUDE_LIBYUV_VERSION_H_
diff --git a/include/libyuv/video_common.h b/include/libyuv/video_common.h
index bcef378..ffcbdbf 100644
--- a/include/libyuv/video_common.h
+++ b/include/libyuv/video_common.h
@@ -30,7 +30,8 @@
 #ifdef __cplusplus
 #define FOURCC(a, b, c, d)                                        \
   ((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \
-   (static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24))
+   (static_cast<uint32_t>(c) << 16) | /* NOLINT */                \
+   (static_cast<uint32_t>(d) << 24))  /* NOLINT */
 #else
 #define FOURCC(a, b, c, d)                                     \
   (((uint32_t)(a)) | ((uint32_t)(b) << 8) |       /* NOLINT */ \
@@ -79,7 +80,7 @@
   // 1 Primary Compressed YUV format.
   FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'),
 
-  // 7 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias.
+  // 8 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias.
   FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'),
   FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'),
   FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'),
@@ -87,6 +88,7 @@
   FOURCC_J420 = FOURCC('J', '4', '2', '0'),
   FOURCC_J400 = FOURCC('J', '4', '0', '0'),  // unofficial fourcc
   FOURCC_H420 = FOURCC('H', '4', '2', '0'),  // unofficial fourcc
+  FOURCC_H422 = FOURCC('H', '4', '2', '2'),  // unofficial fourcc
 
   // 14 Auxiliary aliases.  CanonicalFourCC() maps these to canonical fourcc.
   FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'),  // Alias for I420.
@@ -155,6 +157,7 @@
   FOURCC_BPP_J420 = 12,
   FOURCC_BPP_J400 = 8,
   FOURCC_BPP_H420 = 12,
+  FOURCC_BPP_H422 = 16,
   FOURCC_BPP_H010 = 24,
   FOURCC_BPP_MJPG = 0,  // 0 means unknown.
   FOURCC_BPP_H264 = 0,
diff --git a/source/convert_to_argb.cc b/source/convert_to_argb.cc
index 6748452..bde1aa8 100644
--- a/source/convert_to_argb.cc
+++ b/source/convert_to_argb.cc
@@ -31,8 +31,6 @@
 
 // TODO(fbarchard): Add the following:
 // H010ToARGB
-// H420ToARGB
-// H422ToARGB
 // I010ToARGB
 // J400ToARGB
 // J422ToARGB
@@ -167,13 +165,15 @@
     // Biplanar formats
     case FOURCC_NV12:
       src = sample + (src_width * crop_y + crop_x);
-      src_uv = sample + aligned_src_width * (abs_src_height + crop_y / 2) + crop_x;
+      src_uv =
+          sample + aligned_src_width * (abs_src_height + crop_y / 2) + crop_x;
       r = NV12ToARGB(src, src_width, src_uv, aligned_src_width, dst_argb,
                      dst_stride_argb, crop_width, inv_crop_height);
       break;
     case FOURCC_NV21:
       src = sample + (src_width * crop_y + crop_x);
-      src_uv = sample + aligned_src_width * (abs_src_height + crop_y / 2) + crop_x;
+      src_uv =
+          sample + aligned_src_width * (abs_src_height + crop_y / 2) + crop_x;
       // Call NV12 but with u and v parameters swapped.
       r = NV21ToARGB(src, src_width, src_uv, aligned_src_width, dst_argb,
                      dst_stride_argb, crop_width, inv_crop_height);
@@ -208,16 +208,27 @@
       break;
     }
 
-    case FOURCC_J420: {
-      const uint8_t* src_y = sample + (src_width * crop_y + crop_x);
-      const uint8_t* src_u;
-      const uint8_t* src_v;
+    case FOURCC_H420: {
       int halfwidth = (src_width + 1) / 2;
       int halfheight = (abs_src_height + 1) / 2;
-      src_u = sample + src_width * abs_src_height +
-              (halfwidth * crop_y + crop_x) / 2;
-      src_v = sample + src_width * abs_src_height +
-              halfwidth * (halfheight + crop_y / 2) + crop_x / 2;
+      const uint8_t* src_y = sample + (src_width * crop_y + crop_x);
+      const uint8_t* src_u = sample + src_width * abs_src_height +
+                             (halfwidth * crop_y + crop_x) / 2;
+      const uint8_t* src_v = sample + src_width * abs_src_height +
+                             halfwidth * (halfheight + crop_y / 2) + crop_x / 2;
+      r = H420ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth,
+                     dst_argb, dst_stride_argb, crop_width, inv_crop_height);
+      break;
+    }
+
+    case FOURCC_J420: {
+      int halfwidth = (src_width + 1) / 2;
+      int halfheight = (abs_src_height + 1) / 2;
+      const uint8_t* src_y = sample + (src_width * crop_y + crop_x);
+      const uint8_t* src_u = sample + src_width * abs_src_height +
+                             (halfwidth * crop_y + crop_x) / 2;
+      const uint8_t* src_v = sample + src_width * abs_src_height +
+                             halfwidth * (halfheight + crop_y / 2) + crop_x / 2;
       r = J420ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth,
                      dst_argb, dst_stride_argb, crop_width, inv_crop_height);
       break;
@@ -225,10 +236,10 @@
 
     case FOURCC_I422:
     case FOURCC_YV16: {
+      int halfwidth = (src_width + 1) / 2;
       const uint8_t* src_y = sample + src_width * crop_y + crop_x;
       const uint8_t* src_u;
       const uint8_t* src_v;
-      int halfwidth = (src_width + 1) / 2;
       if (format == FOURCC_YV16) {
         src_v = sample + src_width * abs_src_height + halfwidth * crop_y +
                 crop_x / 2;
@@ -244,6 +255,19 @@
                      dst_argb, dst_stride_argb, crop_width, inv_crop_height);
       break;
     }
+
+    case FOURCC_H422: {
+      int halfwidth = (src_width + 1) / 2;
+      const uint8_t* src_y = sample + src_width * crop_y + crop_x;
+      const uint8_t* src_u =
+          sample + src_width * abs_src_height + halfwidth * crop_y + crop_x / 2;
+      const uint8_t* src_v = sample + src_width * abs_src_height +
+                             halfwidth * (abs_src_height + crop_y) + crop_x / 2;
+      r = H422ToARGB(src_y, src_width, src_u, halfwidth, src_v, halfwidth,
+                     dst_argb, dst_stride_argb, crop_width, inv_crop_height);
+      break;
+    }
+
     case FOURCC_I444:
     case FOURCC_YV24: {
       const uint8_t* src_y = sample + src_width * crop_y + crop_x;
diff --git a/unit_test/video_common_test.cc b/unit_test/video_common_test.cc
index 4d89586..a84206a 100644
--- a/unit_test/video_common_test.cc
+++ b/unit_test/video_common_test.cc
@@ -79,6 +79,7 @@
   EXPECT_TRUE(TestValidFourCC(FOURCC_RGBO, FOURCC_BPP_RGBO));
   EXPECT_TRUE(TestValidFourCC(FOURCC_R444, FOURCC_BPP_R444));
   EXPECT_TRUE(TestValidFourCC(FOURCC_H420, FOURCC_BPP_H420));
+  EXPECT_TRUE(TestValidFourCC(FOURCC_H422, FOURCC_BPP_H422));
   EXPECT_TRUE(TestValidFourCC(FOURCC_H010, FOURCC_BPP_H010));
   EXPECT_TRUE(TestValidFourCC(FOURCC_MJPG, FOURCC_BPP_MJPG));
   EXPECT_TRUE(TestValidFourCC(FOURCC_YV12, FOURCC_BPP_YV12));