brasero r872 - in branches/video: . src src/plugins src/plugins/cdrdao src/plugins/dvdauthor src/plugins/gstreamer src/plugins/transcode



Author: philippr
Date: Sun Jun  8 18:18:01 2008
New Revision: 872
URL: http://svn.gnome.org/viewvc/brasero?rev=872&view=rev

Log:
	Proof of concept:
	- this was only tested on a single video but may work with multiple videos
	- options in the burn option dialogs do nothing (yet)

	* configure.in:
	* src/Makefile.am:
	* src/brasero-disc-option-dialog.c
	(brasero_disc_option_dialog_get_default_label),
	(brasero_disc_option_dialog_add_video_options),
	(brasero_disc_option_dialog_set_disc):
	* src/brasero-file-chooser.c (brasero_file_chooser_init),
	(brasero_file_chooser_set_context):
	* src/brasero-io.c (brasero_io_set_metadata_attributes),
	(brasero_io_get_metadata_info), (brasero_io_get_file_info_thread),
	(brasero_io_get_file_count_process_playlist),
	(brasero_io_get_file_count_process_file),
	(brasero_io_load_directory_playlist),
	(brasero_io_load_directory_thread):
	* src/brasero-io.h:
	* src/brasero-layout.c (brasero_layout_displayed_item_changed_cb),
	(brasero_layout_save), (brasero_layout_load):
	* src/brasero-layout.h:
	* src/brasero-metadata.c (brasero_metadata_info_clear),
	(brasero_metadata_completed), (brasero_metadata_thumbnail),
	(brasero_metadata_success), (brasero_metadata_bus_messages),
	(brasero_metadata_create_audio_pipeline),
	(brasero_metadata_create_video_pipeline),
	(brasero_metadata_new_decoded_pad_cb),
	(brasero_metadata_create_pipeline), (brasero_metadata_set_new_uri),
	(brasero_metadata_get_info_wait), (brasero_metadata_get_info_sync),
	(brasero_metadata_get_info_async), (brasero_metadata_info_copy),
	(brasero_metadata_destroy_pipeline):
	* src/brasero-metadata.h:
	* src/brasero-project-manager.c (brasero_project_manager_switch),
	(brasero_project_manager_new_video_prj_cb),
	(brasero_project_manager_video), (brasero_project_manager_init):
	* src/brasero-project-manager.h:
	* src/brasero-project-type-chooser.c:
	* src/brasero-project-type-chooser.h:
	* src/brasero-project.c (brasero_project_init),
	(brasero_project_switch), (brasero_project_set_audio),
	(brasero_project_set_data), (brasero_project_set_video):
	* src/brasero-project.h:
	* src/brasero-video-disc.c
	(brasero_video_disc_increase_activity_counter),
	(brasero_video_disc_decrease_activity_counter),
	(brasero_video_disc_io_operation_finished),
	(brasero_video_disc_unreadable_dialog),
	(brasero_video_disc_file_not_video_dialog),
	(brasero_video_disc_new_row_cb), (brasero_video_disc_add_uri_real),
	(brasero_video_disc_add_uri), (brasero_video_disc_delete_selected),
	(brasero_video_disc_get_selected_uri),
	(brasero_video_disc_selection_changed_cb),
	(brasero_video_disc_add_ui), (brasero_video_disc_row_deleted_cb),
	(brasero_video_disc_row_inserted_cb),
	(brasero_video_disc_row_changed_cb), (brasero_video_disc_init),
	(brasero_video_disc_reset_real), (brasero_video_disc_clear),
	(brasero_video_disc_reset), (brasero_video_disc_finalize),
	(brasero_video_disc_get_property),
	(brasero_video_disc_set_property), (brasero_video_disc_get_status),
	(brasero_video_disc_set_session_param),
	(brasero_video_disc_set_session_contents),
	(brasero_video_disc_iface_disc_init),
	(brasero_video_disc_class_init), (brasero_video_disc_new):
	* src/brasero-video-disc.h:
	* src/burn-basics.h:
	* src/burn-caps.c (brasero_caps_get_flags),
	(brasero_burn_caps_plugin_can_image):
	* src/burn-debug.c (brasero_debug_audio_format_to_string):
	* src/burn-job.c (brasero_job_item_start),
	(brasero_job_set_progress):
	* src/burn-process.c (brasero_process_finished):
	* src/burn-track.h:
	* src/plugins/Makefile.am:
	* src/plugins/cdrdao/burn-toc2cue.c (brasero_toc2cue_post):
	* src/plugins/dvdauthor/Makefile.am:
	* src/plugins/dvdauthor/burn-dvdauthor.c
	(brasero_dvd_author_add_track), (brasero_dvd_author_read_stdout),
	(brasero_dvd_author_read_stderr),
	(brasero_dvd_author_generate_xml_file),
	(brasero_dvd_author_set_argv), (brasero_dvd_author_post),
	(brasero_dvd_author_init), (brasero_dvd_author_finalize),
	(brasero_dvd_author_class_init), (brasero_dvd_author_export_caps):
	* src/plugins/dvdauthor/burn-dvdauthor.h:
	* src/plugins/gstreamer/Makefile.am:
	* src/plugins/gstreamer/burn-vob.c (brasero_vob_stop_pipeline),
	(brasero_vob_stop), (brasero_vob_finished),
	(brasero_vob_bus_messages), (brasero_vob_new_decoded_pad_cb),
	(brasero_vob_link_audio), (brasero_vob_build_audio_pcm),
	(brasero_vob_build_audio_mp2), (brasero_vob_build_audio_ac3),
	(brasero_vob_build_audio_bins), (brasero_vob_build_video_bin),
	(brasero_vob_build_pipeline), (brasero_vob_start),
	(brasero_vob_clock_tick), (brasero_vob_init),
	(brasero_vob_finalize), (brasero_vob_class_init),
	(brasero_vob_export_caps):
	* src/plugins/gstreamer/burn-vob.h:
	* src/plugins/transcode/Makefile.am:
	* src/plugins/transcode/burn-normalize.c:
	* src/plugins/transcode/burn-normalize.h:
	* src/plugins/transcode/burn-transcode.c:
	* src/plugins/transcode/burn-transcode.h:


Added:
   branches/video/src/brasero-video-disc.c
   branches/video/src/brasero-video-disc.h
   branches/video/src/plugins/dvdauthor/
   branches/video/src/plugins/dvdauthor/Makefile.am
   branches/video/src/plugins/dvdauthor/burn-dvdauthor.c   (contents, props changed)
   branches/video/src/plugins/dvdauthor/burn-dvdauthor.h   (contents, props changed)
   branches/video/src/plugins/gstreamer/
      - copied from r839, /trunk/src/plugins/transcode/
   branches/video/src/plugins/gstreamer/burn-vob.c   (contents, props changed)
   branches/video/src/plugins/gstreamer/burn-vob.h   (contents, props changed)
Removed:
   branches/video/src/plugins/transcode/
Modified:
   branches/video/ChangeLog
   branches/video/configure.in
   branches/video/src/Makefile.am
   branches/video/src/brasero-disc-option-dialog.c
   branches/video/src/brasero-file-chooser.c
   branches/video/src/brasero-io.c
   branches/video/src/brasero-io.h
   branches/video/src/brasero-layout.c
   branches/video/src/brasero-layout.h
   branches/video/src/brasero-metadata.c
   branches/video/src/brasero-metadata.h
   branches/video/src/brasero-project-manager.c
   branches/video/src/brasero-project-manager.h
   branches/video/src/brasero-project-type-chooser.c
   branches/video/src/brasero-project-type-chooser.h
   branches/video/src/brasero-project.c
   branches/video/src/brasero-project.h
   branches/video/src/burn-basics.h
   branches/video/src/burn-caps.c
   branches/video/src/burn-debug.c
   branches/video/src/burn-job.c
   branches/video/src/burn-process.c
   branches/video/src/burn-track.h
   branches/video/src/plugins/Makefile.am
   branches/video/src/plugins/cdrdao/burn-toc2cue.c
   branches/video/src/plugins/gstreamer/Makefile.am

Modified: branches/video/configure.in
==============================================================================
--- branches/video/configure.in	(original)
+++ branches/video/configure.in	Sun Jun  8 18:18:01 2008
@@ -125,6 +125,16 @@
 BRASERO_GIO_CFLAGS="$BRASERO_GIO_CFLAGS $CFLAGS"
 BRASERO_GIO_LIBS="$BRASERO_GIO_LIBS $LDFLAGS"
 
+dnl ** used by brasero and one plugin
+PKG_CHECK_MODULES(BRASERO_LIBXML, 	\
+	libxml-2.0 >= $LIBXML2_REQUIRED)
+
+AC_SUBST(BRASERO_LIBXML_CFLAGS)
+AC_SUBST(BRASERO_LIBXML_LIBS)
+
+BRASERO_LIBXML_CFLAGS="$BRASERO_LIBXML_CFLAGS $CFLAGS"
+BRASERO_LIBXML_LIBS="$BRASERO_LIBXML_LIBS $LDFLAGS"
+
 dnl ** used by brasero and all modules
 PKG_CHECK_MODULES(BRASERO_BASE, 		\
 	gconf-2.0 >= $GCONF_REQUIRED		\
@@ -144,7 +154,6 @@
 	gtk+-2.0 >= $GTK_REQUIRED		\
 	libgnome-2.0 >= $LIBGNOME_REQUIRED	\
 	libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED	\
-	libxml-2.0 >= $LIBXML2_REQUIRED	\
 	dbus-glib-1 >= $DBUS_REQUIRED)
 
 AC_SUBST(BRASERO_CFLAGS)
@@ -340,8 +349,9 @@
 src/plugins/cdrtools/Makefile
 src/plugins/growisofs/Makefile
 src/plugins/libburnia/Makefile
-src/plugins/transcode/Makefile
+src/plugins/gstreamer/Makefile
 src/plugins/dvdcss/Makefile
+src/plugins/dvdauthor/Makefile
 src/plugins/checksum/Makefile
 src/plugins/local-track/Makefile
 po/Makefile.in

Modified: branches/video/src/Makefile.am
==============================================================================
--- branches/video/src/Makefile.am	(original)
+++ branches/video/src/Makefile.am	Sun Jun  8 18:18:01 2008
@@ -14,7 +14,8 @@
 	-DBRASERO_DATADIR=\"$(datadir)/brasero\"     	    		\
 	-DBRASERO_LIBDIR=\"$(libdir)\"  	         		\
 	$(DISABLE_DEPRECATED)						\
-	$(BRASERO_CFLAGS)
+	$(BRASERO_CFLAGS)						\
+	$(BRASERO_LIBXML_CFLAGS)
 
 CLEANFILES = $(RECMARSHALFILES)
 
@@ -259,7 +260,9 @@
 	brasero-notify.c         \
 	brasero-notify.h         \
 	burn-volume-source.c         \
-	burn-volume-source.h
+	burn-volume-source.h         \
+	brasero-video-disc.c         \
+	brasero-video-disc.h
 
 if BUILD_INOTIFY
 brasero_SOURCES += brasero-file-monitor.c brasero-file-monitor.h
@@ -276,7 +279,7 @@
 endif
 
 brasero_LDADD =	\
-	$(BRASERO_LIBS)
+	$(BRASERO_LIBS) $(BRASERO_LIBXML_LIBS)
 
 
 

Modified: branches/video/src/brasero-disc-option-dialog.c
==============================================================================
--- branches/video/src/brasero-disc-option-dialog.c	(original)
+++ branches/video/src/brasero-disc-option-dialog.c	Sun Jun  8 18:18:01 2008
@@ -195,9 +195,14 @@
 		}
 	}
 	else if (source.type == BRASERO_TRACK_TYPE_AUDIO) {
-		/* NOTE to translators: the final string must not be over
-		 * 32 _bytes_ */
-		title_str = g_strdup_printf (_("Audio disc (%s)"), buffer);
+		if (source.subtype.audio_format & (BRASERO_VIDEO_FORMAT_UNDEFINED|BRASERO_VIDEO_FORMAT_MPEG2))
+			/* NOTE to translators: the final string must not be over
+			 * 32 _bytes_ */
+			title_str = g_strdup_printf (_("Video disc (%s)"), buffer);
+		else
+			/* NOTE to translators: the final string must not be over
+			 * 32 _bytes_ */
+			title_str = g_strdup_printf (_("Audio disc (%s)"), buffer);
 
 		if (strlen (title_str) > 32) {
 			g_free (title_str);
@@ -753,7 +758,7 @@
 			  G_CALLBACK (brasero_disc_option_dialog_multi_toggled),
 			  dialog);
 	gtk_widget_set_tooltip_text (priv->multi_toggle,
-			      _("Allow create what is called an enhanced CD or CD+"));
+				     _("Allow create what is called an enhanced CD or CD+"));
 
 	options = brasero_utils_pack_properties (_("<b>Disc options</b>"),
 						 priv->multi_toggle,
@@ -764,6 +769,58 @@
 	gtk_widget_show_all (widget);
 }
 
+static void
+brasero_disc_option_dialog_add_video_options (BraseroDiscOptionDialog *dialog)
+{
+	GtkWidget *button1;
+	GtkWidget *button2;
+	GtkWidget *button3;
+	GtkWidget *widget;
+	GtkWidget *options;
+	BraseroDiscOptionDialogPrivate *priv;
+
+	priv = BRASERO_DISC_OPTION_DIALOG_PRIVATE (dialog);
+
+	widget = gtk_vbox_new (FALSE, 0);
+	gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+			  widget,
+			  TRUE,
+			  FALSE,
+			  6);
+
+	button1 = gtk_radio_button_new_with_mnemonic (NULL, _("_NTSC"));
+	gtk_widget_set_tooltip_text (button1, _("Format used mostly on the North American Continent"));
+	button2 = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (button1), _("_PAL/SECAM"));
+	gtk_widget_set_tooltip_text (button2, _("Format used mostly in Europe"));
+	button3 = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (button1), _("Native _format"));
+	options = brasero_utils_pack_properties (_("<b>Video format</b>"),
+						 button1,
+						 button2,
+						 button3,
+						 NULL);
+	gtk_box_pack_start (GTK_BOX (widget), options, FALSE, FALSE, 0);
+
+	button1 = gtk_radio_button_new_with_mnemonic (NULL, _("_4:3"));
+	button2 = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (button1), _("_16:9"));
+	button3 = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (button1), _("Native aspect _ratio"));
+	options = brasero_utils_pack_properties (_("<b>Aspect ratio</b>"),
+						 button1,
+						 button2,
+						 button3,
+						 NULL);
+	gtk_box_pack_start (GTK_BOX (widget), options, FALSE, FALSE, 0);
+
+	button1 = gtk_check_button_new_with_mnemonic (_("_AC3"));
+	button2 = gtk_check_button_new_with_mnemonic (_("_MP2"));
+	options = brasero_utils_pack_properties (_("<b>Audio formats</b>"),
+						 button1,
+						 button2,
+						 NULL);
+	gtk_box_pack_start (GTK_BOX (widget), options, FALSE, FALSE, 0);
+
+	gtk_widget_show_all (widget);
+}
+
 void
 brasero_disc_option_dialog_set_disc (BraseroDiscOptionDialog *dialog,
 				     BraseroDisc *disc)
@@ -808,9 +865,17 @@
 		brasero_disc_option_dialog_add_data_options (dialog);
 	}
 	else if (type.type == BRASERO_TRACK_TYPE_AUDIO) {
-		brasero_drive_selection_set_type_shown (BRASERO_DRIVE_SELECTION (priv->selection),
-							BRASERO_MEDIA_TYPE_WRITABLE);
-		brasero_disc_option_dialog_add_audio_options (dialog);
+		if (type.subtype.audio_format & (BRASERO_VIDEO_FORMAT_UNDEFINED|BRASERO_VIDEO_FORMAT_MPEG2)) {
+			brasero_drive_selection_set_type_shown (BRASERO_DRIVE_SELECTION (priv->selection),
+								BRASERO_MEDIA_TYPE_WRITABLE|
+								BRASERO_MEDIA_TYPE_FILE);
+			brasero_disc_option_dialog_add_video_options (dialog);
+		}
+		else {
+			brasero_drive_selection_set_type_shown (BRASERO_DRIVE_SELECTION (priv->selection),
+								BRASERO_MEDIA_TYPE_WRITABLE);
+			brasero_disc_option_dialog_add_audio_options (dialog);
+		}
 	}
 }
 

