[mistelix/stable] Fixes video conversion issues



commit 1628c8200981009c3285ba06ae15557dbaccc3db
Author: Jordi Mas <jmas softcatala org>
Date:   Fri Jun 26 16:46:07 2009 +0200

    Fixes video conversion issues

 libmistelix/Makefile.am       |    3 +-
 libmistelix/mistelix.c        |  193 -------------------------------
 libmistelix/mistelix.h        |    6 +-
 libmistelix/video.c           |  249 +++++++++++++++++++++++++++++++++++++++++
 src/core/MistelixLib.cs       |   44 +++++++-
 src/core/Video.cs             |    2 +-
 src/widgets/FileView.cs       |    4 +-
 src/widgets/ImagesFileView.cs |    2 +-
 src/widgets/VideosFileView.cs |   23 ++--
 9 files changed, 310 insertions(+), 216 deletions(-)
---
diff --git a/libmistelix/Makefile.am b/libmistelix/Makefile.am
index 19cb08e..628e5c9 100644
--- a/libmistelix/Makefile.am
+++ b/libmistelix/Makefile.am
@@ -9,7 +9,8 @@ dolib_LTLIBRARIES = libmistelix.la
 
 libmistelix_la_SOURCES =		\
 	mistelix.c	\
-	thumbnail.c
+	thumbnail.c	\
+	video.c
 
 noinst_HEADERS =  \
 	mistelix.h
diff --git a/libmistelix/mistelix.c b/libmistelix/mistelix.c
index 23eba94..611a855 100644
--- a/libmistelix/mistelix.c
+++ b/libmistelix/mistelix.c
@@ -305,179 +305,6 @@ void mistelix_launchtool (const char* app, const char* args, const char* in_file
 	execvp (app, parmList);
 }
 
-typedef struct
-{
-	const char *media;
-	const char *plugin;
-	const char *pipeline;
-} supported_media;
-
-supported_media supported_medias[] = 
-{
-	{"video/mpeg", "ffenc_mpeg2video", "filesrc location=%s ! decodebin !ffenc_mpeg2video ! ffmux_dvd !filesink location=%s"},
-
-};
-
-int 
-mistelix_media_supported (const char* file, char* msg)
-{
-	char media [2048];
-	int i, ncodecs, c, media_present, plugin_present;
-	char* pos;
-
-#ifdef _DEBUG
-	printf ("*** mistelix_media_supported %s\n", file);
-#endif
-
-	mistelix_detect_media (file, media);
-
-	pos = strchr (media, ',');
-
-	if (pos != NULL)
-		*pos = 0x0;
-
-	if (*media == 0x0)
-		return 1; // Could not identify media
-
-	ncodecs = mistelix_get_codecs_count ();
-	char *codecs[ncodecs];
-	mistelix_get_codecs (codecs);
-
-	media_present =  plugin_present = 0;
-	for (i = 0; i < sizeof (supported_medias) / sizeof (supported_media); i++)
-	{
-		//printf ("Comparing %s with %s\n", media, supported_medias[i].media);
-		if (strcmp (media, supported_medias[i].media) != 0)
-			continue;
-
-		media_present = 1;
-		for (c = 0; c < ncodecs; c++)
-		{
-			//printf ("Comparing %s with %s\n", supported_medias[i].plugin, codecs[c]);
-			if (strcmp (supported_medias[i].plugin, codecs[c]) == 0)
-			{
-				plugin_present = 1;
-				break;
-			}
-		}
-		break;
-	}
-
-	for (c = 0; c < ncodecs; c++)
-		free (codecs [c]);
-
-	if (media_present == 0)
-		return 2; // Format not supported 
-
-	if (media_present == 1 && plugin_present == 0) {
-		strcpy (msg, supported_medias[i].plugin);
-		return 3; // Supported media but codec not found + codec name
-	}
-
-	return 0; // Supported media & codec found
-}
-
-int
-mistelix_convert_media (const char* filein, const char* fileout)
-{
-	char media [2048];
-	int i, ncodecs, c, media_present, plugin_present;
-	char* pos;
-
-	mistelix_detect_media (filein, media);
-
-#ifdef _DEBUG
-	printf ("*** mistelix_convert_media %s %s\n", filein, fileout);
-#endif
-
-	pos = strchr (media, ',');
-
-	if (pos != NULL)
-		*pos = 0x0;
-
-	if (*media == 0x0)
-		return 1; // Could not identify media
-
-	ncodecs = mistelix_get_codecs_count ();
-	char *codecs[ncodecs];
-	mistelix_get_codecs (codecs);
-
-	media_present =  plugin_present = 0;
-	for (i = 0; i < sizeof (supported_medias) / sizeof (supported_media); i++)
-	{
-		if (strcmp (media, supported_medias[i].media) != 0)
-			continue;
-
-		media_present = 1;
-		for (c = 0; c < ncodecs; c++)
-		{
-			if (strcmp (supported_medias[i].plugin, codecs[c]) == 0)
-			{
-				plugin_present = 1;
-				break;
-			}
-		}
-		break;
-	}
-
-	for (c = 0; c < ncodecs; c++)
-		free (codecs [c]);
-
-	if (media_present == 0)
-		return 2; // Format not supported 
-
-	if (media_present == 1 && plugin_present == 0)
-		return 3; // Supported media but codec not found + codec name
-
-	char desc [1024];
-	GstElement *pipe;
-
-	mistelix_check_init ();
-	sprintf (desc, supported_medias[i].pipeline, filein, fileout);
-	printf ("pipe %s\n", desc);
-	pipe = gst_parse_launch (desc, NULL);
-	run_pipeline (pipe);
-	return 0;
-}
-
-//
-// Private
-//
-
-void
-mistelix_detect_media (const char* file, char* media)
-{
-	GstElement* pipe, *filesrc, *typefind, *fakesink;
-	GstBus *bus;
-	char media_type [2048];
-
-	mistelix_check_init ();
-
-	pipe = gst_pipeline_new ("pipe");
-	bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
-	gst_object_unref (bus);
-
-	// create file source and typefind element
-	filesrc = gst_element_factory_make ("filesrc", "source");
-	g_object_set (G_OBJECT (filesrc), "location", file, NULL);
-	typefind = gst_element_factory_make ("typefind", "typefinder");
-	g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), (gpointer) media_type);
-	fakesink = gst_element_factory_make ("fakesink", "sink");
-
-	gst_bin_add_many (GST_BIN (pipe), filesrc, typefind, fakesink, NULL);
-	gst_element_link_many (filesrc, typefind, fakesink, NULL);
-
-	gst_element_set_state (GST_ELEMENT (pipe), GST_STATE_PLAYING);
-	/* Wait for status change */
-	gst_element_get_state (pipe, NULL, NULL, SEEK_TIMEOUT);
-
-	gst_element_set_state (GST_ELEMENT (pipe), GST_STATE_NULL);
-	gst_object_unref (GST_OBJECT (pipe));
-	strcpy (media, media_type);
-
-	printf ("*** mistelix_detect_media result for %s is [%s]\n", file, media);
-}
-
 void
 mistelix_check_init ()
 {
@@ -488,26 +315,6 @@ mistelix_check_init ()
 	gstreamer_init = TRUE;
 }
 
