mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 08:11:16 +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/gl2ext.h>
|
||||
|
||||
#include "video_platform_wrapper.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
#define GST_TYPE_EGLGLESSINK \
|
||||
(gst_eglglessink_get_type())
|
||||
|
@ -124,9 +126,9 @@ struct _GstEglGlesRenderContext
|
|||
EGLNativeWindowType window, used_window;
|
||||
EGLSurface surface;
|
||||
gboolean buffer_preserved;
|
||||
GLuint fragshader[3]; /* frame, border, frame-platform */
|
||||
GLuint vertshader[3]; /* frame, border, frame-platform */
|
||||
GLuint glslprogram[3]; /* frame, border, frame-platform */
|
||||
GLuint fragshader[2]; /* frame, border */
|
||||
GLuint vertshader[2]; /* frame, border */
|
||||
GLuint glslprogram[2]; /* frame, border */
|
||||
GLuint texture[3]; /* RGB/Y, U/UV, V */
|
||||
EGLint surface_width;
|
||||
EGLint surface_height;
|
||||
|
@ -135,13 +137,19 @@ struct _GstEglGlesRenderContext
|
|||
gint n_textures;
|
||||
|
||||
/* shader vars */
|
||||
GLuint position_loc[3]; /* frame, border, frame-platform */
|
||||
GLuint texpos_loc[2]; /* frame, frame-platform */
|
||||
GLuint tex_scale_loc[2][3]; /* [frame, frame-platform] RGB/Y, U/UV, V */
|
||||
GLuint tex_loc[2][3]; /* [frame, frame-platform] RGB/Y, U/UV, V */
|
||||
GLuint position_loc[2]; /* frame, border */
|
||||
GLuint texpos_loc[2]; /* frame */
|
||||
GLuint tex_scale_loc[1][3]; /* [frame] 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 */
|
||||
unsigned short index_array[4];
|
||||
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;
|
||||
GstVideoInfo configured_info;
|
||||
gfloat stride[3];
|
||||
GstBufferPool *pool;
|
||||
|
||||
GstEglGlesImageFmt *selected_fmt;
|
||||
GstEglGlesRenderContext eglglesctx;
|
||||
|
|
|
@ -47,10 +47,13 @@
|
|||
#endif
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include "video_platform_wrapper.h"
|
||||
|
@ -70,6 +73,7 @@ platform_wrapper_init (void)
|
|||
|
||||
#ifdef USE_EGL_X11
|
||||
#include <X11/Xlib.h>
|
||||
#include <gst/video/gstvideopool.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -118,10 +122,45 @@ platform_destroy_native_window (EGLNativeDisplayType display,
|
|||
*window_data = NULL;
|
||||
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
|
||||
|
||||
#ifdef USE_EGL_MALI_FB
|
||||
#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
|
||||
platform_create_native_window (gint width, gint height, gpointer * window_data)
|
||||
|
@ -142,9 +181,438 @@ platform_destroy_native_window (EGLNativeDisplayType display,
|
|||
|
||||
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
|
||||
|
||||
#if !defined(USE_EGL_X11) && !defined(USE_EGL_MALI_FB)
|
||||
#include <gst/video/gstvideopool.h>
|
||||
|
||||
/* Dummy functions for creating a native Window */
|
||||
EGLNativeWindowType
|
||||
platform_create_native_window (gint width, gint height, gpointer * window_data)
|
||||
|
@ -161,4 +629,33 @@ platform_destroy_native_window (EGLNativeDisplayType display,
|
|||
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
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#define __GST_ANDROID_VIDEO_PLATFORM_WRAPPER__
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
#include <gst/video/gstvideometa.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
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,
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue