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