change internal handling of media format types and don't scan cd before opening conte...
authorAndreas Frisch <andreas.frisch@multimedia-labs.de>
Tue, 28 Oct 2008 18:06:01 +0000 (18:06 +0000)
committerAndreas Frisch <andreas.frisch@multimedia-labs.de>
Tue, 28 Oct 2008 18:06:01 +0000 (18:06 +0000)
lib/python/Components/Scanner.py
lib/python/Plugins/Extensions/MediaPlayer/plugin.py
lib/service/servicemp3.cpp
lib/service/servicemp3.h

index d944c4c795bdb29fb4addf433bdf06a3491b56ac..766d19663d30db286f112c73f8615d6d30700dd2 100644 (file)
@@ -132,9 +132,9 @@ def scanDevice(mountpoint):
 
        # convert to list
        paths_to_scan = list(paths_to_scan)
 
        # convert to list
        paths_to_scan = list(paths_to_scan)
-       
+
        from Components.Harddisk import harddiskmanager 
        from Components.Harddisk import harddiskmanager 
-       blockdev = mountpoint.rsplit('/',1)[-1]
+       blockdev = mountpoint.rstrip("/").rsplit('/',1)[-1]
        error, blacklisted, removable, is_cdrom, partitions = harddiskmanager.getBlockDevInfo(blockdev)
 
        # now scan the paths
        error, blacklisted, removable, is_cdrom, partitions = harddiskmanager.getBlockDevInfo(blockdev)
 
        # now scan the paths
index 7b5a4a097baa8e5347979f9f2aa93e13d635f104..a144f2cd69d24f672d65b2cc37e7696248735cad 100644 (file)
@@ -1,4 +1,4 @@
-from os import path as os_path, remove as os_remove, listdir as os_listdir, popen
+from os import path as os_path, remove as os_remove, listdir as os_listdir
 from time import strftime
 from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation
 from Screens.Screen import Screen
 from time import strftime
 from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation
 from Screens.Screen import Screen
@@ -66,7 +66,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                self.addPlaylistParser(PlaylistIOInternal, "e2pls")
 
                # 'None' is magic to start at the list of mountpoints
                self.addPlaylistParser(PlaylistIOInternal, "e2pls")
 
                # 'None' is magic to start at the list of mountpoints
-               self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
+               self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
@@ -233,7 +233,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                currPlay = self.session.nav.getCurrentService()
                message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
                print "[__evPluginError]" , message
                currPlay = self.session.nav.getCurrentService()
                message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
                print "[__evPluginError]" , message
-               self.session.open(MessageBox, ("GStreamer Error: missing %s") % message, type = MessageBox.TYPE_INFO,timeout = 20 )
+               self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
 
        def delMPTimer(self):
                del self.rightKeyTimer
 
        def delMPTimer(self):
                del self.rightKeyTimer
@@ -459,18 +459,8 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                menu.append((_("load playlist"), "loadplaylist"));
                menu.append((_("delete saved playlist"), "deleteplaylist"));
                menu.append((_("repeat playlist"), "repeat"));
                menu.append((_("load playlist"), "loadplaylist"));
                menu.append((_("delete saved playlist"), "deleteplaylist"));
                menu.append((_("repeat playlist"), "repeat"));
-               self.cdAudioTrackFiles = []
                drivepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
                if pathExists(drivepath):
                drivepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
                if pathExists(drivepath):
-                       from Components.Scanner import scanDevice
-                       res = scanDevice(drivepath)
-                       list = [ (r.description, r, res[r], self.session) for r in res ]
-                       if list:
-                               (desc, scanner, files, session) = list[0]
-                               for file in files:
-                                       if file.mimetype == "audio/x-cda":
-                                               self.cdAudioTrackFiles.append(file.path)
-               if len(self.cdAudioTrackFiles):
                        menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
                self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
 
                        menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
                self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
 
@@ -515,21 +505,33 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
                                self.repeat = True
                                self["repeat"].setPixmapNum(1)
                elif choice[1] == "audiocd":
                                self.repeat = True
                                self["repeat"].setPixmapNum(1)
                elif choice[1] == "audiocd":
