static void validate_taglist_foreach (const GstTagList * list, const gchar * tag, gpointer user_data) { GstTagList *other = GST_TAG_LIST (user_data); const GValue *val1 = gst_tag_list_get_value_index (list, tag, 0); const GValue *val2 = gst_tag_list_get_value_index (other, tag, 0); fail_if (val1 == NULL); fail_if (val2 == NULL); fail_unless (gst_value_can_intersect (val1, val2)); }
void TagExtractor::printOneTag( const GstTagList * list, const gchar * tag, gpointer user_data ) { int i, num; num = gst_tag_list_get_tag_size( list, tag ); for (i = 0; i < num; ++i) { const GValue *val; /* Note: when looking for specific tags, use the gst_tag_list_get_xyz() API, * we only use the GValue approach here because it is more generic */ val = gst_tag_list_get_value_index( list, tag, i ); if( G_VALUE_HOLDS_STRING (val)) { g_print( "\t%20s : %s\n", tag, g_value_get_string( val ) ); } else if( G_VALUE_HOLDS_UINT (val)) { g_print( "\t%20s : %u\n", tag, g_value_get_uint( val ) ); } else if( G_VALUE_HOLDS_DOUBLE (val)) { g_print( "\t%20s : %g\n", tag, g_value_get_double( val ) ); } else if( G_VALUE_HOLDS_BOOLEAN (val)) { g_print( "\t%20s : %s\n", tag, (g_value_get_boolean( val )) ? "true" : "false" ); } else if( GST_VALUE_HOLDS_BUFFER (val)) { GstBuffer *buf = gst_value_get_buffer (val); guint buffer_size = gst_buffer_get_size( buf ); g_print( "\t%20s : buffer of size %u\n", tag, buffer_size ); } else if( GST_VALUE_HOLDS_DATE_TIME (val)) { GstDateTime *dt = (GstDateTime*) g_value_get_boxed( val ); gchar *dt_str = gst_date_time_to_iso8601_string( dt ); g_print( "\t%20s : %s\n", tag, dt_str ); g_free( dt_str ); } else { g_print( "\t%20s : tag of type '%s'\n", tag, G_VALUE_TYPE_NAME (val)); } } }
static void write_exif_ascii_tag_from_taglist (GstExifWriter * writer, const GstTagList * taglist, const GstExifTagMatch * exiftag) { gchar *str = NULL; gboolean cleanup = FALSE; const GValue *value; gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag); if (tag_size != 1) { /* FIXME support this by serializing them with a ','? */ GST_WARNING ("Multiple string tags not supported yet"); return; } value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0); /* do some conversion if needed */ switch (G_VALUE_TYPE (value)) { case G_TYPE_STRING: str = (gchar *) g_value_get_string (value); break; default: GST_WARNING ("Conversion from %s to ascii string not supported", G_VALUE_TYPE_NAME (value)); break; } if (str == NULL) return; write_exif_ascii_tag (writer, exiftag->exif_tag, str); if (cleanup) g_free (str); }
static void bbd_pipeline_process_tag (const GstTagList *tag_list, const gchar *tag_name, BansheeBpmDetector *detector) { const GValue *value; gint value_count; double bpm; g_return_if_fail (detector != NULL); if (detector->progress_cb == NULL) { return; } if (strcmp (tag_name, GST_TAG_BEATS_PER_MINUTE)) { return; } value_count = gst_tag_list_get_tag_size (tag_list, tag_name); if (value_count < 1) { return; } value = gst_tag_list_get_value_index (tag_list, tag_name, 0); if (value != NULL && G_VALUE_HOLDS_DOUBLE (value)) { bpm = g_value_get_double (value); detector->progress_cb (bpm); } }
static void compare_shutter_speed (ExifEntry * entry, ExifTagCheckData * testdata) { gdouble gst_num, exif_num; ExifSRational rational; GValue exif_value = { 0 }; const GValue *gst_value = NULL; gst_value = gst_tag_list_get_value_index (testdata->taglist, GST_TAG_CAPTURING_SHUTTER_SPEED, 0); if (gst_value == NULL) { GST_WARNING ("Failed to get shutter-speed from taglist"); return; } rational = exif_get_srational (entry->data, exif_data_get_byte_order (entry->parent->parent)); g_value_init (&exif_value, GST_TYPE_FRACTION); gst_value_set_fraction (&exif_value, rational.numerator, rational.denominator); gst_util_fraction_to_double (gst_value_get_fraction_numerator (&exif_value), gst_value_get_fraction_denominator (&exif_value), &exif_num); g_value_unset (&exif_value); gst_util_fraction_to_double (gst_value_get_fraction_numerator (gst_value), gst_value_get_fraction_denominator (gst_value), &gst_num); exif_num = pow (2, -exif_num); GST_LOG ("Shutter speed in gst=%lf and in exif=%lf", gst_num, exif_num); fail_unless (ABS (gst_num - exif_num) < 0.001); testdata->result = TRUE; }
GdkPixbuf * totem_gst_tag_list_get_cover (GstTagList *tag_list) { const GValue *cover_value; g_return_val_if_fail (tag_list != NULL, FALSE); cover_value = totem_gst_tag_list_get_cover_real (tag_list); /* Fallback to preview */ if (!cover_value) { cover_value = gst_tag_list_get_value_index (tag_list, GST_TAG_PREVIEW_IMAGE, 0); } if (cover_value) { GstBuffer *buffer; GdkPixbuf *pixbuf; buffer = gst_value_get_buffer (cover_value); pixbuf = totem_gst_buffer_to_pixbuf (buffer); return pixbuf; } return NULL; }
static void print_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) { gint i, num; num = gst_tag_list_get_tag_size (list, tag); for (i = 0; i < num; ++i) { const GValue *val; val = gst_tag_list_get_value_index (list, tag, i); if (G_VALUE_HOLDS_STRING (val)) { g_print (" %s : %s \n", tag, g_value_get_string (val)); } else if (G_VALUE_HOLDS_UINT (val)) { g_print (" %s : %u \n", tag, g_value_get_uint (val)); } else if (G_VALUE_HOLDS_DOUBLE (val)) { g_print (" %s : %g \n", tag, g_value_get_double (val)); } else if (G_VALUE_HOLDS_BOOLEAN (val)) { g_print (" %s : %s \n", tag, g_value_get_boolean (val) ? "true" : "false"); } else if (GST_VALUE_HOLDS_DATE_TIME (val)) { GstDateTime *dt = g_value_get_boxed (val); gchar *dt_str = gst_date_time_to_iso8601_string (dt); g_print (" %s : %s \n", tag, dt_str); g_free (dt_str); } else { g_print (" %s : tag of type '%s' \n", tag, G_VALUE_TYPE_NAME (val)); } } }
CAMLprim value ocaml_gstreamer_message_parse_tag(value _msg) { CAMLparam1(_msg); CAMLlocal4(v,s,t,ans); GstMessage *msg = Message_val(_msg); GstTagList *tags = NULL; const GValue *val; const gchar *tag; int taglen; int i, j, n; caml_release_runtime_system(); gst_message_parse_tag(msg, &tags); taglen = gst_tag_list_n_tags(tags); caml_acquire_runtime_system(); ans = caml_alloc_tuple(taglen); for(i = 0; i < taglen; i++) { t = caml_alloc_tuple(2); // Tag name tag = gst_tag_list_nth_tag_name(tags, i); Store_field(t, 0, caml_copy_string(tag)); // Tag fields n = gst_tag_list_get_tag_size(tags, tag); v = caml_alloc_tuple(n); for (j = 0; j < n; j++) { val = gst_tag_list_get_value_index(tags, tag, j); if (G_VALUE_HOLDS_STRING(val)) { s = caml_copy_string(g_value_get_string(val)); } else if (GST_VALUE_HOLDS_DATE_TIME(val)) { GstDateTime *dt = g_value_get_boxed(val); gchar *dt_str = gst_date_time_to_iso8601_string(dt); s = caml_copy_string(dt_str); g_free(dt_str); } else { //TODO: better typed handling of non-string values? char *vc = g_strdup_value_contents(val); s = caml_copy_string(vc); free(vc); } Store_field(v, j, s); } Store_field(t, 1, v); Store_field(ans, i, t); } gst_tag_list_unref(tags); CAMLreturn(ans); }
/** * rb_gst_process_tag_string: * @taglist: a #GstTagList containing a string tag * @tag: tag name * @field: returns the #RBMetaDataField corresponding to the tag * @value: returns the tag value * * Processes a tag string, determining the metadata field identifier * corresponding to the tag name, and converting the tag data into the * appropriate value type. * * Return value: %TRUE if the tag was successfully converted. */ gboolean rb_gst_process_tag_string (const GstTagList *taglist, const char *tag, RBMetaDataField *field, GValue *value) { const GValue *tagval; if (gst_tag_list_get_tag_size (taglist, tag) < 0) { rb_debug ("no values in taglist for tag %s", tag); return FALSE; } /* only handle a few fields here */ if (!strcmp (tag, GST_TAG_TITLE)) *field = RB_METADATA_FIELD_TITLE; else if (!strcmp (tag, GST_TAG_GENRE)) *field = RB_METADATA_FIELD_GENRE; else if (!strcmp (tag, GST_TAG_COMMENT)) *field = RB_METADATA_FIELD_COMMENT; else if (!strcmp (tag, GST_TAG_BITRATE)) *field = RB_METADATA_FIELD_BITRATE; else if (!strcmp (tag, GST_TAG_MUSICBRAINZ_TRACKID)) *field = RB_METADATA_FIELD_MUSICBRAINZ_TRACKID; else { rb_debug ("tag %s doesn't correspond to a metadata field we're interested in", tag); return FALSE; } /* most of the fields we care about are strings */ switch (*field) { case RB_METADATA_FIELD_BITRATE: g_value_init (value, G_TYPE_ULONG); break; case RB_METADATA_FIELD_TITLE: case RB_METADATA_FIELD_GENRE: case RB_METADATA_FIELD_COMMENT: case RB_METADATA_FIELD_MUSICBRAINZ_TRACKID: default: g_value_init (value, G_TYPE_STRING); break; } tagval = gst_tag_list_get_value_index (taglist, tag, 0); if (!g_value_transform (tagval, value)) { rb_debug ("Could not transform tag value type %s into %s", g_type_name (G_VALUE_TYPE (tagval)), g_type_name (G_VALUE_TYPE (value))); g_value_unset (value); return FALSE; } return TRUE; }
static void print_tag (const GstTagList * list, const gchar * tag, gpointer unused) { gint i, count; count = gst_tag_list_get_tag_size (list, tag); for (i = 0; i < count; i++) { gchar *str; if (gst_tag_get_type (tag) == G_TYPE_STRING) { if (!gst_tag_list_get_string_index (list, tag, i, &str)) g_assert_not_reached (); } else if (gst_tag_get_type (tag) == GST_TYPE_BUFFER) { GstBuffer *img; img = gst_value_get_buffer (gst_tag_list_get_value_index (list, tag, i)); if (img) { gchar *caps_str; caps_str = GST_BUFFER_CAPS (img) ? gst_caps_to_string (GST_BUFFER_CAPS (img)) : g_strdup ("unknown"); str = g_strdup_printf ("buffer of %u bytes, type: %s", GST_BUFFER_SIZE (img), caps_str); g_free (caps_str); } else { str = g_strdup ("NULL buffer"); } } else { str = g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i)); } if (i == 0) { g_print ("%16s: %s\n", gst_tag_get_nick (tag), str); } else { g_print ("%16s: %s\n", "", str); } g_free (str); } }
void metadatamux_exif_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, const GstTagList * taglist, const MetaExifWriteOptions * opts) { ExifData *ed = NULL; GstBuffer *exif_chunk = NULL; const GValue *val = NULL; if (!(buf && size)) goto done; g_free (*buf); *buf = NULL; *size = 0; val = gst_tag_list_get_value_index (taglist, GST_TAG_EXIF, 0); if (val) { exif_chunk = gst_value_get_buffer (val); if (exif_chunk) { ed = exif_data_new_from_data (GST_BUFFER_DATA (exif_chunk), GST_BUFFER_SIZE (exif_chunk)); } } if (!ed) { ed = exif_data_new (); GST_DEBUG ("setting byteorder %d", opts->byteorder); switch (opts->byteorder) { case GST_META_EXIF_BYTE_ORDER_MOTOROLA: exif_data_set_byte_order (ed, EXIF_BYTE_ORDER_MOTOROLA); break; case GST_META_EXIF_BYTE_ORDER_INTEL: exif_data_set_byte_order (ed, EXIF_BYTE_ORDER_INTEL); break; default: break; } exif_data_set_data_type (ed, EXIF_DATA_TYPE_COMPRESSED); exif_data_fix (ed); } gst_tag_list_foreach (taglist, metadatamux_exif_for_each_tag_in_list, ed); exif_data_save_data (ed, buf, size); done: if (ed) exif_data_unref (ed); return; }
/** * rb_gst_process_embedded_image: * @taglist: a #GstTagList containing an image * @tag: the tag name * * Converts embedded image data extracted from a tag list into * a #GdkPixbuf. The returned #GdkPixbuf is owned by the caller. * * Returns: a #GdkPixbuf, or NULL. */ GdkPixbuf * rb_gst_process_embedded_image (const GstTagList *taglist, const char *tag) { GstBuffer *buf; GdkPixbufLoader *loader; GdkPixbuf *pixbuf; GError *error = NULL; const GValue *val; val = gst_tag_list_get_value_index (taglist, tag, 0); if (val == NULL) { rb_debug ("no value for tag %s in the tag list" , tag); return NULL; } buf = gst_value_get_buffer (val); if (buf == NULL) { rb_debug ("apparently couldn't get image buffer"); return NULL; } /* probably should check media type? text/uri-list won't work too well in a pixbuf loader */ loader = gdk_pixbuf_loader_new (); rb_debug ("sending %d bytes to pixbuf loader", buf->size); if (gdk_pixbuf_loader_write (loader, buf->data, buf->size, &error) == FALSE) { rb_debug ("pixbuf loader doesn't like the data: %s", error->message); g_error_free (error); g_object_unref (loader); return NULL; } pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); if (pixbuf != NULL) { g_object_ref (pixbuf); } gdk_pixbuf_loader_close (loader, NULL); g_object_unref (loader); if (pixbuf == NULL) { rb_debug ("pixbuf loader didn't give us a pixbuf"); return NULL; } rb_debug ("returning embedded image: %d x %d / %d", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_bits_per_sample (pixbuf)); return pixbuf; }
void TagExtractor::parseOneTag( const GstTagList * list, const gchar * tag, gpointer user_data ) { int i, num; num = gst_tag_list_get_tag_size( list, tag ); for (i = 0; i < num; ++i) { const GValue *val; val = gst_tag_list_get_value_index( list, tag, i ); if( g_strcmp0( tag, "artist" ) == 0 ) { g_print( " artist: %s", g_value_get_string( val ) ); } } }
static inline gboolean tag_list_has_tag (GstTagList * list, const gchar * tag, GType type) { const GValue *val = gst_tag_list_get_value_index (list, tag, 0); if (val == NULL) { GST_LOG ("no tag '%s' in taglist %" GST_PTR_FORMAT, tag, list); return FALSE; } if (!G_VALUE_HOLDS (val, type)) { GST_LOG ("tag '%s' in taglist %" GST_PTR_FORMAT " is not of type %s", tag, list, g_type_name (type)); return FALSE; } return TRUE; }
EXPORT_C #endif gboolean gst_tag_list_get_date_index (const GstTagList * list, const gchar * tag, guint index, GDate ** value) { const GValue *v; g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); g_return_val_if_fail (tag != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL) return FALSE; *value = (GDate *) g_value_dup_boxed (v); return (*value != NULL); }
static GUPnPDLNAStringValue get_string_value_from_tag_list (const GstTagList *tags, const gchar *name) { GUPnPDLNAStringValue value = GUPNP_DLNA_STRING_VALUE_UNSET; if (tags != NULL) { const GValue *g_value = gst_tag_list_get_value_index (tags, name, 0); if (g_value != NULL && G_VALUE_HOLDS_STRING (g_value)) { value.state = GUPNP_DLNA_VALUE_STATE_SET; value.value = g_value_dup_string (g_value); } } return value; }
static GUPnPDLNABoolValue get_bool_value_from_tag_list (const GstTagList *tags, const gchar *name) { GUPnPDLNABoolValue value = GUPNP_DLNA_BOOL_VALUE_UNSET; if (tags != NULL) { const GValue *g_value = gst_tag_list_get_value_index (tags, name, 0); if (g_value != NULL && G_VALUE_HOLDS_BOOLEAN (g_value)) { value.state = GUPNP_DLNA_VALUE_STATE_SET; value.value = g_value_get_boolean (g_value); } } return value; }
static void check_unsync_v24 (const GstTagList * tags, const gchar * file) { const GValue *val; GstSample *sample; GstBuffer *buf; gchar *album = NULL; gchar *title = NULL; gchar *artist = NULL; GstMapInfo map; fail_unless (gst_tag_list_get_string (tags, GST_TAG_TITLE, &title)); fail_unless (title != NULL); fail_unless_equals_string (title, "Starlight"); g_free (title); fail_unless (gst_tag_list_get_string (tags, GST_TAG_ALBUM, &album)); fail_unless (album != NULL); fail_unless_equals_string (album, "L'albumRockVol.4 CD1"); g_free (album); fail_unless (gst_tag_list_get_string (tags, GST_TAG_ARTIST, &artist)); fail_unless (artist != NULL); fail_unless_equals_string (artist, "Muse"); g_free (artist); val = gst_tag_list_get_value_index (tags, GST_TAG_IMAGE, 0); fail_unless (val != NULL); fail_unless (GST_VALUE_HOLDS_SAMPLE (val)); sample = gst_value_get_sample (val); fail_unless (sample != NULL); fail_unless (gst_sample_get_caps (sample) != NULL); buf = gst_sample_get_buffer (sample); fail_unless (buf != NULL); gst_buffer_map (buf, &map, GST_MAP_READ); fail_unless_equals_int (map.size, 38022); /* check for jpeg start/end markers */ fail_unless_equals_int (map.data[0], 0xff); fail_unless_equals_int (map.data[1], 0xd8); fail_unless_equals_int (map.data[38020], 0xff); fail_unless_equals_int (map.data[38021], 0xd9); gst_buffer_unmap (buf, &map); }
static gboolean gst_tag_list_has_ifd_tags (const GstTagList * taglist, const GstExifTagMatch * tag_map) { gint i; for (i = 0; tag_map[i].exif_tag != 0; i++) { if (tag_map[i].gst_tag == NULL) { if (tag_map[i].exif_tag == EXIF_GPS_IFD_TAG && gst_tag_list_has_ifd_tags (taglist, tag_map_gps)) return TRUE; continue; } if (gst_tag_list_get_value_index (taglist, tag_map[i].gst_tag, 0)) { return TRUE; } } return FALSE; }
static void print_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) { int i, num; num = gst_tag_list_get_tag_size (list, tag); for (i = 0; i < num; ++i) { const GValue *val; /* Note: when looking for specific tags, use the g_tag_list_get_xyz() API, * we only use the GValue approach here because it is more generic */ val = gst_tag_list_get_value_index (list, tag, i); if (G_VALUE_HOLDS_STRING (val)) { const char* unformatted = g_value_get_string (val); gchar* formatted = strescape(unformatted,"\"","\""); g_print ("(%s . \"%s\")\n", tag, formatted); g_free(formatted); } else if (G_VALUE_HOLDS_UINT (val)) { unsigned int uint = g_value_get_uint (val); if(uint > 0xf) g_print ("(%s . #x%x)\n", tag, uint); } else if (G_VALUE_HOLDS_DOUBLE (val)) { g_print ("(%s . %g)\n", tag, g_value_get_double (val)); } else if (G_VALUE_HOLDS_BOOLEAN (val)) { g_print ("(%s . %s)\n", tag, (g_value_get_boolean (val)) ? "#t" : "#f"); } else if (GST_VALUE_HOLDS_BUFFER (val)) { g_print ("(%s . (buffer %u))", tag, gst_buffer_get_size(gst_value_get_buffer (val))); } else if (GST_VALUE_HOLDS_DATE_TIME (val)) { GDate* date = (GDate*)g_value_get_boxed(val); g_print ("(%s . (date 0 0 0 %u %u %u))\n", tag, g_date_get_day(date), g_date_get_month(date), g_date_get_year (date)); } else { g_print ("(%20s . (type %s))", tag, G_VALUE_TYPE_NAME (val)); } } }
static GUPnPDLNAFractionValue get_fraction_value_from_tag_list (const GstTagList *tags, const gchar *name) { GUPnPDLNAFractionValue value = GUPNP_DLNA_FRACTION_VALUE_UNSET; if (tags != NULL) { const GValue *g_value = gst_tag_list_get_value_index (tags, name, 0); if (g_value != NULL && GST_VALUE_HOLDS_FRACTION (g_value)) { value.state = GUPNP_DLNA_VALUE_STATE_SET; value.numerator = gst_value_get_fraction_numerator (g_value); value.denominator = gst_value_get_fraction_denominator (g_value); } } return value; }
static GUPnPDLNAIntValue get_int_value_from_tag_list (const GstTagList *tags, const gchar *name) { GUPnPDLNAIntValue value = GUPNP_DLNA_INT_VALUE_UNSET; if (tags != NULL) { const GValue *g_value = gst_tag_list_get_value_index (tags, name, 0); if (g_value != NULL) { if (G_VALUE_HOLDS_INT (g_value)) { value.state = GUPNP_DLNA_VALUE_STATE_SET; value.value = g_value_get_int (g_value); } else if (G_VALUE_HOLDS_UINT (g_value)) { value.state = GUPNP_DLNA_VALUE_STATE_SET; value.value = g_value_get_uint (g_value); } } } return value; }
static const GValue * totem_gst_tag_list_get_cover_real (GstTagList *tag_list) { const GValue *cover_value = NULL; guint i; for (i = 0; ; i++) { const GValue *value; GstBuffer *buffer; GstStructure *caps_struct; int type; value = gst_tag_list_get_value_index (tag_list, GST_TAG_IMAGE, i); if (value == NULL) break; buffer = gst_value_get_buffer (value); caps_struct = gst_caps_get_structure (buffer->caps, 0); gst_structure_get_enum (caps_struct, "image-type", GST_TYPE_TAG_IMAGE_TYPE, &type); if (type == GST_TAG_IMAGE_TYPE_UNDEFINED) { if (cover_value == NULL) cover_value = value; } else if (type == GST_TAG_IMAGE_TYPE_FRONT_COVER) { cover_value = value; break; } } return cover_value; }
bool has_value(tag_list const &p_tag_list, std::string const &p_name) { g_assert(!p_name.empty()); return p_tag_list.is_empty() ? false : gst_tag_list_get_value_index(p_tag_list.get_tag_list(), p_name.c_str(), 0) != NULL; }
static GstBuffer * write_exif_ifd (const GstTagList * taglist, gboolean byte_order, guint32 base_offset, const GstExifTagMatch * tag_map) { GstExifWriter writer; gint i; GST_DEBUG ("Formatting taglist %p as exif buffer. Byte order: %d, " "base_offset: %u", taglist, byte_order, base_offset); g_assert (byte_order == G_LITTLE_ENDIAN || byte_order == G_BIG_ENDIAN); if (!gst_tag_list_has_ifd_tags (taglist, tag_map)) { GST_DEBUG ("No tags for this ifd"); return NULL; } gst_exif_writer_init (&writer, byte_order); /* write tag number as 0 */ gst_byte_writer_put_uint16_le (&writer.tagwriter, 0); /* write both tag headers and data * in ascending id order */ for (i = 0; tag_map[i].exif_tag != 0; i++) { /* special cases have NULL gst tag */ if (tag_map[i].gst_tag == NULL) { GstBuffer *inner_ifd = NULL; const GstExifTagMatch *inner_tag_map = NULL; GST_LOG ("Inner ifd tag: %x", tag_map[i].exif_tag); if (tag_map[i].exif_tag == EXIF_GPS_IFD_TAG) { inner_tag_map = tag_map_gps; } if (inner_tag_map) { /* The base offset for this inner ifd is the sum of: * - the current base offset * - the total tag data of current this ifd * - the total data of the current ifd * - its own tag entry length still to be writen (12) * - 4 bytes for the next ifd entry still to be writen */ inner_ifd = write_exif_ifd (taglist, byte_order, base_offset + gst_byte_writer_get_size (&writer.tagwriter) + gst_byte_writer_get_size (&writer.datawriter) + 12 + 4, inner_tag_map); } if (inner_ifd) { GST_DEBUG ("Adding inner ifd: %x", tag_map[i].exif_tag); gst_exif_writer_write_tag_header (&writer, tag_map[i].exif_tag, EXIF_TYPE_LONG, 1, gst_byte_writer_get_size (&writer.datawriter), FALSE); gst_byte_writer_put_data (&writer.datawriter, GST_BUFFER_DATA (inner_ifd), GST_BUFFER_SIZE (inner_ifd)); gst_buffer_unref (inner_ifd); } continue; } GST_LOG ("Checking tag %s", tag_map[i].gst_tag); if (gst_tag_list_get_value_index (taglist, tag_map[i].gst_tag, 0) == NULL) continue; write_exif_tag_from_taglist (&writer, taglist, &tag_map[i]); } /* Add the next IFD offset, we just set it to 0 because * there is no easy way to predict what it is going to be. * The user might rewrite the value if needed */ gst_byte_writer_put_uint32_le (&writer.tagwriter, 0); /* write the number of tags */ gst_byte_writer_set_pos (&writer.tagwriter, 0); if (writer.byte_order == G_LITTLE_ENDIAN) gst_byte_writer_put_uint16_le (&writer.tagwriter, writer.tags_total); else gst_byte_writer_put_uint16_be (&writer.tagwriter, writer.tags_total); /* now that we know the tag headers size, we can add the offsets */ gst_exif_tag_rewrite_offsets (&writer, base_offset); return gst_exif_writer_reset_and_get_buffer (&writer); }
// ---------------------------------------------------------------------------- // Handle the "tag" message void GStreamerImportFileHandle::OnTag(GstAppSink * WXUNUSED(appsink), GstTagList *tags) { // Collect all of the associates tags for (guint i = 0, icnt = gst_tag_list_n_tags(tags); i < icnt; i++) { wxString string; // Get tag name...should always succeed...no need to release const gchar *name = gst_tag_list_nth_tag_name(tags, i); if (!name) { continue; } // For each tag, determine its type and retrieve if possible for (guint j = 0, jcnt = gst_tag_list_get_tag_size(tags, name); j < jcnt; j++) { const GValue *val; val = gst_tag_list_get_value_index(tags, name, j); if (G_VALUE_HOLDS_STRING(val)) { string = wxString::FromUTF8(g_value_get_string(val)); } else if (G_VALUE_HOLDS_UINT(val)) { string.Printf(wxT("%u"), (unsigned int) g_value_get_uint(val)); } else if (G_VALUE_HOLDS_DOUBLE(val)) { string.Printf(wxT("%g"), g_value_get_double(val)); } else if (G_VALUE_HOLDS_BOOLEAN(val)) { string = g_value_get_boolean(val) ? wxT("true") : wxT("false"); } else if (GST_VALUE_HOLDS_DATE_TIME(val)) { GstDateTime *dt = (GstDateTime *) g_value_get_boxed(val); gchar *str = gst_date_time_to_iso8601_string(dt); string = wxString::FromUTF8(str).c_str(); g_free(str); } else if (G_VALUE_HOLDS(val, G_TYPE_DATE)) { gchar *str = gst_value_serialize(val); string = wxString::FromUTF8(str).c_str(); g_free(str); } else { wxLogMessage(wxT("Tag %s has unhandled type: %s"), wxString::FromUTF8(name).c_str(), wxString::FromUTF8(G_VALUE_TYPE_NAME(val)).c_str()); continue; } // Translate known tag names wxString tag; if (strcmp(name, GST_TAG_TITLE) == 0) { tag = TAG_TITLE; } else if (strcmp(name, GST_TAG_ARTIST) == 0) { tag = TAG_ARTIST; } else if (strcmp(name, GST_TAG_ALBUM) == 0) { tag = TAG_ALBUM; } else if (strcmp(name, GST_TAG_TRACK_NUMBER) == 0) { tag = TAG_TRACK; } else if (strcmp(name, GST_TAG_DATE) == 0) { tag = TAG_YEAR; } else if (strcmp(name, GST_TAG_GENRE) == 0) { tag = TAG_GENRE; } else if (strcmp(name, GST_TAG_COMMENT) == 0) { tag = TAG_COMMENTS; } else { tag = wxString::FromUTF8(name).c_str(); } if (jcnt > 1) { tag.Printf(wxT("%s:%d"), tag.c_str(), j); } // Store the tag mTags.SetTag(tag, string); } } }
/* * Makes a pipeline in the form: * filesrc location=file ! demuxer ! fakesink * * And gets the tags that are posted on the bus to compare * with the tags in 'tag_str' */ static void test_demux_tags (const gchar * tag_str, const gchar * demuxer, const gchar * file) { GstElement *pipeline; GstBus *bus; GMainLoop *loop; GstTagList *sent_tags; gint i, j, k, n_recv, n_sent; const gchar *name_sent, *name_recv; const GValue *value_sent, *value_recv; gboolean found; gint comparison; GstElement *demux; gchar *launch_str; guint bus_watch = 0; GST_DEBUG ("testing tags : %s", tag_str); if (received_tags) { gst_tag_list_free (received_tags); received_tags = NULL; } launch_str = g_strdup_printf ("filesrc location=%s ! %s name=demux ! " "fakesink", file, demuxer); pipeline = gst_parse_launch (launch_str, NULL); g_free (launch_str); fail_unless (pipeline != NULL); demux = gst_bin_get_by_name (GST_BIN (pipeline), "demux"); fail_unless (demux != NULL); loop = g_main_loop_new (NULL, TRUE); fail_unless (loop != NULL); bus = gst_element_get_bus (pipeline); fail_unless (bus != NULL); bus_watch = gst_bus_add_watch (bus, bus_handler, loop); gst_object_unref (bus); sent_tags = gst_tag_list_new_from_string (tag_str); fail_unless (sent_tags != NULL); gst_element_set_state (pipeline, GST_STATE_PLAYING); g_main_loop_run (loop); GST_DEBUG ("mainloop done : %p", received_tags); /* verify tags */ fail_unless (received_tags != NULL); n_recv = gst_tag_list_n_tags (received_tags); n_sent = gst_tag_list_n_tags (sent_tags); fail_unless (n_recv >= n_sent); /* FIXME: compare taglits values */ for (i = 0; i < n_sent; i++) { name_sent = gst_tag_list_nth_tag_name (sent_tags, i); found = FALSE; for (j = 0; j < n_recv; j++) { name_recv = gst_tag_list_nth_tag_name (received_tags, j); if (!strcmp (name_sent, name_recv)) { guint sent_len, recv_len; sent_len = gst_tag_list_get_tag_size (sent_tags, name_sent); recv_len = gst_tag_list_get_tag_size (received_tags, name_recv); fail_unless (sent_len == recv_len, "tag item %s has been received with different size", name_sent); for (k = 0; k < sent_len; k++) { value_sent = gst_tag_list_get_value_index (sent_tags, name_sent, k); value_recv = gst_tag_list_get_value_index (received_tags, name_recv, k); comparison = gst_value_compare (value_sent, value_recv); if (comparison != GST_VALUE_EQUAL) { gchar *vs = g_strdup_value_contents (value_sent); gchar *vr = g_strdup_value_contents (value_recv); GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'", G_VALUE_TYPE_NAME (value_sent), vs, G_VALUE_TYPE_NAME (value_recv), vr); g_free (vs); g_free (vr); } fail_unless (comparison == GST_VALUE_EQUAL, "tag item %s has been received with different type or value", name_sent); found = TRUE; break; } } } fail_unless (found, "tag item %s is lost", name_sent); } gst_tag_list_free (received_tags); received_tags = NULL; gst_tag_list_free (sent_tags); gst_element_set_state (pipeline, GST_STATE_NULL); g_main_loop_unref (loop); g_object_unref (demux); g_object_unref (pipeline); g_source_remove (bus_watch); }
GValue const * get_raw_value(tag_list const &p_tag_list, std::string const &p_name, const guint p_index) { g_assert(!p_name.empty()); return p_tag_list.is_empty() ? NULL : gst_tag_list_get_value_index(p_tag_list.get_tag_list(), p_name.c_str(), p_index); }
static void send_tag (const GstTagList * list, const gchar * tag, gpointer data) { InsanityGstPipelineTest *ptest = INSANITY_GST_PIPELINE_TEST (data); gint i, count; GValue string_value = { 0 }; char label[48]; count = gst_tag_list_get_tag_size (list, tag); g_value_init (&string_value, G_TYPE_STRING); ptest->priv->tag_count++; for (i = 0; i < count; i++) { gchar *str; if (gst_tag_get_type (tag) == G_TYPE_STRING) { if (!gst_tag_list_get_string_index (list, tag, i, &str)) g_assert_not_reached (); } else if (gst_tag_get_type (tag) == GST_TYPE_SAMPLE) { GstSample *img; img = gst_value_get_sample (gst_tag_list_get_value_index (list, tag, i)); if (img) { GstBuffer *buffer; GstCaps *caps; gchar *caps_str; buffer = gst_sample_get_buffer (img); caps = gst_sample_get_caps (img); caps_str = caps ? gst_caps_to_string (caps) : g_strdup ("unknown"); str = g_strdup_printf ("sample of %" G_GSIZE_FORMAT " bytes, type: %s", gst_buffer_get_size (buffer), caps_str); g_free (caps_str); } else { str = g_strdup ("NULL sample"); } } else if (gst_tag_get_type (tag) == GST_TYPE_DATE_TIME) { GstDateTime *dt = NULL; gst_tag_list_get_date_time_index (list, tag, i, &dt); str = gst_date_time_to_iso8601_string (dt); gst_date_time_unref (dt); } else { str = g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i)); } if (i == 0) { g_value_set_string (&string_value, gst_tag_get_nick (tag)); snprintf (label, sizeof (label), "tags.%u.id", ptest->priv->tag_count); insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value); g_value_reset (&string_value); } g_value_set_string (&string_value, str); if (count > 1) snprintf (label, sizeof (label), "tags.%u.value.%u", ptest->priv->tag_count, i); else snprintf (label, sizeof (label), "tags.%u.value", ptest->priv->tag_count); insanity_test_set_extra_info (INSANITY_TEST (ptest), label, &string_value); g_value_reset (&string_value); g_free (str); } }
static void metadatamux_exif_for_each_tag_in_list (const GstTagList * list, const gchar * tag, gpointer user_data) { ExifData *ed = (ExifData *) user_data; ExifTag exif_tag; GType type = G_TYPE_INVALID; ExifEntry *entry = NULL; ExifIfd ifd = EXIF_IFD_COUNT; const ExifByteOrder byte_order = exif_data_get_byte_order (ed); exif_tag = metadatamux_exif_get_exif_from_tag (tag, &type, &ifd); if (!exif_tag) goto done; entry = exif_data_get_entry (ed, exif_tag); if (entry) exif_entry_ref (entry); else { entry = exif_entry_new (); exif_content_add_entry (ed->ifd[ifd], entry); exif_entry_initialize (entry, exif_tag); } if (entry->data == NULL) { if (entry->tag == EXIF_TAG_GPS_ALTITUDE) { entry->format = EXIF_FORMAT_RATIONAL; entry->components = 1; entry->size = exif_format_get_size (entry->format) * entry->components; entry->data = g_malloc (entry->size); } else if (entry->tag == EXIF_TAG_GPS_LATITUDE || entry->tag == EXIF_TAG_GPS_LONGITUDE) { entry->format = EXIF_FORMAT_RATIONAL; entry->components = 3; entry->size = exif_format_get_size (entry->format) * entry->components; entry->data = g_malloc (entry->size); } } if (type == GST_TYPE_FRACTION) { const GValue *gvalue = gst_tag_list_get_value_index (list, tag, 0); gint numerator = gst_value_get_fraction_numerator (gvalue); gint denominator = gst_value_get_fraction_denominator (gvalue); switch (entry->format) { case EXIF_FORMAT_SRATIONAL: { ExifSRational sr = { numerator, denominator }; exif_set_srational (entry->data, byte_order, sr); } break; case EXIF_FORMAT_RATIONAL: { ExifRational r; if (entry->tag == EXIF_TAG_X_RESOLUTION || entry->tag == EXIF_TAG_Y_RESOLUTION) { ExifEntry *unit_entry = NULL; unit_entry = exif_data_get_entry (ed, EXIF_TAG_RESOLUTION_UNIT); if (unit_entry) { ExifShort vsh = exif_get_short (unit_entry->data, byte_order); if (vsh != 2) /* inches */ exif_set_short (unit_entry->data, byte_order, 2); } } r.numerator = numerator; r.denominator = denominator; if (numerator < 0) r.numerator = -numerator; if (denominator < 0) r.denominator = -denominator; exif_set_rational (entry->data, byte_order, r); } break; default: break; } } else if (type == GST_TYPE_BUFFER) { const GValue *val = NULL; GstBuffer *buf; val = gst_tag_list_get_value_index (list, tag, 0); buf = gst_value_get_buffer (val); entry->components = GST_BUFFER_SIZE (buf); entry->size = GST_BUFFER_SIZE (buf); entry->data = g_malloc (entry->size); memcpy (entry->data, GST_BUFFER_DATA (buf), entry->size); } else { switch (type) { case G_TYPE_STRING: { gchar *value = NULL; if (gst_tag_list_get_string (list, tag, &value)) { if (entry->tag == EXIF_TAG_DATE_TIME_DIGITIZED || entry->tag == EXIF_TAG_DATE_TIME || entry->tag == EXIF_TAG_DATE_TIME_ORIGINAL) { GString *datetime = g_string_new_len (value, 20); /* enough memory to hold "YYYY:MM:DD HH:MM:SS" */ if (metadatamux_exif_convert_from_datetime (datetime)) { } else { GST_ERROR ("Unexpected date & time format for %s", tag); } g_free (value); value = datetime->str; g_string_free (datetime, FALSE); } else if (value) { entry->components = strlen (value) + 1; entry->size = exif_format_get_size (entry->format) * entry->components; entry->data = (guint8 *) value; value = NULL; } } } break; case G_TYPE_UINT: case G_TYPE_INT: { gint value; ExifShort v_short; if (G_TYPE_UINT == type) { gst_tag_list_get_uint (list, tag, (guint *) & value); } else { gst_tag_list_get_int (list, tag, &value); } switch (entry->format) { case EXIF_FORMAT_SHORT: if (entry->tag == EXIF_TAG_CONTRAST || entry->tag == EXIF_TAG_SATURATION) { if (value < -33) value = 1; /* low */ else if (value < 34) value = 0; /* normal */ else value = 2; /* high */ } v_short = value; exif_set_short (entry->data, byte_order, v_short); break; case EXIF_FORMAT_LONG: exif_set_long (entry->data, byte_order, value); break; default: break; } } break; case G_TYPE_DOUBLE: { gdouble value; gst_tag_list_get_double (list, tag, &value); if (entry->tag == EXIF_TAG_GPS_LATITUDE || entry->tag == EXIF_TAG_GPS_LONGITUDE) { ExifRational *rt = (ExifRational *) entry->data; gdouble v = fabs (value); ExifEntry *ref_entry = NULL; char ref; const ExifTag ref_tag = entry->tag == EXIF_TAG_GPS_LATITUDE ? EXIF_TAG_GPS_LATITUDE_REF : EXIF_TAG_GPS_LONGITUDE_REF; /* DDD - degrees */ rt->numerator = (gulong) v; rt->denominator = 1; GST_DEBUG ("deg: %lf : %lu / %lu", v, (gulong) rt->numerator, (gulong) rt->denominator); v -= rt->numerator; rt++; /* MM - minutes */ rt->numerator = (gulong) (v * 60.0); rt->denominator = 1; GST_DEBUG ("min: %lf : %lu / %lu", v, (gulong) rt->numerator, (gulong) rt->denominator); v -= ((gdouble) rt->numerator / 60.0); rt++; /* SS - seconds */ rt->numerator = (gulong) (0.5 + v * 3600.0); rt->denominator = 1; GST_DEBUG ("sec: %lf : %lu / %lu", v, (gulong) rt->numerator, (gulong) rt->denominator); if (entry->tag == EXIF_TAG_GPS_LONGITUDE) { GST_DEBUG ("longitude : %lf", value); ref = (value < 0.0) ? 'W' : 'E'; } else { GST_DEBUG ("latitude : %lf", value); ref = (value < 0.0) ? 'S' : 'N'; } ref_entry = exif_data_get_entry (ed, ref_tag); if (ref_entry) { exif_entry_ref (ref_entry); } else { ref_entry = exif_entry_new (); exif_content_add_entry (ed->ifd[EXIF_IFD_GPS], ref_entry); exif_entry_initialize (ref_entry, ref_tag); } if (ref_entry->data == NULL) { ref_entry->format = EXIF_FORMAT_ASCII; ref_entry->components = 2; ref_entry->size = 2; ref_entry->data = g_malloc (2); } ref_entry->data[0] = ref; ref_entry->data[1] = 0; exif_entry_unref (ref_entry); } else if (entry->tag == EXIF_TAG_GPS_ALTITUDE) { ExifEntry *ref_entry = NULL; ExifRational *rt = (ExifRational *) entry->data; rt->numerator = (gulong) fabs (10.0 * value); rt->denominator = 10; GST_DEBUG ("altitude : %lf", value); ref_entry = exif_data_get_entry (ed, EXIF_TAG_GPS_ALTITUDE_REF); if (ref_entry) { exif_entry_ref (ref_entry); } else { ref_entry = exif_entry_new (); exif_content_add_entry (ed->ifd[EXIF_IFD_GPS], ref_entry); exif_entry_initialize (ref_entry, EXIF_TAG_GPS_ALTITUDE_REF); } if (ref_entry->data == NULL) { ref_entry->format = EXIF_FORMAT_BYTE; ref_entry->components = 1; ref_entry->size = 1; ref_entry->data = g_malloc (1); } if (value > 0.0) { ref_entry->data[0] = 0; } else { ref_entry->data[0] = 1; } exif_entry_unref (ref_entry); } } break; default: break; } } done: if (entry) exif_entry_unref (entry); }