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