static gboolean get_info_from_tags (GstPad * pad, GstEvent ** event, gpointer user_data) { GstSDPMedia *media = (GstSDPMedia *) user_data; if (GST_EVENT_TYPE (*event) == GST_EVENT_TAG) { GstTagList *tags; guint bitrate = 0; gst_event_parse_tag (*event, &tags); if (gst_tag_list_get_scope (tags) != GST_TAG_SCOPE_STREAM) return TRUE; if (!gst_tag_list_get_uint (tags, GST_TAG_MAXIMUM_BITRATE, &bitrate) || bitrate == 0) if (!gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &bitrate) || bitrate == 0) return TRUE; /* set bandwidth (kbits/s) */ gst_sdp_media_add_bandwidth (media, GST_SDP_BWTYPE_AS, bitrate / 1000); return FALSE; } return TRUE; }
static gboolean gst_h263_parse_sink_event (GstBaseParse * parse, GstEvent * event) { GstH263Parse *h263parse; gboolean res = FALSE; h263parse = GST_H263_PARSE (parse); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_TAG: { GstTagList *taglist; gst_event_parse_tag (event, &taglist); if (gst_tag_list_get_uint (taglist, GST_TAG_BITRATE, &h263parse->bitrate)) GST_DEBUG_OBJECT (h263parse, "got bitrate tag: %u", h263parse->bitrate); break; } default: break; } return res; }
static GstPadProbeReturn tag_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data) { GstEvent *event = gst_pad_probe_info_get_event (info); if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) { KmsEncTreeBin *self = data; GstTagList *taglist; guint bitrate; gst_event_parse_tag (event, &taglist); if (gst_tag_list_get_uint (taglist, "bitrate", &bitrate)) { self->priv->tag_bitrate = bitrate; kms_enc_tree_bin_set_target_bitrate (self); } } return GST_PAD_PROBE_OK; }
/* Extract some metadata from the streams and print it on the screen */ static void analyze_streams (CustomData *data) { gint i; GstTagList *tags; gchar *str; guint rate; /* Read some properties */ g_object_get (data->playbin2, "n-video", &data->n_video, NULL); g_object_get (data->playbin2, "n-audio", &data->n_audio, NULL); g_object_get (data->playbin2, "n-text", &data->n_text, NULL); g_print ("%d video stream(s), %d audio stream(s), %d text stream(s)\n", data->n_video, data->n_audio, data->n_text); g_print ("\n"); for (i = 0; i < data->n_video; i++) { tags = NULL; /* Retrieve the stream's video tags */ g_signal_emit_by_name (data->playbin2, "get-video-tags", i, &tags); if (tags) { g_print ("video stream %d:\n", i); gst_tag_list_get_string (tags, GST_TAG_VIDEO_CODEC, &str); g_print (" codec: %s\n", str ? str : "unknown"); g_free (str); gst_tag_list_free (tags); } } g_print ("\n"); for (i = 0; i < data->n_audio; i++) { tags = NULL; /* Retrieve the stream's audio tags */ g_signal_emit_by_name (data->playbin2, "get-audio-tags", i, &tags); if (tags) { g_print ("audio stream %d:\n", i); if (gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str)) { g_print (" codec: %s\n", str); g_free (str); } if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) { g_print (" language: %s\n", str); g_free (str); } if (gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate)) { g_print (" bitrate: %d\n", rate); } gst_tag_list_free (tags); } } g_print ("\n"); for (i = 0; i < data->n_text; i++) { tags = NULL; /* Retrieve the stream's subtitle tags */ g_signal_emit_by_name (data->playbin2, "get-text-tags", i, &tags); if (tags) { g_print ("subtitle stream %d:\n", i); if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) { g_print (" language: %s\n", str); g_free (str); } gst_tag_list_free (tags); } } g_object_get (data->playbin2, "current-video", &data->current_video, NULL); g_object_get (data->playbin2, "current-audio", &data->current_audio, NULL); g_object_get (data->playbin2, "current-text", &data->current_text, NULL); g_print ("\n"); g_print ("Currently playing video stream %d, audio stream %d and text stream %d\n", data->current_video, data->current_audio, data->current_text); g_print ("Type any number and hit ENTER to select a different audio stream\n"); }
static void test_taglib_id3mux_check_tags (GstTagList * tags, guint32 mask) { if (mask & (1 << 0)) { gchar *s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_ARTIST, &s)); fail_unless (g_str_equal (s, TEST_ARTIST)); g_free (s); } if (mask & (1 << 1)) { gchar *s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_TITLE, &s)); fail_unless (g_str_equal (s, TEST_TITLE)); g_free (s); } if (mask & (1 << 2)) { gchar *s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_ALBUM, &s)); fail_unless (g_str_equal (s, TEST_ALBUM)); g_free (s); } if (mask & (1 << 3)) { GDate *shouldbe, *date = NULL; shouldbe = TEST_DATE; fail_unless (gst_tag_list_get_date (tags, GST_TAG_DATE, &date)); fail_unless (g_date_compare (shouldbe, date) == 0); g_date_free (shouldbe); g_date_free (date); } if (mask & (1 << 4)) { guint num; fail_unless (gst_tag_list_get_uint (tags, GST_TAG_TRACK_NUMBER, &num)); fail_unless (num == TEST_TRACK_NUMBER); } if (mask & (1 << 5)) { guint count; fail_unless (gst_tag_list_get_uint (tags, GST_TAG_TRACK_COUNT, &count)); fail_unless (count == TEST_TRACK_COUNT); } if (mask & (1 << 6)) { guint num; fail_unless (gst_tag_list_get_uint (tags, GST_TAG_ALBUM_VOLUME_NUMBER, &num)); fail_unless (num == TEST_VOLUME_NUMBER); } if (mask & (1 << 7)) { guint count; fail_unless (gst_tag_list_get_uint (tags, GST_TAG_ALBUM_VOLUME_COUNT, &count)); fail_unless (count == TEST_VOLUME_COUNT); } if (mask & (1 << 8)) { gdouble gain; fail_unless (gst_tag_list_get_double (tags, GST_TAG_TRACK_GAIN, &gain)); fail_unless_sorta_equals_float (gain, TEST_TRACK_GAIN); } if (mask & (1 << 9)) { gdouble gain; fail_unless (gst_tag_list_get_double (tags, GST_TAG_ALBUM_GAIN, &gain)); fail_unless_sorta_equals_float (gain, TEST_ALBUM_GAIN); } if (mask & (1 << 10)) { gdouble peak; fail_unless (gst_tag_list_get_double (tags, GST_TAG_TRACK_PEAK, &peak)); fail_unless_sorta_equals_float (peak, TEST_TRACK_PEAK); } if (mask & (1 << 11)) { gdouble peak; fail_unless (gst_tag_list_get_double (tags, GST_TAG_ALBUM_PEAK, &peak)); fail_unless_sorta_equals_float (peak, TEST_ALBUM_PEAK); } if (mask & (1 << 12)) { gdouble bpm; fail_unless (gst_tag_list_get_double (tags, GST_TAG_BEATS_PER_MINUTE, &bpm)); fail_unless_sorta_equals_float (bpm, TEST_BPM); } if (mask & (1 << 13)) { } }
static gboolean gst_async_watch(GstBus *bus, GstMessage *message, gpointer data) { gstPlay *play = (gstPlay *)data; if (play == NULL) return FALSE; switch (GST_MESSAGE_TYPE (message)) { // the pipeline state has changed case GST_MESSAGE_STATE_CHANGED: { GstState new_state; gst_message_parse_state_changed (message, NULL, &new_state, NULL); if (new_state == GST_STATE_PAUSED) { if (play->info_loaded == FALSE) { if (gst_binding_load_video_info (play)) { play->info_loaded = TRUE; if(play->info_cb != NULL) { play->info_cb (play->video_info); } } } } break; } // and error occurred in the pipeline case GST_MESSAGE_ERROR: { if(play->error_cb != NULL) { GError *error; gchar *debug; gst_message_parse_error (message, &error, &debug); play->error_cb (error->message, debug); g_error_free (error); g_free (debug); } break; } // the media file finished playing case GST_MESSAGE_EOS: { if(play->eos_cb != NULL) play->eos_cb(); break; } // the media file is being buffered case GST_MESSAGE_BUFFERING: { const GstStructure *buffer; gint prog = 0; buffer = gst_message_get_structure (message); if(gst_structure_get_int (buffer, "buffer-percent", &prog)) if(play->buffer_cb != NULL) play->buffer_cb(prog); break; } // the media file has a tag case GST_MESSAGE_TAG: { play->tag = g_new0 (gstTag, 1); GstTagList *tags; gst_message_parse_tag (message, &tags); guint64 duration; guint current_track; guint track_count; char *disc_id; char *music_brainz_id; // track number if (gst_tag_list_get_uint (tags, GST_TAG_TRACK_NUMBER, ¤t_track)) play->tag->current_track = current_track; // total tracks if (gst_tag_list_get_uint (tags, GST_TAG_TRACK_COUNT, &track_count)) play->tag->track_count = track_count; // track duration if (gst_tag_list_get_uint64 (tags, GST_TAG_DURATION, &duration)) play->tag->duration = duration; // track cddb disc id if (gst_tag_list_get_string (tags, GST_TAG_CDDA_CDDB_DISCID, &disc_id)) play->tag->disc_id = disc_id; // track music brainz disc id if (gst_tag_list_get_string (tags, GST_TAG_CDDA_MUSICBRAINZ_DISCID, &music_brainz_id)) play->tag->music_brainz_id = music_brainz_id; if(play->tag_cb != NULL) play->tag_cb (play->tag); break; } //By default, do nothing default: break; } return TRUE; }
static void add_metadata_from_tag (GFileInfo *info, const GstTagList *list, const char *tag, const char *tag_key) { GType tag_type; tag_type = gst_tag_get_type (tag); if (tag_type == G_TYPE_BOOLEAN) { gboolean ret; if (gst_tag_list_get_boolean (list, tag, &ret)) { if (ret) add_metadata (info, tag_key, g_strdup ("TRUE"), NULL); else add_metadata (info, tag_key, g_strdup ("FALSE"), NULL); } } if (tag_type == G_TYPE_STRING) { char *ret = NULL; if (gst_tag_list_get_string (list, tag, &ret)) add_metadata (info, tag_key, ret, NULL); } if (tag_type == G_TYPE_UCHAR) { guint ret = 0; if (gst_tag_list_get_uint (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%u", ret), NULL); } if (tag_type == G_TYPE_CHAR) { int ret = 0; if (gst_tag_list_get_int (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%d", ret), NULL); } if (tag_type == G_TYPE_UINT) { guint ret = 0; if (gst_tag_list_get_uint (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%u", ret), NULL); } if (tag_type == G_TYPE_INT) { gint ret = 0; if (gst_tag_list_get_int (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%d", ret), NULL); } if (tag_type == G_TYPE_ULONG) { guint64 ret = 0; if (gst_tag_list_get_uint64 (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%" G_GUINT64_FORMAT, ret), NULL); } if (tag_type == G_TYPE_LONG) { gint64 ret = 0; if (gst_tag_list_get_int64 (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%" G_GINT64_FORMAT, ret), NULL); } if (tag_type == G_TYPE_INT64) { gint64 ret = 0; if (gst_tag_list_get_int64 (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%" G_GINT64_FORMAT, ret), NULL); } if (tag_type == G_TYPE_UINT64) { guint64 ret = 0; if (gst_tag_list_get_uint64 (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%" G_GUINT64_FORMAT, ret), NULL); } if (tag_type == G_TYPE_DOUBLE) { gdouble ret = 0; if (gst_tag_list_get_double (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%f", ret), NULL); } if (tag_type == G_TYPE_FLOAT) { gfloat ret = 0; if (gst_tag_list_get_float (list, tag, &ret)) add_metadata (info, tag_key, g_strdup_printf ("%f", ret), NULL); } if (tag_type == G_TYPE_DATE) { GDate *ret = NULL; if (gst_tag_list_get_date (list, tag, &ret)) { if (ret != NULL) { char buf[128]; char *raw; char *formatted; g_date_strftime (buf, 10, "%F %T", ret); raw = g_strdup (buf); g_date_strftime (buf, 10, "%x %X", ret); formatted = g_strdup (buf); add_metadata (info, tag_key, raw, formatted); } g_free (ret); } } }
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); }
static void test_taglib_apev2mux_check_tags (GstTagList * tags, guint32 mask) { if (mask & (1 << 0)) { gchar *s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_ARTIST, &s)); fail_unless (g_str_equal (s, TEST_ARTIST)); g_free (s); } if (mask & (1 << 1)) { gchar *s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_TITLE, &s)); fail_unless (g_str_equal (s, TEST_TITLE)); g_free (s); } if (mask & (1 << 2)) { gchar *s = NULL; fail_unless (gst_tag_list_get_string (tags, GST_TAG_ALBUM, &s)); fail_unless (g_str_equal (s, TEST_ALBUM)); g_free (s); } if (mask & (1 << 3)) { GDate *shouldbe, *date = NULL; shouldbe = TEST_DATE; fail_unless (gst_tag_list_get_date (tags, GST_TAG_DATE, &date)); fail_unless (g_date_compare (shouldbe, date) == 0); g_date_free (shouldbe); g_date_free (date); } if (mask & (1 << 4)) { guint num; fail_unless (gst_tag_list_get_uint (tags, GST_TAG_TRACK_NUMBER, &num)); fail_unless (num == TEST_TRACK_NUMBER); } if (mask & (1 << 5)) { guint count; fail_unless (gst_tag_list_get_uint (tags, GST_TAG_TRACK_COUNT, &count)); fail_unless (count == TEST_TRACK_COUNT); } if (mask & (1 << 6)) { gdouble gain; fail_unless (gst_tag_list_get_double (tags, GST_TAG_TRACK_GAIN, &gain)); fail_unless (gain == TEST_TRACK_GAIN); } if (mask & (1 << 7)) { gdouble gain; fail_unless (gst_tag_list_get_double (tags, GST_TAG_ALBUM_GAIN, &gain)); fail_unless (gain == TEST_ALBUM_GAIN); } if (mask & (1 << 8)) { } if (mask & (1 << 9)) { } if (mask & (1 << 10)) { } if (mask & (1 << 11)) { } if (mask & (1 << 12)) { } if (mask & (1 << 13)) { } }
static GstCaps * caps_from_video_stream_info (GstDiscovererStreamInfo *info) { GstCaps *temp = gst_discoverer_stream_info_get_caps (info); GstCaps *caps = gst_caps_copy (temp); const GstDiscovererVideoInfo *video_info = GST_DISCOVERER_VIDEO_INFO (info); const GstTagList *stream_tag_list; guint n, d, data; gboolean value; gst_caps_unref (temp); data = gst_discoverer_video_info_get_height (video_info); if (data) gst_caps_set_simple (caps, "height", G_TYPE_INT, data, NULL); data = gst_discoverer_video_info_get_width (video_info); if (data) gst_caps_set_simple (caps, "width", G_TYPE_INT, data, NULL); data = gst_discoverer_video_info_get_depth (video_info); if (data) gst_caps_set_simple (caps, "depth", G_TYPE_INT, data, NULL); n = gst_discoverer_video_info_get_framerate_num (video_info); d = gst_discoverer_video_info_get_framerate_denom (video_info); if (n && d) gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, n, d, NULL); n = gst_discoverer_video_info_get_par_num (video_info); d = gst_discoverer_video_info_get_par_denom (video_info); if (n && d) gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION, n, d, NULL); value = gst_discoverer_video_info_is_interlaced (video_info); if (value) gst_caps_set_simple (caps, "interlaced", G_TYPE_BOOLEAN, value, NULL); stream_tag_list = gst_discoverer_stream_info_get_tags (info); if (stream_tag_list) { guint bitrate; if (gst_tag_list_get_uint (stream_tag_list, "bitrate", &bitrate)) gst_caps_set_simple (caps, "bitrate", G_TYPE_INT, (int) bitrate, NULL); if (gst_tag_list_get_uint (stream_tag_list, "maximum-bitrate", &bitrate)) gst_caps_set_simple (caps, "maximum-bitrate", G_TYPE_INT, (int) bitrate, NULL); } return caps; }
static void rc_tag_get_tag(const GstTagList *tags, RCMusicMetaData *mmd) { gchar *tag_title = NULL; gchar *tag_artist = NULL; gchar *tag_filetype = NULL; gchar *tag_album = NULL; gchar *tag_comment = NULL; gchar *tag_cuelist = NULL; GstBuffer *tag_image = NULL; guint bitrates = 0; guint tracknum = 0; guint tag_cue_num = 0; guint i = 0; if(mmd==NULL || mmd->uri==NULL || tags==NULL) return; if(gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &tag_filetype)) { if(tag_filetype!=NULL) { if(mmd->file_type!=NULL) g_free(mmd->file_type); mmd->file_type = g_strdup(tag_filetype); g_free(tag_filetype); } } if(gst_tag_list_get_string(tags, GST_TAG_TITLE, &tag_title)) { if(tag_title!=NULL) { if(mmd->title!=NULL) g_free(mmd->title); mmd->title = g_strdup(tag_title); g_free(tag_title); } } if(gst_tag_list_get_string(tags, GST_TAG_ARTIST, &tag_artist)) { if(tag_artist!=NULL) { if(mmd->artist!=NULL) g_free(mmd->artist); mmd->artist = g_strdup(tag_artist); g_free(tag_artist); } } if(gst_tag_list_get_string(tags, GST_TAG_ALBUM, &tag_album)) { if(tag_album!=NULL) { if(mmd->album!=NULL) g_free(mmd->album); mmd->album = g_strdup(tag_album); g_free(tag_album); } } if(gst_tag_list_get_string(tags, GST_TAG_COMMENT, &tag_comment)) { if(tag_comment!=NULL) { if(mmd->comment!=NULL) g_free(mmd->comment); mmd->comment = g_strdup(tag_comment); g_free(tag_comment); } } if(gst_tag_list_get_buffer(tags, GST_TAG_IMAGE, &tag_image)) { if(tag_image!=NULL) { if(mmd->image!=NULL) gst_buffer_unref(mmd->image); mmd->image = tag_image; } } if(gst_tag_list_get_buffer(tags, GST_TAG_PREVIEW_IMAGE, &tag_image)) { if(tag_image==NULL) mmd->image = tag_image; else gst_buffer_unref(tag_image); } if(gst_tag_list_get_uint(tags, GST_TAG_NOMINAL_BITRATE, &bitrates)) if(bitrates>0) mmd->bitrate = bitrates; if(gst_tag_list_get_uint(tags, GST_TAG_TRACK_NUMBER, &tracknum)) mmd->tracknum = tracknum; tag_cue_num = gst_tag_list_get_tag_size(tags, GST_TAG_EXTENDED_COMMENT); for(i=0;i<tag_cue_num && mmd->emb_cue==NULL;i++) { if(gst_tag_list_get_string_index(tags, GST_TAG_EXTENDED_COMMENT, i, &tag_cuelist)) { if(!strncmp(tag_cuelist, "cuesheet=", 9)) { if(mmd->emb_cue!=NULL) g_free(mmd->emb_cue); mmd->emb_cue = g_strdup(tag_cuelist+9); } if(tag_cuelist!=NULL) g_free(tag_cuelist); } } }
void TagExtractor::readTags( const gchar* filename ) { freeData(); GstElement *pipe, *dec, *sink; GstMessage *msg; GError* conversion_error = NULL; file_uri = g_filename_to_uri( filename, NULL, &conversion_error ); pipe = gst_pipeline_new( "pipeline" ); dec = gst_element_factory_make( "uridecodebin", NULL ); g_object_set( dec, "uri", file_uri, NULL ); gst_bin_add( GST_BIN (pipe), dec ); sink = gst_element_factory_make( "fakesink", NULL ); gst_bin_add( GST_BIN (pipe), sink ); g_signal_connect( dec, "pad-added", G_CALLBACK (TagExtractor::onNewPad), sink ); gst_element_set_state( pipe, GST_STATE_PAUSED ); g_print( "%s ", filename ); while( TRUE) { GstTagList *tags = NULL; msg = gst_bus_timed_pop_filtered( GST_ELEMENT_BUS (pipe), GST_CLOCK_TIME_NONE, (GstMessageType) (GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_TAG | GST_MESSAGE_ERROR) ); if( GST_MESSAGE_TYPE (msg) != GST_MESSAGE_TAG ) /* error or async_done */ break; gst_message_parse_tag( msg, &tags ); // Try to read all of the tags we care about gst_tag_list_get_string( tags, GST_TAG_ARTIST, &artist ); gst_tag_list_get_string( tags, GST_TAG_ALBUM, &album ); gst_tag_list_get_string( tags, GST_TAG_ALBUM_ARTIST, &album_artist ); gst_tag_list_get_string( tags, GST_TAG_TITLE, &title ); gst_tag_list_get_uint( tags, GST_TAG_TRACK_NUMBER, &track_number ); gst_tag_list_get_uint( tags, GST_TAG_ALBUM_VOLUME_NUMBER, &disc_number ); gst_tag_list_get_double( tags, GST_TAG_TRACK_GAIN, &track_gain ); gst_tag_list_get_double( tags, GST_TAG_ALBUM_GAIN, &album_gain ); // This is for debugging, in case some files use non-standard tag names //printTags( tags ); gst_tag_list_unref( tags ); gst_message_unref( msg ); }; if( GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR ) { GError *err = NULL; gchar *dbg_info = NULL; g_printerr( "==\t%s\n", filename ); gst_message_parse_error (msg, &err, &dbg_info); g_printerr ("ERROR from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr ("\tDebugging info: %s\n", (dbg_info) ? dbg_info : "none"); g_error_free (err); g_free (dbg_info); } else { // TODO: Create a subsystem that can record missing important data if( artist == NULL ) g_print( "ERROR: No Artist " ); if( album == NULL ) g_print( "ERROR: No album " ); if( album_artist == NULL ) { if( album != NULL ) { // In this case, we want to use the standard artist album_artist = g_strdup( artist ); } // TODO: Is no album & no album artist actually erroneous? //g_print( "ERROR: No album artist " ); } if( title == NULL ) g_print( "ERROR: No title " ); if( track_number == 0 ) g_print( "ERROR: No Track Number "); if( disc_number == 0 ) disc_number = 1; if( track_gain == 0.0 ) g_print( "ERROR: No Track Gain " ); if( album_gain == 0.0 ) { // TODO: Verify that clamping album gain to track gain is what we want to do. //g_print( "No Album Gain " ); album_gain = track_gain; } g_print( "\n" ); } gst_message_unref( msg ); gst_element_set_state( pipe, GST_STATE_NULL ); gst_object_unref( pipe ); if( conversion_error != NULL ) g_error_free( conversion_error ); return; }
/* * bt_wave_load_from_uri: * @self: the wave to load * @uri: the location to load from * * Load the wavedata from the @uri. * * Returns: %TRUE if the wavedata could be loaded */ static gboolean bt_wave_load_from_uri (const BtWave * const self, const gchar * const uri) { gboolean res = TRUE, done = FALSE; GstElement *pipeline; GstElement *src, *dec, *conv, *fmt, *sink; GstBus *bus = NULL; GstCaps *caps; GstMessage *msg; GstBtNote root_note = BT_WAVELEVEL_DEFAULT_ROOT_NOTE; GST_INFO ("about to load sample %s / %s", self->priv->uri, uri); // this leaks! //GST_INFO("current dir is %s", g_get_current_dir()); // check if the url is valid // if(!uri) goto invalid_uri; // create loader pipeline pipeline = gst_pipeline_new ("wave-loader"); src = gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL); dec = gst_element_factory_make ("decodebin", NULL); conv = gst_element_factory_make ("audioconvert", NULL); fmt = gst_element_factory_make ("capsfilter", NULL); sink = gst_element_factory_make ("fdsink", NULL); // configure elements caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE (S16), "layout", G_TYPE_STRING, "interleaved", "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT, "channels", GST_TYPE_INT_RANGE, 1, 2, NULL); g_object_set (fmt, "caps", caps, NULL); gst_caps_unref (caps); if ((self->priv->fd = g_file_open_tmp (NULL, NULL, NULL)) == -1) { res = FALSE; GST_WARNING ("Can't create tempfile."); goto Error; } g_object_set (sink, "fd", self->priv->fd, "sync", FALSE, NULL); // add and link gst_bin_add_many (GST_BIN (pipeline), src, dec, conv, fmt, sink, NULL); res = gst_element_link (src, dec); if (!res) { GST_WARNING_OBJECT (pipeline, "Can't link wave loader pipeline (src ! dec ! conv ! fmt ! sink)."); goto Error; } res = gst_element_link_many (conv, fmt, sink, NULL); if (!res) { GST_WARNING_OBJECT (pipeline, "Can't link wave loader pipeline (conf ! fmt ! sink)."); goto Error; } g_signal_connect (dec, "pad-added", G_CALLBACK (on_wave_loader_new_pad), (gpointer) conv); /* TODO(ensonic): during loading wave-data (into wavelevels) * - use statusbar for loader progress ("status" property like in song_io) * - should we do some size checks to avoid unpacking the audio track of a full * video on a machine with low memory * - if so, how to get real/virtual memory sizes? * mallinfo() not enough, sysconf()? */ bus = gst_element_get_bus (pipeline); // play and wait for EOS if (gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { GST_WARNING_OBJECT (pipeline, "Can't set wave loader pipeline for %s / %s to playing", self->priv->uri, uri); gst_element_set_state (pipeline, GST_STATE_NULL); res = FALSE; goto Error; } else { GST_INFO_OBJECT (pipeline, "loading sample ..."); } /* load wave in sync mode, loading them async causes troubles in the * persistence code and makes testing complicated */ while (!done) { msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR | GST_MESSAGE_TAG, GST_CLOCK_TIME_NONE); if (!msg) break; switch (msg->type) { case GST_MESSAGE_EOS: res = done = TRUE; break; case GST_MESSAGE_ERROR: BT_GST_LOG_MESSAGE_ERROR (msg, NULL, NULL); res = FALSE; done = TRUE; break; case GST_MESSAGE_TAG:{ GstTagList *tags; #if GST_CHECK_VERSION(1,3,0) guint base_note; #endif gst_message_parse_tag (msg, &tags); #if GST_CHECK_VERSION(1,3,0) if (gst_tag_list_get_uint (tags, GST_TAG_MIDI_BASE_NOTE, &base_note)) { // map midi note -> BtNote gint octave = base_note / 12; gint tone = base_note - (octave * 12); root_note = GSTBT_NOTE_C_0 + (octave * 16) + tone; GST_INFO_OBJECT (GST_MESSAGE_SRC (msg), "root_note: %d (base_note: %u = oct: %d + tone: %d", root_note, base_note, octave, tone); } #endif gst_tag_list_unref (tags); break; } default: break; } gst_message_unref (msg); } if (res) { GstPad *pad; gint64 duration; guint64 length = 0; gint channels = 1, rate = GST_AUDIO_DEF_RATE; gpointer data = NULL; struct stat buf; res = FALSE; GST_INFO ("sample loaded"); // query length and convert to samples if (!gst_element_query_duration (pipeline, GST_FORMAT_TIME, &duration)) { GST_WARNING ("getting sample duration failed"); } // get caps for sample rate and channels if ((pad = gst_element_get_static_pad (fmt, "src"))) { GstCaps *caps = gst_pad_get_current_caps (pad); if (caps && GST_CAPS_IS_SIMPLE (caps)) { GstStructure *structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "channels", &channels); gst_structure_get_int (structure, "rate", &rate); length = gst_util_uint64_scale (duration, (guint64) rate, GST_SECOND); } else { GST_WARNING ("No caps or format has not been fixed."); } if (caps) gst_caps_unref (caps); gst_object_unref (pad); } GST_INFO ("sample decoded: channels=%d, rate=%d, length=%" GST_TIME_FORMAT, channels, rate, GST_TIME_ARGS (duration)); if (!(fstat (self->priv->fd, &buf))) { if (lseek (self->priv->fd, 0, SEEK_SET) == 0) { if ((data = g_try_malloc (buf.st_size))) { /* mmap is unsave for removable drives :( * gpointer data=mmap(void *start, buf->st_size, PROT_READ, MAP_SHARED, self->priv->fd, 0); */ BtWavelevel *wavelevel; ssize_t bytes = read (self->priv->fd, data, buf.st_size); self->priv->channels = channels; g_object_notify (G_OBJECT (self), "channels"); wavelevel = bt_wavelevel_new (self->priv->song, self, root_note, (gulong) length, 0, length, rate, (gconstpointer) data); g_object_unref (wavelevel); GST_INFO ("sample loaded (%" G_GSSIZE_FORMAT "/%ld bytes)", bytes, buf.st_size); res = TRUE; } else { GST_WARNING ("sample is too long or empty (%ld bytes), not trying to load", buf.st_size); } } else { GST_WARNING ("can't seek to start of sample data"); } } else { GST_WARNING ("can't stat() sample"); } } Error: if (bus) gst_object_unref (bus); if (pipeline) { gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); } if (!res) wave_io_free (self); return res; }
void CGstPlayback::AnalyzeStreams() { return_assert(m_playbin); g_print("%s, begin", __func__); g_object_get (m_playbin, "n-video", &m_numVideo, NULL); g_object_get (m_playbin, "n-audio", &m_numAudio, NULL); g_object_get (m_playbin, "n-text", &m_numText, NULL); for (gint i = 0; i < m_numVideo; i++) { GstTagList *tags = NULL; gchar *str = NULL; /* Retrieve the stream's video tags */ g_signal_emit_by_name (m_playbin, "get-video-tags", i, &tags); if (tags) { g_print ("video stream %d:\n", i); gst_tag_list_get_string (tags, GST_TAG_VIDEO_CODEC, &str); g_print (" codec: %s\n", str ? str : "unknown"); g_free (str); gst_tag_list_free (tags); } } for (gint i = 0; i < m_numAudio; i++) { GstTagList *tags = NULL; gchar *str = NULL; guint rate = 0; /* Retrieve the stream's audio tags */ g_signal_emit_by_name (m_playbin, "get-audio-tags", i, &tags); if (tags) { g_print ("audio stream %d:\n", i); if (gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str)) { g_print (" codec: %s\n", str); g_free (str); } if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) { g_print (" language: %s\n", str); g_free (str); } if (gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate)) { g_print (" bitrate: %d\n", rate); } gst_tag_list_free (tags); } } for (gint i = 0; i < m_numText; i++) { GstTagList *tags = NULL; gchar *str = NULL; /* Retrieve the stream's subtitle tags */ g_signal_emit_by_name (m_playbin, "get-text-tags", i, &tags); if (tags) { g_print ("subtitle stream %d:\n", i); if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) { g_print (" language: %s\n", str); g_free (str); } gst_tag_list_free (tags); } } g_object_get (GST_OBJECT(m_playbin), "current-video", &m_curVideo, NULL); g_object_get (GST_OBJECT(m_playbin), "current-audio", &m_curAudio, NULL); g_object_get (GST_OBJECT(m_playbin), "current-text", &m_curText, NULL); }
int eServiceMP3::getInfo(int w) { const gchar *tag = 0; switch (w) { case sServiceref: return m_ref; case sVideoHeight: return m_height; case sVideoWidth: return m_width; case sFrameRate: return m_framerate; case sProgressive: return m_progressive; case sAspect: return m_aspect; case sTagTitle: case sTagArtist: case sTagAlbum: case sTagTitleSortname: case sTagArtistSortname: case sTagAlbumSortname: case sTagDate: case sTagComposer: case sTagGenre: case sTagComment: case sTagExtendedComment: case sTagLocation: case sTagHomepage: case sTagDescription: case sTagVersion: case sTagISRC: case sTagOrganization: case sTagCopyright: case sTagCopyrightURI: case sTagContact: case sTagLicense: case sTagLicenseURI: case sTagCodec: case sTagAudioCodec: case sTagVideoCodec: case sTagEncoder: case sTagLanguageCode: case sTagKeywords: case sTagChannelMode: case sUser+12: return resIsString; case sTagTrackGain: case sTagTrackPeak: case sTagAlbumGain: case sTagAlbumPeak: case sTagReferenceLevel: case sTagBeatsPerMinute: case sTagImage: case sTagPreviewImage: case sTagAttachment: return resIsPyObject; case sTagTrackNumber: tag = GST_TAG_TRACK_NUMBER; break; case sTagTrackCount: tag = GST_TAG_TRACK_COUNT; break; case sTagAlbumVolumeNumber: tag = GST_TAG_ALBUM_VOLUME_NUMBER; break; case sTagAlbumVolumeCount: tag = GST_TAG_ALBUM_VOLUME_COUNT; break; case sTagBitrate: tag = GST_TAG_BITRATE; break; case sTagNominalBitrate: tag = GST_TAG_NOMINAL_BITRATE; break; case sTagMinimumBitrate: tag = GST_TAG_MINIMUM_BITRATE; break; case sTagMaximumBitrate: tag = GST_TAG_MAXIMUM_BITRATE; break; case sTagSerial: tag = GST_TAG_SERIAL; break; case sTagEncoderVersion: tag = GST_TAG_ENCODER_VERSION; break; case sTagCRC: tag = "has-crc"; break; default: return resNA; } if (!m_stream_tags || !tag) return 0; guint value; if (gst_tag_list_get_uint(m_stream_tags, tag, &value)) return (int) value; return 0; }
gboolean ly_ppl_bus_cb(GstBus *bus,GstMessage *message,gpointer data) { char *tag_codec=NULL; // char *tag_title=NULL; // char *tag_artist=NULL; // char *tag_album=NULL; char *tag_comment=NULL; char *tag_genre=NULL; char *tag_lrc=NULL; guint tag_bitrate=0; guint tag_track=0; GstBuffer *tag_cover=NULL; LyMdhMetadata *md=ly_pqm_get_current_md(); if(!md) return TRUE; GstTagList* tags; switch (message->type) { case GST_MESSAGE_EOS: ly_mbs_put("ppl_eos", "core:ppl", NULL); break; case GST_MESSAGE_TAG: { gst_message_parse_tag(message,&tags); //codec if(gst_tag_list_get_string(tags,GST_TAG_AUDIO_CODEC,&tag_codec)) { if(tag_codec!=NULL) g_strlcpy(md->codec, tag_codec, sizeof(md->codec)); ly_mbs_put("meta_update", "core:ppl", "codec"); } //comment if(gst_tag_list_get_string(tags,GST_TAG_COMMENT,&tag_comment)) { if(g_utf8_validate(tag_comment,-1,NULL)) { g_utf8_strncpy((char *)(md->comment), tag_comment, sizeof(md->comment)); } g_free(tag_comment); ly_mbs_put("meta_update", "core:ppl", "comment"); } //bitrate if(gst_tag_list_get_uint(tags, GST_TAG_BITRATE, &tag_bitrate)) { md->bitrate = tag_bitrate; ly_mbs_put("meta_update", "core:ppl", "bitrate"); } //track_number if(gst_tag_list_get_uint(tags, GST_TAG_TRACK_NUMBER, &tag_track)) { md->track = tag_track; ly_mbs_put("meta_update", "core:ppl", "track"); } //genre if(gst_tag_list_get_string(tags,GST_TAG_GENRE, &tag_genre)) { if(g_utf8_validate(tag_genre,-1,NULL)) { g_utf8_strncpy((gchar *)(md->genre),tag_genre, sizeof(md->genre)); } g_free(tag_genre); ly_mbs_put("meta_update", "core:ppl", "genre"); } //album cover if(gst_tag_list_get_buffer(tags,GST_TAG_IMAGE, &tag_cover)) { if(md->cover) gst_buffer_unref(md->cover); md->cover=tag_cover; ly_mbs_put("meta_update", "core:ppl", "cover"); } //lyrics if(gst_tag_list_get_string(tags,GST_TAG_LYRICS, &tag_lrc)) { if(g_utf8_validate(tag_lrc,-1,NULL)) { g_utf8_strncpy((gchar *)(md->lrc), tag_lrc, sizeof(md->lrc)); } g_free(tag_lrc); ly_mbs_put("meta_update", "core:ppl", "lrc"); } break; } default: break; } return TRUE; }
static gboolean rc_plugin_tag_reader_bus_handler(GstBus *bus, GstMessage *msg, gboolean data) { GstTagList *tags = NULL; gchar *string = NULL; guint number = 0; gint integer = 0; GstState state; GstStructure *structure = NULL; GstCaps *caps; GstFormat fmt = GST_FORMAT_TIME; gint64 length = 0; gdouble replay_gain = 0.0; GDate *date = NULL; switch(GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: break; case GST_MESSAGE_ERROR: break; case GST_MESSAGE_STATE_CHANGED: if(gst_element_get_state(tag_reader_bin, &state, NULL, GST_CLOCK_TIME_NONE)==GST_STATE_CHANGE_SUCCESS) { if(state==GST_STATE_PAUSED && tag_reader_sink_pad!=NULL) { caps = gst_pad_get_negotiated_caps(tag_reader_sink_pad); if(caps!=NULL) { structure = gst_caps_get_structure(caps, 0); gst_structure_get_int(structure, "rate", &integer); string = g_strdup_printf("%d Hz", integer); gtk_label_set_text(GTK_LABEL(tag_ui.sr_entry), string); g_free(string); gst_structure_get_int(structure, "depth", &integer); string = g_strdup_printf("%d", integer); gtk_label_set_text(GTK_LABEL(tag_ui.bd_entry), string); g_free(string); gst_structure_get_int(structure, "channels", &integer); if(integer==2) string = g_strdup_printf(_("Stereo")); else if(integer==1) string = g_strdup_printf(_("Mono")); else string = g_strdup_printf("%d", integer); gtk_label_set_text(GTK_LABEL(tag_ui.channel_entry), string); g_free(string); gst_caps_unref(caps); } } if(state==GST_STATE_PAUSED) { gst_element_query_duration(tag_reader_bin, &fmt, &length); length = length / GST_MSECOND / 10; string = g_strdup_printf("%02d:%02d.%02d", (gint)(length/6000), (gint)(length%6000)/100, (gint)(length%100)); gtk_label_set_text(GTK_LABEL(tag_ui.length_entry), string); g_free(string); } } break; case GST_MESSAGE_TAG: gst_message_parse_tag(msg, &tags); if(gst_tag_list_get_string(tags, GST_TAG_TITLE, &string)) { if(string!=NULL) { if(tag_info.title!=NULL) g_free(tag_info.title); tag_info.title = g_strdup(string); gtk_entry_set_text(GTK_ENTRY(tag_ui.title_entry), string); g_free(string); } } if(gst_tag_list_get_string(tags, GST_TAG_ARTIST, &string)) { if(string!=NULL) { if(tag_info.artist!=NULL) g_free(tag_info.artist); tag_info.artist = g_strdup(string); gtk_entry_set_text(GTK_ENTRY(tag_ui.artist_entry), string); g_free(string); } } if(gst_tag_list_get_string(tags, GST_TAG_ALBUM, &string)) { if(string!=NULL) { if(tag_info.album!=NULL) g_free(tag_info.album); tag_info.album = g_strdup(string); gtk_entry_set_text(GTK_ENTRY(tag_ui.album_entry), string); g_free(string); } } if(gst_tag_list_get_uint(tags, GST_TAG_TRACK_NUMBER, &number)) { tag_info.track = number; string = g_strdup_printf("%d", number); gtk_entry_set_text(GTK_ENTRY(tag_ui.track_entry), string); g_free(string); } if(gst_tag_list_get_string(tags, GST_TAG_GENRE, &string)) { if(string!=NULL) { if(tag_info.genre!=NULL) g_free(tag_info.genre); tag_info.genre = g_strdup(string); gtk_entry_set_text(GTK_ENTRY(tag_ui.genre_entry), string); g_free(string); } } if(gst_tag_list_get_string(tags, GST_TAG_COMMENT, &string)) { if(string!=NULL) { if(tag_info.comment!=NULL) g_free(tag_info.comment); tag_info.comment = g_strdup(string); gtk_entry_set_text(GTK_ENTRY(tag_ui.comment_entry), string); g_free(string); } } if(gst_tag_list_get_uint(tags, GST_TAG_BITRATE, &number)) { string = g_strdup_printf("%d kbps", number/1000); gtk_label_set_text(GTK_LABEL(tag_ui.bitrate_entry), string); g_free(string); } if(gst_tag_list_get_string(tags, GST_TAG_AUDIO_CODEC, &string)) { if(string!=NULL) { gtk_label_set_text(GTK_LABEL(tag_ui.format_entry), string); g_free(string); } } if(gst_tag_list_get_double(tags, GST_TAG_TRACK_GAIN, &replay_gain)) { tag_info.rg = replay_gain; string = g_strdup_printf("%lf", replay_gain); gtk_entry_set_text(GTK_ENTRY(tag_ui.rg_entry), string); g_free(string); } if(gst_tag_list_get_date(tags, GST_TAG_DATE, &date)) { if(date!=NULL) { tag_info.year = g_date_get_year(date); string = g_strdup_printf("%u", g_date_get_year(date)); gtk_entry_set_text(GTK_ENTRY(tag_ui.year_entry), string); g_free(string); g_date_free(date); } } gst_tag_list_free(tags); break; case GST_MESSAGE_ELEMENT: break; default: break; } return TRUE; }
/* Extract metadata from all the streams and write it to the text widget in the GUI */ static void analyze_streams (CustomData *data) { gint i; GstTagList *tags; gchar *str, *total_str; guint rate; gint n_video, n_audio, n_text; GtkTextBuffer *text; /* Clean current contents of the widget */ text = gtk_text_view_get_buffer (GTK_TEXT_VIEW (data->streams_list)); gtk_text_buffer_set_text (text, "", -1); /* Read some properties */ g_object_get (data->playbin, "n-video", &n_video, NULL); g_object_get (data->playbin, "n-audio", &n_audio, NULL); g_object_get (data->playbin, "n-text", &n_text, NULL); for (i = 0; i < n_video; i++) { tags = NULL; /* Retrieve the stream's video tags */ g_signal_emit_by_name (data->playbin, "get-video-tags", i, &tags); if (tags) { total_str = g_strdup_printf ("video stream %d:\n", i); gtk_text_buffer_insert_at_cursor (text, total_str, -1); g_free (total_str); gst_tag_list_get_string (tags, GST_TAG_VIDEO_CODEC, &str); total_str = g_strdup_printf (" codec: %s\n", str ? str : "unknown"); gtk_text_buffer_insert_at_cursor (text, total_str, -1); g_free (total_str); g_free (str); gst_tag_list_free (tags); } } for (i = 0; i < n_audio; i++) { tags = NULL; /* Retrieve the stream's audio tags */ g_signal_emit_by_name (data->playbin, "get-audio-tags", i, &tags); if (tags) { total_str = g_strdup_printf ("\naudio stream %d:\n", i); gtk_text_buffer_insert_at_cursor (text, total_str, -1); g_free (total_str); if (gst_tag_list_get_string (tags, GST_TAG_AUDIO_CODEC, &str)) { total_str = g_strdup_printf (" codec: %s\n", str); gtk_text_buffer_insert_at_cursor (text, total_str, -1); g_free (total_str); g_free (str); } if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) { total_str = g_strdup_printf (" language: %s\n", str); gtk_text_buffer_insert_at_cursor (text, total_str, -1); g_free (total_str); g_free (str); } if (gst_tag_list_get_uint (tags, GST_TAG_BITRATE, &rate)) { total_str = g_strdup_printf (" bitrate: %d\n", rate); gtk_text_buffer_insert_at_cursor (text, total_str, -1); g_free (total_str); } gst_tag_list_free (tags); } } for (i = 0; i < n_text; i++) { tags = NULL; /* Retrieve the stream's subtitle tags */ g_signal_emit_by_name (data->playbin, "get-text-tags", i, &tags); if (tags) { total_str = g_strdup_printf ("\nsubtitle stream %d:\n", i); gtk_text_buffer_insert_at_cursor (text, total_str, -1); g_free (total_str); if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &str)) { total_str = g_strdup_printf (" language: %s\n", str); gtk_text_buffer_insert_at_cursor (text, total_str, -1); g_free (total_str); g_free (str); } gst_tag_list_free (tags); } } }
gboolean ly_mdh_new_with_uri_full_bus_cb (GstBus *bus, GstMessage *message, gpointer data) { LyMdhMetadata *md=data; char *tag_codec=NULL; char *tag_title=NULL; char *tag_artist=NULL; char *tag_album=NULL; char *tag_comment=NULL; char *tag_genre=NULL; guint tag_bitrate=0; guint tag_track=0; GstBuffer *tag_cover=NULL; if(md==NULL) return TRUE; if(md->uri==NULL) return TRUE; switch(GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_EOS: { ly_mdh_md_eos=TRUE; return TRUE; } case GST_MESSAGE_ERROR: { ly_mdh_md_eos=TRUE; return TRUE; } case GST_MESSAGE_TAG: { GstTagList *tags; gst_message_parse_tag(message,&tags); //codec if(gst_tag_list_get_string(tags,GST_TAG_AUDIO_CODEC,&tag_codec)) { if(tag_codec!=NULL) g_strlcpy(md->codec, tag_codec, sizeof(md->codec)); } //title if(gst_tag_list_get_string(tags,GST_TAG_TITLE,&tag_title)) { if(g_utf8_validate(tag_title,-1,NULL)) { g_utf8_strncpy((char *)(md->title),tag_title, sizeof(md->title)); } g_free(tag_title); } //artist if(gst_tag_list_get_string(tags,GST_TAG_ARTIST,&tag_artist)) { if(g_utf8_validate(tag_artist,-1,NULL)) { g_utf8_strncpy((char *)(md->artist), tag_artist, sizeof(md->artist)); } g_free(tag_artist); } //album if(gst_tag_list_get_string(tags,GST_TAG_ALBUM,&tag_album)) { if(g_utf8_validate(tag_album,-1,NULL)) { g_utf8_strncpy((char *)(md->album), tag_album, sizeof(md->album)); } g_free(tag_album); } //comment if(gst_tag_list_get_string(tags,GST_TAG_COMMENT,&tag_comment)) { if(g_utf8_validate(tag_comment,-1,NULL)) { g_utf8_strncpy((char *)(md->comment), tag_comment, sizeof(md->comment)); } g_free(tag_comment); } //bitrate if(gst_tag_list_get_uint(tags, GST_TAG_BITRATE, &tag_bitrate)) { md->bitrate = tag_bitrate; } //track_number if(gst_tag_list_get_uint(tags, GST_TAG_TRACK_NUMBER, &tag_track)) { md->track = tag_track; } //genre if(gst_tag_list_get_string(tags, GST_TAG_GENRE,&tag_genre)) { if(g_utf8_validate(tag_genre,-1,NULL)) { g_utf8_strncpy((char *)(md->genre), tag_genre, sizeof(md->genre)); } g_free(tag_genre); } //album cover if(gst_tag_list_get_buffer(tags, GST_TAG_IMAGE, &tag_cover)) { if(md->cover!=NULL) gst_buffer_unref(md->cover); md->cover=tag_cover; } gst_tag_list_free(tags); return TRUE; break; } case GST_MESSAGE_ELEMENT: break; default: break; } return FALSE; }