+ if (sink)
+ {
+ while (m_subs_to_pull && m_subtitle_pages.size() < 2)
+ {
+ GstBuffer *buffer;
+ {
+ eSingleLocker l(m_subs_to_pull_lock);
+ --m_subs_to_pull;
+ g_signal_emit_by_name (sink, "pull-buffer", &buffer);
+ }
+ if (buffer)
+ {
+ gint64 buf_pos = GST_BUFFER_TIMESTAMP(buffer);
+ gint64 duration_ns = GST_BUFFER_DURATION(buffer);
+ size_t len = GST_BUFFER_SIZE(buffer);
+ eDebug("pullSubtitle m_subtitleStreams[m_currentSubtitleStream].type=%i",m_subtitleStreams[m_currentSubtitleStream].type);
+
+ if ( m_subtitleStreams[m_currentSubtitleStream].type )
+ {
+ if ( m_subtitleStreams[m_currentSubtitleStream].type < stVOB )
+ {
+ unsigned char line[len+1];
+ SubtitlePage page;
+ memcpy(line, GST_BUFFER_DATA(buffer), len);
+ line[len] = 0;
+ eDebug("got new text subtitle @ buf_pos = %lld ns (in pts=%lld): '%s' ", buf_pos, buf_pos/11111, line);
+ gRGB rgbcol(0xD0,0xD0,0xD0);
+ page.type = SubtitlePage::Pango;
+ page.pango_page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)line));
+ page.pango_page.m_show_pts = buf_pos / 11111L;
+ page.pango_page.m_timeout = duration_ns / 1000000;
+ m_subtitle_pages.push_back(page);
+ if (m_subtitle_pages.size()==1)
+ pushSubtitles();
+ }
+ else
+ {
+ eDebug("unsupported subpicture... ignoring");
+ }
+ }
+ gst_buffer_unref(buffer);
+ }
+ }
+ gst_object_unref(sink);
+ }
+ else
+ eDebug("no subtitle sink!");
+}
+
+void eServiceMP3::pushSubtitles()
+{
+ while ( !m_subtitle_pages.empty() )
+ {
+ SubtitlePage &frontpage = m_subtitle_pages.front();
+ pts_t running_pts;
+ gint64 diff_ms = 0;
+ gint64 show_pts = 0;
+
+ getPlayPosition(running_pts);
+
+ if (m_decoder_time_valid_state < 4) {
+ ++m_decoder_time_valid_state;
+ if (m_prev_decoder_time == running_pts)
+ m_decoder_time_valid_state = 0;
+ if (m_decoder_time_valid_state < 4) {
+// if (m_decoder_time_valid_state)
+// eDebug("%d: decoder time not valid! prev %lld, now %lld\n", m_decoder_time_valid_state, m_prev_decoder_time/90, running_pts/90);
+// else
+// eDebug("%d: decoder time not valid! now %lld\n", m_decoder_time_valid_state, running_pts/90);
+ m_subtitle_sync_timer->start(25, true);
+ m_prev_decoder_time = running_pts;
+ break;
+ }
+ }
+
+ if (frontpage.type == SubtitlePage::Pango)
+ show_pts = frontpage.pango_page.m_show_pts;
+
+ diff_ms = ( show_pts - running_pts ) / 90;
+ eDebug("check subtitle: decoder: %lld, show_pts: %lld, diff: %lld ms", running_pts/90, show_pts/90, diff_ms);
+
+ if ( diff_ms < -100 )
+ {
+ eDebug("subtitle too late... drop");
+ m_subtitle_pages.pop_front();
+ }
+ else if ( diff_ms > 20 )
+ {
+ eDebug("start timer");
+ m_subtitle_sync_timer->start(diff_ms, true);
+ break;
+ }
+ else // immediate show
+ {
+ if ( m_subtitle_widget )
+ {
+ eDebug("show!\n");
+ if ( frontpage.type == SubtitlePage::Pango)
+ m_subtitle_widget->setPage(frontpage.pango_page);
+ m_subtitle_widget->show();
+ }
+ m_subtitle_pages.pop_front();
+ }
+ }
+ if (m_subtitle_pages.empty())
+ pullSubtitle();
+}
+
+
+RESULT eServiceMP3::enableSubtitles(eWidget *parent, ePyObject tuple)
+{
+ eDebug ("eServiceMP3::enableSubtitles m_currentSubtitleStream=%i this=%p",m_currentSubtitleStream, this);
+ ePyObject entry;
+ int tuplesize = PyTuple_Size(tuple);
+ int pid, type;
+ gint text_pid = 0;
+ eSingleLocker l(m_subs_to_pull_lock);
+
+// GstPad *pad = 0;
+// g_signal_emit_by_name (m_gst_playbin, "get-text-pad", m_currentSubtitleStream, &pad);
+// gst_element_get_static_pad(m_gst_subtitlebin, "sink");
+// gulong subprobe_handler_id = gst_pad_add_buffer_probe (pad, G_CALLBACK (gstCBsubtitleDrop), NULL);
+
+ 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);
+
+ if (m_currentSubtitleStream != pid)
+ {
+ g_object_set (G_OBJECT (m_gst_playbin), "current-text", pid, NULL);
+ eDebug ("eServiceMP3::enableSubtitles g_object_set current-text = %i", pid);
+ m_currentSubtitleStream = pid;
+ m_subs_to_pull = 0;
+ m_prev_decoder_time = -1;
+ m_subtitle_pages.clear();
+ }
+
+ m_subtitle_widget = 0;
+ 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);
+// gst_pad_remove_buffer_probe (pad, subprobe_handler_id);
+
+ m_event((iPlayableService*)this, evUpdatedInfo);
+
+ 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;