Modified: branches/video/src/brasero-file-chooser.c
==============================================================================
--- branches/video/src/brasero-file-chooser.c	(original)
+++ branches/video/src/brasero-file-chooser.c	Sun Jun  8 18:18:01 2008
@@ -68,6 +68,7 @@
 
 	GtkFileFilter *filter_any;
 	GtkFileFilter *filter_audio;
+	GtkFileFilter *filter_video;
 };
 
 static GObjectClass *parent_class = NULL;
@@ -234,6 +235,8 @@
 	gtk_file_filter_add_mime_type (filter, "application/x-flash-video");
 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (obj->priv->chooser), filter);
 
+	obj->priv->filter_video = filter;
+
 	filter = gtk_file_filter_new ();
 	gtk_file_filter_set_name (filter, _("Image files only"));
 	gtk_file_filter_add_mime_type (filter, "image/*");
@@ -373,6 +376,9 @@
 	if (type == BRASERO_LAYOUT_AUDIO)
 		gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (self->priv->chooser),
 					     self->priv->filter_audio);
+	else if (type == BRASERO_LAYOUT_VIDEO)
+		gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (self->priv->chooser),
+					     self->priv->filter_video);
 	else
 		gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (self->priv->chooser),
 					     self->priv->filter_any);

Modified: branches/video/src/brasero-io.c
==============================================================================
--- branches/video/src/brasero-io.c	(original)
+++ branches/video/src/brasero-io.c	Sun Jun  8 18:18:01 2008
@@ -614,6 +614,9 @@
 	g_file_info_set_attribute_boolean (info, BRASERO_IO_HAS_VIDEO, metadata->has_video);
 	g_file_info_set_attribute_boolean (info, BRASERO_IO_IS_SEEKABLE, metadata->is_seekable);
 
+	if (metadata->snapshot)
+		g_file_info_set_attribute_object (info, BRASERO_IO_SNAPSHOT, G_OBJECT (metadata->snapshot));
+
 	/* FIXME: what about silences */
 }
 
@@ -647,8 +650,24 @@
 				    uri,
 				    brasero_io_metadata_lookup_buffer);
 	if (node) {
-		brasero_metadata_info_copy (meta_info, node->data);
-		return TRUE;
+		if (flags & BRASERO_METADATA_FLAG_SNAPHOT) {
+			BraseroMetadataInfo *saved;
+
+			saved = node->data;
+			if (saved->snapshot) {
+				brasero_metadata_info_copy (meta_info, node->data);
+				return TRUE;
+			}
+
+			/* remove it from the queue since we can't keep the same
+			 * URI twice */
+			g_queue_remove (priv->meta_buffer, saved);
+			brasero_metadata_info_free (saved);
+		}
+		else {
+			brasero_metadata_info_copy (meta_info, node->data);
+			return TRUE;
+		}
 	}
 
 	/* grab an available metadata (NOTE: there should always be at least one
@@ -793,7 +812,8 @@
 						       cancel,
 						       file_uri?file_uri:job->uri,
 						       info,
-						       (job->options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0,
+						       ((job->options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0) |
+						       ((job->options & BRASERO_IO_INFO_METADATA_SNAPSHOT) ? BRASERO_METADATA_FLAG_SNAPHOT : 0),
 						       &metadata);
 
 		if (result)
@@ -1085,6 +1105,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_SNAPSHOT) ? BRASERO_METADATA_FLAG_SNAPHOT : 0) |
 						       BRASERO_METADATA_FLAG_FAST,
 						       &metadata);
 
@@ -1120,7 +1141,8 @@
 						       cancel,
 						       child_uri,
 						       info,
-						       (data->job.options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0,
+						       ((data->job.options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0) |
+						       ((data->job.options & BRASERO_IO_INFO_METADATA_SNAPSHOT) ? BRASERO_METADATA_FLAG_SNAPHOT : 0),
 						       &metadata);
 		if (result)
 			data->total_b += metadata.len;
@@ -1415,6 +1437,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_SNAPSHOT) ? BRASERO_METADATA_FLAG_SNAPHOT : 0) |
 						       BRASERO_METADATA_FLAG_FAST,
 						       &metadata);
 
@@ -1571,7 +1594,8 @@
 							       cancel,
 							       child_uri,
 							       info,
-							       (data->job.options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0,
+							       ((data->job.options & BRASERO_IO_INFO_METADATA_MISSING_CODEC) ? BRASERO_METADATA_FLAG_MISSING : 0) |
+							       ((data->job.options & BRASERO_IO_INFO_METADATA_SNAPSHOT) ? BRASERO_METADATA_FLAG_SNAPHOT : 0),
 							       &metadata);
 
 			if (result)

Modified: branches/video/src/brasero-io.h
==============================================================================
--- branches/video/src/brasero-io.h	(original)
+++ branches/video/src/brasero-io.h	Sun Jun  8 18:18:01 2008
@@ -59,9 +59,10 @@
 	BRASERO_IO_INFO_ICON			= 1,
 	BRASERO_IO_INFO_PERM			= 1 << 1,
 	BRASERO_IO_INFO_METADATA		= 1 << 2,
-	BRASERO_IO_INFO_RECURSIVE		= 1 << 3,
-	BRASERO_IO_INFO_CHECK_PARENT_SYMLINK	= 1 << 4,
-	BRASERO_IO_INFO_METADATA_MISSING_CODEC	= 1 << 5,
+	BRASERO_IO_INFO_METADATA_SNAPSHOT		= 1 << 3,
+	BRASERO_IO_INFO_RECURSIVE		= 1 << 4,
+	BRASERO_IO_INFO_CHECK_PARENT_SYMLINK	= 1 << 5,
+	BRASERO_IO_INFO_METADATA_MISSING_CODEC	= 1 << 6,
 
 	BRASERO_IO_INFO_URGENT			= 1 << 9,
 	BRASERO_IO_INFO_IDLE			= 1 << 10
@@ -81,12 +82,13 @@
 #define BRASERO_IO_COUNT_SIZE		"count::size"
 #define BRASERO_IO_COUNT_INVALID	"count::invalid"
 
+#define BRASERO_IO_SNAPSHOT		"metadata::snapshot"
+
 #define BRASERO_IO_LEN			"metadata::length"
 #define BRASERO_IO_ISRC			"metadata::isrc"
 #define BRASERO_IO_TITLE		"metadata::title"
 #define BRASERO_IO_ARTIST		"metadata::artist"
 #define BRASERO_IO_ALBUM		"metadata::album"
-#define BRASERO_IO_ALBUM		"metadata::album"
 #define BRASERO_IO_GENRE		"metadata::genre"
 #define BRASERO_IO_COMPOSER		"metadata::composer"
 #define BRASERO_IO_HAS_AUDIO		"metadata::has_audio"

Modified: branches/video/src/brasero-layout.c
==============================================================================
--- branches/video/src/brasero-layout.c	(original)
+++ branches/video/src/brasero-layout.c	Sun Jun  8 18:18:01 2008
@@ -158,6 +158,7 @@
 #define BRASERO_KEY_DISPLAY_DIR		"/apps/brasero/display/"
 #define BRASERO_KEY_LAYOUT_AUDIO	BRASERO_KEY_DISPLAY_DIR "audio_pane"
 #define BRASERO_KEY_LAYOUT_DATA		BRASERO_KEY_DISPLAY_DIR "data_pane"
+#define BRASERO_KEY_LAYOUT_VIDEO	BRASERO_KEY_DISPLAY_DIR "video_pane"
 
 static void
 brasero_layout_pack_preview (BraseroLayout *layout)
@@ -560,6 +561,10 @@
 	&&  layout->priv->ctx_type == BRASERO_LAYOUT_DATA)
 		return;
 
+	if (!strcmp (entry->key, BRASERO_KEY_LAYOUT_VIDEO)
+	&&  layout->priv->ctx_type == BRASERO_LAYOUT_VIDEO)
+		return;
+
 	value = gconf_entry_get_value (entry);
 	if (value->type != GCONF_VALUE_STRING)
 		return;
@@ -643,6 +648,25 @@
 								      NULL,
 								      &error);
 	}
+	else if (layout->priv->ctx_type == BRASERO_LAYOUT_VIDEO) {
+		gconf_client_set_string (layout->priv->client,
+					 BRASERO_KEY_LAYOUT_VIDEO,
+					 id,
+					 &error);
+
+		if (error) {
+			g_warning ("Can't set GConf key %s. \n", error->message);
+			g_error_free (error);
+			error = NULL;
+		}
+
+		layout->priv->radio_notify = gconf_client_notify_add (layout->priv->client,
+								      BRASERO_KEY_LAYOUT_VIDEO,
+								      brasero_layout_displayed_item_changed_cb,
+								      layout,
+								      NULL,
+								      &error);
+	}
 
 	if (error) {
 		g_warning ("Can't set GConf notify on key %s. \n", error->message);
@@ -800,6 +824,10 @@
 		layout_id = gconf_client_get_string (layout->priv->client,
 						     BRASERO_KEY_LAYOUT_DATA,
 						     &error);
+	else if (type == BRASERO_LAYOUT_VIDEO)
+		layout_id = gconf_client_get_string (layout->priv->client,
+						     BRASERO_KEY_LAYOUT_VIDEO,
+						     &error);
 
 	if (error) {
 		g_warning ("Can't access GConf key %s. This is probably harmless (first launch of brasero).\n", error->message);
@@ -822,6 +850,13 @@
 								      layout,
 								      NULL,
 								      &error);
+	else if (type == BRASERO_LAYOUT_VIDEO)
+		layout->priv->radio_notify = gconf_client_notify_add (layout->priv->client,
+								      BRASERO_KEY_LAYOUT_VIDEO,
+								      brasero_layout_displayed_item_changed_cb,
+								      layout,
+								      NULL,
+								      &error);
 
 	if (error) {
 		g_warning ("Could not set notify for GConf key %s.\n", error->message);

Modified: branches/video/src/brasero-layout.h
==============================================================================
--- branches/video/src/brasero-layout.h	(original)
+++ branches/video/src/brasero-layout.h	Sun Jun  8 18:18:01 2008
@@ -50,6 +50,7 @@
 	BRASERO_LAYOUT_NONE		= 0,
 	BRASERO_LAYOUT_AUDIO		= 1,
 	BRASERO_LAYOUT_DATA		= 1 << 1,
+	BRASERO_LAYOUT_VIDEO		= 1 << 2
 } BraseroLayoutType;
 
 typedef struct {

Modified: branches/video/src/brasero-metadata.c
==============================================================================
--- branches/video/src/brasero-metadata.c	(original)
+++ branches/video/src/brasero-metadata.c	Sun Jun  8 18:18:01 2008
@@ -32,6 +32,8 @@
 #include <glib/gi18n-lib.h>
 #include <glib-object.h>
 
+#include <gdk/gdkpixbuf.h>
+
 #include <gst/gst.h>
 #include <gst/base/gstbasesink.h>
 #include <gst/pbutils/install-plugins.h>
@@ -42,6 +44,8 @@
 #include "brasero-utils.h"
 #include "burn-debug.h"
 
+#define BRASERO_METADATA_INITIAL_STATE		GST_STATE_PAUSED
+
 
 G_DEFINE_TYPE(BraseroMetadata, brasero_metadata, G_TYPE_OBJECT)
 
@@ -54,7 +58,11 @@
 	GstElement *convert;
 	GstElement *level;
 	GstElement *sink;
-	GstElement *first;
+
+	GstElement *audio;
+	GstElement *video;
+
+	GstElement *snapshot;
 
 	GMainLoop *loop;
 	GError *error;
@@ -77,6 +85,9 @@
 	guint started:1;
 	guint moved_forward:1;
 	guint prev_level_mes:1;
+	guint video_linked:1;
+	guint audio_linked:1;
+	guint snapshot_started:1;
 };
 typedef struct BraseroMetadataPrivate BraseroMetadataPrivate;
 #define BRASERO_METADATA_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), BRASERO_TYPE_METADATA, BraseroMetadataPrivate))
@@ -117,6 +128,11 @@
 	if (!info)
 		return;
 
+	if (info->snapshot) {
+		g_object_unref (info->snapshot);
+		info->snapshot = NULL;
+	}
+
 	if (info->uri)
 		g_free (info->uri);
 
@@ -225,6 +241,26 @@
 	}
 }
 
+static gboolean
+brasero_metadata_completed (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+	if ((!priv->loop || !g_main_loop_is_running (priv->loop)) && !priv->cond) {
+		/* 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)
 {
@@ -250,6 +286,42 @@
 	return TRUE;
 }
 
+static gboolean
+brasero_metadata_thumbnail (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+	gint64 position;
+	gboolean res;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+
+	/* find the right position and move forward */
+	position = 15 * GST_SECOND;
+	while (position >= priv->info->len)
+		position -= 5 * GST_SECOND;
+
+	gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
+
+	priv->snapshot_started = 1;
+	if (position < GST_SECOND)
+		position = GST_SECOND;
+
+	res = gst_element_seek_simple (priv->pipeline,
+				       GST_FORMAT_TIME,
+				       GST_SEEK_FLAG_FLUSH,
+				       position);
+
+	BRASERO_BURN_LOG ("Seeking forward %i for %s", res, priv->info->uri);
+	if (!res)
+		return brasero_metadata_completed (self);
+
+	g_object_set (priv->snapshot,
+		      "send-messages", TRUE,
+		      NULL);
+
+	return TRUE;
+}
+
 static void
 brasero_metadata_is_seekable (BraseroMetadata *self)
 {
@@ -338,26 +410,6 @@
 	return FALSE;
 }
 
-static gboolean
-brasero_metadata_completed (BraseroMetadata *self)
-{
-	BraseroMetadataPrivate *priv;
-
-	priv = BRASERO_METADATA_PRIVATE (self);
-	if ((!priv->loop || !g_main_loop_is_running (priv->loop)) && !priv->cond) {
-		/* 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 void
 foreach_tag (const GstTagList *list,
 	     const gchar *tag,
@@ -436,6 +488,8 @@
 
 	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);
 
@@ -461,7 +515,7 @@
 		return brasero_metadata_completed (self);
 	}
 
-	BRASERO_BURN_LOG ("found duration %lli", duration);
+	BRASERO_BURN_LOG ("found duration %lli for %s", duration, priv->info->uri);
 
 	priv->info->len = duration;
 
@@ -477,6 +531,12 @@
 	/* 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);
+
 	return brasero_metadata_completed (self);
 }
 
@@ -735,10 +795,27 @@
 	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:
+		if (!strcmp (gst_structure_get_name (msg->structure), "preroll-pixbuf")
+		||  !strcmp (gst_structure_get_name (msg->structure), "pixbuf")) {
+			const GValue *value;
+
+			value = gst_structure_get_value (msg->structure, "pixbuf");
+			priv->info->snapshot = g_value_get_object (value);
+			g_object_ref (priv->info->snapshot);
+
+			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;
+		}
 		/* here we just want to check if that's a missing codec */
-		if ((priv->flags & BRASERO_METADATA_FLAG_MISSING)
-		&&   gst_is_missing_plugin_message (msg))
+		else 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")
 		     &&   gst_structure_has_field (msg->structure, "peak")) {
@@ -810,6 +887,7 @@
 		break;
 
 	case GST_MESSAGE_EOS:
+		BRASERO_BURN_LOG ("End of stream reached for %s", priv->info->uri);
 		brasero_metadata_success (self);
 		break;
 
@@ -825,6 +903,7 @@
 						&newstate,
 						NULL,
 						0);
+
 		if (result != GST_STATE_CHANGE_SUCCESS)
 			break;
 
@@ -872,6 +951,109 @@
 	return TRUE;
 }
 
