diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c index 652cf98fa1..0ccc1f7116 100644 --- a/gst-libs/gst/video/video.c +++ b/gst-libs/gst/video/video.c @@ -26,6 +26,7 @@ #include #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,12 +863,96 @@ 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 @@ -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; } diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h index 4b356ce5ff..5adb5cb6d8 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -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 */