+                       from Components.Scanner import scanDevice
+                       drivepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
+                       self.cdAudioTrackFiles = []
+                       res = scanDevice(drivepath)
+                       list = [ (r.description, r, res[r], self.session) for r in res ]
+                       if list:
+                               (desc, scanner, files, session) = list[0]
+                               for file in files:
+                                       if file.mimetype == "audio/x-cda":
+                                               self.cdAudioTrackFiles.append(file.path)
                        self.playAudioCD()
                        self.playAudioCD()
-                       
+
        def playAudioCD(self):
                from enigma import eServiceReference
                from Plugins.Extensions.CDInfo.plugin import Query
        def playAudioCD(self):
                from enigma import eServiceReference
                from Plugins.Extensions.CDInfo.plugin import Query
-               self.playlist.clear()
-               self.savePlaylistOnExit = False
-               self.isAudioCD = True
-               for file in self.cdAudioTrackFiles:
-                       ref = eServiceReference(4097, 0, file)
-                       self.playlist.addFile(ref)
-               cdinfo = Query(self)
-               cdinfo.scan()
-               self.changeEntry(0)
-               self.switchToPlayList()
+
+               if len(self.cdAudioTrackFiles):
+                       self.playlist.clear()
+                       self.savePlaylistOnExit = False
+                       self.isAudioCD = True
+                       for file in self.cdAudioTrackFiles:
+                               ref = eServiceReference(4097, 0, file)
+                               self.playlist.addFile(ref)
+                       cdinfo = Query(self)
+                       cdinfo.scan()
+                       self.changeEntry(0)
+                       self.switchToPlayList()
 
        def showEventInformation(self):
                from Screens.EventView import EventViewSimple
 
        def showEventInformation(self):
                from Screens.EventView import EventViewSimple
index 6d703b5ec74027f57903753b102adbc0f54bc6fb..5c882ba21e5f695edbe0a976f0f4f42443fc7124 100644 (file)
@@ -37,6 +37,7 @@ eServiceFactoryMP3::eServiceFactoryMP3()
                extensions.push_back("avi");
                extensions.push_back("dat");
                extensions.push_back("flac");
                extensions.push_back("avi");
                extensions.push_back("dat");
                extensions.push_back("flac");
+               extensions.push_back("mp4");
                sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
        }
 
                sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
        }
 
@@ -198,48 +199,58 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
        if (!ext)
                ext = filename;
 
        if (!ext)
                ext = filename;
 
-       int is_mpeg_ps = !(strcasecmp(ext, ".mpeg") && strcasecmp(ext, ".mpg") && strcasecmp(ext, ".vob") && strcasecmp(ext, ".bin") && strcasecmp(ext, ".dat"));
-       int is_mpeg_ts = !strcasecmp(ext, ".ts");
-       int is_matroska = !strcasecmp(ext, ".mkv");
-       int is_avi = !strcasecmp(ext, ".avi");
-       int is_mp3 = !strcasecmp(ext, ".mp3"); /* force mp3 instead of decodebin */
-       int is_video = is_mpeg_ps || is_mpeg_ts || is_matroska || is_avi;
-       int is_streaming = !strncmp(filename, "http://", 7);
-       int is_AudioCD = !(strncmp(filename, "/autofs/", 8) || strncmp(filename+strlen(filename)-13, "/track-", 7) || strcasecmp(ext, ".wav"));
-       int is_VCD = !strcasecmp(ext, ".dat");
-       
-       eDebug("filename: %s, is_mpeg_ps: %d, is_mpeg_ts: %d, is_video: %d, is_streaming: %d, is_mp3: %d, is_matroska: %d, is_avi: %d, is_AudioCD: %d, is_VCD: %d", filename, is_mpeg_ps, is_mpeg_ts, is_video, is_streaming, is_mp3, is_matroska, is_avi, is_AudioCD, is_VCD);
-       
-       int is_audio = !is_video;
+       sourceStream sourceinfo;
+       if ( (strcasecmp(ext, ".mpeg") && strcasecmp(ext, ".mpg") && strcasecmp(ext, ".vob") && strcasecmp(ext, ".bin") && strcasecmp(ext, ".dat") ) == 0 )
+               sourceinfo.containertype = ctMPEGPS;
+       else if ( strcasecmp(ext, ".ts") == 0 )
+               sourceinfo.containertype = ctMPEGTS;
+       else if ( strcasecmp(ext, ".mkv") == 0 )
+               sourceinfo.containertype = ctMKV;
+       else if ( strcasecmp(ext, ".avi") == 0 )
+               sourceinfo.containertype = ctAVI;
+       else if ( strcasecmp(ext, ".mp4") == 0 )
+               sourceinfo.containertype = ctMP4;
+       else if ( (strncmp(filename, "/autofs/", 8) || strncmp(filename+strlen(filename)-13, "/track-", 7) || strcasecmp(ext, ".wav")) == 0 )
+               sourceinfo.containertype = ctCDA;
+       if ( strcasecmp(ext, ".dat") == 0 )
+               sourceinfo.containertype = ctVCD;
+       if ( (strncmp(filename, "http://", 7)) == 0 )
+               sourceinfo.is_streaming = TRUE;
+
+       sourceinfo.is_video = ( sourceinfo.containertype && sourceinfo.containertype != ctCDA );
+
+       eDebug("filename=%s, containertype=%d, is_video=%d, is_streaming=%d", filename, sourceinfo.containertype, sourceinfo.is_video, sourceinfo.is_streaming);
 
        int all_ok = 0;
 
        m_gst_pipeline = gst_pipeline_new ("mediaplayer");
        if (!m_gst_pipeline)
 
        int all_ok = 0;
 
        m_gst_pipeline = gst_pipeline_new ("mediaplayer");
        if (!m_gst_pipeline)
