Add flag to services so we can mark services as dedicated 3D
[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 sIsDedicated3D: if (m_dvb_service) return m_dvb_service->isDedicated3D(); return false;
1957         case sVideoPID:
1958                 if (m_dvb_service)
1959                 {
1960                         int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
1961                         if (vpid != -1)
1962                                 return vpid;
1963                 }
1964                 if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
1965         case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
1966         case sAudioPID:
1967                 if (m_dvb_service)
1968                 {
1969                         int apid = m_dvb_service->getCacheEntry(eDVBService::cMPEGAPID);
1970                         if (apid != -1)
1971                                 return apid;
1972                         apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
1973                         if (apid != -1)
1974                                 return apid;
1975                         apid = m_dvb_service->getCacheEntry(eDVBService::cDDPPID);
1976                         if (apid != -1)
1977                                 return apid;
1978                         apid = m_dvb_service->getCacheEntry(eDVBService::cAACHEAPID);
1979                         if (apid != -1)
1980                                 return apid;
1981                 }
1982                 if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
1983         case sPCRPID:
1984                 if (m_dvb_service)
1985                 {
1986                         int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
1987                         if (pcrpid != -1)
1988                                 return pcrpid;
1989                 }
1990                 if (no_program_info) return -1; return program.pcrPid;
1991         case sPMTPID: if (no_program_info) return -1; return program.pmtPid;
1992         case sTXTPID: if (no_program_info) return -1; return program.textPid;
1993         case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
1994         case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
1995         case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
1996         case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
1997         case sProvider: if (!m_dvb_service) return -1; return -2;
1998         case sServiceref: return resIsString;
1999         case sDVBState: return m_tune_state;
2000         default:
2001                 break;
2002         }
2003         return -1;
2004 }
2005
2006 std::string eDVBServicePlay::getInfoString(int w)
2007 {
2008         switch (w)
2009         {
2010         case sProvider:
2011                 if (!m_dvb_service) return "";
2012                 return m_dvb_service->m_provider_name;
2013         case sServiceref:
2014                 return m_reference.toString();
2015         case sHBBTVUrl:
2016         {
2017                 std::string url;
2018                 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2019                 h.getHBBTVUrl(url);
2020                 return url;
2021         }
2022         case sLiveStreamDemuxId:
2023         {
2024                 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2025                 std::string demux;
2026                 demux += h.getDemuxID() + '0';
2027                 return demux;
2028         }
2029         default:
2030                 break;
2031         }
2032         return iServiceInformation::getInfoString(w);
2033 }
2034
2035 ePtr<iDVBTransponderData> eDVBServicePlay::getTransponderData()
2036 {
2037         return eStaticServiceDVBInformation().getTransponderData(m_reference);
2038 }
2039
2040 void eDVBServicePlay::getAITApplications(std::map<int, std::string> &aitlist)
2041 {
2042         return m_service_handler.getAITApplications(aitlist);
2043 }
2044
2045 void eDVBServicePlay::getCaIds(std::vector<int> &caids, std::vector<int> &ecmpids)
2046 {
2047         m_service_handler.getCaIds(caids, ecmpids);
2048 }
2049
2050 int eDVBServicePlay::getNumberOfTracks()
2051 {
2052         eDVBServicePMTHandler::program program;
2053         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2054         if (h.getProgramInfo(program))
2055                 return 0;
2056         return program.audioStreams.size();
2057 }
2058
2059 int eDVBServicePlay::getCurrentTrack()
2060 {
2061         eDVBServicePMTHandler::program program;
2062         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2063         if (h.getProgramInfo(program))
2064                 return 0;
2065
2066         int max = program.audioStreams.size();
2067         int i;
2068
2069         for (i = 0; i < max; ++i)
2070                 if (program.audioStreams[i].pid == m_current_audio_pid)
2071                         return i;
2072
2073         return 0;
2074 }
2075
2076 RESULT eDVBServicePlay::selectTrack(unsigned int i)
2077 {
2078         int ret = selectAudioStream(i);
2079
2080         if (m_decoder->set())
2081                 return -5;
2082
2083         return ret;
2084 }
2085
2086 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
2087 {
2088         eDVBServicePMTHandler::program program;
2089         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2090
2091         if (h.getProgramInfo(program))
2092                 return -1;
2093
2094         if (i >= program.audioStreams.size())
2095                 return -2;
2096
2097         info.m_pid = program.audioStreams[i].pid;
2098
2099         if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
2100                 info.m_description = "MPEG";
2101         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
2102                 info.m_description = "AC3";
2103         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDDP)
2104                 info.m_description = "AC3+";
2105         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
2106                 info.m_description = "AAC";
2107         else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE)
2108                 info.m_description = "AAC-HE";
2109         else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
2110                 info.m_description = "DTS";
2111         else  if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTSHD)
2112                 info.m_description = "DTS-HD";
2113         else
2114                 info.m_description = "???";
2115
2116         if (program.audioStreams[i].component_tag != -1)
2117         {
2118                 ePtr<eServiceEvent> evt;
2119                 if (!m_event_handler.getEvent(evt, 0))
2120                 {
2121                         ePtr<eComponentData> data;
2122                         if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
2123                                 info.m_language = data->getText();
2124                 }
2125         }
2126
2127         if (info.m_language.empty())
2128                 info.m_language = program.audioStreams[i].language_code;
2129
2130         return 0;
2131 }
2132
2133 int eDVBServicePlay::selectAudioStream(int i)
2134 {
2135         eDVBServicePMTHandler::program program;
2136         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2137         pts_t position = -1;
2138
2139         if (h.getProgramInfo(program))
2140                 return -1;
2141
2142         if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
2143                 return -2;
2144
2145         if (!m_decoder)
2146                 return -3;
2147
2148         int stream = i;
2149         if (stream == -1)
2150                 stream = program.defaultAudioStream;
2151
2152         int apid = -1, apidtype = -1;
2153
2154         if (((unsigned int)stream) < program.audioStreams.size())
2155         {
2156                 apid = program.audioStreams[stream].pid;
2157                 apidtype = program.audioStreams[stream].type;
2158         }
2159
2160         if (i != -1 && apid != m_current_audio_pid && (m_is_pvr || m_timeshift_active))
2161                 eDebug("eDVBServicePlay: getPlayPosition ret %d, pos %lld in selectAudioStream", getPlayPosition(position), position);
2162
2163         m_current_audio_pid = apid;
2164
2165         if (m_decoder->setAudioPID(apid, apidtype))
2166         {
2167                 eDebug("eDVBServicePlay: set audio pid failed");
2168                 return -4;
2169         }
2170
2171         if (position != -1)
2172                 eDebug("eDVBServicePlay: seekTo ret %d", seekTo(position));
2173
2174         int rdsPid = apid;
2175
2176                 /* 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 */
2177         if (!(m_is_pvr || m_timeshift_active || m_decoder_index || m_have_video_pid))
2178         {
2179                 int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
2180                 if (different_pid)
2181                         rdsPid = program.audioStreams[stream].rdsPid;
2182                 if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
2183                 {
2184                         m_rds_decoder = 0;
2185                         ePtr<iDVBDemux> data_demux;
2186                         if (!h.getDataDemux(data_demux))
2187                         {
2188                                 m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
2189                                 m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
2190                                 m_rds_decoder->start(rdsPid);
2191                         }
2192                 }
2193         }
2194
2195                         /* store new pid as default only when:
2196                                 a.) we have an entry in the service db for the current service,
2197                                 b.) we are not playing back something,
2198                                 c.) we are not selecting the default entry. (we wouldn't change
2199                                     anything in the best case, or destroy the default setting in
2200                                     case the real default is not yet available.)
2201                                 d.) we have only one audiostream (overwrite the cache to make sure
2202                                     the cache contains the correct audio pid and type)
2203                         */
2204         if (m_dvb_service && ((i != -1) || (program.audioStreams.size() == 1)
2205                 || ((m_dvb_service->getCacheEntry(eDVBService::cMPEGAPID) == -1)
2206                 && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)== -1)
2207                 && (m_dvb_service->getCacheEntry(eDVBService::cDDPPID)== -1)
2208                 && (m_dvb_service->getCacheEntry(eDVBService::cAACHEAPID) == -1))))
2209         {
2210                 m_dvb_service->setCacheEntry(eDVBService::cMPEGAPID, apidtype == eDVBAudio::aMPEG ? apid : -1);
2211                 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apidtype == eDVBAudio::aAC3 ? apid : -1);
2212                 m_dvb_service->setCacheEntry(eDVBService::cDDPPID, apidtype == eDVBAudio::aDDP ? apid : -1);
2213                 m_dvb_service->setCacheEntry(eDVBService::cAACHEAPID, apidtype == eDVBAudio::aAACHE ? apid : -1);
2214         }
2215
2216         h.resetCachedProgram();
2217
2218         return 0;
2219 }
2220
2221 int eDVBServicePlay::getCurrentChannel()
2222 {
2223         return m_decoder ? m_decoder->getAudioChannel() : STEREO;
2224 }
2225
2226 RESULT eDVBServicePlay::selectChannel(int i)
2227 {
2228         if (i < LEFT || i > RIGHT || i == STEREO)
2229                 i = -1;  // Stereo
2230         if (m_dvb_service)
2231                 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
2232         if (m_decoder)
2233                 m_decoder->setAudioChannel(i);
2234         return 0;
2235 }
2236
2237 std::string eDVBServicePlay::getText(int x)
2238 {
2239         if (m_rds_decoder)
2240                 switch(x)
2241                 {
2242                         case RadioText:
2243                                 return convertLatin1UTF8(m_rds_decoder->getRadioText());
2244                         case RtpText:
2245                                 return convertLatin1UTF8(m_rds_decoder->getRtpText());
2246                 }
2247         return "";
2248 }
2249
2250 void eDVBServicePlay::rdsDecoderEvent(int what)
2251 {
2252         switch(what)
2253         {
2254                 case eDVBRdsDecoder::RadioTextChanged:
2255                         m_event((iPlayableService*)this, evUpdatedRadioText);
2256                         break;
2257                 case eDVBRdsDecoder::RtpTextChanged:
2258                         m_event((iPlayableService*)this, evUpdatedRtpText);
2259                         break;
2260                 case eDVBRdsDecoder::RassInteractivePicMaskChanged:
2261                         m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
2262                         break;
2263                 case eDVBRdsDecoder::RecvRassSlidePic:
2264                         m_event((iPlayableService*)this, evUpdatedRassSlidePic);
2265                         break;
2266         }
2267 }
2268
2269 void eDVBServicePlay::showRassSlidePicture()
2270 {
2271         if (m_rds_decoder)
2272         {
2273                 if (m_decoder)
2274                 {
2275                         std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
2276                         if (rass_slide_pic.length())
2277                                 m_decoder->showSinglePic(rass_slide_pic.c_str());
2278                         else
2279                                 eDebug("eDVBServicePlay: empty filename for rass slide picture received!!");
2280                 }
2281                 else
2282                         eDebug("eDVBServicePlay: no MPEG Decoder to show iframes avail");
2283         }
2284         else
2285                 eDebug("eDVBServicePlay: showRassSlidePicture called.. but not decoder");
2286 }
2287
2288 void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
2289 {
2290         if (m_rds_decoder)
2291         {
2292                 if (m_decoder)
2293                 {
2294                         std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
2295                         if (rass_interactive_pic.length())
2296                                 m_decoder->showSinglePic(rass_interactive_pic.c_str());
2297                         else
2298                                 eDebug("eDVBServicePlay: empty filename for rass interactive picture %d/%d received!!", page, subpage);
2299                 }
2300                 else
2301                         eDebug("eDVBServicePlay: no MPEG Decoder to show iframes avail");
2302         }
2303         else
2304                 eDebug("eDVBServicePlay: showRassInteractivePic called.. but not decoder");
2305 }
2306
2307 ePyObject eDVBServicePlay::getRassInteractiveMask()
2308 {
2309         if (m_rds_decoder)
2310                 return m_rds_decoder->getRassPictureMask();
2311         Py_RETURN_NONE;
2312 }
2313
2314 int eDVBServiceBase::getFrontendInfo(int w)
2315 {
2316         eUsePtr<iDVBChannel> channel;
2317         if(m_service_handler.getChannel(channel))
2318                 return 0;
2319         ePtr<iDVBFrontend> fe;
2320         if(channel->getFrontend(fe))
2321                 return 0;
2322         return fe->readFrontendData(w);
2323 }
2324
2325 ePtr<iDVBFrontendData> eDVBServiceBase::getFrontendData()
2326 {
2327         ePtr<iDVBFrontendData> ret;
2328         eUsePtr<iDVBChannel> channel;
2329         if(!m_service_handler.getChannel(channel))
2330         {
2331                 ePtr<iDVBFrontend> fe;
2332                 if(!channel->getFrontend(fe))
2333                         fe->getFrontendData(ret);
2334         }
2335         return ret;
2336 }
2337
2338 ePtr<iDVBFrontendStatus> eDVBServiceBase::getFrontendStatus()
2339 {
2340         ePtr<iDVBFrontendStatus> ret;
2341         eUsePtr<iDVBChannel> channel;
2342         if(!m_service_handler.getChannel(channel))
2343         {
2344                 ePtr<iDVBFrontend> fe;
2345                 if(!channel->getFrontend(fe))
2346                         fe->getFrontendStatus(ret);
2347         }
2348         return ret;
2349 }
2350
2351 ePtr<iDVBTransponderData> eDVBServiceBase::getTransponderData(bool original)
2352 {
2353         ePtr<iDVBTransponderData> ret;
2354         eUsePtr<iDVBChannel> channel;
2355         if(!m_service_handler.getChannel(channel))
2356         {
2357                 ePtr<iDVBFrontend> fe;
2358                 if(!channel->getFrontend(fe))
2359                         fe->getTransponderData(ret, original);
2360         }
2361         return ret;
2362 }
2363
2364 int eDVBServicePlay::getNumberOfSubservices()
2365 {
2366         ePtr<eServiceEvent> evt;
2367         if (!m_event_handler.getEvent(evt, 0))
2368                 return evt->getNumOfLinkageServices();
2369         return 0;
2370 }
2371
2372 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
2373 {
2374         ePtr<eServiceEvent> evt;
2375         if (!m_event_handler.getEvent(evt, 0))
2376         {
2377                 if (!evt->getLinkageService(sub, m_reference, n))
2378                         return 0;
2379         }
2380         sub.type=eServiceReference::idInvalid;
2381         return -1;
2382 }
2383
2384 RESULT eDVBServicePlay::startTimeshift()
2385 {
2386         ePtr<iDVBDemux> demux;
2387
2388         eDebug("eDVBServicePlay: Start timeshift!");
2389
2390         if (m_timeshift_enabled)
2391                 return -1;
2392
2393                 /* start recording with the data demux. */
2394         if (m_service_handler.getDataDemux(demux))
2395                 return -2;
2396
2397         demux->createTSRecorder(m_record);
2398         if (!m_record)
2399                 return -3;
2400
2401         std::string tspath = eConfigManager::getConfigValue("config.usage.timeshift_path");
2402         if (tspath == "")
2403         {
2404                 eDebug("eDVBServicePlay: could not query ts path");
2405                 return -5;
2406         }
2407         if (tspath.empty())
2408         {
2409                 eDebug("eDVBServicePlay: TS path is empty");
2410                 return -5;
2411         }
2412         if (tspath[tspath.length()-1] != '/')
2413                 tspath.append("/");
2414         tspath.append("timeshift.XXXXXX");
2415         char* templ = new char[tspath.length() + 1];
2416         strcpy(templ, tspath.c_str());
2417         m_timeshift_fd = mkstemp(templ);
2418         m_timeshift_file = std::string(templ);
2419         eDebug("eDVBServicePlay: recording to %s", templ);
2420         delete [] templ;
2421
2422         if (m_timeshift_fd < 0)
2423         {
2424                 m_record = 0;
2425                 return -4;
2426         }
2427
2428         m_record->setTargetFD(m_timeshift_fd);
2429         m_record->setTargetFilename(m_timeshift_file);
2430         m_record->enableAccessPoints(false); // no need for AP information during shift
2431         m_timeshift_enabled = 1;
2432
2433         updateTimeshiftPids();
2434         m_record->start();
2435
2436         return 0;
2437 }
2438
2439 RESULT eDVBServicePlay::stopTimeshift(bool swToLive)
2440 {
2441         if (!m_timeshift_enabled)
2442                 return -1;
2443
2444         if (swToLive)
2445                 switchToLive();
2446
2447         m_timeshift_enabled = 0;
2448
2449         m_record->stop();
2450         m_record = 0;
2451
2452         if (m_timeshift_fd >= 0)
2453         {
2454                 close(m_timeshift_fd);
2455                 m_timeshift_fd = -1;
2456         }
2457
2458         if (!m_save_timeshift)
2459         {
2460                 eDebug("eDVBServicePlay: remove timeshift files");
2461                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file);
2462                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file + ".sc");
2463                 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file + ".cuts");
2464         }
2465         else
2466         {
2467                 eDebug("eDVBServicePlay: timeshift files not deleted");
2468                 m_save_timeshift = 0;
2469         }
2470         return 0;
2471 }
2472
2473 int eDVBServicePlay::isTimeshiftActive()
2474 {
2475         return m_timeshift_enabled && m_timeshift_active;
2476 }
2477
2478 int eDVBServicePlay::isTimeshiftEnabled()
2479 {
2480         return m_timeshift_enabled;
2481 }
2482
2483 RESULT eDVBServicePlay::saveTimeshiftFile()
2484 {
2485         if (!m_timeshift_enabled)
2486                 return -1;
2487
2488         m_save_timeshift = 1;
2489
2490         return 0;
2491 }
2492
2493 RESULT eDVBServicePlay::activateTimeshift()
2494 {
2495         if (!m_timeshift_enabled)
2496                 return -1;
2497
2498         if (!m_timeshift_active)
2499         {
2500                 switchToTimeshift();
2501                 return 0;
2502         }
2503
2504         return -2;
2505 }
2506
2507 std::string eDVBServicePlay::getTimeshiftFilename()
2508 {
2509         if (m_timeshift_enabled)
2510                 return m_timeshift_file;
2511         else
2512                 return "";
2513 }
2514
2515 PyObject *eDVBServicePlay::getCutList()
2516 {
2517         ePyObject list = PyList_New(0);
2518
2519         for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2520         {
2521                 ePyObject tuple = PyTuple_New(2);
2522                 PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
2523                 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
2524                 PyList_Append(list, tuple);
2525                 Py_DECREF(tuple);
2526         }
2527
2528         return list;
2529 }
2530
2531 void eDVBServicePlay::setCutList(ePyObject list)
2532 {
2533         if (!PyList_Check(list))
2534                 return;
2535         int size = PyList_Size(list);
2536         int i;
2537
2538         m_cue_entries.clear();
2539
2540         for (i=0; i<size; ++i)
2541         {
2542                 ePyObject tuple = PyList_GET_ITEM(list, i);
2543                 if (!PyTuple_Check(tuple))
2544                 {
2545                         eDebug("eDVBServicePlay: non-tuple in cutlist");
2546                         continue;
2547                 }
2548                 if (PyTuple_Size(tuple) != 2)
2549                 {
2550                         eDebug("eDVBServicePlay: cutlist entries need to be a 2-tuple");
2551                         continue;
2552                 }
2553                 ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
2554                 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
2555                 {
2556                         eDebug("eDVBServicePlay: cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
2557                         continue;
2558                 }
2559                 pts_t pts = PyLong_AsLongLong(ppts);
2560                 int type = PyInt_AsLong(ptype);
2561                 m_cue_entries.insert(cueEntry(pts, type));
2562                 eDebug("eDVBServicePlay: adding %08llx, %d", pts, type);
2563         }
2564         m_cuesheet_changed = 1;
2565
2566         cutlistToCuesheet();
2567         m_event((iPlayableService*)this, evCuesheetChanged);
2568 }
2569
2570 void eDVBServicePlay::setCutListEnable(int enable)
2571 {
2572         m_cutlist_enabled = enable;
2573         cutlistToCuesheet();
2574 }
2575
2576 void eDVBServicePlay::updateTimeshiftPids()
2577 {
2578         if (!m_record)
2579                 return;
2580
2581         eDVBServicePMTHandler::program program;
2582         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2583
2584         if (h.getProgramInfo(program))
2585                 return;
2586         else
2587         {
2588                 int timing_pid = -1;
2589                 int timing_stream_type = -1;
2590                 iDVBTSRecorder::timing_pid_type timing_pid_type = iDVBTSRecorder::none;
2591                 std::set<int> pids_to_record;
2592                 pids_to_record.insert(0); // PAT
2593                 if (program.pmtPid != -1)
2594                         pids_to_record.insert(program.pmtPid); // PMT
2595
2596                 if (program.textPid != -1)
2597                         pids_to_record.insert(program.textPid); // Videotext
2598
2599                 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2600                         i(program.videoStreams.begin());
2601                         i != program.videoStreams.end(); ++i)
2602                 {
2603                         if (timing_pid == -1)
2604                         {
2605                                 timing_pid = i->pid;
2606                                 timing_stream_type = i->type;
2607                                 timing_pid_type = iDVBTSRecorder::video_pid;
2608                         }
2609                         pids_to_record.insert(i->pid);
2610                 }
2611
2612                 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2613                         i(program.audioStreams.begin());
2614                         i != program.audioStreams.end(); ++i)
2615                 {
2616                         if (timing_pid == -1)
2617                         {
2618                                 timing_pid = i->pid;
2619                                 timing_stream_type = i->type;
2620                                 timing_pid_type = iDVBTSRecorder::audio_pid;
2621                         }
2622                         pids_to_record.insert(i->pid);
2623                 }
2624
2625                 for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
2626                         i(program.subtitleStreams.begin());
2627                         i != program.subtitleStreams.end(); ++i)
2628                                 pids_to_record.insert(i->pid);
2629
2630                 std::set<int> new_pids, obsolete_pids;
2631
2632                 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
2633                                 m_pids_active.begin(), m_pids_active.end(),
2634                                 std::inserter(new_pids, new_pids.begin()));
2635
2636                 std::set_difference(
2637                                 m_pids_active.begin(), m_pids_active.end(),
2638                                 pids_to_record.begin(), pids_to_record.end(),
2639                                 std::inserter(new_pids, new_pids.begin())
2640                                 );
2641
2642                 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
2643                         m_record->addPID(*i);
2644
2645                 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
2646                         m_record->removePID(*i);
2647
2648                 if (timing_pid != -1)
2649                         m_record->setTimingPID(timing_pid, timing_pid_type, timing_stream_type);
2650         }
2651 }
2652
2653 RESULT eDVBServicePlay::setNextPlaybackFile(const char *f)
2654 {
2655         m_timeshift_file_next = f;
2656         return 0;
2657 }
2658
2659 void eDVBServicePlay::switchToLive()
2660 {
2661         if (!m_timeshift_active)
2662                 return;
2663
2664         eDebug("eDVBServicePlay: SwitchToLive");
2665
2666         resetTimeshift(0);
2667
2668         m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
2669
2670         /* free the timeshift service handler, we need the resources */
2671         m_service_handler_timeshift.free();
2672
2673         updateDecoder(true);
2674 }
2675
2676 void eDVBServicePlay::resetTimeshift(int start)
2677 {
2678         m_cue = 0;
2679         m_decode_demux = 0;
2680         m_decoder = 0;
2681         m_teletext_parser = 0;
2682         m_rds_decoder = 0;
2683         m_subtitle_parser = 0;
2684         m_new_subtitle_stream_connection = 0;
2685         m_new_subtitle_page_connection = 0;
2686         m_new_dvb_subtitle_page_connection = 0;
2687         m_rds_decoder_event_connection = 0;
2688         m_video_event_connection = 0;
2689         m_timeshift_changed = 1;
2690         m_timeshift_file_next.clear();
2691
2692         if (start)
2693         {
2694                 m_cue = new eCueSheet();
2695                 m_timeshift_active = 1;
2696         }
2697         else
2698                 m_timeshift_active = 0;
2699 }
2700
2701 ePtr<iTsSource> eDVBServicePlay::createTsSource(eServiceReferenceDVB &ref, int packetsize)
2702 {
2703         /*
2704          * NOTE: we cannot use our m_is_stream status, instead we check the reference again.
2705          * It could be that createTsSource is called to start a timeshift on a stream,
2706          * in which case the ref passed here no longer is a url, but a timeshift file instead.
2707          * (but m_is_stream would still be set, because of the ref which was passed to our
2708          * constructor)
2709          */
2710         if (ref.path.substr(0, 7) == "http://")
2711         {
2712                 eHttpStream *f = new eHttpStream();
2713                 f->open(ref.path.c_str());
2714                 return ePtr<iTsSource>(f);
2715         }
2716         else
2717         {
2718                 eRawFile *f = new eRawFile(packetsize);
2719                 f->open(ref.path.c_str());
2720                 return ePtr<iTsSource>(f);
2721         }
2722 }
2723
2724 void eDVBServicePlay::switchToTimeshift()
2725 {
2726         if (m_timeshift_active)
2727                 return;
2728
2729         resetTimeshift(1);
2730
2731         eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
2732         r.path = m_timeshift_file;
2733
2734         m_cue->seekTo(0, -1000);
2735
2736         ePtr<iTsSource> source = createTsSource(r);
2737         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 */
2738
2739         eDebug("eDVBServicePlay: eDVBServicePlay::switchToTimeshift, in pause mode now.");
2740         pause();
2741         updateDecoder(true); /* mainly to switch off PCR, and to set pause */
2742 }
2743
2744 void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged)
2745 {
2746         int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
2747         bool mustPlay = false;
2748
2749         eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2750
2751         eDVBServicePMTHandler::program program;
2752         if (h.getProgramInfo(program))
2753                 eDebug("eDVBServicePlay: getting program info failed.");
2754         else
2755         {
2756                 eDebugNoNewLineStart("eDVBServicePlay: have %zd video stream(s)", program.videoStreams.size());
2757                 if (!program.videoStreams.empty())
2758                 {
2759                         eDebugNoNewLine(" (");
2760                         for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2761                                 i(program.videoStreams.begin());
2762                                 i != program.videoStreams.end(); ++i)
2763                         {
2764                                 if (vpid == -1)
2765                                 {
2766                                         vpid = i->pid;
2767                                         vpidtype = i->type;
2768                                 }
2769                                 if (i != program.videoStreams.begin())
2770                                         eDebugNoNewLine(", ");
2771                                 eDebugNoNewLine("%04x", i->pid);
2772                         }
2773                         eDebugNoNewLine(")");
2774                 }
2775                 eDebugNoNewLine(", and %zd audio stream(s)", program.audioStreams.size());
2776                 if (!program.audioStreams.empty())
2777                 {
2778                         eDebugNoNewLine(" (");
2779                         for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2780                                 i(program.audioStreams.begin());
2781                                 i != program.audioStreams.end(); ++i)
2782                         {
2783                                 if (i != program.audioStreams.begin())
2784                                         eDebugNoNewLine(", ");
2785                                 eDebugNoNewLine("%04x", i->pid);
2786                         }
2787                         eDebugNoNewLine(")");
2788                 }
2789                 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
2790                 pcrpid = program.pcrPid;
2791                 eDebugNoNewLine(", and the text pid is %04x\n", program.textPid);
2792                 tpid = program.textPid;
2793         }
2794
2795         m_have_video_pid = 0;
2796
2797         if (!m_decoder)
2798         {
2799                 h.getDecodeDemux(m_decode_demux);
2800                 if (m_decode_demux)
2801                 {
2802                         m_decode_demux->getMPEGDecoder(m_decoder, m_decoder_index);
2803                         if (m_decoder)
2804                                 m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
2805                 }
2806                 if (m_cue)
2807                         m_cue->setDecodingDemux(m_decode_demux, m_decoder);
2808                 mustPlay = true;
2809         }
2810
2811         m_timeshift_changed = 0;
2812
2813         if (m_decoder)
2814         {
2815                 bool wasSeekable = m_decoder->getVideoProgressive() != -1;
2816                 if (m_dvb_service)
2817                 {
2818                         achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
2819                         ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2820                         pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2821                 }
2822                 else // subservice
2823                 {
2824                         eServiceReferenceDVB ref;
2825                         m_service_handler.getServiceReference(ref);
2826                         eServiceReferenceDVB parent = ref.getParentServiceReference();
2827                         if (!parent)
2828                                 parent = ref;
2829                         if (parent)
2830                         {
2831                                 ePtr<eDVBResourceManager> res_mgr;
2832                                 if (!eDVBResourceManager::getInstance(res_mgr))
2833                                 {
2834                                         ePtr<iDVBChannelList> db;
2835                                         if (!res_mgr->getChannelList(db))
2836                                         {
2837                                                 ePtr<eDVBService> origService;
2838                                                 if (!db->getService(parent, origService))
2839                                                 {
2840                                                         ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
2841                                                         pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
2842                                                 }
2843                                         }
2844                                 }
2845                         }
2846                 }
2847
2848                 setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
2849                 setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
2850
2851                 m_decoder->setVideoPID(vpid, vpidtype);
2852                 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
2853
2854                 selectAudioStream();
2855
2856                 if (!(m_is_pvr || m_is_stream || m_timeshift_active))
2857                         m_decoder->setSyncPCR(pcrpid);
2858                 else
2859                         m_decoder->setSyncPCR(-1);
2860
2861                 if (m_decoder_index == 0)
2862                 {
2863                         m_decoder->setTextPID(tpid);
2864                 }
2865
2866                 if (vpid > 0 && vpid < 0x2000)
2867                         ;
2868                 else
2869                 {
2870                         std::string value;
2871                         bool showRadioBackground = eConfigManager::getConfigBoolValue("config.misc.showradiopic", true);
2872                         std::string radio_pic;
2873                         if (showRadioBackground)
2874                                 radio_pic = eConfigManager::getConfigValue("config.misc.radiopic");
2875                         else
2876                                 radio_pic = eConfigManager::getConfigValue("config.misc.blackradiopic");
2877                         m_decoder->setRadioPic(radio_pic);
2878                 }
2879
2880                 if (mustPlay)
2881                         m_decoder->play();
2882                 else
2883                         m_decoder->set();
2884
2885                 m_decoder->setAudioChannel(achannel);
2886
2887                 if (mustPlay && m_decode_demux && m_decoder_index == 0)
2888                 {
2889                         m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
2890                         m_teletext_parser->connectNewStream(slot(*this, &eDVBServicePlay::newSubtitleStream), m_new_subtitle_stream_connection);
2891                         m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
2892                         m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
2893                         m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
2894                         if (m_timeshift_changed)
2895                         {
2896                                 struct SubtitleTrack track;
2897                                 if (getCachedSubtitle(track) >= 0)
2898                                 {
2899                                         if (track.type == 0) // dvb
2900                                                 m_subtitle_parser->start(track.pid, track.page_number, track.magazine_number);
2901                                         else if (track.type == 1) // ttx
2902                                                 m_teletext_parser->setPageAndMagazine(track.page_number, track.magazine_number, track.language_code.c_str());
2903                                 }
2904                         }
2905                         m_teletext_parser->start(program.textPid);
2906                 }
2907
2908                 /* don't worry about non-existing services, nor pvr services */
2909                 if (m_dvb_service)
2910                 {
2911                         /* (audio pid will be set in selectAudioTrack) */
2912                         if (vpid >= 0)
2913                         {
2914                                 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
2915                                 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
2916                         }
2917                         if (pcrpid >= 0) m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
2918                         if (tpid >= 0) m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
2919                 }
2920                 if (!sendSeekableStateChanged && (m_decoder->getVideoProgressive() != -1) != wasSeekable)
2921                         sendSeekableStateChanged = true;
2922         }
2923
2924         if (sendSeekableStateChanged)
2925                 m_event((iPlayableService*)this, evSeekableStatusChanged);
2926 }
2927
2928 void eDVBServicePlay::loadCuesheet()
2929 {
2930         std::string filename = m_reference.path + ".cuts";
2931
2932         m_cue_entries.clear();
2933
2934         FILE *f = fopen(filename.c_str(), "rb");
2935
2936         if (f)
2937         {
2938                 while (1)
2939                 {
2940                         unsigned long long where;
2941                         unsigned int what;
2942
2943                         if (!fread(&where, sizeof(where), 1, f))
2944                                 break;
2945                         if (!fread(&what, sizeof(what), 1, f))
2946                                 break;
2947
2948