meta: simplify a bit
[platform/upstream/gstreamer.git] / gst / gstmeta.c
1 /* GStreamer
2  * Copyright (C) 2011 Wim Taymans <wim.taymans@gmail.com>
3  *
4  * gstmeta.c: metadata operations
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:gstmeta
24  * @short_description: Buffer metadata
25  *
26  * Last reviewed on December 17th, 2009 (0.10.26)
27  */
28 #include "gst_private.h"
29
30 #include "gstbuffer.h"
31 #include "gstmeta.h"
32 #include "gstinfo.h"
33 #include "gstutils.h"
34
35 static GHashTable *metainfo = NULL;
36 static GStaticRWLock lock = G_STATIC_RW_LOCK_INIT;
37
38 void
39 _gst_meta_init (void)
40 {
41   metainfo = g_hash_table_new (g_str_hash, g_str_equal);
42 }
43
44 /**
45  * gst_meta_register_info:
46  * @info: a #GstMetaInfo
47  *
48  * Register a #GstMetaInfo. The same @info can be retrieved later with
49  * gst_meta_get_info() by using @impl as the key.
50  *
51  * Returns: a #GstMetaInfo that can be used to access metadata.
52  */
53
54 const GstMetaInfo *
55 gst_meta_register (const gchar * api, const gchar * impl, gsize size,
56     GstMetaInitFunction init_func, GstMetaFreeFunction free_func,
57     GstMetaCopyFunction copy_func, GstMetaSubFunction sub_func,
58     GstMetaSerializeFunction serialize_func,
59     GstMetaDeserializeFunction deserialize_func)
60 {
61   GstMetaInfo *info;
62
63   g_return_val_if_fail (api != NULL, NULL);
64   g_return_val_if_fail (impl != NULL, NULL);
65   g_return_val_if_fail (size != 0, NULL);
66
67   info = g_slice_new (GstMetaInfo);
68   info->api = g_quark_from_string (api);
69   info->impl = g_quark_from_string (impl);
70   info->size = size;
71   info->init_func = init_func;
72   info->free_func = free_func;
73   info->copy_func = copy_func;
74   info->sub_func = sub_func;
75   info->serialize_func = serialize_func;
76   info->deserialize_func = deserialize_func;
77
78   GST_DEBUG ("register \"%s\" implementing \"%s\" of size %" G_GSIZE_FORMAT,
79       api, impl, size);
80
81   g_static_rw_lock_writer_lock (&lock);
82   g_hash_table_insert (metainfo, (gpointer) impl, (gpointer) info);
83   g_static_rw_lock_writer_unlock (&lock);
84
85   return info;
86 }
87
88 /**
89  * gst_meta_get_info:
90  * @name: the name
91  *
92  * Lookup a previously registered meta info structure by its @implementor name.
93  *
94  * Returns: a #GstMetaInfo with @name or #NULL when no such metainfo
95  * exists.
96  */
97 const GstMetaInfo *
98 gst_meta_get_info (const gchar * impl)
99 {
100   GstMetaInfo *info;
101
102   g_return_val_if_fail (impl != NULL, NULL);
103
104   g_static_rw_lock_reader_lock (&lock);
105   info = g_hash_table_lookup (metainfo, impl);
106   g_static_rw_lock_reader_unlock (&lock);
107
108   return info;
109 }
110
111 typedef struct
112 {
113   guint8 *data;
114   GFreeFunc free_func;
115   gsize size;
116   gsize offset;
117 } GstMetaMemoryParams;
118
119 typedef struct
120 {
121   GstMetaMemory memory;
122   GstMetaMemoryParams params;
123 } GstMetaMemoryImpl;
124
125 static gpointer
126 meta_memory_mmap (GstMetaMemory * meta, gsize offset, gsize * size,
127     GstMetaMapFlags flags)
128 {
129   GstMetaMemoryImpl *impl = (GstMetaMemoryImpl *) meta;
130
131   *size = impl->params.size - offset;
132   return impl->params.data + offset;
133 }
134
135 static gboolean
136 meta_memory_munmap (GstMetaMemory * meta, gpointer data, gsize size)
137 {
138   return TRUE;
139 }
140
141 static gboolean
142 meta_memory_init (GstMetaMemoryImpl * meta, GstMetaMemoryParams * params,
143     GstBuffer * buffer)
144 {
145   meta->memory.mmap_func = meta_memory_mmap;
146   meta->memory.munmap_func = meta_memory_munmap;
147   meta->params = *params;
148   return TRUE;
149 }
150
151 static void
152 meta_memory_free (GstMetaMemoryImpl * meta, GstBuffer * buffer)
153 {
154   if (meta->params.free_func)
155     meta->params.free_func (meta->params.data);
156 }
157
158 static void
159 meta_memory_copy (GstBuffer * copy, GstMetaMemoryImpl * meta,
160     const GstBuffer * buffer)
161 {
162   gst_buffer_add_meta_memory (copy,
163       g_memdup (meta->params.data, meta->params.size),
164       g_free, meta->params.size, meta->params.offset);
165 }
166
167 static void
168 meta_memory_sub (GstBuffer * subbuf, GstMetaMemoryImpl * meta,
169     GstBuffer * buffer, guint offset, guint size)
170 {
171   gst_buffer_add_meta_memory (subbuf,
172       meta->params.data, NULL, size, meta->params.offset + offset);
173 }
174
175 const GstMetaInfo *
176 gst_meta_memory_get_info (void)
177 {
178   static const GstMetaInfo *meta_info = NULL;
179
180   if (meta_info == NULL) {
181     meta_info = gst_meta_register ("GstMetaMemory", "GstMetaMemoryImpl",
182         sizeof (GstMetaMemoryImpl),
183         (GstMetaInitFunction) meta_memory_init,
184         (GstMetaFreeFunction) meta_memory_free,
185         (GstMetaCopyFunction) meta_memory_copy,
186         (GstMetaSubFunction) meta_memory_sub,
187         (GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
188   }
189   return meta_info;
190 }
191
192 GstMetaMemory *
193 gst_buffer_add_meta_memory (GstBuffer * buffer, gpointer data,
194     GFreeFunc free_func, gsize size, gsize offset)
195 {
196   GstMeta *meta;
197   GstMetaMemoryParams params;
198
199   params.data = data;
200   params.free_func = free_func;
201   params.size = size;
202   params.offset = offset;
203
204   meta = gst_buffer_add_meta (buffer, GST_META_MEMORY_INFO, &params);
205
206   return (GstMetaMemory *) meta;
207 }