#include <lib/dvb/dvb.h>
#include <lib/dvb/db.h>
+#include <lib/dvb/decoder.h>
+
+#include <lib/service/servicedvbrecord.h>
+#include <lib/dvb/metaparser.h>
+#include <lib/dvb/tstools.h>
+
+class eStaticServiceDVBInformation: public iStaticServiceInformation
+{
+ DECLARE_REF(eStaticServiceDVBInformation);
+public:
+ RESULT getName(const eServiceReference &ref, std::string &name);
+ int getLength(const eServiceReference &ref);
+};
+
+DEFINE_REF(eStaticServiceDVBInformation);
+
+RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std::string &name)
+{
+ eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
+ if ( !ref.name.empty() )
+ {
+ if (service.getParentTransportStreamID().get()) // linkage subservice
+ {
+ ePtr<iServiceHandler> service_center;
+ if (!eServiceCenter::getInstance(service_center))
+ {
+ eServiceReferenceDVB parent = service;
+ parent.setTransportStreamID( service.getParentTransportStreamID() );
+ parent.setServiceID( service.getParentServiceID() );
+ parent.setParentTransportStreamID(eTransportStreamID(0));
+ parent.setParentServiceID(eServiceID(0));
+ parent.name="";
+ ePtr<iStaticServiceInformation> service_info;
+ if (!service_center->info(parent, service_info))
+ {
+ if (!service_info->getName(parent, name))
+ {
+ // just show short name
+ unsigned int pos = name.find("\xc2\x86");
+ if ( pos != std::string::npos )
+ name.erase(0, pos+2);
+ pos = name.find("\xc2\x87");
+ if ( pos != std::string::npos )
+ name.erase(pos);
+ name+=" - ";
+ }
+ }
+ }
+ }
+ else
+ name="";
+ name += ref.name;
+ return 0;
+ }
+ else
+ return -1;
+}
+
+int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
+{
+ return -1;
+}
+
+class eStaticServiceDVBBouquetInformation: public iStaticServiceInformation
+{
+ DECLARE_REF(eStaticServiceDVBBouquetInformation);
+public:
+ RESULT getName(const eServiceReference &ref, std::string &name);
+ int getLength(const eServiceReference &ref);
+};
+
+DEFINE_REF(eStaticServiceDVBBouquetInformation);
+
+RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
+{
+ ePtr<iDVBChannelList> db;
+ ePtr<eDVBResourceManager> res;
+
+ int err;
+ if ((err = eDVBResourceManager::getInstance(res)) != 0)
+ {
+ eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
+ return err;
+ }
+ if ((err = res->getChannelList(db)) != 0)
+ {
+ eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
+ return err;
+ }
+
+ eBouquet *bouquet=0;
+ if ((err = db->getBouquet(ref, bouquet)) != 0)
+ {
+ eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
+ return -1;
+ }
+
+ if ( bouquet && bouquet->m_bouquet_name.length() )
+ {
+ name = bouquet->m_bouquet_name;
+ return 0;
+ }
+ else
+ return -1;
+}
+
+int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
+{
+ return -1;
+}
+
+class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
+{
+ DECLARE_REF(eStaticServiceDVBPVRInformation);
+ eServiceReference m_ref;
+ eDVBMetaParser m_parser;
+public:
+ eStaticServiceDVBPVRInformation(const eServiceReference &ref);
+ RESULT getName(const eServiceReference &ref, std::string &name);
+ int getLength(const eServiceReference &ref);
+
+ int getInfo(const eServiceReference &ref, int w);
+ std::string getInfoString(const eServiceReference &ref,int w);
+};
+
+DEFINE_REF(eStaticServiceDVBPVRInformation);
+
+eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref)
+{
+ m_ref = ref;
+ m_parser.parseFile(ref.path);
+}
+
+RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
+{
+ ASSERT(ref == m_ref);
+ name = m_parser.m_name.size() ? m_parser.m_name : ref.path;
+ return 0;
+}
+
+int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
+{
+ ASSERT(ref == m_ref);
+
+ eDVBTSTools tstools;
+
+ if (tstools.openFile(ref.path.c_str()))
+ return 0;
+
+ pts_t len;
+ if (tstools.calcLen(len))
+ return 0;
+
+ return len / 90000;
+}
+
+int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
+{
+ switch (w)
+ {
+ case iServiceInformation::sDescription:
+ return iServiceInformation::resIsString;
+ case iServiceInformation::sTimeCreate:
+ if (m_parser.m_time_create)
+ return m_parser.m_time_create;
+ else
+ return iServiceInformation::resNA;
+ default:
+ return iServiceInformation::resNA;
+ }
+}
+
+std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
+{
+ switch (w)
+ {
+ case iServiceInformation::sDescription:
+ return m_parser.m_description;
+ default:
+ return "";
+ }
+}
+
+class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
+{
+ DECLARE_REF(eDVBPVRServiceOfflineOperations);
+ eServiceReferenceDVB m_ref;
+public:
+ eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
+
+ RESULT deleteFromDisk(int simulate);
+ RESULT getListOfFilenames(std::list<std::string> &);
+};
+
+DEFINE_REF(eDVBPVRServiceOfflineOperations);
+
+eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
+{
+}
+
+RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
+{
+ if (simulate)
+ return 0;
+ else
+ {
+ std::list<std::string> res;
+ if (getListOfFilenames(res))
+ return -1;
+
+ /* TODO: deferred removing.. */
+ for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
+ {
+ eDebug("Removing %s...", i->c_str());
+ ::unlink(i->c_str());
+ }
+
+ return 0;
+ }
+}
+
+RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
+{
+ res.clear();
+ res.push_back(m_ref.path);
+ res.push_back(m_ref.path + ".meta");
+ return 0;
+}
DEFINE_REF(eServiceFactoryDVB)
{
ePtr<eServiceCenter> sc;
- eServiceCenter::getInstance(sc);
+ eServiceCenter::getPrivInstance(sc);
if (sc)
sc->addServiceFactory(eServiceFactoryDVB::id, this);
}
{
ePtr<eServiceCenter> sc;
- eServiceCenter::getInstance(sc);
+ eServiceCenter::getPrivInstance(sc);
if (sc)
sc->removeServiceFactory(eServiceFactoryDVB::id);
}
{
}
-RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list)
+RESULT eDVBServiceList::startQuery()
{
ePtr<iDVBChannelList> db;
ePtr<eDVBResourceManager> res;
return err;
}
- ePtr<iDVBChannelListQuery> query;
-
ePtr<eDVBChannelQuery> q;
- if (m_parent.path.size())
+ if (!m_parent.path.empty())
+ {
eDVBChannelQuery::compile(q, m_parent.path);
+ if (!q)
+ {
+ eDebug("compile query failed");
+ return err;
+ }
+ }
- if ((err = db->startQuery(query, q)) != 0)
+ if ((err = db->startQuery(m_query, q, m_parent)) != 0)
{
eDebug("startQuery failed");
return err;
}
-
+
+ return 0;
+}
+
+RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list)
+{
eServiceReferenceDVB ref;
- while (!query->getNextResult(ref))
+ if (!m_query)
+ return -1;
+
+ while (!m_query->getNextResult(ref))
list.push_back(ref);
return 0;
}
+RESULT eDVBServiceList::getNext(eServiceReference &ref)
+{
+ if (!m_query)
+ return -1;
+
+ return m_query->getNextResult((eServiceReferenceDVB&)ref);
+}
+
+int eDVBServiceList::compareLessEqual(const eServiceReference &a, const eServiceReference &b)
+{
+ return m_query->compareLessEqual((const eServiceReferenceDVB&)a, (const eServiceReferenceDVB&)b);
+}
+
+RESULT eDVBServiceList::startEdit(ePtr<iMutableServiceList> &res)
+{
+ if (m_parent.flags & eServiceReference::flagDirectory) // bouquet
+ {
+ ePtr<iDVBChannelList> db;
+ ePtr<eDVBResourceManager> resm;
+
+ if (eDVBResourceManager::getInstance(resm) || resm->getChannelList(db))
+ return -1;
+
+ if (db->getBouquet(m_parent, m_bouquet) != 0)
+ return -1;
+
+ res = this;
+
+ return 0;
+ }
+ res = 0;
+ return -1;
+}
+
+RESULT eDVBServiceList::addService(eServiceReference &ref)
+{
+ if (!m_bouquet)
+ return -1;
+ return m_bouquet->addService(ref);
+}
+
+RESULT eDVBServiceList::removeService(eServiceReference &ref)
+{
+ if (!m_bouquet)
+ return -1;
+ return m_bouquet->removeService(ref);
+}
+
+RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
+{
+ if (!m_bouquet)
+ return -1;
+ return m_bouquet->moveService(ref, pos);
+}
+
+RESULT eDVBServiceList::flushChanges()
+{
+ if (!m_bouquet)
+ return -1;
+ return m_bouquet->flushChanges();
+}
+
RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
{
+ ePtr<eDVBService> service;
+ int r = lookupService(service, ref);
+ if (r)
+ service = 0;
// check resources...
- ptr = new eDVBServicePlay(ref);
+ ptr = new eDVBServicePlay(ref, service);
return 0;
}
-RESULT eServiceFactoryDVB::record(const eServiceReference &, ePtr<iRecordableService> &ptr)
+RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
{
- ptr = 0;
- return -1;
+ if (ref.path.empty())
+ {
+ ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
+ return 0;
+ } else
+ {
+ ptr = 0;
+ return -1;
+ }
}
RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
{
- ptr = new eDVBServiceList(ref);
+ ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
+ if (list->startQuery())
+ {
+ ptr = 0;
+ return -1;
+ }
+
+ ptr = list;
return 0;
}
RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
{
- ptr = 0;
+ /* is a listable service? */
+ if ((ref.flags & eServiceReference::flagDirectory) == eServiceReference::flagDirectory) // bouquet
+ {
+ if ( !ref.name.empty() ) // satellites or providers list
+ ptr = new eStaticServiceDVBInformation;
+ else // a dvb bouquet
+ ptr = new eStaticServiceDVBBouquetInformation;
+ }
+ else if (!ref.path.empty()) /* do we have a PVR service? */
+ ptr = new eStaticServiceDVBPVRInformation(ref);
+ else // normal dvb service
+ {
+ ePtr<eDVBService> service;
+ if (lookupService(service, ref)) // no eDVBService avail for this reference ( Linkage Services... )
+ ptr = new eStaticServiceDVBInformation;
+ else
+ /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
+ ptr = service;
+ }
+ return 0;
+}
+
+RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
+{
+ if (ref.path.empty())
+ {
+ ptr = 0;
+ return -1;
+ } else
+ {
+ ptr = new eDVBPVRServiceOfflineOperations(ref);
+ return 0;
+ }
+}
+
+RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
+{
// TODO: handle the listing itself
// if (ref.... == -1) .. return "... bouquets ...";
// could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
return err;
}
- ePtr<eDVBService> service;
-
/* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
{
eDebug("getService failed!");
return err;
}
-
- /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
- ptr = service;
+
return 0;
}
-eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref):
- m_reference(ref)
+eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
+ m_reference(ref), m_dvb_service(service), m_service_handler(0), m_is_paused(0)
{
- CONNECT(m_serviceHandler.serviceEvent, eDVBServicePlay::serviceEvent);
- eDebug("DVB start (play)");
+ m_is_pvr = !ref.path.empty();
+ m_timeshift_enabled = 0;
+
+ CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
+ CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
}
eDVBServicePlay::~eDVBServicePlay()
{
- eDebug("DVB stop (play)");
+}
+
+void eDVBServicePlay::gotNewEvent()
+{
+#if 0
+ // debug only
+ ePtr<eServiceEvent> m_event_now, m_event_next;
+ getEvent(m_event_now, 0);
+ getEvent(m_event_next, 1);
+
+ if (m_event_now)
+ eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
+ if (m_event_next)
+ eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
+#endif
+ m_event((iPlayableService*)this, evUpdatedEventInfo);
}
void eDVBServicePlay::serviceEvent(int event)
{
- eDebug("service event %d", event);
switch (event)
{
+ case eDVBServicePMTHandler::eventTuned:
+ {
+ ePtr<iDVBDemux> m_demux;
+ if (!m_service_handler.getDemux(m_demux))
+ {
+ eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
+ int sid = ref.getParentServiceID().get();
+ if (!sid)
+ sid = ref.getServiceID().get();
+ if ( ref.getParentTransportStreamID().get() &&
+ ref.getParentTransportStreamID() != ref.getTransportStreamID() )
+ m_event_handler.startOther(m_demux, sid);
+ else
+ m_event_handler.start(m_demux, sid);
+ }
+ break;
+ }
+ case eDVBServicePMTHandler::eventTuneFailed:
+ {
+ eDebug("DVB service failed to tune");
+ m_event((iPlayableService*)this, evTuneFailed);
+ break;
+ }
case eDVBServicePMTHandler::eventNewProgramInfo:
{
- int vpid = -1, apid = -1, pcrpid = -1;
+ int vpid = -1, apid = -1, apidtype = -1, pcrpid = -1;
eDVBServicePMTHandler::program program;
- if (m_serviceHandler.getProgramInfo(program))
+ if (m_service_handler.getProgramInfo(program))
eDebug("getting program info failed.");
else
{
i != program.audioStreams.end(); ++i)
{
if (apid == -1)
+ {
apid = i->pid;
+ apidtype = i->type;
+ }
if (i != program.audioStreams.begin())
eDebugNoNewLine(", ");
eDebugNoNewLine("%04x", i->pid);
if (!m_decoder)
{
ePtr<iDVBDemux> demux;
- m_serviceHandler.getDemux(demux);
+ m_service_handler.getDemux(demux);
if (demux)
demux->getMPEGDecoder(m_decoder);
}
if (m_decoder)
{
m_decoder->setVideoPID(vpid);
- m_decoder->setAudioPID(apid, 0);
- m_decoder->setSyncPCR(pcrpid);
+ m_current_audio_stream = 0;
+ m_decoder->setAudioPID(apid, apidtype);
+ if (!m_is_pvr)
+ m_decoder->setSyncPCR(pcrpid);
+ else
+ m_decoder->setSyncPCR(-1);
m_decoder->start();
- }
+// how we can do this better?
+// update cache pid when the user changed the audio track or video track
+// TODO handling of difference audio types.. default audio types..
+ /* don't worry about non-existing services, nor pvr services */
+ if (m_dvb_service && !m_is_pvr)
+ {
+ if (apidtype == eDVBAudio::aMPEG)
+ {
+ m_dvb_service->setCachePID(eDVBService::cAPID, apid);
+ m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
+ }
+ else
+ {
+ m_dvb_service->setCachePID(eDVBService::cAPID, -1);
+ m_dvb_service->setCachePID(eDVBService::cAC3PID, apid);
+ }
+ m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
+ m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
+ }
+ }
+
+ m_event((iPlayableService*)this, evUpdatedInfo);
break;
}
}
RESULT eDVBServicePlay::start()
{
+ int r;
eDebug("starting DVB service");
- return m_serviceHandler.tune((eServiceReferenceDVB&)m_reference);
+ r = m_service_handler.tune((eServiceReferenceDVB&)m_reference);
+ eDebug("tune result: %d", r);
+ m_event(this, evStart);
+ return 0;
}
RESULT eDVBServicePlay::stop()
RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
{
- return -1;
+ connection = new eConnection((iPlayableService*)this, m_event.connect(event));
+ return 0;
}
RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
{
- // not yet possible, maybe later...
+ if (!m_is_pvr)
+ {
+ ptr = 0;
+ return -1;
+ }
+
+ ptr = this;
+ return 0;
+}
+
+RESULT eDVBServicePlay::setSlowMotion(int ratio)
+{
+ if (m_decoder)
+ return m_decoder->setSlowMotion(ratio);
+ else
+ return -1;
+}
+
+RESULT eDVBServicePlay::setFastForward(int ratio)
+{
+ if (m_decoder)
+ return m_decoder->setFastForward(ratio);
+ else
+ return -1;
+}
+
+RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
+{
+ if (m_is_pvr)
+ {
+ ptr = this;
+ return 0;
+ }
+
ptr = 0;
return -1;
}
+RESULT eDVBServicePlay::getLength(pts_t &len)
+{
+ ePtr<iDVBPVRChannel> pvr_channel;
+
+ if (m_service_handler.getPVRChannel(pvr_channel))
+ {
+ eDebug("getPVRChannel failed!");
+ return -1;
+ }
+
+ return pvr_channel->getLength(len);
+}
+
+RESULT eDVBServicePlay::pause()
+{
+ if (!m_is_paused && m_decoder)
+ {
+ m_is_paused = 1;
+ return m_decoder->freeze(0);
+ } else
+ return -1;
+}
+
+RESULT eDVBServicePlay::unpause()
+{
+ if (m_is_paused && m_decoder)
+ {
+ m_is_paused = 0;
+ return m_decoder->unfreeze();
+ } else
+ return -1;
+}
+
+RESULT eDVBServicePlay::seekTo(pts_t to)
+{
+ eDebug("eDVBServicePlay::seekTo: jump %lld", to);
+
+ ePtr<iDVBPVRChannel> pvr_channel;
+
+ if (m_service_handler.getPVRChannel(pvr_channel))
+ return -1;
+
+ ePtr<iDVBDemux> demux;
+ m_service_handler.getDemux(demux);
+ if (!demux)
+ return -1;
+
+ return pvr_channel->seekTo(demux, 0, to);
+}
+
+RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
+{
+ eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
+
+ ePtr<iDVBPVRChannel> pvr_channel;
+
+ if (m_service_handler.getPVRChannel(pvr_channel))
+ return -1;
+
+ to *= direction;
+
+ ePtr<iDVBDemux> demux;
+ m_service_handler.getDemux(demux);
+ if (!demux)
+ return -1;
+
+ return pvr_channel->seekTo(demux, 1, to);
+}
+
+RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
+{
+ ePtr<iDVBPVRChannel> pvr_channel;
+
+ if (m_service_handler.getPVRChannel(pvr_channel))
+ return -1;
+
+ ePtr<iDVBDemux> demux;
+ m_service_handler.getDemux(demux);
+ if (!demux)
+ return -1;
+
+ return pvr_channel->getCurrentPosition(demux, pos, 1);
+}
+
+RESULT eDVBServicePlay::setTrickmode(int trick)
+{
+ if (m_decoder)
+ m_decoder->setTrickmode(trick);
+ return 0;
+}
+
+RESULT eDVBServicePlay::frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr)
+{
+ ptr = this;
+ return 0;
+}
+
RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
{
ptr = this;
return 0;
}
-RESULT eDVBServicePlay::getName(const eServiceReference &ref, std::string &name)
+RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
+{
+ ptr = this;
+ return 0;
+}
+
+RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
+{
+ ptr = this;
+ return 0;
+}
+
+RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
+{
+ if (m_timeshift_enabled || !m_is_pvr)
+ {
+ ptr = this;
+ return 0;
+ }
+ ptr = 0;
+ return -1;
+}
+
+RESULT eDVBServicePlay::getName(std::string &name)
+{
+ if (m_dvb_service)
+ {
+ m_dvb_service->getName(m_reference, name);
+ if (name.empty())
+ name = "(...)";
+ }
+ else if (!m_reference.name.empty())
+ eStaticServiceDVBInformation().getName(m_reference, name);
+ else
+ name = "DVB service";
+ return 0;
+}
+
+RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
+{
+ return m_event_handler.getEvent(evt, nownext);
+}
+
+int eDVBServicePlay::getInfo(int w)
+{
+ eDVBServicePMTHandler::program program;
+
+ if (m_service_handler.getProgramInfo(program))
+ return -1;
+
+ switch (w)
+ {
+ case sAspect:
+ if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
+ {
+ ePtr<eServiceEvent> evt;
+ if (!m_event_handler.getEvent(evt, 0))
+ {
+ ePtr<eComponentData> data;
+ if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
+ {
+ if ( data->getStreamContent() == 1 )
+ {
+ switch(data->getComponentType())
+ {
+ // SD
+ case 1: // 4:3 SD PAL
+ case 2:
+ case 3: // 16:9 SD PAL
+ case 4: // > 16:9 PAL
+ case 5: // 4:3 SD NTSC
+ case 6:
+ case 7: // 16:9 SD NTSC
+ case 8: // > 16:9 NTSC
+
+ // HD
+ case 9: // 4:3 HD PAL
+ case 0xA:
+ case 0xB: // 16:9 HD PAL
+ case 0xC: // > 16:9 HD PAL
+ case 0xD: // 4:3 HD NTSC
+ case 0xE:
+ case 0xF: // 16:9 HD NTSC
+ case 0x10: // > 16:9 HD PAL
+ return data->getComponentType();
+ }
+ }
+ }
+ }
+ }
+ return -1;
+ case sIsCrypted: return program.isCrypted;
+ case sVideoPID: if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
+ case sAudioPID: if (program.audioStreams.empty()) return -1; return program.audioStreams[m_current_audio_stream].pid;
+ case sPCRPID: return program.pcrPid;
+ case sPMTPID: return program.pmtPid;
+ case sTXTPID: return -1;
+ case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
+ case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
+ case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
+ case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
+ case sProvider: if (!m_dvb_service) return -1; return -2;
+ default:
+ return -1;
+ }
+}
+
+std::string eDVBServicePlay::getInfoString(int w)
+{
+ switch (w)
+ {
+ case sProvider:
+ if (!m_dvb_service) return "";
+ return m_dvb_service->m_provider_name;
+ default:
+ return "";
+ }
+}
+
+int eDVBServicePlay::getNumberOfTracks()
+{
+ eDVBServicePMTHandler::program program;
+ if (m_service_handler.getProgramInfo(program))
+ return 0;
+ return program.audioStreams.size();
+}
+
+RESULT eDVBServicePlay::selectTrack(unsigned int i)
+{
+ int ret = selectAudioStream(i);
+
+ if (m_decoder->start())
+ return -5;
+
+ return ret;
+}
+
+RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
+{
+ eDVBServicePMTHandler::program program;
+
+ if (m_service_handler.getProgramInfo(program))
+ return -1;
+
+ if (i >= program.audioStreams.size())
+ return -2;
+
+ if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
+ info.m_description = "MPEG";
+ else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
+ info.m_description = "AC3";
+ else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
+ info.m_description = "DTS";
+ else
+ info.m_description = "???";
+
+ if (program.audioStreams[i].component_tag != -1)
+ {
+ ePtr<eServiceEvent> evt;
+ if (!m_event_handler.getEvent(evt, 0))
+ {
+ ePtr<eComponentData> data;
+ if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
+ info.m_language = data->getText();
+ }
+ }
+
+ if (info.m_language.empty())
+ info.m_language = program.audioStreams[i].language_code;
+
+ return 0;
+}
+
+int eDVBServicePlay::selectAudioStream(int i)
+{
+ eDVBServicePMTHandler::program program;
+
+ if (m_service_handler.getProgramInfo(program))
+ return -1;
+
+ if ((unsigned int)i >= program.audioStreams.size())
+ return -2;
+
+ if (!m_decoder)
+ return -3;
+
+ if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
+ return -4;
+
+ if (m_dvb_service && !m_is_pvr)
+ {
+ if (m_dvb_service && !m_is_pvr)
+ {
+ if (program.audioStreams[i].type == eDVBAudio::aMPEG)
+ {
+ m_dvb_service->setCachePID(eDVBService::cAPID, program.audioStreams[i].pid);
+ m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
+ }
+ else
+ {
+ m_dvb_service->setCachePID(eDVBService::cAPID, -1);
+ m_dvb_service->setCachePID(eDVBService::cAC3PID, program.audioStreams[i].pid);
+ }
+ }
+ }
+
+ m_current_audio_stream = i;
+
+ return 0;
+}
+
+int eDVBServicePlay::getFrontendInfo(int w)
+{
+ if (m_is_pvr)
+ return 0;
+ eUsePtr<iDVBChannel> channel;
+ if(m_service_handler.getChannel(channel))
+ return 0;
+ ePtr<iDVBFrontend> fe;
+ if(channel->getFrontend(fe))
+ return 0;
+ return fe->readFrontendData(w);
+}
+
+int eDVBServicePlay::getNumberOfSubservices()
+{
+ ePtr<eServiceEvent> evt;
+ if (!m_event_handler.getEvent(evt, 0))
+ return evt->getNumOfLinkageServices();
+ return 0;
+}
+
+RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
+{
+ ePtr<eServiceEvent> evt;
+ if (!m_event_handler.getEvent(evt, 0))
+ {
+ if (!evt->getLinkageService(sub, m_reference, n))
+ return 0;
+ }
+ sub.type=eServiceReference::idInvalid;
+ return -1;
+}
+
+RESULT eDVBServicePlay::startTimeshift()
+{
+ if (m_timeshift_enabled)
+ return -1;
+ eDebug("TIMESHIFT - start!");
+ return 0;
+}
+
+RESULT eDVBServicePlay::stopTimeshift()
{
- name = "DVB service";
+ if (!m_timeshift_enabled)
+ return -1;
+ m_timeshift_enabled = 0;
+ eDebug("timeshift disabled");
return 0;
}