+static gboolean
+brasero_metadata_create_audio_pipeline (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+	GstPad *audio_pad;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+
+	priv->audio = gst_bin_new (NULL);
+
+	/* set up the pipeline according to flags */
+	if (priv->flags & BRASERO_METADATA_FLAG_SILENCES) {
+		priv->prev_level_mes = 0;
+		gst_object_ref (priv->convert);
+		gst_object_ref (priv->level);
+		gst_object_ref (priv->sink);
+
+		gst_bin_add_many (GST_BIN (priv->audio),
+				  priv->convert,
+				  priv->level,
+				  priv->sink,
+				  NULL);
+		gst_element_link_many (priv->convert,
+				       priv->level,
+				       priv->sink,
+				       NULL);
+		audio_pad = gst_element_get_static_pad (priv->convert, "sink");
+	}
+	else if (priv->flags & BRASERO_METADATA_FLAG_SNAPHOT) {
+		GstElement *queue;
+
+		queue = gst_element_factory_make ("queue", NULL);
+		gst_object_ref (priv->convert);
+		gst_object_ref (priv->sink);
+
+		gst_bin_add_many (GST_BIN (priv->audio),
+				  queue,
+				  priv->convert,
+				  priv->sink,
+				  NULL);
+		gst_element_link_many (queue,
+				       priv->convert,
+				       priv->sink,
+				       NULL);
+		audio_pad = gst_element_get_static_pad (queue, "sink");
+	}
+	else {
+		gst_object_ref (priv->sink);
+		gst_bin_add (GST_BIN (priv->audio), priv->sink);
+		audio_pad = gst_element_get_static_pad (priv->sink, "sink");
+	}
+
+	gst_element_add_pad (priv->audio, gst_ghost_pad_new ("sink", audio_pad));
+	gst_object_unref (audio_pad);
+
+	gst_bin_add (GST_BIN (priv->pipeline), priv->audio);
+	BRASERO_BURN_LOG ("Adding audio pipeline for %s", priv->info->uri);
+
+	return TRUE;
+}
+
+static gboolean
+brasero_metadata_create_video_pipeline (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+	GstElement *colorspace;
+	GstPad *video_pad;
+	GstElement *queue;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+
+	priv->video = gst_bin_new (NULL);
+
+	priv->snapshot = gst_element_factory_make ("gdkpixbufsink", NULL);
+	colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
+	queue = gst_element_factory_make ("queue", NULL);
+
+	g_object_set (priv->snapshot,
+		      "qos", FALSE,
+		      "send-messages", FALSE,
+		      "max-lateness", (gint64) - 1,
+		      NULL);
+
+	gst_bin_add_many (GST_BIN (priv->video),
+			  queue,
+			  colorspace,
+			  priv->snapshot,
+			  NULL);
+	gst_element_link_many (queue,
+			       colorspace,
+			       priv->snapshot,
+			       NULL);
+
+	video_pad = gst_element_get_static_pad (queue, "sink");
+	gst_element_add_pad (priv->video, gst_ghost_pad_new ("sink", video_pad));
+	gst_object_unref (video_pad);
+
+	gst_bin_add (GST_BIN (priv->pipeline), priv->video);
+	BRASERO_BURN_LOG ("Adding pixbuf snapshot sink for %s", priv->info->uri);
+
+	return TRUE;
+}
+
 static void
 brasero_metadata_new_decoded_pad_cb (GstElement *decode,
 				     GstPad *pad,
@@ -880,6 +1062,9 @@
 {
 	GstPad *sink;
 	GstCaps *caps;
+	const gchar *name;
+	gboolean has_audio;
+	gboolean has_video;
 	GstPadLinkReturn res;
 	GstStructure *structure;
 	BraseroMetadataPrivate *priv;
@@ -887,26 +1072,55 @@
 	priv = BRASERO_METADATA_PRIVATE (self);
 
 	res = GST_PAD_LINK_REFUSED;
-	BRASERO_BURN_LOG ("new pad");
-	sink = gst_element_get_pad (priv->first, "sink");
-	if (!sink || GST_PAD_IS_LINKED (sink))
-		return;
+
+	BRASERO_BURN_LOG ("New pad for %s", priv->info->uri);
 
 	/* make sure that this is audio / video */
 	caps = gst_pad_get_caps (pad);
 	structure = gst_caps_get_structure (caps, 0);
-	if (structure) {
-		const gchar *name;
+	if (!structure)
+		return;
+
+	name = gst_structure_get_name (structure);
+	has_audio = (g_strrstr (name, "audio") != NULL);
+	has_video = (g_strrstr (name, "video") != NULL);
+
+	priv->info->has_audio |= has_audio;
+	priv->info->has_video |= has_video;
+
+	if (has_audio && !priv->audio_linked) {
+		brasero_metadata_create_audio_pipeline (self);
+		sink = gst_element_get_static_pad (priv->audio, "sink");
+		if (sink && !GST_PAD_IS_LINKED (sink)) {
+			res = gst_pad_link (pad, sink);
+			BRASERO_BURN_LOG ("Audio stream link %i for %s", res, priv->info->uri);
+			gst_object_unref (sink);
 
-		name = gst_structure_get_name (structure);
-		priv->info->has_audio = (g_strrstr (name, "audio") != NULL);
-		priv->info->has_video = (g_strrstr (name, "video") != NULL);
+			priv->audio_linked = (res == GST_PAD_LINK_OK);
+			gst_element_set_state (priv->audio, BRASERO_METADATA_INITIAL_STATE);
+		}
+	}
+
+	if (g_strrstr (name, "video/x-raw-") && !priv->video_linked) {
+		if (priv->flags & BRASERO_METADATA_FLAG_SNAPHOT) {
+			brasero_metadata_create_video_pipeline (self);
+			sink = gst_element_get_static_pad (priv->video, "sink");
+			if (!sink || GST_PAD_IS_LINKED (sink)) {
+				gst_object_unref (sink);
+				gst_caps_unref (caps);
+				return;
+			}
 
-		if (priv->info->has_audio || priv->info->has_video)
 			res = gst_pad_link (pad, sink);
+			priv->video_linked = (res == GST_PAD_LINK_OK);
+			gst_object_unref (sink);
+
+			gst_element_set_state (priv->video, BRASERO_METADATA_INITIAL_STATE);
+
+			BRASERO_BURN_LOG ("Video stream link %i for %s", res, priv->info->uri);
+		}
 	}
 
-	gst_object_unref (sink);
 	gst_caps_unref (caps);
 }
 
@@ -940,6 +1154,7 @@
 					   "Can't create audioconvert");
 		return FALSE;
 	}
+	gst_object_ref (priv->convert);
 
 	priv->level = gst_element_factory_make ("level", NULL);
 	if (!priv->level) {
@@ -948,6 +1163,7 @@
 					   "Can't create level");
 		return FALSE;
 	}
+	gst_object_ref (priv->level);
 	g_object_set (priv->level,
 		      "message", TRUE,
 		      "interval", (guint64) BRASERO_METADATA_SILENCE_INTERVAL,
@@ -960,7 +1176,7 @@
 					   "Can't create fake sink");
 		return FALSE;
 	}
-	gst_bin_add (GST_BIN (priv->pipeline), priv->sink);
+	gst_object_ref (priv->sink);
 
 	return TRUE;
 }
@@ -974,6 +1190,8 @@
 
 	priv = BRASERO_METADATA_PRIVATE (self);
 
+	BRASERO_BURN_LOG ("New retrieval for %s", uri);
+
 	brasero_metadata_info_free (priv->info);
 	priv->info = NULL;
 
@@ -996,6 +1214,17 @@
 			gst_bin_remove (GST_BIN (priv->pipeline), priv->source);
 			priv->source = NULL;
 		}
+
+		if (priv->audio) {
+			gst_bin_remove (GST_BIN (priv->pipeline), priv->audio);
+			priv->audio = NULL;
+		}
+
+		if (priv->video) {
+			gst_bin_remove (GST_BIN (priv->pipeline), priv->video);
+			priv->snapshot = NULL;
+			priv->video = NULL;
+		}
 	}
 	else if (!brasero_metadata_create_pipeline (self))
 		return FALSE;
@@ -1003,36 +1232,9 @@
 	if (!gst_uri_is_valid (uri))
 		return FALSE;
 
-	/* set up the pipeline according to flags */
-	if (priv->flags & BRASERO_METADATA_FLAG_SILENCES) {
-		priv->prev_level_mes = 0;
-		if (priv->first != priv->convert) {
-			gst_bin_add_many (GST_BIN (priv->pipeline),
-					  priv->convert,
-					  priv->level,
-					  NULL);
-			gst_element_link_many (priv->convert,
-					       priv->level,
-					       priv->sink,
-					       NULL);
-
-			priv->first = priv->convert;
-		}
-	}
-	else {
-		if (priv->first == priv->convert) {
-			gst_object_ref (priv->convert);
-			gst_object_ref (priv->level);
-
-			gst_bin_remove_many (GST_BIN (priv->pipeline),
-					     priv->convert,
-					     priv->level,
-					     NULL);
-		}
-
-		if (priv->first != priv->sink)
-			priv->first = priv->sink;
-	}
+	priv->video_linked = 0;
+	priv->audio_linked = 0;
+	priv->snapshot_started = 0;
 
 	/* create a necessary source */
 	priv->source = gst_element_make_from_uri (GST_URI_SRC,
@@ -1113,7 +1315,7 @@
 	}
 
 	priv->started = 1;
-	gst_element_set_state (GST_ELEMENT (priv->pipeline), GST_STATE_PLAYING);
+	gst_element_set_state (GST_ELEMENT (priv->pipeline), BRASERO_METADATA_INITIAL_STATE);
 	g_cond_wait (priv->cond, priv->mutex);
 	g_mutex_unlock (priv->mutex);
 
@@ -1159,7 +1361,7 @@
 	}
 
 	priv->started = 1;
-	gst_element_set_state (GST_ELEMENT (priv->pipeline), GST_STATE_PLAYING);
+	gst_element_set_state (GST_ELEMENT (priv->pipeline), BRASERO_METADATA_INITIAL_STATE);
 
 	/* run the loop until it's finished */
 	priv->loop = g_main_loop_new (NULL, FALSE);
@@ -1211,7 +1413,7 @@
 	}
 
 	priv->started = 1;
-	gst_element_set_state (GST_ELEMENT (priv->pipeline), GST_STATE_PLAYING);
+	gst_element_set_state (GST_ELEMENT (priv->pipeline), BRASERO_METADATA_INITIAL_STATE);
 
 	return TRUE;
 }
@@ -1252,6 +1454,11 @@
 	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;
 
@@ -1336,16 +1543,34 @@
 	if (change == GST_STATE_CHANGE_FAILURE)
 		g_warning ("State change failure\n");
 
+	if (priv->audio) {
+		gst_bin_remove (GST_BIN (priv->pipeline), priv->audio);
+		priv->audio = NULL;
+	}
+
+	if (priv->video) {
+		gst_bin_remove (GST_BIN (priv->pipeline), priv->video);
+		priv->snapshot = NULL;
+		priv->video = NULL;
+	}
+
 	gst_object_unref (GST_OBJECT (priv->pipeline));
 	priv->pipeline = NULL;
 
-	if (priv->first == priv->sink) {
-		gst_object_unref (GST_OBJECT (priv->convert));
-		priv->convert = NULL;
-
+	if (priv->level) {
 		gst_object_unref (GST_OBJECT (priv->level));
 		priv->level = NULL;
 	}
+
+	if (priv->sink) {
+		gst_object_unref (GST_OBJECT (priv->sink));
+		priv->sink = NULL;
+	}
+
+	if (priv->convert) {
+		gst_object_unref (GST_OBJECT (priv->convert));
+		priv->convert = NULL;
+	}
 }
 
 static void

Modified: branches/video/src/brasero-metadata.h
==============================================================================
--- branches/video/src/brasero-metadata.h	(original)
+++ branches/video/src/brasero-metadata.h	Sun Jun  8 18:18:01 2008
@@ -29,6 +29,8 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
+#include <gdk/gdkpixbuf.h>
+
 #include <gst/gst.h>
 
 G_BEGIN_DECLS
@@ -37,7 +39,8 @@
 	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_MISSING			= 1 << 2,
+	BRASERO_METADATA_FLAG_SNAPHOT			= 1 << 3
 } BraseroMetadataFlag;
 
 #define BRASERO_TYPE_METADATA         (brasero_metadata_get_type ())
@@ -66,6 +69,8 @@
 
 	GSList *silences;
 
+	GdkPixbuf *snapshot;
+
 	gboolean is_seekable;
 	gboolean has_audio;
 	gboolean has_video;

Modified: branches/video/src/brasero-project-manager.c
==============================================================================
--- branches/video/src/brasero-project-manager.c	(original)
+++ branches/video/src/brasero-project-manager.c	Sun Jun  8 18:18:01 2008
@@ -86,6 +86,8 @@
 static void
 brasero_project_manager_new_data_prj_cb (GtkAction *action, BraseroProjectManager *manager);
 static void
+brasero_project_manager_new_video_prj_cb (GtkAction *action, BraseroProjectManager *manager);
+static void
 brasero_project_manager_new_copy_prj_cb (GtkAction *action, BraseroProjectManager *manager);
 static void
 brasero_project_manager_new_iso_prj_cb (GtkAction *action, BraseroProjectManager *manager);
@@ -115,6 +117,8 @@
 	 N_("Create a new audio project"), G_CALLBACK (brasero_project_manager_new_audio_prj_cb)},
 	{"NewData", "media-optical-data-new", N_("New _Data Project"), NULL,
 	 N_("Create a new data project"), G_CALLBACK (brasero_project_manager_new_data_prj_cb)},
+	{"NewVideo", "media-optical-video-new", N_("New _Video Project"), NULL,
+	 N_("Create a new video project"), G_CALLBACK (brasero_project_manager_new_video_prj_cb)},
 	{"NewCopy", "media-optical-copy", N_("Copy _Disc..."), NULL,
 	 N_("Copy a disc"), G_CALLBACK (brasero_project_manager_new_copy_prj_cb)},
 	{"NewIso", "iso-image-burn", N_("_Burn Image..."), NULL,
@@ -132,6 +136,7 @@
 				"<menu action='New'>"
 					"<menuitem action='NewAudio'/>"
 					"<menuitem action='NewData'/>"
+					"<menuitem action='NewVideo'/>"
 					"<menuitem action='NewCopy'/>"	
 					"<menuitem action='NewIso'/>"	
 				"</menu>"
@@ -516,7 +521,8 @@
 	GtkAction *action;
 
 	if ((manager->priv->type == BRASERO_PROJECT_TYPE_AUDIO
-	||   manager->priv->type == BRASERO_PROJECT_TYPE_DATA)
+	||   manager->priv->type == BRASERO_PROJECT_TYPE_DATA
+	||   manager->priv->type == BRASERO_PROJECT_TYPE_VIDEO)
 	&&  !brasero_project_confirm_switch (BRASERO_PROJECT (manager->priv->project)))
 		return;
 
@@ -566,6 +572,20 @@
 		if (toplevel)
 			gtk_window_set_title (GTK_WINDOW (toplevel), _("Brasero - New data disc project"));
 	}
+	else if (type == BRASERO_PROJECT_TYPE_VIDEO) {
+		brasero_layout_load (BRASERO_LAYOUT (manager->priv->layout), BRASERO_LAYOUT_VIDEO);
+
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (manager), 1);
+		gtk_action_set_sensitive (action, TRUE);
+
+		if (reset) {
+			/* tell the BraseroProject object that we want a data selection */
+			brasero_project_set_video (BRASERO_PROJECT (manager->priv->project), uris);
+		}
+
+		if (toplevel)
+			gtk_window_set_title (GTK_WINDOW (toplevel), _("Brasero - New Video disc project"));
+	}
 	else if (type == BRASERO_PROJECT_TYPE_ISO) {
 		brasero_layout_load (BRASERO_LAYOUT (manager->priv->layout), BRASERO_LAYOUT_NONE);
 		brasero_project_set_none (BRASERO_PROJECT (manager->priv->project));
@@ -618,6 +638,12 @@
 }
 
 static void
+brasero_project_manager_new_video_prj_cb (GtkAction *action, BraseroProjectManager *manager)
+{
+	brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_VIDEO, NULL, NULL, TRUE);
+}
+
+static void
 brasero_project_manager_new_copy_prj_cb (GtkAction *action, BraseroProjectManager *manager)
 {
 	brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_COPY, NULL, NULL, TRUE);
@@ -650,6 +676,16 @@
 }
 
 void
