2011-12-09 17 views
9

OpenGL ES ve ffmpeg kullanarak, Apple TV için medya oynatıcı çerçevesi yazıyorum. OpenGL ES'de görüntü vermek için RGBA'ya dönüştürme gereklidir, swscale'i kullanarak yumuşak bir dönüşüme dayanılmaz bir şekilde yavaştır, bu yüzden internette bilgi kullanarak iki fikir ortaya çıkardım: neon kullanarak (here gibi) veya parça gölgelendiriciler ve GL_LUMINANCE ve GL_LUMINANCE_ALPHA kullanarak.YUV - Apple A4'teki RGBA, gölgelendiricileri veya NEON?

Ben OpenGL hakkında neredeyse hiçbir şey bildiği gibi, ikinci seçenek hala :)

Nasıl devam etmek bana herhangi işaretçiler verebilir çalışmıyor? Önceden teşekkür ederiz.

cevap

19

Bu kesinlikle değerli öğrenme OpenGL ES2.0 shader'ların:

  1. için yük dengesi için grafik işlemcisi ve mikroişlemci (takip eden çerçevelerin örneğin, video şifre çözme grafik işlemcisi mevcut çerçeve işlerken) arasında olmalıdır.
  2. Video karelerinin her durumda GPU'ya gitmesi gerekir: YCbCr kullanarak, videonuz 4: 2: 0 örneklenmiş bir renklilik içeriyorsa% 25 veri yolu bant genişliği sağlar.
  3. GPU donanım enterpolatörü ile 4: 2: 0 chrominance up-sample örnekleme işlemini ücretsiz yapabilirsiniz. (Gölgeniz, Y ve C{b,r} dokular için aynı köşe koordinatlarını kullanacak şekilde yapılandırılmalıdır, bu da aynı alan üzerinde krominans yapısını uzatabilir.)
  4. YCbCr dokuları GPU'ya aktarma hızlıdır (veri kopyası yok) ya da swizzling) doku önbelleği ile (CVOpenGLESTextureCache* API fonksiyonlarına bakınız). NEON ile karşılaştırıldığında 1-2 veri kopyasını kaydedeceksiniz.

Bu teknikleri, in my super-fast iPhone camera app, SnappyCam etkiyi büyük ölçüde kullanıyorum.

Sen uygulanması için doğru yolda şunlardır: CbCr araya ilave takdirde Y ve GL_LUMINANCE_ALPHA için GL_LUMINANCE doku kullanın. Aksi takdirde, tüm YCbCr bileşenlerinin tümü işlenmemişse, üç GL_LUMINANCE dokuyu kullanın. 2: 4 için iki dokular oluşturma

(CbCr aralanmış olduğuna) 0 iki düzlemsel YCbCr basittir:

glBindTexture(GL_TEXTURE_2D, texture_y); 
    glTexImage2D(
     GL_TEXTURE_2D, 
     0, 
     GL_LUMINANCE,  // Texture format (8bit) 
     width, 
     height, 
     0,     // No border 
     GL_LUMINANCE,  // Source format (8bit) 
     GL_UNSIGNED_BYTE, // Source data format 
     NULL 
    ); 
    glBindTexture(GL_TEXTURE_2D, texture_cbcr); 
    glTexImage2D(
     GL_TEXTURE_2D, 
     0, 
     GL_LUMINANCE_ALPHA, // Texture format (16-bit) 
     width/2, 
     height/2, 
     0,     // No border 
     GL_LUMINANCE_ALPHA, // Source format (16-bits) 
     GL_UNSIGNED_BYTE, // Source data format 
     NULL 
    ); 

nereye Sonra bu dokuları güncellemek için glTexSubImage2D() veya iOS5 doku önbelleği kullanmak.

Ayrıca, doku koordinat alanını (x: [0,1], y: [0,1]) yayan bir 2B varying kullanmanız önerilir, böylece parça gölgelendiricinizde herhangi bir bağımlı doku okumasını engellersiniz. Son sonuç süper hızlı ve GPU'yu deneyimime dayanmıyor.

+0

Çok teşekkür ederim, aslında anlattığınız gibi her şeyi yapıyordum, ancak iOS 5'deki yeni özellikleri bilmiyordum. Bunu deneyeceğim. – pawlowski

+0

Cevabınız için teşekkürler. IOS'ta yerel kod çözme piksel formatı hakkında daha fazla bilgiyi nerede bulabilirim (pt # 2'nize yanıt olarak)? – fionbio

0

YON'u NEON kullanarak RGB'ye dönüştürmek çok yavaş. GPU'ya yüklemek için bir gölgelendirici kullanın.