YV12 ke RGB - Apa yang salah dengan algoritma saya?

8

Saya mencoba mengubah YV12 ke RGB menggunakan fragmen shader berikut:

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);
}

Di bawah ini adalah gambar asli diikuti oleh gambar yang dikonversi. Berdasarkan output, dapatkah Anda menentukan di mana saya mungkin melihat untuk menentukan apa yang menyebabkan decoding yang tidak tepat?

Sumber Gambar yang diterjemahkan

Kesalahan 454
sumber
Seperti yang dikatakan oleh responden pertama, pasti ada masalah dengan jumlah byte per baris. Saya ingin tahu hal lain. YV12 memiliki subsampled saluran U dan V. Bagaimana Anda mengelola perubahan dimensi ini dengan shader Anda? Berapa ukuran tekstur Anda? Apakah Anda membiarkan OpenGL menangani ini?
Stéphane Péchard
Dalam loop pengundian, data gambar diberikan kepada saya dalam array 3 elemen di mana urutannya selalu YUV (terlepas dari YV12 atau YUV420p dll). Saya menggunakan lebar / tinggi penuh untuk elemen Y dan menggeser lebar / tinggi ke kanan 1 (bagi 2) untuk elemen UV. Tekstur ini kemudian diikat ke shader yang menangani sisanya. Ukuran tekstur yang telah saya kerjakan biasanya 1280x720.
Kesalahan 454

Jawaban:

5

Gambar output memiliki garis yang bergeser satu terhadap yang lain, yang biasanya disebabkan oleh jarak [byte] yang salah di antara garis (langkah). Artinya, matematika konversi warna mungkin benar, namun Anda mengambil piksel sumber dari posisi yang salah dan / atau menempatkan piksel keluaran ke tempat yang salah.

Untuk alasan kinerja, gambar YV12 mungkin menggunakan langkah panjang dalam perangkat keras untuk memfasilitasi kinerja. Misalnya, gambar 320x240 YV12 mungkin memiliki langkah 512 dan ini berarti bahwa buffer data adalah ruang data 512x240 (512x240 byte untuk Y, diikuti oleh dua array 256x120 untuk V dan U) di mana gambar muatan di sebelah kiri, dan di sana adalah padding tak terlihat di sebelah kanan.

Roman R.
sumber
Saya melihat bahwa saya tidak memperhitungkan langkahnya. Saya akan menerapkan ini ketika saya bisa dan memperbarui pertanyaan setelah saya dapat memverifikasi apakah ini memang masalahnya.
Kesalahan 454
Pada akhirnya, langkahnya adalah jawabannya. Itu satu-satunya hal yang saya ubah dan sekarang semuanya berfungsi. Mata yang bagus!
Kesalahan 454
1

Saya tidak tahu apa-apa tentang pemrograman fragmen shader, tetapi bagi saya sepertinya ukuran kata dari input dan output bervariasi. Dan bagi saya sepertinya, Anda tidak memperhatikan membongkar dan mengemas ulang byte YV12 .

bjoernz
sumber