我正在编写一个Android应用程序,我需要缓存视频帧,以便我可以轻松地来回转移,几乎没有延迟.
现在我让android解码视频帧,方法是在MediaCodec对象的Configure调用中提供一个Surface 并调用releaseOutputBufferrender flag设置为true.
的唯一方法,我发现访问解码表面数据(除了解码所返回的字节缓冲区,其格式似乎是依赖于设备的)是调用updateTeximage在SurfaceTexture链接到表面,附接这对GL_TEXTURE_EXTERNAL_OES目标和它渲染到GL_TEXTURE2D目标纹理我创建我自己为了缓存它.
我想优化这个缓存过程,并能够解码不同线程上的帧.使用我当前的方法,这意味着我将不得不为视频解码器创建另一个EGL上下文,共享上下文等...
我的问题是:是否可以在不调用的情况下访问与Surface关联的EGL图像或本机缓冲区数据 updateTexImage?
这样我就可以缓存egl图像(根据不需要EGL上下文EGL_ANDROID_image_native_buffer).这也将以YUV格式缓存,这比我现在缓存的原始RGB纹理更具存储效率.
我正在阅读android源代码,因为我没有得到 OPEN GL ES库做什么以及做 EGL library什么.
这两个图书馆之间有什么关系吗?
我查看了http://www.khronos.org/opengles/documentation/opengles1_0/html/ 但仍未获得.
我正在问这个问题,如何在Android中改进opengl es显示性能.我试图使用ndk-r9d构建使用GraphicBuffer的代码.但是说这个范围没有声明GraphicBuffer.对于eglCreateImageKHR和glEGLImageTargetTexture2DOES的相同注释.
我添加了EGL/eglext.h和GLES2/gl2ext.h.我试图包含ui/GraphicBuffer.h,但它没有接受它.是否有另一个头文件要添加?
下面给出的代码我添加了以避免使用glTexSubImage2D().
GraphicBuffer * pGraphicBuffer = new GraphicBuffer(frame_width, frame_height, PIXEL_FORMAT_RGB_565, GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE);
// Lock the buffer to get a pointer
unsigned char * pBitmap = NULL;
pGraphicBuffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,(void **)&pBitmap);
// Write 2D image to pBitmap
memcpy(pBitmap, frame_buffer, frame_width * frame_height * 3);
// Unlock to allow OpenGL ES to use it
pGraphicBuffer->unlock();
EGLClientBuffer ClientBufferAddress = pGraphicBuffer->getNativeBuffer();
EGLint SurfaceType = EGL_NATIVE_BUFFER_ANDROID;
// Make an EGL Image at the same address of the native client buffer
EGLDisplay eglDisplayHandle …Run Code Online (Sandbox Code Playgroud) 我eglCreateWindowSurface GL Error EGL_BAD_ALLOC在三星Galaxy S6中安装后第一次打开应用程序,并在其他设备中正常工作.
我试图清理内存并破坏纹理并在销毁时取消初始化所有opengl对象,但这无法帮助我.
03-30 09:21:32.983 21942-26083/com.example E/TextureSurfaceRenderer: createContext: EGL10.EGL_YES_CONTEXT com.google.android.gles_jni.GLImpl@24406d0
03-30 09:21:32.983 21942-26083/com.example E/libEGL: eglCreateWindowSurface: native_window_api_connect (win=0x7f7b100e10) failed (0xffffffea) (already connected to another API?)
03-30 09:21:32.983 21942-26083/com.example E/libEGL: eglCreateWindowSurface:485 error 3003 (EGL_BAD_ALLOC)
03-30 09:21:32.993 21942-26083/com.example E/GL Error:: EGL_BAD_ALLOC
Run Code Online (Sandbox Code Playgroud)
这是我的代码.
import android.graphics.SurfaceTexture;
import android.opengl.GLUtils;
import android.os.Handler;
import android.util.Log;
import javax.microedition.khronos.egl.*;
/**
* Renderer which initializes OpenGL 2.0 context on a passed surface and starts
* a rendering thread
*
* This class has to be subclassed …Run Code Online (Sandbox Code Playgroud) 我正在尝试了解Android中的图形内存使用/流,特别是关于使用编码来自相机的帧的方面MediaCodec。为了做到这一点,我必须了解许多我不清楚的图形,OpenGL和Android术语/概念。我已经阅读了Android图形体系结构材料,一系列SO问题和大量资源,但我仍然感到困惑,主要是因为在不同的上下文中术语似乎具有不同的含义。
我已经从fadden的站点这里查看了CameraToMpegTest 。我的具体问题是如何MediaCodec::createInputSurface()与结合使用Camera::setPreviewTexture()。似乎先创建了OpenGL纹理,然后将其用于创建一个Android SurfaceTexture,然后可以将其传递给setPreviewTexture()。我的具体问题:
setPreviewTexture()帧从相机转到哪个内存缓冲区,调用实际上会做什么?SurfaceTexture提到它允许您“将图像流式传输到给定的OpenGL纹理”:https : //developer.android.com/reference/android/graphics/SurfaceTexture.html#SurfaceTexture(int)。SurfaceTexture在OpenGL纹理之上做什么?MediaCodec::createInputSurface()返回一个Android Surface。据我了解,Android Surface代表缓冲区队列的生产方,因此它可能是多个缓冲区。该API参考提到,“表面必须用硬件加速API来呈现,如OpenGL ES”。如何帧从相机获取捕捉SurfaceTexture到这Surface是输入到编码器?我看到CameraToMpegTest的创建EGLSurface使用这种Surface莫名其妙但不知道很多关于EGL我没有得到这个部分。编辑:mstorsjo的答复的后续行动:
SurfaceTexture并CameraClient::setPreviewTarget() 在CameraService一些尝试和了解的内部运作Camera::setPreviewTexture()更好,有更多的问题。对于我最初理解内存分配的问题,似乎要SurfaceTexture创建一个BufferQueue并将其CameraService传递IGraphicBufferProducer给平台摄像机HAL实现。然后,摄像机HAL可以适当地设置gralloc使用标志(例如GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_NEVER | GRALLOC_USAGE_HW_TEXTURE),还可以从中退出缓冲区BufferQueue。因此,摄像机捕获帧的缓冲区是由gralloc分配的缓冲区,这些缓冲区带有一些特殊的使用标志,例如GRALLOC_USAGE_HW_TEXTURE。我在具有统一内存架构的ARM平台上工作,因此GPU和CPU可以访问相同的内存,因此,这会对您产生什么样的影响?GRALLOC_USAGE_HW_TEXTURE 标志有关于如何分配缓冲区的?SurfaceTexture似乎主要是作为的一部分实现的GLConsumer,而魔术似乎在中 …I have written the attached example program that uses GTK2 in conjunction with EGL and OpenGL. On my system this works fine. On the PC of friend it only will produce a black window and I cannot put my finger on why this happens. We event straces which libraries get loaded (Which are the same). My PC has a NVIDIA MX150, he has a GTX 1030, he uses Debian Strech and I use Debian buster.
I cannot put my finger …
我正在研究要编译为WASM并在浏览器中显示图像的C程序。该程序的重点是学习使用EGL进行设置,因此,我对涉及SDL,GLFW等的任何答案都不感兴趣。
此代码可将屏幕清除为蓝色(我省略了错误检查以减小尺寸):
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "emscripten.h"
struct Environment
{
EGLint majorVersion;
EGLint minorVersion;
EGLDisplay display;
EGLSurface surface;
};
static struct Environment g_env = {};
bool initGL(struct Environment* env)
{
env->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(env->display, &env->majorVersion, &env->minorVersion);
EGLint numConfigs = 0;
EGLint attribList[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_DEPTH_SIZE, 1,
EGL_NONE
};
EGLConfig config;
eglChooseConfig(env->display, attribList, &config, 1, &numConfigs);
env->surface = eglCreateWindowSurface(env->display, config, 0, NULL);
static const …Run Code Online (Sandbox Code Playgroud) 我使用NDK和egl命令在Android平板电脑上渲染时间非常短.我有时间调用eglSwapBuffers并且正在花费不同的时间,经常超过设备帧速率.我知道它与刷新同步,但大约是60FPS,而且这里的时间远低于此.
我在调用swap之间发出的唯一命令是glClear,所以我知道这不是我正在绘制的导致问题的任何内容.即使只是通过清除帧速率降至30FPS(虽然不稳定).
在同一台设备上,Java中的简单GL程序可以轻松渲染到60FPS,因此我知道它并不是一个基本的硬件问题.我查看了用于设置GL上下文的Android Java代码,但看不出任何显着差异.我也玩过每个配置属性,虽然有些人稍微改变了速度,但是没有(我能找到)改变了这个可怕的帧速率下降.
为了确保事件轮询不是问题,我将渲染移动到一个线程中.该线程现在只进行渲染,因此只需调用clear和swap重复.缓慢的表现仍然存在.
我没有想法要检查什么,我正在寻找关于问题可能是什么的建议.
我想通过EGL创建一个OpenGL上下文.由于我实际上不会绘制,我想将Pbuffers与GBM平台结合使用.这是代码(C99):
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <gbm.h>
int main( void )
{
assert( eglBindAPI( EGL_OPENGL_API ) == EGL_TRUE );
int fd = open("/dev/dri/card0", O_RDWR);
struct gbm_device * gbm = gbm_create_device( fd );
EGLDisplay dpy = eglGetDisplay( gbm );
eglInitialize( dpy , NULL , NULL );
EGLConfig config;
EGLint n_of_configs;
assert( eglGetConfigs( dpy , &config , 1 , &n_of_configs ) == EGL_TRUE );
EGLSurface srf = eglCreatePbufferSurface( dpy , config , NULL ); …Run Code Online (Sandbox Code Playgroud) 我试图使用OpenGL并将输出直接写入Imx6处理器(cubox)上的Framebuffer.原因是我试图避免使用X11
我使用了https://github.com/benosteen/opengles-book-samples/blob/master/Raspi/Chapter_2/Hello_Triangle/Hello_Triangle.c中的示例应用程序.
我将代码修改为不包含任何X11头文件或Window创建函数,我替换了surface = eglCreatePixmapSurface(display,config,(EGLNativePixmapType)Hwnd,NULL); with surface = eglCreatePbufferSurface(display,config,surfaceAttribs);
然后我使用glReadPixels(..)将OpenGl像素直接输出到帧缓冲区
当我使用VisualGDB运行应用程序时,应用程序运行良好,并通过写入/ dev/fb0直接在屏幕上显示输出
但是,当我从控制台运行时,使用./OpenGL_Test_IMX我收到以下错误:
The framebuffer device was opened successfully.
The framebuffer device was opened successfully.
1920x1200, 32bpp
The framebuffer device was mapped to memory successfully.
libEGL warning: DRI2: xcb_connect failed
libEGL warning: DRI2: xcb_connect failed
libEGL warning: GLX: XOpenDisplay failed
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
我的Egl初始化代码如下所示.我拿出错误检查以缩短时间.
代码在eglInitialize(display,&majorVersion,&minorVersion)上失败.分段错误是eglGetError()的输出
EGLBoolean CreateEGLContext(EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
EGLContext* eglContext, EGLSurface* eglSurface,
EGLint attribList[])
{
EGLint numConfigs;
EGLint majorVersion;
EGLint minorVersion;
EGLDisplay display;
EGLContext context;
EGLSurface surface; …Run Code Online (Sandbox Code Playgroud) egl ×10
android ×6
opengl-es ×5
c ×2
linux ×2
mediacodec ×2
opengl ×2
x11 ×2
android-ndk ×1
caching ×1
emscripten ×1
gtk ×1
mesa ×1
video ×1