/*
 * GStreamer
 * Copyright (C) 2012 Collabora Ltd.
 *   @author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * Copyright (C) 2014 Julien Isorce <julien.isorce@gmail.com>
 * Copyright (C) 2016 Matthew Waters <matthew@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gsteglimage
 * @short_description: EGLImage abstraction
 * @title: GstEGLImage
 * @see_also: #GstGLMemoryEGL, #GstGLContext
 *
 * #GstEGLImage represents and holds an #EGLImage handle.
 *
 * A #GstEGLImage can be created from a dmabuf with gst_egl_image_from_dmabuf()
 * or #GstGLMemoryEGL provides a #GstAllocator to allocate #EGLImage's bound to
 * and OpenGL texture.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gsteglimage.h"

#include <string.h>

#include <gst/gl/gstglfeature.h>
#include <gst/gl/gstglmemory.h>

#include "gst/gl/egl/gstegl.h"
#include "gst/gl/egl/gstglcontext_egl.h"
#include "gst/gl/egl/gstgldisplay_egl.h"

#if GST_GL_HAVE_DMABUF
#include <gst/allocators/gstdmabuf.h>
#include <libdrm/drm_fourcc.h>

#ifndef DRM_FORMAT_R8
#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ')
#endif

#ifndef DRM_FORMAT_RG88
#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8')
#endif

#ifndef DRM_FORMAT_GR88
#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8')
#endif
#endif

#ifndef EGL_LINUX_DMA_BUF_EXT
#define EGL_LINUX_DMA_BUF_EXT 0x3270
#endif

#ifndef EGL_LINUX_DRM_FOURCC_EXT
#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
#endif

#ifndef EGL_DMA_BUF_PLANE0_FD_EXT
#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
#endif

#ifndef EGL_DMA_BUF_PLANE0_OFFSET_EXT
#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
#endif

#ifndef EGL_DMA_BUF_PLANE0_PITCH_EXT
#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
#endif

#if !GST_GL_HAVE_EGLUINT64KHR
typedef khronos_uint64_t EGLuint64KHR;
#endif

GST_DEFINE_MINI_OBJECT_TYPE (GstEGLImage, gst_egl_image);

#ifndef GST_DISABLE_GST_DEBUG
#define GST_CAT_DEFAULT gst_egl_image_ensure_debug_category()

static GstDebugCategory *
gst_egl_image_ensure_debug_category (void)
{
  static gsize cat_gonce = 0;

  if (g_once_init_enter (&cat_gonce)) {
    GstDebugCategory *cat = NULL;

    GST_DEBUG_CATEGORY_INIT (cat, "gleglimage", 0, "EGLImage wrapper");

    g_once_init_leave (&cat_gonce, (gsize) cat);
  }

  return (GstDebugCategory *) cat_gonce;
}
#endif /* GST_DISABLE_GST_DEBUG */

/**
 * gst_egl_image_get_image:
 * @image: a #GstEGLImage
 *
 * Returns: the #EGLImageKHR of @image
 */
gpointer
gst_egl_image_get_image (GstEGLImage * image)
{
  g_return_val_if_fail (GST_IS_EGL_IMAGE (image), EGL_NO_IMAGE_KHR);

  return image->image;
}

static void
_gst_egl_image_free_thread (GstGLContext * context, GstEGLImage * image)
{
  if (image->destroy_notify)
    image->destroy_notify (image, image->destroy_data);
}

static void
_gst_egl_image_free (GstMiniObject * object)
{
  GstEGLImage *image = GST_EGL_IMAGE (object);

  if (image->context) {
    gst_gl_context_thread_add (GST_GL_CONTEXT (image->context),
        (GstGLContextThreadFunc) _gst_egl_image_free_thread, image);
    gst_object_unref (image->context);
  }

  g_free (image);
}

static GstMiniObject *
_gst_egl_image_copy (GstMiniObject * obj)
{
  return gst_mini_object_ref (obj);
}

/**
 * gst_egl_image_new_wrapped:
 * @context: a #GstGLContext (must be an EGL context)
 * @image: the image to wrap
 * @format: the #GstGLFormat
 * @user_data: user data
 * @user_data_destroy: called when @user_data is no longer needed
 *
 * Returns: a new #GstEGLImage wrapping @image
 */