-               eWarning("failed to create pipeline");
+               m_error_message = "failed to create GStreamer pipeline!\n";
 
 
-       if (is_AudioCD)
+       if ( sourceinfo.containertype == ctCDA )
        {
                source = gst_element_factory_make ("cdiocddasrc", "cda-source");
                if (source)
                        g_object_set (G_OBJECT (source), "device", "/dev/cdroms/cdrom0", NULL);
                else
        {
                source = gst_element_factory_make ("cdiocddasrc", "cda-source");
                if (source)
                        g_object_set (G_OBJECT (source), "device", "/dev/cdroms/cdrom0", NULL);
                else
-                       is_AudioCD = 0;
+                       sourceinfo.containertype = ctNone;
        }
        }
-       if ( !is_streaming && !is_AudioCD )
+       if ( !sourceinfo.is_streaming && sourceinfo.containertype != ctCDA )
+       {
                source = gst_element_factory_make ("filesrc", "file-source");
                source = gst_element_factory_make ("filesrc", "file-source");
-       else if ( is_streaming ) 
+               if (source)
+                       g_object_set (G_OBJECT (source), "location", filename, NULL);
+               else
+                       m_error_message = "GStreamer can't open filesrc " + (std::string)filename + "!\n";
+       }
+       else if ( sourceinfo.is_streaming ) 
        {
                source = gst_element_factory_make ("neonhttpsrc", "http-source");
                if (source)
                        g_object_set (G_OBJECT (source), "automatic-redirect", TRUE, NULL);
        {
                source = gst_element_factory_make ("neonhttpsrc", "http-source");
                if (source)
                        g_object_set (G_OBJECT (source), "automatic-redirect", TRUE, NULL);
+               else
+                       m_error_message = "GStreamer plugin neonhttpsrc not available!\n";
        }
        }
-
-       if (!source)
-               eWarning("failed to create %s", is_streaming ? "neonhttpsrc" : "filesrc");
-                               /* configure source */
-       else if (!is_AudioCD)
-               g_object_set (G_OBJECT (source), "location", filename, NULL);
        else
        { 
                int track = atoi(filename+18);
        else
        { 
                int track = atoi(filename+18);
@@ -247,120 +258,107 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
                if (track > 0)
                        g_object_set (G_OBJECT (source), "track", track, NULL);
        }
                if (track > 0)
                        g_object_set (G_OBJECT (source), "track", track, NULL);
        }