+brasero_project_manager_video (BraseroProjectManager *manager, GSList *uris)
+{
+	brasero_project_manager_switch (manager,
+					BRASERO_PROJECT_TYPE_VIDEO,
+					uris,
+					NULL,
+					TRUE);
+}
+
+void
 brasero_project_manager_copy (BraseroProjectManager *manager)
 {
 	brasero_project_manager_switch (manager, BRASERO_PROJECT_TYPE_COPY, NULL, NULL, TRUE);
@@ -951,7 +987,7 @@
 				   _("Browse the file system"),
 				   _("Display file browser"),
 				   GTK_STOCK_DIRECTORY,
-				   BRASERO_LAYOUT_AUDIO|BRASERO_LAYOUT_DATA);
+				   BRASERO_LAYOUT_AUDIO|BRASERO_LAYOUT_DATA|BRASERO_LAYOUT_VIDEO);
 
 #ifdef BUILD_PREVIEW
 	brasero_preview_add_source (BRASERO_PREVIEW (preview),
@@ -975,7 +1011,7 @@
 				   _("Search files using keywords"),
 				   _("Display search"),
 				   GTK_STOCK_FIND,
-				   BRASERO_LAYOUT_AUDIO|BRASERO_LAYOUT_DATA);
+				   BRASERO_LAYOUT_AUDIO|BRASERO_LAYOUT_DATA|BRASERO_LAYOUT_VIDEO);
 
 #ifdef BUILD_PREVIEW
 	brasero_preview_add_source (BRASERO_PREVIEW (preview),

Modified: branches/video/src/brasero-project-manager.h
==============================================================================
--- branches/video/src/brasero-project-manager.h	(original)
+++ branches/video/src/brasero-project-manager.h	Sun Jun  8 18:18:01 2008
@@ -61,6 +61,8 @@
 void
 brasero_project_manager_data (BraseroProjectManager *manager, GSList *uris);
 void
+brasero_project_manager_video (BraseroProjectManager *manager, GSList *uris);
+void
 brasero_project_manager_copy (BraseroProjectManager *manager);
 void
 brasero_project_manager_iso (BraseroProjectManager *manager, const gchar *uri);

Modified: branches/video/src/brasero-project-type-chooser.c
==============================================================================
--- branches/video/src/brasero-project-type-chooser.c	(original)
+++ branches/video/src/brasero-project-type-chooser.c	Sun Jun  8 18:18:01 2008
@@ -79,6 +79,11 @@
 	N_("Create a CD/DVD containing any type of data that can only be read on a computer"),
 	"media-optical-data-new",
 	BRASERO_PROJECT_TYPE_DATA},
+       {N_("<big>_Video project</big>"),
+	N_("Create a video DVD or a SVCD"),
+	N_("Create a video DVD or a SVCD that are readable on TV readers"),
+	"media-optical-copy",
+	BRASERO_PROJECT_TYPE_VIDEO},
        {N_("<big>Disc _copy</big>"),
 	N_("Create 1:1 copy of a CD/DVD"),
 	N_("Create a 1:1 copy of an audio CD or a data CD/DVD on your hardisk or on another CD/DVD"),

Modified: branches/video/src/brasero-project-type-chooser.h
==============================================================================
--- branches/video/src/brasero-project-type-chooser.h	(original)
+++ branches/video/src/brasero-project-type-chooser.h	Sun Jun  8 18:18:01 2008
@@ -31,6 +31,7 @@
 #include <gtk/gtkeventbox.h>
 
 G_BEGIN_DECLS
+
 #define BRASERO_TYPE_PROJECT_TYPE_CHOOSER         (brasero_project_type_chooser_get_type ())
 #define BRASERO_PROJECT_TYPE_CHOOSER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), BRASERO_TYPE_PROJECT_TYPE_CHOOSER, BraseroProjectTypeChooser))
 #define BRASERO_PROJECT_TYPE_CHOOSER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k),BRASERO_TYPE_PROJECT_TYPE_CHOOSER, BraseroProjectTypeChooserClass))
@@ -51,6 +52,7 @@
 	BRASERO_PROJECT_TYPE_ISO,
 	BRASERO_PROJECT_TYPE_AUDIO,
 	BRASERO_PROJECT_TYPE_DATA,
+	BRASERO_PROJECT_TYPE_VIDEO
 } BraseroProjectType;
 
 typedef struct {

Modified: branches/video/src/brasero-project.c
==============================================================================
--- branches/video/src/brasero-project.c	(original)
+++ branches/video/src/brasero-project.c	Sun Jun  8 18:18:01 2008
@@ -71,6 +71,7 @@
 #include "brasero-disc.h"
 #include "brasero-data-disc.h"
 #include "brasero-audio-disc.h"
+#include "brasero-video-disc.h"
 #include "brasero-disc-option-dialog.h"
 #include "brasero-burn-dialog.h"
 #include "brasero-utils.h"
@@ -157,6 +158,7 @@
 	GtkWidget *discs;
 	GtkWidget *audio;
 	GtkWidget *data;
+	GtkWidget *video;
 
 	GtkWidget *message;
 
@@ -438,7 +440,7 @@
 	gtk_container_add (GTK_CONTAINER (alignment), obj->priv->burn);
 	gtk_box_pack_end (GTK_BOX (box), alignment, FALSE, FALSE, 0);
 
-	/* The two panes to put into the notebook */
+	/* The three panes to put into the notebook */
 	obj->priv->audio = brasero_audio_disc_new ();
 	gtk_widget_show (obj->priv->audio);
 	g_signal_connect (G_OBJECT (obj->priv->audio),
@@ -474,10 +476,28 @@
 			  G_CALLBACK (brasero_project_selection_changed_cb),
 			  obj);
 
+	obj->priv->video = brasero_video_disc_new ();
+	gtk_widget_show (obj->priv->video);
+	g_signal_connect (G_OBJECT (obj->priv->video),
+			  "contents-changed",
+			  G_CALLBACK (brasero_project_contents_changed_cb),
+			  obj);
+	g_signal_connect (G_OBJECT (obj->priv->video),
+			  "size-changed",
+			  G_CALLBACK (brasero_project_size_changed_cb),
+			  obj);
+	g_signal_connect (G_OBJECT (obj->priv->video),
+			  "selection-changed",
+			  G_CALLBACK (brasero_project_selection_changed_cb),
+			  obj);
+
 	obj->priv->discs = gtk_notebook_new ();
 	gtk_widget_show (obj->priv->discs);
 	gtk_notebook_set_show_border (GTK_NOTEBOOK (obj->priv->discs), FALSE);
 	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (obj->priv->discs), FALSE);
