From: Wim Taymans Date: Wed, 24 Aug 2011 11:52:20 +0000 (+0200) Subject: video: Add an id to the video frame X-Git-Tag: 1.19.3~511^2~7326 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1bb83435fda91a4612b383194f56ef24c4c0b299;p=platform%2Fupstream%2Fgstreamer.git 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. --- diff --git a/gst-libs/gst/video/gstmetavideo.c b/gst-libs/gst/video/gstmetavideo.c index 574fd76..2946704 100644 --- a/gst-libs/gst/video/gstmetavideo.c +++ b/gst-libs/gst/video/gstmetavideo.c @@ -36,6 +36,36 @@ gst_meta_video_get_info (void) } /** + * 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 * @flags: #GstVideoFlags @@ -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; diff --git a/gst-libs/gst/video/gstmetavideo.h b/gst-libs/gst/video/gstmetavideo.h index 858d048..12c1ed1 100644 --- a/gst-libs/gst/video/gstmetavideo.h +++ b/gst-libs/gst/video/gstmetavideo.h @@ -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, diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index f82b07f..d7a24e5 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -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, @@ -961,6 +983,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 * diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h index 3691dbd..e4e5252 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -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);