servicemp3.cpp: more simple/flexible streaming detection
[enigma2.git] / lib / service / servicemp3.cpp
index 04b1773f400b6d3b144bd4cf9b39f5c774849f25..937032aa64342a9d9b46549f3a55f05b09e341e9 100644 (file)
@@ -1,5 +1,3 @@
-#ifdef HAVE_GSTREAMER
-
        /* note: this requires gstreamer 0.10.x and a big list of plugins. */
        /* it's currently hardcoded to use a big-endian alsasink as sink. */
 #include <lib/base/ebase.h>
@@ -49,7 +47,6 @@ eServiceFactoryMP3::eServiceFactoryMP3()
                extensions.push_back("mp4");
                extensions.push_back("mov");
                extensions.push_back("m4a");
-               extensions.push_back("m2ts");
                sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
        }
 
@@ -231,6 +228,7 @@ eServiceMP3::eServiceMP3(eServiceReference ref)
        m_buffer_size = 1*1024*1024;
        m_prev_decoder_time = -1;
        m_decoder_time_valid_state = 0;
+       m_errorInfo.missing_codec = "";
 
        CONNECT(m_seekTimeout->timeout, eServiceMP3::seekTimeoutCB);
        CONNECT(m_subtitle_sync_timer->timeout, eServiceMP3::pushSubtitles);
@@ -286,7 +284,7 @@ eServiceMP3::eServiceMP3(eServiceReference ref)
                m_sourceinfo.containertype = ctVCD;
                m_sourceinfo.is_video = TRUE;
        }
-       if ( (strncmp(filename, "http://", 7)) == 0 || (strncmp(filename, "udp://", 6)) == 0 || (strncmp(filename, "rtp://", 6)) == 0  || (strncmp(filename, "https://", 8)) == 0 || (strncmp(filename, "mms://", 6)) == 0 || (strncmp(filename, "rtsp://", 7)) == 0 || (strncmp(filename, "rtspt://", 7)) == 0 )
+       if ( strstr(filename, "://") )
                m_sourceinfo.is_streaming = TRUE;
 
        gchar *uri;
@@ -330,7 +328,7 @@ eServiceMP3::eServiceMP3(eServiceReference ref)
 
        m_gst_playbin = gst_element_factory_make("playbin2", "playbin");
        if (!m_gst_playbin)
-               m_error_message = "failed to create GStreamer pipeline!\n";
+               m_errorInfo.error_message = "failed to create GStreamer pipeline!\n";
 
        g_object_set (G_OBJECT (m_gst_playbin), "uri", uri, NULL);
 
@@ -363,6 +361,10 @@ eServiceMP3::eServiceMP3(eServiceReference ref)
                        eDebug("eServiceMP3::subtitle uri: %s", g_filename_to_uri(srt_filename, NULL, NULL));
                        g_object_set (G_OBJECT (m_gst_playbin), "suburi", g_filename_to_uri(srt_filename, NULL, NULL), NULL);
                }
+               if ( m_sourceinfo.is_streaming )
+               {
+                       g_signal_connect (G_OBJECT (m_gst_playbin), "notify::source", G_CALLBACK (gstHTTPSourceSetAgent), this);
+               }
        } else
        {
                m_event((iPlayableService*)this, evUser+12);
@@ -370,7 +372,7 @@ eServiceMP3::eServiceMP3(eServiceReference ref)
                if (m_gst_playbin)
                        gst_object_unref(GST_OBJECT(m_gst_playbin));
 
-               eDebug("eServiceMP3::sorry, can't play: %s",m_error_message.c_str());
+               eDebug("eServiceMP3::sorry, can't play: %s",m_errorInfo.error_message.c_str());
                m_gst_playbin = 0;
        }
 
@@ -934,7 +936,7 @@ std::string eServiceMP3::getInfoString(int w)
                tag = "channel-mode";
                break;
        case sUser+12:
-               return m_error_message;
+               return m_errorInfo.error_message;
        default:
                return "";
        }