+
+	gtk_notebook_prepend_page (GTK_NOTEBOOK (obj->priv->discs),
+				   obj->priv->video, NULL);
 	gtk_notebook_prepend_page (GTK_NOTEBOOK (obj->priv->discs),
 				   obj->priv->data, NULL);
 	gtk_notebook_prepend_page (GTK_NOTEBOOK (obj->priv->discs),
@@ -1069,7 +1089,7 @@
 
 /********************************     ******************************************/
 static void
-brasero_project_switch (BraseroProject *project, gboolean audio)
+brasero_project_switch (BraseroProject *project, BraseroProjectType type)
 {
 	GtkAction *action;
 	GConfClient *client;
@@ -1100,7 +1120,7 @@
 		gtk_ui_manager_remove_ui (project->priv->manager,
 					  project->priv->merge_id);
 
-	if (audio) {
+	if (type == BRASERO_PROJECT_TYPE_AUDIO) {
 		project->priv->current = BRASERO_DISC (project->priv->audio);
 		project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
 							       project->priv->manager,
@@ -1109,7 +1129,7 @@
 		gtk_notebook_set_current_page (GTK_NOTEBOOK (project->priv->discs), 0);
 		brasero_project_size_set_context (BRASERO_PROJECT_SIZE (project->priv->size_display), TRUE);
 	}
-	else {
+	else if (type == BRASERO_PROJECT_TYPE_DATA) {
 		project->priv->current = BRASERO_DISC (project->priv->data);
 		project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
 							       project->priv->manager,
@@ -1118,6 +1138,15 @@
 		gtk_notebook_set_current_page (GTK_NOTEBOOK (project->priv->discs), 1);
 		brasero_project_size_set_context (BRASERO_PROJECT_SIZE (project->priv->size_display), FALSE);
 	}
+	else if (type == BRASERO_PROJECT_TYPE_VIDEO) {
+		project->priv->current = BRASERO_DISC (project->priv->video);
+		project->priv->merge_id = brasero_disc_add_ui (project->priv->current,
+							       project->priv->manager,
+							       project->priv->message);
+
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (project->priv->discs), 2);
+		brasero_project_size_set_context (BRASERO_PROJECT_SIZE (project->priv->size_display), TRUE);
+	}
 
 	brasero_notify_message_remove (BRASERO_NOTIFY (project->priv->message), BRASERO_NOTIFY_CONTEXT_SIZE);
 
@@ -1140,7 +1169,7 @@
 void
 brasero_project_set_audio (BraseroProject *project, GSList *uris)
 {
-	brasero_project_switch (project, TRUE);
+	brasero_project_switch (project, BRASERO_PROJECT_TYPE_AUDIO);
 
 	for (; uris; uris = uris->next) {
 		gchar *uri;
@@ -1153,7 +1182,20 @@
 void
 brasero_project_set_data (BraseroProject *project, GSList *uris)
 {
-	brasero_project_switch (project, FALSE);
+	brasero_project_switch (project, BRASERO_PROJECT_TYPE_DATA);
+
+	for (; uris; uris = uris->next) {
+		gchar *uri;
+
+	    	uri = uris->data;
+		brasero_disc_add_uri (project->priv->current, uri);
+	}
+}
+
+void
+brasero_project_set_video (BraseroProject *project, GSList *uris)
+{
+	brasero_project_switch (project, BRASERO_PROJECT_TYPE_VIDEO);
 
 	for (; uris; uris = uris->next) {
 		gchar *uri;

Modified: branches/video/src/brasero-project.h
==============================================================================
--- branches/video/src/brasero-project.h	(original)
+++ branches/video/src/brasero-project.h	Sun Jun  8 18:18:01 2008
@@ -70,6 +70,8 @@
 void
 brasero_project_set_data (BraseroProject *project, GSList *uris);
 void
+brasero_project_set_video (BraseroProject *project, GSList *uris);
+void
 brasero_project_set_none (BraseroProject *project);
 
 void

Added: branches/video/src/brasero-video-disc.c
==============================================================================
--- (empty file)
+++ branches/video/src/brasero-video-disc.c	Sun Jun  8 18:18:01 2008
@@ -0,0 +1,920 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero
+ * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
+ * 
+ * brasero is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * brasero is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+
+#include <gtk/gtk.h>
+
+#include "brasero-disc.h"
+#include "brasero-io.h"
+#include "brasero-utils.h"
+#include "brasero-video-disc.h"
+
+typedef struct _BraseroVideoDiscPrivate BraseroVideoDiscPrivate;
+struct _BraseroVideoDiscPrivate
+{
+	GtkWidget *notebook;
+	GtkWidget *tree;
+
+	GtkWidget *message;
+	GtkUIManager *manager;
+	GtkActionGroup *disc_group;
+
+	BraseroIO *io;
+	BraseroIOJobBase *add_uri;
+
+	gint64 sectors;
+
+	guint activity;
+
+	guint reject_files:1;
+	guint loading:1;
+};
+
+#define BRASERO_VIDEO_DISC_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_VIDEO_DISC, BraseroVideoDiscPrivate))
+
+static void
+brasero_video_disc_iface_disc_init (BraseroDiscIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (BraseroVideoDisc,
+			 brasero_video_disc,
+			 GTK_TYPE_VBOX,
+			 G_IMPLEMENT_INTERFACE (BRASERO_TYPE_DISC,
+					        brasero_video_disc_iface_disc_init));
+
+enum {
+	NAME_COL,
+	URI_COL,
+	ICON_COL,
+	SIZE_COL,
+	START_COL,
+	END_COL,
+	EDITABLE_COL,
+	NUM_COL
+};
+
+enum {
+	PROP_NONE,
+	PROP_REJECT_FILE,
+};
+
+
+static void
+brasero_video_disc_increase_activity_counter (BraseroVideoDisc *self)
+{
+	GdkCursor *cursor;
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (self);
+
+	if (priv->activity == 0 && GTK_WIDGET (self)->window) {
+		cursor = gdk_cursor_new (GDK_WATCH);
+		gdk_window_set_cursor (GTK_WIDGET (self)->window, cursor);
+		gdk_cursor_unref (cursor);
+	}
+
+	priv->activity++;
+}
+
+static void
+brasero_video_disc_decrease_activity_counter (BraseroVideoDisc *self)
+{
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (self);
+
+	if (priv->activity == 1 && GTK_WIDGET (self)->window)
+		gdk_window_set_cursor (GTK_WIDGET (self)->window, NULL);
+
+	priv->activity--;
+}
+
+static void
+brasero_video_disc_io_operation_finished (GObject *object,
+					  gboolean cancelled,
+					  gpointer null_data)
+{
+	BraseroVideoDisc *self = BRASERO_VIDEO_DISC (object);
+
+	brasero_video_disc_decrease_activity_counter (self);
+}
+
+static void
+brasero_video_disc_unreadable_dialog (BraseroVideoDisc *self,
+				      const gchar *uri,
+				      GError *error)
+{
+	GtkWidget *dialog, *toplevel;
+	gchar *name;
+
+	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
+	if (toplevel == NULL) {
+		g_warning ("Can't open file %s : %s\n",
+			   uri,
+			   error->message);
+		return;
+	}
+
+	name = g_filename_display_basename (uri);
+	dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
+					 GTK_DIALOG_DESTROY_WITH_PARENT|
+					 GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_ERROR,
+					 GTK_BUTTONS_CLOSE,
+					 _("File \"%s\" can't be opened."),
+					 name);
+	g_free (name);
+
+	gtk_window_set_title (GTK_WINDOW (dialog), _("Unreadable file"));
+
+	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+						  error->message);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+}
+
+static void
+brasero_video_disc_file_not_video_dialog (BraseroVideoDisc *self,
+					  const gchar *uri)
+{
+	GtkWidget *dialog, *toplevel;
+	gchar *name;
+
+	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
+	if (toplevel == NULL) {
+		g_warning ("Content widget error : can't handle \"%s\".\n", uri);
+		return ;
+	}
+
+    	BRASERO_GET_BASENAME_FOR_DISPLAY (uri, name);
+	dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
+					 GTK_DIALOG_DESTROY_WITH_PARENT|
+					 GTK_DIALOG_MODAL,
+					 GTK_MESSAGE_ERROR,
+					 GTK_BUTTONS_CLOSE,
+					 _("\"%s\" does not have a suitable type for video projects."),
+					 name);
+	g_free (name);
+
+	gtk_window_set_title (GTK_WINDOW (dialog), _("Unhandled file"));
+
+	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+						  _("Please only add files with video contents."));
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+}
+
+static void
+brasero_video_disc_new_row_cb (GObject *obj,
+			       GError *error,
+			       const gchar *uri,
+			       GFileInfo *info,
+			       gpointer user_data)
+{
+	gint64 len;
+	gchar *size_str;
+	GtkTreeIter iter;
+	const gchar *title;
+	GdkPixbuf *snapshot;
+	GtkTreeModel *model;
+	GtkTreePath *treepath;
+	GtkTreeRowReference *ref = user_data;
+	BraseroVideoDisc *self = BRASERO_VIDEO_DISC (obj);
+	BraseroVideoDiscPrivate *priv = BRASERO_VIDEO_DISC_PRIVATE (self);
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
+	treepath = gtk_tree_row_reference_get_path (ref);
+	gtk_tree_row_reference_free (ref);
+	if (!treepath)
+		return;
+
+	gtk_tree_model_get_iter (model, &iter, treepath);
+	gtk_tree_path_free (treepath);
+
+	if (error) {
+		brasero_video_disc_unreadable_dialog (self, uri, error);
+		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+		return;
+	}
+
+	if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
+//		brasero_video_disc_add_dir (self, uri);
+		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+		return;
+	}
+
+	if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR
+	|| !g_file_info_get_attribute_boolean (info, BRASERO_IO_HAS_VIDEO)) {
+		brasero_video_disc_file_not_video_dialog (self, uri);
+		gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+		return;
+	}
+
+	if (g_file_info_get_is_symlink (info)) {
+		uri = g_strconcat ("file://", g_file_info_get_symlink_target (info), NULL);
+		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+				    URI_COL, uri, -1);
+	}
+
+	/* set the snapshot */
+	snapshot = GDK_PIXBUF (g_file_info_get_attribute_object (info, BRASERO_IO_SNAPSHOT));
+	if (snapshot) {
+		GdkPixbuf *scaled;
+
+		scaled = gdk_pixbuf_scale_simple (snapshot,
+						  96 * gdk_pixbuf_get_width (snapshot) / gdk_pixbuf_get_height (snapshot),
+						  96,
+						  GDK_INTERP_BILINEAR);
+		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+				    ICON_COL, scaled,
+				    -1);
+		g_object_unref (scaled);
+	}
+
+	/* */
+	len = g_file_info_get_attribute_uint64 (info, BRASERO_IO_LEN);
+	size_str = brasero_utils_get_time_string (len, TRUE, FALSE);
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+			    END_COL, len,
+			    SIZE_COL, size_str,
+			    -1);
+	g_free (size_str);
+
+	/* */
+	title = g_file_info_get_attribute_string (info, BRASERO_IO_TITLE);
+	if (title)
+		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+				    NAME_COL, title,
+				    -1);
+
+	/* FIXME: duration to sectors is not correct here, that's not audio... */
+	priv->sectors += BRASERO_DURATION_TO_SECTORS (len);
+	brasero_disc_size_changed (BRASERO_DISC (self), priv->sectors);
+}
+
+static BraseroDiscResult
+brasero_video_disc_add_uri_real (BraseroVideoDisc *self,
+				 const gchar *uri,
+				 gint pos,
+				 gint64 start,
+				 gint64 end,
+				 GtkTreePath **path_return)
+{
+	BraseroVideoDiscPrivate *priv;
+	GtkTreeRowReference *ref;
+	GtkTreePath *treepath;
+	GtkTreeModel *store;
+	GtkTreeIter iter;
+	gchar *markup;
+	gchar *name;
+
+	g_return_val_if_fail (uri != NULL, BRASERO_DISC_ERROR_UNKNOWN);
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (self);
+	if (priv->reject_files)
+		return BRASERO_DISC_NOT_READY;
+
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 1);
+
+	store = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
+	if (pos > -1)
+		gtk_list_store_insert (GTK_LIST_STORE (store), &iter, pos);
+	else
+		gtk_list_store_append (GTK_LIST_STORE (store), &iter);
+
+	BRASERO_GET_BASENAME_FOR_DISPLAY (uri, name);
+	markup = g_markup_escape_text (name, -1);
+	g_free (name);
+
+    	gtk_list_store_set (GTK_LIST_STORE (store), &iter,
+			    NAME_COL, markup,
+			    URI_COL, uri,
+			    -1);
+	g_free (markup);
+
+	/* set size message */
+	start = start > 0 ? start:0;
+	if (end > 0 && end > start) {
+		gchar *string;
+		gint64 length;
+
+		/* update global size */
+		length = BRASERO_AUDIO_TRACK_LENGTH (start, end);
+		priv->sectors += BRASERO_DURATION_TO_SECTORS (length);
+		brasero_disc_size_changed (BRASERO_DISC (self), priv->sectors);
+
+		string = brasero_utils_get_time_string (length, TRUE, FALSE);
+		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
+				    START_COL, start,
+				    END_COL, end,
+				    SIZE_COL, string,
+				    -1);
+		g_free (string);
+	}
+	else
+		gtk_list_store_set (GTK_LIST_STORE (store), &iter,
+				    SIZE_COL, _("loading"),
+				    -1);
+
+	/* Now load */
+	treepath = gtk_tree_model_get_path (store, &iter);
+	ref = gtk_tree_row_reference_new (store, treepath);
+
+	if (path_return)
+		*path_return = treepath;
+	else
+		gtk_tree_path_free (treepath);
+
+	/* get info async for the file */
+	if (!priv->io)
+		priv->io = brasero_io_get_default ();
+
+	if (!priv->add_uri)
+		priv->add_uri = brasero_io_register (G_OBJECT (self),
+						     brasero_video_disc_new_row_cb,
+						     brasero_video_disc_io_operation_finished,
+						     NULL);
+
+	brasero_video_disc_increase_activity_counter (self);
+	brasero_io_get_file_info (priv->io,
+				  uri,
+				  priv->add_uri,
+				  BRASERO_IO_INFO_PERM|
+				  BRASERO_IO_INFO_MIME|
+				  BRASERO_IO_INFO_METADATA|
+				  BRASERO_IO_INFO_METADATA_MISSING_CODEC|
+				  BRASERO_IO_INFO_METADATA_SNAPSHOT,
+				  ref);
+
+	return BRASERO_DISC_OK;
+}
+
+static BraseroDiscResult
+brasero_video_disc_add_uri (BraseroDisc *self,
+			    const gchar *uri)
+{
+	BraseroVideoDiscPrivate *priv;
+	GtkTreePath *treepath = NULL;
+	BraseroDiscResult result;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (self);
+	result = brasero_video_disc_add_uri_real (BRASERO_VIDEO_DISC (self),
+						  uri,
+						  -1,
+						  -1,
+						  -1,
+						  &treepath);
+
+	if (treepath) {
+		gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->tree),
+					      treepath,
+					      NULL,
+					      TRUE,
+					      0.5,
+					      0.5);
+		gtk_tree_path_free (treepath);
+	}
+
+	return result;
+}
+
+static void
+brasero_video_disc_delete_selected (BraseroDisc *self)
+{
+	BraseroVideoDiscPrivate *priv;
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GList *selected;
+	GList *iter;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (self);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree));
+
+	selected = gtk_tree_selection_get_selected_rows (selection, &model);
+	selected = g_list_reverse (selected);
+	for (iter = selected; iter; iter = iter->next) {
+		GtkTreePath *treepath;
+		GtkTreeIter tree_iter;
+		gint64 start;
+		gint64 end;
+
+		treepath = iter->data;
+
+		gtk_tree_model_get_iter (model, &tree_iter, treepath);
+		gtk_tree_model_get (model, &tree_iter,
+				    START_COL, &start,
+				    END_COL, &end,
+				    -1);
+		priv->sectors -= BRASERO_DURATION_TO_SECTORS (end - start);
+
+		gtk_list_store_remove (GTK_LIST_STORE (model), &tree_iter);
+		gtk_tree_path_free (treepath);
+	}
+	g_list_free (selected);
+
+	brasero_disc_size_changed (BRASERO_DISC (self), priv->sectors);
+}
+
+static gboolean
+brasero_video_disc_get_selected_uri (BraseroDisc *self,
+				     gchar **uri)
+{
+	GList *selected;
+	GtkTreeModel *model;
+	GtkTreeSelection *selection;
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (self);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree));
+	selected = gtk_tree_selection_get_selected_rows (selection, &model);
+	if (!selected)
+		return FALSE;
+
+	if (uri) {
+		GtkTreeIter iter;
+		GtkTreePath *treepath;
+
+		treepath = selected->data;
+		gtk_tree_model_get_iter (model, &iter, treepath);
+		gtk_tree_model_get (model, &iter,
+				    URI_COL, uri,
+				    -1);
+	}
+
+	g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (selected);
+
+	return TRUE;
+}
+
+static void
+brasero_video_disc_selection_changed_cb (GtkTreeSelection *selection,
+					 BraseroVideoDisc *self)
+{
+	brasero_disc_selection_changed (BRASERO_DISC (self));
+}
+
+static guint
+brasero_video_disc_add_ui (BraseroDisc *disc,
+			   GtkUIManager *manager,
+			   GtkWidget *message)
+{
+	BraseroVideoDiscPrivate *priv;
+//	GError *error = NULL;
+//	GtkAction *action;
+	guint merge_id;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (disc);
+
+	if (priv->message) {
+		g_object_unref (priv->message);
+		priv->message = NULL;
+	}
+
+	priv->message = message;
+	g_object_ref (message);
+
+	if (!priv->disc_group) {
+		priv->disc_group = gtk_action_group_new (BRASERO_DISC_ACTION);
+		gtk_action_group_set_translation_domain (priv->disc_group, GETTEXT_PACKAGE);
+/*		gtk_action_group_add_actions (priv->disc_group,
+					      entries,
+					      G_N_ELEMENTS (entries),
+					      disc);
+		gtk_action_group_add_toggle_actions (priv->disc_group,
+						     toggle_entries,
+						     G_N_ELEMENTS (toggle_entries),
+						     disc);
+		gtk_ui_manager_insert_action_group (manager,
+						    priv->disc_group,
+						    0);
+*/	}
+
+/*	merge_id = gtk_ui_manager_add_ui_from_string (manager,
+						      description,
+						      -1,
+						      &error);
+	if (!merge_id) {
+		BRASERO_BURN_LOG ("Adding ui elements failed: %s", error->message);
+		g_error_free (error);
+		return 0;
+	}
+
+	action = gtk_action_group_get_action (priv->disc_group, "ImportSession");
+	gtk_action_set_sensitive (action, FALSE);
+	g_object_set (action,
+		      "short-label", _("Import"),
+		      NULL);
+*/
+
+	priv->manager = manager;
+	g_object_ref (manager);
+	return merge_id;
+}
+
+static void
+brasero_video_disc_row_deleted_cb (GtkTreeModel *model,
+				   GtkTreePath *path,
+				   BraseroVideoDisc *self)
+{
+	brasero_disc_contents_changed (BRASERO_DISC (self),
+				       gtk_tree_model_iter_n_children (model, NULL));
+}
+
+static void
+brasero_video_disc_row_inserted_cb (GtkTreeModel *model,
+				    GtkTreePath *path,
+				    GtkTreeIter *iter,
+				    BraseroVideoDisc *self)
+{
+	brasero_disc_contents_changed (BRASERO_DISC (self),
+				       gtk_tree_model_iter_n_children (model, NULL));
+}
+
+static void
+brasero_video_disc_row_changed_cb (GtkTreeModel *model,
+				   GtkTreePath *path,
+				   GtkTreeIter *iter,
+				   BraseroVideoDisc *self)
+{
+	brasero_disc_contents_changed (BRASERO_DISC (self),
+				       gtk_tree_model_iter_n_children (model, NULL));
+}
+
+static void
+brasero_video_disc_init (BraseroVideoDisc *object)
+{
+	BraseroVideoDiscPrivate *priv;
+	GtkTreeSelection *selection;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+	GtkTreeModel *model;
+	GtkWidget *mainbox;
+	GtkWidget *scroll;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (object);
+
+	/* the information displayed about how to use this tree */
+	priv->notebook = brasero_disc_get_use_info_notebook ();
+	gtk_widget_show (priv->notebook);
+	gtk_box_pack_start (GTK_BOX (object), priv->notebook, TRUE, TRUE, 0);
+
+	mainbox = gtk_vbox_new (FALSE, 12);
+	gtk_widget_show (mainbox);
+	gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), mainbox, NULL);
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 0);
+
+	/* Tree */
+	model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COL,
+						    G_TYPE_STRING,
+						    G_TYPE_STRING,
+						    GDK_TYPE_PIXBUF,
+						    G_TYPE_STRING,
+						    G_TYPE_INT64,
+						    G_TYPE_INT64,
+						    G_TYPE_BOOLEAN));
+	g_signal_connect (G_OBJECT (model),
+			  "row-deleted",
+			  G_CALLBACK (brasero_video_disc_row_deleted_cb),
+			  object);
+	g_signal_connect (G_OBJECT (model),
+			  "row-inserted",
+			  G_CALLBACK (brasero_video_disc_row_inserted_cb),
+			  object);
+	g_signal_connect (G_OBJECT (model),
+			  "row-changed",
+			  G_CALLBACK (brasero_video_disc_row_changed_cb),
+			  object);
+
+	priv->tree = gtk_tree_view_new_with_model (model);
+	g_object_unref (G_OBJECT (model));
+	gtk_widget_show (priv->tree);
+
+	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (priv->tree), TRUE);
+	gtk_tree_view_set_rubber_banding (GTK_TREE_VIEW (priv->tree), TRUE);
+
+	/* columns */
+	column = gtk_tree_view_column_new ();
+	gtk_tree_view_column_set_resizable (column, TRUE);
+	gtk_tree_view_column_set_min_width (column, 200);
+
+	renderer = gtk_cell_renderer_pixbuf_new ();
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_add_attribute (column, renderer,
+					    "pixbuf", ICON_COL);
+
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (G_OBJECT (renderer),
+		      "mode", GTK_CELL_RENDERER_MODE_EDITABLE,
+		      "ellipsize-set", TRUE,
+		      "ellipsize", PANGO_ELLIPSIZE_END,
+		      NULL);
+
+	gtk_tree_view_column_pack_end (column, renderer, TRUE);
+	gtk_tree_view_column_add_attribute (column, renderer,
+					    "markup", NAME_COL);
+	gtk_tree_view_column_add_attribute (column, renderer,
+					    "editable", EDITABLE_COL);
+	gtk_tree_view_column_set_title (column, _("Title"));
+	g_object_set (G_OBJECT (column),
+		      "expand", TRUE,
+		      "spacing", 4,
+		      NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree),
+				     column);
+
+	gtk_tree_view_set_expander_column (GTK_TREE_VIEW (priv->tree),
+					   column);
+
+
+	renderer = gtk_cell_renderer_text_new ();
+	column = gtk_tree_view_column_new ();
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+
+	gtk_tree_view_column_add_attribute (column, renderer,
+					    "text", SIZE_COL);
+	gtk_tree_view_column_set_title (column, _("Size"));
+
+	gtk_tree_view_append_column (GTK_TREE_VIEW (priv->tree), column);
+	gtk_tree_view_column_set_resizable (column, TRUE);
+	gtk_tree_view_column_set_expand (column, FALSE);
+	gtk_tree_view_column_set_sort_column_id (column, NAME_COL);
+
+	/* selection */
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->tree));
+	gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+	g_signal_connect (selection,
+			  "changed",
+			  G_CALLBACK (brasero_video_disc_selection_changed_cb),
+			  object);
+
+	/* scroll */
+	scroll = gtk_scrolled_window_new (NULL, NULL);
+	gtk_widget_show (scroll);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
+					     GTK_SHADOW_IN);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+					GTK_POLICY_AUTOMATIC,
+					GTK_POLICY_AUTOMATIC);
+	gtk_container_add (GTK_CONTAINER (scroll), priv->tree);
+	gtk_box_pack_start (GTK_BOX (mainbox), scroll, TRUE, TRUE, 0);
+}
+
+static void
+brasero_video_disc_reset_real (BraseroVideoDisc *self)
+{
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (self);
+
+	if (priv->io)
+		brasero_io_cancel_by_base (priv->io, priv->add_uri);
+
+	priv->sectors = 0;
+
+	priv->activity = 1;
+	brasero_video_disc_decrease_activity_counter (self);
+}
+
+static void
+brasero_video_disc_clear (BraseroDisc *disc)
+{
+	BraseroVideoDiscPrivate *priv;
+	GtkTreeModel *model;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (disc);
+
+	brasero_video_disc_reset_real (BRASERO_VIDEO_DISC (disc));
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
+	gtk_list_store_clear (GTK_LIST_STORE (model));
+
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), 0);
+	brasero_disc_size_changed (disc, 0);
+}
+
+static void
+brasero_video_disc_reset (BraseroDisc *disc)
+{
+	brasero_video_disc_clear (disc);
+}
+
+static void
+brasero_video_disc_finalize (GObject *object)
+{
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (object);
+	
+	brasero_video_disc_reset_real (BRASERO_VIDEO_DISC (object));
+	
+	if (priv->io) {
+		brasero_io_cancel_by_base (priv->io, priv->add_uri);
+		g_free (priv->add_uri);
+		priv->add_uri = NULL;
+
+		g_object_unref (priv->io);
+		priv->io = NULL;
+	}
+
+	G_OBJECT_CLASS (brasero_video_disc_parent_class)->finalize (object);
+}
+
+static void
+brasero_video_disc_get_property (GObject * object,
+				 guint prop_id,
+				 GValue * value,
+				 GParamSpec * pspec)
+{
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_REJECT_FILE:
+		g_value_set_boolean (value, priv->reject_files);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+brasero_video_disc_set_property (GObject * object,
+				 guint prop_id,
+				 const GValue * value,
+				 GParamSpec * pspec)
+{
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_REJECT_FILE:
+		priv->reject_files = g_value_get_boolean (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static BraseroDiscResult
+brasero_video_disc_get_status (BraseroDisc *disc)
+{
+	GtkTreeModel *model;
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (disc);
+
+	if (priv->loading)
+		return BRASERO_DISC_LOADING;
+
+	if (priv->activity)
+		return BRASERO_DISC_NOT_READY;
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
+	if (!gtk_tree_model_iter_n_children (model, NULL))
+		return BRASERO_DISC_ERROR_EMPTY_SELECTION;
+
+	return BRASERO_DISC_OK;
+}
+
+static BraseroDiscResult
+brasero_video_disc_set_session_param (BraseroDisc *disc,
+				      BraseroBurnSession *session)
+{
+	BraseroTrackType type;
+
+	type.type = BRASERO_TRACK_TYPE_AUDIO;
+	type.subtype.audio_format = BRASERO_AUDIO_FORMAT_UNDEFINED|BRASERO_VIDEO_FORMAT_UNDEFINED;
+	brasero_burn_session_set_input_type (session, &type);
+	return BRASERO_BURN_OK;
+}
+
+static BraseroDiscResult
+brasero_video_disc_set_session_contents (BraseroDisc *disc,
+					 BraseroBurnSession *session)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	BraseroTrack *track;
+	BraseroVideoDiscPrivate *priv;
+
+	priv = BRASERO_VIDEO_DISC_PRIVATE (disc);
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->tree));
+	if (!gtk_tree_model_get_iter_first (model, &iter))
+		return BRASERO_DISC_ERROR_EMPTY_SELECTION;
+
+	track = NULL;
+	do {
+		gchar *uri;
+		gint64 end;
+		gint64 start;
+		gchar *title;
+		BraseroSongInfo *info;
+
+		gtk_tree_model_get (model, &iter,
+				    URI_COL, &uri,
+				    NAME_COL, &title,
+				    START_COL, &start,
+				    END_COL, &end,
+				    -1);
+
+		info = g_new0 (BraseroSongInfo, 1);
+		info->title = title;
+
+		track = brasero_track_new (BRASERO_TRACK_TYPE_AUDIO);
+		brasero_track_set_audio_source (track,
+						uri,
+						BRASERO_AUDIO_FORMAT_UNDEFINED|
+						BRASERO_VIDEO_FORMAT_UNDEFINED);
+
+		brasero_track_set_audio_boundaries (track, start, end, -1);
+		brasero_track_set_audio_info (track, info);
+		brasero_burn_session_add_track (session, track);
+
+		/* It's good practice to unref the track afterwards as we don't
+		 * need it anymore. BraseroBurnSession refs it. */
+		brasero_track_unref (track);
+
+	} while (gtk_tree_model_iter_next (model, &iter));
+
+	return BRASERO_DISC_OK;
+}
+
+static void
+brasero_video_disc_iface_disc_init (BraseroDiscIface *iface)
+{
+	iface->add_uri = brasero_video_disc_add_uri;
+	iface->delete_selected = brasero_video_disc_delete_selected;
+	iface->clear = brasero_video_disc_clear;
+	iface->reset = brasero_video_disc_reset;
+
+	iface->get_status = brasero_video_disc_get_status;
+	iface->set_session_param = brasero_video_disc_set_session_param;
+	iface->set_session_contents = brasero_video_disc_set_session_contents;
+
+/*
+	iface->get_track = brasero_data_disc_get_track;
+	iface->load_track = brasero_data_disc_load_track;
+*/
+	iface->get_selected_uri = brasero_video_disc_get_selected_uri;
+	iface->add_ui = brasero_video_disc_add_ui;
+}
+
+static void
+brasero_video_disc_class_init (BraseroVideoDiscClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (BraseroVideoDiscPrivate));
+
+	object_class->finalize = brasero_video_disc_finalize;
+	object_class->set_property = brasero_video_disc_set_property;
+	object_class->get_property = brasero_video_disc_get_property;
+
+	g_object_class_install_property (object_class,
+					 PROP_REJECT_FILE,
+					 g_param_spec_boolean
+					 ("reject-file",
+					  "Whether it accepts files",
+					  "Whether it accepts files",
+					  FALSE,
+					  G_PARAM_READWRITE));
+}
+
+GtkWidget *
+brasero_video_disc_new (void)
+{
+	return g_object_new (BRASERO_TYPE_VIDEO_DISC, NULL);
+}
+