-static void
-cb_typefound (GstElement *typefind,
-	      guint       probability,
-	      GstCaps    *caps,
-	      gpointer    data)
-{
-	gchar *type;
-	char* media_type = (char*) data;
-
-	type = gst_caps_to_string (caps);
-
-//#ifdef _DEBUG
-	printf ("Media type %s found, probability %d%%, %x\n", type, probability, (unsigned int) caps);
-//#endif
-	if (caps!= NULL && type != NULL)
-		strcpy (media_type, type);
-
-	g_free (type);
-}
-
 /*
 	Do not want to start the thread until is necessary
 	to allow for example to add an audio channel before launching it
diff --git a/libmistelix/mistelix.h b/libmistelix/mistelix.h
index 6acfeb1..f952439 100644
--- a/libmistelix/mistelix.h
+++ b/libmistelix/mistelix.h
@@ -46,10 +46,14 @@ void mistelix_slideshow_close ();
 
 void mistelix_launchtool (const char* app, const char* args, const char* in, const char* out, const char* err);
 
-int mistelix_convert_media (const char* filein, const char* fileout);
+int mistelix_convert_media (const char* filein, const char* fileout, unsigned int frames_sec);
 
 void mistelix_video_screenshot (const char* filein, void** image);
 
+unsigned int mistelix_get_codecs_count ();
+
+void mistelix_get_codecs (char *codecs[]);
+
 
 /* Private (not exposed) */
 
