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