video: Add GstVideoFrame helper structure
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 17 Jun 2011 13:29:50 +0000 (15:29 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 17 Jun 2011 13:41:31 +0000 (15:41 +0200)
The videoframe structure can be used to easily parse the contents of video
buffers.

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

index 652cf98..0ccc1f7 100644 (file)
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include "video.h"
+#include "gstmetavideo.h"
 
 static int get_size (GstVideoFormat format, int width, int height);
 static int get_stride (GstVideoFormat format, int plane, int width);
@@ -862,13 +863,97 @@ gst_video_info_to_caps (GstVideoInfo * info)
     gst_caps_set_simple (caps, "color-matrix", G_TYPE_STRING,
         info->color_matrix, NULL);
   if (info->chroma_site)
-    gst_caps_set_simple (caps, "chromar-site", G_TYPE_STRING, info->chroma_site,
+    gst_caps_set_simple (caps, "chroma-site", G_TYPE_STRING, info->chroma_site,
         NULL);
 
   return caps;
 }
 
 /**
+ * gst_video_frame_map:
+ * @frame: pointer to #GstVideoFrame
+ * @info: a #GstVideoInfo
+ * @buffer: the buffer to map
+ *
+ * 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)
+{
+  GstMetaVideo *meta;
+  gint i;
+  guint8 *data;
+  gsize size;
+
+  g_return_val_if_fail (frame != NULL, FALSE);
+  g_return_val_if_fail (info != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+
+  frame->buffer = buffer;
+  meta = gst_buffer_get_meta_video (buffer);
+  frame->meta = meta;
+
+  if (meta) {
+    /* FIXME use metadata */
+  } else {
+    /* copy the info */
+    frame->info = *info;
+
+    data = gst_buffer_map (buffer, &size, NULL, flags);
+
+    /* do some sanity checks */
+    if (size < info->size)
+      goto invalid_size;
+
+    /* set up pointers */
+    for (i = 0; i < info->n_planes; i++) {
+      frame->data[i] = data + info->plane[i].offset;
+    }
+  }
+  return TRUE;
+
+  /* ERRORS */
+invalid_size:
+  {
+    gst_buffer_unmap (buffer, data, size);
+    return FALSE;
+  }
+}
+
+/**
+ * gst_video_frame_unmap:
+ * @frame: a #GstVideoFrame
+ *
+ * Unmap the memory previously mapped with gst_video_frame_map.
+ */
+void
+gst_video_frame_unmap (GstVideoFrame * frame)
+{
+  GstBuffer *buffer;
+  GstMetaVideo *meta;
+  guint8 *data;
+
+  g_return_if_fail (frame != NULL);
+
+  buffer = frame->buffer;
+  meta = frame->meta;
+
+  if (meta) {
+    /* FIXME use metadata */
+  } else {
+    data = frame->data[0];
+    data -= frame->info.plane[0].offset;
+    gst_buffer_unmap (buffer, data, -1);
+  }
+}
+
+/**
  * get_stride:
  * @format: a #GstVideoFormat
  * @component: the component index
@@ -977,7 +1062,6 @@ get_stride (GstVideoFormat format, int plane, int width)
   }
 }
 
-#if 0
 /**
  * gst_video_format_get_component_width:
  * @format: a #GstVideoFormat
@@ -992,7 +1076,7 @@ get_stride (GstVideoFormat format, int plane, int width)
  *
  * Returns: width of component @component
  */
-static int
+int
 gst_video_format_get_component_width (GstVideoFormat format,
     int component, int width)
 {
@@ -1063,9 +1147,7 @@ gst_video_format_get_component_width (GstVideoFormat format,
       return 0;
   }
 }
-#endif
 
-#if 0
 /**
  * gst_video_format_get_component_height:
  * @format: a #GstVideoFormat
@@ -1151,11 +1233,9 @@ gst_video_format_get_component_height (GstVideoFormat format,
       return 0;
   }
 }
-#endif
 
-#if 0
 /**
- * get_component_offset:
+ * gst_video_format_get_component_offset:
  * @format: a #GstVideoFormat
  * @component: the component index
  * @width: the width of video
@@ -1172,8 +1252,8 @@ gst_video_format_get_component_height (GstVideoFormat format,
  *
  * Returns: offset of component @component
  */