+       if ( sourceinfo.is_video )
+       {
+                       /* filesrc -> mpegdemux -> | queue_audio -> dvbaudiosink
+                                                  | queue_video -> dvbvideosink */
+
+               audio = gst_element_factory_make("dvbaudiosink", "audiosink");
+               if (!audio)
+                       m_error_message += "failed to create Gstreamer element dvbaudiosink\n";
+               
+               video = gst_element_factory_make("dvbvideosink", "videosink");
+               if (!video)
+                       m_error_message += "failed to create Gstreamer element dvbvideosink\n";
+
+               queue_audio = gst_element_factory_make("queue", "queue_audio");
+               queue_video = gst_element_factory_make("queue", "queue_video");
+
+               char demux_type[14];
+               switch (sourceinfo.containertype)
+               {
+                       case ctMPEGTS:
+                               strcat(demux_type, "flutsdemux");
+                               break;
+                       case ctMPEGPS:
+                       case ctVCD:
+                               strcat(demux_type, "flupsdemux");
+                               break;
+                       case ctMKV:
+                               strcat(demux_type, "matroskademux");
+                               break;
+                       case ctAVI:
+                               strcat(demux_type, "avidemux");
+                               break;
+                       case ctMP4:
+                               strcat(demux_type, "qtdemux");
+                               break;
+                       default:
+                               break;
+               }
+               videodemux = gst_element_factory_make(demux_type, "videodemux");
+               if (!videodemux)
+                       m_error_message = "GStreamer plugin " + (std::string)demux_type + " not available!\n";
+
+               switch_audio = gst_element_factory_make ("input-selector", "switch_audio");
+               if (!switch_audio)
+                       m_error_message = "GStreamer plugin input-selector not available!\n";
 
 
-       if (is_audio)
+               if (audio && queue_audio && video && queue_video && videodemux && switch_audio)
+               {
+                       g_object_set (G_OBJECT (queue_audio), "max-size-bytes", 256*1024, NULL);
+                       g_object_set (G_OBJECT (queue_audio), "max-size-buffers", 0, NULL);
+                       g_object_set (G_OBJECT (queue_audio), "max-size-time", (guint64)0, NULL);
+                       g_object_set (G_OBJECT (queue_video), "max-size-buffers", 0, NULL);
+                       g_object_set (G_OBJECT (queue_video), "max-size-bytes", 2*1024*1024, NULL);
+                       g_object_set (G_OBJECT (queue_video), "max-size-time", (guint64)0, NULL);
+                       g_object_set (G_OBJECT (switch_audio), "select-all", TRUE, NULL);
+                       all_ok = 1;
+               }
+       } else /* is audio */
        {
        {
-                       /* filesrc -> decodebin -> audioconvert -> capsfilter -> alsasink */
-               const char *decodertype = "decodebin";
 
 
-               decoder = gst_element_factory_make (decodertype, "decoder");
+                       /* filesrc -> decodebin -> audioconvert -> capsfilter -> alsasink */
+               decoder = gst_element_factory_make ("decodebin", "decoder");
                if (!decoder)
                if (!decoder)
-                       eWarning("failed to create %s decoder", decodertype);
+                       m_error_message += "failed to create Gstreamer element decodebin\n";
 
                conv = gst_element_factory_make ("audioconvert", "converter");
                if (!conv)
 
                conv = gst_element_factory_make ("audioconvert", "converter");
                if (!conv)
-                       eWarning("failed to create audioconvert");
+                       m_error_message += "failed to create Gstreamer element audioconvert\n";
 
                flt = gst_element_factory_make ("capsfilter", "flt");
                if (!flt)
 
                flt = gst_element_factory_make ("capsfilter", "flt");
                if (!flt)
-                       eWarning("failed to create capsfilter");
+                       m_error_message += "failed to create Gstreamer element capsfilter\n";
 
                        /* for some reasons, we need to set the sample format to depth/width=16, because auto negotiation doesn't work. */
                        /* endianness, however, is not required to be set anymore. */
                if (flt)
                {
 
                        /* for some reasons, we need to set the sample format to depth/width=16, because auto negotiation doesn't work. */
                        /* endianness, however, is not required to be set anymore. */
                if (flt)
                {
-                       GstCaps *caps = gst_caps_new_simple("audio/x-raw-int", /* "endianness", G_TYPE_INT, 4321, */ "depth", G_TYPE_INT, 16, "width", G_TYPE_INT, 16, /*"channels", G_TYPE_INT, 2, */(char*)0);
-                       g_object_set (G_OBJECT (flt), "caps", caps, (char*)0);
+                       GstCaps *caps = gst_caps_new_simple("audio/x-raw-int", /* "endianness", G_TYPE_INT, 4321, */ "depth", G_TYPE_INT, 16, "width", G_TYPE_INT, 16, /*"channels", G_TYPE_INT, 2, */NULL);
+                       g_object_set (G_OBJECT (flt), "caps", caps, NULL);
                        gst_caps_unref(caps);
                }
 
                sink = gst_element_factory_make ("alsasink", "alsa-output");
                if (!sink)
                        gst_caps_unref(caps);
                }
 
                sink = gst_element_factory_make ("alsasink", "alsa-output");
                if (!sink)
-                       eWarning("failed to create osssink");
+                       m_error_message += "failed to create Gstreamer element alsasink\n";
 
                if (source && decoder && conv && sink)
                        all_ok = 1;
 
                if (source && decoder && conv && sink)
                        all_ok = 1;
-       } else /* is_video */
-       {
-                       /* filesrc -> mpegdemux -> | queue_audio -> dvbaudiosink
-                                                  | queue_video -> dvbvideosink */
-
-               audio = gst_element_factory_make("dvbaudiosink", "audiosink");
-               queue_audio = gst_element_factory_make("queue", "queue_audio");
-               
-               video = gst_element_factory_make("dvbvideosink", "videosink");
-               queue_video = gst_element_factory_make("queue", "queue_video");
-               
-               if (is_mpeg_ps)
-                       videodemux = gst_element_factory_make("flupsdemux", "videodemux");
-               else if (is_mpeg_ts)
-                       videodemux = gst_element_factory_make("flutsdemux", "videodemux");
-               else if (is_matroska)
-                       videodemux = gst_element_factory_make("matroskademux", "videodemux");
-               else if (is_avi)
-                       videodemux = gst_element_factory_make("avidemux", "videodemux");
-
-               if (!videodemux)
-               {
-                       eDebug("fluendo mpegdemux not available, falling back to mpegdemux\n");
-                       videodemux = gst_element_factory_make("mpegdemux", "videodemux");
-               }
-
-               eDebug("audio: %p, queue_audio %p, video %p, queue_video %p, videodemux %p", audio, queue_audio, video, queue_video, videodemux);
-               if (audio && queue_audio && video && queue_video && videodemux)
-               {
-                       g_object_set (G_OBJECT (queue_audio), "max-size-bytes", 256*1024, NULL);
-                       g_object_set (G_OBJECT (queue_audio), "max-size-buffers", 0, NULL);
-                       g_object_set (G_OBJECT (queue_audio), "max-size-time", (guint64)0, NULL);
-                       g_object_set (G_OBJECT (queue_video), "max-size-buffers", 0, NULL);
-                       g_object_set (G_OBJECT (queue_video), "max-size-bytes", 2*1024*1024, NULL);
-                       g_object_set (G_OBJECT (queue_video), "max-size-time", (guint64)0, NULL);
-                       all_ok = 1;
-               }
        }
        }
