首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >vaapi表面到openGl纹理

vaapi表面到openGl纹理
EN

Stack Overflow用户
提问于 2022-08-01 07:27:19
回答 1查看 156关注 0票数 0

我把视频帧解码成一个VASurface。现在,我想使用OpenGL纹理来呈现它们。我能够将帧加载到软件中(使用vaDeriveImagevaMapBuffer),并使用接收到的数据更新纹理。但这真的很慢,这不是我在这里的目标。然后我发现EGL在其他几个回复中使用。

因此,我找到了这个回购,根据我所看到的,它完全使用EGL呈现框架。这不是我想要的。我需要它的纹理,供以后使用。

然后我遇到了fmor演示程序。在我看来这真的很像魔法。有两个步骤在init上,然后他可以使用纹理没有问题。

代码语言:javascript
复制
//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显示将不是正确的事情。伙计们,我真的需要帮助.

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-04 07:31:41

好吧,我找到了。GLFW正在做所有需要的事情。我想我会读一遍密码找到我的答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73190164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档