Blame gst-libs/gst/gl/egl/gsteglimage.c

Packit 971217
/*
Packit 971217
 * GStreamer
Packit 971217
 * Copyright (C) 2012 Collabora Ltd.
Packit 971217
 *   @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
Packit 971217
 * Copyright (C) 2014 Julien Isorce <julien.isorce@gmail.com>
Packit 971217
 * Copyright (C) 2016 Matthew Waters <matthew@centricular.com>
Packit 971217
 *
Packit 971217
 * This library is free software; you can redistribute it and/or
Packit 971217
 * modify it under the terms of the GNU Library General Public
Packit 971217
 * License as published by the Free Software Foundation; either
Packit 971217
 * version 2 of the License, or (at your option) any later version.
Packit 971217
 *
Packit 971217
 * This library is distributed in the hope that it will be useful,
Packit 971217
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 971217
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 971217
 * Library General Public License for more details.
Packit 971217
 *
Packit 971217
 * You should have received a copy of the GNU Library General Public
Packit 971217
 * License along with this library; if not, write to the
Packit 971217
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 971217
 * Boston, MA 02110-1301, USA.
Packit 971217
 */
Packit 971217
Packit 971217
/**
Packit 971217
 * SECTION:gsteglimage
Packit 971217
 * @short_description: EGLImage abstraction
Packit 971217
 * @title: GstEGLImage
Packit 971217
 * @see_also: #GstGLMemoryEGL, #GstGLContext
Packit 971217
 *
Packit 971217
 * #GstEGLImage represents and holds an #EGLImage handle.
Packit 971217
 *
Packit 971217
 * A #GstEGLImage can be created from a dmabuf with gst_egl_image_from_dmabuf()
Packit 971217
 * or #GstGLMemoryEGL provides a #GstAllocator to allocate #EGLImage's bound to
Packit 971217
 * and OpenGL texture.
Packit 971217
 */
Packit 971217
Packit 971217
#ifdef HAVE_CONFIG_H
Packit 971217
#include "config.h"
Packit 971217
#endif
Packit 971217
Packit 971217
#include "gsteglimage.h"
Packit 971217
Packit 971217
#include <string.h>
Packit 971217
Packit 971217
#include <gst/gl/gstglfeature.h>
Packit 971217
#include <gst/gl/gstglmemory.h>
Packit 971217
Packit 971217
#include "gst/gl/egl/gstegl.h"
Packit 971217
#include "gst/gl/egl/gstglcontext_egl.h"
Packit 971217
#include "gst/gl/egl/gstgldisplay_egl.h"
Packit 971217
Packit 971217
#if GST_GL_HAVE_DMABUF
Packit 971217
#include <gst/allocators/gstdmabuf.h>
Packit 971217
#include <libdrm/drm_fourcc.h>
Packit 971217
Packit 971217
#ifndef DRM_FORMAT_R8
Packit 971217
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
Packit 971217
#endif
Packit 971217
Packit 971217
#ifndef DRM_FORMAT_RG88
Packit 971217
#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')
Packit 971217
#endif
Packit 971217
Packit 971217
#ifndef DRM_FORMAT_GR88
Packit 971217
#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
Packit 971217
#endif
Packit 971217
#endif
Packit 971217
Packit 971217
#ifndef EGL_LINUX_DMA_BUF_EXT
Packit 971217
#define EGL_LINUX_DMA_BUF_EXT 0x3270
Packit 971217
#endif
Packit 971217
Packit 971217
#ifndef EGL_LINUX_DRM_FOURCC_EXT
Packit 971217
#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
Packit 971217
#endif
Packit 971217
Packit 971217
#ifndef EGL_DMA_BUF_PLANE0_FD_EXT
Packit 971217
#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
Packit 971217
#endif
Packit 971217
Packit 971217
#ifndef EGL_DMA_BUF_PLANE0_OFFSET_EXT
Packit 971217
#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
Packit 971217
#endif
Packit 971217
Packit 971217
#ifndef EGL_DMA_BUF_PLANE0_PITCH_EXT
Packit 971217
#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
Packit 971217
#endif
Packit 971217
Packit 971217
#ifdef USE_EGL_RPI
Packit 971217
typedef khronos_uint64_t EGLuint64KHR;
Packit 971217
#endif
Packit 971217
Packit 971217
GST_DEFINE_MINI_OBJECT_TYPE (GstEGLImage, gst_egl_image);
Packit 971217
Packit 971217
#ifndef GST_DISABLE_GST_DEBUG
Packit 971217
#define GST_CAT_DEFAULT gst_egl_image_ensure_debug_category()
Packit 971217
Packit 971217
static GstDebugCategory *
Packit 971217
gst_egl_image_ensure_debug_category (void)
Packit 971217
{
Packit 971217
  static gsize cat_gonce = 0;
Packit 971217
Packit 971217
  if (g_once_init_enter (&cat_gonce)) {
Packit 971217
    GstDebugCategory *cat = NULL;
Packit 971217
Packit 971217
    GST_DEBUG_CATEGORY_INIT (cat, "gleglimage", 0, "EGLImage wrapper");
Packit 971217
Packit 971217
    g_once_init_leave (&cat_gonce, (gsize) cat);
Packit 971217
  }
Packit 971217
Packit 971217
  return (GstDebugCategory *) cat_gonce;
Packit 971217
}
Packit 971217
#endif /* GST_DISABLE_GST_DEBUG */
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_egl_image_get_image:
Packit 971217
 * @image: a #GstEGLImage
