8f2889822cea57b17552bb54782e411ff296834f
[enigma2.git] / lib / service / servicedvb.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/base/object.h>
3 #include <string>
4 #include <lib/service/servicedvb.h>
5 #include <lib/service/service.h>
6 #include <lib/base/init_num.h>
7 #include <lib/base/init.h>
8 #include <lib/base/nconfig.h> // access to python config
9 #include <lib/dvb/dvb.h>
10 #include <lib/dvb/db.h>
11 #include <lib/dvb/decoder.h>
12
13 #include <lib/components/file_eraser.h>
14 #include <lib/service/servicedvbrecord.h>
15 #include <lib/service/event.h>
16 #include <lib/dvb/metaparser.h>
17 #include <lib/dvb/tstools.h>
18 #include <lib/python/python.h>
19
20                 /* for subtitles */
21 #include <lib/gui/esubtitle.h>
22
23 #include <sys/vfs.h>
24
25 #include <byteswap.h>
26 #include <netinet/in.h>
27
28 #include <dvbsi++/event_information_section.h>
29
30 #define INTERNAL_TELETEXT
31
32 #ifndef BYTE_ORDER
33 #error no byte order defined!
34 #endif
35
36 #define TSPATH "/media/hdd"
37
38 class eStaticServiceDVBInformation: public iStaticServiceInformation
39 {
40         DECLARE_REF(eStaticServiceDVBInformation);
41 public:
42         RESULT getName(const eServiceReference &ref, std::string &name);
43         int getLength(const eServiceReference &ref);
44 };
45
46 DEFINE_REF(eStaticServiceDVBInformation);
47
48 RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std::string &name)
49 {
50         eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
51         if ( !ref.name.empty() )
52         {
53                 if (service.getParentTransportStreamID().get()) // linkage subservice
54                 {
55                         ePtr<iServiceHandler> service_center;
56                         if (!eServiceCenter::getInstance(service_center))
57                         {
58                                 eServiceReferenceDVB parent = service;
59                                 parent.setTransportStreamID( service.getParentTransportStreamID() );
60                                 parent.setServiceID( service.getParentServiceID() );
61                                 parent.setParentTransportStreamID(eTransportStreamID(0));
62                                 parent.setParentServiceID(eServiceID(0));
63                                 parent.name="";
64                                 ePtr<iStaticServiceInformation> service_info;
65                                 if (!service_center->info(parent, service_info))
66                                 {
67                                         if (!service_info->getName(parent, name))
68                                         {
69                                                 // just show short name
70                                                 unsigned int pos = name.find("\xc2\x86");
71                                                 if ( pos != std::string::npos )
72                                                         name.erase(0, pos+2);
73                                                 pos = name.find("\xc2\x87");
74                                                 if ( pos != std::string::npos )
75                                                         name.erase(pos);
76                                                 name+=" - ";
77                                         }
78                                 }
79                         }
80                 }
81                 else
82                         name="";
83                 name += ref.name;
84                 return 0;
85         }
86         else
87                 return -1;
88 }
89
90 int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
91 {
92         return -1;
93 }
94
95 class eStaticServiceDVBBouquetInformation: public iStaticServiceInformation
96 {
97         DECLARE_REF(eStaticServiceDVBBouquetInformation);
98 public:
99         RESULT getName(const eServiceReference &ref, std::string &name);
100         int getLength(const eServiceReference &ref);
101 };
102
103 DEFINE_REF(eStaticServiceDVBBouquetInformation);
104
105 RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
106 {
107         ePtr<iDVBChannelList> db;
108         ePtr<eDVBResourceManager> res;
109
110         int err;
111         if ((err = eDVBResourceManager::getInstance(res)) != 0)
112         {
113                 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
114                 return err;
115         }
116         if ((err = res->getChannelList(db)) != 0)
117         {
118                 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
119                 return err;
120         }
121
122         eBouquet *bouquet=0;
123         if ((err = db->getBouquet(ref, bouquet)) != 0)
124         {
125                 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
126                 return -1;
127         }
128
129         if ( bouquet && bouquet->m_bouquet_name.length() )
130         {
131                 name = bouquet->m_bouquet_name;
132                 return 0;
133         }
134         else
135                 return -1;
136 }
137
138 int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
139 {
140         return -1;
141 }
142
143 class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
144 {
145         DECLARE_REF(eStaticServiceDVBPVRInformation);
146         eServiceReference m_ref;
147         eDVBMetaParser m_parser;
148 public:
149         eStaticServiceDVBPVRInformation(const eServiceReference &ref);
150         RESULT getName(const eServiceReference &ref, std::string &name);
151         int getLength(const eServiceReference &ref);
152         
153         int getInfo(const eServiceReference &ref, int w);
154         std::string getInfoString(const eServiceReference &ref,int w);
155 };
156
157 DEFINE_REF(eStaticServiceDVBPVRInformation);
158
159 eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref)
160 {
161         m_ref = ref;
162         m_parser.parseFile(ref.path);
163 }
164
165 RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
166 {
167         ASSERT(ref == m_ref);
168         name = m_parser.m_name.size() ? m_parser.m_name : ref.path;
169         return 0;
170 }
171
172 int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
173 {
174         ASSERT(ref == m_ref);
175         
176         eDVBTSTools tstools;
177         
178         if (tstools.openFile(ref.path.c_str()))
179                 return 0;
180
181         pts_t len;
182         if (tstools.calcLen(len))
183                 return 0;
184
185         return len / 90000;
186 }
187
188 int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
189 {
190         switch (w)
191         {
192         case iServiceInformation::sDescription:
193                 return iServiceInformation::resIsString;
194         case iServiceInformation::sServiceref:
195                 return iServiceInformation::resIsString;
196         case iServiceInformation::sTimeCreate:
197                 if (m_parser.m_time_create)
198                         return m_parser.m_time_create;
199                 else
200                         return iServiceInformation::resNA;
201         default:
202                 return iServiceInformation::resNA;
203         }
204 }
205
206 std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
207 {
208         switch (w)
209         {
210         case iServiceInformation::sDescription:
211                 return m_parser.m_description;
212         case iServiceInformation::sServiceref:
213                 return m_parser.m_ref.toString();
214         default:
215                 return "";
216         }
217 }
218
219 class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
220 {
221         DECLARE_REF(eDVBPVRServiceOfflineOperations);
222         eServiceReferenceDVB m_ref;
223 public:
224         eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
225         
226         RESULT deleteFromDisk(int simulate);
227         RESULT getListOfFilenames(std::list<std::string> &);
228 };
229
230 DEFINE_REF(eDVBPVRServiceOfflineOperations);
231
232 eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
233 {
234 }
235
236 RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
237 {
238         if (simulate)
239                 return 0;
240         else
241         {
242                 std::list<std::string> res;
243                 if (getListOfFilenames(res))
244                         return -1;
245                 
246                 eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
247                 if (!eraser)
248                         eDebug("FATAL !! can't get background file eraser");
249                 
250                 for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
251                 {
252                         eDebug("Removing %s...", i->c_str());
253                         if (eraser)
254                                 eraser->erase(i->c_str());
255                         else
256                                 ::unlink(i->c_str());
257                 }
258                 
259                 return 0;
260         }
261 }
262
263 RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
264 {
265         res.clear();
266         res.push_back(m_ref.path);
267
268 // handling for old splitted recordings (enigma 1)
269         char buf[255];
270         int slice=1;
271         while(true)
272         {
273                 snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
274                 struct stat s;
275                 if (stat(buf, &s) < 0)
276                         break;
277                 res.push_back(buf);
278         }       
279
280         res.push_back(m_ref.path + ".meta");
281         res.push_back(m_ref.path + ".ap");
282         res.push_back(m_ref.path + ".cuts");
283         std::string tmp = m_ref.path;
284         tmp.erase(m_ref.path.length()-3);
285         res.push_back(tmp + ".eit");
286         return 0;
287 }
288
289 DEFINE_REF(eServiceFactoryDVB)
290
291 eServiceFactoryDVB::eServiceFactoryDVB()
292 {
293         ePtr<eServiceCenter> sc;
294         
295         eServiceCenter::getPrivInstance(sc);
296         if (sc)
297                 sc->addServiceFactory(eServiceFactoryDVB::id, this);
298 }
299
300 eServiceFactoryDVB::~eServiceFactoryDVB()
301 {
302         ePtr<eServiceCenter> sc;
303         
304         eServiceCenter::getPrivInstance(sc);
305         if (sc)
306                 sc->removeServiceFactory(eServiceFactoryDVB::id);
307 }
308
309 DEFINE_REF(eDVBServiceList);
310
311 eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent)
312 {
313 }
314
315 eDVBServiceList::~eDVBServiceList()
316 {
317 }
318
319 RESULT eDVBServiceList::startQuery()
320 {
321         ePtr<iDVBChannelList> db;
322         ePtr<eDVBResourceManager> res;
323         
324         int err;
325         if ((err = eDVBResourceManager::getInstance(res)) != 0)
326         {
327                 eDebug("no resource manager");
328                 return err;
329         }
330         if ((err = res->getChannelList(db)) != 0)
331         {
332                 eDebug("no channel list");
333                 return err;
334         }
335         
336         ePtr<eDVBChannelQuery> q;
337         
338         if (!m_parent.path.empty())
339         {
340                 eDVBChannelQuery::compile(q, m_parent.path);
341                 if (!q)
342                 {
343                         eDebug("compile query failed");
344                         return err;
345                 }
346         }
347         
348         if ((err = db->startQuery(m_query, q, m_parent)) != 0)
349         {
350                 eDebug("startQuery failed");
351                 return err;
352         }
353
354         return 0;
355 }
356
357 RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
358 {
359         eServiceReferenceDVB ref;
360         
361         if (!m_query)
362                 return -1;
363         
364         while (!m_query->getNextResult(ref))
365                 list.push_back(ref);
366
367         if (sorted)
368                 list.sort(iListableServiceCompare(this));
369
370         return 0;
371 }
372
373 //   The first argument of this function is a format string to specify the order and
374 //   the content of the returned list
375 //   useable format options are
376 //   R = Service Reference (as swig object .. this is very slow)
377 //   S = Service Reference (as python string object .. same as ref.toString())
378 //   N = Service Name (as python string object)
379 //   when exactly one return value per service is selected in the format string,
380 //   then each value is directly a list entry
381 //   when more than one value is returned per service, then the list is a list of
382 //   python tuples
383 //   unknown format string chars are returned as python None values !
384 PyObject *eDVBServiceList::getContent(const char* format, bool sorted)
385 {
386         PyObject *ret=0;
387         std::list<eServiceReference> tmplist;
388         int retcount=1;
389
390         if (!format || !(retcount=strlen(format)))
391                 format = "R"; // just return service reference swig object ...
392
393         if (!getContent(tmplist, sorted))
394         {
395                 int services=tmplist.size();
396                 ePtr<iStaticServiceInformation> sptr;
397                 eServiceCenterPtr service_center;
398
399                 if (strchr(format, 'N'))
400                         eServiceCenter::getPrivInstance(service_center);
401
402                 ret = PyList_New(services);
403                 std::list<eServiceReference>::iterator it(tmplist.begin());
404
405                 for (int cnt=0; cnt < services; ++cnt)
406                 {
407                         eServiceReference &ref=*it++;
408                         PyObject *tuple = retcount > 1 ? PyTuple_New(retcount) : 0;
409                         for (int i=0; i < retcount; ++i)
410                         {
411                                 PyObject *tmp=0;
412                                 switch(format[i])
413                                 {
414                                 case 'R':  // service reference (swig)object
415                                         tmp = New_eServiceReference(ref);
416                                         break;
417                                 case 'S':  // service reference string
418                                         tmp = PyString_FromString(ref.toString().c_str());
419                                         break;
420                                 case 'N':  // service name
421                                         if (service_center)
422                                         {
423                                                 service_center->info(ref, sptr);
424                                                 if (sptr)
425                                                 {
426                                                         std::string name;
427                                                         sptr->getName(ref, name);
428                                                         if (name.length())
429                                                                 tmp = PyString_FromString(name.c_str());
430                                                 }
431                                         }
432                                         if (!tmp)
433                                                 tmp = PyString_FromString("<n/a>");
434                                         break;
435                                 default:
436                                         if (tuple)
437                                         {
438                                                 tmp = Py_None;
439                                                 Py_INCREF(Py_None);
440                                         }
441                                         break;
442                                 }
443                                 if (tmp)
444                                 {
445                                         if (tuple)
446                                                 PyTuple_SET_ITEM(tuple, i, tmp);
447                                         else
448                                                 PyList_SET_ITEM(ret, cnt, tmp);
449                                 }
450                         }
451                         if (tuple)
452                                 PyList_SET_ITEM(ret, cnt, tuple);
453                 }
454         }
455         return ret ? ret : PyList_New(0);
456 }
457
458 RESULT eDVBServiceList::getNext(eServiceReference &ref)
459 {
460         if (!m_query)
461                 return -1;
462         
463         return m_query->getNextResult((eServiceReferenceDVB&)ref);
464 }
465
466 int eDVBServiceList::compareLessEqual(const eServiceReference &a, const eServiceReference &b)
467 {
468         return m_query->compareLessEqual((const eServiceReferenceDVB&)a, (const eServiceReferenceDVB&)b);
469 }
470
471 RESULT eDVBServiceList::startEdit(ePtr<iMutableServiceList> &res)
472 {
473         if (m_parent.flags & eServiceReference::flagDirectory) // bouquet
474         {
475                 ePtr<iDVBChannelList> db;
476                 ePtr<eDVBResourceManager> resm;
477
478                 if (eDVBResourceManager::getInstance(resm) || resm->getChannelList(db))
479                         return -1;
480
481                 if (db->getBouquet(m_parent, m_bouquet) != 0)
482                         return -1;
483
484                 res = this;
485                 
486                 return 0;
487         }
488         res = 0;
489         return -1;
490 }
491
492 RESULT eDVBServiceList::addService(eServiceReference &ref)
493 {
494         if (!m_bouquet)
495                 return -1;
496         return m_bouquet->addService(ref);
497 }
498
499 RESULT eDVBServiceList::removeService(eServiceReference &ref)
500 {
501         if (!m_bouquet)
502                 return -1;
503         return m_bouquet->removeService(ref);
504 }
505
506 RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
507 {
508         if (!m_bouquet)
509                 return -1;
510         return m_bouquet->moveService(ref, pos);
511 }
512
513 RESULT eDVBServiceList::flushChanges()
514 {
515         if (!m_bouquet)
516                 return -1;
517         return m_bouquet->flushChanges();
518 }
519
520 RESULT eDVBServiceList::setListName(const std::string &name)
521 {
522         if (!m_bouquet)
523                 return -1;
524         return m_bouquet->setListName(name);
525 }
526
527 RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
528 {
529         ePtr<eDVBService> service;
530         int r = lookupService(service, ref);
531         if (r)
532                 service = 0;
533                 // check resources...
534         ptr = new eDVBServicePlay(ref, service);
535         return 0;
536 }
537
538 RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
539 {
540         if (ref.path.empty())
541         {
542                 ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
543                 return 0;
544         } else
545         {
546                 ptr = 0;
547                 return -1;
548         }
549 }
550
551 RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
552 {
553         ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
554         if (list->startQuery())
555         {
556                 ptr = 0;
557                 return -1;
558         }
559         
560         ptr = list;
561         return 0;
562 }
563
564 RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
565 {
566         /* is a listable service? */
567         if ((ref.flags & eServiceReference::flagDirectory) == eServiceReference::flagDirectory) // bouquet
568         {
569                 if ( !ref.name.empty() )  // satellites or providers list
570                         ptr = new eStaticServiceDVBInformation;
571                 else // a dvb bouquet
572                         ptr = new eStaticServiceDVBBouquetInformation;
573         }
574         else if (!ref.path.empty()) /* do we have a PVR service? */
575                 ptr = new eStaticServiceDVBPVRInformation(ref);
576         else // normal dvb service
577         {
578                 ePtr<eDVBService> service;
579                 if (lookupService(service, ref)) // no eDVBService avail for this reference ( Linkage Services... )
580                         ptr = new eStaticServiceDVBInformation;
581                 else
582                         /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
583                         ptr = service;
584         }
585         return 0;
586 }
587
588 RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
589 {
590         if (ref.path.empty())
591         {
592                 ptr = 0;
593                 return -1;
594         } else
595         {
596                 ptr = new eDVBPVRServiceOfflineOperations(ref);
597                 return 0;
598         }
599 }
600
601 RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
602 {
603                         // TODO: handle the listing itself
604         // if (ref.... == -1) .. return "... bouquets ...";
605         // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
606                         // TODO: cache
607         ePtr<iDVBChannelList> db;
608         ePtr<eDVBResourceManager> res;
609         
610         int err;
611         if ((err = eDVBResourceManager::getInstance(res)) != 0)
612         {
613                 eDebug("no resource manager");
614                 return err;
615         }
616         if ((err = res->getChannelList(db)) != 0)
617         {
618                 eDebug("no channel list");
619                 return err;
620         }
621         
622                 /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
623         if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
624         {
625                 eDebug("getService failed!");
626                 return err;
627         }
628
629         return 0;
630 }
631
632 eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service): 
633         m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
634 {
635         m_is_primary = 1;
636         m_is_pvr = !m_reference.path.empty();
637         
638         m_timeshift_enabled = m_timeshift_active = 0;
639         m_skipmode = 0;
640         
641         CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
642         CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
643         CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
644
645         m_cuesheet_changed = 0;
646         m_cutlist_enabled = 1;
647         
648         m_subtitle_widget = 0;
649         
650         CONNECT(m_subtitle_sync_timer.timeout, eDVBServicePlay::checkSubtitleTiming);
651 }
652
653 eDVBServicePlay::~eDVBServicePlay()
654 {
655         delete m_subtitle_widget;
656 }
657
658 void eDVBServicePlay::gotNewEvent()
659 {
660 #if 0
661                 // debug only
662         ePtr<eServiceEvent> m_event_now, m_event_next;
663         getEvent(m_event_now, 0);
664         getEvent(m_event_next, 1);
665
666         if (m_event_now)
667                 eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
668         if (m_event_next)
669                 eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
670 #endif
671         m_event((iPlayableService*)this, evUpdatedEventInfo);
672 }
673
674 void eDVBServicePlay::serviceEvent(int event)
675 {
676         switch (event)
677         {
678         case eDVBServicePMTHandler::eventTuned:
679         {
680                 ePtr<iDVBDemux> m_demux;
681                 if (!m_service_handler.getDataDemux(m_demux))
682                 {
683                         eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
684                         int sid = ref.getParentServiceID().get();
685                         if (!sid)
686                                 sid = ref.getServiceID().get();
687                         if ( ref.getParentTransportStreamID().get() &&
688                                 ref.getParentTransportStreamID() != ref.getTransportStreamID() )
689                                 m_event_handler.startOther(m_demux, sid);
690                         else
691                                 m_event_handler.start(m_demux, sid);
692                 }
693                 break;
694         }
695         case eDVBServicePMTHandler::eventTuneFailed:
696         {
697                 eDebug("DVB service failed to tune");
698                 m_event((iPlayableService*)this, evTuneFailed);
699                 break;
700         }
701         case eDVBServicePMTHandler::eventNewProgramInfo:
702         {
703                 eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
704                 if (m_timeshift_enabled)
705                         updateTimeshiftPids();
706                 if (!m_timeshift_active)
707                         updateDecoder();
708                 if (m_first_program_info && m_is_pvr)
709                 {
710                         m_first_program_info = 0;
711                         seekTo(0);
712                 }
713                 m_event((iPlayableService*)this, evUpdatedInfo);
714                 break;
715         }
716         case eDVBServicePMTHandler::eventEOF:
717                 m_event((iPlayableService*)this, evEOF);
718                 break;
719         case eDVBServicePMTHandler::eventSOF:
720                 m_event((iPlayableService*)this, evSOF);
721                 break;
722         }
723 }
724
725 void eDVBServicePlay::serviceEventTimeshift(int event)
726 {
727         switch (event)
728         {
729         case eDVBServicePMTHandler::eventNewProgramInfo:
730                 if (m_timeshift_active)
731                         updateDecoder();
732                 break;
733         case eDVBServicePMTHandler::eventSOF:
734                 m_event((iPlayableService*)this, evSOF);
735                 break;
736         case eDVBServicePMTHandler::eventEOF:
737                 switchToLive();
738                 break;
739         }
740 }
741
742 RESULT eDVBServicePlay::start()
743 {
744         int r;
745                 /* in pvr mode, we only want to use one demux. in tv mode, we're using 
746                    two (one for decoding, one for data source), as we must be prepared
747                    to start recording from the data demux. */
748         if (m_is_pvr)
749                 m_cue = new eCueSheet();
750
751         m_first_program_info = 1;
752         eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference;
753         r = m_service_handler.tune(service, m_is_pvr, m_cue);
754
755         // get back correct service reference (after parsing of recording meta files)
756         m_service_handler.getServiceReference(service);
757
758                 /* inject EIT if there is a stored one */
759         if (m_is_pvr)
760         {
761                 std::string filename = service.path;
762                 filename.erase(filename.length()-2, 2);
763                 filename+="eit";
764                 int fd = ::open( filename.c_str(), O_RDONLY );
765                 if ( fd > -1 )
766                 {
767                         __u8 buf[4096];
768                         int rd = ::read(fd, buf, 4096);
769                         ::close(fd);
770                         if ( rd > 12 /*EIT_LOOP_SIZE*/ )
771                         {
772                                 Event ev(buf);
773                                 ePtr<eServiceEvent> event = new eServiceEvent;
774                                 ePtr<eServiceEvent> empty;
775                                 event->parseFrom(&ev, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get());
776                                 m_event_handler.inject(event, 0);
777                                 m_event_handler.inject(empty, 1);
778                                 eDebug("injected");
779                         }
780                 }
781         }
782         
783         if (m_is_pvr)
784                 loadCuesheet();
785
786         m_event(this, evStart);
787         m_event((iPlayableService*)this, evSeekableStatusChanged);
788         return 0;
789 }
790
791 RESULT eDVBServicePlay::stop()
792 {
793         stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
794
795         m_service_handler_timeshift.free();
796         m_service_handler.free();
797         
798         if (m_is_pvr && m_cuesheet_changed)
799                 saveCuesheet();
800         
801         return 0;
802 }
803
804 RESULT eDVBServicePlay::setTarget(int target)
805 {
806         m_is_primary = !target;
807         return 0;
808 }
809
810 RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
811 {
812         connection = new eConnection((iPlayableService*)this, m_event.connect(event));
813         return 0;
814 }
815
816 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
817 {
818                 /* note: we check for timeshift to be enabled,
819                    not neccessary active. if you pause when timeshift
820                    is not active, you should activate it when unpausing */
821         if ((!m_is_pvr) && (!m_timeshift_enabled))
822         {
823                 ptr = 0;
824                 return -1;
825         }
826
827         ptr = this;
828         return 0;
829 }
830
831 RESULT eDVBServicePlay::setSlowMotion(int ratio)
832 {
833         if (m_decoder)
834                 return m_decoder->setSlowMotion(ratio);
835         else
836                 return -1;
837 }
838
839 RESULT eDVBServicePlay::setFastForward(int ratio)
840 {
841         int skipmode, ffratio;
842         
843         if (ratio > 8)
844         {
845                 skipmode = ratio;
846                 ffratio = 1;
847         } else if (ratio > 0)
848         {
849                 skipmode = 0;
850                 ffratio = ratio;
851         } else if (!ratio)
852         {
853                 skipmode = 0;
854                 ffratio = 0;
855         } else // if (ratio < 0)
856         {
857                 skipmode = ratio;
858                 ffratio = 1;
859         }
860
861         if (m_skipmode != skipmode)
862         {
863                 eDebug("setting cue skipmode to %d", skipmode);
864                 if (m_cue)
865                         m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
866         }
867         
868         m_skipmode = skipmode;
869         
870         if (!m_decoder)
871                 return -1;
872
873         return m_decoder->setFastForward(ffratio);
874 }
875     
876 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
877 {
878         if (m_is_pvr || m_timeshift_enabled)
879         {
880                 ptr = this;
881                 return 0;
882         }
883         
884         ptr = 0;
885         return -1;
886 }
887
888         /* TODO: when timeshift is enabled but not active, this doesn't work. */
889 RESULT eDVBServicePlay::getLength(pts_t &len)
890 {
891         ePtr<iDVBPVRChannel> pvr_channel;
892         
893         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
894                 return -1;
895         
896         return pvr_channel->getLength(len);
897 }
898
899 RESULT eDVBServicePlay::pause()
900 {
901         if (!m_is_paused && m_decoder)
902         {
903                 m_is_paused = 1;
904                 return m_decoder->freeze(0);
905         } else
906                 return -1;
907 }
908
909 RESULT eDVBServicePlay::unpause()
910 {
911         if (m_is_paused && m_decoder)
912         {
913                 m_is_paused = 0;
914                 return m_decoder->unfreeze();
915         } else
916                 return -1;
917 }
918
919 RESULT eDVBServicePlay::seekTo(pts_t to)
920 {
921         eDebug("eDVBServicePlay::seekTo: jump %lld", to);
922         
923         if (!m_decode_demux)
924                 return -1;
925
926         ePtr<iDVBPVRChannel> pvr_channel;
927         
928         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
929                 return -1;
930         
931         if (!m_cue)
932                 return -1;
933         
934         m_cue->seekTo(0, to);
935         return 0;
936 }
937
938 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
939 {
940         eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
941         
942         if (!m_decode_demux)
943                 return -1;
944
945         ePtr<iDVBPVRChannel> pvr_channel;
946         
947         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
948                 return -1;
949         
950         int mode = 1;
951         
952                         /* HACK until we have skip-AP api */
953         if ((to > 0) && (to < 100))
954                 mode = 2;
955         
956         to *= direction;
957         
958         if (!m_cue)
959                 return 0;
960         
961         m_cue->seekTo(mode, to);
962         return 0;
963 }
964
965 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
966 {
967         ePtr<iDVBPVRChannel> pvr_channel;
968         
969         if (!m_decode_demux)
970                 return -1;
971         
972         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
973                 return -1;
974         
975         int r = 0;
976
977                 /* if there is a decoder, use audio or video PTS */
978         if (m_decoder)
979         {
980                 r = m_decoder->getPTS(0, pos);
981                 if (r)
982                         return r;
983         }
984         
985                 /* fixup */
986         return pvr_channel->getCurrentPosition(m_decode_demux, pos, m_decoder ? 1 : 0);
987 }
988
989 RESULT eDVBServicePlay::setTrickmode(int trick)
990 {
991         if (m_decoder)
992                 m_decoder->setTrickmode(trick);
993         return 0;
994 }
995
996 RESULT eDVBServicePlay::isCurrentlySeekable()
997 {
998         return m_is_pvr || m_timeshift_active;
999 }
1000
1001 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
1002 {
1003         ptr = this;
1004         return 0;
1005 }
1006
1007 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
1008 {
1009         ptr = this;
1010         return 0;
1011 }
1012
1013 RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
1014 {
1015         ptr = this;
1016         return 0;
1017 }
1018
1019 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
1020 {
1021         ptr = this;
1022         return 0;
1023 }
1024
1025 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
1026 {
1027         ptr = this;
1028         return 0;
1029 }
1030
1031 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
1032 {
1033         ptr = 0;
1034         if (m_have_video_pid &&  // HACK !!! FIXMEE !! temporary no timeshift on radio services !!
1035                 (m_timeshift_enabled || !m_is_pvr))
1036         {
1037                 if (!m_timeshift_enabled)
1038                 {
1039                                 /* we need enough diskspace */
1040                         struct statfs fs;
1041                         if (statfs(TSPATH "/.", &fs) < 0)
1042                         {
1043                                 eDebug("statfs failed!");
1044                                 return -2;
1045                         }
1046                 
1047                         if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 1024*1024*1024LL)
1048                         {
1049                                 eDebug("not enough diskspace for timeshift! (less than 1GB)");
1050                                 return -3;
1051                         }
1052                 }
1053                 ptr = this;
1054                 return 0;
1055         }
1056         return -1;
1057 }
1058
1059 RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
1060 {
1061         if (m_is_pvr)
1062         {
1063                 ptr = this;
1064                 return 0;
1065         }
1066         ptr = 0;
1067         return -1;
1068 }
1069
1070 RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
1071 {
1072         ptr = this;
1073         return 0;
1074 }
1075
1076 RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
1077 {
1078         ptr = this;
1079         return 0;
1080 }
1081
1082 RESULT eDVBServicePlay::getName(std::string &name)
1083 {
1084         if (m_is_pvr)
1085         {
1086                 ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
1087                 return i->getName(m_reference, name);
1088         }
1089         if (m_dvb_service)
1090         {
1091                 m_dvb_service->getName(m_reference, name);
1092                 if (name.empty())
1093                         name = "(...)";
1094         }
1095         else if (!m_reference.name.empty())
1096                 eStaticServiceDVBInformation().getName(m_reference, name);
1097         else
1098                 name = "DVB service";
1099         return 0;
1100 }
1101
1102 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
1103 {
1104         return m_event_handler.getEvent(evt, nownext);
1105 }
1106
1107 int eDVBServicePlay::getInfo(int w)
1108 {
1109         eDVBServicePMTHandler::program program;
1110
1111         if (w == sCAIDs)
1112                 return resIsPyObject;
1113
1114         if (m_service_handler.getProgramInfo(program))
1115                 return -1;
1116         
1117         switch (w)
1118         {
1119         case sAspect:
1120                 if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
1121                 {
1122                         ePtr<eServiceEvent> evt;
1123                         if (!m_event_handler.getEvent(evt, 0))
1124                         {
1125                                 ePtr<eComponentData> data;
1126                                 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
1127                                 {
1128                                         if ( data->getStreamContent() == 1 )
1129                                         {
1130                                                 switch(data->getComponentType())
1131                                                 {
1132                                                         // SD
1133                                                         case 1: // 4:3 SD PAL
1134                                                         case 2:
1135                                                         case 3: // 16:9 SD PAL
1136                                                         case 4: // > 16:9 PAL
1137                                                         case 5: // 4:3 SD NTSC
1138                                                         case 6: 
1139                                                         case 7: // 16:9 SD NTSC
1140                                                         case 8: // > 16:9 NTSC
1141
1142                                                         // HD
1143                                                         case 9: // 4:3 HD PAL
1144                                                         case 0xA:
1145                                                         case 0xB: // 16:9 HD PAL
1146                                                         case 0xC: // > 16:9 HD PAL
1147                                                         case 0xD: // 4:3 HD NTSC
1148                                                         case 0xE:
1149                                                         case 0xF: // 16:9 HD NTSC
1150                                                         case 0x10: // > 16:9 HD PAL
1151                                                                 return data->getComponentType();
1152                                                 }
1153                                         }
1154                                 }
1155                         }
1156                 }
1157                 return -1;
1158         case sIsCrypted: return program.isCrypted();
1159         case sVideoPID: if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
1160         case sVideoType: if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
1161         case sAudioPID: if (program.audioStreams.empty()) return -1; return program.audioStreams[m_current_audio_stream].pid;
1162         case sPCRPID: return program.pcrPid;
1163         case sPMTPID: return program.pmtPid;
1164         case sTXTPID: return program.textPid;
1165         case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
1166         case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
1167         case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
1168         case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
1169         case sProvider: if (!m_dvb_service) return -1; return -2;
1170         default:
1171                 return -1;
1172         }
1173 }
1174
1175 std::string eDVBServicePlay::getInfoString(int w)
1176 {
1177         switch (w)
1178         {
1179         case sProvider:
1180                 if (!m_dvb_service) return "";
1181                 return m_dvb_service->m_provider_name;
1182         default:
1183                 break;
1184         }
1185         return iServiceInformation::getInfoString(w);
1186 }
1187
1188 PyObject *eDVBServicePlay::getInfoObject(int w)
1189 {
1190         switch (w)
1191         {
1192         case sCAIDs:
1193                 return m_service_handler.getCaIds();
1194         default:
1195                 break;
1196         }
1197         return iServiceInformation::getInfoObject(w);
1198 }
1199
1200 int eDVBServicePlay::getNumberOfTracks()
1201 {
1202         eDVBServicePMTHandler::program program;
1203         if (m_service_handler.getProgramInfo(program))
1204                 return 0;
1205         return program.audioStreams.size();
1206 }
1207
1208 RESULT eDVBServicePlay::selectTrack(unsigned int i)
1209 {
1210         int ret = selectAudioStream(i);
1211
1212         if (m_decoder->start())
1213                 return -5;
1214
1215         return ret;
1216 }
1217
1218 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
1219 {
1220         eDVBServicePMTHandler::program program;
1221
1222         if (m_service_handler.getProgramInfo(program))
1223                 return -1;
1224         
1225         if (i >= program.audioStreams.size())
1226                 return -2;
1227         
1228         if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
1229                 info.m_description = "MPEG";
1230         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
1231                 info.m_description = "AC3";
1232         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
1233                 info.m_description = "AAC";
1234         else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
1235                 info.m_description = "DTS";
1236         else
1237                 info.m_description = "???";
1238
1239         if (program.audioStreams[i].component_tag != -1)
1240         {
1241                 ePtr<eServiceEvent> evt;
1242                 if (!m_event_handler.getEvent(evt, 0))
1243                 {
1244                         ePtr<eComponentData> data;
1245                         if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
1246                                 info.m_language = data->getText();
1247                 }
1248         }
1249
1250         if (info.m_language.empty())
1251                 info.m_language = program.audioStreams[i].language_code;
1252         
1253         return 0;
1254 }
1255
1256 int eDVBServicePlay::selectAudioStream(int i)
1257 {
1258         eDVBServicePMTHandler::program program;
1259
1260         if (m_service_handler.getProgramInfo(program))
1261                 return -1;
1262         
1263         if ((unsigned int)i >= program.audioStreams.size())
1264                 return -2;
1265         
1266         if (!m_decoder)
1267                 return -3;
1268         
1269         if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
1270                 return -4;
1271
1272         if (m_dvb_service && !m_is_pvr)
1273         {
1274                 if (program.audioStreams[i].type == eDVBAudio::aMPEG)
1275                 {
1276                         m_dvb_service->setCacheEntry(eDVBService::cAPID, program.audioStreams[i].pid);
1277                         m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1278                 }       else
1279                 {
1280                         m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1281                         m_dvb_service->setCacheEntry(eDVBService::cAC3PID, program.audioStreams[i].pid);
1282                 }
1283         }
1284
1285         m_current_audio_stream = i;
1286
1287         return 0;
1288 }
1289
1290 int eDVBServicePlay::getCurrentChannel()
1291 {
1292         return m_decoder ? m_decoder->getAudioChannel() : STEREO;
1293 }
1294
1295 RESULT eDVBServicePlay::selectChannel(int i)
1296 {
1297         if (i < LEFT || i > RIGHT || i == STEREO)
1298                 i = -1;  // Stereo
1299         if (m_dvb_service)
1300                 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
1301         if (m_decoder)
1302                 m_decoder->setAudioChannel(i);
1303         return 0;
1304 }
1305
1306 int eDVBServiceBase::getFrontendInfo(int w)
1307 {
1308         eUsePtr<iDVBChannel> channel;
1309         if(m_service_handler.getChannel(channel))
1310                 return 0;
1311         ePtr<iDVBFrontend> fe;
1312         if(channel->getFrontend(fe))
1313                 return 0;
1314         return fe->readFrontendData(w);
1315 }
1316
1317 PyObject *eDVBServiceBase::getFrontendData(bool original)
1318 {
1319         PyObject *ret=0;
1320
1321         eUsePtr<iDVBChannel> channel;
1322         if(!m_service_handler.getChannel(channel))
1323         {
1324                 ePtr<iDVBFrontend> fe;
1325                 if(!channel->getFrontend(fe))
1326                 {
1327                         ret = fe->readTransponderData(original);
1328                         if (ret)
1329                         {
1330                                 ePtr<iDVBFrontendParameters> feparm;
1331                                 channel->getCurrentFrontendParameters(feparm);
1332                                 if (feparm)
1333                                 {
1334                                         eDVBFrontendParametersSatellite osat;
1335                                         if (!feparm->getDVBS(osat))
1336                                         {
1337                                                 void PutToDict(PyObject *, const char*, long);
1338                                                 void PutToDict(PyObject *, const char*, const char*);
1339                                                 PutToDict(ret, "orbital_position", osat.orbital_position);
1340                                                 const char *tmp = "UNKNOWN";
1341                                                 switch(osat.polarisation)
1342                                                 {
1343                                                         case eDVBFrontendParametersSatellite::Polarisation::Horizontal: tmp="HORIZONTAL"; break;
1344                                                         case eDVBFrontendParametersSatellite::Polarisation::Vertical: tmp="VERTICAL"; break;
1345                                                         case eDVBFrontendParametersSatellite::Polarisation::CircularLeft: tmp="CIRCULAR_LEFT"; break;
1346                                                         case eDVBFrontendParametersSatellite::Polarisation::CircularRight: tmp="CIRCULAR_RIGHT"; break;
1347                                                         default:break;
1348                                                 }
1349                                                 PutToDict(ret, "polarization", tmp);
1350                                         }
1351                                 }
1352                         }
1353                 }
1354         }
1355         if (!ret)
1356         {
1357                 ret = Py_None;
1358                 Py_INCREF(ret);
1359         }
1360         return ret;
1361 }
1362
1363 int eDVBServicePlay::getNumberOfSubservices()
1364 {
1365         ePtr<eServiceEvent> evt;
1366         if (!m_event_handler.getEvent(evt, 0))
1367                 return evt->getNumOfLinkageServices();
1368         return 0;
1369 }
1370
1371 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
1372 {
1373         ePtr<eServiceEvent> evt;
1374         if (!m_event_handler.getEvent(evt, 0))
1375         {
1376                 if (!evt->getLinkageService(sub, m_reference, n))
1377                         return 0;
1378         }
1379         sub.type=eServiceReference::idInvalid;
1380         return -1;
1381 }
1382
1383 RESULT eDVBServicePlay::startTimeshift()
1384 {
1385         ePtr<iDVBDemux> demux;
1386         
1387         eDebug("Start timeshift!");
1388         
1389         if (m_timeshift_enabled)
1390                 return -1;
1391         
1392                 /* start recording with the data demux. */
1393         if (m_service_handler.getDataDemux(demux))
1394                 return -2;
1395
1396         demux->createTSRecorder(m_record);
1397         if (!m_record)
1398                 return -3;
1399
1400         char templ[]=TSPATH "/timeshift.XXXXXX";
1401         m_timeshift_fd = mkstemp(templ);
1402         m_timeshift_file = templ;
1403         
1404         eDebug("recording to %s", templ);
1405         
1406         if (m_timeshift_fd < 0)
1407         {
1408                 m_record = 0;
1409                 return -4;
1410         }
1411                 
1412         m_record->setTargetFD(m_timeshift_fd);
1413
1414         m_timeshift_enabled = 1;
1415         
1416         updateTimeshiftPids();
1417         m_record->start();
1418
1419         return 0;
1420 }
1421
1422 RESULT eDVBServicePlay::stopTimeshift()
1423 {
1424         if (!m_timeshift_enabled)
1425                 return -1;
1426         
1427         switchToLive();
1428         
1429         m_timeshift_enabled = 0;
1430         
1431         m_record->stop();
1432         m_record = 0;
1433         
1434         close(m_timeshift_fd);
1435         eDebug("remove timeshift file");
1436         remove(m_timeshift_file.c_str());
1437         
1438         return 0;
1439 }
1440
1441 int eDVBServicePlay::isTimeshiftActive()
1442 {
1443         return m_timeshift_enabled && m_timeshift_active;
1444 }
1445
1446 RESULT eDVBServicePlay::activateTimeshift()
1447 {
1448         if (!m_timeshift_enabled)
1449                 return -1;
1450         
1451         if (!m_timeshift_active)
1452         {
1453                 switchToTimeshift();
1454                 return 0;
1455         }
1456         
1457         return -2;
1458 }
1459
1460 PyObject *eDVBServicePlay::getCutList()
1461 {
1462         PyObject *list = PyList_New(0);
1463         
1464         for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
1465         {
1466                 PyObject *tuple = PyTuple_New(2);
1467                 PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(i->where));
1468                 PyTuple_SetItem(tuple, 1, PyInt_FromLong(i->what));
1469                 PyList_Append(list, tuple);
1470                 Py_DECREF(tuple);
1471         }
1472         
1473         return list;
1474 }
1475
1476 void eDVBServicePlay::setCutList(PyObject *list)
1477 {
1478         if (!PyList_Check(list))
1479                 return;
1480         int size = PyList_Size(list);
1481         int i;
1482         
1483         m_cue_entries.clear();
1484         
1485         for (i=0; i<size; ++i)
1486         {
1487                 PyObject *tuple = PyList_GetItem(list, i);
1488                 if (!PyTuple_Check(tuple))
1489                 {
1490                         eDebug("non-tuple in cutlist");
1491                         continue;
1492                 }
1493                 if (PyTuple_Size(tuple) != 2)
1494                 {
1495                         eDebug("cutlist entries need to be a 2-tuple");
1496                         continue;
1497                 }
1498                 PyObject *ppts = PyTuple_GetItem(tuple, 0), *ptype = PyTuple_GetItem(tuple, 1);
1499                 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
1500                 {
1501                         eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
1502                         continue;
1503                 }
1504                 pts_t pts = PyLong_AsLongLong(ppts);
1505                 int type = PyInt_AsLong(ptype);
1506                 m_cue_entries.insert(cueEntry(pts, type));
1507                 eDebug("adding %08llx, %d", pts, type);
1508         }
1509         m_cuesheet_changed = 1;
1510         
1511         cutlistToCuesheet();
1512         m_event((iPlayableService*)this, evCuesheetChanged);
1513 }
1514
1515 void eDVBServicePlay::setCutListEnable(int enable)
1516 {
1517         m_cutlist_enabled = enable;
1518         cutlistToCuesheet();
1519 }
1520
1521 void eDVBServicePlay::updateTimeshiftPids()
1522 {
1523         if (!m_record)
1524                 return;
1525         
1526         eDVBServicePMTHandler::program program;
1527         if (m_service_handler.getProgramInfo(program))
1528                 return;
1529         else
1530         {
1531                 std::set<int> pids_to_record;
1532                 pids_to_record.insert(0); // PAT
1533                 if (program.pmtPid != -1)
1534                         pids_to_record.insert(program.pmtPid); // PMT
1535
1536                 if (program.textPid != -1)
1537                         pids_to_record.insert(program.textPid); // Videotext
1538
1539                 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1540                         i(program.videoStreams.begin()); 
1541                         i != program.videoStreams.end(); ++i)
1542                         pids_to_record.insert(i->pid);
1543
1544                 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1545                         i(program.audioStreams.begin()); 
1546                         i != program.audioStreams.end(); ++i)
1547                                 pids_to_record.insert(i->pid);
1548
1549                 std::set<int> new_pids, obsolete_pids;
1550                 
1551                 std::set_difference(pids_to_record.begin(), pids_to_record.end(), 
1552                                 m_pids_active.begin(), m_pids_active.end(),
1553                                 std::inserter(new_pids, new_pids.begin()));
1554                 
1555                 std::set_difference(
1556                                 m_pids_active.begin(), m_pids_active.end(),
1557                                 pids_to_record.begin(), pids_to_record.end(), 
1558                                 std::inserter(new_pids, new_pids.begin())
1559                                 );
1560
1561                 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
1562                         m_record->addPID(*i);
1563
1564                 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
1565                         m_record->removePID(*i);
1566         }
1567 }
1568
1569 void eDVBServicePlay::switchToLive()
1570 {
1571         if (!m_timeshift_active)
1572                 return;
1573         
1574         m_cue = 0;
1575         m_decoder = 0;
1576         m_decode_demux = 0;
1577         m_teletext_parser = 0;
1578         m_new_subtitle_page_connection = 0;
1579         
1580                 /* free the timeshift service handler, we need the resources */
1581         m_service_handler_timeshift.free();
1582         m_timeshift_active = 0;
1583         
1584         m_event((iPlayableService*)this, evSeekableStatusChanged);
1585         
1586         updateDecoder();
1587 }
1588
1589 void eDVBServicePlay::switchToTimeshift()
1590 {
1591         if (m_timeshift_active)
1592                 return;
1593         
1594         m_decode_demux = 0;
1595         m_decoder = 0;
1596         m_teletext_parser = 0;
1597         m_new_subtitle_page_connection = 0;
1598         
1599         m_timeshift_active = 1;
1600
1601         m_event((iPlayableService*)this, evSeekableStatusChanged);
1602         
1603         eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
1604         r.path = m_timeshift_file;
1605         
1606         m_cue = new eCueSheet();
1607         m_service_handler_timeshift.tune(r, 1, m_cue); /* use the decoder demux for everything */
1608         updateDecoder(); /* mainly to switch off PCR */
1609 }
1610
1611 void eDVBServicePlay::updateDecoder()
1612 {
1613         int vpid = -1, vpidtype = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
1614
1615         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1616
1617         bool defaultac3=false;
1618         std::string default_ac3;
1619
1620         if (!ePythonConfigQuery::getConfigValue("config.av.defaultac3", default_ac3))
1621                 defaultac3 = default_ac3 == "enable";
1622
1623         eDVBServicePMTHandler::program program;
1624         if (h.getProgramInfo(program))
1625                 eDebug("getting program info failed.");
1626         else
1627         {
1628                 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
1629                 if (!program.videoStreams.empty())
1630                 {
1631                         eDebugNoNewLine(" (");
1632                         for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1633                                 i(program.videoStreams.begin()); 
1634                                 i != program.videoStreams.end(); ++i)
1635                         {
1636                                 if (vpid == -1)
1637                                 {
1638                                         vpid = i->pid;
1639                                         vpidtype = i->type;
1640                                 }
1641                                 if (i != program.videoStreams.begin())
1642                                         eDebugNoNewLine(", ");
1643                                 eDebugNoNewLine("%04x", i->pid);
1644                         }
1645                         eDebugNoNewLine(")");
1646                 }
1647                 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
1648                 if (!program.audioStreams.empty())
1649                 {
1650                         eDebugNoNewLine(" (");
1651                         for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1652                                 i(program.audioStreams.begin()); 
1653                                 i != program.audioStreams.end(); ++i)
1654                         {
1655                                 if (apid == -1 || (apidtype == eDVBAudio::aMPEG && defaultac3))
1656                                 {
1657                                         if ( apid == -1 || (i->type != eDVBAudio::aMPEG) )
1658                                         {
1659                                                 apid = i->pid;
1660                                                 apidtype = i->type;
1661                                         }
1662                                 }
1663                                 if (i != program.audioStreams.begin())
1664                                         eDebugNoNewLine(", ");
1665                                 eDebugNoNewLine("%04x", i->pid);
1666                         }
1667                         eDebugNoNewLine(")");
1668                 }
1669                 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
1670                 pcrpid = program.pcrPid;
1671                 eDebug(", and the text pid is %04x", program.textPid);
1672                 tpid = program.textPid;
1673         }
1674
1675         if (!m_decoder)
1676         {
1677                 h.getDecodeDemux(m_decode_demux);
1678                 if (m_decode_demux)
1679                         m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
1680                 if (m_cue)
1681                         m_cue->setDecodingDemux(m_decode_demux, m_decoder);
1682 #ifdef INTERNAL_TELETEXT
1683                 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
1684                 m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
1685 #endif
1686         }
1687
1688         if (m_decoder)
1689         {
1690                 if (m_dvb_service)
1691                 {
1692                         achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
1693                         ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
1694                         pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
1695                 }
1696                 else // subservice or recording
1697                 {
1698                         eServiceReferenceDVB parent = ((eServiceReferenceDVB&)m_reference).getParentServiceReference();
1699                         if (!parent && !m_reference.path.empty()) // is recording
1700                         {
1701                                 parent = (eServiceReferenceDVB&)m_reference;
1702                                 parent.path="";
1703                         }
1704                         if (parent)
1705                         {
1706                                 ePtr<eDVBResourceManager> res_mgr;
1707                                 if (!eDVBResourceManager::getInstance(res_mgr))
1708                                 {
1709                                         ePtr<iDVBChannelList> db;
1710                                         if (!res_mgr->getChannelList(db))
1711                                         {
1712                                                 ePtr<eDVBService> origService;
1713                                                 if (!db->getService(parent, origService))
1714                                                 {
1715                                                         ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
1716                                                         pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
1717                                                 }
1718                                         }
1719                                 }
1720                         }
1721                 }
1722
1723                 m_decoder->setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
1724                 m_decoder->setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
1725
1726                 m_decoder->setVideoPID(vpid, vpidtype);
1727                 m_current_audio_stream = 0;
1728                 m_decoder->setAudioPID(apid, apidtype);
1729                 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
1730                         m_decoder->setSyncPCR(pcrpid);
1731                 else
1732                         m_decoder->setSyncPCR(-1);
1733
1734                 m_decoder->setTextPID(tpid);
1735
1736                 if (m_teletext_parser)
1737                         m_teletext_parser->start(tpid);
1738
1739                 if (!m_is_primary)
1740                         m_decoder->setTrickmode(1);
1741
1742                 m_decoder->start();
1743
1744                 if (vpid > 0 && vpid < 0x2000)
1745                         ;
1746                 else
1747                 {
1748                         std::string radio_pic;
1749                         if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
1750                                 m_decoder->setRadioPic(radio_pic);
1751                 }
1752
1753                 m_decoder->setAudioChannel(achannel);
1754
1755 // how we can do this better?
1756 // update cache pid when the user changed the audio track or video track
1757 // TODO handling of difference audio types.. default audio types..
1758                                 
1759                 /* don't worry about non-existing services, nor pvr services */
1760                 if (m_dvb_service && !m_is_pvr)
1761                 {
1762                         if (apidtype == eDVBAudio::aMPEG)
1763                         {
1764                                 m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
1765                                 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1766                         }
1767                         else
1768                         {
1769                                 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1770                                 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
1771                         }
1772                         m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
1773                         m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
1774                         m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
1775                         m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
1776                 }
1777         }
1778         m_have_video_pid = (vpid > 0 && vpid < 0x2000);
1779 }
1780
1781 void eDVBServicePlay::loadCuesheet()
1782 {
1783         std::string filename = m_reference.path + ".cuts";
1784         
1785         m_cue_entries.clear();
1786
1787         FILE *f = fopen(filename.c_str(), "rb");
1788
1789         if (f)
1790         {
1791                 eDebug("loading cuts..");
1792                 while (1)
1793                 {
1794                         unsigned long long where;
1795                         unsigned int what;
1796                         
1797                         if (!fread(&where, sizeof(where), 1, f))
1798                                 break;
1799                         if (!fread(&what, sizeof(what), 1, f))
1800                                 break;
1801                         
1802 #if BYTE_ORDER == LITTLE_ENDIAN
1803                         where = bswap_64(where);
1804 #endif
1805                         what = ntohl(what);
1806                         
1807                         if (what > 2)
1808                                 break;
1809                         
1810                         m_cue_entries.insert(cueEntry(where, what));
1811                 }
1812                 fclose(f);
1813                 eDebug("%d entries", m_cue_entries.size());
1814         } else
1815                 eDebug("cutfile not found!");
1816         
1817         m_cuesheet_changed = 0;
1818         cutlistToCuesheet();
1819         m_event((iPlayableService*)this, evCuesheetChanged);
1820 }
1821
1822 void eDVBServicePlay::saveCuesheet()
1823 {
1824         std::string filename = m_reference.path + ".cuts";
1825         
1826         FILE *f = fopen(filename.c_str(), "wb");
1827
1828         if (f)
1829         {
1830                 unsigned long long where;
1831                 int what;
1832
1833                 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
1834                 {
1835 #if BYTE_ORDER == BIG_ENDIAN
1836                         where = i->where;
1837 #else
1838                         where = bswap_64(i->where);
1839 #endif
1840                         what = htonl(i->what);
1841                         fwrite(&where, sizeof(where), 1, f);
1842                         fwrite(&what, sizeof(what), 1, f);
1843                         
1844                 }
1845                 fclose(f);
1846         }
1847         
1848         m_cuesheet_changed = 0;
1849 }
1850
1851 void eDVBServicePlay::cutlistToCuesheet()
1852 {
1853         if (!m_cue)
1854         {
1855                 eDebug("no cue sheet");
1856                 return;
1857         }       
1858         m_cue->clear();
1859         
1860         if (!m_cutlist_enabled)
1861         {
1862                 m_cue->commitSpans();
1863                 eDebug("cutlists where disabled");
1864                 return;
1865         }
1866
1867         pts_t in = 0, out = 0, length = 0;
1868         
1869         getLength(length);
1870                 
1871         std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
1872         
1873         while (1)
1874         {
1875                 if (i == m_cue_entries.end())
1876                         out = length;
1877                 else {
1878                         if (i->what == 0) /* in */
1879                         {
1880                                 in = i++->where;
1881                                 continue;
1882                         } else if (i->what == 1) /* out */
1883                                 out = i++->where;
1884                         else /* mark */
1885                         {
1886                                 i++;
1887                                 continue;
1888                         }
1889                 }
1890                 
1891                 if (in != out)
1892                         m_cue->addSourceSpan(in, out);
1893                 
1894                 in = length;
1895                 
1896                 if (i == m_cue_entries.end())
1897                         break;
1898         }
1899         m_cue->commitSpans();
1900 }
1901
1902 RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, PyObject *entry)
1903 {
1904         if (m_subtitle_widget)
1905                 disableSubtitles(parent);
1906         
1907         if (!m_teletext_parser)
1908                 return -1;
1909         
1910         if (!PyInt_Check(entry))
1911                 return -1;
1912         
1913         m_subtitle_widget = new eSubtitleWidget(parent);
1914         m_subtitle_widget->resize(parent->size()); /* full size */
1915         
1916         int page = PyInt_AsLong(entry);
1917         
1918         m_teletext_parser->setPage(page);
1919
1920         return 0;
1921 }
1922
1923 RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
1924 {
1925         delete m_subtitle_widget;
1926         m_subtitle_widget = 0;
1927         return 0;
1928 }
1929
1930 PyObject *eDVBServicePlay::getSubtitleList()
1931 {
1932         if (!m_teletext_parser)
1933         {
1934                 Py_INCREF(Py_None);
1935                 return Py_None;
1936         }
1937         
1938         PyObject *l = PyList_New(0);
1939         
1940         for (std::set<int>::iterator i(m_teletext_parser->m_found_subtitle_pages.begin()); i != m_teletext_parser->m_found_subtitle_pages.end(); ++i)
1941         {
1942                 PyObject *tuple = PyTuple_New(2);
1943                 char desc[20];
1944                 sprintf(desc, "Page %x", *i);
1945                 PyTuple_SetItem(tuple, 0, PyString_FromString(desc));
1946                 PyTuple_SetItem(tuple, 1, PyInt_FromLong(*i));
1947                 PyList_Append(l, tuple);
1948         }
1949         
1950         return l;
1951 }
1952
1953 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
1954 {
1955         if (m_subtitle_widget)
1956         {
1957                 m_subtitle_pages.push_back(page);
1958                 
1959                 checkSubtitleTiming();
1960         }
1961 }
1962
1963 void eDVBServicePlay::checkSubtitleTiming()
1964 {
1965         while (1)
1966         {
1967                 if (m_subtitle_pages.empty())
1968                         return;
1969         
1970                 eDVBTeletextSubtitlePage p = m_subtitle_pages.front();
1971         
1972                 pts_t pos = 0;
1973         
1974                 if (m_decoder)
1975                         m_decoder->getPTS(0, pos);
1976         
1977                 int diff = p.m_pts - pos;
1978                 if (diff < 0)
1979                 {
1980                         eDebug("[late (%d ms)]", -diff / 90);
1981                         diff = 0;
1982                 }
1983                 if (diff > 900000)
1984                 {
1985                         eDebug("[invalid]");
1986                         diff = 0;
1987                 }
1988         
1989                 if (!diff)
1990                 {
1991                         m_subtitle_widget->setPage(p);
1992                         m_subtitle_pages.pop_front();
1993                 } else
1994                 {
1995                         m_subtitle_sync_timer.start(diff / 90, 1);
1996                         break;
1997                 }
1998         }
1999 }
2000
2001 int eDVBServicePlay::getAC3Delay()
2002 {
2003         if (m_dvb_service)
2004                 return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2005         else if (m_decoder)
2006                 return m_decoder->getAC3Delay();
2007         else
2008                 return 0;
2009 }
2010
2011 int eDVBServicePlay::getPCMDelay()
2012 {
2013         if (m_dvb_service)
2014                 return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2015         else if (m_decoder)
2016                 return m_decoder->getPCMDelay();
2017         else
2018                 return 0;
2019 }
2020
2021 void eDVBServicePlay::setAC3Delay(int delay)
2022 {
2023         if (m_dvb_service)
2024                 m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
2025         if (m_decoder)
2026                 m_decoder->setAC3Delay(delay);
2027 }
2028
2029 void eDVBServicePlay::setPCMDelay(int delay)
2030 {
2031         if (m_dvb_service)
2032                 m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
2033         if (m_decoder)
2034                 m_decoder->setPCMDelay(delay);
2035 }
2036
2037 DEFINE_REF(eDVBServicePlay)
2038
2039 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");