brasero r1855 - in trunk: . src
- From: philippr svn gnome org
- To: svn-commits-list gnome org
- Subject: brasero r1855 - in trunk: . src
- Date: Sun, 1 Feb 2009 13:50:23 +0000 (UTC)
Author: philippr
Date: Sun Feb 1 13:50:23 2009
New Revision: 1855
URL: http://svn.gnome.org/viewvc/brasero?rev=1855&view=rev
Log:
2009-02-01 Philippe Rouquier <ykw localhost localdomain>
Fix #561626 â loading file info slow for audio projects
For vbr mp3s we used to read/decode them till the end to get a very
precise length. Now, we just read/parse the frame headers till the end
which saves a lot of time and CPU.
* src/brasero-io.c (brasero_io_get_file_count_process_playlist),
(brasero_io_load_directory_playlist):
* src/brasero-metadata.c (brasero_metadata_info_copy),
(brasero_metadata_stop_pipeline),
(brasero_metadata_destroy_pipeline), (brasero_metadata_stop),
(brasero_metadata_completed), (brasero_metadata_success),
(brasero_metadata_get_duration),
(brasero_metadata_mp3_bus_messages),
(brasero_metadata_create_mp3_pipeline),
(brasero_metadata_success_main), (brasero_metadata_bus_messages),
(brasero_metadata_set_new_uri), (brasero_metadata_finalize),
(brasero_metadata_class_init):
* src/brasero-metadata.h:
Modified:
trunk/ChangeLog
trunk/src/brasero-io.c
trunk/src/brasero-metadata.c
trunk/src/brasero-metadata.h
Modified: trunk/src/brasero-io.c
==============================================================================
--- trunk/src/brasero-io.c (original)
+++ trunk/src/brasero-io.c Sun Feb 1 13:50:23 2009
@@ -1489,8 +1489,7 @@
child_uri,
info,
((data->job.options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0) |
- ((data->job.options & BRASERO_IO_INFO_METADATA_THUMBNAIL) ? BRASERO_METADATA_FLAG_THUMBNAIL : 0) |
- BRASERO_METADATA_FLAG_FAST,
+ ((data->job.options & BRASERO_IO_INFO_METADATA_THUMBNAIL) ? BRASERO_METADATA_FLAG_THUMBNAIL : 0),
&metadata);
if (result)
@@ -1835,8 +1834,7 @@
child_uri,
info,
((data->job.options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0) |
- ((data->job.options & BRASERO_IO_INFO_METADATA_THUMBNAIL) ? BRASERO_METADATA_FLAG_THUMBNAIL : 0) |
- BRASERO_METADATA_FLAG_FAST,
+ ((data->job.options & BRASERO_IO_INFO_METADATA_THUMBNAIL) ? BRASERO_METADATA_FLAG_THUMBNAIL : 0),
&metadata);
if (result) {
Modified: trunk/src/brasero-metadata.c
==============================================================================
--- trunk/src/brasero-metadata.c (original)
+++ trunk/src/brasero-metadata.c Sun Feb 1 13:50:23 2009
@@ -61,6 +61,8 @@
GstElement *level;
GstElement *sink;
+ GstElement *pipeline_mp3;
+
GstElement *audio;
GstElement *video;
@@ -68,8 +70,7 @@
GError *error;
guint watch;
-
- guint progress_id;
+ guint watch_mp3;
BraseroMetadataSilence *silence;
@@ -102,7 +103,6 @@
typedef enum {
COMPLETED_SIGNAL,
- PROGRESS_CHANGED_SIGNAL,
LAST_SIGNAL
} BraseroMetadataSignalType;
@@ -175,24 +175,71 @@
g_free (info);
}
-static void
-brasero_metadata_destroy_pipeline (BraseroMetadata *self)
+void
+brasero_metadata_info_copy (BraseroMetadataInfo *dest,
+ BraseroMetadataInfo *src)
{
- GstState state;
- GstStateChangeReturn change;
- BraseroMetadataPrivate *priv;
+ GSList *iter;
- priv = BRASERO_METADATA_PRIVATE (self);
+ if (!dest || !src)
+ return;
- priv->started = 0;
+ dest->isrc = src->isrc;
+ dest->len = src->len;
+ dest->is_seekable = src->is_seekable;
+ dest->has_audio = src->has_audio;
+ dest->has_video = src->has_video;
- if (!priv->pipeline)
- return;
+ if (src->uri)
+ dest->uri = g_strdup (src->uri);
+
+ if (src->type)
+ dest->type = g_strdup (src->type);
+
+ if (src->title)
+ dest->title = g_strdup (src->title);
- change = gst_element_set_state (GST_ELEMENT (priv->pipeline),
+ if (src->artist)
+ dest->artist = g_strdup (src->artist);
+
+ if (src->album)
+ dest->album = g_strdup (src->album);
+
+ if (src->genre)
+ dest->genre = g_strdup (src->genre);
+
+ if (src->musicbrainz_id)
+ dest->musicbrainz_id = g_strdup (src->musicbrainz_id);
+
+ if (src->snapshot) {
+ dest->snapshot = src->snapshot;
+ g_object_ref (dest->snapshot);
+ }
+
+ for (iter = src->silences; iter; iter = iter->next) {
+ BraseroMetadataSilence *silence, *copy;
+
+ silence = iter->data;
+
+ copy = g_new0 (BraseroMetadataSilence, 1);
+ copy->start = silence->start;
+ copy->end = silence->end;
+
+ dest->silences = g_slist_append (dest->silences, copy);
+ }
+
+}
+
+static void
+brasero_metadata_stop_pipeline (GstElement *pipeline)
+{
+ GstState state;
+ GstStateChangeReturn change;
+
+ change = gst_element_set_state (GST_ELEMENT (pipeline),
GST_STATE_NULL);
- change = gst_element_get_state (priv->pipeline,
+ change = gst_element_get_state (pipeline,
&state,
NULL,
GST_MSECOND);
@@ -201,7 +248,7 @@
while (change == GST_STATE_CHANGE_ASYNC && state != GST_STATE_NULL) {
GstState pending;
- change = gst_element_get_state (priv->pipeline,
+ change = gst_element_get_state (pipeline,
&state,
&pending,
GST_MSECOND);
@@ -212,6 +259,33 @@
if (change == GST_STATE_CHANGE_FAILURE)
g_warning ("State change failure");
+}
+
+static void
+brasero_metadata_destroy_pipeline (BraseroMetadata *self)
+{
+ BraseroMetadataPrivate *priv;
+
+ priv = BRASERO_METADATA_PRIVATE (self);
+
+ priv->started = 0;
+
+ if (priv->pipeline_mp3) {
+ brasero_metadata_stop_pipeline (priv->pipeline_mp3);
+ gst_object_unref (GST_OBJECT (priv->pipeline_mp3));
+ priv->pipeline_mp3 = NULL;
+ }
+
+ if (priv->watch_mp3) {
+ g_source_remove (priv->watch_mp3);
+ priv->watch_mp3 = 0;
+ }
+
+ if (!priv->pipeline)
+ return;
+
+ brasero_metadata_stop_pipeline (priv->pipeline);
+
if (priv->audio) {
gst_bin_remove (GST_BIN (priv->pipeline), priv->audio);
priv->audio = NULL;
@@ -257,19 +331,14 @@
g_mutex_lock (priv->mutex);
/* Destroy the pipeline as it has become un-re-usable */
- if (priv->pipeline)
- brasero_metadata_destroy_pipeline (self);
-
- if (priv->progress_id) {
- g_source_remove (priv->progress_id);
- priv->progress_id = 0;
- }
-
if (priv->watch) {
g_source_remove (priv->watch);
priv->watch = 0;
}
+ if (priv->pipeline)
+ brasero_metadata_destroy_pipeline (self);
+
/* That's automatic missing plugin installation */
if (priv->missing_plugins) {
g_slist_foreach (priv->missing_plugins,
@@ -332,41 +401,24 @@
priv = BRASERO_METADATA_PRIVATE (self);
+ if (priv->error) {
+ BRASERO_BURN_LOG ("Operation completed with an error %s", priv->error->message);
+ }
+
/* we send a message only if we haven't got a loop (= async mode) */
g_object_ref (self);
g_signal_emit (G_OBJECT (self),
brasero_metadata_signals [COMPLETED_SIGNAL],
0,
priv->error);
- g_object_unref (self);
brasero_metadata_stop (self);
- return TRUE;
-}
-static gint
-brasero_metadata_report_progress (BraseroMetadata *self)
-{
- gdouble progress;
- gint64 position = -1;
- gint64 duration = -1;
- BraseroMetadataPrivate *priv;
- GstFormat format = GST_FORMAT_BYTES;
-
- priv = BRASERO_METADATA_PRIVATE (self);
- if (!gst_element_query_duration (priv->pipeline, &format, &duration))
- return TRUE;
-
- if (!gst_element_query_position (priv->pipeline, &format, &position))
- return TRUE;
-
- progress = position / duration;
- g_signal_emit (self,
- brasero_metadata_signals [PROGRESS_CHANGED_SIGNAL],
- 0,
- progress);
+ g_object_unref (self);
- return TRUE;
+ /* Return FALSE on purpose here as it will stop the bus callback
+ * It's not whether we succeeded or not. */
+ return FALSE;
}
static gboolean
@@ -565,26 +617,47 @@
static gboolean
brasero_metadata_success (BraseroMetadata *self)
{
- GstFormat format = GST_FORMAT_TIME;
BraseroMetadataPrivate *priv;
- gint64 duration = -1;
priv = BRASERO_METADATA_PRIVATE (self);
- BRASERO_BURN_LOG ("Metadata retrieval successfully completed for %s", priv->info->uri);
+ BRASERO_BURN_LOG ("Metadata retrieval completed for %s", priv->info->uri);
- /* find the type of the file */
- brasero_metadata_get_mime_type (self);
+ /* check if that's a seekable one */
+ brasero_metadata_is_seekable (self);
- /* get the size */
- if (!BRASERO_METADATA_IS_FAST (priv->flags)
- && brasero_metadata_is_mp3 (self))
- gst_element_query_position (GST_ELEMENT (priv->sink),
+ if (priv->silence) {
+ priv->silence->end = priv->info->len;
+ priv->info->silences = g_slist_append (priv->info->silences, priv->silence);
+ priv->silence = NULL;
+ }
+
+ /* before leaving, check if we need a snapshot */
+ if (priv->snapshot
+ && priv->video_linked
+ && !priv->snapshot_started)
+ return brasero_metadata_thumbnail (self);
+
+ return brasero_metadata_completed (self);
+}
+
+static gboolean
+brasero_metadata_get_duration (BraseroMetadata *self,
+ GstElement *pipeline,
+ gboolean use_duration)
+{
+ GstFormat format = GST_FORMAT_TIME;
+ BraseroMetadataPrivate *priv;
+ gint64 duration = -1;
+
+ priv = BRASERO_METADATA_PRIVATE (self);
+
+ if (!use_duration)
+ gst_element_query_position (GST_ELEMENT (pipeline),
&format,
&duration);
-
- if (duration == -1)
- gst_element_query_duration (GST_ELEMENT (priv->pipeline),
+ else
+ gst_element_query_duration (GST_ELEMENT (pipeline),
&format,
&duration);
@@ -606,26 +679,153 @@
BRASERO_BURN_LOG ("found duration %lli for %s", duration, priv->info->uri);
priv->info->len = duration;
+ return brasero_metadata_success (self);
+}
- /* check if that's a seekable one */
- brasero_metadata_is_seekable (self);
+/**
+ * This is to deal with mp3 more particularly the vbrs
+ **/
- if (priv->silence) {
- priv->silence->end = duration;
- priv->info->silences = g_slist_append (priv->info->silences, priv->silence);
- priv->silence = NULL;
+static gboolean
+brasero_metadata_mp3_bus_messages (GstBus *bus,
+ GstMessage *msg,
+ BraseroMetadata *self)
+{
+ BraseroMetadataPrivate *priv;
+ gchar *debug_string = NULL;
+ GError *error = NULL;
+
+ priv = BRASERO_METADATA_PRIVATE (self);
+
+ switch (GST_MESSAGE_TYPE (msg)) {
+ case GST_MESSAGE_ERROR:
+ /* save the error message */
+ gst_message_parse_error (msg, &error, &debug_string);
+ BRASERO_BURN_LOG ("Gstreamer error - mp3 - (%s)", debug_string);
+ g_free (debug_string);
+ if (!priv->error && error)
+ priv->error = error;
+
+ brasero_metadata_completed (self);
+ return FALSE;
+
+ case GST_MESSAGE_EOS:
+ BRASERO_BURN_LOG ("End of stream reached - mp3 - for %s", priv->info->uri);
+ brasero_metadata_get_duration (self, priv->pipeline_mp3, FALSE);
+ return FALSE;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+brasero_metadata_create_mp3_pipeline (BraseroMetadata *self)
+{
+ BraseroMetadataPrivate *priv;
+ GstElement *source;
+ GstElement *parse;
+ GstElement *sink;
+ GstBus *bus;
+
+ priv = BRASERO_METADATA_PRIVATE (self);
+
+ priv->pipeline_mp3 = gst_pipeline_new (NULL);
+
+ source = gst_element_make_from_uri (GST_URI_SRC,
+ priv->info->uri,
+ NULL);
+ if (!source) {
+ priv->error = g_error_new (BRASERO_ERROR,
+ BRASERO_ERROR_GENERAL,
+ _("%s element could not be created"),
+ "\"Source\"");
+
+ g_object_unref (priv->pipeline_mp3);
+ priv->pipeline_mp3 = NULL;
+ return FALSE;
}
+ gst_bin_add (GST_BIN (priv->pipeline_mp3), source);
+
+ parse = gst_element_factory_make ("mp3parse", NULL);
+ if (!parse) {
+ priv->error = g_error_new (BRASERO_ERROR,
+ BRASERO_ERROR_GENERAL,
+ _("%s element could not be created"),
+ "\"mp3parse\"");
+
+ g_object_unref (priv->pipeline_mp3);
+ priv->pipeline_mp3 = NULL;
+ return FALSE;
+ }
+ gst_bin_add (GST_BIN (priv->pipeline_mp3), parse);
+
+ sink = gst_element_factory_make ("fakesink", NULL);
+ if (!sink) {
+ priv->error = g_error_new (BRASERO_ERROR,
+ BRASERO_ERROR_GENERAL,
+ _("%s element could not be created"),
+ "\"Fakesink\"");
+
+ g_object_unref (priv->pipeline_mp3);
+ priv->pipeline_mp3 = NULL;
+ return FALSE;
+ }
+ gst_bin_add (GST_BIN (priv->pipeline_mp3), sink);
+
+ /* Link */
+ if (!gst_element_link (source, parse)) {
+ g_object_unref (priv->pipeline_mp3);
+ priv->pipeline_mp3 = NULL;
+ return FALSE;
+ }
+
+ if (!gst_element_link (parse, sink)) {
+ g_object_unref (priv->pipeline_mp3);
+ priv->pipeline_mp3 = NULL;
+ return FALSE;
+ }
+
+ /* Bus */
+ bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline_mp3));
+ priv->watch_mp3 = gst_bus_add_watch (bus,
+ (GstBusFunc) brasero_metadata_mp3_bus_messages,
+ self);
+ gst_object_unref (bus);
+
+ gst_element_set_state (priv->pipeline_mp3, GST_STATE_PLAYING);
+ return TRUE;
+}
+
+static gboolean
+brasero_metadata_success_main (BraseroMetadata *self)
+{
+ BraseroMetadataPrivate *priv;
+
+ priv = BRASERO_METADATA_PRIVATE (self);
+
+ BRASERO_BURN_LOG ("Metadata retrieval successfully completed for %s", priv->info->uri);
+
+ /* find the type of the file */
+ brasero_metadata_get_mime_type (self);
/* empty the bus of any pending message */
brasero_metadata_process_pending_tag_messages (self);
- /* before leaving, check if we need a snapshot */
- if (priv->snapshot
- && priv->video_linked
- && !priv->snapshot_started)
- return brasero_metadata_thumbnail (self);
+ /* get the size */
+ if (brasero_metadata_is_mp3 (self)) {
+ if (!brasero_metadata_create_mp3_pipeline (self)) {
+ BRASERO_BURN_LOG ("Impossible to run mp3 specific pipeline");
+ return brasero_metadata_completed (self);
+ }
- return brasero_metadata_completed (self);
+ /* Return FALSE here not because we failed but to stop the Bus callback */
+ return FALSE;
+ }
+
+ return brasero_metadata_get_duration (self, priv->pipeline, TRUE);
}
static void
@@ -883,10 +1083,8 @@
priv = BRASERO_METADATA_PRIVATE (self);
switch (GST_MESSAGE_TYPE (msg)) {
- case GST_MESSAGE_ASYNC_DONE:
- BRASERO_BURN_LOG ("Async state change done for %s", priv->info->uri);
- break;
case GST_MESSAGE_ELEMENT:
+ /* This is for snapshot function */
if (!strcmp (gst_structure_get_name (msg->structure), "preroll-pixbuf")
|| !strcmp (gst_structure_get_name (msg->structure), "pixbuf")) {
const GValue *value;
@@ -898,11 +1096,11 @@
BRASERO_BURN_LOG ("Received pixbuf snapshot sink (%p) for %s", priv->info->snapshot, priv->info->uri);
/* Now we can stop */
- brasero_metadata_completed (self);
- return TRUE;
+ return brasero_metadata_completed (self);
}
+
/* here we just want to check if that's a missing codec */
- else if ((priv->flags & BRASERO_METADATA_FLAG_MISSING)
+ if ((priv->flags & BRASERO_METADATA_FLAG_MISSING)
&& gst_is_missing_plugin_message (msg))
priv->missing_plugins = g_slist_prepend (priv->missing_plugins, gst_message_ref (msg));
else if (!strcmp (gst_structure_get_name (msg->structure), "level")
@@ -967,17 +1165,16 @@
/* See if we have missing plugins */
if (priv->missing_plugins) {
if (!brasero_metadata_install_missing_plugins (self))
- brasero_metadata_completed (self);
+ return brasero_metadata_completed (self);
}
else
- brasero_metadata_completed (self);
+ return brasero_metadata_completed (self);
break;
case GST_MESSAGE_EOS:
BRASERO_BURN_LOG ("End of stream reached for %s", priv->info->uri);
- brasero_metadata_success (self);
- break;
+ return brasero_metadata_success_main (self);
case GST_MESSAGE_TAG:
gst_message_parse_tag (msg, &tags);
@@ -998,41 +1195,8 @@
if (newstate != GST_STATE_PAUSED && newstate != GST_STATE_PLAYING)
break;
- if ((priv->flags & BRASERO_METADATA_FLAG_SILENCES)
- || brasero_metadata_is_mp3 (self)) {
- gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
-
- if (BRASERO_METADATA_IS_FAST (priv->flags)
- && !priv->moved_forward) {
- /* we try to go forward. This allows us to avoid
- * reading the whole file till the end. The byte
- * format is really important here as time
- * format needs calculation and is dead slow.
- * The number of bytes is important to reach
- * the end. */
- gst_element_seek (priv->pipeline,
- 1.0,
- GST_FORMAT_BYTES,
- GST_SEEK_FLAG_FLUSH,
- GST_SEEK_TYPE_SET,
- 52428800,
- GST_SEEK_TYPE_NONE,
- GST_CLOCK_TIME_NONE);
- priv->moved_forward = 1;
- }
-
- if (!priv->progress_id)
- priv->progress_id = g_timeout_add (500,
- (GSourceFunc) brasero_metadata_report_progress,
- self);
-
- break;
- }
-
- BRASERO_BURN_LOG ("State changed to PAUSED or PLAYING");
-
if (!priv->snapshot_started)
- brasero_metadata_success (self);
+ return brasero_metadata_success_main (self);
break;
@@ -1399,11 +1563,6 @@
priv->silence = NULL;
}
- if (priv->progress_id) {
- g_source_remove (priv->progress_id);
- priv->progress_id = 0;
- }
-
priv->info = g_new0 (BraseroMetadataInfo, 1);
priv->info->uri = g_strdup (uri);
@@ -1618,61 +1777,6 @@
return priv->flags;
}
-void
-brasero_metadata_info_copy (BraseroMetadataInfo *dest,
- BraseroMetadataInfo *src)
-{
- GSList *iter;
-
- if (!dest || !src)
- return;
-
- dest->isrc = src->isrc;
- dest->len = src->len;
- dest->is_seekable = src->is_seekable;
- dest->has_audio = src->has_audio;
- dest->has_video = src->has_video;
-
- if (src->uri)
- dest->uri = g_strdup (src->uri);
-
- if (src->type)
- dest->type = g_strdup (src->type);
-
- if (src->title)
- dest->title = g_strdup (src->title);
-
- if (src->artist)
- dest->artist = g_strdup (src->artist);
-
- if (src->album)
- dest->album = g_strdup (src->album);
-
- if (src->genre)
- dest->genre = g_strdup (src->genre);
-
- if (src->musicbrainz_id)
- dest->musicbrainz_id = g_strdup (src->musicbrainz_id);
-
- if (src->snapshot) {
- dest->snapshot = src->snapshot;
- g_object_ref (dest->snapshot);
- }
-
- for (iter = src->silences; iter; iter = iter->next) {
- BraseroMetadataSilence *silence, *copy;
-
- silence = iter->data;
-
- copy = g_new0 (BraseroMetadataSilence, 1);
- copy->start = silence->start;
- copy->end = silence->end;
-
- dest->silences = g_slist_append (dest->silences, copy);
- }
-
-}
-
gboolean
brasero_metadata_get_result (BraseroMetadata *self,
BraseroMetadataInfo *info,
@@ -1725,11 +1829,6 @@
priv->silence = NULL;
}
- if (priv->progress_id) {
- g_source_remove (priv->progress_id);
- priv->progress_id = 0;
- }
-
if (priv->error) {
g_error_free (priv->error);
priv->error = NULL;
@@ -1843,17 +1942,6 @@
G_TYPE_NONE,
1,
G_TYPE_POINTER);
- brasero_metadata_signals[PROGRESS_CHANGED_SIGNAL] =
- g_signal_new ("progress",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (BraseroMetadataClass,
- progress),
- NULL, NULL,
- g_cclosure_marshal_VOID__DOUBLE,
- G_TYPE_NONE,
- 1,
- G_TYPE_DOUBLE);
g_object_class_install_property (object_class,
PROP_URI,
g_param_spec_string ("uri",
Modified: trunk/src/brasero-metadata.h
==============================================================================
--- trunk/src/brasero-metadata.h (original)
+++ trunk/src/brasero-metadata.h Sun Feb 1 13:50:23 2009
@@ -39,7 +39,6 @@
typedef enum {
BRASERO_METADATA_FLAG_NONE = 0,
- BRASERO_METADATA_FLAG_FAST = 1,
BRASERO_METADATA_FLAG_SILENCES = 1 << 1,
BRASERO_METADATA_FLAG_MISSING = 1 << 2,
BRASERO_METADATA_FLAG_THUMBNAIL = 1 << 3
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]