-       
        if (m_gst_pipeline && all_ok)
        {
                gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (m_gst_pipeline)), gstBusSyncHandler, this);
 
        if (m_gst_pipeline && all_ok)
        {
                gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (m_gst_pipeline)), gstBusSyncHandler, this);
 
-               if (is_AudioCD)
+               if ( sourceinfo.containertype == ctCDA )
                {
                        queue_audio = gst_element_factory_make("queue", "queue_audio");
                        g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL);
                        gst_bin_add_many (GST_BIN (m_gst_pipeline), source, queue_audio, conv, sink, NULL);
                        gst_element_link_many(source, queue_audio, conv, sink, NULL);
                }
                {
                        queue_audio = gst_element_factory_make("queue", "queue_audio");
                        g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL);
                        gst_bin_add_many (GST_BIN (m_gst_pipeline), source, queue_audio, conv, sink, NULL);
                        gst_element_link_many(source, queue_audio, conv, sink, NULL);
                }
-               else if (is_audio)
-               {
-                       queue_audio = gst_element_factory_make("queue", "queue_audio");
-
-                       g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK(gstCBnewPad), this);
-                       g_signal_connect (decoder, "unknown-type", G_CALLBACK(gstCBunknownType), this);
-
-                       if (!is_mp3)
-                               g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL);
-
-                               /* gst_bin will take the 'floating references' */
-                       gst_bin_add_many (GST_BIN (m_gst_pipeline),
-                                               source, queue_audio, decoder, NULL);
-
-                               /* in decodebin's case we can just connect the source with the decodebin, and decodebin will take care about id3demux (or whatever is required) */
-                       gst_element_link_many(source, queue_audio, decoder, NULL);
-
-                               /* create audio bin with the audioconverter, the capsfilter and the audiosink */
-                       audio = gst_bin_new ("audiobin");
-
-                       GstPad *audiopad = gst_element_get_static_pad (conv, "sink");
-                       gst_bin_add_many(GST_BIN(audio), conv, flt, sink, (char*)0);
-                       gst_element_link_many(conv, flt, sink, (char*)0);
-                       gst_element_add_pad(audio, gst_ghost_pad_new ("sink", audiopad));
-                       gst_object_unref(audiopad);
-                       gst_bin_add (GST_BIN(m_gst_pipeline), audio);
-                               /* in mad's case, we can directly connect the decoder to the audiobin. otherwise, we do this in gstCBnewPad */
-                       if (is_mp3)
-                               gst_element_link(decoder, audio);
-
-               } else /* is_video */
+               else if ( sourceinfo.is_video )
                {
                        char srt_filename[strlen(filename)+1];
                        strncpy(srt_filename,filename,strlen(filename)-3);
                {
                        char srt_filename[strlen(filename)+1];
                        strncpy(srt_filename,filename,strlen(filename)-3);
@@ -381,16 +379,9 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
                                subs.language_code = std::string("und");
                                m_subtitleStreams.push_back(subs);
                        }
                                subs.language_code = std::string("und");
                                m_subtitleStreams.push_back(subs);
                        }
