在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