2013-05-06 31 views
7

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); 
    } 

. 
. 

} 
+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

+0

Đố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. –

Trả lời

0

Tôi chưa bao giờ thử điều gì đó như vậy trước đây (opengl + video enconding) nhưng tôi có thể cho bạn biết rằng việc đọc từ bộ nhớ thiết bị là SLOW. Hãy thử đệm đôi, điều này có thể giúp vì GPU có thể tiếp tục hiển thị bộ đệm thứ hai trong khi bộ điều khiển DMA đọc lại nội dung.

Tải hồ sơ (kiểm tra nhà cung cấp GPU của thiết bị của bạn), điều này có thể cung cấp cho bạn một số ý tưởng. Một thứ khác có thể giúp là đặt định dạng pbuffer nội bộ thành một cái gì đó khác, hãy thử các số thấp hơn và thả một kênh (alpha).

EDIT: Nếu bạn cảm thấy như vậy, bạn có thể mã hóa video tại GPU, điều đó sẽ tăng cường, bộ nhớ và xử lý thông minh, ứng dụng của bạn.

+0

TraxNet, cảm ơn bạn đã trả lời. Tôi sẽ thử mất kênh alpha. Tôi chắc chắn nó sẽ giúp nhưng nó sẽ không tạo ra sự khác biệt đủ lớn. Mã hóa ở GPU sẽ là nhà cung cấp cụ thể, phải không? Tôi cần phải chạy trên các thiết bị khác nhau. –

+0

Có thể anh ấy sử dụng RenderScript cho các hiệu ứng bên GPU. Đó sẽ là nhà cung cấp độc lập. – akauppi

1

Vì tôi nhớ glBufferData() không ánh xạ bộ đệm trong của bạn lên bộ nhớ GPU, nó chỉ sao chép dữ liệu từ bộ nhớ của bạn vào bộ đệm (khởi tạo).

Để truy cập vào bộ nhớ được phân bổ theo glBufferData(), bạn nên sử dụng glMapBufferRange(). Hàm đó trả về một đối tượng Bộ đệm Java mà bạn có thể đọc.

Các vấn đề liên quan