1

AndroidでOpenGLES2.0を使用してビデオを処理しています。画像データはYUV420Pとしてプルされており、OpenGLフラグメントシェーダーでRGBAで処理する必要があります。

YUV420PデータをRGBAに変換するにはどうすればよいですか?(ビデオを考えると、パフォーマンスが重要です)

更新:Brad Larssonの回答に感謝しますが、正しく見えません。

UPDATE2:ええと、私はまだRGBAフラグメントシェーダーを使用していました。もちろん、それは間違って見えました。今、私は別の問題を抱えています。さらに掘り下げてみましょう。

UPDATE3:OK、ここで何かがうまくいかない。

ここに画像の説明を入力してください

これをテクスチャに使用しています。これは正しいです?

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, luminanceBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width / 2, height / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, chrominanceBuffer);

UPDATE4:GL_LUMINANCE_ALPHAソートされたインターレースの問題を使用していますが、画像はまだ破損しています...問題がバイトバッファにあることを知ったので、これを回答済みとしてマークします。

4

1 に答える 1

2

Appleには、OpenGLES2.0シェーダーでYUV420平面データからRGBAに変換するiOSの例がいくつかあります。特にAndroid向けではありませんが、このGLSLシェーダーコードを使用して目的を達成できるはずです。

これは、例に基づいて変換フラグメントシェーダーで使用するものです。

 varying highp vec2 textureCoordinate;

 uniform sampler2D luminanceTexture;
 uniform sampler2D chrominanceTexture;

 void main()
 {
     mediump vec3 yuv;
     lowp vec3 rgb;

     yuv.x = texture2D(luminanceTexture, textureCoordinate).r;
     yuv.yz = texture2D(chrominanceTexture, textureCoordinate).rg - vec2(0.5, 0.5);

     // BT.601, which is the standard for SDTV is provided as a reference
     /*
      rgb = mat3(      1,       1,       1,
      0, -.39465, 2.03211,
      1.13983, -.58060,       0) * yuv;
      */

     // Using BT.709 which is the standard for HDTV
     rgb = mat3(      1,       1,       1,
                0, -.21482, 2.12798,
                1.28033, -.38059,       0) * yuv;

     gl_FragColor = vec4(rgb, 1);
 }

luminanceTextureはテクスチャとしての画像のY平面であり、chrominanceTextureはUV平面です。

上記はビデオレンジYUV用に調整されていると思いますので、フルレンジYUV用にこれらの値を調整する必要があるかもしれません。このシェーダーは、iPhone4Sの1080pビデオフレームに対して数分の1ミリ秒で実行されます。

于 2013-01-12T22:01:36.247 に答える