diff --git a/libmistelix/video.c b/libmistelix/video.c
new file mode 100644
index 0000000..e2bb466
--- /dev/null
+++ b/libmistelix/video.c
@@ -0,0 +1,249 @@
+//
+// Copyright (C) 2008-2009 Jordi Mas i Hernandez, jmas softcatala org
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+#include "mistelix.h"
+
+typedef struct
+{
+	const char *media;
+	const char *plugin;
+	const char *pipeline;
+} supported_media;
+
+supported_media supported_medias[] = 
+{
+	{"video/mpeg", "ffenc_mpeg2video", 
+		"filesrc location=%s ! flupsdemux name=demux \\ "
+		"{ffmux_dvd name=mux ! filesink location=%s } \\ "
+		"{demux. ! queue ! flump3dec ! queue ! lame ! mux. } \\ "
+		"{demux. ! queue ! mpeg2dec ! ffmpegcolorspace ! videorate ! video/x-raw-yuv,format=(fourcc)I420,framerate=%u/1 ! queue ! ffenc_mpeg2video ! mux. }"},
+
+	{"video/x-msvideo", "avidemux", 
+		"filesrc location=%s ! decodebin name=demux \\ "
+		"{ffmux_dvd name=mux ! filesink location=%s } \\ "
+		"{demux. ! queue ! lame ! mux. } \\ "
+		"{demux. ! queue ! ffmpegcolorspace ! videorate ! video/x-raw-yuv,format=(fourcc)I420,framerate=%u/1 ! queue ! ffenc_mpeg2video ! mux. }"},
+
+	{"video/x-ms-asf", "asfdemux", 
+		"filesrc location=%s ! decodebin name=demux \\ "
+		"{ffmux_dvd name=mux ! filesink location=%s } \\ "
+		"{demux. ! queue ! lame ! mux. } \\ "
+		"{demux. ! queue ! ffmpegcolorspace ! videorate ! video/x-raw-yuv,format=(fourcc)I420,framerate=%u/1 ! queue ! ffenc_mpeg2video ! mux. }"},
+
+	{"application/ogg", "oggdemux", 
+		"filesrc location=%s ! decodebin name=demux \\ "
+		"{ffmux_dvd name=mux ! filesink location=%s } \\ "
+		"{demux. !queue ! vorbisdec ! queue ! audioconvert ! lame ! mux. } \\ "
+		"{demux. ! queue ! ffmpegcolorspace ! videorate ! video/x-raw-yuv,format=(fourcc)I420,framerate=%u/1 ! queue ! ffenc_mpeg2video ! mux. }"},
+
+};
+
+void
+mistelix_video_extensions (char* extensions)
+{
+	strcpy (extensions, "*.mpeg; *.mpg; *.avi; *.wmv; *.asf;*.ogg");
+}
+
+int 
+mistelix_media_supported (const char* file, char* msg)
+{
+	char media [2048];
+	int i, ncodecs, c, media_present, plugin_present;
+	char* pos;
+
+//#ifdef _DEBUG
+	printf ("*** mistelix_media_supported %s\n", file);
+//#endif
+
+	mistelix_detect_media (file, media);
+
+	pos = strchr (media, ',');
+
+	if (pos != NULL)
+		*pos = 0x0;
+
+	if (*media == 0x0)
+		return 1; // Could not identify media
+
+	ncodecs = mistelix_get_codecs_count ();
+	char *codecs[ncodecs];
+	mistelix_get_codecs (codecs);
+
+	media_present =  plugin_present = 0;
+	for (i = 0; i < sizeof (supported_medias) / sizeof (supported_media); i++)
+	{
+		//printf ("Comparing %s with %s\n", media, supported_medias[i].media);
+		if (strcmp (media, supported_medias[i].media) != 0)
+			continue;
+
+		media_present = 1;
+		for (c = 0; c < ncodecs; c++)
+		{
+			//printf ("Comparing %s with %s\n", supported_medias[i].plugin, codecs[c]);
+			if (strcmp (supported_medias[i].plugin, codecs[c]) == 0)
+			{
+				plugin_present = 1;
+				break;
+			}
+		}
+		break;
+	}
+
+	for (c = 0; c < ncodecs; c++)
+		free (codecs [c]);
+
+	if (media_present == 0)
+		return 2; // Format not supported 
+
+	if (media_present == 1 && plugin_present == 0) {
+		strcpy (msg, supported_medias[i].plugin);
+		return 3; // Supported media but codec not found + codec name
+	}
+
+	return 0; // Supported media & codec found
+}
+
+int
+mistelix_convert_media (const char* filein, const char* fileout, unsigned int frames_sec)
+{
+	char media [2048];
+	int i, ncodecs, c, media_present, plugin_present;
+	char* pos;
+
+	mistelix_detect_media (filein, media);
+
+#ifdef _DEBUG
+	printf ("*** mistelix_convert_media %s %s\n", filein, fileout);
+#endif
+
+	pos = strchr (media, ',');
+
+	if (pos != NULL)
+		*pos = 0x0;
+
+	if (*media == 0x0)
+		return 1; // Could not identify media
+
+	ncodecs = mistelix_get_codecs_count ();
+	char *codecs[ncodecs];
+	mistelix_get_codecs (codecs);
+
+	media_present =  plugin_present = 0;
+	for (i = 0; i < sizeof (supported_medias) / sizeof (supported_media); i++)
+	{
+		if (strcmp (media, supported_medias[i].media) != 0)
+			continue;
+
+		media_present = 1;
+		for (c = 0; c < ncodecs; c++)
+		{
+			if (strcmp (supported_medias[i].plugin, codecs[c]) == 0)
+			{
+				plugin_present = 1;
+				break;
+			}
+		}
+		break;
+	}
+
+	for (c = 0; c < ncodecs; c++)
+		free (codecs [c]);
+
+	if (media_present == 0)
+		return 2; // Format not supported 
+
+	if (media_present == 1 && plugin_present == 0)
+		return 3; // Supported media but codec not found + codec name
+
+	char desc [1024];
+	GstElement *pipe;
+
+	mistelix_check_init ();
+	sprintf (desc, supported_medias[i].pipeline, filein, fileout, frames_sec);
+	printf ("pipe %s\n", desc);
+	pipe = gst_parse_launch (desc, NULL);
+	run_pipeline (pipe);
+	return 0;
+}
+
+
+//
+// Private
+//
+
+void
+mistelix_detect_media (const char* file, char* media)
+{
+	GstElement* pipe, *filesrc, *typefind, *fakesink;
+	GstBus *bus;
+	char media_type [2048];
+
+	mistelix_check_init ();
+
+	pipe = gst_pipeline_new ("pipe");
+	bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
+	gst_object_unref (bus);
+
+	// create file source and typefind element
+	filesrc = gst_element_factory_make ("filesrc", "source");
+	g_object_set (G_OBJECT (filesrc), "location", file, NULL);
+	typefind = gst_element_factory_make ("typefind", "typefinder");
+	g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), (gpointer) media_type);
+	fakesink = gst_element_factory_make ("fakesink", "sink");
+
+	gst_bin_add_many (GST_BIN (pipe), filesrc, typefind, fakesink, NULL);
+	gst_element_link_many (filesrc, typefind, fakesink, NULL);
+
+	gst_element_set_state (GST_ELEMENT (pipe), GST_STATE_PLAYING);
+	/* Wait for status change */
+	gst_element_get_state (pipe, NULL, NULL, SEEK_TIMEOUT);
+
+	gst_element_set_state (GST_ELEMENT (pipe), GST_STATE_NULL);
+	gst_object_unref (GST_OBJECT (pipe));
+	strcpy (media, media_type);
+
+	printf ("*** mistelix_detect_media result for %s is [%s]\n", file, media);
+}
+
+
+static void
+cb_typefound (GstElement *typefind,
+	      guint       probability,
+	      GstCaps    *caps,
+	      gpointer    data)
+{
+	gchar *type;
+	char* media_type = (char*) data;
+
+	type = gst_caps_to_string (caps);
+
+//#ifdef _DEBUG
+	printf ("Media type %s found, probability %d%%, %x\n", type, probability, (unsigned int) caps);
+//#endif
+	if (caps!= NULL && type != NULL)
+		strcpy (media_type, type);
+
+	g_free (type);
+}
+
diff --git a/src/core/MistelixLib.cs b/src/core/MistelixLib.cs
index 8f1f2d2..6dd5d11 100644
--- a/src/core/MistelixLib.cs
+++ b/src/core/MistelixLib.cs
@@ -1,5 +1,5 @@
 //