-                       gst_bin_add_many(GST_BIN(m_gst_pipeline), source, videodemux, audio, queue_audio, video, queue_video, NULL);
-                       switch_audio = gst_element_factory_make ("input-selector", "switch_audio");
-                       if (switch_audio)
-                       {
-                               g_object_set (G_OBJECT (switch_audio), "select-all", TRUE, NULL);
-                               gst_bin_add(GST_BIN(m_gst_pipeline), switch_audio);
-                               gst_element_link(switch_audio, queue_audio);
-                       }
+                       gst_bin_add_many(GST_BIN(m_gst_pipeline), source, videodemux, audio, queue_audio, video, queue_video, switch_audio, NULL);
 
 
-                       if (is_VCD)
+                       if ( sourceinfo.containertype == ctVCD )
                        {
                                GstElement *cdxaparse = gst_element_factory_make("cdxaparse", "cdxaparse");
                                gst_bin_add(GST_BIN(m_gst_pipeline), cdxaparse);
                        {
                                GstElement *cdxaparse = gst_element_factory_make("cdxaparse", "cdxaparse");
                                gst_bin_add(GST_BIN(m_gst_pipeline), cdxaparse);
@@ -399,12 +390,42 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
                        }
                        else
                                gst_element_link(source, videodemux);
                        }
                        else
                                gst_element_link(source, videodemux);
+
+                       gst_element_link(switch_audio, queue_audio);
                        gst_element_link(queue_audio, audio);
                        gst_element_link(queue_video, video);
                        g_signal_connect(videodemux, "pad-added", G_CALLBACK (gstCBpadAdded), this);
                        gst_element_link(queue_audio, audio);
                        gst_element_link(queue_video, video);
                        g_signal_connect(videodemux, "pad-added", G_CALLBACK (gstCBpadAdded), this);
