mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
video: Improve video frame map/unmap
Install defaul map/unmap function on the metadata and really call the functions instead of always calling a default implementation. Rework some bits so that we don't have to mess with the GstMapInfo information (adding the offset), instead pass the adjusted data pointer from the map function.
This commit is contained in:
parent
f552d8f0c0
commit
e32e8f6c52
3 changed files with 88 additions and 96 deletions
|
@ -91,6 +91,71 @@ gst_buffer_get_video_meta_id (GstBuffer * buffer, gint id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
default_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
|
||||
gpointer * data, gint * stride, GstMapFlags flags)
|
||||
{
|
||||
guint n, i;
|
||||
guint offset;
|
||||
GstBuffer *buffer = meta->buffer;
|
||||
|
||||
if ((n = gst_buffer_n_memory (buffer)) == 0)
|
||||
goto no_memory;
|
||||
|
||||
offset = meta->offset[plane];
|
||||
*stride = meta->stride[plane];
|
||||
/* find the memory block for this plane, this is the memory block containing
|
||||
* the plane offset. @offset will be updated with the offset inside the memory
|
||||
* block where the plane starts. */
|
||||
for (i = 0; i < n; i++) {
|
||||
GstMemory *mem = NULL;
|
||||
gsize size;
|
||||
|
||||
mem = gst_buffer_get_memory (buffer, i);
|
||||
size = gst_memory_get_sizes (mem, NULL, NULL);
|
||||
|
||||
if (offset < size) {
|
||||
GstMemory *mapped;
|
||||
|
||||
if (!(mapped = gst_memory_make_mapped (mem, info, flags)))
|
||||
goto cannot_map;
|
||||
|
||||
/* buffer is writable when WRITE map is requested, we checked this in
|
||||
* _map * */
|
||||
if (mapped != mem && (flags & GST_MAP_WRITE))
|
||||
gst_buffer_replace_memory (buffer, i, gst_memory_ref (mapped));
|
||||
|
||||
*data = (guint8 *) info->data + offset;
|
||||
return TRUE;
|
||||
}
|
||||
offset -= size;
|
||||
gst_memory_unref (mem);
|
||||
}
|
||||
GST_DEBUG ("no memory found for offset %u", meta->offset[plane]);
|
||||
return FALSE;
|
||||
|
||||
/* ERRORS */
|
||||
no_memory:
|
||||
{
|
||||
GST_DEBUG ("no memory");
|
||||
return FALSE;
|
||||
}
|
||||
cannot_map:
|
||||
{
|
||||
GST_DEBUG ("cannot map memory");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
default_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info)
|
||||
{
|
||||
gst_memory_unmap (info->memory, info);
|
||||
gst_memory_unref (info->memory);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_add_video_meta:
|
||||
* @buffer: a #GstBuffer
|
||||
|
@ -161,59 +226,18 @@ gst_buffer_add_video_meta_full (GstBuffer * buffer, GstVideoFlags flags,
|
|||
meta->offset[i] = offset[i];
|
||||
meta->stride[i] = stride[i];
|
||||
}
|
||||
meta->map = default_map;
|
||||
meta->unmap = default_unmap;
|
||||
|
||||
return meta;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
map_mem_for_offset (GstBuffer * buffer, guint * offset, GstMapInfo * info,
|
||||
GstMapFlags flags)
|
||||
{
|
||||
guint n, i;
|
||||
|
||||
if ((n = gst_buffer_n_memory (buffer)) == 0)
|
||||
goto no_memory;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
GstMemory *mem = NULL;
|
||||
gsize size;
|
||||
|
||||
mem = gst_buffer_get_memory (buffer, i);
|
||||
size = gst_memory_get_sizes (mem, NULL, NULL);
|
||||
|
||||
if (*offset < size) {
|
||||
GstMemory *mapped;
|
||||
|
||||
if (!(mapped = gst_memory_make_mapped (mem, info, flags)))
|
||||
goto cannot_map;
|
||||
|
||||
if (mapped != mem && (flags & GST_MAP_WRITE))
|
||||
gst_buffer_replace_memory (buffer, i, gst_memory_ref (mapped));
|
||||
break;
|
||||
}
|
||||
*offset -= size;
|
||||
gst_memory_unref (mem);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
no_memory:
|
||||
{
|
||||
GST_DEBUG ("no memory");
|
||||
return FALSE;
|
||||
}
|
||||
cannot_map:
|
||||
{
|
||||
GST_DEBUG ("cannot map memory");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_meta_map:
|
||||
* @meta: a #GstVideoMeta
|
||||
* @plane: a plane
|
||||
* @info: a #GstMapInfo
|
||||
* @stride: result stride
|
||||
* @offset: the offset of where the plane starts in @info
|
||||
* @flags: @GstMapFlags
|
||||
*
|
||||
* Map the video plane with index @plane in @meta and return a pointer to the
|
||||
|
@ -223,36 +247,19 @@ cannot_map:
|
|||
*/
|
||||
gboolean
|
||||
gst_video_meta_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
|
||||
gint * stride, GstMapFlags flags)
|
||||
gpointer * data, gint * stride, GstMapFlags flags)
|
||||
{
|
||||
guint offset;
|
||||
gboolean write, res;
|
||||
GstBuffer *buffer;
|
||||
|
||||
g_return_val_if_fail (meta != NULL, FALSE);
|
||||
g_return_val_if_fail (meta->map != NULL, FALSE);
|
||||
g_return_val_if_fail (plane < meta->n_planes, FALSE);
|
||||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
g_return_val_if_fail (stride != NULL, FALSE);
|
||||
g_return_val_if_fail (meta->buffer != NULL, FALSE);
|
||||
g_return_val_if_fail (!(flags & GST_MAP_WRITE)
|
||||
|| gst_buffer_is_writable (meta->buffer), FALSE);
|
||||
|
||||
buffer = meta->buffer;
|
||||
g_return_val_if_fail (buffer != NULL, FALSE);
|
||||
|
||||
write = (flags & GST_MAP_WRITE) != 0;
|
||||
g_return_val_if_fail (!write || gst_buffer_is_writable (buffer), FALSE);
|
||||
|
||||
offset = meta->offset[plane];
|
||||
*stride = meta->stride[plane];
|
||||
/* find the memory block for this plane, this is the memory block containing
|
||||
* the plane offset */
|
||||
res = map_mem_for_offset (buffer, &offset, info, flags);
|
||||
if (G_LIKELY (res)) {
|
||||
/* move to the right offset inside the block */
|
||||
info->data += offset;
|
||||
info->size -= offset;
|
||||
info->maxsize -= offset;
|
||||
}
|
||||
|
||||
return res;
|
||||
return meta->map (meta, plane, info, data, stride, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,27 +275,12 @@ gst_video_meta_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
|
|||
gboolean
|
||||
gst_video_meta_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info)
|
||||
{
|
||||
guint offset;
|
||||
GstBuffer *buffer;
|
||||
|
||||
g_return_val_if_fail (meta != NULL, FALSE);
|
||||
g_return_val_if_fail (meta->unmap != NULL, FALSE);
|
||||
g_return_val_if_fail (plane < meta->n_planes, FALSE);
|
||||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
|
||||
buffer = meta->buffer;
|
||||
g_return_val_if_fail (buffer != NULL, FALSE);
|
||||
|
||||
offset = meta->offset[plane];
|
||||
|
||||
/* move to the right offset inside the block */
|
||||
info->data -= offset;
|
||||
info->size += offset;
|
||||
info->maxsize += offset;
|
||||
|
||||
gst_memory_unmap (info->memory, info);
|
||||
gst_memory_unref (info->memory);
|
||||
|
||||
return TRUE;
|
||||
return meta->unmap (meta, plane, info);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -44,8 +44,10 @@ typedef struct _GstVideoCropMeta GstVideoCropMeta;
|
|||
* @width: the video width
|
||||
* @height: the video height
|
||||
* @n_planes: the number of planes in the image
|
||||
* @offset: array of offsets for the planes
|
||||
* @stride: array of strides for the planes
|
||||
* @offset: array of offsets for the planes. This field might not always be
|
||||
* valid, it is used by the default implementation of @map.
|
||||
* @stride: array of strides for the planes. This field might not always be
|
||||
* valid, it is used by the default implementation of @map.
|
||||
* @map: map the memory of a plane
|
||||
* @unmap: unmap the memory of a plane
|
||||
*
|
||||
|
@ -66,8 +68,8 @@ struct _GstVideoMeta {
|
|||
gsize offset[GST_VIDEO_MAX_PLANES];
|
||||
gint stride[GST_VIDEO_MAX_PLANES];
|
||||
|
||||
gboolean (*map) (GstVideoMeta *meta, guint plane, GstMapInfo *info, gint *stride,
|
||||
GstMapFlags flags);
|
||||
gboolean (*map) (GstVideoMeta *meta, guint plane, GstMapInfo *info,
|
||||
gpointer *data, gint * stride, GstMapFlags flags);
|
||||
gboolean (*unmap) (GstVideoMeta *meta, guint plane, GstMapInfo *info);
|
||||
};
|
||||
|
||||
|
@ -84,7 +86,7 @@ GstVideoMeta * gst_buffer_add_video_meta_full (GstBuffer *buffer, GstVideoFlags
|
|||
gint stride[GST_VIDEO_MAX_PLANES]);
|
||||
|
||||
gboolean gst_video_meta_map (GstVideoMeta *meta, guint plane, GstMapInfo *info,
|
||||
gint *stride, GstMapFlags flags);
|
||||
gpointer *data, gint *stride, GstMapFlags flags);
|
||||
gboolean gst_video_meta_unmap (GstVideoMeta *meta, guint plane, GstMapInfo *info);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1040,11 +1040,9 @@ gst_video_frame_map_id (GstVideoFrame * frame, GstVideoInfo * info,
|
|||
frame->info.height = meta->height;
|
||||
frame->id = meta->id;
|
||||
|
||||
for (i = 0; i < info->finfo->n_planes; i++) {
|
||||
gst_video_meta_map (meta, i, &frame->map[i], &frame->info.stride[i],
|
||||
flags);
|
||||
frame->data[i] = frame->map[i].data;
|
||||
}
|
||||
for (i = 0; i < info->finfo->n_planes; i++)
|
||||
gst_video_meta_map (meta, i, &frame->map[i], &frame->data[i],
|
||||
&frame->info.stride[i], flags);
|
||||
} else {
|
||||
/* no metadata, we really need to have the metadata when the id is
|
||||
* specified. */
|
||||
|
|
Loading…
Reference in a new issue