2012-06-22 12 views
9

Yerel iş parçacığımda, FFMpeg çerçeveleri alma ve çözme işlemlerini daha sonra bir sıraya yerleştiriyorum.AndroidBitmap_xxx işlevlerini kullanmaktan daha hızlı bir video işleme çözümü var mı?

Java tarafında bir GLSurfaceView var ve Renderer.onDrawFrame'dan bir bitmap ileten yerel koda arıyorum (yalnızca bir kez oluşturduğum bu bitmap, sonra her seferinde ilet).

Yerel kodda kuyruğun başını alıyorum, AndroidBitmap_xxx işlevlerini kullanarak veriyi java bitmap'e kopyalayın ve ardından bu Bitmap'i bir doku olarak Java tarafında oluşturun.

Video çekmenin daha hızlı bir yolu var mı? Tamamen yerel kodda yapalım mı, evet ise, neden daha hızlı olacak?

Düzenleme: Şimdi RGB çerçeve piksellerini kilitli bitmap piksellerine kopyalamıyorum, YUV çerçevesini doğrudan kilitli bitmap piksellerine çözüyorum. Bu, görüntülemeyi önemli ölçüde daha hızlı hale getirir (artık gereksiz bir memcpy olmadığı için) hala soru kalır.

+0

FFMpegs çerçeve çıktısını doku verileri olarak doğrudan kullanmak ve ara Bitmap adımı olmadan yüklemek için bir yol var mı? –

+0

Android'de FFMpeg'i nasıl kullanabilirim? bana herhangi bir referans verebilir misin ?? Aslında, bitmap çerçevelerini kullanarak bir video oluşturmak istedim. –

cevap

2

Dokudaki pikselleri değiştirmek için en etkili teknik, Dokuya Render olarak adlandırılır ve FBOs aracılığıyla OpenGL/OpenGL ES'de yapılabilir. Masaüstü OpenGL'de, piksel verilerini doğrudan GPU üzerinde işlemek için piksel tamponu nesnelerini (PBOs) kullanabilirsiniz (ancak OpenGL ES bunu henüz desteklememektedir).

Genişletilmemiş OpenGL'de, sistem belleğindeki pikselleri değiştirebilir ve glTexImage2D/glTexSubImage2D ile dokuları güncelleyebilirsiniz - ancak bu, son çare çözümü için verimsizdir ve mümkünse kaçınılmalıdır. GltexImage2D, yalnızca dokudaki pikselleri güncellediğinden, çok daha hızlıdır, glTexImage2D ise tamamen yeni bir doku yaratır (avantaj olarak, doku boyutunu ve piksel biçimini değiştirebilirsiniz). Diğer tarafta, glTexSubImage2D sadece doku bölümlerini güncellemeye izin verir.

Sen bunu OpenGL ES ile çalışmak istediğini söylemekte, bu yüzden aşağıdaki adımları yapmak önereceğini:

  • glTexSubImage2D() ile glTexImage2D() değiştirin - Eğer bu kadar yeterli performansı elde eğer, sadece bırak olsun;
  • FBO'lar ve gölgelendiriciler ile dokuları oluşturmayı uygulayın - kodunuzu yeniden yazmak için çok daha fazla çalışma gerektirir, ancak daha iyi performansı verir.

FBOs için kod şöyle olabilir:

// setup FBO 
glGenFramebuffers(1, &FFrameBuffer); 
glBindFramebuffer(GL_FRAMEBUFFER, FFrameBuffer); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, YourTextureID, 0); 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

// render to FBO 
glBindFramebuffer(GL_FRAMEBUFFER, FFrameBuffer); 
glViewport(0, 0, YourTextureWidth, YourTextureHeight); 
your rendering code goes here - it will draw directly into the texture 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 

// cleanup 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glDeleteFramebuffers(1, &FFrameBuffer); 

tüm piksel formatları için kılınabilir değil unutmayın. RGB/RGBA genellikle iyidir.

İlgili konular