GstEGLImage *
gst_egl_image_new_wrapped (GstGLContext * context, gpointer image,
    GstGLFormat format, gpointer user_data,
    GstEGLImageDestroyNotify user_data_destroy)
{
  GstEGLImage *img = NULL;

  g_return_val_if_fail (context != NULL, NULL);
  g_return_val_if_fail ((gst_gl_context_get_gl_platform (context) &
          GST_GL_PLATFORM_EGL) != 0, NULL);
  g_return_val_if_fail (image != EGL_NO_IMAGE_KHR, NULL);

  img = g_new0 (GstEGLImage, 1);
  gst_mini_object_init (GST_MINI_OBJECT_CAST (img), 0, GST_TYPE_EGL_IMAGE,
      (GstMiniObjectCopyFunction) _gst_egl_image_copy, NULL,
      (GstMiniObjectFreeFunction) _gst_egl_image_free);

  img->context = gst_object_ref (context);
  img->image = image;
  img->format = format;

  img->destroy_data = user_data;
  img->destroy_notify = user_data_destroy;

  return img;
}

static EGLImageKHR
_gst_egl_image_create (GstGLContext * context, guint target,
    EGLClientBuffer buffer, guintptr * attribs)
{
  EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
  EGLContext egl_context = EGL_NO_CONTEXT;
  EGLImageKHR img = EGL_NO_IMAGE_KHR;
  GstGLDisplayEGL *display_egl;
  gint plat_major, plat_minor;
  guint attrib_len = 0;

  gst_gl_context_get_gl_platform_version (context, &plat_major, &plat_minor);

  display_egl = gst_gl_display_egl_from_gl_display (context->display);
  if (!display_egl) {
    GST_WARNING_OBJECT (context, "Failed to retrieve GstGLDisplayEGL from %"
        GST_PTR_FORMAT, context->display);
    return EGL_NO_IMAGE_KHR;
  }
  egl_display =
      (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
  gst_object_unref (display_egl);

  if (target != EGL_LINUX_DMA_BUF_EXT)
    egl_context = (EGLContext) gst_gl_context_get_gl_context (context);

  if (attribs)
    while (attribs[attrib_len++] != EGL_NONE) {
    }
#ifdef EGL_VERSION_1_5
  if (GST_GL_CHECK_GL_VERSION (plat_major, plat_minor, 1, 5)) {
    EGLImageKHR (*gst_eglCreateImage) (EGLDisplay dpy, EGLContext ctx,
        EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list);
    EGLAttrib *egl_attribs = NULL;
    guint i;

    gst_eglCreateImage = gst_gl_context_get_proc_address (context,
        "eglCreateImage");
    if (!gst_eglCreateImage) {
      GST_ERROR_OBJECT (context, "\"eglCreateImage\" not exposed by the "
          "implementation as required by EGL >= 1.5");
      return EGL_NO_IMAGE_KHR;
    }

    if (attribs) {
      egl_attribs = g_new0 (EGLAttrib, attrib_len);
      for (i = 0; i < attrib_len; i++)
        egl_attribs[i] = (EGLAttrib) attribs[i];
    }

    img = gst_eglCreateImage (egl_display, egl_context, target, buffer,
        egl_attribs);

    g_free (egl_attribs);
  } else
#endif
  {
    EGLImageKHR (*gst_eglCreateImageKHR) (EGLDisplay dpy, EGLContext ctx,
        EGLenum target, EGLClientBuffer buffer, const EGLint * attrib_list);
    EGLint *egl_attribs = NULL;
    gint i;

    gst_eglCreateImageKHR = gst_gl_context_get_proc_address (context,
        "eglCreateImageKHR");
    if (!gst_eglCreateImageKHR) {
      GST_WARNING_OBJECT (context, "\"eglCreateImageKHR\" not exposed by the "
          "implementation");
      return EGL_NO_IMAGE_KHR;
    }

    if (attribs) {
      egl_attribs = g_new0 (EGLint, attrib_len);
      for (i = 0; i < attrib_len; i++)
        egl_attribs[i] = (EGLint) attribs[i];
    }

    img = gst_eglCreateImageKHR (egl_display, egl_context, target, buffer,
        egl_attribs);

    g_free (egl_attribs);
  }

  return img;
}

static void
_gst_egl_image_destroy (GstGLContext * context, EGLImageKHR image)
{
  EGLBoolean (*gst_eglDestroyImage) (EGLDisplay dpy, EGLImageKHR image);
  EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
  GstGLDisplayEGL *display_egl;

  gst_eglDestroyImage = gst_gl_context_get_proc_address (context,
      "eglDestroyImage");
  if (!gst_eglDestroyImage) {
    gst_eglDestroyImage = gst_gl_context_get_proc_address (context,
        "eglDestroyImageKHR");
    if (!gst_eglDestroyImage) {
      GST_ERROR_OBJECT (context, "\"eglDestroyImage\" not exposed by the "
          "implementation");
      return;
    }
  }

  display_egl = gst_gl_display_egl_from_gl_display (context->display);
  if (!display_egl) {
    GST_WARNING_OBJECT (context, "Failed to retrieve GstGLDisplayEGL from %"
        GST_PTR_FORMAT, context->display);
    return;
  }
  egl_display =
      (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
  gst_object_unref (display_egl);

  if (!gst_eglDestroyImage (egl_display, image))
    GST_WARNING_OBJECT (context, "eglDestroyImage failed");
}

static void
_destroy_egl_image (GstEGLImage * image, gpointer user_data)
{
  _gst_egl_image_destroy (image->context, image->image);
}

/**
 * gst_egl_image_from_texture:
 * @context: a #GstGLContext (must be an EGL context)
 * @gl_mem: a #GstGLMemory
 * @attribs: additional attributes to add to the eglCreateImage() call.
 *
 * Returns: (transfer full): a #GstEGLImage wrapping @gl_mem or %NULL on failure
 */
GstEGLImage *
gst_egl_image_from_texture (GstGLContext * context, GstGLMemory * gl_mem,
    guintptr * attribs)
{
  EGLenum egl_target;
  EGLImageKHR img;

  if (gl_mem->tex_target != GST_GL_TEXTURE_TARGET_2D) {
    GST_FIXME_OBJECT (context, "Only know how to create EGLImage's from 2D "
        "textures");
    return NULL;
  }

  egl_target = EGL_GL_TEXTURE_2D_KHR;

  img = _gst_egl_image_create (context, egl_target,
      (EGLClientBuffer) (guintptr) gl_mem->tex_id, attribs);
  if (!img)
    return NULL;

  return gst_egl_image_new_wrapped (context, img, gl_mem->tex_format, NULL,
      (GstEGLImageDestroyNotify) _destroy_egl_image);
}

#if GST_GL_HAVE_DMABUF
/*
 * GStreamer format descriptions differ from DRM formats as the representation
 * is relative to a register, hence in native endianness. To reduce the driver
 * requirement, we only import with a subset of texture formats and use
 * shaders to convert. This way we avoid having to use external texture
 * target.
 */
static int
_drm_fourcc_from_info (GstVideoInfo * info, int plane)
{
  GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info);
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
  const gint rgba_fourcc = DRM_FORMAT_ABGR8888;
  const gint rgb_fourcc = DRM_FORMAT_BGR888;
  const gint rg_fourcc = DRM_FORMAT_GR88;
#else
  const gint rgba_fourcc = DRM_FORMAT_RGBA8888;
  const gint rgb_fourcc = DRM_FORMAT_RGB888;
  const gint rg_fourcc = DRM_FORMAT_RG88;
#endif

  GST_DEBUG ("Getting DRM fourcc for %s plane %i",
      gst_video_format_to_string (format), plane);

  switch (format) {
    case GST_VIDEO_FORMAT_RGB16:
    case GST_VIDEO_FORMAT_BGR16:
      return DRM_FORMAT_RGB565;

    case GST_VIDEO_FORMAT_RGB:
    case GST_VIDEO_FORMAT_BGR:
      return rgb_fourcc;

    case GST_VIDEO_FORMAT_RGBA:
    case GST_VIDEO_FORMAT_RGBx:
    case GST_VIDEO_FORMAT_BGRA:
    case GST_VIDEO_FORMAT_BGRx:
    case GST_VIDEO_FORMAT_ARGB:
    case GST_VIDEO_FORMAT_xRGB:
    case GST_VIDEO_FORMAT_ABGR:
    case GST_VIDEO_FORMAT_xBGR:
    case GST_VIDEO_FORMAT_AYUV:
      return rgba_fourcc;

    case GST_VIDEO_FORMAT_GRAY8:
      return DRM_FORMAT_R8;

    case GST_VIDEO_FORMAT_YUY2:
    case GST_VIDEO_FORMAT_UYVY:
    case GST_VIDEO_FORMAT_GRAY16_LE:
    case GST_VIDEO_FORMAT_GRAY16_BE:
      return rg_fourcc;

    case GST_VIDEO_FORMAT_NV12:
    case GST_VIDEO_FORMAT_NV21:
      return plane == 0 ? DRM_FORMAT_R8 : rg_fourcc;

    case GST_VIDEO_FORMAT_I420:
    case GST_VIDEO_FORMAT_YV12:
    case GST_VIDEO_FORMAT_Y41B:
    case GST_VIDEO_FORMAT_Y42B:
    case GST_VIDEO_FORMAT_Y444:
      return DRM_FORMAT_R8;

    default:
      GST_ERROR ("Unsupported format for DMABuf.");
      return -1;
  }
}

/*
 * From GStreamer 1.15
 * Variant of _drm_rgba_fourcc_from_info() that is used in case the GPU can
 * handle YUV formats directly (by using internal shaders, or hardwired
 * YUV->RGB conversion matrices etc.)
 */
static int
_drm_direct_fourcc_from_info (GstVideoInfo * info)
{
  GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info);

  GST_DEBUG ("Getting DRM fourcc for %s", gst_video_format_to_string (format));

  switch (format) {
    case GST_VIDEO_FORMAT_YUY2:
      return DRM_FORMAT_YUYV;

    case GST_VIDEO_FORMAT_YVYU:
      return DRM_FORMAT_YVYU;

    case GST_VIDEO_FORMAT_UYVY:
      return DRM_FORMAT_UYVY;

    case GST_VIDEO_FORMAT_VYUY:
      return DRM_FORMAT_VYUY;

    case GST_VIDEO_FORMAT_AYUV:
      return DRM_FORMAT_AYUV;

    case GST_VIDEO_FORMAT_NV12:
      return DRM_FORMAT_NV12;

    case GST_VIDEO_FORMAT_NV21:
      return DRM_FORMAT_NV21;

    case GST_VIDEO_FORMAT_NV16:
      return DRM_FORMAT_NV16;

    case GST_VIDEO_FORMAT_NV61:
      return DRM_FORMAT_NV61;

    case GST_VIDEO_FORMAT_NV24:
      return DRM_FORMAT_NV24;

    case GST_VIDEO_FORMAT_YUV9:
      return DRM_FORMAT_YUV410;

    case GST_VIDEO_FORMAT_YVU9:
      return DRM_FORMAT_YVU410;

    case GST_VIDEO_FORMAT_Y41B:
      return DRM_FORMAT_YUV411;

    case GST_VIDEO_FORMAT_I420:
      return DRM_FORMAT_YUV420;

    case GST_VIDEO_FORMAT_YV12:
      return DRM_FORMAT_YVU420;

    case GST_VIDEO_FORMAT_Y42B:
      return DRM_FORMAT_YUV422;

    case GST_VIDEO_FORMAT_Y444:
      return DRM_FORMAT_YUV444;

    case GST_VIDEO_FORMAT_RGB16:
      return DRM_FORMAT_RGB565;

    case GST_VIDEO_FORMAT_BGR16:
      return DRM_FORMAT_BGR565;

    case GST_VIDEO_FORMAT_RGBA:
      return DRM_FORMAT_ABGR8888;

    case GST_VIDEO_FORMAT_RGBx:
      return DRM_FORMAT_XBGR8888;

    case GST_VIDEO_FORMAT_BGRA:
      return DRM_FORMAT_ARGB8888;

    case GST_VIDEO_FORMAT_BGRx:
      return DRM_FORMAT_XRGB8888;

    case GST_VIDEO_FORMAT_ARGB:
      return DRM_FORMAT_BGRA8888;

    case GST_VIDEO_FORMAT_xRGB:
      return DRM_FORMAT_BGRX8888;

    case GST_VIDEO_FORMAT_ABGR:
      return DRM_FORMAT_RGBA8888;

    case GST_VIDEO_FORMAT_xBGR:
      return DRM_FORMAT_RGBX8888;

    case GST_VIDEO_FORMAT_RGB:
      return DRM_FORMAT_BGR888;

    default:
      GST_INFO ("Unsupported format for direct DMABuf.");
      return -1;
  }
}

