2 * Copyright (C) <2011> Wim Taymans <wim.taymans@gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "gstvideometa.h"
23 gst_video_meta_copy (GstBuffer * dest, GstMeta * meta,
24 GstBuffer * buffer, gsize offset, gsize size)
26 GstVideoMeta *dmeta, *smeta;
29 smeta = (GstVideoMeta *) meta;
32 (GstVideoMeta *) gst_buffer_add_meta (dest, GST_VIDEO_META_INFO, NULL);
35 dmeta->flags = smeta->flags;
36 dmeta->id = smeta->id;
37 dmeta->format = smeta->format;
38 dmeta->width = smeta->width;
39 dmeta->height = smeta->height;
41 dmeta->n_planes = smeta->n_planes;
42 for (i = 0; i < dmeta->n_planes; i++) {
43 dmeta->offset[i] = smeta->offset[i];
44 dmeta->stride[i] = smeta->stride[i];
50 gst_video_meta_get_info (void)
52 static const GstMetaInfo *video_meta_info = NULL;
54 if (video_meta_info == NULL) {
55 video_meta_info = gst_meta_register (GST_VIDEO_META_API, "GstVideoMeta",
56 sizeof (GstVideoMeta),
57 (GstMetaInitFunction) NULL,
58 (GstMetaFreeFunction) NULL,
59 gst_video_meta_copy, (GstMetaTransformFunction) NULL);
61 return video_meta_info;
65 * gst_buffer_get_video_meta_id:
66 * @buffer: a #GstBuffer
69 * Find the #GstVideoMeta on @buffer with the given @id.
71 * Buffers can contain multiple #GstVideoMeta metadata items when dealing with
74 * Returns: the #GstVideoMeta with @id or %NULL when there is no such metadata
78 gst_buffer_get_video_meta_id (GstBuffer * buffer, gint id)
80 gpointer state = NULL;
82 const GstMetaInfo *info = GST_VIDEO_META_INFO;
84 while ((meta = gst_buffer_iterate_meta (buffer, &state))) {
85 if (meta->info->api == info->api) {
86 GstVideoMeta *vmeta = (GstVideoMeta *) meta;
95 default_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
96 gpointer * data, gint * stride, GstMapFlags flags)
100 GstBuffer *buffer = meta->buffer;
102 if ((n = gst_buffer_n_memory (buffer)) == 0)
105 offset = meta->offset[plane];
106 *stride = meta->stride[plane];
107 /* find the memory block for this plane, this is the memory block containing
108 * the plane offset. @offset will be updated with the offset inside the memory
109 * block where the plane starts. */
110 for (i = 0; i < n; i++) {
111 GstMemory *mem = NULL;
114 mem = gst_buffer_get_memory (buffer, i);
115 size = gst_memory_get_sizes (mem, NULL, NULL);
120 if (!(mapped = gst_memory_make_mapped (mem, info, flags)))
123 /* buffer is writable when WRITE map is requested, we checked this in
125 if (mapped != mem && (flags & GST_MAP_WRITE))
126 gst_buffer_replace_memory (buffer, i, gst_memory_ref (mapped));
128 *data = (guint8 *) info->data + offset;
132 gst_memory_unref (mem);
134 GST_DEBUG ("no memory found for offset %u", meta->offset[plane]);
140 GST_DEBUG ("no memory");
145 GST_DEBUG ("cannot map memory");
151 default_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info)
153 gst_memory_unmap (info->memory, info);
154 gst_memory_unref (info->memory);
160 * gst_buffer_add_video_meta:
161 * @buffer: a #GstBuffer
162 * @flags: #GstVideoFlags
163 * @format: a #GstVideoFormat
165 * @height: the height
167 * Attaches GstVideoMeta metadata to @buffer with the given parameters and the
168 * default offsets and strides for @format and @width x @height.
170 * This function calculates the default offsets and strides and then calls
171 * gst_buffer_add_video_meta_full() with them.
173 * Returns: the #GstVideoMeta on @buffer.
176 gst_buffer_add_video_meta (GstBuffer * buffer, GstVideoFlags flags,
177 GstVideoFormat format, guint width, guint height)
182 gst_video_info_set_format (&info, format, width, height);
184 meta = gst_buffer_add_video_meta_full (buffer, flags, format, width, height,
185 info.finfo->n_planes, info.offset, info.stride);
191 * gst_buffer_add_video_meta_full:
192 * @buffer: a #GstBuffer
193 * @flags: #GstVideoFlags
194 * @format: a #GstVideoFormat
196 * @height: the height
197 * @n_planes: number of planes
198 * @offset: offset of each plane
199 * @stride: stride of each plane
201 * Attaches GstVideoMeta metadata to @buffer with the given parameters.
203 * Returns: the #GstVideoMeta on @buffer.
206 gst_buffer_add_video_meta_full (GstBuffer * buffer, GstVideoFlags flags,
207 GstVideoFormat format, guint width, guint height,
208 guint n_planes, gsize offset[GST_VIDEO_MAX_PLANES],
209 gint stride[GST_VIDEO_MAX_PLANES])
215 (GstVideoMeta *) gst_buffer_add_meta (buffer, GST_VIDEO_META_INFO, NULL);
218 meta->format = format;
221 meta->height = height;
222 meta->buffer = buffer;
224 meta->n_planes = n_planes;
225 for (i = 0; i < n_planes; i++) {
226 meta->offset[i] = offset[i];
227 meta->stride[i] = stride[i];
229 meta->map = default_map;
230 meta->unmap = default_unmap;
236 * gst_video_meta_map:
237 * @meta: a #GstVideoMeta
239 * @info: a #GstMapInfo
240 * @data: the data of @plane
241 * @stride: the stride of @plane
242 * @flags: @GstMapFlags
244 * Map the video plane with index @plane in @meta and return a pointer to the
245 * first byte of the plane and the stride of the plane.
247 * Returns: TRUE if the map operation was successful.
250 gst_video_meta_map (GstVideoMeta * meta, guint plane, GstMapInfo * info,
251 gpointer * data, gint * stride, GstMapFlags flags)
253 g_return_val_if_fail (meta != NULL, FALSE);
254 g_return_val_if_fail (meta->map != NULL, FALSE);
255 g_return_val_if_fail (plane < meta->n_planes, FALSE);
256 g_return_val_if_fail (info != NULL, FALSE);
257 g_return_val_if_fail (data != NULL, FALSE);
258 g_return_val_if_fail (stride != NULL, FALSE);
259 g_return_val_if_fail (meta->buffer != NULL, FALSE);
260 g_return_val_if_fail (!(flags & GST_MAP_WRITE)
261 || gst_buffer_is_writable (meta->buffer), FALSE);
263 return meta->map (meta, plane, info, data, stride, flags);
267 * gst_video_meta_unmap:
268 * @meta: a #GstVideoMeta
270 * @info: a #GstMapInfo
272 * Unmap a previously mapped plane with gst_video_meta_map().
274 * Returns: TRUE if the memory was successfully unmapped.
277 gst_video_meta_unmap (GstVideoMeta * meta, guint plane, GstMapInfo * info)
279 g_return_val_if_fail (meta != NULL, FALSE);
280 g_return_val_if_fail (meta->unmap != NULL, FALSE);
281 g_return_val_if_fail (plane < meta->n_planes, FALSE);
282 g_return_val_if_fail (info != NULL, FALSE);
284 return meta->unmap (meta, plane, info);
288 gst_video_crop_meta_copy (GstBuffer * dest, GstMeta * meta,
289 GstBuffer * buffer, gsize offset, gsize size)
291 GstVideoCropMeta *dmeta, *smeta;
293 smeta = (GstVideoCropMeta *) meta;
294 dmeta = gst_buffer_add_video_crop_meta (dest);
298 dmeta->width = smeta->width;
299 dmeta->height = smeta->height;
303 gst_video_crop_meta_get_info (void)
305 static const GstMetaInfo *video_crop_meta_info = NULL;
307 if (video_crop_meta_info == NULL) {
308 video_crop_meta_info =
309 gst_meta_register (GST_VIDEO_CROP_META_API, "GstVideoCropMeta",
310 sizeof (GstVideoCropMeta), (GstMetaInitFunction) NULL,
311 (GstMetaFreeFunction) NULL, gst_video_crop_meta_copy,
312 (GstMetaTransformFunction) NULL);
314 return video_crop_meta_info;