mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
video: Add an id to the video frame
Rename @view_id to @id. Add an id to the video metadata. Add a method to get the metadata from a buffer with the given id. Make a method to map a frame with a certain id. This only maps the frame with the given id on the video metadata. The generic frame id can be used when a buffer carries multiple video frames such as in multiview mode but maybe also when dealing with interlaced video that stores the fields in separate buffers.
This commit is contained in:
parent
b0b6d9124d
commit
1bb83435fd
4 changed files with 88 additions and 7 deletions
|
@ -35,6 +35,36 @@ gst_meta_video_get_info (void)
|
|||
return meta_video_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_get_meta_video_id:
|
||||
* @buffer: a #GstBuffer
|
||||
* @id: a metadata id
|
||||
*
|
||||
* Find the #GstMetaVideo on @buffer with the given @id.
|
||||
*
|
||||
* Buffers can contain multiple #GstMetaVideo metadata items when dealing with
|
||||
* multiview buffers.
|
||||
*
|
||||
* Returns: the #GstMetaVideo with @id or %NULL when there is no such metadata
|
||||
* on @buffer.
|
||||
*/
|
||||
GstMetaVideo *
|
||||
gst_buffer_get_meta_video_id (GstBuffer * buffer, gint id)
|
||||
{
|
||||
gpointer state = NULL;
|
||||
GstMeta *meta;
|
||||
const GstMetaInfo *info = GST_META_INFO_VIDEO;
|
||||
|
||||
while ((meta = gst_buffer_iterate_meta (buffer, &state))) {
|
||||
if (meta->info->api == info->api) {
|
||||
GstMetaVideo *vmeta = (GstMetaVideo *) meta;
|
||||
if (vmeta->id == id)
|
||||
return vmeta;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_add_meta_video:
|
||||
* @buffer: a #GstBuffer
|
||||
|
@ -95,6 +125,7 @@ gst_buffer_add_meta_video_full (GstBuffer * buffer, GstVideoFlags flags,
|
|||
|
||||
meta->flags = flags;
|
||||
meta->format = format;
|
||||
meta->id = 0;
|
||||
meta->width = width;
|
||||
meta->height = height;
|
||||
meta->buffer = buffer;
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef struct _GstMetaVideoCrop GstMetaVideoCrop;
|
|||
* @buffer: the buffer this metadata belongs to
|
||||
* @flags: additional video flags
|
||||
* @format: the video format
|
||||
* @id: identifier of the frame
|
||||
* @width: the video width
|
||||
* @height: the video height
|
||||
* @n_planes: the number of planes in the image
|
||||
|
@ -57,6 +58,7 @@ struct _GstMetaVideo {
|
|||
|
||||
GstVideoFlags flags;
|
||||
GstVideoFormat format;
|
||||
gint id;
|
||||
guint width;
|
||||
guint height;
|
||||
|
||||
|
@ -72,6 +74,8 @@ struct _GstMetaVideo {
|
|||
const GstMetaInfo * gst_meta_video_get_info (void);
|
||||
|
||||
#define gst_buffer_get_meta_video(b) ((GstMetaVideo*)gst_buffer_get_meta((b),GST_META_INFO_VIDEO))
|
||||
GstMetaVideo * gst_buffer_get_meta_video_id (GstBuffer *buffer, gint id);
|
||||
|
||||
GstMetaVideo * gst_buffer_add_meta_video (GstBuffer *buffer, GstVideoFlags flags,
|
||||
GstVideoFormat format, guint width, guint height);
|
||||
GstMetaVideo * gst_buffer_add_meta_video_full (GstBuffer *buffer, GstVideoFlags flags,
|
||||
|
|
|
@ -894,12 +894,18 @@ gst_video_info_to_caps (GstVideoInfo * info)
|
|||
}
|
||||
|
||||
/**
|
||||
* gst_video_frame_map:
|
||||
* gst_video_frame_map_id:
|
||||
* @frame: pointer to #GstVideoFrame
|
||||
* @info: a #GstVideoInfo
|
||||
* @buffer: the buffer to map
|
||||
* @id: the frame id to map
|
||||
* @flags: #GstMapFlags
|
||||
*
|
||||
* Use @info and @buffer to fill in the values of @frame.
|
||||
* Use @info and @buffer to fill in the values of @frame with the video frame
|
||||
* information of frame @id.
|
||||
*
|
||||
* When @id is -1, the default frame is mapped. When @id != -1, this function
|
||||
* will return %FALSE when there is no GstMetaVideo with that id.
|
||||
*
|
||||
* All video planes of @buffer will be mapped and the pointers will be set in
|
||||
* @frame->data.
|
||||
|
@ -907,8 +913,8 @@ gst_video_info_to_caps (GstVideoInfo * info)
|
|||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
gst_video_frame_map (GstVideoFrame * frame, GstVideoInfo * info,
|
||||
GstBuffer * buffer, GstMapFlags flags)
|
||||
gst_video_frame_map_id (GstVideoFrame * frame, GstVideoInfo * info,
|
||||
GstBuffer * buffer, gint id, GstMapFlags flags)
|
||||
{
|
||||
GstMetaVideo *meta;
|
||||
guint8 *data;
|
||||
|
@ -919,8 +925,12 @@ gst_video_frame_map (GstVideoFrame * frame, GstVideoInfo * info,
|
|||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
|
||||
|
||||
if (id == -1)
|
||||
meta = gst_buffer_get_meta_video (buffer);
|
||||
else
|
||||
meta = gst_buffer_get_meta_video_id (buffer, id);
|
||||
|
||||
frame->buffer = buffer;
|
||||
meta = gst_buffer_get_meta_video (buffer);
|
||||
frame->meta = meta;
|
||||
|
||||
if (meta) {
|
||||
|
@ -928,14 +938,21 @@ gst_video_frame_map (GstVideoFrame * frame, GstVideoInfo * info,
|
|||
frame->info.finfo = &formats[meta->format].info;
|
||||
frame->info.width = meta->width;
|
||||
frame->info.height = meta->height;
|
||||
frame->id = meta->id;
|
||||
|
||||
for (i = 0; i < info->finfo->n_planes; i++) {
|
||||
frame->data[i] =
|
||||
gst_meta_video_map (meta, i, &frame->info.stride[i], flags);
|
||||
}
|
||||
} else {
|
||||
/* no metadata, we really need to have the metadata when the id is
|
||||
* specified. */
|
||||
if (id != -1)
|
||||
goto no_metadata;
|
||||
|
||||
/* copy the info */
|
||||
frame->info = *info;
|
||||
frame->id = id;
|
||||
|
||||
data = gst_buffer_map (buffer, &size, NULL, flags);
|
||||
|
||||
|
@ -951,6 +968,11 @@ gst_video_frame_map (GstVideoFrame * frame, GstVideoInfo * info,
|
|||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
no_metadata:
|
||||
{
|
||||
GST_ERROR ("no GstMetaVideo for id", id);
|
||||
return FALSE;
|
||||
}
|
||||
invalid_size:
|
||||
{
|
||||
GST_ERROR ("invalid buffer size %" G_GSIZE_FORMAT " < %" G_GSIZE_FORMAT,
|
||||
|
@ -960,6 +982,27 @@ invalid_size:
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_frame_map:
|
||||
* @frame: pointer to #GstVideoFrame
|
||||
* @info: a #GstVideoInfo
|
||||
* @buffer: the buffer to map
|
||||
* @flags: #GstMapFlags
|
||||
*
|
||||
* Use @info and @buffer to fill in the values of @frame.
|
||||
*
|
||||
* All video planes of @buffer will be mapped and the pointers will be set in
|
||||
* @frame->data.
|
||||
*
|
||||
* Returns: %TRUE on success.
|
||||
*/
|
||||
gboolean
|
||||
gst_video_frame_map (GstVideoFrame * frame, GstVideoInfo * info,
|
||||
GstBuffer * buffer, GstMapFlags flags)
|
||||
{
|
||||
return gst_video_frame_map_id (frame, info, buffer, -1, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_frame_unmap:
|
||||
* @frame: a #GstVideoFrame
|
||||
|
|
|
@ -563,7 +563,8 @@ gboolean gst_video_info_convert (GstVideoInfo *info,
|
|||
* @info: the #GstVideoInfo
|
||||
* @buffer: the mapped buffer
|
||||
* @meta: pointer to metadata if any
|
||||
* @view_id: id of the view in multiview
|
||||
* @id: id of the mapped frame. the id can for example be used to
|
||||
* indentify the frame in case of multiview video.
|
||||
* @data: pointers to the plane data
|
||||
*
|
||||
* A video frame obtained from gst_video_frame_map()
|
||||
|
@ -573,13 +574,15 @@ struct _GstVideoFrame {
|
|||
|
||||
GstBuffer *buffer;
|
||||
gpointer meta;
|
||||
gint view_id;
|
||||
gint id;
|
||||
|
||||
gpointer data[GST_VIDEO_MAX_PLANES];
|
||||
};
|
||||
|
||||
gboolean gst_video_frame_map (GstVideoFrame *frame, GstVideoInfo *info,
|
||||
GstBuffer *buffer, GstMapFlags flags);
|
||||
gboolean gst_video_frame_map_id (GstVideoFrame *frame, GstVideoInfo *info,
|
||||
GstBuffer *buffer, gint id, GstMapFlags flags);
|
||||
void gst_video_frame_unmap (GstVideoFrame *frame);
|
||||
|
||||
gboolean gst_video_frame_copy (GstVideoFrame *dest, const GstVideoFrame *src);
|
||||
|
|
Loading…
Reference in a new issue