GstEGLImage * gst_egl_image_from_dmabuf (GstGLContext * context, gint dmabuf, GstVideoInfo * in_info, gint plane, gsize offset) { GstGLContextEGL *ctx_egl = GST_GL_CONTEXT_EGL (context); gint fourcc; gint atti = 0; EGLint attribs[13]; EGLImageKHR img = EGL_NO_IMAGE_KHR; GstVideoGLTextureType type; fourcc = _drm_fourcc_from_info (in_info, plane); type = gst_gl_texture_type_from_format (context, GST_VIDEO_INFO_FORMAT (in_info), plane); GST_DEBUG ("fourcc %.4s (%d) plane %d (%dx%d)", (char *) &fourcc, fourcc, plane, GST_VIDEO_INFO_COMP_WIDTH (in_info, plane), GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane)); attribs[atti++] = EGL_WIDTH; attribs[atti++] = GST_VIDEO_INFO_COMP_WIDTH (in_info, plane); attribs[atti++] = EGL_HEIGHT; attribs[atti++] = GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane); attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT; attribs[atti++] = fourcc; attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT; attribs[atti++] = dmabuf; attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; attribs[atti++] = offset; attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, plane); attribs[atti] = EGL_NONE; for (int i = 0; i < atti; i++) GST_LOG ("attr %i: %08X", i, attribs[i]); g_assert (atti == 12); img = ctx_egl->eglCreateImage (ctx_egl->egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); if (!img) { GST_WARNING ("eglCreateImage failed: %s", gst_gl_context_egl_get_error_string (eglGetError ())); return NULL; } return gst_egl_image_new_wrapped (context, img, type, GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL, (GstEGLImageDestroyNotify) _destroy_egl_image, NULL); }
static gboolean _gl_mem_create (GstGLMemoryEGL * gl_mem, GError ** error) { GstGLContext *context = gl_mem->mem.mem.context; GstGLContextEGL *ctx_egl = GST_GL_CONTEXT_EGL (context); const GstGLFuncs *gl = context->gl_vtable; GstGLBaseMemoryAllocatorClass *alloc_class; if (!gst_gl_context_check_feature (GST_GL_CONTEXT (context), "EGL_KHR_image_base")) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, "EGL_KHR_image_base is not supported"); return FALSE; } alloc_class = GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class); if (!alloc_class->create ((GstGLBaseMemory *) gl_mem, error)) return FALSE; if (gl_mem->image == NULL) { EGLImageKHR image = ctx_egl->eglCreateImageKHR (ctx_egl->egl_display, ctx_egl->egl_context, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer) (guintptr) gl_mem->mem.tex_id, NULL); GST_TRACE ("Generating EGLImage handle:%p from a texture:%u", gl_mem->image, gl_mem->mem.tex_id); if (eglGetError () != EGL_SUCCESS) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED, "Failed to create EGLImage"); return FALSE; } gl_mem->image = gst_egl_image_new_wrapped (context, image, 0, 0, NULL, (GstEGLImageDestroyNotify) _destroy_egl_image); } else { gl->ActiveTexture (GL_TEXTURE0 + gl_mem->mem.plane); gl->BindTexture (GL_TEXTURE_2D, gl_mem->mem.tex_id); gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, gst_egl_image_get_image (GST_EGL_IMAGE (gl_mem->image))); } return TRUE; }