-static int
-get_component_offset (GstVideoFormat format,
+int
+gst_video_format_get_component_offset (GstVideoFormat format,
     int component, int width, int height)
 {
   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
@@ -1420,7 +1500,6 @@ get_component_offset (GstVideoFormat format,
   GST_WARNING ("unhandled format %d or component %d", format, component);
   return 0;
 }
-#endif
 
 /**
  * get_plane_offset:
@@ -1551,9 +1630,9 @@ fill_planes (GstVideoInfo * info)
           (GST_ROUND_UP_4 (height) / 4);
       break;
     default:
+      GST_WARNING ("unhandled format %d", info->format);
       break;
   }
-  GST_WARNING ("unhandled format %d", info->format);
   return 0;
 }
 
index 4b356ce..5adb5cb 100644 (file)
@@ -145,6 +145,7 @@ int            gst_video_format_get_pixel_stride     (GstVideoFormat format,
 
 typedef struct _GstVideoPlane GstVideoPlane;
 typedef struct _GstVideoInfo GstVideoInfo;
+typedef struct _GstVideoFrame GstVideoFrame;
 
 /**
  * GstVideoFlags:
@@ -228,6 +229,22 @@ struct _GstVideoInfo {
   GstVideoPlane  plane[GST_VIDEO_MAX_PLANES];
 };
 
+/**
+ * GstVideoFrame:
+ * @info: the #GstVideoInfo
+ * @buffer: the mapped buffer
+ * @data: pointers to the plane data
+ *
+ * A video frame obtained from gst_video_frame_map()
+ */
+struct _GstVideoFrame {
+  GstVideoInfo info;
+
+  GstBuffer *buffer;
+  gpointer   meta;
+
+  guint8    *data[GST_VIDEO_MAX_PLANES];
+};
 
 void         gst_video_info_init        (GstVideoInfo *info);
 
@@ -244,6 +261,10 @@ gboolean     gst_video_info_convert     (GstVideoInfo *info,
                                          GstFormat     dest_format,
                                          gint64       *dest_value);
 
+gboolean    gst_video_frame_map         (GstVideoFrame *frame, GstVideoInfo *info,
+                                         GstBuffer *buffer, GstMapFlags flags);
+void        gst_video_frame_unmap       (GstVideoFrame *frame);
+
 #define GST_VIDEO_SIZE_RANGE "(int) [ 1, max ]"
 #define GST_VIDEO_FPS_RANGE "(fraction) [ 0, max ]"
 
@@ -323,7 +344,6 @@ gboolean       gst_video_calculate_display_ratio (guint * dar_n,
 gboolean       gst_video_parse_caps_framerate    (GstCaps * caps, int *fps_n, int *fps_d);
 GstBuffer *    gst_video_parse_caps_palette      (GstCaps * caps);
 
-#if 0
 int            gst_video_format_get_component_width  (GstVideoFormat format,
                                                       int            component,
                                                       int            width) G_GNUC_CONST;
@@ -331,19 +351,10 @@ int            gst_video_format_get_component_width  (GstVideoFormat format,
 int            gst_video_format_get_component_height (GstVideoFormat format,
                                                       int            component,
                                                       int            height) G_GNUC_CONST;
-
 int            gst_video_format_get_component_offset (GstVideoFormat format,
                                                       int            component,
                                                       int            width,
-                                                      int            height) G_GNUC_CONST;
-
-int            gst_video_format_get_size             (GstVideoFormat format,
-                                                      int            width,
-                                                      int            height) G_GNUC_CONST;
-
-gboolean       gst_video_get_size_from_caps (const GstCaps * caps, gint * size);
-#endif
-
+                                                      int            height);
 
 /* video still frame event creation and parsing */