我把视频帧解码成一个VASurface。现在,我想使用OpenGL纹理来呈现它们。我能够将帧加载到软件中(使用vaDeriveImage和vaMapBuffer),并使用接收到的数据更新纹理。但这真的很慢,这不是我在这里的目标。然后我发现EGL在其他几个回复中使用。
因此,我找到了这个回购,根据我所看到的,它完全使用EGL呈现框架。这不是我想要的。我需要它的纹理,供以后使用。
然后我遇到了fmor演示程序。在我看来这真的很像魔法。有两个步骤在init上,然后他可以使用纹理没有问题。
//in player.c before the decoding happens:
egl_image = egl_create_image_from_va( &surface, player->video_va_display, player->video_cc->width, player->video_cc->height );
if( egl_image == EGL_NO_IMAGE )
goto LBL_FAILED;
glGenTextures( 1, &player->video_texture );
glBindTexture( GL_TEXTURE_2D, player->video_texture );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glEGLImageTargetTexture2DOES( GL_TEXTURE_2D, egl_image );
//in util.c:
EGLImage egl_create_image_from_va(VASurfaceID* _va_surface, VADisplay va_display, int width, int height)
{
EGLImage egl_image;
VASurfaceID va_surface;
VASurfaceAttrib va_surface_attrib;
VADRMPRIMESurfaceDescriptor va_surface_descriptor;
int r;
egl_image = EGL_NO_IMAGE;
va_surface = VA_INVALID_SURFACE;
va_surface_attrib.type = VASurfaceAttribPixelFormat;
va_surface_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
va_surface_attrib.value.type = VAGenericValueTypeInteger;
va_surface_attrib.value.value.i = VA_FOURCC_RGBA;
r = vaCreateSurfaces( va_display, VA_RT_FORMAT_RGB32, width, height, &va_surface, 1, &va_surface_attrib, 1 );
if( r != VA_STATUS_SUCCESS )
goto LBL_FAILED;
r = vaExportSurfaceHandle( va_display, va_surface, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, VA_EXPORT_SURFACE_READ_ONLY, &va_surface_descriptor );
if( r != 0 )
goto LBL_FAILED;
EGLAttrib egl_img_attributes[] = {
EGL_LINUX_DRM_FOURCC_EXT, va_surface_descriptor.layers[0].drm_format,
EGL_WIDTH, va_surface_descriptor.width,
EGL_HEIGHT, va_surface_descriptor.height,
EGL_DMA_BUF_PLANE0_FD_EXT, va_surface_descriptor.objects[va_surface_descriptor.layers[0].object_index[0]].fd,
EGL_DMA_BUF_PLANE0_OFFSET_EXT, va_surface_descriptor.layers[0].offset[0],
EGL_DMA_BUF_PLANE0_PITCH_EXT, va_surface_descriptor.layers[0].pitch[0],
EGL_NONE
};
egl_image = eglCreateImage( eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, egl_img_attributes );
if( egl_image == EGL_NO_IMAGE )
goto LBL_FAILED;
*_va_surface = va_surface;
return egl_image;
LBL_FAILED:
if( va_surface != VA_INVALID_SURFACE )
vaDestroySurfaces( va_display, &va_surface, 1 );
return EGL_NO_IMAGE;
}有人能告诉我这里发生了什么吗?我怎么能不用glew复制这个?
我最难猜测的是,对于用于创建EGL_LINUX_DMA_BUF_EXT的eglImage参数,有一些直接访问正在进行的内存。vaapi在这里呈现为OpenGL纹理吗?
另外,这里使用的是vaExportSurfaceHandle,我不太明白这是在做什么。
编辑:,我现在读了很多与EGL相关的文章。我想我现在更明白了。但是当我再次看到fmor演示程序时,我感到很困惑。有几个eglGetCurrentDisplay()调用,但是我找不到设置这个显示的位置,所以我可以复制它。可能是glew在幕后做了什么,还是我错过了别的什么?
甚至连eglInitialze()也从来没有被调用过一次。
当我尝试用eglGetDisplay(native_display)实例化一个eglGetDisplay(native_display)时,就像它是在ffvademo中所做的那样,我应该为native_display添加什么?在ffvademo中有X11显示或DRM显示(?)插入。据我所知,这两者都是用来呈现给屏幕的吗?此外,我认为插入vaapi显示将不是正确的事情。伙计们,我真的需要帮助.
发布于 2022-08-04 07:31:41
好吧,我找到了。GLFW正在做所有需要的事情。我想我会读一遍密码找到我的答案。
https://stackoverflow.com/questions/73190164
复制相似问题