marlin r1309 - trunk/marlin
- From: iain svn gnome org
- To: svn-commits-list gnome org
- Subject: marlin r1309 - trunk/marlin
- Date: Sat, 11 Oct 2008 23:44:08 +0000 (UTC)
Author: iain
Date: Sat Oct 11 23:44:07 2008
New Revision: 1309
URL: http://svn.gnome.org/viewvc/marlin?rev=1309&view=rev
Log:
Make metadata extraction work
Neaten up preview layout
Modified:
trunk/marlin/ChangeLog
trunk/marlin/marlin-file-chooser.c
Modified: trunk/marlin/marlin-file-chooser.c
==============================================================================
--- trunk/marlin/marlin-file-chooser.c (original)
+++ trunk/marlin/marlin-file-chooser.c Sat Oct 11 23:44:07 2008
@@ -63,7 +63,10 @@
/* Preview */
GstElement *player;
GstElement *md_pipeline;
+ GstElement *sink;
GstPad *decode_pad;
+ gboolean md_eos;
+ gboolean can_decode;
};
static void
@@ -173,37 +176,6 @@
}
}
-static gboolean
-md_message_cb (GstBus *bus,
- GstMessage *message,
- gpointer data)
-{
- struct _ChooserOpenData *od = data;
- GstTagList *tags;
-
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_EOS:
- clear_info (od);
- break;
-
- case GST_MESSAGE_ERROR:
- clear_info (od);
- break;
-
- case GST_MESSAGE_TAG:
- gtk_file_chooser_set_preview_widget_active (GTK_FILE_CHOOSER (od->chooser), TRUE);
- gst_message_parse_tag (message, &tags);
- set_info (od, tags);
- gst_tag_list_free (tags);
- break;
-
- default:
- break;
- }
-
- return TRUE;
-}
-
static void
unknown_type_cb (GstElement *decodebin,
GstPad *pad,
@@ -214,32 +186,37 @@
}
static void
-have_type_cb (GstElement *typefind,
- guint probability,
- GstCaps *caps,
- struct _ChooserOpenData *od)
-{
- char *type;
- const char *name;
-
- type = gst_caps_to_string (caps);
-
- name = g_content_type_get_description (type);
- if (name) {
- gtk_label_set_text (GTK_LABEL (od->mimetype), name);
- } else {
- gtk_label_set_text (GTK_LABEL (od->mimetype), type);
- }
- g_free (type);
-}
-
-static void
new_pad (GstElement *decodebin,
GstPad *pad,
gboolean final,
struct _ChooserOpenData *od)
{
+ GstCaps *caps;
+ GstStructure *structure;
+ const char *mimetype;
+
od->decode_pad = pad;
+
+ caps = gst_pad_get_caps (pad);
+
+ /* We get "ANY" caps for text/plain files etc */
+ if (gst_caps_is_empty (caps) || gst_caps_is_any (caps)) {
+ od->can_decode = FALSE;
+ } else {
+ /* is this pad audio? */
+ structure = gst_caps_get_structure (caps, 0);
+ mimetype = gst_structure_get_name (structure);
+ if (g_str_has_prefix (mimetype, "audio/x-raw")) {
+ GstPad *sink_pad;
+
+ /* Link this to the fakesink */
+ sink_pad = gst_element_get_pad (od->sink, "sink");
+ gst_pad_link (pad, sink_pad);
+ od->can_decode = TRUE;
+ }
+ }
+
+ gst_caps_unref (caps);
}
static void
@@ -285,18 +262,87 @@
gst_query_unref (query);
}
+static gboolean
+metadata_bus_handler (GstBus *bus,
+ GstMessage *message,
+ struct _ChooserOpenData *od)
+{
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_EOS:
+ od->md_eos = TRUE;
+ clear_info (od);
+ return TRUE;
+
+ case GST_MESSAGE_ERROR:
+ {
+ GError *error;
+ char *debug, *src;
+
+ gst_message_parse_error (message, &error, &debug);
+ src = gst_element_get_name (GST_MESSAGE_SRC (message));
+ g_warning ("Error from %s: %s\n%s", src, error->message, debug);
+ g_error_free (error);
+ g_free (src);
+ g_free (debug);
+
+ clear_info (od);
+ od->md_eos = TRUE;
+ return TRUE;
+ }
+
+ case GST_MESSAGE_TAG:
+ {
+ GstTagList *tags;
+
+ gst_message_parse_tag (message, &tags);
+ if (!tags) {
+ g_warning ("Could not retrieve tag list");
+ od->md_eos = TRUE;
+ return TRUE;
+ }
+
+ set_info (od, tags);
+ gst_tag_list_free (tags);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+static void
+metadata_event_loop (struct _ChooserOpenData *od,
+ GstBus *bus)
+{
+ gboolean done = FALSE;
+
+ while (!done && !od->md_eos) {
+ GstMessage *message;
+
+ message = gst_bus_pop (bus);
+ if (message == NULL) {
+ return;
+ }
+
+ done = metadata_bus_handler (bus, message, od);
+ gst_message_unref (message);
+ }
+}
+
static void
get_metadata (struct _ChooserOpenData *od,
- const char *filename)
+ const char *uri)
{
GstElement *decodebin, *source;
- GstObject *typefind;
GstStateChangeReturn sret;
- GstState state;
+ int change_timeout;
+ GstBus *bus;
od->md_pipeline = gst_pipeline_new (NULL);
- gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (od->md_pipeline)),
- md_message_cb, od);
+ od->md_eos = FALSE;
source = marlin_make_gst_source ("source");
decodebin = gst_element_factory_make ("decodebin", "decodebin");
@@ -305,32 +351,63 @@
g_signal_connect (G_OBJECT (decodebin), "new-decoded-pad",
G_CALLBACK (new_pad), od);
- typefind = gst_child_proxy_get_child_by_name (GST_CHILD_PROXY (decodebin),
- "typefind");
- g_signal_connect (G_OBJECT (typefind), "have-type",
- G_CALLBACK (have_type_cb), od);
-
- gst_bin_add_many (GST_BIN (od->md_pipeline), source, decodebin, NULL);
+ od->sink = gst_element_factory_make ("fakesink", "fakesink");
+ gst_bin_add_many (GST_BIN (od->md_pipeline), source,
+ decodebin, od->sink, NULL);
gst_element_link (source, decodebin);
g_object_set (G_OBJECT (source),
- "location", filename,
+ "location", uri,
NULL);
+ bus = gst_element_get_bus (GST_ELEMENT (od->md_pipeline));
sret = gst_element_set_state (od->md_pipeline, GST_STATE_PAUSED);
-
- if (sret == GST_STATE_CHANGE_ASYNC) {
- if (gst_element_get_state (od->md_pipeline, &state, NULL,
- 5 * GST_SECOND) != GST_STATE_CHANGE_SUCCESS) {
- clear_info (od);
+ change_timeout = 0;
+ while (sret == GST_STATE_CHANGE_ASYNC &&
+ !od->md_eos && change_timeout < 5) {
+ GstMessage *msg;
+
+ msg = gst_bus_timed_pop (bus, 1 * GST_SECOND);
+ if (msg) {
+ metadata_bus_handler (bus, msg, od);
+ gst_message_unref (msg);
+ change_timeout = 0;
} else {
- /* Need to wait til the state has gone to PAUSED
- before we get the stream info */
- get_stream_info (od);
+ change_timeout++;
}
- } else if (sret != GST_STATE_CHANGE_SUCCESS) {
- clear_info (od);
+
+ sret = gst_element_get_state (od->md_pipeline, NULL, NULL, 1);
}
+
+ metadata_event_loop (od, bus);
+ gst_object_unref (bus);
+
+ get_stream_info (od);
+ if (od->can_decode) {
+ GFile *file;
+ GFileInfo *info;
+
+ file = g_file_new_for_uri (uri);
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ G_FILE_QUERY_INFO_NONE, NULL, NULL);
+ if (info) {
+ char *desc;
+ const char *content_type;
+
+ content_type = g_file_info_get_content_type (info);
+ desc = g_content_type_get_description (content_type);
+
+ gtk_label_set_text (GTK_LABEL (od->mimetype), desc);
+ g_free (desc);
+ g_object_unref (info);
+ }
+ g_object_unref (file);
+ }
+
+ gst_element_set_state (od->md_pipeline, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (od->md_pipeline));
+ od->md_pipeline = NULL;
}
static void
@@ -353,10 +430,14 @@
}
if (filename != NULL) {
+ char *uri;
+
gtk_file_chooser_set_preview_widget_active (GTK_FILE_CHOOSER (od->chooser), TRUE);
+ uri = gtk_file_chooser_get_preview_uri (GTK_FILE_CHOOSER (od->chooser));
gtk_widget_set_sensitive (od->play, TRUE);
- get_metadata (od, filename);
+ get_metadata (od, uri);
g_free (filename);
+ g_free (uri);
} else {
gtk_file_chooser_set_preview_widget_active (GTK_FILE_CHOOSER (od->chooser), FALSE);
gtk_widget_set_sensitive (od->play, FALSE);
@@ -407,7 +488,7 @@
g_object_set (G_OBJECT (od->player),
"uri", uri,
NULL);
-
+
gst_element_set_state (od->player, GST_STATE_PLAYING);
gtk_widget_hide (od->play);
@@ -419,7 +500,7 @@
struct _ChooserOpenData *od)
{
gst_element_set_state (od->player, GST_STATE_READY);
-
+
gtk_widget_hide (od->stop);
gtk_widget_show (od->play);
}
@@ -434,28 +515,12 @@
gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (od->chooser), vbox);
od->name = marlin_make_title_label (_("Untitled"));
+ gtk_misc_set_alignment (GTK_MISC (od->name), 0.5, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (od->name), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), od->name, FALSE, FALSE, 0);
- hbox = gtk_hbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
-
- spacer = gtk_label_new (" ");
- gtk_box_pack_start (GTK_BOX (hbox), spacer, FALSE, FALSE, 0);
-
table = marlin_make_table (4, 2, FALSE);
- gtk_box_pack_start (GTK_BOX (hbox), table, TRUE, TRUE, 0);
-
-#if 0
- label = marlin_make_title_label (_("Name:"));
- gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
- PACK (table, label, 0, 0, GTK_FILL);
-
- gtk_label_set_line_wrap (GTK_LABEL (od->name), TRUE);
- PACK (table, od->name, 1, 0, GTK_FILL);
-
- marlin_add_paired_relations (label, ATK_RELATION_LABEL_FOR,
- od->name, ATK_RELATION_LABELLED_BY);
-#endif
+ gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
label = marlin_make_title_label (_("Mime Type:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
@@ -466,7 +531,7 @@
marlin_add_paired_relations (label, ATK_RELATION_LABEL_FOR,
od->mimetype, ATK_RELATION_LABELLED_BY);
-
+
label = marlin_make_title_label (_("Length:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
PACK (table, label, 0, 1, GTK_FILL);
@@ -476,7 +541,7 @@
marlin_add_paired_relations (label, ATK_RELATION_LABEL_FOR,
od->length, ATK_RELATION_LABELLED_BY);
-
+
label = marlin_make_title_label (_("Sample Rate:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
PACK (table, label, 0, 2, GTK_FILL);
@@ -486,7 +551,7 @@
marlin_add_paired_relations (label, ATK_RELATION_LABEL_FOR,
od->sample_rate, ATK_RELATION_LABELLED_BY);
-
+
label = marlin_make_title_label (_("Channels:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
PACK (table, label, 0, 3, GTK_FILL);
@@ -496,7 +561,7 @@
marlin_add_paired_relations (label, ATK_RELATION_LABEL_FOR,
od->channels, ATK_RELATION_LABELLED_BY);
-
+
hbox = gtk_hbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -510,7 +575,7 @@
g_signal_connect (G_OBJECT (od->stop), "clicked",
G_CALLBACK (stop_playing), od);
gtk_box_pack_start (GTK_BOX (hbox), od->stop, FALSE, FALSE, 0);
-
+
gtk_widget_show_all (vbox);
gtk_widget_hide (od->stop);
}
@@ -524,7 +589,7 @@
char *filename;
od = g_new0 (struct _ChooserOpenData, 1);
-
+
widget = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
"action", GTK_FILE_CHOOSER_ACTION_OPEN,
"title", _("Open File"),
@@ -535,16 +600,11 @@
build_info_contents (od);
- /* Check if we can display the first selected file */
- filename = gtk_file_chooser_get_preview_filename (GTK_FILE_CHOOSER (widget));
- get_metadata (od, filename);
- g_free (filename);
-
g_signal_connect (G_OBJECT (od->chooser), "destroy",
G_CALLBACK (free_open_data), od);
g_signal_connect (G_OBJECT (od->chooser), "update-preview",
G_CALLBACK (selection_changed), od);
-
+
gtk_dialog_add_buttons (GTK_DIALOG (widget),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_OK,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]