2015-08-23 28 views
2

我有2 OES_EGL_image_external紋理,我組合(從兩者採樣)並渲染到由MediaCodec給出的輸入Surface,然後編碼並保存到mp4文件。Android OpenGL將渲染結果作爲Java字節數組獲得

我想要做的是將組合幀作爲Java Byte數組獲取。 我讀到將其渲染爲紋理,使用glReadPixels()非常慢,我必須跟上大約30-40 FPS。

Android中最有效的方法是什麼?

+0

'glReadPixels(...)'沒有那麼慢,如果你正確使用它,因爲它晚了。當您可以容忍等待2-3幀以使結果在像素緩衝區對象中可用時,保持特定的幀速率會更容易。順便提一下,你使用的是哪個版本的OpenGL ES(順便說一下,你的問題被標記爲錯誤)?在3.0+像素緩衝區對象中是核心的,否則只有當['GL_NV_pixel_buffer_object'](https://www.khronos.org/registry/gles/extensions/NV/NV_pixel_buffer_object.txt)可用時才能做到這一點。 –

+0

Opengl es 2.我不熟悉像素緩衝區對象。你介意提供一個例子還是更詳細一些?感謝您的幫助 –

+0

爲什麼downvote?這是一個合法的問題!主題也不平凡! –

回答

1

沒有真正的「快」路徑,但「慢」路徑並不是那麼慢。

獲得「外部」紋理內容的唯一方法是將其渲染到某處(例如pbuffer),然後讀取像素。這是因爲外部紋理可能處於「外來」色彩格式(通常是YUV的某種風格),所以支持的操作集是有限的。這聽起來像你想要合併兩幀的GLES操作的輸出,所以這不是問題。

您不太可能在Android上的GLES 2中有PBOs,即使您確實需要使用NDK,因爲我不認爲存在Java語言綁定。 (說起'K',可能'L',不知道'M'中會出現什麼。)

就像讀出像素一樣,我的ExtractMpegFramesTest實驗發現它花費了大約8ms到glReadPixels()拉出一個720p的框架,這對於你的目的來說足夠快。不同設備之間的速度差異很大,並且可能會發布到不同的顏色格式 - 例如,我運行指定的RGB而不是RGBA的一些代碼,並且發送的速度很慢。在Grafika有一個基本的基準,可以用來獲得一般意義。

glReadPixels()的輸出轉到「直接」ByteBuffer,但不能保證被byte[]支持。在最近的Android版本中(因爲可能是Jellybean?),它保證分配的緩衝區爲allocDirect(),但可能不適用於使用JNI功能創建的緩衝區。所以要小心你選擇的分配方法。

所有這些......一旦你的數據在byte[]中,你可以用Java來完成所有的工作,除非你的圖像非常小,否則它將保留你想要的幀頻。要找到一種解決GPU問題的方法會更好。