+
+void eServiceMP3::gstCBsubtitleAvail(GstElement *appsink, gpointer user_data)
+{
+ eServiceMP3 *_this = (eServiceMP3*)user_data;
+ GstBuffer *buffer;
+ g_signal_emit_by_name (appsink, "pull-buffer", &buffer);
+ if (buffer)
+ {
+ GstFormat fmt = GST_FORMAT_TIME;
+ gint64 buf_pos = GST_BUFFER_TIMESTAMP(buffer);
+ gint64 duration_ns = GST_BUFFER_DURATION(buffer);
+ size_t len = GST_BUFFER_SIZE(buffer);
+ unsigned char line[len+1];
+ memcpy(line, GST_BUFFER_DATA(buffer), len);
+ line[len] = 0;
+// eDebug("got new subtitle @ buf_pos = %lld ns (in pts=%lld): '%s' ", buf_pos, buf_pos/11111, line);
+ if ( _this->m_subtitle_widget )
+ {
+ ePangoSubtitlePage page;
+ gRGB rgbcol(0xD0,0xD0,0xD0);
+ page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)line));
+ page.show_pts = buf_pos / 11111L;
+ page.m_timeout = duration_ns / 1000000;
+ _this->m_subtitle_pages.push_back(page);
+ _this->pushSubtitles();
+ }
+ }
+}
+
+void eServiceMP3::pushSubtitles()
+{
+ ePangoSubtitlePage page;
+ GstClockTime base_time;
+ pts_t running_pts;
+ GstElement *syncsink;
+ g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &syncsink, NULL);
+ GstClock *clock;
+ clock = gst_element_get_clock (syncsink);
+ while ( !m_subtitle_pages.empty() )
+ {
+ page = m_subtitle_pages.front();
+
+ base_time = gst_element_get_base_time (syncsink);
+ running_pts = gst_clock_get_time (clock) / 11111L;
+ gint64 diff_ms = ( page.show_pts - running_pts ) / 90;
+// eDebug("eServiceMP3::pushSubtitles show_pts = %lld running_pts = %lld diff = %lld", page.show_pts, running_pts, diff_ms);
+ if ( diff_ms > 20 )
+ {
+// eDebug("m_subtitle_sync_timer->start(%lld,1)", diff_ms);
+ m_subtitle_sync_timer->start(diff_ms, 1);
+ break;
+ }
+ else
+ {
+ m_subtitle_widget->setPage(page);
+ m_subtitle_pages.pop_front();
+ }
+ }
+ gst_object_unref (clock);
+ gst_object_unref (syncsink);
+}
+
+RESULT eServiceMP3::enableSubtitles(eWidget *parent, ePyObject tuple)
+{
+ ePyObject entry;
+ int tuplesize = PyTuple_Size(tuple);
+ int pid, type;
+ gint text_pid = 0;
+
+ if (!PyTuple_Check(tuple))
+ goto error_out;
+ if (tuplesize < 1)
+ goto error_out;
+ entry = PyTuple_GET_ITEM(tuple, 1);
+ if (!PyInt_Check(entry))
+ goto error_out;
+ pid = PyInt_AsLong(entry);
+ entry = PyTuple_GET_ITEM(tuple, 2);
+ if (!PyInt_Check(entry))
+ goto error_out;
+ type = PyInt_AsLong(entry);
+
+ g_object_set (G_OBJECT (m_gst_playbin), "current-text", pid, NULL);
+ m_currentSubtitleStream = pid;
+
+ m_subtitle_widget = new eSubtitleWidget(parent);
+ m_subtitle_widget->resize(parent->size()); /* full size */
+
+ g_object_get (G_OBJECT (m_gst_playbin), "current-text", &text_pid, NULL);
+
+ eDebug ("eServiceMP3::switched to subtitle stream %i", text_pid);
+ m_subtitle_pages.clear();
+
+ return 0;
+
+error_out:
+ eDebug("eServiceMP3::enableSubtitles needs a tuple as 2nd argument!\n"
+ "for gst subtitles (2, subtitle_stream_count, subtitle_type)");
+ return -1;
+}
+
+RESULT eServiceMP3::disableSubtitles(eWidget *parent)
+{
+ eDebug("eServiceMP3::disableSubtitles");
+ m_subtitle_pages.clear();
+ delete m_subtitle_widget;
+ m_subtitle_widget = 0;
+ return 0;
+}
+
+PyObject *eServiceMP3::getCachedSubtitle()
+{
+// eDebug("eServiceMP3::getCachedSubtitle");
+ Py_RETURN_NONE;
+}
+
+PyObject *eServiceMP3::getSubtitleList()
+{
+ eDebug("eServiceMP3::getSubtitleList");
+
+ ePyObject l = PyList_New(0);
+ int stream_count[sizeof(subtype_t)];
+ for ( unsigned int i = 0; i < sizeof(subtype_t); i++ )
+ stream_count[i] = 0;
+
+ for (std::vector<subtitleStream>::iterator IterSubtitleStream(m_subtitleStreams.begin()); IterSubtitleStream != m_subtitleStreams.end(); ++IterSubtitleStream)
+ {
+ subtype_t type = IterSubtitleStream->type;
+ ePyObject tuple = PyTuple_New(5);
+ PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(2));
+ PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(stream_count[type]));
+ 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_count[type]++;
+ }
+ return l;
+}
+
+RESULT eServiceMP3::streamed(ePtr<iStreamedService> &ptr)
+{
+ ptr = this;
+ return 0;
+}
+
+PyObject *eServiceMP3::getBufferCharge()
+{
+ ePyObject tuple = PyTuple_New(5);
+ PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(m_bufferInfo.bufferPercent));
+ PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(m_bufferInfo.avgInRate));
+ PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(m_bufferInfo.avgOutRate));
+ PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(m_bufferInfo.bufferingLeft));
+ PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong(m_buffer_size));
+ return tuple;
+}
+
+int eServiceMP3::setBufferSize(int size)
+{
+ m_buffer_size = size;
+ g_object_set (G_OBJECT (m_gst_playbin), "buffer-size", m_buffer_size, NULL);
+ return 0;
+}
+
+