Added: branches/video/src/brasero-video-disc.h
==============================================================================
--- (empty file)
+++ branches/video/src/brasero-video-disc.h	Sun Jun  8 18:18:01 2008
@@ -0,0 +1,56 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero
+ * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
+ * 
+ * brasero is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * brasero is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BRASERO_VIDEO_DISC_H_
+#define _BRASERO_VIDEO_DISC_H_
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define BRASERO_TYPE_VIDEO_DISC             (brasero_video_disc_get_type ())
+#define BRASERO_VIDEO_DISC(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), BRASERO_TYPE_VIDEO_DISC, BraseroVideoDisc))
+#define BRASERO_VIDEO_DISC_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), BRASERO_TYPE_VIDEO_DISC, BraseroVideoDiscClass))
+#define BRASERO_IS_VIDEO_DISC(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BRASERO_TYPE_VIDEO_DISC))
+#define BRASERO_IS_VIDEO_DISC_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), BRASERO_TYPE_VIDEO_DISC))
+#define BRASERO_VIDEO_DISC_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), BRASERO_TYPE_VIDEO_DISC, BraseroVideoDiscClass))
+
+typedef struct _BraseroVideoDiscClass BraseroVideoDiscClass;
+typedef struct _BraseroVideoDisc BraseroVideoDisc;
+
+struct _BraseroVideoDiscClass
+{
+	GtkVBoxClass parent_class;
+};
+
+struct _BraseroVideoDisc
+{
+	GtkVBox parent_instance;
+};
+
+GType brasero_video_disc_get_type (void) G_GNUC_CONST;
+
+GtkWidget *
+brasero_video_disc_new (void);
+
+G_END_DECLS
+
+#endif /* _BRASERO_VIDEO_DISC_H_ */

Modified: branches/video/src/burn-basics.h
==============================================================================
--- branches/video/src/burn-basics.h	(original)
+++ branches/video/src/burn-basics.h	Sun Jun  8 18:18:01 2008
@@ -180,6 +180,12 @@
 void
 brasero_burn_library_shutdown (void);
 
+/**
+ * Some defined and usable tags for a session
+ */
+
+#define BRASERO_AUDIO_VIDEO_OUTPUT_FORMAT	"audio-video-format"
+
 G_END_DECLS
 
 #endif /* _BURN_BASICS_H */

Modified: branches/video/src/burn-caps.c
==============================================================================
--- branches/video/src/burn-caps.c	(original)
+++ branches/video/src/burn-caps.c	Sun Jun  8 18:18:01 2008
@@ -2089,7 +2089,6 @@
 						   flags,
 						   supported,
 						   compulsory);
-
 		if (io_flags == BRASERO_PLUGIN_IO_NONE)
 			continue;
 
@@ -3365,7 +3364,8 @@
 
 		caps = iter->data;
 		if (caps->type.type != BRASERO_TRACK_TYPE_IMAGE
-		&&  caps->type.type != BRASERO_TRACK_TYPE_AUDIO)
+		&&  caps->type.type != BRASERO_TRACK_TYPE_AUDIO
+		&&  caps->type.type != BRASERO_TRACK_TYPE_DATA)
 			continue;
 
 		destination = caps->type.type;

Modified: branches/video/src/burn-debug.c
==============================================================================
--- branches/video/src/burn-debug.c	(original)
+++ branches/video/src/burn-debug.c	Sun Jun  8 18:18:01 2008
@@ -265,10 +265,22 @@
 		strcat (buffer, "RAW ");
 
 	if (format & BRASERO_AUDIO_FORMAT_UNDEFINED)
-		strcat (buffer, "UNDEFINED ");
+		strcat (buffer, "AUDIO UNDEFINED ");
 
 	if (format & BRASERO_AUDIO_FORMAT_4_CHANNEL)
 		strcat (buffer, "4 CHANNELS ");
+
+	if (format & BRASERO_AUDIO_FORMAT_MP2)
+		strcat (buffer, "MP2 ");
+
+	if (format & BRASERO_AUDIO_FORMAT_AC3)
+		strcat (buffer, "AC3 ");
+
+	if (format & BRASERO_VIDEO_FORMAT_UNDEFINED)
+		strcat (buffer, "VIDEO UNDEFINED ");
+
+	if (format & BRASERO_VIDEO_FORMAT_MPEG2)
+		strcat (buffer, "MPEG2 ");
 }
 
 void

Modified: branches/video/src/burn-job.c
==============================================================================
--- branches/video/src/burn-job.c	(original)
+++ branches/video/src/burn-job.c	Sun Jun  8 18:18:01 2008
@@ -608,8 +608,7 @@
 		}
 	}
 	else
-		BRASERO_JOB_LOG (self, "linked to %s",
-				 G_OBJECT_TYPE_NAME (priv->linked));
+		BRASERO_JOB_LOG (self, "linked to %s", G_OBJECT_TYPE_NAME (priv->linked));
 
 	if (!brasero_job_is_first_active (self)) {
 		int fd [2];
@@ -1648,8 +1647,7 @@
 {
 	BraseroJobPrivate *priv;
 
-	BRASERO_JOB_DEBUG (self);
-
+	BRASERO_JOB_LOG (self, "Called brasero_job_set_progress (%lf)", progress);
 	priv = BRASERO_JOB_PRIVATE (self);
 	if (priv->next)
 		return BRASERO_BURN_ERR;

Modified: branches/video/src/burn-process.c
==============================================================================
--- branches/video/src/burn-process.c	(original)
+++ branches/video/src/burn-process.c	Sun Jun  8 18:18:01 2008
@@ -285,11 +285,13 @@
 		g_free (uri);
 	}
 
-	brasero_job_add_track (BRASERO_JOB (self), track);
+	if (track) {
+		brasero_job_add_track (BRASERO_JOB (self), track);
 
-	/* It's good practice to unref the track afterwards as we don't need it
-	 * anymore. BraseroTaskCtx refs it. */
-	brasero_track_unref (track);
+		/* It's good practice to unref the track afterwards as we don't
+		 * need it anymore. BraseroTaskCtx refs it. */
+		brasero_track_unref (track);
+	}
 
 	klass->post (BRASERO_JOB (self));
 	return BRASERO_BURN_OK;

Modified: branches/video/src/burn-track.h
==============================================================================
--- branches/video/src/burn-track.h	(original)
+++ branches/video/src/burn-track.h	Sun Jun  8 18:18:01 2008
@@ -63,7 +63,11 @@
 	BRASERO_AUDIO_FORMAT_NONE		= 0,
 	BRASERO_AUDIO_FORMAT_UNDEFINED		= 1,
 	BRASERO_AUDIO_FORMAT_4_CHANNEL		= 1 << 1,
-	BRASERO_AUDIO_FORMAT_RAW		= 1 << 2
+	BRASERO_AUDIO_FORMAT_RAW		= 1 << 2,
+	BRASERO_AUDIO_FORMAT_AC3		= 1 << 3,
+	BRASERO_AUDIO_FORMAT_MP2		= 1 << 4,
+	BRASERO_VIDEO_FORMAT_UNDEFINED		= 1 << 5,
+	BRASERO_VIDEO_FORMAT_MPEG2		= 1 << 6
 } BraseroAudioFormat;
 
 typedef enum {

Modified: branches/video/src/plugins/Makefile.am
==============================================================================
--- branches/video/src/plugins/Makefile.am	(original)
+++ branches/video/src/plugins/Makefile.am	Sun Jun  8 18:18:01 2008
@@ -1,4 +1,4 @@
-SUBDIRS = cdrdao transcode dvdcss growisofs checksum local-track
+SUBDIRS = cdrdao gstreamer dvdcss growisofs checksum local-track dvdauthor
 
 if BUILD_LIBBURNIA
 SUBDIRS += libburnia

Modified: branches/video/src/plugins/cdrdao/burn-toc2cue.c
==============================================================================
--- branches/video/src/plugins/cdrdao/burn-toc2cue.c	(original)
+++ branches/video/src/plugins/cdrdao/burn-toc2cue.c	Sun Jun  8 18:18:01 2008
@@ -263,7 +263,7 @@
 		priv->output = NULL;
 	}
 
-	return BRASERO_BURN_OK;
+	return brasero_job_finished_session (job);
 }
 
 static void

Added: branches/video/src/plugins/dvdauthor/Makefile.am
==============================================================================
--- (empty file)
+++ branches/video/src/plugins/dvdauthor/Makefile.am	Sun Jun  8 18:18:01 2008
@@ -0,0 +1,24 @@
+DISABLE_DEPRECATED = -DG_DISABLE_DEPRECATED
+
+INCLUDES = \
+	-I$(top_srcdir)					\
+	-I$(top_builddir)				\
+	-I$(top_srcdir)/src				\
+	-DBRASERO_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" 	\
+	-DBRASERO_PREFIX=\"$(prefix)\"           		\
+	-DBRASERO_SYSCONFDIR=\"$(sysconfdir)\"   		\
+	-DBRASERO_DATADIR=\"$(datadir)/brasero\"     	    	\
+	-DBRASERO_LIBDIR=\"$(libdir)\"  	         	\
+	$(DISABLE_DEPRECATED)				\
+	$(BRASERO_BASE_CFLAGS)				\
+	$(BRASERO_LIBXML_CFLAGS)
+
+AM_CFLAGS = -g
+
+dvdauthordir = $(libdir)/brasero/plugins
+dvdauthor_LTLIBRARIES = libbrasero-dvdauthor.la
+
+libbrasero_dvdauthor_la_SOURCES = burn-dvdauthor.c burn-dvdauthor.h burn-normalize.h
+libbrasero_dvdauthor_la_LIBADD = $(BRASERO_BASE_LIBS) $(BRASERO_LIBXML_LIBS)
+libbrasero_dvdauthor_la_LDFLAGS = -module -avoid-version
+