@@ -1164,18 +1166,18 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
                return;
        gchar *sourceName;
        GstObject *source;
-
        source = GST_MESSAGE_SRC(msg);
+       if (!GST_IS_OBJECT(source))
+               return;
        sourceName = gst_object_get_name(source);
 #if 0
+       gchar *string;
        if (gst_message_get_structure(msg))
-       {
-               gchar *string = gst_structure_to_string(gst_message_get_structure(msg));
-               eDebug("eServiceMP3::gst_message from %s: %s", sourceName, string);
-               g_free(string);
-       }
+               string = gst_structure_to_string(gst_message_get_structure(msg));
        else
-               eDebug("eServiceMP3::gst_message from %s: %s (without structure)", sourceName, GST_MESSAGE_TYPE_NAME(msg));
+               string = g_strdup(GST_MESSAGE_TYPE_NAME(msg));
+       eDebug("eTsRemoteSource::gst_message from %s: %s", sourceName, string);
+       g_free(string);
 #endif
        switch (GST_MESSAGE_TYPE (msg))
        {
@@ -1376,44 +1378,58 @@ void eServiceMP3::gstBusCall(GstBus *bus, GstMessage *msg)
                                g_free (g_lang);
                        }
                        m_event((iPlayableService*)this, evUpdatedEventInfo);
