mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-09 05:38:58 +00:00
eglglessink: Add support for allocating EGLImages on Mali
This allows to decoders and other upstream elements to do zero-copy to the sink.
This commit is contained in:
parent
21d9fe45e4
commit
4df3e56c9a
4 changed files with 1983 additions and 516 deletions
File diff suppressed because it is too large
Load diff
|
@ -56,6 +56,8 @@
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES2/gl2ext.h>
|
||||||
|
|
||||||
|
#include "video_platform_wrapper.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
#define GST_TYPE_EGLGLESSINK \
|
#define GST_TYPE_EGLGLESSINK \
|
||||||
(gst_eglglessink_get_type())
|
(gst_eglglessink_get_type())
|
||||||
|
@ -124,9 +126,9 @@ struct _GstEglGlesRenderContext
|
||||||
EGLNativeWindowType window, used_window;
|
EGLNativeWindowType window, used_window;
|
||||||
EGLSurface surface;
|
EGLSurface surface;
|
||||||
gboolean buffer_preserved;
|
gboolean buffer_preserved;
|
||||||
GLuint fragshader[3]; /* frame, border, frame-platform */
|
GLuint fragshader[2]; /* frame, border */
|
||||||
GLuint vertshader[3]; /* frame, border, frame-platform */
|
GLuint vertshader[2]; /* frame, border */
|
||||||
GLuint glslprogram[3]; /* frame, border, frame-platform */
|
GLuint glslprogram[2]; /* frame, border */
|
||||||
GLuint texture[3]; /* RGB/Y, U/UV, V */
|
GLuint texture[3]; /* RGB/Y, U/UV, V */
|
||||||
EGLint surface_width;
|
EGLint surface_width;
|
||||||
EGLint surface_height;
|
EGLint surface_height;
|
||||||
|
@ -135,13 +137,19 @@ struct _GstEglGlesRenderContext
|
||||||
gint n_textures;
|
gint n_textures;
|
||||||
|
|
||||||
/* shader vars */
|
/* shader vars */
|
||||||
GLuint position_loc[3]; /* frame, border, frame-platform */
|
GLuint position_loc[2]; /* frame, border */
|
||||||
GLuint texpos_loc[2]; /* frame, frame-platform */
|
GLuint texpos_loc[2]; /* frame */
|
||||||
GLuint tex_scale_loc[2][3]; /* [frame, frame-platform] RGB/Y, U/UV, V */
|
GLuint tex_scale_loc[1][3]; /* [frame] RGB/Y, U/UV, V */
|
||||||
GLuint tex_loc[2][3]; /* [frame, frame-platform] RGB/Y, U/UV, V */
|
GLuint tex_loc[1][3]; /* [frame] RGB/Y, U/UV, V */
|
||||||
coord5 position_array[12]; /* 4 x Frame, 4 x Border1, 4 x Border2 */
|
coord5 position_array[12]; /* 4 x Frame, 4 x Border1, 4 x Border2 */
|
||||||
unsigned short index_array[4];
|
unsigned short index_array[4];
|
||||||
unsigned int position_buffer, index_buffer;
|
unsigned int position_buffer, index_buffer;
|
||||||
|
|
||||||
|
gboolean can_map_eglimage;
|
||||||
|
GstMemoryMapFunction eglimage_map;
|
||||||
|
GstMemoryUnmapFunction eglimage_unmap;
|
||||||
|
PlatformMapVideo eglimage_video_map;
|
||||||
|
PlatformUnmapVideo eglimage_video_unmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -201,6 +209,7 @@ struct _GstEglGlesSink
|
||||||
GstCaps *current_caps, *configured_caps;
|
GstCaps *current_caps, *configured_caps;
|
||||||
GstVideoInfo configured_info;
|
GstVideoInfo configured_info;
|
||||||
gfloat stride[3];
|
gfloat stride[3];
|
||||||
|
GstBufferPool *pool;
|
||||||
|
|
||||||
GstEglGlesImageFmt *selected_fmt;
|
GstEglGlesImageFmt *selected_fmt;
|
||||||
GstEglGlesRenderContext eglglesctx;
|
GstEglGlesRenderContext eglglesctx;
|
||||||
|
|
|
@ -47,10 +47,13 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EGL_EGLEXT_PROTOTYPES
|
#define EGL_EGLEXT_PROTOTYPES
|
||||||
|
#define GL_GLEXT_PROTOTYPES
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
|
#include <GLES2/gl2ext.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include "video_platform_wrapper.h"
|
#include "video_platform_wrapper.h"
|
||||||
|
@ -70,6 +73,7 @@ platform_wrapper_init (void)
|
||||||
|
|
||||||
#ifdef USE_EGL_X11
|
#ifdef USE_EGL_X11
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include <gst/video/gstvideopool.h>
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -118,10 +122,45 @@ platform_destroy_native_window (EGLNativeDisplayType display,
|
||||||
*window_data = NULL;
|
*window_data = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_can_map_eglimage (GstMemoryMapFunction * map,
|
||||||
|
GstMemoryUnmapFunction * unmap, PlatformMapVideo * video_map,
|
||||||
|
PlatformUnmapVideo * video_unmap)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_has_custom_eglimage_alloc (void)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_alloc_eglimage (EGLDisplay display, EGLContext context, GLint format,
|
||||||
|
GLint type, gint width, gint height, GLuint tex_id, EGLImageKHR * image,
|
||||||
|
gpointer * image_platform_data)
|
||||||
|
{
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id,
|
||||||
|
EGLImageKHR * image, gpointer * image_platform_data)
|
||||||
|
{
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_EGL_MALI_FB
|
#ifdef USE_EGL_MALI_FB
|
||||||
#include <EGL/fbdev_window.h>
|
#include <EGL/fbdev_window.h>
|
||||||
|
#include <mali_egl_image.h>
|
||||||
|
#include <ump/ump.h>
|
||||||
|
#include <ump/ump_ref_drv.h>
|
||||||
|
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
EGLNativeWindowType
|
EGLNativeWindowType
|
||||||
platform_create_native_window (gint width, gint height, gpointer * window_data)
|
platform_create_native_window (gint width, gint height, gpointer * window_data)
|
||||||
|
@ -142,9 +181,438 @@ platform_destroy_native_window (EGLNativeDisplayType display,
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
eglimage_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
|
||||||
|
{
|
||||||
|
GstEGLImageMemory *mem;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (strcmp (gmem->allocator->mem_type,
|
||||||
|
GST_EGL_IMAGE_MEMORY_NAME) == 0, FALSE);
|
||||||
|
|
||||||
|
mem = GST_EGL_IMAGE_MEMORY (gmem);
|
||||||
|
|
||||||
|
g_mutex_lock (&mem->lock);
|
||||||
|
for (i = 0; i < mem->n_textures; i++) {
|
||||||
|
if (mem->memory_refcount[i]) {
|
||||||
|
/* Only multiple READ maps are allowed */
|
||||||
|
if ((mem->memory_flags[i] & GST_MAP_WRITE)) {
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mem->mapped_memory_refcount) {
|
||||||
|
EGLint attribs[] = {
|
||||||
|
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||||
|
MALI_EGL_IMAGE_ACCESS_MODE, MALI_EGL_IMAGE_ACCESS_READ_ONLY,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
GstVideoInfo info;
|
||||||
|
mali_egl_image *mali_egl_image;
|
||||||
|
guint8 *plane_memory, *p;
|
||||||
|
gint stride, h;
|
||||||
|
gint j;
|
||||||
|
|
||||||
|
gst_video_info_set_format (&info, mem->format, mem->width, mem->height);
|
||||||
|
|
||||||
|
mem->mapped_memory = g_malloc (mem->parent.size);
|
||||||
|
|
||||||
|
for (i = 0; i < mem->n_textures; i++) {
|
||||||
|
mali_egl_image = mali_egl_image_lock_ptr (mem->image[i]);
|
||||||
|
if (!mali_egl_image) {
|
||||||
|
g_free (mem->mapped_memory);
|
||||||
|
GST_ERROR ("Failed to lock Mali EGL image: 0x%04x",
|
||||||
|
mali_egl_image_get_error ());
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
plane_memory = mali_egl_image_map_buffer (mali_egl_image, attribs);
|
||||||
|
if (!plane_memory) {
|
||||||
|
mali_egl_image_unlock_ptr (mem->image[i]);
|
||||||
|
g_free (mem->mapped_memory);
|
||||||
|
GST_ERROR ("Failed to lock Mali map image: 0x%04x",
|
||||||
|
mali_egl_image_get_error ());
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ((guint8 *) mem->mapped_memory) + mem->offset[i];
|
||||||
|
stride = mem->stride[i];
|
||||||
|
h = GST_VIDEO_INFO_COMP_HEIGHT (&info, i);
|
||||||
|
for (j = 0; j < h; j++) {
|
||||||
|
memcpy (p, plane_memory, stride);
|
||||||
|
p += mem->stride[i];
|
||||||
|
plane_memory += mem->stride[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
mali_egl_image_unmap_buffer (mem->image[i], attribs);
|
||||||
|
mali_egl_image_unlock_ptr (mem->image[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Only multiple READ maps are allowed */
|
||||||
|
if ((mem->mapped_memory_flags & GST_MAP_WRITE)) {
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mem->mapped_memory_refcount++;
|
||||||
|
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
|
||||||
|
return mem->mapped_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eglimage_unmap (GstMemory * gmem)
|
||||||
|
{
|
||||||
|
GstEGLImageMemory *mem;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
g_return_if_fail (strcmp (gmem->allocator->mem_type,
|
||||||
|
GST_EGL_IMAGE_MEMORY_NAME) == 0);
|
||||||
|
|
||||||
|
mem = GST_EGL_IMAGE_MEMORY (gmem);
|
||||||
|
g_return_if_fail (mem->mapped_memory);
|
||||||
|
|
||||||
|
g_mutex_lock (&mem->lock);
|
||||||
|
|
||||||
|
mem->mapped_memory_refcount--;
|
||||||
|
if (mem->mapped_memory_refcount > 0) {
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write back */
|
||||||
|
if ((mem->mapped_memory_flags & GST_MAP_WRITE)) {
|
||||||
|
EGLint attribs[] = {
|
||||||
|
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||||
|
MALI_EGL_IMAGE_ACCESS_MODE, MALI_EGL_IMAGE_ACCESS_WRITE_ONLY,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
GstVideoInfo info;
|
||||||
|
mali_egl_image *mali_egl_image;
|
||||||
|
guint8 *plane_memory, *p;
|
||||||
|
gint stride, h;
|
||||||
|
gint j;
|
||||||
|
|
||||||
|
gst_video_info_set_format (&info, mem->format, mem->width, mem->height);
|
||||||
|
|
||||||
|
for (i = 0; i < mem->n_textures; i++) {
|
||||||
|
mali_egl_image = mali_egl_image_lock_ptr (mem->image[i]);
|
||||||
|
if (!mali_egl_image) {
|
||||||
|
g_free (mem->mapped_memory);
|
||||||
|
GST_ERROR ("Failed to lock Mali EGL image: 0x%04x",
|
||||||
|
mali_egl_image_get_error ());
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
plane_memory = mali_egl_image_map_buffer (mali_egl_image, attribs);
|
||||||
|
if (!plane_memory) {
|
||||||
|
mali_egl_image_unlock_ptr (mem->image[i]);
|
||||||
|
g_free (mem->mapped_memory);
|
||||||
|
GST_ERROR ("Failed to lock Mali map image: 0x%04x",
|
||||||
|
mali_egl_image_get_error ());
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = ((guint8 *) mem->mapped_memory) + mem->offset[i];
|
||||||
|
stride = mem->stride[i];
|
||||||
|
h = GST_VIDEO_INFO_COMP_HEIGHT (&info, i);
|
||||||
|
for (j = 0; j < h; j++) {
|
||||||
|
memcpy (plane_memory, p, stride);
|
||||||
|
p += mem->stride[i];
|
||||||
|
plane_memory += mem->stride[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
mali_egl_image_unmap_buffer (mem->image[i], attribs);
|
||||||
|
mali_egl_image_unlock_ptr (mem->image[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_free (mem->mapped_memory);
|
||||||
|
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
eglimage_video_map (GstVideoMeta * meta, guint plane,
|
||||||
|
GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
|
||||||
|
{
|
||||||
|
GstMemory *gmem;
|
||||||
|
GstEGLImageMemory *mem;
|
||||||
|
GstVideoInfo vinfo;
|
||||||
|
|
||||||
|
g_return_val_if_fail (gst_buffer_n_memory (meta->buffer) == 1, FALSE);
|
||||||
|
|
||||||
|
gmem = gst_buffer_peek_memory (meta->buffer, 0);
|
||||||
|
g_return_val_if_fail (strcmp (gmem->allocator->mem_type,
|
||||||
|
GST_EGL_IMAGE_MEMORY_NAME) == 0, FALSE);
|
||||||
|
|
||||||
|
mem = GST_EGL_IMAGE_MEMORY (gmem);
|
||||||
|
|
||||||
|
g_mutex_lock (&mem->lock);
|
||||||
|
if (mem->format == GST_VIDEO_FORMAT_YV12) {
|
||||||
|
if (plane == 1)
|
||||||
|
plane = 2;
|
||||||
|
else if (plane == 2)
|
||||||
|
plane = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mem->mapped_memory_refcount) {
|
||||||
|
/* Only multiple READ maps are allowed */
|
||||||
|
if ((mem->mapped_memory_flags & GST_MAP_WRITE)) {
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mem->memory_refcount[plane]) {
|
||||||
|
EGLint attribs[] = {
|
||||||
|
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||||
|
MALI_EGL_IMAGE_ACCESS_MODE, MALI_EGL_IMAGE_ACCESS_READ_WRITE,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((flags & GST_MAP_READ) && (flags & GST_MAP_WRITE))
|
||||||
|
attribs[3] = MALI_EGL_IMAGE_ACCESS_READ_WRITE;
|
||||||
|
else if ((flags & GST_MAP_READ))
|
||||||
|
attribs[3] = MALI_EGL_IMAGE_ACCESS_READ_ONLY;
|
||||||
|
else if ((flags & GST_MAP_WRITE))
|
||||||
|
attribs[3] = MALI_EGL_IMAGE_ACCESS_WRITE_ONLY;
|
||||||
|
|
||||||
|
mem->memory_platform_data[plane] =
|
||||||
|
mali_egl_image_lock_ptr (mem->image[plane]);
|
||||||
|
if (!mem->memory_platform_data[plane]) {
|
||||||
|
GST_ERROR ("Failed to lock Mali EGL image: 0x%04x",
|
||||||
|
mali_egl_image_get_error ());
|
||||||
|
goto map_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem->memory[plane] =
|
||||||
|
mali_egl_image_map_buffer (mem->memory_platform_data[plane], attribs);
|
||||||
|
if (!mem->memory[plane])
|
||||||
|
goto map_error;
|
||||||
|
|
||||||
|
mem->memory_flags[plane] = flags;
|
||||||
|
} else {
|
||||||
|
/* Only multiple READ maps are allowed */
|
||||||
|
if ((mem->memory_flags[plane] & GST_MAP_WRITE)) {
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mem->memory_refcount[plane]++;
|
||||||
|
gst_video_info_set_format (&vinfo, mem->format, mem->width, mem->height);
|
||||||
|
|
||||||
|
*data = mem->memory[plane];
|
||||||
|
*stride = mem->stride[plane];
|
||||||
|
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
map_error:
|
||||||
|
{
|
||||||
|
EGLint attribs[] = {
|
||||||
|
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
GST_ERROR ("Failed to map Mali EGL image: 0x%04x",
|
||||||
|
mali_egl_image_get_error ());
|
||||||
|
|
||||||
|
if (mem->memory_platform_data[plane]) {
|
||||||
|
mali_egl_image_unmap_buffer (mem->image[plane], attribs);
|
||||||
|
mali_egl_image_unlock_ptr (mem->image[plane]);
|
||||||
|
}
|
||||||
|
mem->memory[plane] = NULL;
|
||||||
|
mem->memory_platform_data[plane] = NULL;
|
||||||
|
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
eglimage_video_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info)
|
||||||
|
{
|
||||||
|
GstMemory *gmem;
|
||||||
|
GstEGLImageMemory *mem;
|
||||||
|
EGLint attribs[] = {
|
||||||
|
MALI_EGL_IMAGE_PLANE, MALI_EGL_IMAGE_PLANE_Y,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
g_return_val_if_fail (gst_buffer_n_memory (meta->buffer) == 1, FALSE);
|
||||||
|
|
||||||
|
gmem = gst_buffer_peek_memory (meta->buffer, 0);
|
||||||
|
g_return_val_if_fail (strcmp (gmem->allocator->mem_type,
|
||||||
|
GST_EGL_IMAGE_MEMORY_NAME) == 0, FALSE);
|
||||||
|
mem = GST_EGL_IMAGE_MEMORY (gmem);
|
||||||
|
|
||||||
|
g_mutex_lock (&mem->lock);
|
||||||
|
if (mem->format == GST_VIDEO_FORMAT_YV12) {
|
||||||
|
if (plane == 1)
|
||||||
|
plane = 2;
|
||||||
|
else if (plane == 2)
|
||||||
|
plane = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mem->memory_refcount[plane]) {
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem->memory_refcount[plane]--;
|
||||||
|
if (mem->memory_refcount[plane] > 0) {
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unmaps automatically */
|
||||||
|
if (mem->memory_platform_data[plane]) {
|
||||||
|
mali_egl_image_unmap_buffer (mem->image[plane], attribs);
|
||||||
|
mali_egl_image_unlock_ptr (mem->image[plane]);
|
||||||
|
}
|
||||||
|
mem->memory[plane] = NULL;
|
||||||
|
mem->memory_platform_data[plane] = NULL;
|
||||||
|
|
||||||
|
g_mutex_unlock (&mem->lock);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_can_map_eglimage (GstMemoryMapFunction * map,
|
||||||
|
GstMemoryUnmapFunction * unmap, PlatformMapVideo * video_map,
|
||||||
|
PlatformUnmapVideo * video_unmap)
|
||||||
|
{
|
||||||
|
*map = eglimage_map;
|
||||||
|
*unmap = eglimage_unmap;
|
||||||
|
*video_map = eglimage_video_map;
|
||||||
|
*video_unmap = eglimage_video_unmap;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_has_custom_eglimage_alloc (void)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_alloc_eglimage (EGLDisplay display, EGLContext context, GLint format,
|
||||||
|
GLint type, gint width, gint height, GLuint tex_id, EGLImageKHR * image,
|
||||||
|
gpointer * image_platform_data)
|
||||||
|
{
|
||||||
|
fbdev_pixmap pixmap;
|
||||||
|
|
||||||
|
pixmap.flags = FBDEV_PIXMAP_SUPPORTS_UMP;
|
||||||
|
pixmap.width = width;
|
||||||
|
pixmap.height = height;
|
||||||
|
|
||||||
|
switch (format) {
|
||||||
|
case GL_LUMINANCE:
|
||||||
|
g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
|
||||||
|
pixmap.red_size = 0;
|
||||||
|
pixmap.green_size = 0;
|
||||||
|
pixmap.blue_size = 0;
|
||||||
|
pixmap.alpha_size = 0;
|
||||||
|
pixmap.luminance_size = 8;
|
||||||
|
break;
|
||||||
|
case GL_LUMINANCE_ALPHA:
|
||||||
|
g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
|
||||||
|
pixmap.red_size = 0;
|
||||||
|
pixmap.green_size = 0;
|
||||||
|
pixmap.blue_size = 0;
|
||||||
|
pixmap.alpha_size = 8;
|
||||||
|
pixmap.luminance_size = 8;
|
||||||
|
break;
|
||||||
|
case GL_RGB:
|
||||||
|
if (type == GL_UNSIGNED_BYTE) {
|
||||||
|
pixmap.red_size = 8;
|
||||||
|
pixmap.green_size = 8;
|
||||||
|
pixmap.blue_size = 8;
|
||||||
|
pixmap.alpha_size = 0;
|
||||||
|
pixmap.luminance_size = 0;
|
||||||
|
} else if (type == GL_UNSIGNED_SHORT_5_6_5) {
|
||||||
|
pixmap.red_size = 5;
|
||||||
|
pixmap.green_size = 6;
|
||||||
|
pixmap.blue_size = 5;
|
||||||
|
pixmap.alpha_size = 0;
|
||||||
|
pixmap.luminance_size = 0;
|
||||||
|
} else {
|
||||||
|
g_return_val_if_reached (FALSE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_RGBA:
|
||||||
|
g_return_val_if_fail (type == GL_UNSIGNED_BYTE, FALSE);
|
||||||
|
pixmap.red_size = 8;
|
||||||
|
pixmap.green_size = 8;
|
||||||
|
pixmap.blue_size = 8;
|
||||||
|
pixmap.alpha_size = 8;
|
||||||
|
pixmap.luminance_size = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap.buffer_size =
|
||||||
|
pixmap.red_size + pixmap.green_size + pixmap.blue_size +
|
||||||
|
pixmap.alpha_size + pixmap.luminance_size;
|
||||||
|
pixmap.bytes_per_pixel = pixmap.buffer_size / 8;
|
||||||
|
pixmap.format = 0;
|
||||||
|
|
||||||
|
if (ump_open () != UMP_OK) {
|
||||||
|
GST_ERROR ("Failed to open UMP");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap.data =
|
||||||
|
ump_ref_drv_allocate (GST_ROUND_UP_4 (pixmap.width) * pixmap.height *
|
||||||
|
pixmap.bytes_per_pixel, UMP_REF_DRV_CONSTRAINT_PHYSICALLY_LINEAR);
|
||||||
|
if (pixmap.data == UMP_INVALID_MEMORY_HANDLE) {
|
||||||
|
GST_ERROR ("Failed to allocate pixmap data via UMP");
|
||||||
|
ump_close ();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*image_platform_data = g_slice_dup (fbdev_pixmap, &pixmap);
|
||||||
|
*image =
|
||||||
|
eglCreateImageKHR (display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
|
||||||
|
(EGLClientBuffer) * image_platform_data, NULL);
|
||||||
|
if (!image) {
|
||||||
|
GST_ERROR ("Failed to create EGLImage for pixmap");
|
||||||
|
ump_reference_release ((ump_handle) pixmap.data);
|
||||||
|
ump_close ();
|
||||||
|
g_slice_free (fbdev_pixmap, *image_platform_data);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id,
|
||||||
|
EGLImageKHR * image, gpointer * image_platform_data)
|
||||||
|
{
|
||||||
|
fbdev_pixmap *pixmap = *image_platform_data;
|
||||||
|
|
||||||
|
eglDestroyImageKHR (display, *image);
|
||||||
|
ump_reference_release ((ump_handle) pixmap->data);
|
||||||
|
ump_close ();
|
||||||
|
g_slice_free (fbdev_pixmap, *image_platform_data);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_EGL_X11) && !defined(USE_EGL_MALI_FB)
|
#if !defined(USE_EGL_X11) && !defined(USE_EGL_MALI_FB)
|
||||||
|
#include <gst/video/gstvideopool.h>
|
||||||
|
|
||||||
/* Dummy functions for creating a native Window */
|
/* Dummy functions for creating a native Window */
|
||||||
EGLNativeWindowType
|
EGLNativeWindowType
|
||||||
platform_create_native_window (gint width, gint height, gpointer * window_data)
|
platform_create_native_window (gint width, gint height, gpointer * window_data)
|
||||||
|
@ -161,4 +629,33 @@ platform_destroy_native_window (EGLNativeDisplayType display,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_can_map_eglimage (GstMemoryMapFunction * map,
|
||||||
|
GstMemoryUnmapFunction * unmap, PlatformMapVideo * video_map,
|
||||||
|
PlatformUnmapVideo * video_unmap)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_has_custom_eglimage_alloc (void)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
platform_alloc_eglimage (EGLDisplay display, EGLContext context, GLint format,
|
||||||
|
GLint type, gint width, gint height, GLuint tex_id, EGLImageKHR * image,
|
||||||
|
gpointer * image_platform_data)
|
||||||
|
{
|
||||||
|
g_assert_not_reached ();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id,
|
||||||
|
EGLImageKHR * image, gpointer * image_platform_data)
|
||||||
|
{
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,6 +51,8 @@
|
||||||
#define __GST_ANDROID_VIDEO_PLATFORM_WRAPPER__
|
#define __GST_ANDROID_VIDEO_PLATFORM_WRAPPER__
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
#include <gst/video/gstvideometa.h>
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
gboolean platform_wrapper_init (void);
|
gboolean platform_wrapper_init (void);
|
||||||
|
@ -58,5 +60,44 @@ EGLNativeWindowType platform_create_native_window (gint width, gint height, gpoi
|
||||||
gboolean platform_destroy_native_window (EGLNativeDisplayType display,
|
gboolean platform_destroy_native_window (EGLNativeDisplayType display,
|
||||||
EGLNativeWindowType w, gpointer * window_data);
|
EGLNativeWindowType w, gpointer * window_data);
|
||||||
|
|
||||||
|
GstBufferPool *platform_create_buffer_pool (EGLDisplay display);
|
||||||
|
|
||||||
|
#define GST_EGL_IMAGE_MEMORY_NAME "GstEGLImage"
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GstMemory parent;
|
||||||
|
|
||||||
|
GstVideoFormat format;
|
||||||
|
gint width, height;
|
||||||
|
|
||||||
|
GMutex lock;
|
||||||
|
|
||||||
|
/* Always in order RGB/Y, UV/U, V */
|
||||||
|
EGLImageKHR image[3];
|
||||||
|
gpointer image_platform_data[3];
|
||||||
|
GLuint texture[3];
|
||||||
|
gint stride[3];
|
||||||
|
gsize offset[3];
|
||||||
|
guint n_textures;
|
||||||
|
|
||||||
|
gpointer memory[3];
|
||||||
|
gpointer memory_platform_data[3];
|
||||||
|
gint memory_refcount[3];
|
||||||
|
GstMapFlags memory_flags[3];
|
||||||
|
|
||||||
|
gpointer mapped_memory;
|
||||||
|
gint mapped_memory_refcount;
|
||||||
|
GstMapFlags mapped_memory_flags;
|
||||||
|
} GstEGLImageMemory;
|
||||||
|
|
||||||
|
#define GST_EGL_IMAGE_MEMORY(m) ((GstEGLImageMemory*)(m))
|
||||||
|
|
||||||
|
typedef gboolean (*PlatformMapVideo) (GstVideoMeta *meta, guint plane, GstMapInfo *info, gpointer *data, gint * stride, GstMapFlags flags);
|
||||||
|
typedef gboolean (*PlatformUnmapVideo) (GstVideoMeta *meta, guint plane, GstMapInfo *info);
|
||||||
|
|
||||||
|
gboolean platform_can_map_eglimage (GstMemoryMapFunction *map, GstMemoryUnmapFunction *unmap, PlatformMapVideo *video_map, PlatformUnmapVideo *video_unmap);
|
||||||
|
gboolean platform_has_custom_eglimage_alloc (void);
|
||||||
|
gboolean platform_alloc_eglimage (EGLDisplay display, EGLContext context, GLint format, GLint type, gint width, gint height, GLuint tex_id, EGLImageKHR *image, gpointer *image_platform_data);
|
||||||
|
void platform_free_eglimage (EGLDisplay display, EGLContext context, GLuint tex_id, EGLImageKHR *image, gpointer *image_platform_data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue