EGLDisplay gst_egl_image_memory_get_display (GstMemory * mem) { g_return_val_if_fail (gst_is_egl_image_memory (mem), NULL); if (mem->parent) mem = mem->parent; return GST_EGL_IMAGE_MEMORY (mem)->context->egl_display; }
EGLImageKHR gst_egl_image_memory_get_image (GstMemory * mem) { g_return_val_if_fail (gst_is_egl_image_memory (mem), EGL_NO_IMAGE_KHR); if (mem->parent) mem = mem->parent; return GST_EGL_IMAGE_MEMORY (mem)->image; }
GstEGLDisplay * gst_egl_image_memory_get_display (GstMemory * mem) { g_return_val_if_fail (gst_is_egl_image_memory (mem), EGL_NO_IMAGE_KHR); if (mem->parent) mem = mem->parent; return gst_egl_display_ref (GST_EGL_IMAGE_MEMORY (mem)->display); }
void gst_egl_image_memory_set_orientation (GstMemory * mem, GstVideoGLTextureOrientation orientation) { g_return_if_fail (gst_is_egl_image_memory (mem)); if (mem->parent) mem = mem->parent; GST_EGL_IMAGE_MEMORY (mem)->orientation = orientation; }
GstVideoGLTextureOrientation gst_egl_image_memory_get_orientation (GstMemory * mem) { g_return_val_if_fail (gst_is_egl_image_memory (mem), GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL); if (mem->parent) mem = mem->parent; return GST_EGL_IMAGE_MEMORY (mem)->orientation; }
GstEGLImageType gst_egl_image_memory_get_type (GstMemory * mem) { g_return_val_if_fail (gst_is_egl_image_memory (mem), GST_EGL_IMAGE_MEMORY_TYPE_INVALID); if (mem->parent) mem = mem->parent; return GST_EGL_IMAGE_MEMORY (mem)->type; }
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 }; if (gst_buffer_n_memory (meta->buffer) != 1) return default_unmap_video (meta, plane, info); gmem = gst_buffer_peek_memory (meta->buffer, 0); if (strcmp (gmem->allocator->mem_type, GST_EGL_IMAGE_MEMORY_NAME) != 0) return default_unmap_video (meta, plane, info); mem = GST_EGL_IMAGE_MEMORY ((gmem->parent ? gmem->parent : 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; }
static gboolean gst_eglimage_to_gl_texture_upload_meta (GstVideoGLTextureUploadMeta * meta, guint texture_id[4]) { gint i = 0; gint n = 0; g_return_val_if_fail (meta != NULL, FALSE); g_return_val_if_fail (texture_id != NULL, FALSE); GST_DEBUG ("Uploading for meta with textures %i,%i,%i,%i", texture_id[0], texture_id[1], texture_id[2], texture_id[3]); n = gst_buffer_n_memory (meta->buffer); for (i = 0; i < n; i++) { GstMemory *mem = gst_buffer_peek_memory (meta->buffer, i); const GstGLFuncs *gl = NULL; if (!gst_is_egl_image_memory (mem)) { GST_WARNING ("memory %p does not hold an EGLImage", mem); return FALSE; } gl = GST_GL_CONTEXT (GST_EGL_IMAGE_MEMORY (mem)->context)->gl_vtable; gl->ActiveTexture (GL_TEXTURE0 + i); gl->BindTexture (GL_TEXTURE_2D, texture_id[i]); gl->EGLImageTargetTexture2D (GL_TEXTURE_2D, gst_egl_image_memory_get_image (mem)); } if (GST_IS_GL_BUFFER_POOL (meta->buffer->pool)) gst_gl_buffer_pool_replace_last_buffer (GST_GL_BUFFER_POOL (meta-> buffer->pool), meta->buffer); return TRUE; }
static gboolean eglimage_video_map (GstVideoMeta * meta, guint plane, GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags) { GstMemory *gmem; GstEGLImageMemory *mem; GstVideoInfo vinfo; if (gst_buffer_n_memory (meta->buffer) != 1) return default_map_video (meta, plane, info, data, stride, flags); gmem = gst_buffer_peek_memory (meta->buffer, 0); if (strcmp (gmem->allocator->mem_type, GST_EGL_IMAGE_MEMORY_NAME) != 0) return default_map_video (meta, plane, info, data, stride, flags); mem = GST_EGL_IMAGE_MEMORY ((gmem->parent ? gmem->parent : 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 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 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; }