#include <lib/dvb/tstools.h>
#include <lib/python/python.h>
+ /* for subtitles */
+#include <lib/gui/esubtitle.h>
+
#include <sys/vfs.h>
#include <byteswap.h>
#include <dvbsi++/event_information_section.h>
+#define INTERNAL_TELETEXT
+
#ifndef BYTE_ORDER
#error no byte order defined!
#endif
}
eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
- m_reference(ref), m_dvb_service(service), m_is_paused(0)
+ m_reference(ref), m_dvb_service(service), m_is_paused(0), m_current_audio_channel(-1)
{
m_is_primary = 1;
m_is_pvr = !m_reference.path.empty();
m_cuesheet_changed = 0;
m_cutlist_enabled = 1;
+
+ m_subtitle_widget = 0;
+
+ CONNECT(m_subtitle_sync_timer.timeout, eDVBServicePlay::checkSubtitleTiming);
}
eDVBServicePlay::~eDVBServicePlay()
{
+ delete m_subtitle_widget;
}
void eDVBServicePlay::gotNewEvent()
return m_is_pvr || m_timeshift_active;
}
-RESULT eDVBServicePlay::frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr)
+RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
{
ptr = this;
return 0;
return -1;
}
+RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
+{
+ ptr = this;
+ return 0;
+}
+
RESULT eDVBServicePlay::getName(std::string &name)
{
if (m_is_pvr)
}
}
return -1;
- case sIsCrypted: return program.isCrypted;
+ case sIsCrypted: return program.isCrypted();
case sVideoPID: if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
case sVideoType: if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
case sAudioPID: if (program.audioStreams.empty()) return -1; return program.audioStreams[m_current_audio_stream].pid;
int eDVBServicePlay::getCurrentChannel()
{
- int curChannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
- return curChannel == -1 ? STEREO : curChannel;
+ return m_current_audio_channel == -1 ? STEREO : m_current_audio_channel;
}
RESULT eDVBServicePlay::selectChannel(int i)
{
if (i < iAudioChannelSelection::LEFT || i > iAudioChannelSelection::RIGHT)
i = -1; // Stereo
- if (m_dvb_service->getCacheEntry(eDVBService::cACHANNEL) != i)
+ if (m_current_audio_channel != i)
{
- m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
+ if (m_dvb_service)
+ m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
+ m_current_audio_channel=i;
if (m_decoder)
m_decoder->setAudioChannel(i);
}
+ return 0;
}
-int eDVBServicePlay::getFrontendInfo(int w)
+int eDVBServiceBase::getFrontendInfo(int w)
{
- if (m_is_pvr)
- return 0;
eUsePtr<iDVBChannel> channel;
if(m_service_handler.getChannel(channel))
return 0;
return fe->readFrontendData(w);
}
-PyObject *eDVBServicePlay::getFrontendData(bool original)
+PyObject *eDVBServiceBase::getFrontendData(bool original)
{
PyObject *ret=0;
m_cue->setDecodingDemux(m_decode_demux, m_decoder);
#ifdef INTERNAL_TELETEXT
m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
+ m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
#endif
}
m_decoder->setSyncPCR(pcrpid);
else
m_decoder->setSyncPCR(-1);
-#ifndef INTERNAL_TELETEXT
+
m_decoder->setTextPID(tpid);
-#else
+
if (m_teletext_parser)
m_teletext_parser->start(tpid);
-#endif
if (!m_is_primary)
m_decoder->setTrickmode(1);
m_decoder->start();
+ m_current_audio_channel=achannel;
m_decoder->setAudioChannel(achannel);
// how we can do this better?
m_cue->commitSpans();
}
+RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, PyObject *entry)
+{
+ if (m_subtitle_widget)
+ disableSubtitles(parent);
+
+ if (!m_teletext_parser)
+ return -1;
+
+ if (!PyInt_Check(entry))
+ return -1;
+
+ m_subtitle_widget = new eSubtitleWidget(parent);
+ m_subtitle_widget->resize(parent->size()); /* full size */
+
+ int page = PyInt_AsLong(entry);
+
+ m_teletext_parser->setPage(page);
+
+ return 0;
+}
+
+RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
+{
+ delete m_subtitle_widget;
+ m_subtitle_widget = 0;
+ return 0;
+}
+
+PyObject *eDVBServicePlay::getSubtitleList()
+{
+ if (!m_teletext_parser)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ PyObject *l = PyList_New(0);
+
+ for (std::set<int>::iterator i(m_teletext_parser->m_found_subtitle_pages.begin()); i != m_teletext_parser->m_found_subtitle_pages.end(); ++i)
+ {
+ PyObject *tuple = PyTuple_New(2);
+ char desc[20];
+ sprintf(desc, "Page %x", *i);
+ PyTuple_SetItem(tuple, 0, PyString_FromString(desc));
+ PyTuple_SetItem(tuple, 1, PyInt_FromLong(*i));
+ PyList_Append(l, tuple);
+ }
+
+ return l;
+}
+
+void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
+{
+ if (m_subtitle_widget)
+ {
+ m_subtitle_pages.push_back(page);
+
+ checkSubtitleTiming();
+ }
+}
+
+void eDVBServicePlay::checkSubtitleTiming()
+{
+ while (1)
+ {
+ if (m_subtitle_pages.empty())
+ return;
+
+ eDVBTeletextSubtitlePage p = m_subtitle_pages.front();
+
+ pts_t pos = 0;
+
+ if (m_decoder)
+ m_decoder->getPTS(0, pos);
+
+ int diff = p.m_pts - pos;
+ if (diff < 0)
+ {
+ eDebug("[late (%d ms)]", -diff / 90);
+ diff = 0;
+ }
+ if (diff > 900000)
+ {
+ eDebug("[invalid]");
+ diff = 0;
+ }
+
+ if (!diff)
+ {
+ m_subtitle_widget->setPage(p);
+ m_subtitle_pages.pop_front();
+ } else
+ {
+ m_subtitle_sync_timer.start(diff / 90, 1);
+ break;
+ }
+ }
+}
+
DEFINE_REF(eDVBServicePlay)
eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");