title: Android MediaCodec output format: GLES External Texture (YUV / NV12) to GLES Texture (RGB)
body: <p>I am currently trying to develop a video player on Android, but am struggling with color formats.</p>
  
  <p><strong>Context:</strong> I extract and decode a video through the standard combinaison of <em>MediaExtractor/MediaCodec</em>. Because <strong>I need the extracted frames to be available as OpenGLES textures (RGB)</strong>, I setup my decoder (<em>MediaCodec</em>) so that it feeds an external GLES texture (<em>GL_TEXTURE_EXTERNAL_OES</em>) through a SurfaceTexture. I know the data output by my HW decoder is in the <em>NV12</em> (<em>YUV420SemiPlanar</em>) format, and I need to convert it to RGB by rendering it (with a fragment shader doing the conversion).</p>
  
  <blockquote>
    <p>MediaCodec ---> GLES External Texture (NV12) <strong>[1]</strong> ---> Rendering ---> GLES Texture (RGB)</p>
  </blockquote>
  
  <p><strong>The point where I struggle is</strong>: How do I access the specific Y, U, and V values contained in the GLES External Texture (<strong>[1]</strong>). I have no idea how the GLES texture memory is set, nor how to access it (except for the "texture()" and "texelFetch()" GLSL functions).</p>
  
  <ul>
  <li>Is there a way to access the data as I would access a simple array (pointer + offset)?</li>
  <li>Did I overthink the whole thing?</li>
  <li>Do either <em>Surface</em> or <em>SurfaceTexture</em> take care of conversions? (I don't think so)</li>
  <li>Do either <em>Surface</em> or <em>SurfaceTexture</em> change the memory layout of the data while populating the GLES External Texture (<strong>[1]</strong>) so components can be accessed through GLES texture access functions?</li>
  </ul>