6539e39b0d8539a768b4b4b0c1797752111b664b
[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=0;
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=0;
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 %d %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 TS");
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, 1, 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, 1, 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         ePtr<eDVBResourceManager> res_mgr;
1343
1344         bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false);
1345         std::string remote_fallback_url = eConfigManager::getConfigValue("config.usage.remote_fallback");
1346
1347         if(!m_is_stream && !m_is_pvr &&
1348                         remote_fallback_enabled &&
1349                         (remote_fallback_url.length() > 0) &&
1350                         !eDVBResourceManager::getInstance(res_mgr))
1351         {
1352                 eDVBChannelID chid, chid_ignore;
1353                 int system;
1354
1355                 service.getChannelID(chid);
1356                 eServiceReferenceDVB().getChannelID(chid_ignore);
1357
1358                 if(!res_mgr->canAllocateChannel(chid, chid_ignore, system))
1359                 {
1360                         size_t index;
1361
1362                         while((index = remote_fallback_url.find(':')) != std::string::npos)
1363                         {
1364                                 remote_fallback_url.erase(index, 1);
1365                                 remote_fallback_url.insert(index, "%3a");
1366                         }
1367
1368                         std::ostringstream remote_service_ref;
1369                         remote_service_ref << std::hex << service.type << ":" << service.flags << ":" << 
1370                                         service.getData(0) << ":" << service.getData(1) << ":" << service.getData(2) << ":0:0:0:0:0:" <<
1371                                         remote_fallback_url << "/" <<
1372                                         service.type << "%3a" << service.flags;
1373                         for(index = 0; index < 8; index++)
1374                                         remote_service_ref << "%3a" << service.getData(index);
1375
1376                         service = eServiceReferenceDVB(remote_service_ref.str());
1377
1378                         m_is_stream = true;
1379                         m_is_pvr = false;
1380                 }
1381         }
1382
1383                 /* in pvr mode, we only want to use one demux. in tv mode, we're using
1384                    two (one for decoding, one for data source), as we must be prepared
1385                    to start recording from the data demux. */
1386         if (m_is_pvr)
1387         {
1388                 eDVBMetaParser meta;
1389                 if (!meta.parseFile(m_reference.path))
1390                 {
1391                         service = meta.m_ref;
1392                         service.path = m_reference.path;
1393                         packetsize = meta.m_packet_size;
1394                         scrambled = meta.m_scrambled;
1395                 }
1396                 m_cue = new eCueSheet();
1397                 type = eDVBServicePMTHandler::playback;
1398         }
1399         else
1400                 m_event(this, evStart);
1401
1402         if (m_is_stream)
1403         {
1404                 /*
1405                  * streams are considered to be descrambled by default;
1406                  * user can indicate a stream is scrambled, by using servicetype id + 0x100
1407                  */
1408                 scrambled = (m_reference.type == eServiceFactoryDVB::id + 0x100);
1409                 type = eDVBServicePMTHandler::streamclient;
1410         }
1411
1412         m_first_program_info = 1;
1413         ePtr<iTsSource> source = createTsSource(service, packetsize);
1414         m_service_handler.tuneExt(service, m_is_pvr, source, service.path.c_str(), m_cue, false, m_dvb_service, type, scrambled);
1415
1416         if (m_is_pvr)
1417         {
1418                 /* inject EIT if there is a stored one */
1419                 std::string filename = service.path;
1420                 filename.erase(filename.length()-2, 2);
1421                 filename+="eit";
1422                 ePtr<eServiceEvent> event = new eServiceEvent;
1423                 if (!event->parseFrom(filename, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get()))
1424                 {
1425                         ePtr<eServiceEvent> empty;
1426                         m_event_handler.inject(event, 0);
1427                         m_event_handler.inject(empty, 1);
1428                 }
1429                 m_event(this, evStart);
1430         }
1431         return 0;
1432 }
1433
1434 RESULT eDVBServicePlay::stop()
1435 {
1436                 /* add bookmark for last play position */
1437                 /* m_cutlist_enabled bit 2 is the "don't remember bit" */
1438         if (m_is_pvr && ((m_cutlist_enabled & 2) == 0))
1439         {
1440                 pts_t play_position, length;
1441                 if (!getPlayPosition(play_position))
1442                 {
1443                                 /* remove last position */
1444                         for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end();)
1445                         {
1446                                 if (i->what == 3) /* current play position */
1447                                 {
1448                                         m_cue_entries.erase(i);
1449                                         i = m_cue_entries.begin();
1450                                         continue;
1451                                 } else
1452                                         ++i;
1453                         }
1454
1455                         if (getLength(length))
1456                                 length = 0;
1457
1458                         if (length)
1459                         {
1460                                 m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
1461                         }
1462                         m_cuesheet_changed = 1;
1463                 }
1464         }
1465
1466         if ((m_is_pvr || m_timeshift_enabled) && m_cuesheet_changed)
1467         {
1468                 saveCuesheet();
1469         }
1470
1471         stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
1472
1473         m_service_handler_timeshift.free();
1474         m_service_handler.free();
1475
1476         m_nownext_timer->stop();
1477         m_event((iPlayableService*)this, evStopped);
1478         return 0;
1479 }
1480
1481 RESULT eDVBServicePlay::setTarget(int target)
1482 {
1483         m_decoder_index = target;
1484         return 0;
1485 }
1486
1487 RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
1488 {
1489         connection = new eConnection((iPlayableService*)this, m_event.connect(event));
1490         return 0;
1491 }
1492
1493 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
1494 {
1495                 /* note: we check for timeshift to be enabled,
1496                    not neccessary active. if you pause when timeshift
1497                    is not active, you should activate it when unpausing */
1498         if ((!m_is_pvr) && (!m_timeshift_enabled))
1499         {
1500                 ptr = 0;
1501                 return -1;
1502         }
1503
1504         ptr = this;
1505         return 0;
1506 }
1507
1508 RESULT eDVBServicePlay::setSlowMotion(int ratio)
1509 {
1510         int ret = 0;
1511         ASSERT(ratio); /* The API changed: instead of calling setSlowMotion(0), call play! */
1512         eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio);
1513         setFastForward_internal(0);
1514         if (m_decoder)
1515         {
1516                 ret = m_decoder->setSlowMotion(ratio);
1517                 if (!ret)
1518                         m_slowmotion = ratio;
1519                 return ret;
1520         }
1521         else
1522                 return -1;
1523 }
1524
1525 RESULT eDVBServicePlay::setFastForward(int ratio)
1526 {
1527         eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
1528         ASSERT(ratio);
1529         return setFastForward_internal(ratio);
1530 }
1531
1532 RESULT eDVBServicePlay::setFastForward_internal(int ratio, bool final_seek)
1533 {
1534         int skipmode, ffratio, ret = 0;
1535         pts_t pos=0;
1536
1537         if (ratio > 8)
1538         {
1539                 skipmode = ratio;
1540                 ffratio = 1;
1541         } else if (ratio > 0)
1542         {
1543                 skipmode = 0;
1544                 ffratio = ratio;
1545         } else if (!ratio)
1546         {
1547                 skipmode = 0;
1548                 ffratio = 0;
1549         } else // if (ratio < 0)
1550         {
1551                 skipmode = ratio;
1552                 ffratio = 1;
1553         }
1554
1555         if (m_skipmode != skipmode)
1556         {
1557                 eDebug("eDVBServicePlay::setFastForward: setting cue skipmode to %d", skipmode);
1558                 if (m_cue)
1559                         m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
1560         }
1561
1562         m_skipmode = skipmode;
1563
1564         if (final_seek)
1565                 eDebug("eDVBServicePlay::setFastForward: trickplay stopped .. ret %d, pos %lld", getPlayPosition(pos), pos);
1566
1567         m_fastforward = ffratio;
1568
1569         if (!m_decoder)
1570                 return -1;
1571
1572         if (ffratio == 0)
1573                 ; /* return m_decoder->play(); is done in caller*/
1574         else if (ffratio != 1)
1575                 ret = m_decoder->setFastForward(ffratio);
1576         else
1577                 ret = m_decoder->setTrickmode();
1578
1579         if (pos)
1580                 eDebug("eDVBServicePlay::setFastForward: final seek after trickplay ret %d", seekTo(pos));
1581
1582         return ret;
1583 }
1584
1585 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
1586 {
1587         if (m_is_pvr || m_timeshift_enabled)
1588         {
1589                 ptr = this;
1590                 return 0;
1591         }
1592
1593         ptr = 0;
1594         return -1;
1595 }
1596
1597         /* TODO: when timeshift is enabled but not active, this doesn't work. */
1598 RESULT eDVBServicePlay::getLength(pts_t &len)
1599 {
1600         ePtr<iDVBPVRChannel> pvr_channel;
1601
1602         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1603                 return -1;
1604
1605         return pvr_channel->getLength(len);
1606 }
1607
1608 RESULT eDVBServicePlay::pause()
1609 {
1610         eDebug("eDVBServicePlay::pause");
1611         setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
1612         if (m_decoder)
1613         {
1614                 m_slowmotion = 0;
1615                 m_is_paused = 1;
1616                 return m_decoder->pause();
1617         } else
1618                 return -1;
1619 }
1620
1621 RESULT eDVBServicePlay::unpause()
1622 {
1623         eDebug("eDVBServicePlay::unpause");
1624         setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
1625         if (m_decoder)
1626         {
1627                 m_slowmotion = 0;
1628                 m_is_paused = 0;
1629                 return m_decoder->play();
1630         } else
1631                 return -1;
1632 }
1633
1634 RESULT eDVBServicePlay::seekTo(pts_t to)
1635 {
1636         eDebug("eDVBServicePlay::seekTo: jump %lld", to);
1637
1638         if (!m_decode_demux)
1639                 return -1;
1640
1641         ePtr<iDVBPVRChannel> pvr_channel;
1642
1643         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1644                 return -1;
1645
1646         if (!m_cue)
1647                 return -1;
1648
1649         m_cue->seekTo(0, to);
1650         m_dvb_subtitle_pages.clear();
1651         m_subtitle_pages.clear();
1652
1653         return 0;
1654 }
1655
1656 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
1657 {
1658         eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
1659
1660         if (!m_decode_demux)
1661                 return -1;
1662
1663         ePtr<iDVBPVRChannel> pvr_channel;
1664
1665         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1666                 return -1;
1667
1668         int mode = 1;
1669
1670                         /* HACK until we have skip-AP api */
1671         if ((to > 0) && (to < 100))
1672                 mode = 2;
1673
1674         to *= direction;
1675
1676         if (!m_cue)
1677                 return 0;
1678
1679         m_cue->seekTo(mode, to);
1680         m_dvb_subtitle_pages.clear();
1681         m_subtitle_pages.clear();
1682         return 0;
1683 }
1684
1685 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
1686 {
1687         ePtr<iDVBPVRChannel> pvr_channel;
1688
1689         if (!m_decode_demux)
1690                 return -1;
1691
1692         if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1693                 return -1;
1694
1695         int r = 0;
1696
1697                 /* if there is a decoder, use audio or video PTS */
1698         if (m_decoder)
1699         {
1700                 r = m_decoder->getPTS(0, pos);
1701                 if (r)
1702                         return r;
1703         }
1704
1705                 /* fixup */
1706         return pvr_channel->getCurrentPosition(m_decode_demux, pos, m_decoder);
1707 }
1708
1709 RESULT eDVBServicePlay::setTrickmode(int trick)
1710 {
1711                 /* currently unimplemented */
1712         return -1;
1713 }
1714
1715 RESULT eDVBServicePlay::isCurrentlySeekable()
1716 {
1717         return (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
1718 }
1719
1720 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
1721 {
1722         ptr = this;
1723         return 0;
1724 }
1725
1726 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
1727 {
1728         ptr = this;
1729         return 0;
1730 }
1731
1732 RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
1733 {
1734         ptr = this;
1735         return 0;
1736 }
1737
1738 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
1739 {
1740         ptr = this;
1741         return 0;
1742 }
1743
1744 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
1745 {
1746         ptr = this;
1747         return 0;
1748 }
1749
1750 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
1751 {
1752         ptr = 0;
1753         if (m_timeshift_enabled || !m_is_pvr)
1754         {
1755                 if (!m_timeshift_enabled)
1756                 {
1757                         /* query config path */
1758                         std::string tspath = eConfigManager::getConfigValue("config.usage.timeshift_path");
1759                         if(tspath == "")
1760                         {
1761                                 eDebug("eDVBServicePlay::timeshift: could not query ts path from config");
1762                                 return -4;
1763                         }
1764                         tspath.append("/");
1765                         /* we need enough diskspace */
1766                         struct statfs fs;
1767                         if (statfs(tspath.c_str(), &fs) < 0)
1768                         {
1769                                 eDebug("eDVBServicePlay::timeshift: statfs failed!");
1770                                 return -2;
1771                         }
1772
1773                         if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 200*1024*1024LL)
1774                         {
1775                                 eDebug("eDVBServicePlay::timeshift: not enough diskspace for timeshift! (less than 200MB)");
1776                                 return -3;
1777                         }
1778                 }
1779                 ptr = this;
1780                 return 0;
1781         }
1782         return -1;
1783 }
1784
1785 RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
1786 {
1787         if (m_is_pvr || m_timeshift_enabled)
1788         {
1789                 ptr = this;
1790                 return 0;
1791         }
1792         ptr = 0;
1793         return -1;
1794 }
1795
1796 RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
1797 {
1798         ptr = this;
1799         return 0;
1800 }
1801
1802 RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
1803 {
1804         ptr = this;
1805         return 0;
1806 }
1807
1808 RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
1809 {
1810         ptr = this;
1811         return 0;
1812 }
1813
1814 RESULT eDVBServicePlay::streamed(ePtr<iStreamedService> &ptr)
1815 {
1816         if (m_is_stream)
1817         {
1818                 ptr = this;
1819                 return 0;
1820         }
1821         ptr = 0;
1822         return -1;
1823 }
1824
1825 ePtr<iStreamBufferInfo> eDVBServicePlay::getBufferCharge()
1826 {
1827         /** FIXME **/
1828         return 0;
1829 }
1830
1831 int eDVBServicePlay::setBufferSize(int size)
1832 {
1833         /** FIXME **/
1834         return 0;
1835 }
1836
1837 RESULT eDVBServicePlay::getName(std::string &name)
1838 {
1839         if (m_is_pvr)
1840         {
1841                 ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
1842                 return i->getName(m_reference, name);
1843         }
1844         else if (m_is_stream)
1845         {
1846                 if (m_dvb_service)
1847                         m_dvb_service->getName(m_reference, name);
1848                 else
1849                         name = "unknown service";
1850                 if (name.empty())
1851                         name = m_reference.name;
1852                         if (name.empty())
1853                                 name = m_reference.path;
1854                                 if (name.empty())
1855                                         name = "(...)";
1856         }
1857         else if (m_dvb_service)
1858         {
1859                 m_dvb_service->getName(m_reference, name);
1860                 if (name.empty())
1861                         name = "(...)";
1862         }
1863         else if (!m_reference.name.empty())
1864                 eStaticServiceDVBInformation().getName(m_reference, name);
1865         else
1866                 name = "DVB service";
1867         return 0;
1868 }
1869
1870 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
1871 {
1872         return m_event_handler.getEvent(evt, nownext);
1873 }
1874
1875 int eDVBServicePlay::getInfo(int w)
1876 {
1877         eDVBServicePMTHandler::program program;
1878
1879         if (w == sCAIDs || w == sCAIDPIDs)
1880                 return resIsPyObject;
1881
1882         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1883
1884         int no_program_info = 0;
1885
1886         if (h.getProgramInfo(program))
1887                 no_program_info = 1;
1888
1889         switch (w)
1890         {
1891         case sVideoHeight:
1892                 if (m_decoder)
1893                         return m_decoder->getVideoHeight();
1894                 break;
1895         case sVideoWidth:
1896                 if (m_decoder)
1897                         return m_decoder->getVideoWidth();
1898                 break;
1899         case sFrameRate:
1900                 if (m_decoder)
1901                         return m_decoder->getVideoFrameRate();
1902                 break;
1903         case sProgressive:
1904                 if (m_decoder)
1905                         return m_decoder->getVideoProgressive();
1906                 break;
1907         case sAspect:
1908         {
1909                 int aspect = -1;
1910                 if (m_decoder)
1911                         aspect = m_decoder->getVideoAspect();
1912                 if (aspect == -1 && no_program_info)
1913                         break;
1914                 else if (aspect == -1 && !program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
1915                 {
1916                         ePtr<eServiceEvent> evt;
1917                         if (!m_event_handler.getEvent(evt, 0))
1918                         {
1919                                 ePtr<eComponentData> data;
1920                                 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
1921                                 {
1922                                         if ( data->getStreamContent() == 1 )
1923                                         {
1924                                                 switch(data->getComponentType())
1925                                                 {
1926                                                         // SD
1927                                                         case 1: // 4:3 SD PAL
1928                                                         case 2:
1929                                                         case 3: // 16:9 SD PAL
1930                                                         case 4: // > 16:9 PAL
1931                                                         case 5: // 4:3 SD NTSC
1932                                                         case 6:
1933                                                         case 7: // 16:9 SD NTSC
1934                                                         case 8: // > 16:9 NTSC
1935
1936                                                         // HD
1937                                                         case 9: // 4:3 HD PAL
1938                                                         case 0xA:
1939                                                         case 0xB: // 16:9 HD PAL
1940                                                         case 0xC: // > 16:9 HD PAL
1941                                                         case 0xD: // 4:3 HD NTSC
1942                                                         case 0xE:
1943                                                         case 0xF: // 16:9 HD NTSC
1944                                                         case 0x10: // > 16:9 HD PAL
1945                                                                 return data->getComponentType();
1946                                                 }
1947                                         }
1948                                 }
1949                         }
1950                 }
1951                 else
1952                         return aspect;
1953                 break;
1954         }
1955         case sIsCrypted: if (no_program_info) return false; return program.isCrypted();
1956         case sVideoPID:
1957                 if (m_dvb_service)
1958                 {
1959                         int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
1960                         if (vpid != -1)
1961                                 return vpid;
1962                 }
1963                 if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
1964         case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
1965         case sAudioPID:
1966                 if (m_dvb_service)
1967                 {
1968                         int apid = m_dvb_service->getCacheEntry(eDVBService::cMPEGAPID);
1969                         if (apid != -1)
1970                                 return apid;
1971                         apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
1972                         if (apid != -1)
1973                                 return apid;
1974                         apid = m_dvb_service->getCacheEntry(eDVBService::cDDPPID);
1975                         if (apid != -1)
1976                                 return apid;
1977                         apid = m_dvb_service->getCacheEntry(eDVBService::cAACHEAPID);
1978                         if (apid != -1)
1979                                 return apid;
1980                 }
1981                 if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
1982         case sPCRPID:
1983                 if (m_dvb_service)
1984                 {
1985                         int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
1986                         if (pcrpid != -1)
1987                                 return pcrpid;
1988                 }
1989                 if (no_program_info) return -1; return program.pcrPid;
1990         case sPMTPID: if (no_program_info) return -1; return program.pmtPid;
1991         case sTXTPID: if (no_program_info) return -1; return program.textPid;
1992         case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
1993         case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
1994         case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
1995         case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
1996         case sProvider: if (!m_dvb_service) return -1; return -2;
1997         case sServiceref: return resIsString;
1998         case sDVBState: return m_tune_state;
1999         default:
2000                 break;
2001         }
2002         return -1;
2003 }
2004
2005 std::string eDVBServicePlay::getInfoString(int w)
2006 {
2007         switch (w)
2008         {
2009         case sProvider:
2010                 if (!m_dvb_service) return "";
2011                 return m_dvb_service->m_provider_name;
2012         case sServiceref:
2013                 return m_reference.toString();
2014         case sHBBTVUrl:
2015         {
2016                 std::string url;
2017                 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2018                 h.getHBBTVUrl(url);
2019                 return url;
2020         }
2021         case sLiveStreamDemuxId:
2022         {
2023                 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2024                 std::string demux;
2025                 demux += h.getDemuxID() + '0';
2026                 return demux;
2027         }
2028         default:
2029                 break;
2030         }
2031         return iServiceInformation::getInfoString(w);
2032 }
2033
2034 ePtr<iDVBTransponderData> eDVBServicePlay::getTransponderData()
2035 {
2036         return eStaticServiceDVBInformation().getTransponderData(m_reference);
2037 }
2038
2039 void eDVBServicePlay::getAITApplications(std::map<int, std::string> &aitlist)
2040 {
2041         return m_service_handler.getAITApplications(aitlist);
2042 }
2043
2044 void eDVBServicePlay::getCaIds(std::vector<int> &caids, std::vector<int> &ecmpids)
2045 {
2046         m_service_handler.getCaIds(caids, ecmpids);
2047 }
2048
2049 int eDVBServicePlay::getNumberOfTracks()
2050 {
2051         eDVBServicePMTHandler::program program;
2052         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2053         if (h.getProgramInfo(program))
2054                 return 0;
2055         return program.audioStreams.size();
2056 }
2057
2058 int eDVBServicePlay::getCurrentTrack()
2059 {
2060         eDVBServicePMTHandler::program program;
2061         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2062         if (h.getProgramInfo(program))
2063                 return 0;
2064
2065         int max = program.audioStreams.size();
2066         int i;
2067
2068         for (i = 0; i < max; ++i)
2069                 if (program.audioStreams[i].pid == m_current_audio_pid)
2070                         return i;
2071
2072         return 0;
2073 }
2074
2075 RESULT eDVBServicePlay::selectTrack(unsigned int i)
2076 {
2077         int ret = selectAudioStream(i);
2078
2079         if (m_decoder->set())
2080                 return -5;
2081
2082         return ret;
2083 }
2084
2085 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
2086 {
2087         eDVBServicePMTHandler::program program;
2088         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2089
2090         if (h.getProgramInfo(program))
2091                 return -1;
2092
2093         if (i >= program.audioStreams.size())
2094                 return -2;
2095
2096         info.m_pid = program.audioStreams[i].pid;
2097
2098         if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
2099                 info.m_description = "MPEG";
2100         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
2101                 info.m_description = "AC3";
2102         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDDP)
2103                 info.m_description = "AC3+";
2104         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
2105                 info.m_description = "AAC";
2106         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE)
2107                 info.m_description = "AAC-HE";
2108         else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
2109                 info.m_description = "DTS";
2110         else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTSHD)
2111                 info.m_description = "DTS-HD";
2112         else
2113                 info.m_description = "???";
2114
2115         if (program.audioStreams[i].component_tag != -1)
2116         {
2117                 ePtr<eServiceEvent> evt;
2118                 if (!m_event_handler.getEvent(evt, 0))
2119                 {
2120                         ePtr<eComponentData> data;
2121                         if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
2122                                 info.m_language = data->getText();
2123                 }
2124         }
2125
2126         if (info.m_language.empty())
2127                 info.m_language = program.audioStreams[i].language_code;
2128
2129         return 0;
2130 }
2131
2132 int eDVBServicePlay::selectAudioStream(int i)
2133 {
2134         eDVBServicePMTHandler::program program;
2135         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2136         pts_t position = -1;
2137
2138         if (h.getProgramInfo(program))
2139                 return -1;
2140
2141         if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
2142                 return -2;
2143
2144         if (!m_decoder)
2145                 return -3;
2146
2147         int stream = i;
2148         if (stream == -1)
2149                 stream = program.defaultAudioStream;
2150
2151         int apid = -1, apidtype = -1;
2152
2153         if (((unsigned int)stream) < program.audioStreams.size())
2154         {
2155                 apid = program.audioStreams[stream].pid;
2156                 apidtype = program.audioStreams[stream].type;
2157         }
2158
2159         if (i != -1 && apid != m_current_audio_pid && (m_is_pvr || m_timeshift_active))
2160                 eDebug("eDVBServicePlay: getPlayPosition ret %d, pos %lld in selectAudioStream", getPlayPosition(position), position);
2161
2162         m_current_audio_pid = apid;
2163
2164         if (m_decoder->setAudioPID(apid, apidtype))
2165         {
2166                 eDebug("eDVBServicePlay: set audio pid failed");
2167                 return -4;
2168         }
2169
2170         if (position != -1)
2171                 eDebug("eDVBServicePlay: seekTo ret %d", seekTo(position));
2172
2173         int rdsPid = apid;
2174
2175                 /* 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 */
2176         if (!(m_is_pvr || m_timeshift_active || m_decoder_index || m_have_video_pid))
2177         {
2178                 int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
2179                 if (different_pid)
2180                         rdsPid = program.audioStreams[stream].rdsPid;
2181                 if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
2182                 {
2183                         m_rds_decoder = 0;
2184                         ePtr<iDVBDemux> data_demux;
2185                         if (!h.getDataDemux(data_demux))
2186                         {
2187                                 m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
2188                                 m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
2189                                 m_rds_decoder->start(rdsPid);
2190                         }
2191                 }
2192         }
2193
2194                         /* store new pid as default only when:
2195                                 a.) we have an entry in the service db for the current service,
2196                                 b.) we are not playing back something,
2197                                 c.) we are not selecting the default entry. (we wouldn't change
2198                                     anything in the best case, or destroy the default setting in
2199                                     case the real default is not yet available.)
2200                                 d.) we have only one audiostream (overwrite the cache to make sure
2201                                     the cache contains the correct audio pid and type)
2202                         */
2203         if (m_dvb_service && ((i != -1) || (program.audioStreams.size() == 1)
2204                 || ((m_dvb_service->getCacheEntry(eDVBService::cMPEGAPID) == -1)
2205                 && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)== -1)
2206                 && (m_dvb_service->getCacheEntry(eDVBService::cDDPPID)== -1)
2207                 && (m_dvb_service->getCacheEntry(eDVBService::cAACHEAPID) == -1))))
2208         {
2209                 m_dvb_service->setCacheEntry(eDVBService::cMPEGAPID, apidtype == eDVBAudio::aMPEG ? apid : -1);
2210                 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apidtype == eDVBAudio::aAC3 ? apid : -1);
2211                 m_dvb_service->setCacheEntry(eDVBService::cDDPPID, apidtype == eDVBAudio::aDDP ? apid : -1);
2212                 m_dvb_service->setCacheEntry(eDVBService::cAACHEAPID, apidtype == eDVBAudio::aAACHE ? apid : -1);
2213         }
2214
2215         h.resetCachedProgram();
2216
2217         return 0;
2218 }
2219
2220 int eDVBServicePlay::getCurrentChannel()
2221 {
2222         return m_decoder ? m_decoder->getAudioChannel() : STEREO;
2223 }
2224
2225 RESULT eDVBServicePlay::selectChannel(int i)
2226 {
2227         if (i < LEFT || i > RIGHT || i == STEREO)
2228                 i = -1;  // Stereo
2229         if (m_dvb_service)
2230                 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
2231         if (m_decoder)
2232                 m_decoder->setAudioChannel(i);
2233         return 0;
2234 }
2235
2236 std::string eDVBServicePlay::getText(int x)
2237 {
2238         if (m_rds_decoder)
2239                 switch(x)
2240                 {
2241                         case RadioText:
2242                                 return convertLatin1UTF8(m_rds_decoder->getRadioText());
2243                         case RtpText:
2244                                 return convertLatin1UTF8(m_rds_decoder->getRtpText());
2245                 }
2246         return "";
2247 }
2248
2249 void eDVBServicePlay::rdsDecoderEvent(int what)
2250 {
2251         switch(what)
2252         {
2253                 case eDVBRdsDecoder::RadioTextChanged:
2254                         m_event((iPlayableService*)this, evUpdatedRadioText);
2255                         break;
2256                 case eDVBRdsDecoder::RtpTextChanged:
2257                         m_event((iPlayableService*)this, evUpdatedRtpText);
2258                         break;
2259                 case eDVBRdsDecoder::RassInteractivePicMaskChanged:
2260                         m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
2261                         break;
2262                 case eDVBRdsDecoder::RecvRassSlidePic:
2263                         m_event((iPlayableService*)this, evUpdatedRassSlidePic);
2264                         break;
2265         }
2266 }
2267
2268 void eDVBServicePlay::showRassSlidePicture()
2269 {
2270         if (m_rds_decoder)
2271         {
2272                 if (m_decoder)
2273                 {
2274                         std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
2275                         if (rass_slide_pic.length())
2276                                 m_decoder->showSinglePic(rass_slide_pic.c_str());
2277                         else
2278                                 eDebug("eDVBServicePlay: empty filename for rass slide picture received!!");
2279                 }
2280                 else
2281                         eDebug("eDVBServicePlay: no MPEG Decoder to show iframes avail");
2282         }
2283         else
2284                 eDebug("eDVBServicePlay: showRassSlidePicture called.. but not decoder");
2285 }
2286
2287 void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
2288 {
2289         if (m_rds_decoder)
2290         {
2291                 if (m_decoder)
2292                 {
2293                         std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
2294                         if (rass_interactive_pic.length())
2295                                 m_decoder->showSinglePic(rass_interactive_pic.c_str());
2296                         else
2297                                 eDebug("eDVBServicePlay: empty filename for rass interactive picture %d/%d received!!", page, subpage);
2298                 }
2299                 else
2300                         eDebug("eDVBServicePlay: no MPEG Decoder to show iframes avail");
2301         }
2302         else
2303                 eDebug("eDVBServicePlay: showRassInteractivePic called.. but not decoder");
2304 }
2305
2306 ePyObject eDVBServicePlay::getRassInteractiveMask()
2307 {
2308         if (m_rds_decoder)
2309                 return m_rds_decoder->getRassPictureMask();
2310         Py_RETURN_NONE;
2311 }
2312
2313 int eDVBServiceBase::getFrontendInfo(int w)
2314 {
2315         eUsePtr<iDVBChannel> channel;
2316         if(m_service_handler.getChannel(channel))
2317                 return 0;
2318         ePtr<iDVBFrontend> fe;
2319         if(channel->getFrontend(fe))
2320                 return 0;
2321         return fe->readFrontendData(w);
2322 }
2323
2324 ePtr<iDVBFrontendData> eDVBServiceBase::getFrontendData()
2325 {
2326         ePtr<iDVBFrontendData> ret;
2327         eUsePtr<iDVBChannel> channel;
2328         if(!m_service_handler.getChannel(channel))
2329         {
2330                 ePtr<iDVBFrontend> fe;
2331                 if(!channel->getFrontend(fe))
2332                         fe->getFrontendData(ret);
2333         }
2334         return ret;
2335 }
2336
2337 ePtr<iDVBFrontendStatus> eDVBServiceBase::getFrontendStatus()
2338 {
2339         ePtr<iDVBFrontendStatus> ret;
2340         eUsePtr<iDVBChannel> channel;
2341         if(!m_service_handler.getChannel(channel))
2342         {
2343                 ePtr<iDVBFrontend> fe;
2344                 if(!channel->getFrontend(fe))
2345                         fe->getFrontendStatus(ret);
2346         }
2347         return ret;
2348 }
2349
2350 ePtr<iDVBTransponderData> eDVBServiceBase::getTransponderData(bool original)
2351 {
2352         ePtr<iDVBTransponderData> ret;
2353         eUsePtr<iDVBChannel> channel;
2354         if(!m_service_handler.getChannel(channel))
2355         {
2356                 ePtr<iDVBFrontend> fe;
2357                 if(!channel->getFrontend(fe))
2358                         fe->getTransponderData(ret, original);
2359         }
2360         return ret;
2361 }
2362
2363 int eDVBServicePlay::getNumberOfSubservices()
2364 {
2365         ePtr<eServiceEvent> evt;
2366         if (!m_event_handler.getEvent(evt, 0))
2367                 return evt->getNumOfLinkageServices();
2368         return 0;
2369 }
2370
2371 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
2372 {
2373         ePtr<eServiceEvent> evt;
2374         if (!m_event_handler.getEvent(evt, 0))
2375         {
2376                 if (!evt->getLinkageService(sub, m_reference, n))
2377                         return 0;
2378         }
2379         sub.type=eServiceReference::idInvalid;
2380         return -1;
2381 }
2382
2383 RESULT eDVBServicePlay::startTimeshift()
2384 {
2385         ePtr<iDVBDemux> demux;
2386
2387         eDebug("eDVBServicePlay: Start timeshift!");
2388
2389         if (m_timeshift_enabled)
2390                 return -1;
2391
2392                 /* start recording with the data demux. */
2393         if (m_service_handler.getDataDemux(demux))
2394                 return -2;
2395
2396         demux->createTSRecorder(m_record);
2397         if (!m_record)
2398                 return -3;
2399
2400         std::string tspath = eConfigManager::getConfigValue("config.usage.timeshift_path");
2401         if (tspath == "")
2402         {
2403                 eDebug("eDVBServicePlay: could not query ts path");
2404                 return -5;
2405         }
2406         if (tspath.empty())
2407         {
2408                 eDebug("eDVBServicePlay: TS path is empty");
2409                 return -5;
2410         }
2411         if (tspath[tspath.length()-1] != '/')
2412                 tspath.append("/");
2413         tspath.append("timeshift.XXXXXX");
2414         char* templ = new char[tspath.length() + 1];
2415         strcpy(templ, tspath.c_str());
2416         m_timeshift_fd = mkstemp(templ);
2417         m_timeshift_file = std::string(templ);
2418         eDebug("eDVBServicePlay: recording to %s", templ);
2419         delete [] templ;
2420
2421         if (m_timeshift_fd < 0)
2422         {
2423                 m_record = 0;
2424                 return -4;
2425         }
2426
2427         m_record->setTargetFD(m_timeshift_fd);
2428         m_record->setTargetFilename(m_timeshift_file);
2429         m_record->enableAccessPoints(false); // no need for AP information during shift
2430         m_timeshift_enabled = 1;
2431
2432         updateTimeshiftPids();
2433         m_record->start();
2434
2435         return 0;
2436 }
2437
2438 RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
2439 {
2440         if (!m_timeshift_enabled)
2441                 return -1;
2442
2443         if (swToLive)
2444                 switchToLive();
2445
2446         m_timeshift_enabled = 0;
2447
2448         m_record->stop();
2449         m_record = 0;
2450
2451         if (m_timeshift_fd >= 0)
2452         {
2453                 close(m_timeshift_fd);
2454                 m_timeshift_fd = -1;
2455         }
2456
2457         if (!m_save_timeshift)
2458         {
2459                 eDebug("eDVBServicePlay: remove timeshift files");
2460                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file);
2461                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file + ".sc");
2462                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file + ".cuts");
2463         }
2464         else
2465         {
2466                 eDebug("eDVBServicePlay: timeshift files not deleted");
2467                 m_save_timeshift = 0;
2468         }
2469         return 0;
2470 }
2471
2472 int eDVBServicePlay::isTimeshiftActive()
2473 {
2474         return m_timeshift_enabled && m_timeshift_active;
2475 }
2476
2477 int eDVBServicePlay::isTimeshiftEnabled()
2478 {
2479         return m_timeshift_enabled;
2480 }
2481
2482 RESULT eDVBServicePlay::saveTimeshiftFile()
2483 {
2484         if (!m_timeshift_enabled)
2485                 return -1;
2486
2487         m_save_timeshift = 1;
2488
2489         return 0;
2490 }
2491
2492 RESULT eDVBServicePlay::activateTimeshift()
2493 {
2494         if (!m_timeshift_enabled)
2495                 return -1;
2496
2497         if (!m_timeshift_active)
2498         {
2499                 switchToTimeshift();
2500                 return 0;
2501         }
2502
2503         return -2;
2504 }
2505
2506 std::string eDVBServicePlay::getTimeshiftFilename()
2507 {
2508         if (m_timeshift_enabled)
2509                 return m_timeshift_file;
2510         else
2511                 return "";
2512 }
2513
2514 PyObject *eDVBServicePlay::getCutList()
2515 {
2516         ePyObject list = PyList_New(0);
2517
2518         for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2519         {
2520                 ePyObject tuple = PyTuple_New(2);
2521                 PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
2522                 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
2523                 PyList_Append(list, tuple);
2524                 Py_DECREF(tuple);
2525         }
2526
2527         return list;
2528 }
2529
2530 void eDVBServicePlay::setCutList(ePyObject list)
2531 {
2532         if (!PyList_Check(list))
2533                 return;
2534         int size = PyList_Size(list);
2535         int i;
2536
2537         m_cue_entries.clear();
2538
2539         for (i=0; i<size; ++i)
2540         {
2541                 ePyObject tuple = PyList_GET_ITEM(list, i);
2542                 if (!PyTuple_Check(tuple))
2543                 {
2544                         eDebug("eDVBServicePlay: non-tuple in cutlist");
2545                         continue;
2546                 }
2547                 if (PyTuple_Size(tuple) != 2)
2548                 {
2549                         eDebug("eDVBServicePlay: cutlist entries need to be a 2-tuple");
2550                         continue;
2551                 }
2552                 ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
2553                 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
2554                 {
2555                         eDebug("eDVBServicePlay: cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
2556                         continue;
2557                 }
2558                 pts_t pts = PyLong_AsLongLong(ppts);
2559                 int type = PyInt_AsLong(ptype);
2560                 m_cue_entries.insert(cueEntry(pts, type));
2561                 eDebug("eDVBServicePlay: adding %08llx, %d", pts, type);
2562         }
2563         m_cuesheet_changed = 1;
2564
2565         cutlistToCuesheet();
2566         m_event((iPlayableService*)this, evCuesheetChanged);
2567 }
2568
2569 void eDVBServicePlay::setCutListEnable(int enable)
2570 {
2571         m_cutlist_enabled = enable;
2572         cutlistToCuesheet();
2573 }
2574
2575 void eDVBServicePlay::updateTimeshiftPids()
2576 {
2577         if (!m_record)
2578                 return;
2579
2580         eDVBServicePMTHandler::program program;
2581         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2582
2583         if (h.getProgramInfo(program))
2584                 return;
2585         else
2586         {
2587                 int timing_pid = -1;
2588                 int timing_stream_type = -1;
2589                 iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none;
2590                 std::set<int> pids_to_record;
2591                 pids_to_record.insert(0); // PAT
2592                 if (program.pmtPid != -1)
2593                         pids_to_record.insert(program.pmtPid); // PMT
2594
2595                 if (program.textPid != -1)
2596                         pids_to_record.insert(program.textPid); // Videotext
2597
2598                 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2599                         i(program.videoStreams.begin());
2600                         i != program.videoStreams.end(); ++i)
2601                 {
2602                         if (timing_pid == -1)
2603                         {
2604                                 timing_pid = i->pid;
2605                                 timing_stream_type = i->type;
2606                                 timing_pid_type = iDVBTSRecorder::video_pid;
2607                         }
2608                         pids_to_record.insert(i->pid);
2609                 }
2610
2611                 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2612                         i(program.audioStreams.begin());
2613                         i != program.audioStreams.end(); ++i)
2614                 {
2615                         if (timing_pid == -1)
2616                         {
2617                                 timing_pid = i->pid;
2618                                 timing_stream_type = i->type;
2619                                 timing_pid_type = iDVBTSRecorder::audio_pid;
2620                         }
2621                         pids_to_record.insert(i->pid);
2622                 }
2623
2624                 for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
2625                         i(program.subtitleStreams.begin());
2626                         i != program.subtitleStreams.end(); ++i)
2627                                 pids_to_record.insert(i->pid);
2628
2629                 std::set<int> new_pids, obsolete_pids;
2630
2631                 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
2632                                 m_pids_active.begin(), m_pids_active.end(),
2633                                 std::inserter(new_pids, new_pids.begin()));
2634
2635                 std::set_difference(
2636                                 m_pids_active.begin(), m_pids_active.end(),
2637                                 pids_to_record.begin(), pids_to_record.end(),
2638                                 std::inserter(new_pids, new_pids.begin())
2639                                 );
2640
2641                 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
2642                         m_record->addPID(*i);
2643
2644                 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
2645                         m_record->removePID(*i);
2646
2647                 if (timing_pid != -1)
2648                         m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type);
2649         }
2650 }
2651
2652 RESULT eDVBServicePlay::setNextPlaybackFile(const char *f)
2653 {
2654         m_timeshift_file_next = f;
2655         return 0;
2656 }
2657
2658 void eDVBServicePlay::switchToLive()
2659 {
2660         if (!m_timeshift_active)
2661                 return;
2662
2663         eDebug("eDVBServicePlay: SwitchToLive");
2664
2665         resetTimeshift(0);
2666
2667         m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
2668
2669         /* free the timeshift service handler, we need the resources */
2670         m_service_handler_timeshift.free();
2671
2672         updateDecoder(true);
2673 }
2674
2675 void eDVBServicePlay::resetTimeshift(int start)
2676 {
2677         m_cue = 0;
2678         m_decode_demux = 0;
2679         m_decoder = 0;
2680         m_teletext_parser = 0;
2681         m_rds_decoder = 0;
2682         m_subtitle_parser = 0;
2683         m_new_subtitle_stream_connection = 0;
2684         m_new_subtitle_page_connection = 0;
2685         m_new_dvb_subtitle_page_connection = 0;
2686         m_rds_decoder_event_connection = 0;
2687         m_video_event_connection = 0;
2688         m_timeshift_changed = 1;
2689         m_timeshift_file_next.clear();
2690
2691         if (start)
2692         {
2693                 m_cue = new eCueSheet();
2694                 m_timeshift_active = 1;
2695         }
2696         else
2697                 m_timeshift_active = 0;
2698 }
2699
2700 ePtr<iTsSource> eDVBServicePlay::createTsSource(eServiceReferenceDVB &ref, int packetsize)
2701 {
2702         /*
2703          * NOTE: we cannot use our m_is_stream status, instead we check the reference again.
2704          * It could be that createTsSource is called to start a timeshift on a stream,
2705          * in which case the ref passed here no longer is a url, but a timeshift file instead.
2706          * (but m_is_stream would still be set, because of the ref which was passed to our
2707          * constructor)
2708          */
2709         if (ref.path.substr(0, 7) == "http://")
2710         {
2711                 eHttpStream *f = new eHttpStream();
2712                 f->open(ref.path.c_str());
2713                 return ePtr<iTsSource>(f);
2714         }
2715         else
2716         {
2717                 eRawFile *f = new eRawFile(packetsize);
2718                 f->open(ref.path.c_str());
2719                 return ePtr<iTsSource>(f);
2720         }
2721 }
2722
2723 void eDVBServicePlay::switchToTimeshift()
2724 {
2725         if (m_timeshift_active)
2726                 return;
2727
2728         resetTimeshift(1);
2729
2730         eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
2731         r.path = m_timeshift_file;
2732
2733         m_cue->seekTo(0, -1000);
2734
2735         ePtr<iTsSource> source = createTsSource(r);
2736         m_service_handler_timeshift.tuneExt(r, 1, source, m_timeshift_file.c_str(), m_cue, 0, m_dvb_service, eDVBServicePMTHandler::timeshift_playback, false); /* use the decoder demux for everything */
2737
2738         eDebug("eDVBServicePlay: eDVBServicePlay::switchToTimeshift, in pause mode now.");
2739         pause();
2740         updateDecoder(true); /* mainly to switch off PCR, and to set pause */
2741 }
2742
2743 void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged)
2744 {
2745         int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
2746         bool mustPlay = false;
2747
2748         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2749
2750         eDVBServicePMTHandler::program program;
2751         if (h.getProgramInfo(program))
2752                 eDebug("eDVBServicePlay: getting program info failed.");
2753         else
2754         {
2755                 eDebugNoNewLineStart("eDVBServicePlay: have %zd video stream(s)", program.videoStreams.size());
2756                 if (!program.videoStreams.empty())
2757                 {
2758                         eDebugNoNewLine(" (");
2759                         for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2760                                 i(program.videoStreams.begin());
2761                                 i != program.videoStreams.end(); ++i)
2762                         {
2763                                 if (vpid == -1)
2764                                 {
2765                                         vpid = i->pid;
2766                                         vpidtype = i->type;
2767                                 }
2768                                 if (i != program.videoStreams.begin())
2769                                         eDebugNoNewLine(", ");
2770                                 eDebugNoNewLine("%04x", i->pid);
2771                         }
2772                         eDebugNoNewLine(")");
2773                 }
2774                 eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
2775                 if (!program.audioStreams.empty())
2776                 {
2777                         eDebugNoNewLine(" (");
2778                         for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2779                                 i(program.audioStreams.begin());
2780                                 i != program.audioStreams.end(); ++i)
2781                         {
2782                                 if (i != program.audioStreams.begin())
2783                                         eDebugNoNewLine(", ");
2784                                 eDebugNoNewLine("%04x", i->pid);
2785                         }
2786                         eDebugNoNewLine(")");
2787                 }
2788                 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
2789                 pcrpid = program.pcrPid;
2790                 eDebugNoNewLine(", and the text pid is %04x\n", program.textPid);
2791                 tpid = program.textPid;
2792         }
2793
2794         m_have_video_pid = 0;
2795
2796         if (!m_decoder)
2797         {
2798                 h.getDecodeDemux(m_decode_demux);
2799                 if (m_decode_demux)
2800                 {
2801                         m_decode_demux->getMPEGDecoder(m_decoder, m_decoder_index);
2802                         if (m_decoder)
2803                                 m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
2804                 }
2805                 if (m_cue)
2806                         m_cue->setDecodingDemux(m_decode_demux, m_decoder);
2807                 mustPlay = true;
2808         }
2809
2810         m_timeshift_changed = 0;
2811
2812         if (m_decoder)
2813         {
2814                 bool wasSeekable = m_decoder->getVideoProgressive() != -1;
2815                 if (m_dvb_service)
2816                 {
2817                         achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
2818                         ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2819                         pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2820                 }
2821                 else // subservice
2822                 {
2823                         eServiceReferenceDVB ref;
2824                         m_service_handler.getServiceReference(ref);
2825                         eServiceReferenceDVB parent = ref.getParentServiceReference();
2826                         if (!parent)
2827                                 parent = ref;
2828                         if (parent)
2829                         {
2830                                 ePtr<eDVBResourceManager> res_mgr;
2831                                 if (!eDVBResourceManager::getInstance(res_mgr))
2832                                 {
2833                                         ePtr<iDVBChannelList> db;
2834                                         if (!res_mgr->getChannelList(db))
2835                                         {
2836                                                 ePtr<eDVBService> origService;
2837                                                 if (!db->getService(parent, origService))
2838                                                 {
2839                                                         ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
2840                                                         pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
2841                                                 }
2842                                         }
2843                                 }
2844                         }
2845                 }
2846
2847                 setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
2848                 setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
2849
2850                 m_decoder->setVideoPID(vpid, vpidtype);
2851                 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
2852
2853                 selectAudioStream();
2854
2855                 if (!(m_is_pvr || m_is_stream || m_timeshift_active))
2856                         m_decoder->setSyncPCR(pcrpid);
2857                 else
2858                         m_decoder->setSyncPCR(-1);
2859
2860                 if (m_decoder_index == 0)
2861                 {
2862                         m_decoder->setTextPID(tpid);
2863                 }
2864
2865                 if (vpid > 0 && vpid < 0x2000)
2866                         ;
2867                 else
2868                 {
2869                         std::string value;
2870                         bool showRadioBackground = eConfigManager::getConfigBoolValue("config.misc.showradiopic", true);
2871                         std::string radio_pic;
2872                         if (showRadioBackground)
2873                                 radio_pic = eConfigManager::getConfigValue("config.misc.radiopic");
2874                         else
2875                                 radio_pic = eConfigManager::getConfigValue("config.misc.blackradiopic");
2876                         m_decoder->setRadioPic(radio_pic);
2877                 }
2878
2879                 if (mustPlay)
2880                         m_decoder->play();
2881                 else
2882                         m_decoder->set();
2883
2884                 m_decoder->setAudioChannel(achannel);
2885
2886                 if (mustPlay && m_decode_demux && m_decoder_index == 0)
2887                 {
2888                         m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
2889                         m_teletext_parser->connectNewStream(slot(*this, &eDVBServicePlay::newSubtitleStream), m_new_subtitle_stream_connection);
2890                         m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
2891                         m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
2892                         m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
2893                         if (m_timeshift_changed)
2894                         {
2895                                 struct SubtitleTrack track;
2896                                 if (getCachedSubtitle(track) >= 0)
2897                                 {
2898                                         if (track.type == 0) // dvb
2899                                                 m_subtitle_parser->start(track.pid, track.page_number, track.magazine_number);
2900                                         else if (track.type == 1) // ttx
2901                                                 m_teletext_parser->setPageAndMagazine(track.page_number, track.magazine_number, track.language_code.c_str());
2902                                 }
2903                         }
2904                         m_teletext_parser->start(program.textPid);
2905                 }
2906
2907                 /* don't worry about non-existing services, nor pvr services */
2908                 if (m_dvb_service)
2909                 {
2910                         /* (audio pid will be set in selectAudioTrack) */
2911                         if (vpid >= 0)
2912                         {
2913                                 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
2914                                 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
2915                         }
2916                         if (pcrpid >= 0) m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
2917                         if (tpid >= 0) m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
2918                 }
2919                 if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
2920                         sendSeekableStateChanged = true;
2921         }
2922
2923         if (sendSeekableStateChanged)
2924                 m_event((iPlayableService*)this, evSeekableStatusChanged);
2925 }
2926
2927 void eDVBServicePlay::loadCuesheet()
2928 {
2929         std::string filename = m_reference.path + ".cuts";
2930
2931         m_cue_entries.clear();
2932
2933         FILE *f = fopen(filename.c_str(), "rb");
2934
2935         if (f)
2936         {
2937                 while (1)
2938                 {
2939                         unsigned long long where;
2940                         unsigned int what;
2941
2942                         if (!fread(&where, sizeof(where), 1, f))
2943                                 break;
2944                         if (!fread(&what, sizeof(what), 1, f))
2945                                 break;
2946
2947                         where = be64toh(where);
2948                         what = ntohl(what);
2949
2950                         if (what > 3)
2951                                 break;
2952
2953                         m_cue_entries.insert(cueEntry(where, what));
2954                 }
2955                 fclose(f);
2956                 eDebug("eDVBServicePlay: cuts file has %zd entries", m_cue_entries.size());
2957         } else
2958                 eDebug("eDVBServicePlay: cutfile not found!");
2959
2960         m_cuesheet_changed = 0;
2961         cutlistToCuesheet();
2962         m_event((iPlayableService*)this, evCuesheetChanged);
2963 }
2964
2965 void eDVBServicePlay::saveCuesheet()
2966 {
2967         std::string filename = m_timeshift_enabled ? m_timeshift_file : m_reference.path;
2968
2969                 /* save cuesheet only when main file is accessible. */
2970         if (::access(filename.c_str(), R_OK) < 0)
2971                 return;
2972
2973         filename.append(".cuts");
2974
2975         FILE *f = fopen(filename.c_str(), "wb");
2976
2977         if (f)
2978         {
2979                 unsigned long long where;
2980                 int what;
2981
2982                 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2983                 {
2984                         where = htobe64(i->where);
2985                         what = htonl(i->what);
2986                         fwrite(&where, sizeof(where), 1, f);
2987                         fwrite(&what, sizeof(what), 1, f);
2988
2989                 }
2990                 fclose(f);
2991         }
2992
2993         m_cuesheet_changed = 0;
2994 }
2995
2996 void eDVBServicePlay::cutlistToCuesheet()
2997 {
2998         if (!m_cue)
2999         {
3000                 eDebug("eDVBServicePlay: no cue sheet");
3001                 return;
3002         }
3003         m_cue->clear();
3004
3005         if ((m_cutlist_enabled & 1) == 0)
3006         {
3007                 m_cue->commitSpans();
3008                 eDebug("eDVBServicePlay: cutlists were disabled");
3009                 return;
3010         }
3011
3012         pts_t in = 0, out = 0, length = 0;
3013
3014         getLength(length);
3015
3016         std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
3017
3018         int have_any_span = 0;
3019
3020         while (1)
3021         {
3022                 if (i == m_cue_entries.end())
3023                 {
3024                         if (!have_any_span && !in)
3025                                 break;
3026                         out = length;
3027                 } else {
3028                         if (i->what == 0) /* in */
3029                         {
3030                                 in = i++->where;
3031                                 continue;
3032                         } else if (i->what == 1) /* out */
3033                                 out = i++->where;
3034                         else /* mark (2) or last play position (3) */
3035                         {
3036                                 i++;
3037                                 continue;
3038                         }
3039                 }
3040
3041                 if (in < 0)
3042                         in = 0;
3043                 if (out < 0)
3044                         out = 0;
3045                 if (in > length)
3046                         in = length;
3047                 if (out > length)
3048                         out = length;
3049
3050                 if (in < out)
3051                 {
3052                         have_any_span = 1;
3053                         m_cue->addSourceSpan(in, out);
3054                         in = out = 0;
3055                 }
3056
3057                 in = length;
3058
3059                 if (i == m_cue_entries.end())
3060                         break;
3061         }
3062         m_cue->commitSpans();
3063 }
3064
3065 RESULT eDVBServicePlay::enableSubtitles(iSubtitleUser *user, SubtitleTrack &track)
3066 {
3067         if (m_subtitle_widget)
3068                 disableSubtitles();
3069
3070         if (track.type == 1)  // teletext subtitles
3071         {
3072                 int page, magazine, pid;
3073                 std::string lang;
3074
3075                 if (!m_teletext_parser)
3076                 {
3077                         eDebug("eDVBServicePlay: enable teletext subtitles.. no parser !!!");
3078                         return -1;
3079                 }
3080
3081                 pid = track.pid;
3082                 page = track.page_number;
3083                 magazine = track.magazine_number;
3084                 lang = track.language_code;
3085
3086                 m_subtitle_widget = user;
3087                 m_teletext_parser->setPageAndMagazine(page, magazine, lang.c_str());
3088                 if (m_dvb_service)
3089                 {
3090                         int i, sub = 0;
3091                         for (i=0; i < m_teletext_parser->max_id; i++)
3092                         {
3093                                 if (!memcmp(m_teletext_parser->my_country_codes[i], lang.c_str(), 3))
3094                                 {
3095                                         sub = i;
3096                                         break;
3097                                 }
3098                         }
3099                         m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|((sub&0x1F)<<3)|(magazine&0x7));
3100                 }
3101         }
3102         else if (track.type == 0)
3103         {
3104                 int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
3105                 if (!m_subtitle_parser)
3106                 {
3107                         eDebug("eDVBServicePlay: enable dvb subtitles.. no parser !!!");
3108                         return -1;
3109                 }
3110
3111                 pid = track.pid;
3112                 composition_page_id = track.page_number;
3113                 ancillary_page_id = track.magazine_number;
3114
3115                 m_subtitle_widget = user;
3116                 m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
3117                 if (m_dvb_service)
3118                         m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
3119         }
3120         else
3121                 goto error_out;
3122         return 0;
3123 error_out:
3124         eDebug("eDVBServicePlay: enableSubtitles needs a valid type:\n"
3125                 "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
3126                 "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
3127         return -1;
3128 }
3129
3130 RESULT eDVBServicePlay::disableSubtitles()
3131 {
3132         if (m_subtitle_widget) m_subtitle_widget->destroy();
3133         m_subtitle_widget = 0;
3134         if (m_subtitle_parser)
3135         {
3136                 m_subtitle_parser->stop();
3137                 m_dvb_subtitle_pages.clear();
3138         }
3139         if (m_teletext_parser)
3140         {
3141                 m_teletext_parser->setPageAndMagazine(-1, -1, "und");
3142                 m_subtitle_pages.clear();
3143         }
3144         if (m_dvb_service)
3145                 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, 0);
3146         return 0;
3147 }
3148
3149 RESULT eDVBServicePlay::getCachedSubtitle(struct SubtitleTrack &track)
3150 {
3151         if (m_dvb_service)
3152         {
3153                 eDVBServicePMTHandler::program program;
3154                 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
3155                 if (!h.getProgramInfo(program))
3156                 {
3157                         bool usecache = eConfigManager::getConfigBoolValue("config.autolanguage.subtitle_usecache");
3158                         int stream=program.defaultSubtitleStream;
3159                         int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
3160
3161                         if (usecache || stream == -1)
3162                         {
3163                                 if (tmp != -1 && tmp != 0)
3164                                 {
3165                                         unsigned int data = (unsigned int)tmp;
3166                                         int pid = (data&0xFFFF0000)>>16;
3167                                         if (program.textPid == pid) // teletext
3168                                                 track.type = 1; // type teletext
3169                                         else
3170                                                 track.type = 0; // type dvb
3171                                         track.pid = pid; // pid
3172                                         track.page_number = (data >> 8) & 0xff; // composition_page / page
3173                                         int k = (data >> 3) & 0x1f;
3174                                         track.magazine_number = data & 0x7; // ancillary_page / magazine
3175                                         track.language_code = m_teletext_parser->my_country_codes[k];
3176                                         return 0;
3177                                 }
3178                         }
3179                         if (stream != -1 && (tmp != 0 || !usecache))
3180                         {
3181                                 if (program.subtitleStreams[stream].subtitling_type == 1)
3182                                 {
3183                                         track.type = 1; // type teletext
3184                                         track.pid = program.subtitleStreams[stream].pid;
3185                                         track.page_number = program.subtitleStreams[stream].teletext_page_number & 0xff;
3186                                         track.magazine_number = program.subtitleStreams[stream].teletext_magazine_number & 0x07;
3187                                         track.language_code = program.subtitleStreams[stream].language_code;
3188                                         return 0;
3189                                 }
3190                                 else
3191                                 {
3192                                         track.type = 0; // type dvb
3193                                         track.pid = program.subtitleStreams[stream].pid;
3194                                         track.page_number = program.subtitleStreams[stream].composition_page_id;
3195                                         track.magazine_number = program.subtitleStreams[stream].ancillary_page_id;
3196                                         track.language_code = program.subtitleStreams[stream].language_code;
3197                                         return 0;
3198                                 }
3199                         }
3200                 }
3201         }
3202         return -1;
3203 }
3204
3205 RESULT eDVBServicePlay::getSubtitleList(std::vector<SubtitleTrack> &subtitlelist)
3206 {
3207         if (!m_teletext_parser)
3208                 return -1;
3209
3210         std::set<int> added_ttx_pages;
3211
3212         std::set<eDVBServicePMTHandler::subtitleStream> &subs =
3213                 m_teletext_parser->m_found_subtitle_pages;
3214
3215         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
3216         eDVBServicePMTHandler::program program;
3217         if (h.getProgramInfo(program))
3218                 eDebug("eDVBServicePlay: getting program info failed.");
3219         else
3220         {
3221                 for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
3222                         it != program.subtitleStreams.end(); ++it)
3223                 {
3224                         struct SubtitleTrack track;
3225                         switch(it->subtitling_type)
3226                         {
3227                                 case 0x01: // ebu teletext subtitles
3228                                 {
3229                                         int page_number = it->teletext_page_number & 0xFF;
3230                                         int magazine_number = it->teletext_magazine_number & 7;
3231                                         int hash = magazine_number << 8 | page_number;
3232                                         if (added_ttx_pages.find(hash) == added_ttx_pages.end())
3233                                         {
3234                                                 track.type = 1;
3235                                                 track.pid = it->pid;
3236                                                 track.page_number = page_number;
3237                                                 track.magazine_number = magazine_number;
3238                                                 track.language_code = it->language_code;
3239                                                 subtitlelist.push_back(track);
3240                                                 added_ttx_pages.insert(hash);
3241                                         }
3242                                         break;
3243                                 }
3244                                 case 0x10 ... 0x13:
3245                                 case 0x20 ... 0x23: // dvb subtitles
3246                                 {
3247                                         track.type = 0;
3248                                         track.pid = it->pid;
3249                                         track.page_number = it->composition_page_id;
3250                                         track.magazine_number = it->ancillary_page_id;
3251                                         track.language_code = it->language_code;
3252                                         subtitlelist.push_back(track);
3253                                         break;
3254                                 }
3255                         }
3256                 }
3257         }
3258
3259         for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
3260                 it != subs.end(); ++it)
3261         {
3262                 int page_number = it->teletext_page_number & 0xFF;
3263                 int magazine_number = it->teletext_magazine_number & 7;
3264                 int hash = magazine_number << 8 | page_number;
3265                 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
3266                 {
3267                         struct SubtitleTrack track;
3268                         track.type = 1;
3269                         track.pid = it->pid;
3270                         track.page_number = page_number;
3271                         track.magazine_number = magazine_number;
3272                         track.language_code = "und";
3273                         subtitlelist.push_back(track);
3274                 }
3275         }
3276
3277         return 0;
3278 }
3279
3280 void eDVBServicePlay::newSubtitleStream()
3281 {
3282         m_event((iPlayableService*)this, evUpdatedInfo);
3283 }
3284
3285 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
3286 {
3287         if (m_subtitle_widget)
3288         {
3289                 int subtitledelay = 0;
3290                 pts_t pts;
3291                 m_decoder->getPTS(0, pts);
3292                 if (m_is_pvr || m_timeshift_enabled)
3293                 {
3294                         eDebug("eDVBServicePlay: Subtitle in recording/timeshift");
3295                         subtitledelay = eConfigManager::getConfigIntValue("config.subtitles.subtitle_noPTSrecordingdelay", 315000);
3296                 }
3297                 else
3298                 {
3299                         /* check the setting for subtitle delay in live playback, either with pts, or without pts */
3300                         subtitledelay = eConfigManager::getConfigIntValue("config.subtitles.subtitle_bad_timing_delay", 0);
3301                 }
3302
3303                 // 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);
3304                 eDVBTeletextSubtitlePage tmppage = page;
3305                 tmppage.m_have_pts = true;
3306
3307                 if (abs(tmppage.m_pts - pts) > 20*90000)
3308                         tmppage.m_pts = pts; // fix abnormal pts diffs
3309
3310                 tmppage.m_pts += subtitledelay;
3311                 m_subtitle_pages.push_back(tmppage);
3312
3313                 checkSubtitleTiming();
3314         }
3315 }
3316
3317 void eDVBServicePlay::checkSubtitleTiming()
3318 {
3319         pts_t pos = 0;
3320 //      eDebug("eDVBServicePlay: checkSubtitleTiming");
3321         if (!m_subtitle_widget)
3322                 return;
3323         if (m_subtitle_pages.empty() && m_dvb_subtitle_pages.empty())
3324         {
3325                 return;
3326         }
3327         if (m_decoder)
3328         {
3329                 m_decoder->getPTS(0, pos);
3330         }
3331
3332         while (1)
3333         {
3334                 enum { TELETEXT, DVB } type;
3335                 eDVBTeletextSubtitlePage page;
3336                 eDVBSubtitlePage dvb_page;
3337                 pts_t show_time;
3338                 if (!m_subtitle_pages.empty())
3339                 {
3340                         page = m_subtitle_pages.front();
3341                         type = TELETEXT;
3342                         show_time = page.m_pts;
3343                 }
3344                 else if (!m_dvb_subtitle_pages.empty())
3345                 {