-// Copyright (C) 2008 Jordi Mas i Hernandez, jmas softcatala org
+// Copyright (C) 2008-2009 Jordi Mas i Hernandez, jmas softcatala org
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -67,15 +67,51 @@ namespace Mistelix.Core
 		static extern int mistelix_media_supported (string file, StringBuilder media);
 
 		[DllImport ("libmistelix")]	
-		static extern int mistelix_convert_media (string filein, string fileout);
+		static extern int mistelix_convert_media (string filein, string fileout, uint frames_sec);
 
 		[DllImport ("libmistelix")]	
 		static extern void mistelix_video_screenshot (string filein, out IntPtr pixbuf);
+	
+		[DllImport ("libmistelix")]	
+		static extern void mistelix_video_extensions (StringBuilder extensions);
 
 		public MistelixLib ()
 		{
 		}
 
+		static string [] extensions;
+
+		static public string[] VideoExtensions ()
+		{
+			if (extensions != null)
+				return extensions;
+
+			List <string> strs = new List <string> ();
+			string rslt;
+			int pos;
+			StringBuilder sb = new StringBuilder (1024);
+
+			mistelix_video_extensions (sb);
+			rslt = sb.ToString ();
+	
+			while (true) {
+				rslt = rslt.TrimStart ();
+				pos = rslt.IndexOf (";");
+				
+				if (pos == -1) {
+					if (rslt.Length > 0)
+						strs.Add (rslt);
+					break;
+				}
+
+				strs.Add (rslt.Substring (0, pos));
+				pos++;
+				rslt = rslt.Substring (pos);
+			}
+			extensions = strs.ToArray ();
+			return extensions;
+		}
+
 		static public bool IsMediaSupported (string file, out string msg)
 		{
 			int r;
@@ -102,9 +138,9 @@ namespace Mistelix.Core
 			}
 		}
 	
