YV12からRGB-アルゴリズムの何が問題になっていますか?


8

次のフラグメントシェーダーを使用してYV12をRGBに変換しようとしています。

precision mediump float;
uniform sampler2D tex0, tex1, tex2;
varying vec2 v_texCoord;

void main(void) {
    float r, g, b, y, u, v;
    y = texture2D(tex0, v_texCoord).x;
    u = texture2D(tex1, v_texCoord).x;
    v = texture2D(tex2, v_texCoord).x;

    y = 1.1643 * (y - 0.0625);
    u = u - 0.5;
    v = v - 0.5;

    r = y + 1.5958 * v;
    g = y - 0.39173 * u - 0.81290 * v;
    b = y + 2.017 * u;

    gl_FragColor = vec4(r, g, b, 1.0);
}

以下は、元の画像とそれに続く変換された画像です。出力に基づいて、不適切なデコードの原因を特定するためにどこを見ればよいかを判断できますか?

ソース デコードされた画像


ファーストレスポンダーが言ったように、1行あたりのバイト数には間違いなく問題があります。別のことかな。YV12にはサブサンプリングされたUおよびVチャネルがあります。シェーダーでこの寸法変更をどのように管理しますか?テクスチャのサイズはどのくらいですか?OpenGLにこれを処理させますか?
ステファンPéchard

描画ループでは、画像データは3要素配列で与えられ、順序は常にYUVです(YV12やYUV420pなどに関係ありません)。Y要素には幅/高さ全体を使用し、UV要素には幅/高さを右に1(2で除算)シフトします。これらのテクスチャは、残りを処理するシェーダーにバインドされます。私が扱ってきたテクスチャサイズは通常1280x720です。
エラー454

回答:


5

出力画像のラインが互いにずれています。これは通常、ライン間の不適切な[バイト]距離(ストライド)が原因です。つまり、色変換の計算はおそらく正しいのですが、ソースピクセルを間違った位置から取得したり、出力ピクセルを間違った場所に配置したりしています。

パフォーマンス上の理由により、YV12イメージはハードウェアで拡張ストライドを使用してパフォーマンスを促進している場合があります。たとえば、320x240 YV12イメージのストライドは512である可能性があり、これは、データバッファーが512x240データスペース(Yの場合は512x240バイト、その後にVおよびUの場合は2つの256x120アレイ)であることを意味します。右側の見えないパディングです。


私はストライドを考慮していないようです。私ができるときにこれを実装し、問題が本当に問題かどうかを確認できたら質問を更新します。
エラー454

結局、ストライドが答えでした。それが私が変更した唯一のものであり、今ではすべてが機能します。素晴らしい目!
エラー454

1

フラグメントシェーダープログラミングについては何も知りませんが、入力と出力のワードサイズが異なるように見えます。そして、私には、YV12バイトのアンパックと再パックに注意を払っていないように見えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.