video: Add an id to the video frame
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 24 Aug 2011 11:52:20 +0000 (13:52 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 24 Aug 2011 11:52:20 +0000 (13:52 +0200)
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.

gst-libs/gst/video/gstmetavideo.c
gst-libs/gst/video/gstmetavideo.h
gst-libs/gst/video/video.c
gst-libs/gst/video/video.h

index 574fd76..2946704 100644 (file)
@@ -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;
index 858d048..12c1ed1 100644 (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,
index f82b07f..d7a24e5 100644 (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,
@@ -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
  *
index 3691dbd..e4e5252 100644 (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);