eServiceCenter::getPrivInstance(sc);
if (sc)
- sc->addServiceFactory(eServiceFactoryMP3::id, this);
+ {
+ std::list<std::string> extensions;
+ extensions.push_back("mp3");
+ extensions.push_back("ogg");
+ extensions.push_back("mpg");
+ extensions.push_back("vob");
+ extensions.push_back("wav");
+ extensions.push_back("wave");
+ extensions.push_back("mkv");
+ extensions.push_back("avi");
+ sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
+ }
m_service_info = new eStaticServiceMP3Info();
}
int is_mpeg_ps = !(strcasecmp(ext, ".mpeg") && strcasecmp(ext, ".mpg") && strcasecmp(ext, ".vob") && strcasecmp(ext, ".bin"));
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;
+ 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/hda/track-", 18) || strcasecmp(ext, ".wav"));
- eDebug("filename: %s, is_mpeg_ps: %d, is_mpeg_ts: %d, is_video: %d, is_streaming: %d, is_mp3: %d", filename, is_mpeg_ps, is_mpeg_ts, is_video, is_streaming, is_mp3);
+ 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", filename, is_mpeg_ps, is_mpeg_ts, is_video, is_streaming, is_mp3, is_matroska, is_avi, is_AudioCD);
int is_audio = !is_video;
if (!m_gst_pipeline)
eWarning("failed to create pipeline");
- if (!is_streaming)
+ if (is_AudioCD)
+ {
+ 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;
+ }
+ if ( !is_streaming && !is_AudioCD )
source = gst_element_factory_make ("filesrc", "file-source");
- else
+ else if ( is_streaming )
{
source = gst_element_factory_make ("neonhttpsrc", "http-source");
if (source)
if (!source)
eWarning("failed to create %s", is_streaming ? "neonhttpsrc" : "filesrc");
- else
/* configure source */
+ else if (!is_AudioCD)
g_object_set (G_OBJECT (source), "location", filename, NULL);
+ else
+ {
+ int track = atoi(filename+18);
+ eDebug("play audio CD track #%i",track);
+ if (track > 0)
+ g_object_set (G_OBJECT (source), "track", track, NULL);
+ }
if (is_audio)
{
if (is_mpeg_ps)
mpegdemux = gst_element_factory_make("flupsdemux", "mpegdemux");
- else
+ else if (is_mpeg_ts)
mpegdemux = gst_element_factory_make("flutsdemux", "mpegdemux");
-
+ else if (is_matroska)
+ mpegdemux = gst_element_factory_make("matroskademux", "mpegdemux");
+ else if (is_avi)
+ mpegdemux = gst_element_factory_make("avidemux", "mpegdemux");
+
if (!mpegdemux)
{
eDebug("fluendo mpegdemux not available, falling back to mpegdemux\n");
eDebug("audio: %p, queue_audio %p, video %p, queue_video %p, mpegdemux %p", audio, queue_audio, video, queue_video, mpegdemux);
if (audio && queue_audio && video && queue_video && mpegdemux)
{
+ 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;
}
{
gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (m_gst_pipeline)), gstBusSyncHandler, this);
- if (is_audio)
+ if (is_AudioCD)
{
+ 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");
+
if (!is_mp3)
{
/* decodebin has dynamic pads. When they get created, we connect them to the audio bin */
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, decoder, NULL);
+ source, queue_audio, decoder, NULL);
if (filter)
{
g_signal_connect (filter, "pad-added", G_CALLBACK(gstCBfilterPadAdded), this);
} else
/* 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(source, decoder);
+ gst_element_link_many(source, queue_audio, decoder, NULL);
/* create audio bin with the audioconverter, the capsfilter and the audiosink */
m_gst_audio = gst_bin_new ("audiobin");
- GstPad *audiopad = gst_element_get_pad (conv, "sink");
+ GstPad *audiopad = gst_element_get_static_pad (conv, "sink");
gst_bin_add_many(GST_BIN(m_gst_audio), conv, flt, sink, (char*)0);
gst_element_link_many(conv, flt, sink, (char*)0);
gst_element_add_pad(m_gst_audio, gst_ghost_pad_new ("sink", audiopad));
/* 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, m_gst_audio);
- } else
+ } else /* is_video */
{
gst_bin_add_many(GST_BIN(m_gst_pipeline), source, mpegdemux, audio, queue_audio, video, queue_video, NULL);
gst_element_link(source, mpegdemux);
RESULT eServiceMP3::getName(std::string &name)
{
name = m_filename;
- int n = name.rfind('/');
+ size_t n = name.rfind('/');
if (n != std::string::npos)
name = name.substr(n + 1);
return 0;
int eServiceMP3::getInfo(int w)
{
+ gchar *tag = 0;
+
switch (w)
{
case sTitle:
case sTracknumber:
case sGenre:
return resIsString;
-
+ case sCurrentTitle:
+ tag = GST_TAG_TRACK_NUMBER;
+ break;
+ case sTotalTitles:
+ tag = GST_TAG_TRACK_COUNT;
+ break;
default:
return resNA;
}
+
+ if (!m_stream_tags || !tag)
+ return 0;
+
+ guint value;
+ if (gst_tag_list_get_uint(m_stream_tags, tag, &value))
+ return (int) value;
+
+ return 0;
+
}
std::string eServiceMP3::getInfoString(int w)
{
if (msg)
{
- gchar *string = gst_structure_to_string(gst_message_get_structure(msg));
- eDebug("gst_message: %s", string);
- g_free(string);
+ if (gst_message_get_structure(msg))
+ {
+ gchar *string = gst_structure_to_string(gst_message_get_structure(msg));
+ eDebug("gst_message: %s", string);
+ g_free(string);
+ }
+ else
+ eDebug("gst_message: %s (without structure)", GST_MESSAGE_TYPE_NAME(msg));
}
switch (GST_MESSAGE_TYPE (msg))
void eServiceMP3::gstCBpadAdded(GstElement *decodebin, GstPad *pad, gpointer user_data)
{
eServiceMP3 *_this = (eServiceMP3*)user_data;
-
gchar *name;
name = gst_pad_get_name (pad);
g_print ("A new pad %s was created\n", name);
- if (!strncmp(name, "audio_", 6)) // mpegdemux uses video_nn with n=0,1,.., flupsdemux uses stream id
- gst_pad_link(pad, gst_element_get_pad (_this->m_gst_audioqueue, "sink"));
- if (!strncmp(name, "video_", 6))
- gst_pad_link(pad, gst_element_get_pad (_this->m_gst_videoqueue, "sink"));
+ GstPad *sinkpad;
+
+ if (g_strrstr(name,"audio")) // mpegdemux uses video_nn with n=0,1,.., flupsdemux uses stream id
+ gst_pad_link(pad, gst_element_get_static_pad (_this->m_gst_audioqueue, "sink"));
+ if (g_strrstr(name,"video"))
+ gst_pad_link(pad, gst_element_get_static_pad (_this->m_gst_videoqueue, "sink"));
g_free (name);
-
}
void eServiceMP3::gstCBfilterPadAdded(GstElement *filter, GstPad *pad, gpointer user_data)
{
eServiceMP3 *_this = (eServiceMP3*)user_data;
- gst_pad_link(pad, gst_element_get_pad (_this->m_decoder, "sink"));
+ gst_pad_link(pad, gst_element_get_static_pad (_this->m_decoder, "sink"));
}
void eServiceMP3::gstCBnewPad(GstElement *decodebin, GstPad *pad, gboolean last, gpointer user_data)
GstPad *audiopad;
/* only link once */
- audiopad = gst_element_get_pad (_this->m_gst_audio, "sink");
- if (GST_PAD_IS_LINKED (audiopad)) {
+ audiopad = gst_element_get_static_pad (_this->m_gst_audio, "sink");
+ if ( !audiopad || GST_PAD_IS_LINKED (audiopad)) {
eDebug("audio already linked!");
g_object_unref (audiopad);
return;