Packit 971217
 *
Packit 971217
 * Returns: the #EGLImageKHR of @image
Packit 971217
 */
Packit 971217
gpointer
Packit 971217
gst_egl_image_get_image (GstEGLImage * image)
Packit 971217
{
Packit 971217
  g_return_val_if_fail (GST_IS_EGL_IMAGE (image), EGL_NO_IMAGE_KHR);
Packit 971217
Packit 971217
  return image->image;
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
_gst_egl_image_free_thread (GstGLContext * context, GstEGLImage * image)
Packit 971217
{
Packit 971217
  if (image->destroy_notify)
Packit 971217
    image->destroy_notify (image, image->destroy_data);
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
_gst_egl_image_free (GstMiniObject * object)
Packit 971217
{
Packit 971217
  GstEGLImage *image = GST_EGL_IMAGE (object);
Packit 971217
Packit 971217
  if (image->context) {
Packit 971217
    gst_gl_context_thread_add (GST_GL_CONTEXT (image->context),
Packit 971217
        (GstGLContextThreadFunc) _gst_egl_image_free_thread, image);
Packit 971217
    gst_object_unref (image->context);
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
static GstMiniObject *
Packit 971217
_gst_egl_image_copy (GstMiniObject * obj)
Packit 971217
{
Packit 971217
  return gst_mini_object_ref (obj);
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_egl_image_new_wrapped:
Packit 971217
 * @context: a #GstGLContext (must be an EGL context)
Packit 971217
 * @image: the image to wrap
Packit 971217
 * @format: the #GstGLFormat
Packit 971217
 * @user_data: user data
Packit 971217
 * @user_data_destroy: called when @user_data is no longer needed
Packit 971217
 *
Packit 971217
 * Returns: a new #GstEGLImage wrapping @image
Packit 971217
 */
Packit 971217
GstEGLImage *
Packit 971217
gst_egl_image_new_wrapped (GstGLContext * context, gpointer image,
Packit 971217
    GstGLFormat format, gpointer user_data,
Packit 971217
    GstEGLImageDestroyNotify user_data_destroy)
Packit 971217
{
Packit 971217
  GstEGLImage *img = NULL;
Packit 971217
Packit 971217
  g_return_val_if_fail (context != NULL, NULL);
Packit 971217
  g_return_val_if_fail ((gst_gl_context_get_gl_platform (context) &
Packit 971217
          GST_GL_PLATFORM_EGL) != 0, NULL);
Packit 971217
  g_return_val_if_fail (image != EGL_NO_IMAGE_KHR, NULL);
Packit 971217
Packit 971217
  img = g_new0 (GstEGLImage, 1);
Packit 971217
  gst_mini_object_init (GST_MINI_OBJECT_CAST (img), 0, GST_TYPE_EGL_IMAGE,
Packit 971217
      (GstMiniObjectCopyFunction) _gst_egl_image_copy, NULL,
Packit 971217
      (GstMiniObjectFreeFunction) _gst_egl_image_free);
Packit 971217
Packit 971217
  img->context = gst_object_ref (context);
Packit 971217
  img->image = image;
Packit 971217
  img->format = format;
Packit 971217
Packit 971217
  img->destroy_data = user_data;
Packit 971217
  img->destroy_notify = user_data_destroy;
Packit 971217
Packit 971217
  return img;
Packit 971217
}
Packit 971217
Packit 971217
static EGLImageKHR
Packit 971217
_gst_egl_image_create (GstGLContext * context, guint target,
Packit 971217
    EGLClientBuffer buffer, guintptr * attribs)
Packit 971217
{
Packit 971217
  EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
Packit 971217
  EGLContext egl_context = EGL_NO_CONTEXT;
Packit 971217
  EGLImageKHR img = EGL_NO_IMAGE_KHR;
Packit 971217
  GstGLDisplayEGL *display_egl;
Packit 971217
  gint plat_major, plat_minor;
Packit 971217
  guint attrib_len = 0;
Packit 971217
Packit 971217
  gst_gl_context_get_gl_platform_version (context, &plat_major, &plat_minor);
Packit 971217
Packit 971217
  display_egl = gst_gl_display_egl_from_gl_display (context->display);
Packit 971217
  if (!display_egl) {
Packit 971217
    GST_WARNING_OBJECT (context, "Failed to retrieve GstGLDisplayEGL from %"
Packit 971217
        GST_PTR_FORMAT, context->display);
Packit 971217
    return EGL_NO_IMAGE_KHR;
Packit 971217
  }
Packit 971217
  egl_display =
Packit 971217
      (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
Packit 971217
  gst_object_unref (display_egl);
Packit 971217
Packit 971217
  if (target != EGL_LINUX_DMA_BUF_EXT)
Packit 971217
    egl_context = (EGLContext) gst_gl_context_get_gl_context (context);
Packit 971217
Packit 971217
  if (attribs)
Packit 971217
    while (attribs[attrib_len++] != EGL_NONE) {
Packit 971217
    }
Packit 971217
#ifdef EGL_VERSION_1_5
Packit 971217
  if (GST_GL_CHECK_GL_VERSION (plat_major, plat_minor, 1, 5)) {
Packit 971217
    EGLImageKHR (*gst_eglCreateImage) (EGLDisplay dpy, EGLContext ctx,
Packit 971217
        EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list);
Packit 971217
    EGLAttrib *egl_attribs = NULL;
Packit 971217
    guint i;
Packit 971217
Packit 971217
    gst_eglCreateImage = gst_gl_context_get_proc_address (context,
Packit 971217
        "eglCreateImage");
Packit 971217
    if (!gst_eglCreateImage) {
Packit 971217
      GST_ERROR_OBJECT (context, "\"eglCreateImage\" not exposed by the "
Packit 971217
          "implementation as required by EGL >= 1.5");
Packit 971217
      return EGL_NO_IMAGE_KHR;
Packit 971217
    }
Packit 971217
Packit 971217
    if (attribs) {
Packit 971217
      egl_attribs = g_new0 (EGLAttrib, attrib_len);
Packit 971217
      for (i = 0; i < attrib_len; i++)
Packit 971217
        egl_attribs[i] = (EGLAttrib) attribs[i];
Packit 971217
    }
Packit 971217
Packit 971217
    img = gst_eglCreateImage (egl_display, egl_context, target, buffer,
Packit 971217
        egl_attribs);
Packit 971217
Packit 971217
    g_free (egl_attribs);
Packit 971217
  } else
Packit 971217
#endif
Packit 971217
  {
Packit 971217
    EGLImageKHR (*gst_eglCreateImageKHR) (EGLDisplay dpy, EGLContext ctx,
Packit 971217
        EGLenum target, EGLClientBuffer buffer, const EGLint * attrib_list);
Packit 971217
    EGLint *egl_attribs = NULL;
Packit 971217
    gint i;
Packit 971217
Packit 971217
    gst_eglCreateImageKHR = gst_gl_context_get_proc_address (context,
Packit 971217
        "eglCreateImageKHR");
Packit 971217
    if (!gst_eglCreateImageKHR) {
Packit 971217
      GST_WARNING_OBJECT (context, "\"eglCreateImageKHR\" not exposed by the "
Packit 971217
          "implementation");
Packit 971217
      return EGL_NO_IMAGE_KHR;
Packit 971217
    }
Packit 971217
Packit 971217
    if (attribs) {
Packit 971217
      egl_attribs = g_new0 (EGLint, attrib_len);
Packit 971217
      for (i = 0; i < attrib_len; i++)
Packit 971217
        egl_attribs[i] = (EGLint) attribs[i];
Packit 971217
    }
Packit 971217
Packit 971217
    img = gst_eglCreateImageKHR (egl_display, egl_context, target, buffer,
Packit 971217
        egl_attribs);
Packit 971217
Packit 971217
    g_free (egl_attribs);
Packit 971217
  }
Packit 971217
Packit 971217
  return img;
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
_gst_egl_image_destroy (GstGLContext * context, EGLImageKHR image)
Packit 971217
{
Packit 971217
  EGLBoolean (*gst_eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image);
Packit 971217
  EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
Packit 971217
  GstGLDisplayEGL *display_egl;
Packit 971217
Packit 971217
  gst_eglDestroyImage = gst_gl_context_get_proc_address (context,
Packit 971217
      "eglDestroyImage");
Packit 971217
  if (!gst_eglDestroyImage) {
Packit 971217
    gst_eglDestroyImage = gst_gl_context_get_proc_address (context,
Packit 971217
        "eglDestroyImageKHR");
Packit 971217
    if (!gst_eglDestroyImage) {
Packit 971217
      GST_ERROR_OBJECT (context, "\"eglDestroyImage\" not exposed by the "
Packit 971217
          "implementation");
Packit 971217
      return;
Packit 971217
    }
Packit 971217
  }
Packit 971217
Packit 971217
  display_egl = gst_gl_display_egl_from_gl_display (context->display);
Packit 971217
  if (!display_egl) {
Packit 971217
    GST_WARNING_OBJECT (context, "Failed to retrieve GstGLDisplayEGL from %"
Packit 971217
        GST_PTR_FORMAT, context->display);
Packit 971217
    return;
Packit 971217
  }
Packit 971217
  egl_display =
Packit 971217
      (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
Packit 971217
  gst_object_unref (display_egl);
Packit 971217
Packit 971217
  if (!gst_eglDestroyImage (egl_display, image))
Packit 971217
    GST_WARNING_OBJECT (context, "eglDestroyImage failed");
Packit 971217
}
Packit 971217
Packit 971217
static void
Packit 971217
_destroy_egl_image (GstEGLImage * image, gpointer user_data)
Packit 971217
{
Packit 971217
  _gst_egl_image_destroy (image->context, image->image);
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_egl_image_from_texture:
Packit 971217
 * @context: a #GstGLContext (must be an EGL context)
Packit 971217
 * @gl_mem: a #GstGLMemory
Packit 971217
 * @attribs: additional attributes to add to the eglCreateImage() call.
Packit 971217
 *
Packit 971217
 * Returns: (transfer full): a #GstEGLImage wrapping @gl_mem or %NULL on failure
Packit 971217
 */
Packit 971217
GstEGLImage *
Packit 971217
gst_egl_image_from_texture (GstGLContext * context, GstGLMemory * gl_mem,
Packit 971217
    guintptr * attribs)
Packit 971217
{
Packit 971217
  EGLenum egl_target;
Packit 971217
  EGLImageKHR img;
Packit 971217
Packit 971217
  if (gl_mem->tex_target != GST_GL_TEXTURE_TARGET_2D) {
Packit 971217
    GST_FIXME_OBJECT (context, "Only know how to create EGLImage's from 2D "
Packit 971217
        "textures");
Packit 971217
    return NULL;
Packit 971217
  }
Packit 971217
Packit 971217
  egl_target = EGL_GL_TEXTURE_2D_KHR;
Packit 971217
Packit 971217
  img = _gst_egl_image_create (context, egl_target,
Packit 971217
      (EGLClientBuffer) (guintptr) gl_mem->tex_id, attribs);
Packit 971217
  if (!img)
Packit 971217
    return NULL;
Packit 971217
Packit 971217
  return gst_egl_image_new_wrapped (context, img, gl_mem->tex_format, NULL,
Packit 971217
      (GstEGLImageDestroyNotify) _destroy_egl_image);
Packit 971217
}
Packit 971217
Packit 971217
#if GST_GL_HAVE_DMABUF
Packit 971217
/*
Packit 971217
 * GStreamer format descriptions differ from DRM formats as the representation
Packit 971217
 * is relative to a register, hence in native endianness. To reduce the driver
Packit 971217
 * requirement, we only import with a subset of texture formats and use
Packit 971217
 * shaders to convert. This way we avoid having to use external texture
Packit 971217
 * target.
Packit 971217
 */
Packit 971217
static int
Packit 971217
_drm_fourcc_from_info (GstVideoInfo * info, int plane)
Packit 971217
{
Packit 971217
  GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info);
Packit 971217
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
Packit 971217
  const gint rgba_fourcc = DRM_FORMAT_ABGR8888;
Packit 971217
  const gint rgb_fourcc = DRM_FORMAT_BGR888;
Packit 971217
  const gint rg_fourcc = DRM_FORMAT_GR88;
Packit 971217
#else
Packit 971217
  const gint rgba_fourcc = DRM_FORMAT_RGBA8888;
Packit 971217
  const gint rgb_fourcc = DRM_FORMAT_RGB888;
Packit 971217
  const gint rg_fourcc = DRM_FORMAT_RG88;
Packit 971217
#endif
Packit 971217
Packit 971217
  GST_DEBUG ("Getting DRM fourcc for %s plane %i",
Packit 971217
      gst_video_format_to_string (format), plane);
Packit 971217
Packit 971217
  switch (format) {
Packit 971217
    case GST_VIDEO_FORMAT_RGB16:
Packit 971217
    case GST_VIDEO_FORMAT_BGR16:
Packit 971217
      return DRM_FORMAT_RGB565;
Packit 971217
Packit 971217
    case GST_VIDEO_FORMAT_RGB:
Packit 971217
    case GST_VIDEO_FORMAT_BGR:
Packit 971217
      return rgb_fourcc;
Packit 971217
Packit 971217
    case GST_VIDEO_FORMAT_RGBA:
Packit 971217
    case GST_VIDEO_FORMAT_RGBx:
Packit 971217
    case GST_VIDEO_FORMAT_BGRA:
Packit 971217
    case GST_VIDEO_FORMAT_BGRx:
Packit 971217
    case GST_VIDEO_FORMAT_ARGB:
Packit 971217
    case GST_VIDEO_FORMAT_xRGB:
Packit 971217
    case GST_VIDEO_FORMAT_ABGR:
Packit 971217
    case GST_VIDEO_FORMAT_xBGR:
Packit 971217
    case GST_VIDEO_FORMAT_AYUV:
Packit 971217
      return rgba_fourcc;
Packit 971217
Packit 971217
    case GST_VIDEO_FORMAT_GRAY8:
Packit 971217
      return DRM_FORMAT_R8;
Packit 971217
Packit 971217
    case GST_VIDEO_FORMAT_YUY2:
Packit 971217
    case GST_VIDEO_FORMAT_UYVY:
Packit 971217
    case GST_VIDEO_FORMAT_GRAY16_LE:
Packit 971217
    case GST_VIDEO_FORMAT_GRAY16_BE:
Packit 971217
      return rg_fourcc;
Packit 971217
Packit 971217
    case GST_VIDEO_FORMAT_NV12:
Packit 971217
    case GST_VIDEO_FORMAT_NV21:
Packit 971217
      return plane == 0 ? DRM_FORMAT_R8 : rg_fourcc;
Packit 971217
Packit 971217
    case GST_VIDEO_FORMAT_I420:
Packit 971217
    case GST_VIDEO_FORMAT_YV12:
Packit 971217
    case GST_VIDEO_FORMAT_Y41B:
Packit 971217
    case GST_VIDEO_FORMAT_Y42B:
Packit 971217
    case GST_VIDEO_FORMAT_Y444:
Packit 971217
      return DRM_FORMAT_R8;
Packit 971217
Packit 971217
    default:
Packit 971217
      GST_ERROR ("Unsupported format for DMABuf.");
Packit 971217
      return -1;
Packit 971217
  }
Packit 971217
}
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_egl_image_from_dmabuf:
Packit 971217
 * @context: a #GstGLContext (must be an EGL context)
Packit 971217
 * @dmabuf: the DMA-Buf file descriptor
Packit 971217
 * @in_info: the #GstVideoInfo in @dmabuf
Packit 971217
 * @plane: the plane in @in_info to create and #GstEGLImage for
Packit 971217
 * @offset: the byte-offset in the data
Packit 971217
 *
Packit 971217
 * Returns: a #GstEGLImage wrapping @dmabuf or %NULL on failure
Packit 971217
 */
Packit 971217
GstEGLImage *
Packit 971217
gst_egl_image_from_dmabuf (GstGLContext * context,
Packit 971217
    gint dmabuf, GstVideoInfo * in_info, gint plane, gsize offset)
Packit 971217
{
Packit 971217
  GstGLFormat format;
Packit 971217
  guintptr attribs[13];
Packit 971217
  EGLImageKHR img;
Packit 971217
  gint atti = 0;
Packit 971217
  gint fourcc;
Packit 971217
  gint i;
Packit 971217
Packit 971217
  fourcc = _drm_fourcc_from_info (in_info, plane);
Packit 971217
  format = gst_gl_format_from_video_info (context, in_info, plane);
Packit 971217
Packit 971217
  GST_DEBUG ("fourcc %.4s (%d) plane %d (%dx%d)",
Packit 971217
      (char *) &fourcc, fourcc, plane,
Packit 971217
      GST_VIDEO_INFO_COMP_WIDTH (in_info, plane),
Packit 971217
      GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane));
Packit 971217
Packit 971217
  attribs[atti++] = EGL_WIDTH;
Packit 971217
  attribs[atti++] = GST_VIDEO_INFO_COMP_WIDTH (in_info, plane);
Packit 971217
  attribs[atti++] = EGL_HEIGHT;
Packit 971217
  attribs[atti++] = GST_VIDEO_INFO_COMP_HEIGHT (in_info, plane);
Packit 971217
  attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
Packit 971217
  attribs[atti++] = fourcc;
Packit 971217
  attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT;
Packit 971217
  attribs[atti++] = dmabuf;
Packit 971217
  attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
Packit 971217
  attribs[atti++] = offset;
Packit 971217
  attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
Packit 971217
  attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, plane);
Packit 971217
  attribs[atti] = EGL_NONE;
Packit 971217
Packit 971217
  for (i = 0; i < atti; i++)
Packit 971217
    GST_LOG ("attr %i: %" G_GINTPTR_FORMAT, i, attribs[i]);
Packit 971217
Packit 971217
  g_assert (atti == 12);
Packit 971217
Packit 971217
  img = _gst_egl_image_create (context, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
Packit 971217
  if (!img) {
Packit 971217
    GST_WARNING ("eglCreateImage failed: %s",
Packit 971217
        gst_egl_get_error_string (eglGetError ()));
Packit 971217
    return NULL;
Packit 971217
  }
Packit 971217
Packit 971217
  return gst_egl_image_new_wrapped (context, img, format, NULL,
Packit 971217
      (GstEGLImageDestroyNotify) _destroy_egl_image);
Packit 971217
}
Packit 971217
Packit 971217
gboolean
Packit 971217
gst_egl_image_export_dmabuf (GstEGLImage * image, int *fd, gint * stride,
Packit 971217
    gsize * offset)
Packit 971217
{
Packit 971217
  EGLBoolean (*gst_eglExportDMABUFImageQueryMESA) (EGLDisplay dpy,
Packit 971217
      EGLImageKHR image, int *fourcc, int *num_planes,
Packit 971217
      EGLuint64KHR * modifiers);
Packit 971217
  EGLBoolean (*gst_eglExportDMABUFImageMESA) (EGLDisplay dpy, EGLImageKHR image,
Packit 971217
      int *fds, EGLint * strides, EGLint * offsets);
Packit 971217
  GstGLDisplayEGL *display_egl;
Packit 971217
  EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
Packit 971217
  int num_planes = 0;
Packit 971217
  int egl_fd = 0;
Packit 971217
  EGLint egl_stride = 0;
Packit 971217
  EGLint egl_offset = 0;
Packit 971217
Packit 971217
  gst_eglExportDMABUFImageQueryMESA =
Packit 971217
      gst_gl_context_get_proc_address (image->context,
Packit 971217
      "eglExportDMABUFImageQueryMESA");
Packit 971217
  gst_eglExportDMABUFImageMESA =
Packit 971217
      gst_gl_context_get_proc_address (image->context,
Packit 971217
      "eglExportDMABUFImageMESA");
Packit 971217
Packit 971217
  if (!gst_eglExportDMABUFImageQueryMESA || !gst_eglExportDMABUFImageMESA)
Packit 971217
    return FALSE;
Packit 971217
Packit 971217
  display_egl =
Packit 971217
      (GstGLDisplayEGL *) gst_gl_display_egl_from_gl_display (image->
Packit 971217
      context->display);
Packit 971217
  if (!display_egl) {
Packit 971217
    GST_WARNING_OBJECT (image->context,
Packit 971217
        "Failed to retrieve GstGLDisplayEGL from %" GST_PTR_FORMAT,
Packit 971217
        image->context->display);
Packit 971217
    return FALSE;
Packit 971217
  }
Packit 971217
  egl_display =
Packit 971217
      (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
Packit 971217
  gst_object_unref (display_egl);
Packit 971217
Packit 971217
  if (!gst_eglExportDMABUFImageQueryMESA (egl_display, image->image,
Packit 971217
          NULL, &num_planes, NULL))
Packit 971217
    return FALSE;
Packit 971217
Packit 971217
  /* Don't allow multi-plane dmabufs */
Packit 971217
  if (num_planes > 1)
Packit 971217
    return FALSE;
Packit 971217
Packit 971217
  if (!gst_eglExportDMABUFImageMESA (egl_display, image->image, &egl_fd,
Packit 971217
          &egl_stride, &egl_offset))
Packit 971217
    return FALSE;
Packit 971217
Packit 971217
  *fd = egl_fd;
Packit 971217
  *stride = egl_stride;
Packit 971217
  *offset = egl_offset;
Packit 971217
Packit 971217
  return TRUE;
Packit 971217
}
Packit 971217
Packit 971217
#endif /* GST_GL_HAVE_DMABUF */