+typedef struct
+{
+ GstBaseTransform *trans;
+ GstBuffer *outbuf;
+} CopyMetaData;
+
+static gboolean
+foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
+{
+ CopyMetaData *data = user_data;
+ GstBaseTransform *trans = data->trans;
+ GstBaseTransformClass *klass;
+ const GstMetaInfo *info = (*meta)->info;
+ GstBuffer *outbuf = data->outbuf;
+ gboolean do_copy;
+
+ klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
+
+ if (GST_META_FLAG_IS_SET (*meta, GST_META_FLAG_POOLED)) {
+ /* never call the transform_meta with pool private metadata */
+ GST_DEBUG_OBJECT (trans, "not copying pooled metadata %s",
+ g_type_name (info->api));
+ do_copy = FALSE;
+ } else if (gst_meta_api_type_has_tag (info->api, GST_META_TAG_MEMORY)) {
+ /* never call the transform_meta with memory specific metadata */
+ GST_DEBUG_OBJECT (trans, "not copying memory specific metadata %s",
+ g_type_name (info->api));
+ do_copy = FALSE;
+ } else if (klass->transform_meta) {
+ do_copy = klass->transform_meta (trans, outbuf, *meta, inbuf);
+ GST_DEBUG_OBJECT (trans, "transformed metadata %s: copy: %d",
+ g_type_name (info->api), do_copy);
+ } else {
+ do_copy = FALSE;
+ GST_DEBUG_OBJECT (trans, "not copying metadata %s",
+ g_type_name (info->api));
+ }
+
+ /* we only copy metadata when the subclass implemented a transform_meta
+ * function and when it returns TRUE */
+ if (do_copy) {
+ GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
+ GST_DEBUG_OBJECT (trans, "copy metadata %s", g_type_name (info->api));
+ /* simply copy then */
+ info->transform_func (outbuf, *meta, inbuf,
+ _gst_meta_transform_copy, ©_data);
+ }
+ return TRUE;
+}
+