Added: branches/video/src/plugins/dvdauthor/burn-dvdauthor.c
==============================================================================
--- (empty file)
+++ branches/video/src/plugins/dvdauthor/burn-dvdauthor.c	Sun Jun  8 18:18:01 2008
@@ -0,0 +1,389 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * burn-dvdauthor.c
+ * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
+ * 
+ * burn-dvdauthor.c is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ * 
+ * burn-dvdauthor.c is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with burn-dvdauthor.c.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
+#include <gmodule.h>
+
+#include <libxml/xmlerror.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/parser.h>
+#include <libxml/xmlstring.h>
+#include <libxml/uri.h>
+
+#include "burn-basics.h"
+#include "burn-plugin.h"
+#include "burn-job.h"
+#include "burn-process.h"
+#include "burn-dvdauthor.h"
+
+BRASERO_PLUGIN_BOILERPLATE (BraseroDvdAuthor, brasero_dvd_author, BRASERO_TYPE_PROCESS, BraseroProcess);
+
+typedef struct _BraseroDvdAuthorPrivate BraseroDvdAuthorPrivate;
+struct _BraseroDvdAuthorPrivate
+{
+	gchar *output;
+};
+
+#define BRASERO_DVD_AUTHOR_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_DVD_AUTHOR, BraseroDvdAuthorPrivate))
+
+static BraseroProcessClass *parent_class = NULL;
+
+static BraseroBurnResult
+brasero_dvd_author_add_track (BraseroJob *job)
+{
+	gchar *path;
+	BraseroTrack *track;
+	GSList *grafts = NULL;
+	BraseroGraftPt *graft;
+	BraseroDvdAuthorPrivate *priv;
+
+	priv = BRASERO_DVD_AUTHOR_PRIVATE (job);
+
+	/* create the track */
+	track = brasero_track_new (BRASERO_TRACK_TYPE_DATA);
+
+	/* audio */
+	graft = g_new (BraseroGraftPt, 1);
+	path = g_build_path (G_DIR_SEPARATOR_S,
+			     priv->output,
+			     "AUDIO_TS",
+			     NULL);
+	graft->uri = g_filename_to_uri (path, NULL, NULL);
+	g_free (path);
+
+	graft->path = g_strdup ("/AUDIO_TS");
+	grafts = g_slist_prepend (grafts, graft);
+
+	BRASERO_JOB_LOG (job, "Adding graft point for %s", graft->uri);
+
+	/* video */
+	graft = g_new (BraseroGraftPt, 1);
+	path = g_build_path (G_DIR_SEPARATOR_S,
+			     priv->output,
+			     "VIDEO_TS",
+			     NULL);
+	graft->uri = g_filename_to_uri (path, NULL, NULL);
+	g_free (path);
+
+	graft->path = g_strdup ("/VIDEO_TS");
+	grafts = g_slist_prepend (grafts, graft);
+
+	BRASERO_JOB_LOG (job, "Adding graft point for %s", graft->uri);
+
+	brasero_track_add_data_fs (track,
+				   BRASERO_IMAGE_FS_ISO|
+				   BRASERO_IMAGE_FS_UDF|
+				   BRASERO_IMAGE_FS_VIDEO);
+	brasero_track_set_data_source (track,
+				       grafts,
+				       NULL);
+	brasero_job_add_track (job, track);
+	brasero_track_unref (track);
+
+	return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_dvd_author_read_stdout (BraseroProcess *process,
+				const gchar *line)
+{
+	return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_dvd_author_read_stderr (BraseroProcess *process,
+				const gchar *line)
+{
+	if (!strstr (line, ""))
+		return BRASERO_BURN_OK;
+
+	return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_dvd_author_generate_xml_file (BraseroProcess *process,
+				      const gchar *path,
+				      GError **error)
+{
+	BraseroDvdAuthorPrivate *priv;
+	BraseroBurnResult result;
+	GSList *tracks = NULL;
+	xmlTextWriter *xml;
+	gint success;
+	GSList *iter;
+
+	BRASERO_JOB_LOG (process, "Creating DVD layout xml file(%s)", path);
+
+	xml = xmlNewTextWriterFilename (path, 0);
+	if (!xml)
+		return BRASERO_BURN_ERR;
+
+	priv = BRASERO_DVD_AUTHOR_PRIVATE (process);
+
+	xmlTextWriterSetIndent (xml, 1);
+	xmlTextWriterSetIndentString (xml, (xmlChar *) "\t");
+
+	success = xmlTextWriterStartDocument (xml,
+					      NULL,
+					      "UTF8",
+					      NULL);
+	if (success < 0)
+		goto error;
+
+	result = brasero_job_get_tmp_dir (BRASERO_JOB (process),
+					  &priv->output,
+					  error);
+	if (result != BRASERO_BURN_OK)
+		return result;
+
+	/* let's start */
+	success = xmlTextWriterStartElement (xml, (xmlChar *) "dvdauthor");
+	if (success < 0)
+		goto error;
+
+	success = xmlTextWriterWriteAttribute (xml,
+					       (xmlChar *) "dest",
+					       (xmlChar *) priv->output);
+	if (success < 0)
+		goto error;
+
+	/* This is needed to finalize */
+	success = xmlTextWriterWriteElement (xml, (xmlChar *) "vmgm", (xmlChar *) "");
+	if (success < 0)
+		goto error;
+
+	/* the tracks */
+	success = xmlTextWriterStartElement (xml, (xmlChar *) "titleset");
+	if (success < 0)
+		goto error;
+
+	success = xmlTextWriterStartElement (xml, (xmlChar *) "titles");
+	if (success < 0)
+		goto error;
+
+	/* get all tracks */
+	brasero_job_get_tracks (BRASERO_JOB (process), &tracks);
+	for (iter = tracks; iter; iter = iter->next) {
+		BraseroTrack *track;
+		gchar *video;
+
+		track = iter->data;
+		success = xmlTextWriterStartElement (xml, (xmlChar *) "pgc");
+		if (success < 0)
+			goto error;
+
+		success = xmlTextWriterStartElement (xml, (xmlChar *) "vob");
+		if (success < 0)
+			goto error;
+
+		video = brasero_track_get_audio_source (track, FALSE);
+		success = xmlTextWriterWriteAttribute (xml,
+						       (xmlChar *) "file",
+						       (xmlChar *) video);
+		g_free (video);
+
+		if (success < 0)
+			goto error;
+
+		/* vob */
+		success = xmlTextWriterEndElement (xml);
+		if (success < 0)
+			goto error;
+
+		/* pgc */
+		success = xmlTextWriterEndElement (xml);
+		if (success < 0)
+			goto error;
+	}
+
+	/* titles */
+	success = xmlTextWriterEndElement (xml);
+	if (success < 0)
+		goto error;
+
+	/* titleset */
+	success = xmlTextWriterEndElement (xml);
+	if (success < 0)
+		goto error;
+
+	/* close dvdauthor */
+	success = xmlTextWriterEndElement (xml);
+	if (success < 0)
+		goto error;
+
+	xmlTextWriterEndDocument (xml);
+	xmlFreeTextWriter (xml);
+
+	return BRASERO_BURN_OK;
+
+error:
+
+	BRASERO_JOB_LOG (process, "Error");
+
+	/* close everything */
+	xmlTextWriterEndDocument (xml);
+	xmlFreeTextWriter (xml);
+
+	/* FIXME: get the error */
+
+	return BRASERO_BURN_ERR;
+}
+
+static BraseroBurnResult
+brasero_dvd_author_set_argv (BraseroProcess *process,
+			     GPtrArray *argv,
+			     GError **error)
+{
+	BraseroDvdAuthorPrivate *priv;
+	BraseroBurnResult result;
+	BraseroJobAction action;
+	gchar *output;
+
+	priv = BRASERO_DVD_AUTHOR_PRIVATE (process);
+
+	brasero_job_get_action (BRASERO_JOB (process), &action);
+	if (action != BRASERO_JOB_ACTION_IMAGE)
+		BRASERO_JOB_NOT_SUPPORTED (process);
+
+	g_ptr_array_add (argv, g_strdup ("dvdauthor"));
+	
+	/* get all arguments to write XML file */
+	result = brasero_job_get_tmp_file (BRASERO_JOB (process),
+					   NULL,
+					   &output,
+					   error);
+	if (result != BRASERO_BURN_OK)
+		return result;
+
+	g_ptr_array_add (argv, g_strdup ("-x"));
+	g_ptr_array_add (argv, output);
+
+	result = brasero_dvd_author_generate_xml_file (process, output, error);
+	if (result != BRASERO_BURN_OK)
+		return result;
+
+	brasero_job_set_current_action (BRASERO_JOB (process),
+					BRASERO_BURN_ACTION_CREATING_IMAGE,
+					_("Creating file layout"),
+					FALSE);
+	return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_dvd_author_post (BraseroJob *job)
+{
+	BraseroDvdAuthorPrivate *priv;
+
+	priv = BRASERO_DVD_AUTHOR_PRIVATE (job);
+
+	brasero_dvd_author_add_track (job);
+
+	if (priv->output) {
+		g_free (priv->output);
+		priv->output = NULL;
+	}
+
+	return brasero_job_finished_session (job);
+}
+
+static void
+brasero_dvd_author_init (BraseroDvdAuthor *object)
+{}
+
+static void
+brasero_dvd_author_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+brasero_dvd_author_class_init (BraseroDvdAuthorClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	BraseroProcessClass* process_class = BRASERO_PROCESS_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (BraseroDvdAuthorPrivate));
+
+	object_class->finalize = brasero_dvd_author_finalize;
+
+	process_class->stdout_func = brasero_dvd_author_read_stdout;
+	process_class->stderr_func = brasero_dvd_author_read_stderr;
+	process_class->set_argv = brasero_dvd_author_set_argv;
+	process_class->post = brasero_dvd_author_post;
+}
+
+static BraseroBurnResult
+brasero_dvd_author_export_caps (BraseroPlugin *plugin, gchar **error)
+{
+	BraseroBurnResult result;
+	GSList *output;
+	GSList *input;
+
+	/* NOTE: it seems that cdrecord can burn cue files on the fly */
+	brasero_plugin_define (plugin,
+			       "dvdauthor",
+			       _("use dvdauthor to convert a set of files to burn to Video DVDs"),
+			       "Philippe Rouquier",
+			       1);
+
+	/* First see if this plugin can be used */
+	result = brasero_process_check_path ("dvdauthor", error);
+	if (result != BRASERO_BURN_OK)
+		return result;
+
+	input = brasero_caps_audio_new (BRASERO_PLUGIN_IO_ACCEPT_FILE,
+					BRASERO_AUDIO_FORMAT_AC3|
+					BRASERO_AUDIO_FORMAT_MP2|
+					BRASERO_AUDIO_FORMAT_RAW|
+					BRASERO_VIDEO_FORMAT_MPEG2);
+	output = brasero_caps_data_new (BRASERO_IMAGE_FS_ISO|
+					BRASERO_IMAGE_FS_UDF|
+					BRASERO_IMAGE_FS_VIDEO);
+
+	brasero_plugin_link_caps (plugin, output, input);
+	g_slist_free (output);
+	g_slist_free (input);
+
+	/* we only support DVDs */
+	brasero_plugin_set_flags (plugin,
+				  BRASERO_MEDIUM_DVDR|
+				  BRASERO_MEDIUM_DVDRW|
+				  BRASERO_MEDIUM_DVDRW_RESTRICTED|
+				  BRASERO_MEDIUM_DVDR_PLUS|
+				  BRASERO_MEDIUM_DVDRW_PLUS|
+				  BRASERO_MEDIUM_DVD_DL,
+				  BRASERO_BURN_FLAG_NONE,
+				  BRASERO_BURN_FLAG_NONE);
+
+	return BRASERO_BURN_OK;
+}

Added: branches/video/src/plugins/dvdauthor/burn-dvdauthor.h
==============================================================================
--- (empty file)
+++ branches/video/src/plugins/dvdauthor/burn-dvdauthor.h	Sun Jun  8 18:18:01 2008
@@ -0,0 +1,41 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * burn-dvdauthor.c
+ * Copyright (C) Philippe Rouquier 2008 <bonfire-app wanadoo fr>
+ * 
+ * burn-dvdauthor.c is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ * 
+ * burn-dvdauthor.c is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with burn-dvdauthor.c.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _BRASERO_DVD_AUTHOR_H_
+#define _BRASERO_DVD_AUTHOR_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define BRASERO_TYPE_DVD_AUTHOR             (brasero_dvd_author_get_type ())
+#define BRASERO_DVD_AUTHOR(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), BRASERO_TYPE_DVD_AUTHOR, BraseroDvdAuthor))
+#define BRASERO_DVD_AUTHOR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), BRASERO_TYPE_DVD_AUTHOR, BraseroDvdAuthorClass))
+#define BRASERO_IS_DVD_AUTHOR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BRASERO_TYPE_DVD_AUTHOR))
+#define BRASERO_IS_DVD_AUTHOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), BRASERO_TYPE_DVD_AUTHOR))
+#define BRASERO_DVD_AUTHOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), BRASERO_TYPE_DVD_AUTHOR, BraseroDvdAuthorClass))
+
+G_END_DECLS
+
+#endif /* _BRASERO_DVD_AUTHOR_H_ */

Modified: branches/video/src/plugins/gstreamer/Makefile.am
==============================================================================
--- /trunk/src/plugins/transcode/Makefile.am	(original)
+++ branches/video/src/plugins/gstreamer/Makefile.am	Sun Jun  8 18:18:01 2008
@@ -28,3 +28,10 @@
 libbrasero_normalize_la_SOURCES = burn-normalize.c burn-normalize.h
 libbrasero_normalize_la_LIBADD = $(BRASERO_BASE_LIBS) $(BRASERO_GSTREAMER_CFLAGS)
 libbrasero_normalize_la_LDFLAGS = -module -avoid-version
+
+vobdir = $(libdir)/brasero/plugins
+vob_LTLIBRARIES = libbrasero-vob.la
+
+libbrasero_vob_la_SOURCES = burn-vob.c burn-vob.h
+libbrasero_vob_la_LIBADD = $(BRASERO_BASE_LIBS) $(BRASERO_GSTREAMER_CFLAGS)
+libbrasero_vob_la_LDFLAGS = -module -avoid-version

Added: branches/video/src/plugins/gstreamer/burn-vob.c
==============================================================================
--- (empty file)
+++ branches/video/src/plugins/gstreamer/burn-vob.c	Sun Jun  8 18:18:01 2008
@@ -0,0 +1,803 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero-vob.c
+ * Copyright (C) Rouquier Philippe 2008 <bonfire-app wanadoo fr>
+ * 
+ * brasero-vob.c is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ * 
+ * brasero-vob.c is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with brasero-vob.c.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+
+#include <gst/gst.h>
+
+#include "burn-basics.h"
+#include "burn-job.h"
+#include "burn-plugin.h"
+#include "burn-vob.h"
+
+BRASERO_PLUGIN_BOILERPLATE (BraseroVob, brasero_vob, BRASERO_TYPE_JOB, BraseroJob);
+
+typedef struct _BraseroVobPrivate BraseroVobPrivate;
+struct _BraseroVobPrivate
+{
+	GstElement *pipeline;
+
+	GstElement *audio;
+	GstElement *video;
+
+	BraseroAudioFormat format;
+};
+
+#define BRASERO_VOB_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_VOB, BraseroVobPrivate))
+
+static GObjectClass *parent_class = NULL;
+
+
+static void
+brasero_vob_stop_pipeline (BraseroVob *vob)
+{
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+	if (!priv->pipeline)
+		return;
+
+	gst_element_set_state (priv->pipeline, GST_STATE_NULL);
+	gst_object_unref (GST_OBJECT (priv->pipeline));
+	priv->pipeline = NULL;
+}
+
+static BraseroBurnResult
+brasero_vob_stop (BraseroJob *job,
+		  GError **error)
+{
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (job);
+
+	brasero_vob_stop_pipeline (BRASERO_VOB (job));
+	return BRASERO_BURN_OK;
+}
+
+static void
+brasero_vob_finished (BraseroVob *vob)
+{
+	BraseroVobPrivate *priv;
+	gchar *output = NULL;
+	BraseroTrack *track;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+
+	brasero_job_get_audio_output (BRASERO_JOB (vob), &output);
+
+	track = brasero_track_new (BRASERO_TRACK_TYPE_AUDIO);
+	brasero_track_set_audio_source (track,
+					output,
+					priv->format|
+					BRASERO_AUDIO_FORMAT_RAW|
+					BRASERO_VIDEO_FORMAT_MPEG2);
+
+	brasero_job_add_track (BRASERO_JOB (vob), track);
+	brasero_track_unref (track);
+	g_free (output);
+
+	brasero_job_finished_track (BRASERO_JOB (vob));
+}
+
+static gboolean
+brasero_vob_bus_messages (GstBus *bus,
+			  GstMessage *msg,
+			  BraseroVob *vob)
+{
+	BraseroVobPrivate *priv;
+	GError *error = NULL;
+	gchar *debug;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+	switch (GST_MESSAGE_TYPE (msg)) {
+	case GST_MESSAGE_TAG:
+		return TRUE;
+
+	case GST_MESSAGE_ERROR:
+		gst_message_parse_error (msg, &error, &debug);
+		BRASERO_JOB_LOG (vob, debug);
+		g_free (debug);
+
+	        brasero_job_error (BRASERO_JOB (vob), error);
+		return FALSE;
+
+	case GST_MESSAGE_EOS:
+		BRASERO_JOB_LOG (vob, "Transcoding finished");
+
+		/* add a new track and terminate */
+		brasero_vob_finished (vob);
+		return FALSE;
+
+	case GST_MESSAGE_STATE_CHANGED:
+		break;
+
+	default:
+		return TRUE;
+	}
+
+	return TRUE;
+}
+
+static void
+brasero_vob_new_decoded_pad_cb (GstElement *decode,
+				GstPad *pad,
+				gboolean arg2,
+				BraseroVob *vob)
+{
+	GstPad *sink;
+	GstCaps *caps;
+	GstStructure *structure;
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+
+	/* make sure we only have audio */
+	caps = gst_pad_get_caps (pad);
+	if (!caps)
+		return;
+
+	structure = gst_caps_get_structure (caps, 0);
+	if (structure) {
+		if (g_strrstr (gst_structure_get_name (structure), "video")) {
+			sink = gst_element_get_pad (priv->video, "sink");
+			gst_pad_link (pad, sink);
+			gst_object_unref (sink);
+
+			gst_element_set_state (priv->video, GST_STATE_PLAYING);
+		}
+
+		if (g_strrstr (gst_structure_get_name (structure), "audio")) {
+			sink = gst_element_get_pad (priv->audio, "sink");
+			gst_pad_link (pad, sink);
+			gst_object_unref (sink);
+
+			gst_element_set_state (priv->audio, GST_STATE_PLAYING);
+		}
+	}
+
+	gst_caps_unref (caps);
+}
+
+static gboolean
+brasero_vob_link_audio (BraseroVob *vob,
+			GstElement *start,
+			GstElement *end,
+			GstElement *tee,
+			GstElement *muxer)
+{
+	GstPad *srcpad;
+	GstPad *sinkpad;
+	GstPadLinkReturn res;
+
+	srcpad = gst_element_get_request_pad (tee, "src%d");
+	sinkpad = gst_element_get_static_pad (start, "sink");
+	res = gst_pad_link (srcpad, sinkpad);
+	gst_object_unref (sinkpad);
+	gst_object_unref (srcpad);
+
+	BRASERO_JOB_LOG (vob, "Linked audio bin to tee == %d", res);
+	if (res != GST_PAD_LINK_OK)
+		return FALSE;
+
+	sinkpad = gst_element_get_request_pad (muxer, "audio_%d");
+	srcpad = gst_element_get_static_pad (end, "src");
+	res = gst_pad_link (srcpad, sinkpad);
+	gst_object_unref (sinkpad);
+	gst_object_unref (srcpad);
+
+	BRASERO_JOB_LOG (vob, "Linked audio bin to muxer == %d", res);
+	if (res != GST_PAD_LINK_OK)
+		return FALSE;
+
+	return TRUE;
+}
+
+static gboolean
+brasero_vob_build_audio_pcm (BraseroVob *vob,
+			     GstElement *tee,
+			     GstElement *muxer,
+			     GError **error)
+{
+	GstElement *queue;
+	GstElement *convert;
+	GstElement *resample;
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+
+	/* queue */
+	queue = gst_element_factory_make ("queue", NULL);
+	if (queue == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("queue element can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), queue);
+	g_object_set (queue,
+		      "max-size-bytes", 0,
+		      "max-size-buffers", 0,
+		      "max-size-time", (gint64) 0,
+		      NULL);
+
+	/* audioresample */
+	resample = gst_element_factory_make ("audioresample", NULL);
+	if (resample == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("audioresample can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), resample);
+
+	/* audioconvert */
+	convert = gst_element_factory_make ("audioconvert", NULL);
+	if (convert == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("audioconvert can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), convert);
+
+	gst_element_link_many (queue, resample, convert, NULL);
+	brasero_vob_link_audio (vob, queue, convert, tee, muxer);
+
+	return TRUE;
+
+error:
+
+	return FALSE;
+}
+
+static gboolean
+brasero_vob_build_audio_mp2 (BraseroVob *vob,
+			     GstElement *tee,
+			     GstElement *muxer,
+			     GError **error)
+{
+	GstElement *queue;
+	GstElement *encode;
+	GstElement *convert;
+	GstElement *resample;
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+
+	/* queue */
+	queue = gst_element_factory_make ("queue", NULL);
+	if (queue == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("queue element can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), queue);
+	g_object_set (queue,
+		      "max-size-bytes", 0,
+		      "max-size-buffers", 0,
+		      "max-size-time", (gint64) 0,
+		      NULL);
+
+	/* audioconvert */
+	convert = gst_element_factory_make ("audioconvert", NULL);
+	if (convert == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("audioconvert can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), convert);
+
+	/* audioresample */
+	resample = gst_element_factory_make ("audioresample", NULL);
+	if (resample == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("audioresample can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), resample);
+
+	encode = gst_element_factory_make ("ffenc_mp2", NULL);
+	if (encode == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("ffenc_mp2 can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), encode);
+
+	gst_element_link_many (queue, convert, resample, encode, NULL);
+	brasero_vob_link_audio (vob, queue, encode, tee, muxer);
+
+	return TRUE;
+
+error:
+
+	return FALSE;
+}
+
+static gboolean
+brasero_vob_build_audio_ac3 (BraseroVob *vob,
+			     GstElement *tee,
+			     GstElement *muxer,
+			     GError **error)
+{
+	GstElement *queue;
+	GstElement *encode;
+	GstElement *convert;
+	GstElement *resample;
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+
+	/* queue */
+	queue = gst_element_factory_make ("queue", NULL);
+	if (queue == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("queue element can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), queue);
+	g_object_set (queue,
+		      "max-size-bytes", 0,
+		      "max-size-buffers", 0,
+		      "max-size-time", (gint64) 0,
+		      NULL);
+
+	/* audioconvert */
+	convert = gst_element_factory_make ("audioconvert", NULL);
+	if (convert == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("audioconvert can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), convert);
+
+	/* audioresample */
+	resample = gst_element_factory_make ("audioresample", NULL);
+	if (resample == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("audioresample can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), resample);
+
+	encode = gst_element_factory_make ("ffenc_ac3", NULL);
+	if (encode == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("ffenc_ac3 can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), encode);
+
+	gst_element_link_many (queue, convert, resample, encode, NULL);
+	brasero_vob_link_audio (vob, queue, encode, tee, muxer);
+
+	return TRUE;
+
+error:
+
+	return FALSE;
+}
+
+static GstElement *
+brasero_vob_build_audio_bins (BraseroVob *vob,
+			      GstElement *muxer,
+			      GError **error)
+{
+	GValue *value;
+	GstElement *tee;
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+
+	/* queue */
+	tee = gst_element_factory_make ("tee", NULL);
+	if (tee == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("tee element can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), tee);
+
+	/* PCM : always */
+	if (!brasero_vob_build_audio_pcm (vob, tee, muxer, error))
+		goto error;
+
+	/* Get output format */
+	value = NULL;
+	brasero_job_tag_lookup (BRASERO_JOB (vob),
+				BRASERO_AUDIO_VIDEO_OUTPUT_FORMAT,
+				&value);
+
+	if (value)
+		priv->format = g_value_get_int (value);
+	else
+		priv->format = BRASERO_AUDIO_FORMAT_NONE;
+
+	if (priv->format & BRASERO_AUDIO_FORMAT_AC3) {
+		/* AC3 : on demand */
+		if (!brasero_vob_build_audio_ac3 (vob, tee, muxer, error))
+			goto error;
+	}
+
+	if (priv->format & BRASERO_AUDIO_FORMAT_MP2) {
+		/* MP2 : on demand */
+		if (!brasero_vob_build_audio_mp2 (vob, tee, muxer, error))
+			goto error;
+	}
+
+	return tee;
+
+error:
+	return NULL;
+}
+
+static GstElement *
+brasero_vob_build_video_bin (BraseroVob *vob,
+			     GstElement *muxer,
+			     GError **error)
+{
+	GstPad *srcpad;
+	GstPad *sinkpad;
+	GstElement *queue;
+	GstElement *encode;
+	GstPadLinkReturn res;
+	GstElement *colorspace;
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+
+	queue = gst_element_factory_make ("queue", NULL);
+	if (queue == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("queue element can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), queue);
+	g_object_set (queue,
+		      "max-size-bytes", 0,
+		      "max-size-buffers", 0,
+		      "max-size-time", (gint64) 0,
+		      NULL);
+
+	colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
+	if (colorspace == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("ffmpegcolorspace can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), colorspace);
+
+	encode = gst_element_factory_make ("ffenc_mpeg2video", NULL);
+	if (encode == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("ffenc_mpeg2video can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (priv->pipeline), encode);
+
+	gst_element_link_many (queue, colorspace, encode, NULL);
+
+	srcpad = gst_element_get_static_pad (encode, "src");
+	sinkpad = gst_element_get_request_pad (muxer, "video_%d");
+	res = gst_pad_link (srcpad, sinkpad);
+	BRASERO_JOB_LOG (vob, "Linked video bin to muxer == %d", res)
+	gst_object_unref (sinkpad);
+	gst_object_unref (srcpad);
+
+	return queue;
+
+error:
+
+	return NULL;
+}
+
+static gboolean
+brasero_vob_build_pipeline (BraseroVob *vob,
+			    GError **error)
+{
+	gchar *uri;
+	GstBus *bus;
+	gchar *output;
+	GstElement *sink;
+	GstElement *muxer;
+	GstElement *source;
+	GstElement *decode;
+	BraseroTrack *track;
+	GstElement *pipeline;
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (vob);
+
+	BRASERO_JOB_LOG (vob, "Creating new pipeline");
+
+	pipeline = gst_pipeline_new (NULL);
+	priv->pipeline = pipeline;
+
+	/* source */
+	brasero_job_get_current_track (BRASERO_JOB (vob), &track);
+	uri = brasero_track_get_audio_source (track, TRUE);
+	source = gst_element_make_from_uri (GST_URI_SRC, uri, NULL);
+	if (source == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("source can't be created"));
+		return FALSE;
+	}
+	gst_bin_add (GST_BIN (pipeline), source);
+	g_object_set (source,
+		      "typefind", FALSE,
+		      NULL);
+
+	/* decode */
+	decode = gst_element_factory_make ("decodebin", NULL);
+	if (decode == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("decode can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (pipeline), decode);
+	gst_element_link_many (source, decode, NULL);
+
+	/* muxer: "mplex" */
+	muxer = gst_element_factory_make ("mplex", NULL);
+	if (muxer == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("ffmux_mpeg can't be created"));
+		goto error;
+	}
+	gst_bin_add (GST_BIN (pipeline), muxer);
+	g_object_set (muxer,
+		      "format", 8,
+		      NULL);
+
+	/* create sink */
+	output = NULL;
+	brasero_job_get_audio_output (BRASERO_JOB (vob), &output);
+	sink = gst_element_factory_make ("filesink", NULL);
+	if (sink == NULL) {
+		g_set_error (error,
+			     BRASERO_BURN_ERROR,
+			     BRASERO_BURN_ERROR_GENERAL,
+			     _("sink can't be created"));
+		return FALSE;
+	}
+	g_object_set (sink,
+		      "location", output,
+		      NULL);
+
+	gst_bin_add (GST_BIN (pipeline), sink);
+	gst_element_link (muxer, sink);
+
+	/* video encoding */
+	priv->video = brasero_vob_build_video_bin (vob, muxer, error);
+	if (!priv->video)
+		goto error;
+
+	/* audio encoding */
+	priv->audio = brasero_vob_build_audio_bins (vob, muxer, error);
+	if (!priv->audio)
+		goto error;
+
+	/* to be able to link everything */
+	g_signal_connect (G_OBJECT (decode),
+			  "new-decoded-pad",
+			  G_CALLBACK (brasero_vob_new_decoded_pad_cb),
+			  vob);
+
+	/* connect to the bus */	
+	bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
+	gst_bus_add_watch (bus,
+			   (GstBusFunc) brasero_vob_bus_messages,
+			   vob);
+	gst_object_unref (bus);
+
+	return TRUE;
+
+error:
+
+	if (error && (*error))
+		BRASERO_JOB_LOG (vob,
+				 "can't create object : %s \n",
+				 (*error)->message);
+
+	gst_object_unref (GST_OBJECT (pipeline));
+	return FALSE;
+}
+
+static BraseroBurnResult
+brasero_vob_start (BraseroJob *job,
+		   GError **error)
+{
+	BraseroVobPrivate *priv;
+	BraseroJobAction action;
+	BraseroTrack *track;
+
+	brasero_job_get_action (job, &action);
+	if (action != BRASERO_JOB_ACTION_IMAGE)
+		return BRASERO_BURN_NOT_SUPPORTED;
+
+	priv = BRASERO_VOB_PRIVATE (job);
+
+	/* get tracks */
+	brasero_job_get_current_track (job, &track);
+	if (!track)
+		return BRASERO_BURN_ERR;
+
+	if (!brasero_vob_build_pipeline (BRASERO_VOB (job), error))
+		return BRASERO_BURN_ERR;
+
+	/* ready to go */
+	brasero_job_set_current_action (job,
+					BRASERO_BURN_ACTION_ANALYSING,
+					_("Converting video file to MPEG2"),
+					FALSE);
+	gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
+
+	return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_vob_clock_tick (BraseroJob *job)
+{
+	gint64 position = 0.0;
+	gint64 duration = 0.0;
+	BraseroVobPrivate *priv;
+	GstFormat format = GST_FORMAT_TIME;
+
+	priv = BRASERO_VOB_PRIVATE (job);
+
+	gst_element_query_duration (priv->pipeline, &format, &duration);
+	gst_element_query_position (priv->pipeline, &format, &position);
+
+	if (duration > 0.0) {
+		gdouble progress;
+
+		progress = (gdouble) position / (gdouble) duration;
+		brasero_job_set_progress (job, progress);
+	}
+
+	return BRASERO_BURN_OK;
+}
+
+static void
+brasero_vob_init (BraseroVob *object)
+{}
+
+static void
+brasero_vob_finalize (GObject *object)
+{
+	BraseroVobPrivate *priv;
+
+	priv = BRASERO_VOB_PRIVATE (object);
+
+	if (priv->pipeline) {
+		gst_object_unref (priv->pipeline);
+		priv->pipeline = NULL;
+	}
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+brasero_vob_class_init (BraseroVobClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	BraseroJobClass* job_class = BRASERO_JOB_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (BraseroVobPrivate));
+
+	object_class->finalize = brasero_vob_finalize;
+
+	job_class->start = brasero_vob_start;
+	job_class->clock_tick = brasero_vob_clock_tick;
+	job_class->stop = brasero_vob_stop;
+}
+
+static BraseroBurnResult
+brasero_vob_export_caps (BraseroPlugin *plugin, gchar **error)
+{
+	GSList *input;
+	GSList *output;
+	GstElement *element;
+
+	/* Let's see if we've got the plugins we need */
+	element = gst_element_factory_make ("ffenc_mpeg2video", NULL);
+	if (!element)
+		return BRASERO_BURN_ERR;
+
+	element = gst_element_factory_make ("ffenc_ac3", NULL);
+	if (!element)
+		return BRASERO_BURN_ERR;
+
+	element = gst_element_factory_make ("ffenc_mp2", NULL);
+	if (!element)
+		return BRASERO_BURN_ERR;
+
+	element = gst_element_factory_make ("mplex", NULL);
+	if (!element)
+		return BRASERO_BURN_ERR;
+
+	gst_object_unref (element);
+
+	brasero_plugin_define (plugin,
+			       "transcode2vob",
+			       _("Vob allows to transcode any video file to a format suitable for video DVDs"),
+			       "Philippe Rouquier",
+			       0);
+
+	input = brasero_caps_audio_new (BRASERO_PLUGIN_IO_ACCEPT_FILE,
+					BRASERO_AUDIO_FORMAT_UNDEFINED|
+					BRASERO_VIDEO_FORMAT_UNDEFINED);
+	output = brasero_caps_audio_new (BRASERO_PLUGIN_IO_ACCEPT_FILE,
+					 BRASERO_AUDIO_FORMAT_AC3|
+					 BRASERO_AUDIO_FORMAT_MP2|
+					 BRASERO_AUDIO_FORMAT_RAW|
+					 BRASERO_VIDEO_FORMAT_MPEG2);
+
+	brasero_plugin_link_caps (plugin, output, input);
+	g_slist_free (output);
+	g_slist_free (input);
+
+	return BRASERO_BURN_OK;
+}

Added: branches/video/src/plugins/gstreamer/burn-vob.h
==============================================================================
--- (empty file)
+++ branches/video/src/plugins/gstreamer/burn-vob.h	Sun Jun  8 18:18:01 2008
@@ -0,0 +1,41 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero-vob.c
+ * Copyright (C) Rouquier Philippe 2008 <bonfire-app wanadoo fr>
+ * 
+ * brasero-vob.c is free software.
+ * 
+ * You may redistribute it and/or modify it under the terms of the
+ * GNU General Public License, as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ * 
+ * brasero-vob.c is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with brasero-vob.c.  If not, write to:
+ * 	The Free Software Foundation, Inc.,
+ * 	51 Franklin Street, Fifth Floor
+ * 	Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _BRASERO_VOB_H_
+#define _BRASERO_VOB_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define BRASERO_TYPE_VOB             (brasero_vob_get_type ())
+#define BRASERO_VOB(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), BRASERO_TYPE_VOB, BraseroVob))
+#define BRASERO_VOB_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), BRASERO_TYPE_VOB, BraseroVobClass))
+#define BRASERO_IS_VOB(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BRASERO_TYPE_VOB))
+#define BRASERO_IS_VOB_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), BRASERO_TYPE_VOB))
+#define BRASERO_VOB_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), BRASERO_TYPE_VOB, BraseroVobClass))
+
+G_END_DECLS
+
+#endif /* _BRASERO_VOB_H_ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]