gst_jif_mux_mangle_markers (GstJifMux * self)
{
gboolean modified = FALSE;
- const GstTagList *tags;
+ GstTagList *tags = NULL;
+ gboolean cleanup_tags;
GstJifMuxMarker *m;
GList *node, *file_hdr = NULL, *frame_hdr = NULL, *scan_hdr = NULL;
GList *app0_jfif = NULL, *app1_exif = NULL, *app1_xmp = NULL, *com = NULL;
}
break;
case APP1:
- if (m->size > 6 && !memcmp (m->data, "EXIF\0\0", 6)) {
+ if (m->size > 6 && (!memcmp (m->data, "EXIF\0\0", 6) ||
+ !memcmp (m->data, "Exif\0\0", 6))) {
GST_DEBUG_OBJECT (self, "found APP1 EXIF");
if (!app1_exif)
app1_exif = node;
/* else */
/* remove JFIF if exists */
- /* if we want combined or EXIF */
- /* check if we don't have EXIF APP1 */
- if (!app1_exif) {
- /* exif_data = gst_tag_list_to_exif_buffer (tags); */
- /* insert into self->markers list */
+ /* Existing exif tags will be removed and our own will be added */
+ if (!tags) {
+ tags = (GstTagList *) gst_tag_setter_get_tag_list (GST_TAG_SETTER (self));
+ cleanup_tags = FALSE;
}
- /* else */
- /* remove EXIF if exists */
-
- tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (self));
if (!tags) {
tags = gst_tag_list_new ();
}
+
/* FIXME: not happy with those
* - else where we would use VIDEO_CODEC = "Jpeg"
gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE,
GST_TAG_VIDEO_CODEC, "image/jpeg", NULL);
*/
+ /* Add EXIF */
+ {
+ GstBuffer *exif_data;
+ guint8 *data;
+ GstJifMuxMarker *m;
+ GList *pos;
+
+ /* insert into self->markers list */
+ exif_data = gst_tag_list_to_exif_buffer_with_tiff_header (tags);
+ if (exif_data &&
+ GST_BUFFER_SIZE (exif_data) + 8 >= G_GUINT64_CONSTANT (65536)) {
+ GST_WARNING_OBJECT (self, "Exif tags data size exceed maximum size");
+ gst_buffer_unref (exif_data);
+ exif_data = NULL;
+ }
+ if (exif_data) {
+ data = g_malloc0 (GST_BUFFER_SIZE (exif_data) + 6);
+ memcpy (data, "Exif", 4);
+ memcpy (data + 6, GST_BUFFER_DATA (exif_data),
+ GST_BUFFER_SIZE (exif_data));
+ m = gst_jif_mux_new_marker (APP1, GST_BUFFER_SIZE (exif_data) + 6, data,
+ TRUE);
+ gst_buffer_unref (exif_data);
+
+ if (app1_exif) {
+ gst_jif_mux_marker_free ((GstJifMuxMarker *) app1_exif->data);
+ app1_exif->data = m;
+ } else {
+ pos = file_hdr;
+ if (app0_jfif)
+ pos = app0_jfif;
+ pos = g_list_next (pos);
+
+ self->priv->markers =
+ g_list_insert_before (self->priv->markers, pos, m);
+ if (pos) {
+ app1_exif = g_list_previous (pos);
+ } else {
+ app1_exif = g_list_last (self->priv->markers);
+ }
+ }
+ modified = TRUE;
+ }
+ }
+
/* add xmp */
xmp_data = gst_tag_list_to_xmp_buffer (tags, FALSE);
if (xmp_data) {
modified = TRUE;
}
+
+ if (tags && cleanup_tags)
+ gst_tag_list_free (tags);
return modified;
}
if (!gst_byte_reader_get_string_utf8 (&reader, &id_str))
goto error;
- if (!strcmp (id_str, "http://ns.adobe.com/xap/1.0/")) {
+ if (!strcmp (id_str, "Exif")) {
+ const guint8 *exif_data = NULL;
+ guint exif_size = size - 2;
+ GstTagList *tags;
+ GstBuffer *buf;
+
+ /* skip padding */
+ gst_byte_reader_skip (&reader, 1);
+
+ /* handle exif metadata */
+ if (!gst_byte_reader_get_data (&reader, exif_size, &exif_data))
+ goto error;
+
+ buf = gst_buffer_new ();
+ GST_BUFFER_DATA (buf) = (guint8 *) exif_data;
+ GST_BUFFER_SIZE (buf) = exif_size;
+ tags = gst_tag_list_from_exif_buffer_with_tiff_header (buf);
+ gst_buffer_unref (buf);
+ if (tags) {
+ GST_INFO_OBJECT (parse, "post exif metadata");
+ gst_element_found_tags_for_pad (GST_ELEMENT_CAST (parse),
+ parse->priv->srcpad, tags);
+ }
+ GST_LOG_OBJECT (parse, "parsed marker %x: '%s' %u bytes",
+ marker, id_str, size - 2);
+ } else if (!strcmp (id_str, "http://ns.adobe.com/xap/1.0/")) {
const guint8 *xmp_data = NULL;
guint xmp_size = size - 2 - 29;
GstTagList *tags;