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_VIDEO_INFO_SIZE (vinfo) = sinfo.size;
gst_tizen_video_memory_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
gpointer * data, gint * stride, GstMapFlags flags)
{
- gint err;
- tbm_surface_info_s surface_info;
+ int tbm_ret = TBM_SURFACE_ERROR_NONE;
+ gboolean mapped = FALSE;
GstBuffer *buffer = meta->buffer;
GstTizenMemory *vmem =
(GstTizenMemory *) gst_buffer_get_memory (buffer, 0);
g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (((GstMemory *) vmem)->allocator), FALSE);
- err = tbm_surface_map (vmem->surface, TBM_SURF_OPTION_WRITE|TBM_SURF_OPTION_READ, &surface_info);
- if (err == TBM_SURFACE_ERROR_NONE) {
- if (surface_info.num_planes > plane) {
- *data = surface_info.planes[plane].ptr;
- *stride = surface_info.planes[plane].stride;
- GST_DEBUG ("_video_memory_map -> plane : %d, data : %p, stride : %d",
- plane, *data, *stride);
- } else {
- GST_ERROR_OBJECT (meta, "invalid format");
- return FALSE;
+ g_mutex_lock (&vmem->lock);
+
+ if (vmem->video_memory_map[plane]) {
+ GST_ERROR ("plane [%d] is already mapped", 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 (tbm_ret != TBM_SURFACE_ERROR_NONE) {
+ GST_ERROR ("tbm_surface_map for %p failed, 0x%x", vmem->surface, tbm_ret);
+ goto _VIDEO_MEMORY_MAP_DONE;
+ }
+ }
+
+ if (plane >= vmem->surface_info.num_planes) {
+ GST_ERROR ("invalid plane index %d (num plane %d)",
+ plane, vmem->surface_info.num_planes);
+
+ if (vmem->video_memory_map_count == 0) {
+ GST_ERROR ("unmap surface %p", vmem->surface);
+ tbm_surface_unmap (vmem->surface);
}
+
+ goto _VIDEO_MEMORY_MAP_DONE;
}
- return TRUE;
+
+ *data = vmem->surface_info.planes[plane].ptr;
+ *stride = vmem->surface_info.planes[plane].stride;
+
+ GST_DEBUG ("mapped plane : %d, data : %p, stride : %d",
+ plane, *data, *stride);
+
+ vmem->video_memory_map[plane] = TRUE;
+ vmem->video_memory_map_count++;
+
+ mapped = TRUE;
+
+_VIDEO_MEMORY_MAP_DONE:
+ g_mutex_unlock (&vmem->lock);
+
+ return mapped;
}
gboolean
gst_tizen_video_memory_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info)
{
+ int tbm_ret = TBM_SURFACE_ERROR_NONE;
+ gboolean unmapped = FALSE;
GstBuffer *buffer = meta->buffer;
GstTizenMemory *vmem =
(GstTizenMemory *) gst_buffer_get_memory (buffer, 0);
g_return_val_if_fail (GST_IS_TIZEN_ALLOCATOR (((GstMemory *) vmem)->allocator), FALSE);
- tbm_surface_unmap (vmem->surface);
- GST_DEBUG ("_video_memory_unmap -> plane : %d", plane);
- return TRUE;
+ g_mutex_lock (&vmem->lock);
+
+ if (vmem->video_memory_map[plane] == FALSE) {
+ GST_ERROR ("plane [%d] is already unmapped", plane);
+ goto _VIDEO_MEMORY_UNMAP_DONE;
+ }
+
+ if (vmem->video_memory_map_count - 1 > 0) {
+ GST_DEBUG ("[plane %d] skip unmap surface %p", plane, vmem->surface);
+ unmapped = TRUE;
+ goto _VIDEO_MEMORY_UNMAP_DONE;
+ }
+
+ tbm_ret = tbm_surface_unmap (vmem->surface);
+ if (tbm_ret != TBM_SURFACE_ERROR_NONE) {
+ GST_ERROR ("tbm_surface_unmap %p failed, 0x%x", vmem->surface, tbm_ret);
+ goto _VIDEO_MEMORY_UNMAP_DONE;
+ }
+
+ unmapped = TRUE;
+
+ GST_DEBUG ("[plane %d] unmap surface %p done", plane, vmem->surface);
+
+_VIDEO_MEMORY_UNMAP_DONE:
+ if (unmapped == TRUE) {
+ vmem->video_memory_map[plane] = FALSE;
+ vmem->video_memory_map_count--;
+ }
+
+ g_mutex_unlock (&vmem->lock);
+
+ return unmapped;
}