+
+                       if ( m_errorInfo.missing_codec != "" )
+                       {
+                               if ( m_errorInfo.missing_codec.find("video/") == 0 || ( m_errorInfo.missing_codec.find("audio/") == 0 && getNumberOfTracks() == 0 ) )
+                                       m_event((iPlayableService*)this, evUser+12);
+                       }
                        break;
                }
                case GST_MESSAGE_ELEMENT:
                {
-                       if ( gst_is_missing_plugin_message(msg) )
-                       {
-                               gchar *description = gst_missing_plugin_message_get_description(msg);
-                               if ( description )
-                               {
-                                       m_error_message = "GStreamer plugin " + (std::string)description + " not available!\n";
-                                       g_free(description);
-                                       m_event((iPlayableService*)this, evUser+12);
-                               }
-                       }
-                       else if (const GstStructure *msgstruct = gst_message_get_structure(msg))
+                       if (const GstStructure *msgstruct = gst_message_get_structure(msg))
                        {
-                               const gchar *eventname = gst_structure_get_name(msgstruct);
-                               if ( eventname )
+                               if ( gst_is_missing_plugin_message(msg) )
                                {
-                                       if (!strcmp(eventname, "eventSizeChanged") || !strcmp(eventname, "eventSizeAvail"))
-                                       {
-                                               gst_structure_get_int (msgstruct, "aspect_ratio", &m_aspect);
-                                               gst_structure_get_int (msgstruct, "width", &m_width);
-                                               gst_structure_get_int (msgstruct, "height", &m_height);
-                                               if (strstr(eventname, "Changed"))
-                                                       m_event((iPlayableService*)this, evVideoSizeChanged);
-                                       }
-                                       else if (!strcmp(eventname, "eventFrameRateChanged") || !strcmp(eventname, "eventFrameRateAvail"))
+                                       GstCaps *caps;
+                                       gst_structure_get (msgstruct, "detail", GST_TYPE_CAPS, &caps, NULL); 
+                                       std::string codec = (const char*) gst_caps_to_string(caps);
+                                       gchar *description = gst_missing_plugin_message_get_description(msg);
+                                       if ( description )
                                        {
-                                               gst_structure_get_int (msgstruct, "frame_rate", &m_framerate);
-                                               if (strstr(eventname, "Changed"))
-                                                       m_event((iPlayableService*)this, evVideoFramerateChanged);
+                                               eDebug("eServiceMP3::m_errorInfo.missing_codec = %s", codec.c_str());
+                                               m_errorInfo.error_message = "GStreamer plugin " + (std::string)description + " not available!\n";
+                                               m_errorInfo.missing_codec = codec.substr(0,(codec.find_first_of(',')));
+                                               g_free(description);
                                        }
-                                       else if (!strcmp(eventname, "eventProgressiveChanged") || !strcmp(eventname, "eventProgressiveAvail"))
+                                       gst_caps_unref(caps);
+                               }
+                               else
+                               {
+                                       const gchar *eventname = gst_structure_get_name(msgstruct);
+                                       if ( eventname )
                                        {
-                                               gst_structure_get_int (msgstruct, "progressive", &m_progressive);
-                                               if (strstr(eventname, "Changed"))
-                                                       m_event((iPlayableService*)this, evVideoProgressiveChanged);
+                                               if (!strcmp(eventname, "eventSizeChanged") || !strcmp(eventname, "eventSizeAvail"))
+                                               {
+                                                       gst_structure_get_int (msgstruct, "aspect_ratio", &m_aspect);
+                                                       gst_structure_get_int (msgstruct, "width", &m_width);
+                                                       gst_structure_get_int (msgstruct, "height", &m_height);
+                                                       if (strstr(eventname, "Changed"))
+                                                               m_event((iPlayableService*)this, evVideoSizeChanged);
+                                               }
+                                               else if (!strcmp(eventname, "eventFrameRateChanged") || !strcmp(eventname, "eventFrameRateAvail"))
+                                               {
+                                                       gst_structure_get_int (msgstruct, "frame_rate", &m_framerate);
+                                                       if (strstr(eventname, "Changed"))
+                                                               m_event((iPlayableService*)this, evVideoFramerateChanged);
+                                               }
+                                               else if (!strcmp(eventname, "eventProgressiveChanged") || !strcmp(eventname, "eventProgressiveAvail"))
+                                               {
+                                                       gst_structure_get_int (msgstruct, "progressive", &m_progressive);
+                                                       if (strstr(eventname, "Changed"))
+                                                               m_event((iPlayableService*)this, evVideoProgressiveChanged);
+                                               }
                                        }
                                }
                        }
@@ -1806,15 +1822,25 @@ PyObject *eServiceMP3::getSubtitleList()
        for (std::vector<subtitleStream>::iterator IterSubtitleStream(m_subtitleStreams.begin()); IterSubtitleStream != m_subtitleStreams.end(); ++IterSubtitleStream)
        {
                subtype_t type = IterSubtitleStream->type;
-               ePyObject tuple = PyTuple_New(5);
-//             eDebug("eServiceMP3::getSubtitleList idx=%i type=%i, code=%s", stream_idx, int(type), (IterSubtitleStream->language_code).c_str());
-               PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(2));
-               PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(stream_idx));
-               PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(int(type)));
-               PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(0));
-               PyTuple_SET_ITEM(tuple, 4, PyString_FromString((IterSubtitleStream->language_code).c_str()));
-               PyList_Append(l, tuple);
-               Py_DECREF(tuple);
+               switch(type)
+               {
+               case stUnknown:
+               case stVOB:
+               case stPGS:
+                       break;
+               default:
+               {
+                       ePyObject tuple = PyTuple_New(5);
+//                     eDebug("eServiceMP3::getSubtitleList idx=%i type=%i, code=%s", stream_idx, int(type), (IterSubtitleStream->language_code).c_str());
+                       PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(2));
+                       PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(stream_idx));
+                       PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(int(type)));
+                       PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(0));
+                       PyTuple_SET_ITEM(tuple, 4, PyString_FromString((IterSubtitleStream->language_code).c_str()));
+                       PyList_Append(l, tuple);
+                       Py_DECREF(tuple);
+               }
+               }
                stream_idx++;
        }
        eDebug("eServiceMP3::getSubtitleList finished");
@@ -1936,6 +1962,3 @@ void eServiceMP3::setPCMDelay(int delay)
        }
 }
 
-#else
-#warning gstreamer not available, not building media player
-#endif