/**
 * gst_egl_image_from_dmabuf:
 * @context: a #GstGLContext (must be an EGL context)
 * @dmabuf: the DMA-Buf file descriptor
 * @in_info: the #GstVideoInfo in @dmabuf
 * @plane: the plane in @in_info to create and #GstEGLImage for
 * @offset: the byte-offset in the data
 *
 * Returns: a #GstEGLImage wrapping @dmabuf or %NULL on failure
 */
GstEGLImage *
gst_egl_image_from_dmabuf (GstGLContext * context,
    gint dmabuf, GstVideoInfo * in_info, gint plane, gsize offset)
{
  GstGLFormat format;
  guintptr attribs[13];
  EGLImageKHR img;
  gint atti = 0;
  gint fourcc;
  gint i;

  fourcc = _drm_fourcc_from_info (in_info, plane);
  format = gst_gl_format_from_video_info (context, 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 (i = 0; i < atti; i++)
    GST_LOG ("attr %i: %" G_GINTPTR_FORMAT, i, attribs[i]);

  g_assert (atti == 12);

  img = _gst_egl_image_create (context, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
  if (!img) {
    GST_WARNING ("eglCreateImage failed: %s",
        gst_egl_get_error_string (eglGetError ()));
    return NULL;
  }

  return gst_egl_image_new_wrapped (context, img, format, NULL,
      (GstEGLImageDestroyNotify) _destroy_egl_image);
}

static int
_drm_fourcc_from_video_info (GstVideoInfo * info)
{
  GstVideoFormat fmt = GST_VIDEO_INFO_FORMAT (info);

  GST_DEBUG ("Getting DRM fourcc for %s",
      gst_video_format_to_string (fmt));

  if (GST_VIDEO_INFO_IS_YUV(info)) {
    gint fourcc;
    fourcc = gst_video_format_to_fourcc (fmt);

    /* gstreamer fourcc is not compatible with DRM FOURCC*/
    if(fmt == GST_VIDEO_FORMAT_I420)
      fourcc = DRM_FORMAT_YUV420;
    if(fmt == GST_VIDEO_FORMAT_YUY2)
      fourcc = DRM_FORMAT_YUYV;

    return fourcc;
  }

  switch (fmt) {
    case GST_VIDEO_FORMAT_RGB16:
      return DRM_FORMAT_RGB565;
    case GST_VIDEO_FORMAT_BGR16:
      return DRM_FORMAT_BGR565;
    case GST_VIDEO_FORMAT_RGBA:
      return DRM_FORMAT_ABGR8888;
    case GST_VIDEO_FORMAT_RGBx:
      return DRM_FORMAT_XBGR8888;
    case GST_VIDEO_FORMAT_BGRA:
      return DRM_FORMAT_ARGB8888;
    case GST_VIDEO_FORMAT_BGRx:
      return DRM_FORMAT_XRGB8888;
    case GST_VIDEO_FORMAT_ARGB:
      return DRM_FORMAT_BGRA8888;
    case GST_VIDEO_FORMAT_xRGB:
      return DRM_FORMAT_BGRX8888;
    case GST_VIDEO_FORMAT_ABGR:
      return DRM_FORMAT_RGBA8888;
    case GST_VIDEO_FORMAT_xBGR:
      return DRM_FORMAT_RGBX8888;

    default:
      GST_ERROR ("Unsupported format for DMABuf.");
      return -1;
  }
}

GstEGLImage *
gst_egl_image_from_dmabuf_singleplaner (GstGLContext * context,
    GstMemory ** mems, GstVideoInfo * in_info, gint n_planes, gsize * offset)
{
  gint fourcc;
  gint atti = 0;
  guint i;
  guintptr attribs[25];
  guintptr dmafd_flags[] = {
    EGL_DMA_BUF_PLANE0_FD_EXT,
    EGL_DMA_BUF_PLANE1_FD_EXT,
    EGL_DMA_BUF_PLANE2_FD_EXT
  };
  guintptr offset_flags[] = {
    EGL_DMA_BUF_PLANE0_OFFSET_EXT,
    EGL_DMA_BUF_PLANE1_OFFSET_EXT,
    EGL_DMA_BUF_PLANE2_OFFSET_EXT
  };
  guintptr pitch_flags[] = {
    EGL_DMA_BUF_PLANE0_PITCH_EXT,
    EGL_DMA_BUF_PLANE1_PITCH_EXT,
    EGL_DMA_BUF_PLANE2_PITCH_EXT
  };
  EGLImageKHR img = EGL_NO_IMAGE_KHR;

  fourcc = _drm_direct_fourcc_from_info (in_info);
  if (fourcc == -1)
    return NULL;

  GST_DEBUG ("fourcc %.4s (%d) n_planes %d (%dx%d)",
      (char *) &fourcc, fourcc, n_planes,
      GST_VIDEO_INFO_COMP_WIDTH (in_info, 0),
      GST_VIDEO_INFO_COMP_HEIGHT (in_info, 0));

  attribs[atti++] = EGL_WIDTH;
  attribs[atti++] = GST_VIDEO_INFO_WIDTH (in_info);
  attribs[atti++] = EGL_HEIGHT;
  attribs[atti++] = GST_VIDEO_INFO_HEIGHT (in_info);

  attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT;
  attribs[atti++] = fourcc;

  for (i = 0; i < n_planes; i++) {
    attribs[atti++] = dmafd_flags[i];
    attribs[atti++] = gst_dmabuf_memory_get_fd (mems[i]);
    attribs[atti++] = offset_flags[i];
    attribs[atti++] = offset[i];
    attribs[atti++] = pitch_flags[i];
    attribs[atti++] = GST_VIDEO_INFO_PLANE_STRIDE (in_info, i);
  }

  attribs[atti] = EGL_NONE;

  for (int i = 0; i < atti; i++)
    GST_LOG ("attr %i: %" G_GINTPTR_FORMAT, i, attribs[i]);

  g_assert (atti <= 25);

  img = _gst_egl_image_create (context, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);

  if (!img) {
    GST_WARNING ("eglCreateImage failed: %s",
        gst_egl_get_error_string (eglGetError ()));
    return NULL;
  }

  /* one texture for YUV format is treat as RGBA texture in imx GPU */
  return gst_egl_image_new_wrapped (context, img, GST_GL_RGBA,
      NULL, (GstEGLImageDestroyNotify) _destroy_egl_image);
}

gboolean
gst_egl_image_export_dmabuf (GstEGLImage * image, int *fd, gint * stride,
    gsize * offset)
{
  EGLBoolean (*gst_eglExportDMABUFImageQueryMESA) (EGLDisplay dpy,
      EGLImageKHR image, int *fourcc, int *num_planes,
      EGLuint64KHR * modifiers);
  EGLBoolean (*gst_eglExportDMABUFImageMESA) (EGLDisplay dpy, EGLImageKHR image,
      int *fds, EGLint * strides, EGLint * offsets);
  GstGLDisplayEGL *display_egl;
  EGLDisplay egl_display = EGL_DEFAULT_DISPLAY;
  int num_planes = 0;
  int egl_fd = 0;
  EGLint egl_stride = 0;
  EGLint egl_offset = 0;

  gst_eglExportDMABUFImageQueryMESA =
      gst_gl_context_get_proc_address (image->context,
      "eglExportDMABUFImageQueryMESA");
  gst_eglExportDMABUFImageMESA =
      gst_gl_context_get_proc_address (image->context,
      "eglExportDMABUFImageMESA");

  if (!gst_eglExportDMABUFImageQueryMESA || !gst_eglExportDMABUFImageMESA)
    return FALSE;

  display_egl =
      (GstGLDisplayEGL *) gst_gl_display_egl_from_gl_display (image->
      context->display);
  if (!display_egl) {
    GST_WARNING_OBJECT (image->context,
        "Failed to retrieve GstGLDisplayEGL from %" GST_PTR_FORMAT,
        image->context->display);
    return FALSE;
  }
  egl_display =
      (EGLDisplay) gst_gl_display_get_handle (GST_GL_DISPLAY (display_egl));
  gst_object_unref (display_egl);

  if (!gst_eglExportDMABUFImageQueryMESA (egl_display, image->image,
          NULL, &num_planes, NULL))
    return FALSE;

  /* Don't allow multi-plane dmabufs */
  if (num_planes > 1)
    return FALSE;

  if (!gst_eglExportDMABUFImageMESA (egl_display, image->image, &egl_fd,
          &egl_stride, &egl_offset))
    return FALSE;

  *fd = egl_fd;
  *stride = egl_stride;
  *offset = egl_offset;

  return TRUE;
}

#endif /* GST_GL_HAVE_DMABUF */