+
+               } else /* is audio*/
+               {
+                       queue_audio = gst_element_factory_make("queue", "queue_audio");
+
+                       g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK(gstCBnewPad), this);
+                       g_signal_connect (decoder, "unknown-type", G_CALLBACK(gstCBunknownType), this);
+
+                       g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL);
+
+                               /* gst_bin will take the 'floating references' */
+                       gst_bin_add_many (GST_BIN (m_gst_pipeline),
+                                               source, queue_audio, decoder, NULL);
+
+                               /* in decodebin's case we can just connect the source with the decodebin, and decodebin will take care about id3demux (or whatever is required) */
+                       gst_element_link_many(source, queue_audio, decoder, NULL);
+
+                               /* create audio bin with the audioconverter, the capsfilter and the audiosink */
+                       audio = gst_bin_new ("audiobin");
+
+                       GstPad *audiopad = gst_element_get_static_pad (conv, "sink");
+                       gst_bin_add_many(GST_BIN(audio), conv, flt, sink, NULL);
+                       gst_element_link_many(conv, flt, sink, NULL);
+                       gst_element_add_pad(audio, gst_ghost_pad_new ("sink", audiopad));
+                       gst_object_unref(audiopad);
+                       gst_bin_add (GST_BIN(m_gst_pipeline), audio);
                }
        } else
        {
                }
        } else
        {
+               m_event((iPlayableService*)this, evUser+12);
+
                if (m_gst_pipeline)
                        gst_object_unref(GST_OBJECT(m_gst_pipeline));
                if (source)
                if (m_gst_pipeline)
                        gst_object_unref(GST_OBJECT(m_gst_pipeline));
                if (source)
@@ -429,10 +450,10 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp
                if (switch_audio)
                        gst_object_unref(GST_OBJECT(switch_audio));
 
                if (switch_audio)
                        gst_object_unref(GST_OBJECT(switch_audio));
 
-               eDebug("sorry, can't play.");
+               eDebug("sorry, can't play: %s",m_error_message.c_str());
                m_gst_pipeline = 0;
        }
                m_gst_pipeline = 0;
        }
-       
+
        gst_element_set_state (m_gst_pipeline, GST_STATE_PLAYING);
 }
 
        gst_element_set_state (m_gst_pipeline, GST_STATE_PLAYING);
 }
 
@@ -963,7 +984,7 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
                        gchar *description = gst_missing_plugin_message_get_description(msg);                   
                        if ( description )
                        {
                        gchar *description = gst_missing_plugin_message_get_description(msg);                   
                        if ( description )
                        {
-                               m_error_message = description;
+                               m_error_message = "GStreamer plugin " + (std::string)description + " not available!\n";
                                g_free(description);
                                m_event((iPlayableService*)this, evUser+12);
                        }
                                g_free(description);
                                m_event((iPlayableService*)this, evUser+12);
                        }
index ea06429917e2681856fea5b6a73806c0a4d4ff70..ae12c33a66aa400ecd0b23cf89c01cdd03691466 100644 (file)
@@ -43,8 +43,9 @@ public:
 
 typedef struct _GstElement GstElement;
 
 
 typedef struct _GstElement GstElement;
 
-typedef enum { atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG } audiotype_t;
+typedef enum { atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC } audiotype_t;
 typedef enum { stPlainText, stSSA, stSRT } subtype_t;
 typedef enum { stPlainText, stSSA, stSRT } subtype_t;
+typedef enum { ctNone, ctMPEGTS, ctMPEGPS, ctMKV, ctAVI, ctMP4, ctVCD, ctCDA } containertype_t;
 
 class eServiceMP3: public iPlayableService, public iPauseableService, 
        public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection, public iSubtitleOutput, public Object
 
 class eServiceMP3: public iPlayableService, public iPauseableService, 
        public iServiceInformation, public iSeekableService, public iAudioTrackSelection, public iAudioChannelSelection, public iSubtitleOutput, public Object
@@ -133,6 +134,17 @@ public:
                {
                }
        };
                {
                }
        };
+       struct sourceStream
+       {
+               audiotype_t audiotype;
+               containertype_t containertype;
+               bool is_video;
+               bool is_streaming;
+               sourceStream()
+                       :audiotype(atUnknown), containertype(ctNone), is_video(FALSE), is_streaming(FALSE)
+               {
+               }
+       };
 private:
        int m_currentAudioStream;
        int m_currentSubtitleStream;
 private:
        int m_currentAudioStream;
        int m_currentSubtitleStream;