-		static public bool ConvertMedia (string filein, string fileout)
+		static public bool ConvertMedia (string filein, string fileout, uint frames_sec)
 		{
-			int rslt = mistelix_convert_media (filein, fileout);
+			int rslt = mistelix_convert_media (filein, fileout, frames_sec);
 
 			if (rslt == 0)
 				return true;
diff --git a/src/core/Video.cs b/src/core/Video.cs
index 9992ccc..01680ca 100644
--- a/src/core/Video.cs
+++ b/src/core/Video.cs
@@ -60,7 +60,7 @@ namespace Mistelix.Core
 
 			Logger.Debug ("Video.Convert. File {0} to {1}", filename, outfile);
 			// TODO: If rslt != 0 throw an exception
-			rslt =  MistelixLib.ConvertMedia (filename, outfile);
+			rslt =  MistelixLib.ConvertMedia (filename, outfile, (uint) project.Details.FramesPerSecond);
 			return outfile;
 		}
 	}
diff --git a/src/widgets/FileView.cs b/src/widgets/FileView.cs
index 1db0ddd..aa67345 100644
--- a/src/widgets/FileView.cs
+++ b/src/widgets/FileView.cs
@@ -40,7 +40,7 @@ namespace Mistelix.Widgets
 	public class FileView : IconView, IDisposable
 	{
 		virtual public void OnDirChanged (string new_dir) {}
-		virtual public bool IsValidExtesion (string filename) {return false;}
+		virtual public bool IsValidExtension (string filename) {return false;}
 		virtual public void DoWork (object sender, DoWorkEventArgs e) {}
 		
 		protected ListStore store;
@@ -143,7 +143,7 @@ namespace Mistelix.Widgets
 			// TODO: Optimize for directories with images videos
 			foreach (FileInfo di in parent.GetFiles ())
 			{
-				if (di.Name.StartsWith (".") || IsValidExtesion (di.Name) == false)
+				if (di.Name.StartsWith (".") || IsValidExtension (di.Name) == false)
 					continue;
 
 				store.AppendValues (di.FullName, di.Name, def_image, true);
diff --git a/src/widgets/ImagesFileView.cs b/src/widgets/ImagesFileView.cs
index 1b488bd..03d8d07 100644
--- a/src/widgets/ImagesFileView.cs
+++ b/src/widgets/ImagesFileView.cs
@@ -104,7 +104,7 @@ namespace Mistelix.Widgets
 			LoadElements ();
 		}
 
-		public override bool IsValidExtesion (string filename)
+		public override bool IsValidExtension (string filename)
 		{
 			filename = filename.ToLower ();
 			if (filename.EndsWith (".jpeg"))
diff --git a/src/widgets/VideosFileView.cs b/src/widgets/VideosFileView.cs
index c3d6a35..da21dc7 100644
--- a/src/widgets/VideosFileView.cs
+++ b/src/widgets/VideosFileView.cs
@@ -48,22 +48,19 @@ namespace Mistelix.Widgets
 			LoadElements ();
 		}
 
-		public override bool IsValidExtesion (string filename)
+		public override bool IsValidExtension (string filename)
 		{
+			string [] extensions;
+			int pos;
+		
 			filename = filename.ToLower ();
+			extensions = MistelixLib.VideoExtensions ();
 
-			if (filename.EndsWith (".mpeg"))
-				return true;
-
-			if (filename.EndsWith (".mpg"))
-				return true;
-
-			if (filename.EndsWith (".avi"))
-				return true;
-
-			if (filename.EndsWith (".wmv"))
-				return true;
-
+			foreach (string extension in extensions) {
+				pos = extension.IndexOf ("."); // Extensions are returned as [*.ext]
+				if (filename.EndsWith (extension.Substring (pos + 1)))
+					return true;
+			}
 			return false;
 		}
 



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