tbm_format format;
gint i;
+ if (!vinfo) {
+ GST_ERROR ("invalid vinfo");
+ return NULL;
+ }
+
+ if (!tbm_surface_internal_is_valid (surface)) {
+ GST_ERROR ("Invalid tbm surface");
+ return NULL;
+ }
+
tmem = g_slice_new0 (GstTizenMemory);
/* Creates the tbm_surface with buffer objects. */
tmem->surface = tbm_surface_internal_create_with_flags (width, height, format, TBM_BO_NONCACHABLE);
}
- if (!tbm_surface_internal_is_valid (tmem->surface)) {
- GST_ERROR ("Invalid tbm surface");
- goto failed;
- }
-
tbm_surface_get_info (tmem->surface, &sinfo);
for (i = 0; i < sinfo.num_planes; i++) {
GST_VIDEO_INFO_PLANE_STRIDE (vinfo, i) = sinfo.planes[i].stride;
GST_VIDEO_INFO_PLANE_OFFSET (vinfo, i) = sinfo.planes[i].offset;
- GST_DEBUG ("tbm surface plane[%d] %p", i, sinfo.planes[i].ptr);
+ GST_DEBUG ("tbm surface plane[%d][%p]", i, sinfo.planes[i].ptr);
}
+
GST_VIDEO_INFO_SIZE (vinfo) = sinfo.size;
gst_memory_init (GST_MEMORY_CAST (tmem), GST_MEMORY_FLAG_NO_SHARE,
tmem->user_data = user_data;
g_mutex_init (&tmem->lock);
- GST_DEBUG ("%p: surface: %p size %" G_GSIZE_FORMAT, tmem, tmem->surface,
- tmem->mem.maxsize);
+ GST_DEBUG ("mem[%p], surface[%p], size[%" G_GSIZE_FORMAT"]",
+ tmem, tmem->surface, tmem->mem.maxsize);
return tmem;
+}
- /* ERRORS */
-failed:
- {
- GST_ERROR ("Failed to create tbm surface");
- g_slice_free (GstTizenMemory, tmem);
+static GstTizenMemory *
+_tizen_video_mem_new2 (GstAllocator * allocator, GstMemory * parent, GstVideoInfo * vinfo,
+ tbm_bo bo, gsize size, gpointer user_data, GDestroyNotify notify)
+{
+ int bo_size = tbm_bo_size (bo);
+ GstTizenMemory *tmem;
+
+ if (!vinfo) {
+ GST_ERROR ("invalid vinfo");
+ return NULL;
+ }
+
+ if (size > bo_size) {
+ GST_ERROR ("size[%"G_GSIZE_FORMAT"] can not exceed bo size[%d]",
+ size, bo_size);
return NULL;
}
+
+ bo = tbm_bo_ref (bo);
+ if (!bo) {
+ GST_ERROR ("invalid bo");
+ return NULL;
+ }
+
+ tmem = g_slice_new0 (GstTizenMemory);
+
+ gst_memory_init (GST_MEMORY_CAST (tmem), GST_MEMORY_FLAG_NO_SHARE,
+ allocator, parent, bo_size, 0, 0, size);
+
+ tmem->bo = bo;
+ tmem->info = gst_video_info_copy (vinfo);
+ tmem->notify = notify;
+ tmem->user_data = user_data;
+ GST_VIDEO_INFO_SIZE (tmem->info) = size;
+
+ g_mutex_init (&tmem->lock);
+
+ GST_DEBUG ("mem[%p], bo[%p], size[%" G_GSIZE_FORMAT"], max[%" G_GSIZE_FORMAT"]",
+ tmem, tmem->bo, tmem->mem.size, tmem->mem.maxsize);
+
+ return tmem;
}
static void
{
GstTizenMemory *tmem = (GstTizenMemory *) mem;
- tbm_surface_internal_unref (tmem->surface);
- GST_DEBUG ("free surface from mem : %p", tmem->surface);
+ if (tmem->bo) {
+ GST_DEBUG ("unref bo[%p] from mem[%p]", tmem->bo, tmem);
+ tbm_bo_unref (tmem->bo);
+ tmem->bo = NULL;
+ }
+
+ if (tmem->surface) {
+ GST_DEBUG ("unref surface[%p] from mem[%p]", tmem->surface, tmem);
+ tbm_surface_internal_unref (tmem->surface);
+ tmem->surface = NULL;
+ }
if (tmem->notify)
tmem->notify (tmem->user_data);
static gpointer
gst_tizen_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
{
- int err;
+ int tbm_ret;
+ int tbm_opt = 0;
+ gpointer data = NULL;
GstTizenMemory *tmem;
- tbm_surface_info_s info;
- gpointer data;
+ tbm_surface_info_s info = {0, };
+ tbm_bo_handle bo_handle = {NULL, };
tmem = (GstTizenMemory *)gmem;
+
g_mutex_lock (&tmem->lock);
- err = tbm_surface_map (tmem->surface, TBM_SURF_OPTION_WRITE|TBM_SURF_OPTION_READ, &info);
- if (err == TBM_SURFACE_ERROR_NONE) {
- data = info.planes[0].ptr;
+ if (tmem->surface) {
+ GST_DEBUG ("map surface[%p] in mem[%p]", tmem->surface, tmem);
+
+ if (flags & GST_MAP_READ)
+ tbm_opt |= TBM_SURF_OPTION_READ;
+ if (flags & GST_MAP_WRITE)
+ tbm_opt |= TBM_SURF_OPTION_WRITE;
+
+ tbm_ret = tbm_surface_map (tmem->surface, tbm_opt, &info);
+ if (tbm_ret != TBM_SURFACE_ERROR_NONE) {
+ GST_ERROR ("tbm_surface_map failed[0x%x]", tbm_ret);
+ goto done;
+ }
+
+ data = (gpointer) info.planes[0].ptr;
} else {
- GST_ERROR ("failed to get surface info");
- data = NULL;
- goto done;
+ GST_DEBUG ("map bo[%p] in mem[%p]", tmem->bo, tmem);
+
+ if (flags & GST_MAP_READ)
+ tbm_opt |= TBM_OPTION_READ;
+ if (flags & GST_MAP_WRITE)
+ tbm_opt |= TBM_OPTION_WRITE;
+
+ bo_handle = tbm_bo_map (tmem->bo, TBM_DEVICE_CPU, tbm_opt);
+ if (!bo_handle.ptr) {
+ GST_ERROR ("tbm_bo_map failed for bo[%p]", tmem->bo);
+ goto done;
+ }
+
+ data = (gpointer) bo_handle.ptr;
}
done:
tmem = (GstTizenMemory *)gmem;
g_mutex_lock (&tmem->lock);
- tbm_surface_unmap (tmem->surface);
+
+ if (tmem->surface) {
+ GST_DEBUG ("unmap surface[%p] in mem[%p]", tmem->surface, tmem);
+ tbm_surface_unmap (tmem->surface);
+ } else {
+ GST_DEBUG ("unmap bo[%p] in mem[%p]", tmem->bo, tmem);
+ tbm_bo_unmap (tmem->bo);
+ }
+
g_mutex_unlock (&tmem->lock);
}
static GstMemory *
gst_tizen_mem_share (GstMemory * gmem, gssize offset, gssize size)
{
+ GST_WARNING ("not supported");
return NULL;
}
static GstMemory *
gst_tizen_mem_copy (GstMemory * gmem, gssize offset, gsize size)
{
- gint i;
- GstMemory *copy;
- GstTizenMemory *tmem;
- tbm_surface_h new_surface, old_surface;
- tbm_format format;
- tbm_surface_info_s old_surface_info;
- tbm_surface_info_s new_surface_info;
+ gint i = 0;
+ GstMemory *copy = NULL;
+ GstTizenMemory *tmem = (GstTizenMemory *) gmem;
+
+ GST_DEBUG ("copy mem[%p], offset[%d], size[%"G_GSIZE_FORMAT"]",
+ tmem, offset, size);
+
+ if (tmem->surface) {
+ tbm_surface_h new_surface, old_surface;
+ tbm_format format;
+ tbm_surface_info_s old_surface_info;
+ tbm_surface_info_s new_surface_info;
+
+ old_surface = tmem->surface;
+ format = tbm_surface_get_format (old_surface);
+
+ copy = gst_tizen_allocator_alloc (gmem->allocator, tmem->info);
+ new_surface = gst_tizen_memory_get_surface (copy);
+
+ tbm_surface_get_info (old_surface, &old_surface_info);
+ tbm_surface_get_info (new_surface, &new_surface_info);
+
+ for (i = 0; i < tbm_surface_internal_get_num_planes (format); i++) {
+ memcpy (new_surface_info.planes[i].ptr,
+ old_surface_info.planes[i].ptr, new_surface_info.planes[i].size);
+ }
+ } else {
+ int old_size = tbm_bo_size (tmem->bo);
+ tbm_bo new_bo = NULL;
+ tbm_bo_handle old_handle = {NULL, };
+ tbm_bo_handle new_handle = {NULL, };
+ tbm_bufmgr bufmgr = NULL;
+
+ if (size > old_size - offset) {
+ GST_ERROR ("invalid size[%"G_GSIZE_FORMAT"] (offset[%"G_GSSIZE_FORMAT"],bo size[%d])",
+ size, offset, old_size);
+ goto _BO_COPY_OUT;
+ }
+
+ bufmgr = tbm_bufmgr_init (-1);
+ if (!bufmgr) {
+ GST_ERROR ("tbm bufmgr failed");
+ goto _BO_COPY_OUT;
+ }
+
+ new_bo = tbm_bo_alloc (bufmgr, tbm_bo_size (tmem->bo), TBM_BO_DEFAULT);
+ if (!new_bo) {
+ GST_ERROR ("tbm_bo_alloc failed");
+ goto _BO_COPY_OUT;
+ }
+
+ old_handle = tbm_bo_map (tmem->bo, TBM_DEVICE_CPU, TBM_OPTION_READ);
+ new_handle = tbm_bo_map (new_bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
+
+ if (!old_handle.ptr || !new_handle.ptr) {
+ GST_ERROR ("tbm bo map failed[old:%p,new:%p]",
+ old_handle.ptr, new_handle.ptr);
+ goto _BO_COPY_OUT;
+ }
- tmem = (GstTizenMemory *) gmem;
+ memcpy (new_handle.ptr, (char *) old_handle.ptr + offset, size);
- GST_DEBUG ("copy memory %p, offset %d, size : %u", tmem, offset, size);
+ copy = gst_tizen_allocator_alloc_bo (gmem->allocator,
+ tmem->info, new_bo, size, NULL, NULL);
- old_surface = tmem->surface;
- format = tbm_surface_get_format (old_surface);
+_BO_COPY_OUT:
+ if (old_handle.ptr)
+ tbm_bo_unmap (tmem->bo);
- copy = gst_tizen_allocator_alloc (gmem->allocator, tmem->info);
- new_surface = gst_tizen_memory_get_surface (copy);
+ if (new_handle.ptr)
+ tbm_bo_unmap (new_bo);
- tbm_surface_get_info (old_surface, &old_surface_info);
- tbm_surface_get_info (new_surface, &new_surface_info);
+ if (new_bo)
+ tbm_bo_unref (new_bo);
- for (i = 0; i < tbm_surface_internal_get_num_planes (format); i++) {
- memcpy (new_surface_info.planes[i].ptr,
- old_surface_info.planes[i].ptr, new_surface_info.planes[i].size);
+ if (bufmgr)
+ tbm_bufmgr_deinit (bufmgr);
}
return copy;
/**
* gst_tizen_allocator_alloc:
* @allocator: a #GstAllocator to use
- * @vinfo: a #GstVideoInfo to be refered for size and type of allocated memory
+ * @vinfo: a #GstVideoInfo to be referred for size and type of allocated memory
*
* Returns: (transfer full) (nullable): a new #GstMemory.
*/
/**
* gst_tizen_allocator_alloc_surface: (skip)
* @allocator: a #GstAllocator to use
- * @vinfo: a #GstVideoInfo to be refered for memory size and type
+ * @vinfo: a #GstVideoInfo to be referred for memory size and type
* @surface: a #tbm_surface_h to be used for allocated memory
* @user_data: (allow-none): user data pointer
* @notify: (allow-none) (closure user_data): called with @user_data when the memory is freed
return (GstMemory *)_tizen_video_mem_new (allocator, NULL, vinfo, surface, user_data, notify);
}
+/**
+ * gst_tizen_allocator_alloc_bo: (skip)
+ * @allocator: a #GstAllocator to use
+ * @vinfo: a #GstVideoInfo to be referred for memory size and type
+ * @bo: a #tbm_bo to be used for allocated memory
+ * @size: size of used memory in @bo, it should not be bigger than size of bo
+ * @user_data: (allow-none): user data pointer
+ * @notify: (allow-none) (closure user_data): called with @user_data when the memory is freed
+ *
+ * Returns: (transfer full) (nullable): a new #GstMemory.
+ */
+GstMemory *
+gst_tizen_allocator_alloc_bo (GstAllocator * allocator, GstVideoInfo * vinfo,
+ tbm_bo bo, gsize size, gpointer user_data, GDestroyNotify notify)
+{
+ g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (allocator), NULL);
+
+ return (GstMemory *)_tizen_video_mem_new2 (allocator, NULL, vinfo, bo, size, user_data, notify);
+}
+
gboolean
gst_is_tizen_memory (GstMemory * mem)
{
tmem = (GstTizenMemory *)mem;
- bo_num = tbm_surface_internal_get_num_bos(tmem->surface);
+ if (tmem->surface) {
+ bo_num = tbm_surface_internal_get_num_bos(tmem->surface);
+ if (bo_idx >= bo_num) {
+ GST_ERROR ("invalid idx[%d] for surface[bo_num:%d]", bo_idx, bo_num);
+ return NULL;
+ }
+
+ return tbm_surface_internal_get_bo(tmem->surface, bo_idx);
+ }
- if (bo_idx > bo_num) {
- GST_ERROR ("Failed to set set bo_idx");
+ if (bo_idx > 0) {
+ GST_ERROR ("invalid idx[%d] for bo", bo_idx);
return NULL;
}
- return tbm_surface_internal_get_bo(tmem->surface, bo_idx);
+ return tmem->bo;
}
void *
tmem = (GstTizenMemory *)mem;
+ GST_DEBUG ("surface[%p] in mem[%p]", tmem->surface, tmem);
+
return tmem->surface;
}
gpointer * data, gint * stride, GstMapFlags flags)
{
int tbm_ret = TBM_SURFACE_ERROR_NONE;
+ int tbm_opt = 0;
gboolean mapped = FALSE;
GstBuffer *buffer = meta->buffer;
- GstTizenMemory *vmem =
- (GstTizenMemory *) gst_buffer_get_memory (buffer, 0);
+ GstTizenMemory *tmem = (GstTizenMemory *) gst_buffer_get_memory (buffer, 0);
- g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (((GstMemory *) vmem)->allocator), FALSE);
+ g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (((GstMemory *) tmem)->allocator), FALSE);
- g_mutex_lock (&vmem->lock);
+ if (!tmem->surface || plane >= GST_VIDEO_MAX_PLANES) {
+ GST_ERROR ("invalid param[surface:%p,plane:%u]", tmem->surface, plane);
+ return FALSE;
+ }
+
+ g_mutex_lock (&tmem->lock);
- if (vmem->video_memory_map[plane]) {
- GST_ERROR ("[%p] plane [%d] is already mapped", buffer, plane);
+ if (tmem->video_memory_map[plane]) {
+ GST_ERROR ("buf[%p] plane[%d] is already mapped", buffer, plane);
goto _VIDEO_MEMORY_MAP_DONE;
}
- if (vmem->video_memory_map_count == 0) {
- tbm_ret = tbm_surface_map (vmem->surface,
- TBM_SURF_OPTION_WRITE | TBM_SURF_OPTION_READ,
- &vmem->surface_info);
+ if (tmem->video_memory_map_count == 0) {
+ if (flags & GST_MAP_READ)
+ tbm_opt |= TBM_SURF_OPTION_READ;
+ if (flags & GST_MAP_WRITE)
+ tbm_opt |= TBM_SURF_OPTION_WRITE;
+
+ tbm_ret = tbm_surface_map (tmem->surface, tbm_opt, &tmem->surface_info);
if (tbm_ret != TBM_SURFACE_ERROR_NONE) {
- GST_ERROR ("[%p] tbm_surface_map for %p failed, 0x%x", buffer, vmem->surface, tbm_ret);
+ GST_ERROR ("buf[%p] tbm_surface_map[%p] failed[0x%x]",
+ buffer, tmem->surface, tbm_ret);
goto _VIDEO_MEMORY_MAP_DONE;
}
}
- if (plane >= vmem->surface_info.num_planes) {
- GST_ERROR ("[%p] invalid plane index %d (num plane %d)",
- buffer, plane, vmem->surface_info.num_planes);
+ if (plane >= tmem->surface_info.num_planes) {
+ GST_ERROR ("buf[%p] invalid plane index[%d] (num plane[%d])",
+ buffer, plane, tmem->surface_info.num_planes);
- if (vmem->video_memory_map_count == 0) {
- GST_ERROR ("[%p] unmap surface %p", buffer, vmem->surface);
- tbm_surface_unmap (vmem->surface);
+ if (tmem->video_memory_map_count == 0) {
+ GST_ERROR ("buf[%p] unmap surface[%p]", buffer, tmem->surface);
+ tbm_surface_unmap (tmem->surface);
}
goto _VIDEO_MEMORY_MAP_DONE;
}
- *data = vmem->surface_info.planes[plane].ptr;
- *stride = vmem->surface_info.planes[plane].stride;
+ *data = tmem->surface_info.planes[plane].ptr;
+ *stride = tmem->surface_info.planes[plane].stride;
- vmem->video_memory_map[plane] = TRUE;
- vmem->video_memory_map_count++;
+ tmem->video_memory_map[plane] = TRUE;
+ tmem->video_memory_map_count++;
/* set map flags */
info->flags = flags;
- GST_DEBUG ("[%p] mapped plane %d, data %p, stride %d, flags 0x%x",
+ GST_DEBUG ("buf[%p] plane[%d], data[%p], stride[%d], flags[0x%x]",
buffer, plane, *data, *stride, info->flags);
mapped = TRUE;
_VIDEO_MEMORY_MAP_DONE:
- g_mutex_unlock (&vmem->lock);
+ g_mutex_unlock (&tmem->lock);
return mapped;
}
int tbm_ret = TBM_SURFACE_ERROR_NONE;
gboolean unmapped = FALSE;
GstBuffer *buffer = meta->buffer;
- GstTizenMemory *vmem =
- (GstTizenMemory *) gst_buffer_get_memory (buffer, 0);
+ GstTizenMemory *tmem = (GstTizenMemory *) gst_buffer_get_memory (buffer, 0);
+
+ g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (((GstMemory *) tmem)->allocator), FALSE);
- g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (((GstMemory *) vmem)->allocator), FALSE);
+ if (!tmem->surface) {
+ GST_ERROR ("no surface");
+ return FALSE;
+ }
- g_mutex_lock (&vmem->lock);
+ g_mutex_lock (&tmem->lock);
- if (vmem->video_memory_map[plane] == FALSE) {
- GST_ERROR ("[%p] plane %d is already unmapped", buffer, plane);
+ if (tmem->video_memory_map[plane] == FALSE) {
+ GST_ERROR ("buf[%p] plane[%d] is already unmapped",
+ buffer, plane);
goto _VIDEO_MEMORY_UNMAP_DONE;
}
- if (vmem->video_memory_map_count - 1 > 0) {
- GST_DEBUG ("[%p] plane %d skip unmap surface %p", buffer, plane, vmem->surface);
+ if (tmem->video_memory_map_count > 1) {
+ GST_DEBUG ("buf[%p] plane[%d] skip unmap surface[%p]",
+ buffer, plane, tmem->surface);
unmapped = TRUE;
goto _VIDEO_MEMORY_UNMAP_DONE;
}
- tbm_ret = tbm_surface_unmap (vmem->surface);
+ tbm_ret = tbm_surface_unmap (tmem->surface);
if (tbm_ret != TBM_SURFACE_ERROR_NONE) {
- GST_ERROR ("[%p] tbm_surface_unmap %p failed, 0x%x", buffer, vmem->surface, tbm_ret);
+ GST_ERROR ("buf[%p] tbm_surface_unmap[%p] failed[0x%x]",
+ buffer, tmem->surface, tbm_ret);
goto _VIDEO_MEMORY_UNMAP_DONE;
}
unmapped = TRUE;
- GST_DEBUG ("[%p] plane %d unmap surface %p done", buffer, plane, vmem->surface);
+ GST_DEBUG ("buf[%p] plane[%d] unmap surface[%p] done",
+ buffer, plane, tmem->surface);
_VIDEO_MEMORY_UNMAP_DONE:
if (unmapped == TRUE) {
- vmem->video_memory_map[plane] = FALSE;
- vmem->video_memory_map_count--;
+ tmem->video_memory_map[plane] = FALSE;
+ tmem->video_memory_map_count--;
}
- g_mutex_unlock (&vmem->lock);
+ g_mutex_unlock (&tmem->lock);
return unmapped;
}