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:
Wim Taymans 2011-08-24 13:52:20 +02:00
parent b0b6d9124d
commit 1bb83435fd
4 changed files with 88 additions and 7 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -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);