在Android上,我試圖對相機框架執行一些OpenGL處理,在相機預覽中顯示這些框架,然後在視頻文件中對框架進行編碼。我試圖用OpenGL來做到這一點,使用GLSurfaceView和GLSurfaceView.Renderer和FFMPEG進行視頻編碼。在Android上使用像素緩衝對象(PBO)
我已經使用着色器成功處理了圖像幀。現在我需要將處理後的幀編碼爲視頻。 GLSurfaceView.Renderer提供了onDrawFrame(GL10 ..)方法。正是在這種方法中,我試圖僅使用glReadPixels()讀取圖像幀,然後將這些幀放在隊列中以編碼爲視頻。就它自己而言,glReadPixels()太慢了 - 我的幀速率是單個數字。我正在嘗試使用像素緩衝區對象加快速度。這不起作用。插入pbo後,幀速率不變。這是我第一次使用OpenGL,我不知道從哪裏開始尋找問題。我做對了嗎?任何人都可以給我一些方向嗎?提前致謝。
public class MainRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
.
.
public void onDrawFrame (GL10 gl10) {
//Create a buffer to hold the image frame
ByteBuffer byte_buffer = ByteBuffer.allocateDirect(this.width * this.height * 4);
byte_buffer.order(ByteOrder.nativeOrder());
//Generate a pointer to the frame buffers
IntBuffer image_buffers = IntBuffer.allocate(1);
GLES20.glGenBuffers(1, image_buffers);
//Create the buffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, image_buffers.get(0));
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, byte_buffer.limit(), byte_buffer, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, image_buffers.get(0));
//Read the pixel data into the buffer
gl10.glReadPixels(0, 0, this.width, this.height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, byte_buffer);
//encode the frame to video
enQueueForEncoding(byte_buffer);
//unbind the buffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
.
.
}
您是否檢查過Google Grafika示例?如果這些OpenGL實現非常接近您在Android上可以達到的最佳效果,不會感到驚訝;即https://github.com/google/grafika/blob/master/src/com/android/grafika/RecordFBOActivity.java – harism 2014-07-09 10:32:19
對於你的glReadPixels調用,嘗試使用glReadPixels(0,0,寬度,高度,格式,GL_UNSIGNED_BYTE, 0);在最後傳遞零,但是你需要通過JNI來完成,因爲java不允許爲空。然後像往常一樣使用地圖緩衝區。 – 2015-02-20 16:06:49