title: RGB to YUV420 Planar and Semi-Planar?
body: <p>In Android, I have a <code>byte[]</code> of individual r,g,b,a colors that make up the pixels of an image.</p>
  
  <p>I need to convert these colors to <strong>YUV420 planar or semi-planar</strong> (depending on the device) before I can use Android's MediaCodec and MediaMuxer to create an MP4 of these images.</p>
  
  <p>I'm currently testing on my Nexus 10 which reports that it uses <code>COLOR_FormatYUV420Planar</code>.</p>
  
  <p>Here's the code I have to convert RGB to YUV420 <strong>planar</strong>:</p>
  
  <pre><code>private void convertRGBAtoYUV420P(byte[] rgba, byte[] yuv, int width, int height)
  {
      final int frameSize = width * height;
      final int chromasize = frameSize / 4;
  
      int yIndex = 0;
      int uIndex = frameSize;
      int vIndex = frameSize + chromasize;
  
      int R, G, B, Y, U, V;
      int index = 0;
  
      int rgbaIndex = 0;
  
      for (int j = 0; j &lt; height; j++)
      {
          for (int i = 0; i &lt; width; i++)
          {
              R = rgba[rgbaIndex++] + 128; // My rgba bytes are -128 to 127
              G = rgba[rgbaIndex++] + 128;
              B = rgba[rgbaIndex++] + 128;
              rgbaIndex++; // skip A
  
              Y = ((66 * R + 129 * G + 25 * B + 128) &gt;&gt; 8) + 16;
              U = ((-38 * R - 74 * G + 112 * B + 128) &gt;&gt; 8) + 128;
              V = ((112 * R - 94 * G - 18 * B + 128) &gt;&gt; 8) + 128;
  
              yuv[yIndex++] = (byte)clamp(Y);
  
              if (j % 2 == 0 &amp;&amp; index % 2 == 0)
              {
                  yuv[uIndex++] = (byte)clamp(U);
                  yuv[vIndex++] = (byte)clamp(V);
              }
  
              index++;
          }
      }
  }
  </code></pre>
  
  <p>I found this code from <a href="http://embedav.blogspot.com/2013/06/convert-rgb-to-yuv420-planar-format-in.html" rel="nofollow">this blog</a>.</p>
  
  <p>It works, just the color isn't correct. White is gray and all other colors are just wrong. Can't quite figure out what is wrong in the code above, but I feel like it might have to do with the fact that my r,g,b,a bytes are in a range from -128 to 127, but I try to correct that by adding 128 to them.</p>
  
  <hr>
  
  <p>Second question, how would the above code change when I need to convert from RGB to YUV420 <strong>semi-planar</strong> instead?</p>