Trên Android, tôi đang cố gắng thực hiện một số xử lý OpenGL trên khung máy ảnh, hiển thị các khung đó trong xem trước máy ảnh và sau đó mã hóa khung trong tệp video. Tôi đang cố gắng làm điều này với OpenGL, sử dụng GLSurfaceView và GLSurfaceView.Renderer và với FFMPEG để mã hóa video.Sử dụng đối tượng đệm pixel (PBO) trên Android
Tôi đã xử lý thành công khung hình bằng cách sử dụng trình đổ bóng. Bây giờ tôi cần mã hóa các khung được xử lý thành video. GLSurfaceView.Renderer cung cấp phương thức onDrawFrame (GL10 ..). Đó là trong phương pháp này mà tôi đang cố gắng để đọc các khung hình ảnh bằng cách sử dụng chỉ glReadPixels() và sau đó đặt các khung hình trên một hàng đợi để mã hóa video. Trên riêng của nó, glReadPixels() là quá chậm - tốc độ khung hình của tôi là trong các chữ số duy nhất. Tôi đang cố gắng tăng tốc độ này bằng cách sử dụng Đối tượng bộ đệm pixel. Đây không phải là làm việc. Sau khi cắm pbo, tốc độ khung hình không thay đổi. Đây là lần đầu tiên tôi sử dụng OpenGL và tôi không biết bắt đầu tìm kiếm vấn đề ở đâu. Tôi làm đúng chứ hả? Bất cứ ai có thể cho tôi một số hướng? Cảm ơn trước.
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);
}
.
.
}
Bạn đã kiểm tra ví dụ về Google Grafika chưa? Sẽ không quá ngạc nhiên nếu những triển khai OpenGL này khá gần với tối ưu mà bạn có thể tiếp cận trên Android; tức là https://github.com/google/grafika/blob/master/src/com/android/grafika/RecordFBOActivity.java – harism
Đối với cuộc gọi glReadPixels của bạn, hãy thử sử dụng glReadPixels (0, 0, chiều rộng, chiều cao, định dạng, GL_UNSIGNED_BYTE, 0); với số không được truyền vào cuối, nhưng bạn sẽ cần phải thực hiện điều này thông qua JNI, vì java không cho phép null. Sau đó, bạn sử dụng bộ đệm bản đồ như bình thường. –