Merge branch 'master' of https://github.com/OpenPLi/enigma2
[openblackhole/openblackhole-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/estring.h>
7 #include <lib/base/init_num.h>
8 #include <lib/base/init.h>
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 #include <lib/base/nconfig.h> // access to python config
20 #include <lib/base/httpstream.h>
21
22                 /* for subtitles */
23 #include <lib/gui/esubtitle.h>
24
25 #include <sys/vfs.h>
26 #include <sys/stat.h>
27
28 #include <byteswap.h>
29 #include <netinet/in.h>
30
31 #ifndef BYTE_ORDER
32 #error no byte order defined!
33 #endif
34
35 #include <ios>
36 #include <sstream>
37 #include <iomanip>
38
39 class eStaticServiceDVBInformation: public iStaticServiceInformation
40 {
41         DECLARE_REF(eStaticServiceDVBInformation);
42 public:
43         RESULT getName(const eServiceReference &ref, std::string &name);
44         int getLength(const eServiceReference &ref);
45         int isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate=false);
46         ePtr<iDVBTransponderData> getTransponderData(const eServiceReference &ref);
47 };
48
49 DEFINE_REF(eStaticServiceDVBInformation);
50
51 RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std::string &name)
52 {
53         eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
54         if ( !ref.name.empty() )
55         {
56                 if (service.getParentTransportStreamID().get()) // linkage subservice
57                 {
58                         ePtr<iServiceHandler> service_center;
59                         if (!eServiceCenter::getInstance(service_center))
60                         {
61                                 eServiceReferenceDVB parent = service;
62                                 parent.setTransportStreamID( service.getParentTransportStreamID() );
63                                 parent.setServiceID( service.getParentServiceID() );
64                                 parent.setParentTransportStreamID(eTransportStreamID(0));
65                                 parent.setParentServiceID(eServiceID(0));
66                                 parent.name="";
67                                 ePtr<iStaticServiceInformation> service_info;
68                                 if (!service_center->info(parent, service_info))
69                                 {
70                                         if (!service_info->getName(parent, name))
71                                                 name=buildShortName(name) + " - ";
72                                 }
73                         }
74                 }
75                 else
76                         name="";
77                 name += ref.name;
78                 return 0;
79         }
80         else
81                 return -1;
82 }
83
84 int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
85 {
86         return -1;
87 }
88
89 int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
90 {
91         ePtr<eDVBResourceManager> res_mgr;
92         if ( eDVBResourceManager::getInstance( res_mgr ) )
93                 eDebug("[eStaticServiceDVBInformation] isPlayable... no res manager!!");
94         else
95         {
96                 eDVBChannelID chid, chid_ignore;
97                 int system;
98                 ((const eServiceReferenceDVB&)ref).getChannelID(chid);
99                 ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
100                 return res_mgr->canAllocateChannel(chid, chid_ignore, system);
101         }
102         return 0;
103 }
104
105 ePtr<iDVBTransponderData> eStaticServiceDVBInformation::getTransponderData(const eServiceReference &r)
106 {
107         ePtr<iDVBTransponderData> retval;
108         if (r.type == eServiceReference::idDVB)
109         {
110                 const eServiceReferenceDVB &ref = (const eServiceReferenceDVB&)r;
111                 ePtr<eDVBResourceManager> res;
112                 if (!eDVBResourceManager::getInstance(res))
113                 {
114                         ePtr<iDVBChannelList> db;
115                         if (!res->getChannelList(db))
116                         {
117                                 eDVBChannelID chid;
118                                 ref.getChannelID(chid);
119                                 ePtr<iDVBFrontendParameters> feparm;
120                                 if (!db->getChannelFrontendData(chid, feparm))
121                                 {
122                                         int system;
123                                         if (!feparm->getSystem(system))
124                                         {
125                                                 switch (system)
126                                                 {
127                                                         case iDVBFrontend::feSatellite:
128                                                         {
129                                                                 eDVBFrontendParametersSatellite s;
130                                                                 feparm->getDVBS(s);
131                                                                 retval = new eDVBSatelliteTransponderData(NULL, 0, s, 0, true);
132                                                                 break;
133                                                         }
134                                                         case iDVBFrontend::feTerrestrial:
135                                                         {
136                                                                 eDVBFrontendParametersTerrestrial t;
137                                                                 feparm->getDVBT(t);
138                                                                 retval = new eDVBTerrestrialTransponderData(NULL, 0, t, true);
139                                                                 break;
140                                                         }
141                                                         case iDVBFrontend::feCable:
142                                                         {
143                                                                 eDVBFrontendParametersCable c;
144                                                                 feparm->getDVBC(c);
145                                                                 retval = new eDVBCableTransponderData(NULL, 0, c, true);
146                                                                 break;
147                                                         }
148                                                         case iDVBFrontend::feATSC:
149                                                         {
150                                                                 eDVBFrontendParametersATSC a;
151                                                                 feparm->getATSC(a);
152                                                                 retval = new eDVBATSCTransponderData(NULL, 0, a, true);
153                                                                 break;
154                                                         }
155                                                         default:
156                                                                 eDebug("[eStaticServiceDVBInformation] unknown frontend type %d", system);
157                                                                 break;
158                                                 }
159                                         }
160                                 }
161                         }
162                 }
163         }
164         return retval;
165 }
166
167 DEFINE_REF(eStaticServiceDVBBouquetInformation);
168
169 RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
170 {
171         ePtr<iDVBChannelList> db;
172         ePtr<eDVBResourceManager> res;
173
174         int err;
175         if ((err = eDVBResourceManager::getInstance(res)) != 0)
176         {
177                 eDebug("[eStaticServiceDVBBouquetInformation] getName failed.. no resource manager!");
178                 return err;
179         }
180         if ((err = res->getChannelList(db)) != 0)
181         {
182                 eDebug("[eStaticServiceDVBBouquetInformation] getName failed.. no channel list!");
183                 return err;
184         }
185
186         eBouquet *bouquet = NULL;
187         if ((err = db->getBouquet(ref, bouquet)) != 0)
188         {
189                 eDebug("[eStaticServiceDVBBouquetInformation] getName failed.. getBouquet failed!");
190                 return -1;
191         }
192
193         if ( bouquet && bouquet->m_bouquet_name.length() )
194         {
195                 name = bouquet->m_bouquet_name;
196                 return 0;
197         }
198         else
199                 return -1;
200 }
201
202 int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
203 {
204         if (ref.flags & eServiceReference::isGroup)
205         {
206                 ePtr<iDVBChannelList> db;
207                 ePtr<eDVBResourceManager> res;
208                 eServiceReference streamable_service;
209
210                 if (eDVBResourceManager::getInstance(res))
211                 {
212                         eDebug("[eStaticServiceDVBBouquetInformation] isPlayable failed.. no resource manager!");
213                         return 0;
214                 }
215
216                 if (res->getChannelList(db))
217                 {
218                         eDebug("[eStaticServiceDVBBouquetInformation] isPlayable failed.. no channel list!");
219                         return 0;
220                 }
221
222                 eBouquet *bouquet = NULL;
223                 if (db->getBouquet(ref, bouquet))
224                 {
225                         eDebug("[eStaticServiceDVBBouquetInformation] isPlayable failed.. getBouquet failed!");
226                         return 0;
227                 }
228
229                 int prio_order = eDVBFrontend::getTypePriorityOrder();
230                 int cur=0;
231                 eDVBChannelID chid, chid_ignore;
232                 ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
233                 for (std::list<eServiceReference>::iterator it(bouquet->m_services.begin()); it != bouquet->m_services.end(); ++it)
234                 {
235                         static unsigned char prio_map[6][3] = {
236                                 { 3, 2, 1 }, // -S -C -T
237                                 { 3, 1, 2 }, // -S -T -C
238                                 { 2, 3, 1 }, // -C -S -T
239                                 { 1, 3, 2 }, // -C -T -S
240                                 { 1, 2, 3 }, // -T -C -S
241                                 { 2, 1, 3 }  // -T -S -C
242                         };
243                         int system;
244                         ((const eServiceReferenceDVB&)*it).getChannelID(chid);
245                         int tmp = res->canAllocateChannel(chid, chid_ignore, system, simulate);
246                         if (prio_order == 127) // ignore dvb-type priority, try all alternatives one-by-one
247                         {
248                                 if (((tmp > 0) || (!it->path.empty())))
249                                 {
250                                         m_playable_service = *it;
251                                         return 1;
252                                 }
253                         }
254                         else
255                         {
256                                 if (tmp > 0)
257                                 {
258                                         switch (system)
259                                         {
260                                                 case iDVBFrontend::feTerrestrial:
261                                                         tmp = prio_map[prio_order][2];
262                                                         break;
263                                                 case iDVBFrontend::feCable:
264                                                         tmp = prio_map[prio_order][1];
265                                                         break;
266                                                 default:
267                                                 case iDVBFrontend::feSatellite:
268                                                         tmp = prio_map[prio_order][0];
269                                                         break;
270                                         }
271                                 }
272                                 if (tmp > cur)
273                                 {
274                                         m_playable_service = *it;
275                                         cur = tmp;
276                                 }
277                                 if (!it->path.empty())
278                                 {
279                                         streamable_service = *it;
280                                 }
281                         }
282                 }
283                 if (cur)
284                 {
285                         return !!cur;
286                 }
287                 /* fallback to stream (or pvr) service alternative */
288                 if (streamable_service)
289                 {
290                         m_playable_service = streamable_service;
291                         return 1;
292                 }
293         }
294         m_playable_service = eServiceReference();
295         return 0;
296 }
297
298 int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
299 {
300         return -1;
301 }
302
303 #include <lib/dvb/epgcache.h>
304
305 RESULT eStaticServiceDVBBouquetInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time)
306 {
307         return eEPGCache::getInstance()->lookupEventTime(ref, start_time, ptr);
308 }
309
310 class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
311 {
312         DECLARE_REF(eStaticServiceDVBPVRInformation);
313         eServiceReference m_ref;
314         eDVBMetaParser m_parser;
315 public:
316         eStaticServiceDVBPVRInformation(const eServiceReference &ref);
317         RESULT getName(const eServiceReference &ref, std::string &name);
318         int getLength(const eServiceReference &ref);
319         RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time);
320         int isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { return 1; }
321         int getInfo(const eServiceReference &ref, int w);
322         std::string getInfoString(const eServiceReference &ref,int w);
323         ePtr<iDVBTransponderData> getTransponderData(const eServiceReference &r);
324         long long getFileSize(const eServiceReference &r);
325 };
326
327 DEFINE_REF(eStaticServiceDVBPVRInformation);
328
329 eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref)
330 {
331         m_ref = ref;
332         m_parser.parseFile(ref.path);
333 }
334
335 static bool looksLikeRecording(const std::string& n)
336 {
337         return
338                 (n.size() > 19) &&
339                 (n[8] == ' ') &&
340                 (n[13] == ' ') &&
341                 (n[14] == '-') &&
342                 (n[15] == ' ') &&
343                 (isdigit(n[0]));
344 }
345
346 RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
347 {
348         ASSERT(ref == m_ref);
349         if (!ref.name.empty())
350                 name = ref.name;
351         else if (!m_parser.m_name.empty())
352                 name = m_parser.m_name;
353         else
354         {
355                 name = ref.path;
356                 size_t n = name.rfind('/');
357                 if (n != std::string::npos)
358                         name = name.substr(n + 1);
359                 if (looksLikeRecording(name))
360                 {
361                         // Parse recording names in 'YYYYMMDD HHMM - ... - name.ts' into name
362                         std::size_t dash2 = name.find(" - ", 16, 3);
363                         if (dash2 != std::string::npos)
364                         {
365                                 struct tm stm = {0};
366                                 if (strptime(name.c_str(), "%Y%m%d %H%M", &stm) != NULL)
367                                 {
368                                         m_parser.m_time_create = mktime(&stm);
369                                 }
370                                 name.erase(0,dash2+3);
371                         }
372                         if (name[name.size()-3] == '.')
373                         {
374                                 name.erase(name.size()-3);
375                         }
376                 }
377                 m_parser.m_name = name;
378         }
379         return 0;
380 }
381
382 int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
383 {
384         ASSERT(ref == m_ref);
385
386         eDVBTSTools tstools;
387
388         if (tstools.openFile(ref.path.c_str(), 1))
389                 return 0;
390
391         struct stat s;
392         stat(ref.path.c_str(), &s);
393
394                         /* check if cached data is still valid */
395         if (m_parser.m_data_ok && (s.st_size == m_parser.m_filesize) && (m_parser.m_length))
396                 return m_parser.m_length / 90000;
397
398                         /* open again, this time with stream info */
399         if (tstools.openFile(ref.path.c_str()))
400                 return 0;
401
402                         /* otherwise, re-calc length and update meta file */
403         pts_t len;
404         if (tstools.calcLen(len))
405                 return 0;
406
407         if (m_parser.m_name.empty())
408         {
409                 std::string name;
410                 getName(ref, name); // This also updates m_parser.name
411         }
412         m_parser.m_data_ok = 1;
413         m_parser.m_length = len;
414         m_parser.m_filesize = s.st_size;
415         m_parser.updateMeta(ref.path);
416         return m_parser.m_length / 90000;
417 }
418
419 int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
420 {
421         switch (w)
422         {
423         case iServiceInformation::sDescription:
424                 return iServiceInformation::resIsString;
425         case iServiceInformation::sServiceref:
426                 return iServiceInformation::resIsString;
427         case iServiceInformation::sFileSize:
428                 return m_parser.m_filesize;
429         case iServiceInformation::sTimeCreate:
430                 if (m_parser.m_time_create)
431                         return m_parser.m_time_create;
432                 else
433                         return iServiceInformation::resNA;
434         default:
435                 return iServiceInformation::resNA;
436         }
437 }
438
439 std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
440 {
441         switch (w)
442         {
443         case iServiceInformation::sDescription:
444                 return m_parser.m_description;
445         case iServiceInformation::sServiceref:
446                 return m_parser.m_ref.toString();
447         case iServiceInformation::sTags:
448                 return m_parser.m_tags;
449         default:
450                 return "";
451         }
452 }
453
454 ePtr<iDVBTransponderData> eStaticServiceDVBPVRInformation::getTransponderData(const eServiceReference &r)
455 {
456         ePtr<iDVBTransponderData> retval;
457         return retval;
458 }
459
460 long long eStaticServiceDVBPVRInformation::getFileSize(const eServiceReference &ref)
461 {
462         return m_parser.m_filesize;
463 }
464
465 RESULT eStaticServiceDVBPVRInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &evt, time_t start_time)
466 {
467         if (!ref.path.empty())
468         {
469                 if (ref.path.substr(0, 7) == "http://")
470                 {
471                         eServiceReference equivalentref(ref);
472                         /* this might be a scrambled stream (id + 0x100), force equivalent dvb type */
473                         equivalentref.type = eServiceFactoryDVB::id;
474                         equivalentref.path.clear();
475                         return eEPGCache::getInstance()->lookupEventTime(equivalentref, start_time, evt);
476                 }
477                 else
478                 {
479                         ePtr<eServiceEvent> event = new eServiceEvent;
480                         std::string filename = ref.path;
481                         filename.erase(filename.length()-2, 2);
482                         filename+="eit";
483                         if (!event->parseFrom(filename, (m_parser.m_ref.getTransportStreamID().get()<<16)|m_parser.m_ref.getOriginalNetworkID().get()))
484                         {
485                                 evt = event;
486                                 return 0;
487                         }
488                 }
489         }
490         evt = 0;
491         return -1;
492 }
493
494 class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
495 {
496         DECLARE_REF(eDVBPVRServiceOfflineOperations);
497         eServiceReferenceDVB m_ref;
498 public:
499         eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
500
501         RESULT deleteFromDisk(int simulate);
502         RESULT getListOfFilenames(std::list<std::string> &);
503         RESULT reindex();
504 };
505
506 DEFINE_REF(eDVBPVRServiceOfflineOperations);
507
508 eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
509 {
510 }
511
512 RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
513 {
514         if (simulate)
515                 return 0;
516         else
517         {
518                 std::list<std::string> res;
519                 if (getListOfFilenames(res))
520                         return -1;
521
522                 eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
523                 if (!eraser)
524                         eDebug("[eDVBPVRServiceOfflineOperations] deleteFromDisk FATAL !! can't get background file eraser");
525
526                 for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
527                 {
528                         eDebug("[eDVBPVRServiceOfflineOperations] deleteFromDisk Removing %s...", i->c_str());
529                         if (eraser)
530                                 eraser->erase(*i);
531                         else
532                                 ::unlink(i->c_str());
533                 }
534
535                 return 0;
536         }
537 }
538
539 RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
540 {
541         res.clear();
542         res.push_back(m_ref.path);
543
544 // handling for old splitted recordings (enigma 1)
545         char buf[255];
546         int slice=1;
547         while(true)
548         {
549                 snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
550                 if (::access(buf, R_OK) < 0) break;
551                 res.push_back(buf);
552         }
553
554         res.push_back(m_ref.path + ".meta");
555         res.push_back(m_ref.path + ".ap");
556         res.push_back(m_ref.path + ".sc");
557         res.push_back(m_ref.path + ".cuts");
558         std::string tmp = m_ref.path;
559         tmp.erase(m_ref.path.length()-3);
560         res.push_back(tmp + ".eit");
561         return 0;
562 }
563
564 static int reindex_work(const std::string& filename)
565 {
566         /* This does not work, need to call parser.setPid(pid, type) otherwise
567          * the parser will not actually output any data! */
568
569         eRawFile f;
570
571         int err = f.open(filename.c_str());
572         if (err < 0)
573                 return err;
574
575         eMPEGStreamParserTS parser; /* Missing packetsize, should be determined from stream? */
576
577         {
578                 unsigned int i;
579                 bool timingpidset = false;
580                 eDVBTSTools tstools;
581                 tstools.openFile(filename.c_str(), 1);
582                 eDVBPMTParser::program program;
583                 err = tstools.findPMT(program);
584                 if (err)
585                 {
586                         eDebug("[eDVBPVRServiceOfflineOperations] reindex - Failed to find PMT");
587                         return err;
588                 }
589                 for (i = 0; i < program.videoStreams.size(); i++)
590                 {
591                         if (timingpidset) break;
592                         eDebug("[eDVBPVRServiceOfflineOperations] reindex: video pid=0x%x", program.videoStreams[i].pid);
593                         parser.setPid(program.videoStreams[i].pid, iDVBTSRecorder::video_pid, program.videoStreams[i].type);
594                         timingpidset = true;
595                 }
596                 for (i = 0; i < program.audioStreams.size(); i++)
597                 {
598                         if (timingpidset) break;
599                         eDebug("[eDVBPVRServiceOfflineOperations] reindex: audio pid=0x%x", program.audioStreams[i].pid);
600                         parser.setPid(program.audioStreams[i].pid, iDVBTSRecorder::audio_pid, program.audioStreams[i].type);
601                         timingpidset = true;
602                 }
603         }
604
605         parser.startSave(filename);
606
607         off_t offset = 0;
608         std::vector<char> buffer(188*1024);
609         while (1)
610         {
611                 int r = f.read(offset, &buffer[0], buffer.size());
612                 if (!r)
613                         break;
614                 if (r < 0)
615                         return r;
616                 parser.parseData(offset, &buffer[0], r);
617                 offset += r;
618         }
619
620         parser.stopSave();
621         return 0;
622 }
623
624 RESULT eDVBPVRServiceOfflineOperations::reindex()
625 {
626         int result;
627         /* Release global interpreter lock */
628         Py_BEGIN_ALLOW_THREADS;
629         result = reindex_work(m_ref.path.c_str());
630         Py_END_ALLOW_THREADS;
631         return result;
632 }
633
634 DEFINE_REF(eServiceFactoryDVB)
635
636 eServiceFactoryDVB::eServiceFactoryDVB()
637 {
638         ePtr<eServiceCenter> sc;
639
640         eServiceCenter::getPrivInstance(sc);
641         if (sc)
642         {
643                 std::list<std::string> extensions;
644                 extensions.push_back("ts");
645                 extensions.push_back("trp");
646                 sc->addServiceFactory(eServiceFactoryDVB::id, this, extensions);
647                 /*
648                  * User can indicate that a ts stream is scrambled, by using servicetype id + 0x100
649                  * This only works by specifying the servicetype, we won't allow file extension
650                  * lookup, as we cannot map the same extensions to several service types.
651                  */
652                 extensions.clear();
653                 sc->addServiceFactory(eServiceFactoryDVB::id + 0x100, this, extensions);
654         }
655
656         m_StaticServiceDVBInfo = new eStaticServiceDVBInformation;
657         m_StaticServiceDVBBouquetInfo = new eStaticServiceDVBBouquetInformation;
658 }
659
660 eServiceFactoryDVB::~eServiceFactoryDVB()
661 {
662         ePtr<eServiceCenter> sc;
663
664         eServiceCenter::getPrivInstance(sc);
665         if (sc)
666                 sc->removeServiceFactory(eServiceFactoryDVB::id);
667 }
668
669 DEFINE_REF(eDVBServiceList);
670
671 eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent)
672 {
673 }
674
675 eDVBServiceList::~eDVBServiceList()
676 {
677 }
678
679 RESULT eDVBServiceList::startQuery()
680 {
681         ePtr<iDVBChannelList> db;
682         ePtr<eDVBResourceManager> res;
683
684         int err;
685         if ((err = eDVBResourceManager::getInstance(res)) != 0)
686         {
687                 eDebug("[eDVBServiceList] no resource manager");
688                 return err;
689         }
690         if ((err = res->getChannelList(db)) != 0)
691         {
692                 eDebug("[eDVBServiceList] no channel list");
693                 return err;
694         }
695
696         ePtr<eDVBChannelQuery> q;
697
698         if (!m_parent.path.empty())
699         {
700                 eDVBChannelQuery::compile(q, m_parent.path);
701                 if (!q)
702                 {
703                         eDebug("[eDVBServiceList] compile query failed");
704                         return err;
705                 }
706         }
707
708         if ((err = db->startQuery(m_query, q, m_parent)) != 0)
709         {
710                 eDebug("[eDVBServiceList] startQuery failed");
711                 return err;
712         }
713
714         return 0;
715 }
716
717 RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
718 {
719         eServiceReferenceDVB ref;
720
721         if (!m_query)
722                 return -1;
723
724         while (!m_query->getNextResult(ref))
725                 list.push_back(ref);
726
727         if (sorted)
728                 list.sort(iListableServiceCompare(this));
729
730         return 0;
731 }
732
733 //   The first argument of this function is a format string to specify the order and
734 //   the content of the returned list
735 //   useable format options are
736 //   R = Service Reference (as swig object .. this is very slow)
737 //   S = Service Reference (as python string object .. same as ref.toString())
738 //   C = Service Reference (as python string object .. same as ref.toCompareString())
739 //   N = Service Name (as python string object)
740 //   n = Short Service Name (short name brakets used) (as python string object)
741 //   when exactly one return value per service is selected in the format string,
742 //   then each value is directly a list entry
743 //   when more than one value is returned per service, then the list is a list of
744 //   python tuples
745 //   unknown format string chars are returned as python None values !
746 PyObject *eDVBServiceList::getContent(const char* format, bool sorted)
747 {
748         ePyObject ret;
749         std::list<eServiceReference> tmplist;
750         int retcount=1;
751
752         if (!format || !(retcount=strlen(format)))
753                 format = "R"; // just return service reference swig object ...
754
755         if (!getContent(tmplist, sorted))
756         {
757                 int services=tmplist.size();
758                 ePtr<iStaticServiceInformation> sptr;
759                 eServiceCenterPtr service_center;
760
761                 if (strchr(format, 'N') || strchr(format, 'n'))
762                         eServiceCenter::getPrivInstance(service_center);
763
764                 ret = PyList_New(services);
765                 std::list<eServiceReference>::iterator it(tmplist.begin());
766
767                 for (int cnt=0; cnt < services; ++cnt)
768                 {
769                         eServiceReference &ref=*it++;
770                         ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : ePyObject();
771                         for (int i=0; i < retcount; ++i)
772                         {
773                                 ePyObject tmp;
774                                 switch(format[i])
775                                 {
776                                 case 'R':  // service reference (swig)object
777                                         tmp = NEW_eServiceReference(ref);
778                                         break;
779                                 case 'C':  // service reference compare string
780                                         tmp = PyString_FromString(ref.toCompareString().c_str());
781                                         break;
782                                 case 'S':  // service reference string
783                                         tmp = PyString_FromString(ref.toString().c_str());
784                                         break;
785                                 case 'N':  // service name
786                                         if (service_center)
787                                         {
788                                                 service_center->info(ref, sptr);
789                                                 if (sptr)
790                                                 {
791                                                         std::string name;
792                                                         sptr->getName(ref, name);
793
794                                                         // filter short name brakets
795                                                         size_t pos;
796                                                         while((pos = name.find("\xc2\x86")) != std::string::npos)
797                                                                 name.erase(pos,2);
798                                                         while((pos = name.find("\xc2\x87")) != std::string::npos)
799                                                                 name.erase(pos,2);
800
801                                                         if (name.length())
802                                                                 tmp = PyString_FromString(name.c_str());
803                                                 }
804                                         }
805                                         if (!tmp)
806                                                 tmp = PyString_FromString("<n/a>");
807                                         break;
808                                 case 'n':  // short service name
809                                         if (service_center)
810                                         {
811                                                 service_center->info(ref, sptr);
812                                                 if (sptr)
813                                                 {
814                                                         std::string name;
815                                                         sptr->getName(ref, name);
816                                                         name = buildShortName(name);
817                                                         if (name.length())
818                                                                 tmp = PyString_FromString(name.c_str());
819                                                 }
820                                         }
821                                         if (!tmp)
822                                                 tmp = PyString_FromString("<n/a>");
823                                         break;
824                                 default:
825                                         if (tuple)
826                                         {
827                                                 tmp = Py_None;
828                                                 Py_INCREF(Py_None);
829                                         }
830                                         break;
831                                 }
832                                 if (tmp)
833                                 {
834                                         if (tuple)
835                                                 PyTuple_SET_ITEM(tuple, i, tmp);
836                                         else
837                                                 PyList_SET_ITEM(ret, cnt, tmp);
838                                 }
839                         }
840                         if (tuple)
841                                 PyList_SET_ITEM(ret, cnt, tuple);
842                 }
843         }
844         return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
845 }
846
847 RESULT eDVBServiceList::getNext(eServiceReference &ref)
848 {
849         if (!m_query)
850                 return -1;
851
852         return m_query->getNextResult((eServiceReferenceDVB&)ref);
853 }
854
855 RESULT eDVBServiceList::startEdit(ePtr<iMutableServiceList> &res)
856 {
857         if (m_parent.flags & eServiceReference::canDescent) // bouquet
858         {
859                 ePtr<iDVBChannelList> db;
860                 ePtr<eDVBResourceManager> resm;
861
862                 if (eDVBResourceManager::getInstance(resm) || resm->getChannelList(db))
863                         return -1;
864
865                 if (db->getBouquet(m_parent, m_bouquet) != 0)
866                         return -1;
867
868                 res = this;
869
870                 return 0;
871         }
872         res = 0;
873         return -1;
874 }
875
876 RESULT eDVBServiceList::addService(eServiceReference &ref, eServiceReference before)
877 {
878         if (!m_bouquet)
879                 return -1;
880         return m_bouquet->addService(ref, before);
881 }
882
883 RESULT eDVBServiceList::removeService(eServiceReference &ref, bool renameBouquet)
884 {
885         if (!m_bouquet)
886                 return -1;
887         return m_bouquet->removeService(ref, renameBouquet);
888 }
889
890 RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
891 {
892         if (!m_bouquet)
893                 return -1;
894         return m_bouquet->moveService(ref, pos);
895 }
896
897 RESULT eDVBServiceList::flushChanges()
898 {
899         if (!m_bouquet)
900                 return -1;
901         return m_bouquet->flushChanges();
902 }
903
904 RESULT eDVBServiceList::setListName(const std::string &name)
905 {
906         if (!m_bouquet)
907                 return -1;
908         return m_bouquet->setListName(name);
909 }
910
911 RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
912 {
913         ePtr<eDVBService> service;
914         int r = lookupService(service, ref);
915         if (r)
916                 service = 0;
917                 // check resources...
918         ptr = new eDVBServicePlay(ref, service);
919         return 0;
920 }
921
922 RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
923 {
924         bool isstream = ref.path.substr(0, 7) == "http://";
925         ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref, isstream);
926         return 0;
927 }
928
929 RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
930 {
931         ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
932         if (list->startQuery())
933         {
934                 ptr = 0;
935                 return -1;
936         }
937
938         ptr = list;
939         return 0;
940 }
941
942 RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
943 {
944         /* is a listable service? */
945         if (ref.flags & eServiceReference::canDescent) // bouquet
946         {
947                 if ( !ref.name.empty() )  // satellites or providers list
948                         ptr = m_StaticServiceDVBInfo;
949                 else // a dvb bouquet
950                         ptr = m_StaticServiceDVBBouquetInfo;
951         }
952         else if (!ref.path.empty()) /* do we have a PVR service? */
953                 ptr = new eStaticServiceDVBPVRInformation(ref);
954         else // normal dvb service
955         {
956                 ePtr<eDVBService> service;
957                 if (lookupService(service, ref)) // no eDVBService avail for this reference ( Linkage Services... )
958                         ptr = m_StaticServiceDVBInfo;
959                 else
960                         /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
961                         ptr = service;
962         }
963         return 0;
964 }
965
966 RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
967 {
968         if (ref.path.empty())
969         {
970                 ptr = 0;
971                 return -1;
972         } else
973         {
974                 ptr = new eDVBPVRServiceOfflineOperations(ref);
975                 return 0;
976         }
977 }
978
979 RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
980 {
981         if (!ref.path.empty()) // playback
982         {
983                 eDVBMetaParser parser;
984                 int ret=parser.parseFile(ref.path);
985                 service = new eDVBService;
986                 if (!ret)
987                         eDVBDB::getInstance()->parseServiceData(service, parser.m_service_data);
988         }
989         else
990         {
991                         // TODO: handle the listing itself
992                 // if (ref.... == -1) .. return "... bouquets ...";
993                 // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
994                         // TODO: cache
995                 ePtr<iDVBChannelList> db;
996                 ePtr<eDVBResourceManager> res;
997
998                 int err;
999                 if ((err = eDVBResourceManager::getInstance(res)) != 0)
1000                 {
1001                         eDebug("[eServiceFactoryDVB] no resource manager");
1002                         return err;
1003                 }
1004                 if ((err = res->getChannelList(db)) != 0)
1005                 {
1006                         eDebug("[eServiceFactoryDVB] no channel list");
1007                         return err;
1008                 }
1009
1010                 /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
1011                 if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
1012                 {
1013 //                      eDebug("[eServiceFactoryDVB] getService failed!");
1014                         return err;
1015                 }
1016         }
1017
1018         return 0;
1019 }
1020
1021 eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
1022         m_reference(ref),
1023         m_dvb_service(service),
1024         m_decoder_index(0),
1025         m_have_video_pid(0),
1026         m_tune_state(-1),
1027         m_is_stream(ref.path.substr(0, 7) == "http://"),
1028         m_is_pvr(!ref.path.empty() && !m_is_stream),
1029         m_is_paused(0),
1030         m_timeshift_enabled(0),
1031         m_timeshift_active(0),
1032         m_timeshift_changed(0),
1033         m_save_timeshift(0),
1034         m_timeshift_fd(-1),
1035         m_skipmode(0),
1036         m_fastforward(0),
1037         m_slowmotion(0),
1038         m_cuesheet_changed(0),
1039         m_cutlist_enabled(1),
1040         m_subtitle_widget(0),
1041         m_subtitle_sync_timer(eTimer::create(eApp)),
1042         m_nownext_timer(eTimer::create(eApp))
1043 {
1044         CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
1045         CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
1046         CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
1047         CONNECT(m_subtitle_sync_timer->timeout, eDVBServicePlay::checkSubtitleTiming);
1048         CONNECT(m_nownext_timer->timeout, eDVBServicePlay::updateEpgCacheNowNext);
1049 }
1050
1051 eDVBServicePlay::~eDVBServicePlay()
1052 {
1053         if (m_is_pvr)
1054         {
1055                 eDVBMetaParser meta;
1056                 int ret=meta.parseFile(m_reference.path);
1057                 if (!ret)
1058                 {
1059                         char tmp[255];
1060                         meta.m_service_data="";
1061                         sprintf(tmp, "f:%x", m_dvb_service->m_flags);
1062                         meta.m_service_data += tmp;
1063                         // cached pids
1064                         for (int x=0; x < eDVBService::cacheMax; ++x)
1065                         {
1066                                 int entry = m_dvb_service->getCacheEntry((eDVBService::cacheID)x);
1067                                 if (entry != -1)
1068                                 {
1069                                         sprintf(tmp, ",c:%02d%04x", x, entry);
1070                                         meta.m_service_data += tmp;
1071                                 }
1072                         }
1073                         meta.updateMeta(m_reference.path);
1074                 }
1075         }
1076         if (m_subtitle_widget) m_subtitle_widget->destroy();
1077 }
1078
1079 void eDVBServicePlay::gotNewEvent(int error)
1080 {
1081         ePtr<eServiceEvent> event_now;
1082         getEvent(event_now, 0);
1083 #if 0
1084                 // debug only
1085         ePtr<eServiceEvent> event_next;
1086         getEvent(event_next, 1);
1087
1088         if (event_now)
1089                 eDebug("[eDVBServicePlay] now running: %s (%d seconds :)", event_now->m_event_name.c_str(), event_now->m_duration);
1090         if (event_next)
1091                 eDebug("[eDVBServicePlay] next running: %s (%d seconds :)", event_next->m_event_name.c_str(), event_next->m_duration);
1092 #endif
1093         if (!error)
1094         {
1095                 m_nownext_timer->stop();
1096                 m_event((iPlayableService*)this, evUpdatedEventInfo);
1097         }
1098         else
1099         {
1100                 /* our eit reader has stopped, we have to take care of our own event updates */
1101                 updateEpgCacheNowNext();
1102         }
1103
1104         if (m_timeshift_enabled)
1105         {
1106                 if (!event_now)
1107                         return;
1108
1109                 pts_t now_pts, first_pts, fixup_pts;
1110                 if (m_record)
1111                 {
1112                         if (m_record->getCurrentPCR(now_pts))
1113                                 eDebug("[eDVBServicePlay] getting current PTS failed!");
1114                         else
1115                         {
1116                                 if (m_record->getFirstPTS(first_pts))
1117                                         return;
1118                                 if (now_pts < first_pts)
1119                                         fixup_pts = now_pts + 0x200000000LL - first_pts;
1120                                 else
1121                                         fixup_pts = now_pts - first_pts;
1122                                 m_cue_entries.insert(cueEntry(fixup_pts, 2));
1123                                 m_cuesheet_changed = 1;
1124                                 eDebug("[eDVBServicePlay] pts of eit change: %llx, fixup_pts: %llx, first_pts: %llx", now_pts, fixup_pts, first_pts);
1125                                 m_event((iPlayableService*)this, evCuesheetChanged);
1126                         }
1127                 }
1128         }
1129 }
1130
1131 void eDVBServicePlay::updateEpgCacheNowNext()
1132 {
1133         bool update = false;
1134         ePtr<eServiceEvent> next = 0;
1135         ePtr<eServiceEvent> ptr = 0;
1136         eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
1137         if (eEPGCache::getInstance() && eEPGCache::getInstance()->lookupEventTime(ref, -1, ptr) >= 0)
1138         {
1139                 ePtr<eServiceEvent> current = 0;
1140                 m_event_handler.getEvent(current, 0);
1141                 if (!current || !ptr || current->getEventId() != ptr->getEventId())
1142                 {
1143                         update = true;
1144                         m_event_handler.inject(ptr, 0);
1145                         time_t next_time = ptr->getBeginTime() + ptr->getDuration();
1146                         if (eEPGCache::getInstance()->lookupEventTime(ref, next_time, ptr) >= 0)
1147                         {
1148                                 next = ptr;
1149                                 m_event_handler.inject(ptr, 1);
1150                         }
1151                 }
1152         }
1153
1154         int refreshtime = 60;
1155         if (!next)
1156         {
1157                 m_event_handler.getEvent(next, 1);
1158         }
1159         if (next)
1160         {
1161                 time_t now = eDVBLocalTimeHandler::getInstance()->nowTime();
1162                 refreshtime = (int)(next->getBeginTime() - now) + 3;
1163                 if (refreshtime <= 0 || refreshtime > 60) refreshtime = 60;
1164         }
1165         m_nownext_timer->startLongTimer(refreshtime);
1166         if (update) m_event((iPlayableService*)this, evUpdatedEventInfo);
1167 }
1168
1169 void eDVBServicePlay::serviceEvent(int event)
1170 {
1171         m_tune_state = event;
1172
1173         switch (event)
1174         {
1175         case eDVBServicePMTHandler::eventTuned:
1176         {
1177                 /* fill now/next with info from the epg cache, will be replaced by EIT when it arrives */
1178                 updateEpgCacheNowNext();
1179
1180                 /* default behaviour is to start an eit reader, and wait for now/next info, unless this is disabled */
1181                 if (eConfigManager::getConfigBoolValue("config.usage.show_eit_nownext", true))
1182                 {
1183                         ePtr<iDVBDemux> m_demux;
1184                         if (!m_service_handler.getDataDemux(m_demux))
1185                         {
1186                                 eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
1187                                 int sid = ref.getParentServiceID().get();
1188                                 if (!sid)
1189                                         sid = ref.getServiceID().get();
1190
1191                                 if ( ref.getParentTransportStreamID().get() &&
1192                                         ref.getParentTransportStreamID() != ref.getTransportStreamID() )
1193                                         m_event_handler.startOther(m_demux, sid);
1194                                 else
1195                                         m_event_handler.start(m_demux, sid);
1196                         }
1197                 }
1198                 m_event((iPlayableService*)this, evTunedIn);
1199                 break;
1200         }
1201         case eDVBServicePMTHandler::eventNoResources:
1202         case eDVBServicePMTHandler::eventNoPAT:
1203         case eDVBServicePMTHandler::eventNoPATEntry:
1204         case eDVBServicePMTHandler::eventNoPMT:
1205         case eDVBServicePMTHandler::eventTuneFailed:
1206         case eDVBServicePMTHandler::eventMisconfiguration:
1207         {
1208                 eDebug("[eDVBServicePlay] DVB service failed to tune - error %d", event);
1209                 m_event((iPlayableService*)this, evTuneFailed);
1210                 break;
1211         }
1212         case eDVBServicePMTHandler::eventNewProgramInfo:
1213         {
1214                 eDebug("[eDVBServicePlay] eventNewProgramInfo timeshift_enabled=%d timeshift_active=%d", m_timeshift_enabled, m_timeshift_active);
1215                 if (m_timeshift_enabled)
1216                         updateTimeshiftPids();
1217                 if (!m_timeshift_active)
1218                         updateDecoder();
1219                 if (m_first_program_info & 1 && m_is_pvr)
1220                 {
1221                         m_first_program_info &= ~1;
1222                         seekTo(0);
1223                 }
1224                 if (!m_timeshift_active)
1225                         m_event((iPlayableService*)this, evUpdatedInfo);
1226
1227                 m_event((iPlayableService*)this, evNewProgramInfo);
1228                 break;
1229         }
1230         case eDVBServicePMTHandler::eventPreStart:
1231                 loadCuesheet();
1232                 break;
1233         case eDVBServicePMTHandler::eventEOF:
1234                 m_event((iPlayableService*)this, evEOF);
1235                 break;
1236         case eDVBServicePMTHandler::eventSOF:
1237                 m_event((iPlayableService*)this, evSOF);
1238                 break;
1239         case eDVBServicePMTHandler::eventHBBTVInfo:
1240                 m_event((iPlayableService*)this, evHBBTVInfo);
1241                 break;
1242         }
1243 }
1244
1245 void eDVBServicePlay::serviceEventTimeshift(int event)
1246 {
1247         switch (event)
1248         {
1249         case eDVBServicePMTHandler::eventNewProgramInfo:
1250                 eDebug("[eDVBServicePlay] eventNewProgramInfo TimeshiftS");
1251                 if (m_timeshift_active)
1252                 {
1253                         updateDecoder();
1254                         if (m_first_program_info & 2)
1255                         {
1256                                 if (m_slowmotion)
1257                                 {
1258                                         eDebug("[eDVBServicePlay] re-apply slowmotion after timeshift file change");
1259                                         m_decoder->setSlowMotion(m_slowmotion);
1260                                 }
1261                                 if (m_fastforward)
1262                                 {
1263                                         eDebug("[eDVBServicePlay] re-apply skip %d, ratio %d after timeshift file change", m_skipmode, m_fastforward);
1264                                         if (m_skipmode)
1265                                                 m_cue->setSkipmode(m_skipmode * 90000); /* convert to 90000 per second */
1266                                         if (m_fastforward != 1)
1267                                                 m_decoder->setFastForward(m_fastforward);
1268                                         else
1269                                                 m_decoder->setTrickmode();
1270                                 }
1271                                 else
1272                                         seekTo(0);
1273                                 m_first_program_info &= ~2;
1274                         }
1275                         m_event((iPlayableService*)this, evUpdatedInfo);
1276                 }
1277                 break;
1278         case eDVBServicePMTHandler::eventSOF:
1279 #if 0
1280                 if (!m_timeshift_file_next.empty())
1281                 {
1282                         eDebug("[eDVBServicePlay] timeshift SOF, switch to next file");
1283                         m_decoder->pause();
1284
1285                         m_first_program_info |= 2;
1286
1287                         eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
1288                         r.path = m_timeshift_file_next;
1289
1290                         /* free the timeshift service handler, we need the resources */
1291                         m_service_handler_timeshift.free();
1292                         resetTimeshift(1);
1293
1294                         if (m_skipmode < 0)
1295                                 m_cue->seekTo(0, -1000);
1296                         ePtr<iTsSource> source = createTsSource(r);
1297                         m_service_handler_timeshift.tuneExt(r, source, r.path.c_str(), m_cue, 0, m_dvb_service, false); /* use the decoder demux for everything */
1298
1299                         m_event((iPlayableService*)this, evUser+1);
1300                 }
1301                 else
1302 #endif
1303                         m_event((iPlayableService*)this, evSOF);
1304                 break;
1305         case eDVBServicePMTHandler::eventEOF:
1306                 if ((!m_is_paused) && (m_skipmode >= 0))
1307                 {
1308                         if (m_timeshift_file_next.empty())
1309                         {
1310                                 eDebug("[eDVBServicePlay] timeshift EOF, so let's go live");
1311                                 switchToLive();
1312                         }
1313                         else
1314                         {
1315                                 eDebug("[eDVBServicePlay] timeshift EOF, switch to next file");
1316
1317                                 m_first_program_info |= 2;
1318
1319                                 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
1320                                 r.path = m_timeshift_file_next;
1321
1322                                 /* free the timeshift service handler, we need the resources */
1323                                 m_service_handler_timeshift.free();
1324                                 resetTimeshift(1);
1325
1326                                 ePtr<iTsSource> source = createTsSource(r);
1327                                 m_service_handler_timeshift.tuneExt(r, source, m_timeshift_file_next.c_str(), m_cue, 0, m_dvb_service, eDVBServicePMTHandler::timeshift_playback, false); /* use the decoder demux for everything */
1328
1329                                 m_event((iPlayableService*)this, evUser+1);
1330                         }
1331                 }
1332                 break;
1333         }
1334 }
1335
1336 RESULT eDVBServicePlay::start()
1337 {
1338         eServiceReferenceDVB service = (eServiceReferenceDVB&)m_reference;
1339         bool scrambled = true;
1340         int packetsize = 188;
1341         eDVBServicePMTHandler::serviceType type = eDVBServicePMTHandler::livetv;
1342
1343         if(tryFallbackTuner(/*REF*/service, /*REF*/m_is_stream, m_is_pvr, /*simulate*/false))
1344                 eDebug("ServicePlay: fallback tuner selected");
1345
1346                 /* in pvr mode, we only want to use one demux. in tv mode, we're using
1347                    two (one for decoding, one for data source), as we must be prepared
1348                    to start recording from the data demux. */
1349         if (m_is_pvr)
1350         {
1351                 eDVBMetaParser meta;
1352                 if (!meta.parseFile(m_reference.path))
1353                 {
1354                         service = meta.m_ref;
1355                         service.path = m_reference.path;
1356                         packetsize = meta.m_packet_size;
1357                         scrambled = meta.m_scrambled;
1358                 }
1359                 else
1360                 {
1361                         /* when there is no meta file we need to handle ts/m2ts as descrambled */
1362                         scrambled = false;
1363                 }
1364                 m_cue = new eCueSheet();
1365                 type = eDVBServicePMTHandler::playback;
1366         }
1367         else
1368                 m_event(this, evStart);
1369
1370         if (m_is_stream)
1371         {
1372                 /*
1373                  * streams are considered to be descrambled by default;
1374                  * user can indicate a stream is scrambled, by using servicetype id + 0x100
1375                  */
1376                 bool config_descramble_client = eConfigManager::getConfigBoolValue("config.streaming.descramble_client", false);
1377
1378                 scrambled = (m_reference.type == eServiceFactoryDVB::id + 0x100);
1379
1380                 if(config_descramble_client)
1381                         scrambled = true;
1382
1383                 type = eDVBServicePMTHandler::streamclient;
1384         }
1385
1386         m_first_program_info = 1;
1387         ePtr<iTsSource> source = createTsSource(service, packetsize);
1388         m_service_handler.tuneExt(service, source, service.path.c_str(), m_cue, false, m_dvb_service, type, scrambled);
1389
1390         if (m_is_pvr)
1391         {
1392                 /* inject EIT if there is a stored one */
1393                 std::string filename = service.path;
1394                 filename.erase(filename.length()-2, 2);
1395                 filename+="eit";
1396                 ePtr<eServiceEvent> event = new eServiceEvent;
1397                 if (!event->parseFrom(filename, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get()))
1398                 {
1399                         ePtr<eServiceEvent> empty;
1400                         m_event_handler.inject(event, 0);
1401                         m_event_handler.inject(empty, 1);
1402                 }
1403                 m_event(this, evStart);
1404         }
1405         return 0;
1406 }
1407
1408 RESULT eDVBServicePlay::stop()
1409 {
1410                 /* add bookmark for last play position */
1411                 /* m_cutlist_enabled bit 2 is the "don't remember bit" */
1412         if (m_is_pvr && ((m_cutlist_enabled & 2) == 0))
1413         {
1414                 pts_t play_position, length;
1415                 if (!getPlayPosition(play_position))
1416                 {
1417                                 /* remove last position */
1418                         for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end();)
1419                         {
1420                                 if (i->what == 3) /* current play position */
1421                                 {
1422                                         m_cue_entries.erase(i);
1423                                         i = m_cue_entries.begin();
1424                                         continue;
1425                                 } else
1426                                         ++i;
1427                         }
1428
1429                         if (getLength(length))
1430                                 length = 0;
1431
1432                         if (length)
1433                         {
1434                                 m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
1435                         }
1436                         m_cuesheet_changed = 1;
1437                 }
1438         }
1439
1440         if ((m_is_pvr || m_timeshift_enabled) && m_cuesheet_changed)
1441         {
1442                 saveCuesheet();
1443         }
1444
1445         stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
1446
1447         m_service_handler_timeshift.free();
1448         m_service_handler.free();
1449
1450         m_nownext_timer->stop();
1451         m_event((iPlayableService*)this, evStopped);
1452         return 0;
1453 }
1454
1455 RESULT eDVBServicePlay::setTarget(int target)
1456 {
1457         m_decoder_index = target;
1458         return 0;
1459 }
1460
1461 RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
1462 {
1463         connection = new eConnection((iPlayableService*)this, m_event.connect(event));
1464         return 0;
1465 }
1466
1467 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
1468 {
1469                 /* note: we check for timeshift to be enabled,
1470                    not neccessary active. if you pause when timeshift
1471                    is not active, you should activate it when unpausing */
1472         if ((!m_is_pvr) && (!m_timeshift_enabled))
1473         {
1474                 ptr = 0;
1475                 return -1;
1476         }
1477
1478         ptr = this;
1479         return 0;
1480 }
1481
1482 RESULT eDVBServicePlay::setSlowMotion(int ratio)
1483 {
1484         int ret = 0;
1485         ASSERT(ratio); /* The API changed: instead of calling setSlowMotion(0), call play! */
1486         eDebug("[eDVBServicePlay] setSlowMotion %d", ratio);
1487         setFastForward_internal(0);
1488         if (m_decoder)
1489         {
1490                 ret = m_decoder->setSlowMotion(ratio);
1491                 if (!ret)
1492                         m_slowmotion = ratio;
1493                 return ret;
1494         }
1495         else
1496                 return -1;
1497 }
1498
1499 RESULT eDVBServicePlay::setFastForward(int ratio)
1500 {
1501         eDebug("[eDVBServicePlay] setFastForward %d", ratio);
1502         ASSERT(ratio);
1503         return setFastForward_internal(ratio);
1504 }
1505
1506 RESULT eDVBServicePlay::setFastForward_internal(int ratio, bool final_seek)
1507 {
1508         int skipmode, ffratio, ret = 0;
1509         pts_t pos=0;
1510
1511         if (ratio > 8)
1512         {
1513                 skipmode = ratio;
1514                 ffratio = 1;
1515         } else if (ratio > 0)
1516         {
1517                 skipmode = 0;
1518                 ffratio = ratio;
1519         } else if (!ratio)
1520         {
1521                 skipmode = 0;
1522                 ffratio = 0;
1523         } else // if (ratio < 0)
1524         {
1525                 skipmode = ratio;
1526                 ffratio = 1;
1527         }
1528
1529         if (m_skipmode != skipmode)
1530         {
1531                 eDebug("[eDVBServicePlay] setFastForward setting cue skipmode to %d", skipmode);
1532                 if (m_cue)
1533                         m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
1534         }
1535
1536         m_skipmode = skipmode;
1537
1538         if (final_seek)
1539                 eDebug("[eDVBServicePlay] setFastForward trickplay stopped .. ret %d, pos %lld", getPlayPosition(pos), pos);
1540
1541         m_fastforward = ffratio;
1542
1543         if (!m_decoder)
1544                 return -1;
1545
1546         if (ffratio == 0)
1547                 ; /* return m_decoder->play(); is done in caller*/
1548         else if (ffratio != 1)
1549                 ret = m_decoder->setFastForward(ffratio);
1550         else
1551                 ret = m_decoder->setTrickmode();
1552
1553         if (pos)
1554                 eDebug("[eDVBServicePlay] setFastForward final seek after trickplay ret %d", seekTo(pos));
1555
1556         return ret;
1557 }
1558
1559 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
1560 {
1561         if (m_is_pvr || m_timeshift_enabled)
1562         {
1563                 ptr = this;
1564                 return 0;
1565         }
1566
1567         ptr = 0;
1568         return -1;
1569 }
1570
1571         /* TODO: when timeshift is enabled but not active, this doesn't work. */
1572 RESULT eDVBServicePlay::getLength(pts_t &len)
1573 {
1574         ePtr<iDVBPVRChannel> pvr_channel;
1575
1576         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1577                 return -1;
1578
1579         return pvr_channel->getLength(len);
1580 }
1581
1582 RESULT eDVBServicePlay::pause()
1583 {
1584         eDebug("[eDVBServicePlay] pause");
1585         setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
1586         if (m_decoder)
1587         {
1588                 m_slowmotion = 0;
1589                 m_is_paused = 1;
1590                 return m_decoder->pause();
1591         } else
1592                 return -1;
1593 }
1594
1595 RESULT eDVBServicePlay::unpause()
1596 {
1597         eDebug("[eDVBServicePlay] unpause");
1598         setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
1599         if (m_decoder)
1600         {
1601                 m_slowmotion = 0;
1602                 m_is_paused = 0;
1603                 return m_decoder->play();
1604         } else
1605                 return -1;
1606 }
1607
1608 RESULT eDVBServicePlay::seekTo(pts_t to)
1609 {
1610         eDebug("[eDVBServicePlay] seekTo %lld", to);
1611
1612         if (!m_decode_demux)
1613                 return -1;
1614
1615         ePtr<iDVBPVRChannel> pvr_channel;
1616
1617         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1618                 return -1;
1619
1620         if (!m_cue)
1621                 return -1;
1622
1623         m_cue->seekTo(0, to);
1624         m_dvb_subtitle_pages.clear();
1625         m_subtitle_pages.clear();
1626
1627         return 0;
1628 }
1629
1630 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
1631 {
1632         eDebug("[eDVBServicePlay] seekRelative %d, %lld", direction, to);
1633
1634         if (!m_decode_demux)
1635                 return -1;
1636
1637         ePtr<iDVBPVRChannel> pvr_channel;
1638
1639         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1640                 return -1;
1641
1642         int mode = 1;
1643
1644                         /* HACK until we have skip-AP api */
1645         if ((to > 0) && (to < 100))
1646                 mode = 2;
1647
1648         to *= direction;
1649
1650         if (!m_cue)
1651                 return 0;
1652
1653         m_cue->seekTo(mode, to);
1654         m_dvb_subtitle_pages.clear();
1655         m_subtitle_pages.clear();
1656         return 0;
1657 }
1658
1659 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
1660 {
1661         ePtr<iDVBPVRChannel> pvr_channel;
1662
1663         if (!m_decode_demux)
1664                 return -1;
1665
1666         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1667                 return -1;
1668
1669         int r = 0;
1670
1671                 /* if there is a decoder, use audio or video PTS */
1672         if (m_decoder)
1673         {
1674                 r = m_decoder->getPTS(0, pos);
1675                 if (r)
1676                         return r;
1677         }
1678
1679                 /* fixup */
1680         return pvr_channel->getCurrentPosition(m_decode_demux, pos, m_decoder);
1681 }
1682
1683 RESULT eDVBServicePlay::setTrickmode(int trick)
1684 {
1685                 /* currently unimplemented */
1686         return -1;
1687 }
1688
1689 RESULT eDVBServicePlay::isCurrentlySeekable()
1690 {
1691         return (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
1692 }
1693
1694 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
1695 {
1696         ptr = this;
1697         return 0;
1698 }
1699
1700 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
1701 {
1702         ptr = this;
1703         return 0;
1704 }
1705
1706 RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
1707 {
1708         ptr = this;
1709         return 0;
1710 }
1711
1712 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
1713 {
1714         ptr = this;
1715         return 0;
1716 }
1717
1718 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
1719 {
1720         ptr = this;
1721         return 0;
1722 }
1723
1724 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
1725 {
1726         ptr = 0;
1727         eDebug("[eDVBServicePlay] timeshift");
1728         if (m_timeshift_enabled || !m_is_pvr)
1729         {
1730                 if (!m_timeshift_enabled)
1731                 {
1732                         /* query config path */
1733                         std::string tspath = eConfigManager::getConfigValue("config.usage.timeshift_path");
1734                         if(tspath == "")
1735                         {
1736                                 eDebug("[eDVBServicePlay] timeshift could not query ts path from config");
1737                                 return -4;
1738                         }
1739                         tspath.append("/");
1740                         /* we need enough diskspace */
1741                         struct statfs fs;
1742                         if (statfs(tspath.c_str(), &fs) < 0)
1743                         {
1744                                 eDebug("[eDVBServicePlay] timeshift %s statfs failed: %m", tspath.c_str());
1745                                 return -2;
1746                         }
1747
1748                         if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 200*1024*1024LL)
1749                         {
1750                                 eDebug("[eDVBServicePlay] timeshift not enough diskspace for timeshift! (less than 200MB)");
1751                                 return -3;
1752                         }
1753                 }
1754                 ptr = this;
1755                 return 0;
1756         }
1757         return -1;
1758 }
1759
1760 RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
1761 {
1762         if (m_is_pvr || m_timeshift_enabled)
1763         {
1764                 ptr = this;
1765                 return 0;
1766         }
1767         ptr = 0;
1768         return -1;
1769 }
1770
1771 RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
1772 {
1773         ptr = this;
1774         return 0;
1775 }
1776
1777 RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
1778 {
1779         ptr = this;
1780         return 0;
1781 }
1782
1783 RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
1784 {
1785         ptr = this;
1786         return 0;
1787 }
1788
1789 RESULT eDVBServicePlay::streamed(ePtr<iStreamedService> &ptr)
1790 {
1791         if (m_is_stream)
1792         {
1793                 ptr = this;
1794                 return 0;
1795         }
1796         ptr = 0;
1797         return -1;
1798 }
1799
1800 ePtr<iStreamBufferInfo> eDVBServicePlay::getBufferCharge()
1801 {
1802         /** FIXME **/
1803         return 0;
1804 }
1805
1806 int eDVBServicePlay::setBufferSize(int size)
1807 {
1808         /** FIXME **/
1809         return 0;
1810 }
1811
1812 RESULT eDVBServicePlay::getName(std::string &name)
1813 {
1814         if (m_is_pvr)
1815         {
1816                 ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
1817                 return i->getName(m_reference, name);
1818         }
1819         else if (m_is_stream)
1820         {
1821                 if (m_dvb_service)
1822                         m_dvb_service->getName(m_reference, name);
1823                 else
1824                         name = "unknown service";
1825                 if (name.empty())
1826                         name = m_reference.name;
1827                         if (name.empty())
1828                                 name = m_reference.path;
1829                                 if (name.empty())
1830                                         name = "(...)";
1831         }
1832         else if (m_dvb_service)
1833         {
1834                 m_dvb_service->getName(m_reference, name);
1835                 if (name.empty())
1836                         name = "(...)";
1837         }
1838         else if (!m_reference.name.empty())
1839                 eStaticServiceDVBInformation().getName(m_reference, name);
1840         else
1841                 name = "DVB service";
1842         return 0;
1843 }
1844
1845 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
1846 {
1847         return m_event_handler.getEvent(evt, nownext);
1848 }
1849
1850 int eDVBServicePlay::getInfo(int w)
1851 {
1852         eDVBServicePMTHandler::program program;
1853
1854         if (w == sCAIDs || w == sCAIDPIDs)
1855                 return resIsPyObject;
1856
1857         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1858
1859         int no_program_info = 0;
1860
1861         if (h.getProgramInfo(program))
1862                 no_program_info = 1;
1863
1864         switch (w)
1865         {
1866         case sVideoHeight:
1867                 if (m_decoder)
1868                         return m_decoder->getVideoHeight();
1869                 break;
1870         case sVideoWidth:
1871                 if (m_decoder)
1872                         return m_decoder->getVideoWidth();
1873                 break;
1874         case sFrameRate:
1875                 if (m_decoder)
1876                         return m_decoder->getVideoFrameRate();
1877                 break;
1878         case sProgressive:
1879                 if (m_decoder)
1880                         return m_decoder->getVideoProgressive();
1881                 break;
1882         case sAspect:
1883         {
1884                 int aspect = -1;
1885                 if (m_decoder)
1886                         aspect = m_decoder->getVideoAspect();
1887                 if (aspect == -1 && no_program_info)
1888                         break;
1889                 else if (aspect == -1 && !program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
1890                 {
1891                         ePtr<eServiceEvent> evt;
1892                         if (!m_event_handler.getEvent(evt, 0))
1893                         {
1894                                 ePtr<eComponentData> data;
1895                                 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
1896                                 {
1897                                         if ( data->getStreamContent() == 1 )
1898                                         {
1899                                                 switch(data->getComponentType())
1900                                                 {
1901                                                         // SD
1902                                                         case 1: // 4:3 SD PAL
1903                                                         case 2:
1904                                                         case 3: // 16:9 SD PAL
1905                                                         case 4: // > 16:9 PAL
1906                                                         case 5: // 4:3 SD NTSC
1907                                                         case 6:
1908                                                         case 7: // 16:9 SD NTSC
1909                                                         case 8: // > 16:9 NTSC
1910
1911                                                         // HD
1912                                                         case 9: // 4:3 HD PAL
1913                                                         case 0xA:
1914                                                         case 0xB: // 16:9 HD PAL
1915                                                         case 0xC: // > 16:9 HD PAL
1916                                                         case 0xD: // 4:3 HD NTSC
1917                                                         case 0xE:
1918                                                         case 0xF: // 16:9 HD NTSC
1919                                                         case 0x10: // > 16:9 HD PAL
1920                                                                 return data->getComponentType();
1921                                                 }
1922                                         }
1923                                 }
1924                         }
1925                 }
1926                 else
1927                         return aspect;
1928                 break;
1929         }
1930         case sIsCrypted: if (no_program_info) return false; return program.isCrypted();
1931         case sIsDedicated3D: if (m_dvb_service) return m_dvb_service->isDedicated3D(); return false;
1932         case sVideoPID:
1933                 if (m_dvb_service)
1934                 {
1935                         int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
1936                         if (vpid != -1)
1937                                 return vpid;
1938                 }
1939                 if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
1940         case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
1941         case sAudioPID:
1942                 if (m_dvb_service)
1943                 {
1944                         int apid = m_dvb_service->getCacheEntry(eDVBService::cMPEGAPID);
1945                         if (apid != -1)
1946                                 return apid;
1947                         apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
1948                         if (apid != -1)
1949                                 return apid;
1950                         apid = m_dvb_service->getCacheEntry(eDVBService::cDDPPID);
1951                         if (apid != -1)
1952                                 return apid;
1953                         apid = m_dvb_service->getCacheEntry(eDVBService::cAACHEAPID);
1954                         if (apid != -1)
1955                                 return apid;
1956                         apid = m_dvb_service->getCacheEntry(eDVBService::cAACAPID);
1957                         if (apid != -1)
1958                                 return apid;
1959                 }
1960                 if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
1961         case sPCRPID:
1962                 if (m_dvb_service)
1963                 {
1964                         int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
1965                         if (pcrpid != -1)
1966                                 return pcrpid;
1967                 }
1968                 if (no_program_info) return -1; return program.pcrPid;
1969         case sPMTPID: if (no_program_info) return -1; return program.pmtPid;
1970         case sTXTPID: if (no_program_info) return -1; return program.textPid;
1971         case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
1972         case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
1973         case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
1974         case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
1975         case sProvider: if (!m_dvb_service) return -1; return -2;
1976         case sServiceref: return resIsString;
1977         case sDVBState: return m_tune_state;
1978         default:
1979                 break;
1980         }
1981         return -1;
1982 }
1983
1984 std::string eDVBServicePlay::getInfoString(int w)
1985 {
1986         switch (w)
1987         {
1988         case sProvider:
1989                 if (!m_dvb_service) return "";
1990                 return m_dvb_service->m_provider_name;
1991         case sServiceref:
1992                 return m_reference.toString();
1993         case sHBBTVUrl:
1994         {
1995                 std::string url;
1996                 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1997                 h.getHBBTVUrl(url);
1998                 return url;
1999         }
2000         case sLiveStreamDemuxId:
2001         {
2002                 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2003                 std::stringstream demux;
2004                 demux << h.getDemuxID();
2005                 return demux.str();
2006         }
2007         default:
2008                 break;
2009         }
2010         return iServiceInformation::getInfoString(w);
2011 }
2012
2013 ePtr<iDVBTransponderData> eDVBServicePlay::getTransponderData()
2014 {
2015         return eStaticServiceDVBInformation().getTransponderData(m_reference);
2016 }
2017
2018 void eDVBServicePlay::getAITApplications(std::map<int, std::string> &aitlist)
2019 {
2020         return m_service_handler.getAITApplications(aitlist);
2021 }
2022
2023 void eDVBServicePlay::getCaIds(std::vector<int> &caids, std::vector<int> &ecmpids)
2024 {
2025         m_service_handler.getCaIds(caids, ecmpids);
2026 }
2027
2028 int eDVBServicePlay::getNumberOfTracks()
2029 {
2030         eDVBServicePMTHandler::program program;
2031         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2032         if (h.getProgramInfo(program))
2033                 return 0;
2034         return program.audioStreams.size();
2035 }
2036
2037 int eDVBServicePlay::getCurrentTrack()
2038 {
2039         eDVBServicePMTHandler::program program;
2040         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2041         if (h.getProgramInfo(program))
2042                 return 0;
2043
2044         int max = program.audioStreams.size();
2045         int i;
2046
2047         for (i = 0; i < max; ++i)
2048                 if (program.audioStreams[i].pid == m_current_audio_pid)
2049                         return i;
2050
2051         return 0;
2052 }
2053
2054 RESULT eDVBServicePlay::selectTrack(unsigned int i)
2055 {
2056         int ret = selectAudioStream(i);
2057
2058         if (m_decoder->set())
2059                 return -5;
2060
2061         return ret;
2062 }
2063
2064 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
2065 {
2066         eDVBServicePMTHandler::program program;
2067         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2068
2069         if (h.getProgramInfo(program))
2070                 return -1;
2071
2072         if (i >= program.audioStreams.size())
2073                 return -2;
2074
2075         info.m_pid = program.audioStreams[i].pid;
2076
2077         if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
2078                 info.m_description = "MPEG";
2079         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
2080                 info.m_description = "AC3";
2081         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDDP)
2082                 info.m_description = "AC3+";
2083         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
2084                 info.m_description = "AAC";
2085         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE)
2086                 info.m_description = "AAC-HE";
2087         else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
2088                 info.m_description = "DTS";
2089         else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTSHD)
2090                 info.m_description = "DTS-HD";
2091         else
2092                 info.m_description = "???";
2093
2094         if (program.audioStreams[i].component_tag != -1)
2095         {
2096                 ePtr<eServiceEvent> evt;
2097                 if (!m_event_handler.getEvent(evt, 0))
2098                 {
2099                         ePtr<eComponentData> data;
2100                         if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
2101                                 info.m_language = data->getText();
2102                 }
2103         }
2104
2105         if (info.m_language.empty())
2106                 info.m_language = program.audioStreams[i].language_code;
2107
2108         return 0;
2109 }
2110
2111 int eDVBServicePlay::selectAudioStream(int i)
2112 {
2113         eDVBServicePMTHandler::program program;
2114         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2115         pts_t position = -1;
2116
2117         if (h.getProgramInfo(program))
2118                 return -1;
2119
2120         if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
2121                 return -2;
2122
2123         if (!m_decoder)
2124                 return -3;
2125
2126         int stream = i;
2127         if (stream == -1)
2128                 stream = program.defaultAudioStream;
2129
2130         int apid = -1, apidtype = -1;
2131
2132         if (((unsigned int)stream) < program.audioStreams.size())
2133         {
2134                 apid = program.audioStreams[stream].pid;
2135                 apidtype = program.audioStreams[stream].type;
2136         }
2137
2138         if (i != -1 && apid != m_current_audio_pid && (m_is_pvr || m_timeshift_active))
2139                 eDebug("[eDVBServicePlay] getPlayPosition ret %d, pos %lld in selectAudioStream", getPlayPosition(position), position);
2140
2141         m_current_audio_pid = apid;
2142
2143         if (m_decoder->setAudioPID(apid, apidtype))
2144         {
2145                 eDebug("[eDVBServicePlay] set audio pid %04x failed", apid);
2146                 return -4;
2147         }
2148
2149         if (position != -1)
2150                 eDebug("[eDVBServicePlay] seekTo ret %d", seekTo(position));
2151
2152         int rdsPid = apid;
2153
2154                 /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
2155         if (!(m_is_pvr || m_timeshift_active || m_decoder_index || m_have_video_pid))
2156         {
2157                 int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
2158                 if (different_pid)
2159                         rdsPid = program.audioStreams[stream].rdsPid;
2160                 if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
2161                 {
2162                         m_rds_decoder = 0;
2163                         ePtr<iDVBDemux> data_demux;
2164                         if (!h.getDataDemux(data_demux))
2165                         {
2166                                 m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
2167                                 m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
2168                                 m_rds_decoder->start(rdsPid);
2169                         }
2170                 }
2171         }
2172
2173                         /* store new pid as default only when:
2174                                 a.) we have an entry in the service db for the current service,
2175                                 b.) we are not playing back something,
2176                                 c.) we are not selecting the default entry. (we wouldn't change
2177                                     anything in the best case, or destroy the default setting in
2178                                     case the real default is not yet available.)
2179                                 d.) we have only one audiostream (overwrite the cache to make sure
2180                                     the cache contains the correct audio pid and type)
2181                         */
2182         if (m_dvb_service && ((i != -1) || (program.audioStreams.size() == 1)
2183                 || ((m_dvb_service->getCacheEntry(eDVBService::cMPEGAPID) == -1)
2184                 && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)== -1)
2185                 && (m_dvb_service->getCacheEntry(eDVBService::cDDPPID)== -1)
2186                 && (m_dvb_service->getCacheEntry(eDVBService::cAACHEAPID) == -1)
2187                 && (m_dvb_service->getCacheEntry(eDVBService::cAACAPID) == -1))))
2188         {
2189                 m_dvb_service->setCacheEntry(eDVBService::cMPEGAPID, apidtype == eDVBAudio::aMPEG ? apid : -1);
2190                 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apidtype == eDVBAudio::aAC3 ? apid : -1);
2191                 m_dvb_service->setCacheEntry(eDVBService::cDDPPID, apidtype == eDVBAudio::aDDP ? apid : -1);
2192                 m_dvb_service->setCacheEntry(eDVBService::cAACHEAPID, apidtype == eDVBAudio::aAACHE ? apid : -1);
2193                 m_dvb_service->setCacheEntry(eDVBService::cAACAPID, apidtype == eDVBAudio::aAAC ? apid : -1);
2194         }
2195
2196         h.resetCachedProgram();
2197
2198         return 0;
2199 }
2200
2201 int eDVBServicePlay::getCurrentChannel()
2202 {
2203         return m_decoder ? m_decoder->getAudioChannel() : STEREO;
2204 }
2205
2206 RESULT eDVBServicePlay::selectChannel(int i)
2207 {
2208         if (i < LEFT || i > RIGHT || i == STEREO)
2209                 i = -1;  // Stereo
2210         if (m_dvb_service)
2211                 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
2212         if (m_decoder)
2213                 m_decoder->setAudioChannel(i);
2214         return 0;
2215 }
2216
2217 std::string eDVBServicePlay::getText(int x)
2218 {
2219         if (m_rds_decoder)
2220                 switch(x)
2221                 {
2222                         case RadioText:
2223                                 return convertLatin1UTF8(m_rds_decoder->getRadioText());
2224                         case RtpText:
2225                                 return convertLatin1UTF8(m_rds_decoder->getRtpText());
2226                 }
2227         return "";
2228 }
2229
2230 void eDVBServicePlay::rdsDecoderEvent(int what)
2231 {
2232         switch(what)
2233         {
2234                 case eDVBRdsDecoder::RadioTextChanged:
2235                         m_event((iPlayableService*)this, evUpdatedRadioText);
2236                         break;
2237                 case eDVBRdsDecoder::RtpTextChanged:
2238                         m_event((iPlayableService*)this, evUpdatedRtpText);
2239                         break;
2240                 case eDVBRdsDecoder::RassInteractivePicMaskChanged:
2241                         m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
2242                         break;
2243                 case eDVBRdsDecoder::RecvRassSlidePic:
2244                         m_event((iPlayableService*)this, evUpdatedRassSlidePic);
2245                         break;
2246         }
2247 }
2248
2249 void eDVBServicePlay::showRassSlidePicture()
2250 {
2251         if (m_rds_decoder)
2252         {
2253                 if (m_decoder)
2254                 {
2255                         std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
2256                         if (rass_slide_pic.length())
2257                                 m_decoder->showSinglePic(rass_slide_pic.c_str());
2258                         else
2259                                 eDebug("[eDVBServicePlay] empty filename for rass slide picture received!!");
2260                 }
2261                 else
2262                         eDebug("[eDVBServicePlay] no MPEG Decoder to show iframes avail");
2263         }
2264         else
2265                 eDebug("[eDVBServicePlay] showRassSlidePicture called.. but not decoder");
2266 }
2267
2268 void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
2269 {
2270         if (m_rds_decoder)
2271         {
2272                 if (m_decoder)
2273                 {
2274                         std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
2275                         if (rass_interactive_pic.length())
2276                                 m_decoder->showSinglePic(rass_interactive_pic.c_str());
2277                         else
2278                                 eDebug("[eDVBServicePlay] empty filename for rass interactive picture %d/%d received!!", page, subpage);
2279                 }
2280                 else
2281                         eDebug("[eDVBServicePlay] no MPEG Decoder to show iframes avail");
2282         }
2283         else
2284                 eDebug("[eDVBServicePlay] showRassInteractivePic called.. but not decoder");
2285 }
2286
2287 ePyObject eDVBServicePlay::getRassInteractiveMask()
2288 {
2289         if (m_rds_decoder)
2290                 return m_rds_decoder->getRassPictureMask();
2291         Py_RETURN_NONE;
2292 }
2293
2294 bool eDVBServiceBase::tryFallbackTuner(eServiceReferenceDVB &service, bool &is_stream, bool is_pvr, bool simulate)
2295 {
2296         ePtr<eDVBResourceManager> res_mgr;
2297         std::ostringstream remote_service_ref;
2298         eDVBChannelID chid, chid_ignore;
2299         int system;
2300         size_t index;
2301
2302         bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false);
2303         std::string remote_fallback_url = eConfigManager::getConfigValue("config.usage.remote_fallback");
2304
2305         if(is_stream || is_pvr || simulate ||
2306                         !remote_fallback_enabled || (remote_fallback_url.length() == 0) ||
2307                         eDVBResourceManager::getInstance(res_mgr))
2308                 return(false);
2309
2310         service.getChannelID(chid);                                             // this sets chid
2311         eServiceReferenceDVB().getChannelID(chid_ignore);       // this sets chid_ignore
2312
2313         if(res_mgr->canAllocateChannel(chid, chid_ignore, system))      // this sets system
2314                 return(false);
2315
2316         while((index = remote_fallback_url.find(':')) != std::string::npos)
2317         {
2318                 remote_fallback_url.erase(index, 1);
2319                 remote_fallback_url.insert(index, "%3a");
2320         }
2321
2322         remote_service_ref << std::hex << service.type << ":" << service.flags << ":";
2323
2324         for(index = 0; index < 8; index++)
2325                 remote_service_ref << std::hex << service.getData(index) << ":";
2326
2327         remote_service_ref << std::hex << remote_fallback_url << "/" << service.type << "%3a" << service.flags;
2328
2329         for(index = 0; index < 8; index++)
2330                 remote_service_ref << std::hex << "%3a" << service.getData(index);
2331
2332         eDebug("Fallback tuner: redirected unavailable service to: %s\n", remote_service_ref.str().c_str());
2333
2334         service = eServiceReferenceDVB(remote_service_ref.str());
2335
2336         is_stream = true;
2337
2338         return(true);
2339 }
2340
2341 int eDVBServiceBase::getFrontendInfo(int w)
2342 {
2343         eUsePtr<iDVBChannel> channel;
2344         if(m_service_handler.getChannel(channel))
2345                 return 0;
2346         ePtr<iDVBFrontend> fe;
2347         if(channel->getFrontend(fe))
2348                 return 0;
2349         return fe->readFrontendData(w);
2350 }
2351
2352 ePtr<iDVBFrontendData> eDVBServiceBase::getFrontendData()
2353 {
2354         ePtr<iDVBFrontendData> ret;
2355         eUsePtr<iDVBChannel> channel;
2356         if(!m_service_handler.getChannel(channel))
2357         {
2358                 ePtr<iDVBFrontend> fe;
2359                 if(!channel->getFrontend(fe))
2360                         fe->getFrontendData(ret);
2361         }
2362         return ret;
2363 }
2364
2365 ePtr<iDVBFrontendStatus> eDVBServiceBase::getFrontendStatus()
2366 {
2367         ePtr<iDVBFrontendStatus> ret;
2368         eUsePtr<iDVBChannel> channel;
2369         if(!m_service_handler.getChannel(channel))
2370         {
2371                 ePtr<iDVBFrontend> fe;
2372                 if(!channel->getFrontend(fe))
2373                         fe->getFrontendStatus(ret);
2374         }
2375         return ret;
2376 }
2377
2378 ePtr<iDVBTransponderData> eDVBServiceBase::getTransponderData(bool original)
2379 {
2380         ePtr<iDVBTransponderData> ret;
2381         eUsePtr<iDVBChannel> channel;
2382         if(!m_service_handler.getChannel(channel))
2383         {
2384                 ePtr<iDVBFrontend> fe;
2385                 if(!channel->getFrontend(fe))
2386                         fe->getTransponderData(ret, original);
2387         }
2388         return ret;
2389 }
2390
2391 int eDVBServicePlay::getNumberOfSubservices()
2392 {
2393         ePtr<eServiceEvent> evt;
2394         if (!m_event_handler.getEvent(evt, 0))
2395                 return evt->getNumOfLinkageServices();
2396         return 0;
2397 }
2398
2399 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
2400 {
2401         ePtr<eServiceEvent> evt;
2402         if (!m_event_handler.getEvent(evt, 0))
2403         {
2404                 if (!evt->getLinkageService(sub, m_reference, n))
2405                         return 0;
2406         }
2407         sub.type=eServiceReference::idInvalid;
2408         return -1;
2409 }
2410
2411 RESULT eDVBServicePlay::startTimeshift()
2412 {
2413         ePtr<iDVBDemux> demux;
2414
2415         eDebug("[eDVBServicePlay] Start timeshift!");
2416
2417         if (m_timeshift_enabled)
2418                 return -1;
2419
2420                 /* start recording with the data demux. */
2421         if (m_service_handler.getDataDemux(demux))
2422                 return -2;
2423
2424         demux->createTSRecorder(m_record);
2425         if (!m_record)
2426                 return -3;
2427
2428         std::string tspath = eConfigManager::getConfigValue("config.usage.timeshift_path");
2429         if (tspath == "")
2430         {
2431                 eDebug("[eDVBServicePlay] could not query timeshift path");
2432                 return -5;
2433         }
2434         if (tspath.empty())
2435         {
2436                 eDebug("[eDVBServicePlay] timeshift path is empty");
2437                 return -5;
2438         }
2439         if (tspath[tspath.length()-1] != '/')
2440                 tspath.append("/");
2441         tspath.append("timeshift.XXXXXX");
2442         char* templ = new char[tspath.length() + 1];
2443         strcpy(templ, tspath.c_str());
2444         m_timeshift_fd = mkstemp(templ);
2445         m_timeshift_file = std::string(templ);
2446         eDebug("[eDVBServicePlay] timeshift recording to %s", templ);
2447         delete [] templ;
2448
2449         if (m_timeshift_fd < 0)
2450         {
2451                 m_record = 0;
2452                 return -4;
2453         }
2454
2455         m_record->setTargetFD(m_timeshift_fd);
2456         m_record->setTargetFilename(m_timeshift_file);
2457         m_record->enableAccessPoints(false); // no need for AP information during shift
2458         m_timeshift_enabled = 1;
2459
2460         updateTimeshiftPids();
2461         m_record->start();
2462
2463         return 0;
2464 }
2465
2466 RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
2467 {
2468         if (!m_timeshift_enabled)
2469                 return -1;
2470
2471         if (swToLive)
2472                 switchToLive();
2473
2474         m_timeshift_enabled = 0;
2475
2476         m_record->stop();
2477         m_record = 0;
2478
2479         if (m_timeshift_fd >= 0)
2480         {
2481                 close(m_timeshift_fd);
2482                 m_timeshift_fd = -1;
2483         }
2484
2485         if (!m_save_timeshift)
2486         {
2487                 eDebug("[eDVBServicePlay] remove timeshift files");
2488                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file);
2489                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file + ".sc");
2490                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file + ".cuts");
2491         }
2492         else
2493         {
2494                 eDebug("[eDVBServicePlay] timeshift files not deleted");
2495                 m_save_timeshift = 0;
2496         }
2497         return 0;
2498 }
2499
2500 int eDVBServicePlay::isTimeshiftActive()
2501 {
2502         return m_timeshift_enabled && m_timeshift_active;
2503 }
2504
2505 int eDVBServicePlay::isTimeshiftEnabled()
2506 {
2507         return m_timeshift_enabled;
2508 }
2509
2510 RESULT eDVBServicePlay::saveTimeshiftFile()
2511 {
2512         if (!m_timeshift_enabled)
2513                 return -1;
2514
2515         m_save_timeshift = 1;
2516
2517         return 0;
2518 }
2519
2520 RESULT eDVBServicePlay::activateTimeshift()
2521 {
2522         if (!m_timeshift_enabled)
2523                 return -1;
2524
2525         if (!m_timeshift_active)
2526         {
2527                 switchToTimeshift();
2528                 return 0;
2529         }
2530
2531         return -2;
2532 }
2533
2534 std::string eDVBServicePlay::getTimeshiftFilename()
2535 {
2536         if (m_timeshift_enabled)
2537                 return m_timeshift_file;
2538         else
2539                 return "";
2540 }
2541
2542 PyObject *eDVBServicePlay::getCutList()
2543 {
2544         ePyObject list = PyList_New(0);
2545
2546         for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2547         {
2548                 ePyObject tuple = PyTuple_New(2);
2549                 PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
2550                 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
2551                 PyList_Append(list, tuple);
2552                 Py_DECREF(tuple);
2553         }
2554
2555         return list;
2556 }
2557
2558 void eDVBServicePlay::setCutList(ePyObject list)
2559 {
2560         if (!PyList_Check(list))
2561                 return;
2562         int size = PyList_Size(list);
2563         int i;
2564
2565         m_cue_entries.clear();
2566
2567         for (i=0; i<size; ++i)
2568         {
2569                 ePyObject tuple = PyList_GET_ITEM(list, i);
2570                 if (!PyTuple_Check(tuple))
2571                 {
2572                         eDebug("[eDVBServicePlay] non-tuple in cutlist");
2573                         continue;
2574                 }
2575                 if (PyTuple_Size(tuple) != 2)
2576                 {
2577                         eDebug("[eDVBServicePlay] cutlist entries need to be a 2-tuple");
2578                         continue;
2579                 }
2580                 ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
2581                 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
2582                 {
2583                         eDebug("[eDVBServicePlay] cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
2584                         continue;
2585                 }
2586                 pts_t pts = PyLong_AsLongLong(ppts);
2587                 int type = PyInt_AsLong(ptype);
2588                 m_cue_entries.insert(cueEntry(pts, type));
2589                 eDebug("[eDVBServicePlay] adding %08llx, %d", pts, type);
2590         }
2591         m_cuesheet_changed = 1;
2592
2593         cutlistToCuesheet();
2594         m_event((iPlayableService*)this, evCuesheetChanged);
2595 }
2596
2597 void eDVBServicePlay::setCutListEnable(int enable)
2598 {
2599         m_cutlist_enabled = enable;
2600         cutlistToCuesheet();
2601 }
2602
2603 void eDVBServicePlay::updateTimeshiftPids()
2604 {
2605         if (!m_record)
2606                 return;
2607
2608         eDVBServicePMTHandler::program program;
2609         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2610
2611         if (h.getProgramInfo(program))
2612                 return;
2613         else
2614         {
2615                 int timing_pid = -1;
2616                 int timing_stream_type = -1;
2617                 iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none;
2618                 std::set<int> pids_to_record;
2619                 pids_to_record.insert(0); // PAT
2620                 if (program.pmtPid != -1)
2621                         pids_to_record.insert(program.pmtPid); // PMT
2622
2623                 if (program.textPid != -1)
2624                         pids_to_record.insert(program.textPid); // Videotext
2625
2626                 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2627                         i(program.videoStreams.begin());
2628                         i != program.videoStreams.end(); ++i)
2629                 {
2630                         if (timing_pid == -1)
2631                         {
2632                                 timing_pid = i->pid;
2633                                 timing_stream_type = i->type;
2634                                 timing_pid_type = iDVBTSRecorder::video_pid;
2635                         }
2636                         pids_to_record.insert(i->pid);
2637                 }
2638
2639                 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2640                         i(program.audioStreams.begin());
2641                         i != program.audioStreams.end(); ++i)
2642                 {
2643                         if (timing_pid == -1)
2644                         {
2645                                 timing_pid = i->pid;
2646                                 timing_stream_type = i->type;
2647                                 timing_pid_type = iDVBTSRecorder::audio_pid;
2648                         }
2649                         pids_to_record.insert(i->pid);
2650                 }
2651
2652                 for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
2653                         i(program.subtitleStreams.begin());
2654                         i != program.subtitleStreams.end(); ++i)
2655                                 pids_to_record.insert(i->pid);
2656
2657                 std::set<int> new_pids, obsolete_pids;
2658
2659                 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
2660                                 m_pids_active.begin(), m_pids_active.end(),
2661                                 std::inserter(new_pids, new_pids.begin()));
2662
2663                 std::set_difference(
2664                                 m_pids_active.begin(), m_pids_active.end(),
2665                                 pids_to_record.begin(), pids_to_record.end(),
2666                                 std::inserter(new_pids, new_pids.begin())
2667                                 );
2668
2669                 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
2670                         m_record->addPID(*i);
2671
2672                 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
2673                         m_record->removePID(*i);
2674
2675                 if (timing_pid != -1)
2676                         m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type);
2677         }
2678 }
2679
2680 RESULT eDVBServicePlay::setNextPlaybackFile(const char *f)
2681 {
2682         m_timeshift_file_next = f;
2683         return 0;
2684 }
2685
2686 void eDVBServicePlay::switchToLive()
2687 {
2688         if (!m_timeshift_active)
2689                 return;
2690
2691         eDebug("[eDVBServicePlay] SwitchToLive");
2692
2693         resetTimeshift(0);
2694
2695         m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
2696
2697         /* free the timeshift service handler, we need the resources */
2698         m_service_handler_timeshift.free();
2699
2700         updateDecoder(true);
2701 }
2702
2703 void eDVBServicePlay::resetTimeshift(int start)
2704 {
2705         m_cue = 0;
2706         m_decode_demux = 0;
2707         m_decoder = 0;
2708         m_teletext_parser = 0;
2709         m_rds_decoder = 0;
2710         m_subtitle_parser = 0;
2711         m_new_subtitle_stream_connection = 0;
2712         m_new_subtitle_page_connection = 0;
2713         m_new_dvb_subtitle_page_connection = 0;
2714         m_rds_decoder_event_connection = 0;
2715         m_video_event_connection = 0;
2716         m_timeshift_changed = 1;
2717         m_timeshift_file_next.clear();
2718
2719         if (start)
2720         {
2721                 m_cue = new eCueSheet();
2722                 m_timeshift_active = 1;
2723         }
2724         else
2725                 m_timeshift_active = 0;
2726 }
2727
2728 ePtr<iTsSource> eDVBServicePlay::createTsSource(eServiceReferenceDVB &ref, int packetsize)
2729 {
2730         /*
2731          * NOTE: we cannot use our m_is_stream status, instead we check the reference again.
2732          * It could be that createTsSource is called to start a timeshift on a stream,
2733          * in which case the ref passed here no longer is a url, but a timeshift file instead.
2734          * (but m_is_stream would still be set, because of the ref which was passed to our
2735          * constructor)
2736          */
2737         if (ref.path.substr(0, 7) == "http://")
2738         {
2739                 eHttpStream *f = new eHttpStream();
2740                 f->open(ref.path.c_str());
2741                 return ePtr<iTsSource>(f);
2742         }
2743         else
2744         {
2745                 eRawFile *f = new eRawFile(packetsize);
2746                 f->open(ref.path.c_str());
2747                 return ePtr<iTsSource>(f);
2748         }
2749 }
2750
2751 void eDVBServicePlay::switchToTimeshift()
2752 {
2753         if (m_timeshift_active)
2754                 return;
2755
2756         resetTimeshift(1);
2757
2758         eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
2759         r.path = m_timeshift_file;
2760
2761         m_cue->seekTo(0, -1000);
2762
2763         ePtr<iTsSource> source = createTsSource(r);
2764         m_service_handler_timeshift.tuneExt(r, source, m_timeshift_file.c_str(), m_cue, 0, m_dvb_service, eDVBServicePMTHandler::timeshift_playback, false); /* use the decoder demux for everything */
2765
2766         eDebug("[eDVBServicePlay] switchToTimeshift, in pause mode now.");
2767         pause();
2768         updateDecoder(true); /* mainly to switch off PCR, and to set pause */
2769 }
2770
2771 void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged)
2772 {
2773         int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
2774         bool mustPlay = false;
2775
2776         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2777
2778         eDVBServicePMTHandler::program program;
2779         if (h.getProgramInfo(program))
2780                 eDebug("[eDVBServicePlay] getting program info failed.");
2781         else
2782         {
2783                 eDebugNoNewLineStart("[eDVBServicePlay] have %zd video stream(s)", program.videoStreams.size());
2784                 if (!program.videoStreams.empty())
2785                 {
2786                         eDebugNoNewLine(" (");
2787                         for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2788                                 i(program.videoStreams.begin());
2789                                 i != program.videoStreams.end(); ++i)
2790                         {
2791                                 if (vpid == -1)
2792                                 {
2793                                         vpid = i->pid;
2794                                         vpidtype = i->type;
2795                                 }
2796                                 if (i != program.videoStreams.begin())
2797                                         eDebugNoNewLine(", ");
2798                                 eDebugNoNewLine("%04x", i->pid);
2799                         }
2800                         eDebugNoNewLine(")");
2801                 }
2802                 eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
2803                 if (!program.audioStreams.empty())
2804                 {
2805                         eDebugNoNewLine(" (");
2806                         for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2807                                 i(program.audioStreams.begin());
2808                                 i != program.audioStreams.end(); ++i)
2809                         {
2810                                 if (i != program.audioStreams.begin())
2811                                         eDebugNoNewLine(", ");
2812                                 eDebugNoNewLine("%04x", i->pid);
2813                         }
2814                         eDebugNoNewLine(")");
2815                 }
2816                 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
2817                 pcrpid = program.pcrPid;
2818                 eDebugNoNewLine(", and the text pid is %04x\n", program.textPid);
2819                 tpid = program.textPid;
2820         }
2821
2822         m_have_video_pid = 0;
2823
2824         if (!m_decoder)
2825         {
2826                 h.getDecodeDemux(m_decode_demux);
2827                 if (m_decode_demux)
2828                 {
2829                         m_decode_demux->getMPEGDecoder(m_decoder, m_decoder_index);
2830                         if (m_decoder)
2831                                 m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
2832                 }
2833                 if (m_cue)
2834                         m_cue->setDecodingDemux(m_decode_demux, m_decoder);
2835                 mustPlay = true;
2836         }
2837
2838         m_timeshift_changed = 0;
2839
2840         if (m_decoder)
2841         {
2842                 bool wasSeekable = m_decoder->getVideoProgressive() != -1;
2843                 if (m_dvb_service)
2844                 {
2845                         achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
2846                         ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2847                         pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2848                 }
2849                 else // subservice
2850                 {
2851                         eServiceReferenceDVB ref;
2852                         m_service_handler.getServiceReference(ref);
2853                         eServiceReferenceDVB parent = ref.getParentServiceReference();
2854                         if (!parent)
2855                                 parent = ref;
2856                         if (parent)
2857                         {
2858                                 ePtr<eDVBResourceManager> res_mgr;
2859                                 if (!eDVBResourceManager::getInstance(res_mgr))
2860                                 {
2861                                         ePtr<iDVBChannelList> db;
2862                                         if (!res_mgr->getChannelList(db))
2863                                         {
2864                                                 ePtr<eDVBService> origService;
2865                                                 if (!db->getService(parent, origService))
2866                                                 {
2867                                                         ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
2868                                                         pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
2869                                                 }
2870                                         }
2871                                 }
2872                         }
2873                 }
2874
2875                 setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
2876                 setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
2877
2878                 m_decoder->setVideoPID(vpid, vpidtype);
2879                 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
2880
2881                 selectAudioStream();
2882
2883                 if (!(m_is_pvr || m_is_stream || m_timeshift_active))
2884                         m_decoder->setSyncPCR(pcrpid);
2885                 else
2886                         m_decoder->setSyncPCR(-1);
2887
2888                 if (m_decoder_index == 0)
2889                 {
2890                         m_decoder->setTextPID(tpid);
2891                 }
2892
2893                 if (vpid > 0 && vpid < 0x2000)
2894                         ;
2895                 else
2896                 {
2897                         std::string value;
2898                         bool showRadioBackground = eConfigManager::getConfigBoolValue("config.misc.showradiopic", true);
2899                         std::string radio_pic;
2900                         if (showRadioBackground)
2901                                 radio_pic = eConfigManager::getConfigValue("config.misc.radiopic");
2902                         else
2903                                 radio_pic = eConfigManager::getConfigValue("config.misc.blackradiopic");
2904                         m_decoder->setRadioPic(radio_pic);
2905                 }
2906
2907                 if (mustPlay)
2908                         m_decoder->play();
2909                 else
2910                         m_decoder->set();
2911
2912                 m_decoder->setAudioChannel(achannel);
2913
2914                 if (mustPlay && m_decode_demux && m_decoder_index == 0)
2915                 {
2916                         m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
2917                         m_teletext_parser->connectNewStream(slot(*this, &eDVBServicePlay::newSubtitleStream), m_new_subtitle_stream_connection);
2918                         m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
2919                         m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
2920                         m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
2921                         if (m_timeshift_changed)
2922                         {
2923                                 struct SubtitleTrack track;
2924                                 if (getCachedSubtitle(track) >= 0)
2925                                 {
2926                                         if (track.type == 0) // dvb
2927                                                 m_subtitle_parser->start(track.pid, track.page_number, track.magazine_number);
2928                                         else if (track.type == 1) // ttx
2929                                                 m_teletext_parser->setPageAndMagazine(track.page_number, track.magazine_number, track.language_code.c_str());
2930                                 }
2931                         }
2932                         m_teletext_parser->start(program.textPid);
2933                 }
2934
2935                 /* don't worry about non-existing services, nor pvr services */
2936                 if (m_dvb_service)
2937                 {
2938                         /* (audio pid will be set in selectAudioTrack) */
2939                         if (vpid >= 0)
2940                         {
2941                                 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
2942                                 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
2943                         }
2944                         if (pcrpid >= 0) m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
2945                         if (tpid >= 0) m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
2946                 }
2947                 if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
2948                         sendSeekableStateChanged = true;
2949         }
2950
2951         if (sendSeekableStateChanged)
2952                 m_event((iPlayableService*)this, evSeekableStatusChanged);
2953 }
2954
2955 void eDVBServicePlay::loadCuesheet()
2956 {
2957         std::string filename = m_reference.path + ".cuts";
2958
2959         m_cue_entries.clear();
2960
2961         FILE *f = fopen(filename.c_str(), "rb");
2962
2963         if (f)
2964         {
2965                 while (1)
2966                 {
2967                         unsigned long long where;
2968                         unsigned int what;
2969
2970                         if (!fread(&where, sizeof(where), 1, f))
2971                                 break;
2972                         if (!fread(&what, sizeof(what), 1, f))
2973                                 break;
2974
2975                         where = be64toh(where);
2976                         what = ntohl(what);
2977
2978                         if (what > 3)
2979                                 break;
2980
2981                         m_cue_entries.insert(cueEntry(where, what));
2982                 }
2983                 fclose(f);
2984                 eDebug("[eDVBServicePlay] cuts file has %zd entries", m_cue_entries.size());
2985         } else
2986                 eDebug("[eDVBServicePlay] cutfile not found!");
2987
2988         m_cuesheet_changed = 0;
2989         cutlistToCuesheet();
2990         m_event((iPlayableService*)this, evCuesheetChanged);
2991 }
2992
2993 void eDVBServicePlay::saveCuesheet()
2994 {
2995         std::string filename = m_timeshift_enabled ? m_timeshift_file : m_reference.path;
2996
2997                 /* save cuesheet only when main file is accessible. */
2998         if (::access(filename.c_str(), R_OK) < 0)
2999                 return;
3000
3001         filename.append(".cuts");
3002
3003         FILE *f = fopen(filename.c_str(), "wb");
3004
3005         if (f)
3006         {
3007                 unsigned long long where;
3008                 int what;
3009
3010                 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
3011                 {
3012                         where = htobe64(i->where);
3013                         what = htonl(i->what);
3014                         fwrite(&where, sizeof(where), 1, f);
3015                         fwrite(&what, sizeof(what), 1, f);
3016
3017                 }
3018                 fclose(f);
3019         }
3020
3021         m_cuesheet_changed = 0;
3022 }
3023
3024 void eDVBServicePlay::cutlistToCuesheet()
3025 {
3026         if (!m_cue)
3027         {
3028                 eDebug("[eDVBServicePlay] no cue sheet");
3029                 return;
3030         }
3031         m_cue->clear();
3032
3033         if ((m_cutlist_enabled & 1) == 0)
3034         {
3035                 m_cue->commitSpans();
3036                 eDebug("[eDVBServicePlay] cutlists were disabled");
3037                 return;
3038         }
3039
3040         pts_t in = 0, out = 0, length = 0;
3041
3042         getLength(length);
3043
3044         std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
3045
3046         int have_any_span = 0;
3047
3048         while (1)
3049         {
3050                 if (i == m_cue_entries.end())
3051                 {
3052                         if (!have_any_span && !in)
3053                                 break;
3054                         out = length;
3055                 } else {
3056                         if (i->what == 0) /* in */
3057                         {
3058                                 in = i++->where;
3059                                 continue;
3060                         } else if (i->what == 1) /* out */
3061                                 out = i++->where;
3062                         else /* mark (2) or last play position (3) */
3063                         {
3064                                 i++;
3065                                 continue;
3066                         }
3067                 }
3068
3069                 if (in < 0)
3070                         in = 0;
3071                 if (out < 0)
3072                         out = 0;
3073                 if (in > length)
3074                         in = length;
3075                 if (out > length)
3076                         out = length;
3077
3078                 if (in < out)
3079                 {
3080                         have_any_span = 1;
3081                         m_cue->addSourceSpan(in, out);
3082                         in = out = 0;
3083                 }
3084
3085                 in = length;
3086
3087                 if (i == m_cue_entries.end())
3088                         break;
3089         }
3090         m_cue->commitSpans();
3091 }
3092
3093 RESULT eDVBServicePlay::enableSubtitles(iSubtitleUser *user, SubtitleTrack &track)
3094 {
3095         if (m_subtitle_widget)
3096                 disableSubtitles();
3097
3098         if (track.type == 1)  // teletext subtitles
3099         {
3100                 int page, magazine, pid;
3101                 std::string lang;
3102
3103                 if (!m_teletext_parser)
3104                 {
3105                         eDebug("[eDVBServicePlay] enable teletext subtitles.. no parser !!!");
3106                         return -1;
3107                 }
3108
3109                 pid = track.pid;
3110                 page = track.page_number;
3111                 magazine = track.magazine_number;
3112                 lang = track.language_code;
3113
3114                 m_subtitle_widget = user;
3115                 m_teletext_parser->setPageAndMagazine(page, magazine, lang.c_str());
3116                 if (m_dvb_service)
3117                 {
3118                         int i, sub = 0;
3119                         for (i=0; i < m_teletext_parser->max_id; i++)
3120                         {
3121                                 if (!memcmp(m_teletext_parser->my_country_codes[i], lang.c_str(), 3))
3122                                 {
3123                                         sub = i;
3124                                         break;
3125                                 }
3126                         }
3127                         m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|((sub&0x1F)<<3)|(magazine&0x7));
3128                 }
3129         }
3130         else if (track.type == 0)
3131         {
3132                 int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
3133                 if (!m_subtitle_parser)
3134                 {
3135                         eDebug("[eDVBServicePlay] enable dvb subtitles.. no parser !!!");
3136                         return -1;
3137                 }
3138
3139                 pid = track.pid;
3140                 composition_page_id = track.page_number;
3141                 ancillary_page_id = track.magazine_number;
3142
3143                 m_subtitle_widget = user;
3144                 m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
3145                 if (m_dvb_service)
3146                         m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
3147         }
3148         else
3149                 goto error_out;
3150         return 0;
3151 error_out:
3152         eDebug("[eDVBServicePlay] enableSubtitles needs a valid type:\n"
3153                 "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
3154                 "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
3155         return -1;
3156 }
3157
3158 RESULT eDVBServicePlay::disableSubtitles()
3159 {
3160         if (m_subtitle_widget) m_subtitle_widget->destroy();
3161         m_subtitle_widget = 0;
3162         if (m_subtitle_parser)
3163         {
3164                 m_subtitle_parser->stop();
3165                 m_dvb_subtitle_pages.clear();
3166         }
3167         if (m_teletext_parser)
3168         {
3169                 m_teletext_parser->setPageAndMagazine(-1, -1, "und");
3170                 m_subtitle_pages.clear();
3171         }
3172         if (m_dvb_service)
3173                 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, 0);
3174         return 0;
3175 }
3176
3177 RESULT eDVBServicePlay::getCachedSubtitle(struct SubtitleTrack &track)
3178 {
3179         if (m_dvb_service)
3180         {
3181                 eDVBServicePMTHandler::program program;
3182                 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
3183                 if (!h.getProgramInfo(program))
3184                 {
3185                         bool usecache = eConfigManager::getConfigBoolValue("config.autolanguage.subtitle_usecache");
3186                         int stream=program.defaultSubtitleStream;
3187                         int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
3188
3189                         if (usecache || stream == -1)
3190                         {
3191                                 if (tmp != -1 && tmp != 0)
3192                                 {
3193                                         unsigned int data = (unsigned int)tmp;
3194                                         int pid = (data&0xFFFF0000)>>16;
3195                                         if (program.textPid == pid) // teletext
3196                                                 track.type = 1; // type teletext
3197                                         else
3198                                                 track.type = 0; // type dvb
3199                                         track.pid = pid; // pid
3200                                         track.page_number = (data >> 8) & 0xff; // composition_page / page
3201                                         int k = (data >> 3) & 0x1f;
3202                                         track.magazine_number = data & 0x7; // ancillary_page / magazine
3203                                         track.language_code = m_teletext_parser->my_country_codes[k];
3204                                         return 0;
3205                                 }
3206                         }
3207                         if (stream != -1 && (tmp != 0 || !usecache))
3208                         {
3209                                 if (program.subtitleStreams[stream].subtitling_type == 1)
3210                                 {
3211                                         track.type = 1; // type teletext
3212                                         track.pid = program.subtitleStreams[stream].pid;
3213                                         track.page_number = program.subtitleStreams[stream].teletext_page_number & 0xff;
3214                                         track.magazine_number = program.subtitleStreams[stream].teletext_magazine_number & 0x07;
3215                                         track.language_code = program.subtitleStreams[stream].language_code;
3216                                         return 0;
3217                                 }
3218                                 else
3219                                 {
3220                                         track.type = 0; // type dvb
3221                                         track.pid = program.subtitleStreams[stream].pid;
3222                                         track.page_number = program.subtitleStreams[stream].composition_page_id;
3223                                         track.magazine_number = program.subtitleStreams[stream].ancillary_page_id;
3224                                         track.language_code = program.subtitleStreams[stream].language_code;
3225                                         return 0;
3226                                 }
3227                         }
3228                 }
3229         }
3230         return -1;
3231 }
3232
3233 RESULT eDVBServicePlay::getSubtitleList(std::vector<SubtitleTrack> &subtitlelist)
3234 {
3235         if (!m_teletext_parser)
3236                 return -1;
3237
3238         std::set<int> added_ttx_pages;
3239
3240         std::set<eDVBServicePMTHandler::subtitleStream> &subs =
3241                 m_teletext_parser->m_found_subtitle_pages;
3242
3243         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
3244         eDVBServicePMTHandler::program program;
3245         if (h.getProgramInfo(program))
3246                 eDebug("[eDVBServicePlay] getting program info failed.");
3247         else
3248         {
3249                 for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
3250                         it != program.subtitleStreams.end(); ++it)
3251                 {
3252                         struct SubtitleTrack track;
3253                         switch(it->subtitling_type)
3254                         {
3255                                 case 0x01: // ebu teletext subtitles
3256                                 {
3257                                         int page_number = it->teletext_page_number & 0xFF;
3258                                         int magazine_number = it->teletext_magazine_number & 7;
3259                                         int hash = magazine_number << 8 | page_number;
3260                                         if (added_ttx_pages.find(hash) == added_ttx_pages.end())
3261                                         {
3262                                                 track.type = 1;
3263                                                 track.pid = it->pid;
3264                                                 track.page_number = page_number;
3265                                                 track.magazine_number = magazine_number;
3266                                                 track.language_code = it->language_code;
3267                                                 subtitlelist.push_back(track);
3268                                                 added_ttx_pages.insert(hash);
3269                                         }
3270                                         break;
3271                                 }
3272                                 case 0x10 ... 0x13:
3273                                 case 0x20 ... 0x23: // dvb subtitles
3274                                 {
3275                                         track.type = 0;
3276                                         track.pid = it->pid;
3277                                         track.page_number = it->composition_page_id;
3278                                         track.magazine_number = it->ancillary_page_id;
3279                                         track.language_code = it->language_code;
3280                                         subtitlelist.push_back(track);
3281                                         break;
3282                                 }
3283                         }
3284                 }
3285         }
3286
3287         for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
3288                 it != subs.end(); ++it)
3289         {
3290                 int page_number = it->teletext_page_number & 0xFF;
3291                 int magazine_number = it->teletext_magazine_number & 7;
3292                 int hash = magazine_number << 8 | page_number;
3293                 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
3294                 {
3295                         struct SubtitleTrack track;
3296                         track.type = 1;
3297                         track.pid = it->pid;
3298                         track.page_number = page_number;
3299                         track.magazine_number = magazine_number;
3300                         track.language_code = "und";
3301                         subtitlelist.push_back(track);
3302                 }
3303         }
3304
3305         return 0;
3306 }
3307
3308 void eDVBServicePlay::newSubtitleStream()
3309 {
3310         m_event((iPlayableService*)this, evUpdatedInfo);
3311 }
3312
3313 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
3314 {
3315         if (m_subtitle_widget)
3316         {
3317                 int subtitledelay = 0;
3318                 pts_t pts;
3319                 m_decoder->getPTS(0, pts);
3320                 if (m_is_pvr || m_timeshift_enabled)
3321                 {
3322                         eDebug("[eDVBServicePlay] Subtitle in recording/timeshift");
3323                         subtitledelay = eConfigManager::getConfigIntValue("config.subtitles.subtitle_noPTSrecordingdelay", 315000);
3324                 }
3325                 else
3326                 {
3327                         /* check the setting for subtitle delay in live playback, either with pts, or without pts */
3328                         subtitledelay = eConfigManager::getConfigIntValue("config.subtitles.subtitle_bad_timing_delay", 0);
3329                 }
3330
3331                 // eDebug("[eDVBServicePlay] Subtitle get  TTX have_pts=%d pvr=%d timeshift=%d page.pts=%lld pts=%lld delay=%d", page.m_have_pts, m_is_pvr, m_timeshift_enabled, page.m_pts, pts, subtitledelay);
3332                 eDVBTeletextSubtitlePage tmppage = page;
3333                 tmppage.m_have_pts = true;
3334
3335                 if (abs(tmppage.m_pts - pts) > 20*90000)
3336                         tmppage.m_pts = pts; // fix abnormal pts diffs
3337
3338                 tmppage.m_pts += subtitledelay;
3339                 m_subtitle_pages.push_back(tmppage);
3340
3341                 checkSubtitleTiming();
3342         }
3343 }
3344
3345 void eDVBServicePlay::checkSubtitleTiming()
3346 {
3347         pts_t pos = 0;
3348 //      eDebug("[eDVBServicePlay] checkSubtitleTiming");
3349         if (!m_subtitle_widget)
3350                 return;
3351         if (m_subtitle_pages.empty() && m_dvb_subtitle_pages.empty())
3352         {
3353                 return;
3354         }
3355         if (m_decoder)
3356         {
3357                 m_decoder->getPTS(0, pos);
3358         }
3359
3360         while (1)
3361         {
3362                 enum { TELETEXT, DVB } type;
3363                 eDVBTeletextSubtitlePage page;
3364                 eDVBSubtitlePage dvb_page;
3365                 pts_t show_time;
3366                 if (!m_subtitle_pages.empty())
3367                 {
3368                         page = m_subtitle_pages.front();
3369                         type = TELETEXT;
3370                         show_time = page.m_pts;
3371                 }
3372                 else if (!m_dvb_subtitle_pages.empty())
3373                 {
3374                         dvb_page = m_dvb_subtitle_pages.front();
3375                         type = DVB;
3376                         show_time = dvb_page.m_show_time;
3377                 }
3378                 else
3379                         return;
3380
3381                 int diff = show_time - pos;
3382 //              eDebug("[eDVBServicePlay] Subtitle show %d page.pts=%lld pts=%lld diff=%d", type, show_time, pos, diff);
3383
3384                 if (diff < 20*90 || diff > 1800000)
3385                 {
3386                         if (type == TELETEXT)
3387                         {
3388                                 m_subtitle_widget->setPage(page);
3389                                 m_subtitle_pages.pop_front();
3390                         }
3391                         else
3392                         {
3393                                 m_subtitle_widget->setPage(dvb_page);
3394                                 m_dvb_subtitle_pages.pop_front();
3395                         }
3396                 } else
3397                 {
3398                         m_subtitle_sync_timer->start(diff / 90, 1);
3399                         break;
3400                 }
3401         }
3402 }
3403
3404 void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
3405 {
3406         if (m_subtitle_widget)
3407         {
3408                 pts_t pos = 0;
3409                 if (m_decoder)
3410                         m_decoder->getPTS(0, pos);
3411                 if ( abs(pos-p.m_show_time)>1800000 && (m_is_pvr || m_timeshift_enabled))
3412                 {
3413                         eDebug("[eDVBServicePlay] Subtitle without PTS and recording");
3414                         int subtitledelay = eConfigManager::getConfigIntValue("config.subtitles.subtitle_noPTSrecordingdelay", 315000);
3415
3416                         eDVBSubtitlePage tmppage;
3417                         tmppage = p;
3418                         tmppage.m_show_time = pos + subtitledelay;
3419                         m_dvb_subtitle_pages.push_back(tmppage);
3420                 }
3421                 else
3422                 {
3423                         int subtitledelay = eConfigManager::getConfigIntValue("config.subtitles.subtitle_bad_timing_delay", 0);
3424                         if (subtitledelay != 0)
3425                         {
3426                                 eDVBSubtitlePage tmppage;
3427                                 tmppage = p;
3428                                 tmppage.m_show_time += subtitledelay;
3429                                 m_dvb_subtitle_pages.push_back(tmppage);
3430                         }
3431                         else
3432                                 m_dvb_subtitle_pages.push_back(p);
3433                 }
3434                 checkSubtitleTiming();
3435         }
3436 }
3437
3438 int eDVBServicePlay::getAC3Delay()
3439 {
3440         if (m_dvb_service)
3441                 return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
3442         else if (m_decoder)
3443                 return m_decoder->getAC3Delay();
3444         else
3445                 return 0;
3446 }
3447
3448 int eDVBServicePlay::getPCMDelay()
3449 {
3450         if (m_dvb_service)
3451                 return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
3452         else if (m_decoder)
3453                 return m_decoder->getPCMDelay();
3454         else
3455                 return 0;
3456 }
3457
3458 void eDVBServicePlay::setAC3Delay(int delay)
3459 {
3460         if (m_dvb_service)
3461                 m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
3462         if (m_decoder)
3463         {
3464                 m_decoder->setAC3Delay(delay + eConfigManager::getConfigIntValue("config.av.generalAC3delay"));
3465         }
3466 }
3467
3468 void eDVBServicePlay::setPCMDelay(int delay)
3469 {
3470         if (m_dvb_service)
3471                 m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
3472         if (m_decoder)
3473         {
3474                 m_decoder->setPCMDelay(delay + eConfigManager::getConfigIntValue("config.av.generalPCMdelay"));
3475         }
3476 }
3477
3478 void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
3479 {
3480         switch(event.type) {
3481                 case iTSMPEGDecoder::videoEvent::eventSizeChanged:
3482                         m_event((iPlayableService*)this, evVideoSizeChanged);
3483                         break;
3484                 case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
3485                         m_event((iPlayableService*)this, evVideoFramerateChanged);
3486                         break;
3487                 case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
3488                         m_event((iPlayableService*)this, evVideoProgressiveChanged);
3489                         break;
3490                 default:
3491                         break;
3492         }
3493 }
3494
3495 RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
3496 {
3497         ptr = this;
3498         return 0;
3499 }
3500
3501 ePtr<iStreamData> eDVBServicePlay::getStreamingData()
3502 {
3503         ePtr<iStreamData> retval;
3504         eDVBServicePMTHandler::program program;
3505         if (!m_service_handler.getProgramInfo(program))
3506         {
3507                 retval = new eDVBServicePMTHandler::eStreamData(program);
3508         }
3509         return retval;
3510 }
3511
3512
3513 DEFINE_REF(eDVBServicePlay)
3514
3515 ePtr<iDVBTransponderData> eDVBService::getTransponderData(const eServiceReference &ref)
3516 {
3517         return eStaticServiceDVBInformation().getTransponderData(ref);
3518 }
3519
3520 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");