2016-04-27 3 views
1

Я реализовал аппаратное декодирование в Linux с помощью VAAPI через FFmpeg. Поскольку у меня есть приложение OpenGL, я преобразовываю декодированные поверхности VAAPI в текстуры OpenGL, используя vaCopySurfaceGLX. Это работает отлично, за исключением того, что есть копия (на графическом процессоре), которая была сделана. Мне сказали, что я могу напрямую использовать поверхность VAAPI как текстуры OpenGL, используя EGL. Я рассмотрел некоторые примеры (главным образом исходный код Kodi), но я не могу создать EGLImageKHR. Функция eglCreateImageKHR возвращает 0, и когда я проверяю ошибки, я получаю ошибку EGL_BAD_ATTRIBUTE, но я не понимаю, почему.eglCreateImageKHR, возвращающий ошибку EGL_BAD_ATTRIBUTE

Ниже показано, как я преобразую поверхность VAAPI.

Во время инициализации, настроить EGL таким образом:

// currentDisplay comes from call to glXGetCurrentDisplay() and is also used when getting the VADisplay like this: vaGetDisplay(currentDisplay)  

EGLint major, minor; 
_eglDisplay = eglGetDisplay(currentDisplay); 
eglInitialize(_eglDisplay, &major, &minor); 
eglBindAPI(EGL_OPENGL_API); 

Тогда позже, чтобы создать свой EGL образ, это то, что я делаю:

// _vaapiContext.vaDisplay comes from vaGetDisplay(currentDisplay) 
// surface is the VASurfaceID of the surface I want to use in OpenGL 
vaDeriveImage(_vaapiContext.vaDisplay, surface, &_vaapiContext.vaImage); 

VABufferInfo buf_info; 
memset(&buf_info, 0, sizeof(buf_info)); 
buf_info.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; 
vaAcquireBufferHandle(_vaapiContext.vaDisplay, _vaapiContext.vaImage.buf, &buf_info); 
EGLint attribs[] = { 
    EGL_WIDTH, _vaapiContext.vaImage.width, 
    EGL_HEIGHT, _vaapiContext.vaImage.height, 
    EGL_LINUX_DRM_FOURCC_EXT, fourcc_code('R', '8', ' ', ' '), 
    EGL_DMA_BUF_PLANE0_FD_EXT, buf_info.handle, 
    EGL_DMA_BUF_PLANE0_OFFSET_EXT, _vaapiContext.vaImage.offsets[0], 
    EGL_DMA_BUF_PLANE0_PITCH_EXT, _vaapiContext.vaImage.pitches[0], 
    EGL_NONE 
}; 

EGLImageKHR eglImage = eglCreateImageKHR(_eglDisplay, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, (EGLClientBuffer)NULL, attribs); 

Глядя на то, что может привести к этой ошибке в следующем документе https://www.khronos.org/registry/egl/extensions/EXT/EGL_EXT_image_dma_buf_import.txt, я также попытался добавить следующие параметры, которые не должны иметь значения, поскольку мой формат не является плоским.

EGL_YUV_COLOR_SPACE_HINT_EXT, EGL_ITU_REC601_EXT, 
EGL_SAMPLE_RANGE_HINT_EXT, EGL_YUV_FULL_RANGE_EXT, 
EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT, EGL_YUV_CHROMA_SITING_0_EXT, 
EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT, EGL_YUV_CHROMA_SITING_0_EXT 

Код, который я использую, похож на все примеры, которые я видел, поэтому я не уверен, что такое ошибка.

Обратите внимание, что я удалил все проверки ошибок для этого сообщения. Все вышеперечисленные вызовы успешны, за исключением eglCreateImageKHR.

ответ

1

После поворота уровня журнала egl для отладки я смог получить дополнительную информацию об ошибке и указать, где в исходном коде egl произошла эта ошибка. Оказывается, формат fourcc_code ('R', '8', '', '') не поддерживался, потому что моя версия mesa была слишком старой. Вам нужно установить mesa 11.0.0 или выше. После перекомпиляции mesa (я запускаю Ubuntu 15.04) и установки версии 11.0.0, я наконец получаю изображение EGL.

Смежные вопросы