当前位置: 首页 > 知识库问答 >
问题:

在Android上使用像素缓冲区对象(PBO)

隆扬
2023-03-14

在Android上,我试图对相机帧执行一些OpenGL处理,在相机预览中显示这些帧,然后将这些帧编码为视频文件。我试图用OpenGL做这件事,使用GLSurfaceView和GLSurfaceView。渲染器和FFMPEG用于视频编码。

我已经使用着色器成功地处理了图像帧。现在我需要将处理后的帧编码为视频。这是一个表面视图。渲染器提供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);
    }

.
.

}

共有2个答案

程赞
2023-03-14

因为我记得glBufferData()不是映射到GPU内存的内部缓冲区,它只是从内存复制数据到缓冲区(初始化)。

要访问由glBufferData()分配的内存,应该使用glMapBufferRange()。该函数返回一个可以读取的JavaBuffer对象。

何华灿
2023-03-14

我以前从未尝试过类似的东西(opengl视频重唱),但我可以告诉你,从设备内存读取是很慢的。尝试双缓冲,这可能会有所帮助,因为当DMA控制器读回内容时,GPU可以继续渲染到第二个缓冲区。

加载分析器(检查您的设备的GPU供应商),这可能会给您一些想法。另一件可能有帮助的事情是将内部p缓冲区格式设置为其他格式,尝试较低的数字并删除通道(alpha)。

编辑:如果你喜欢,你可以在GPU上对视频进行编码,这将提高你的应用程序的内存和处理能力。

 类似资料:
  • 我有一个JSON对象,我正在将它转换成一个,并在这里进行一些处理。稍后,我想将相同的缓冲区数据转换为有效的JSON对象。 我的工作节点V6.9.1 下面是我尝试过的代码,但当我转换回JSON并且无法打开此对象时,我得到了。 所以我试着用检查的方式打印整个物体 如果我试着像数组一样读取它 我试图解析它也抛出SynTaxError:意外令牌o在JSON在位置2 我需要像我创建的那样将其视为真实对象(我

  • 我目前正在使用LWJGL / OpenGL创建一个2D,自上而下的游戏,但是在绘制实体之后,在使用顶点缓冲区对象渲染实体后,在让它们四处移动的过程中,我遇到了一些问题。这是渲染线程的 run() 方法,以及设置方法: 实体从抽象超类继承这些方法来设置 VBO 并绘制实体(呈现线程中的 drawEntities 方法仅调用该方法,实体更新方法(见下文),而 setUpEntities 调用 setU

  • 问题内容: 我正在通过套接字在字节数组中接收到位图,并且读取了该位图,然后将其设置为应用程序中的位图。我使用的代码是: 当我运行我的应用程序并开始接收并期望更改时,事实并非如此。 LogCat 说: 我搜索了类似的问题,但是找不到解决我问题的方法。 问题答案: 看看Bitmap :: copyPixelsFromBuffer() 的源(版本2.3.4_r1,上一次在Grepcode上更新Bitma

  • 我正在努力理解这两个,如何使用它们,以及它们是如何联系的。假设我想创建一个简单的地形和一个有纹理的立方体。对于这两个对象,我有三角形、顶点的数组,对于立方体,我有一个包含纹理数据的数组。我的问题是:我如何使用VAOs和VBOs来创建和呈现这两个? null

  • 当你使用画布时,你可以检索读取画布上的像素数据,或者操作画布上的像素。读取图像数据使用createImageData(sw,sh)或者getImageData(sx,sy,sw,sh)。这两个函数都会返回一个包含宽度(width),高度(height)和数据(data)的图像数据(ImageData)对象。图像数据包含了一维数组像素数据,使用RGBA格式进行检索。每个数据的数据范围在0到255之间

  • 我正在尝试从ArrayList读取并创建VBO,然后对其进行渲染。问题是我只是渲染了一个空白屏幕。当我立即渲染时,一切都很好;只有现在VBO的才不起作用。 游戏循环如下所示,相机调用glTranslate和glRotate函数。 渲染方法: 阵列列表具有顶点和链接的颜色。每个体素将其顶点添加到ArrayList(而不是立即渲染)。