reserve first two demuxes for decoder
[vuplus_dvbapp] / lib / dvb / dvb.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/base/filepush.h>
3 #include <lib/dvb/idvb.h>
4 #include <lib/dvb/dvb.h>
5 #include <lib/dvb/sec.h>
6
7 #include <errno.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <sys/ioctl.h>
13
14 DEFINE_REF(eDVBRegisteredFrontend);
15 DEFINE_REF(eDVBRegisteredDemux);
16
17 DEFINE_REF(eDVBAllocatedFrontend);
18
19 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
20 {
21         m_fe->inc_use();
22 }
23
24 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
25 {
26         m_fe->dec_use();
27 }
28
29 DEFINE_REF(eDVBAllocatedDemux);
30
31 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
32 {
33         m_demux->m_inuse++;
34 }
35
36 eDVBAllocatedDemux::~eDVBAllocatedDemux()
37 {
38         --m_demux->m_inuse;
39 }
40
41 DEFINE_REF(eDVBResourceManager);
42
43 eDVBResourceManager *eDVBResourceManager::instance;
44
45 RESULT eDVBResourceManager::getInstance(ePtr<eDVBResourceManager> &ptr)
46 {
47         if (instance)
48         {
49                 ptr = instance;
50                 return 0;
51         }
52         return -1;
53 }
54
55 eDVBResourceManager::eDVBResourceManager()
56         :m_releaseCachedChannelTimer(eApp)
57 {
58         avail = 1;
59         busy = 0;
60         m_sec = new eDVBSatelliteEquipmentControl(m_frontend);
61         if (!instance)
62                 instance = this;
63                 
64                 /* search available adapters... */
65
66                 // add linux devices
67         
68         int num_adapter = 0;
69         while (eDVBAdapterLinux::exist(num_adapter))
70         {
71                 addAdapter(new eDVBAdapterLinux(num_adapter));
72                 num_adapter++;
73         }
74         
75         eDebug("found %d adapter, %d frontends and %d demux", 
76                 m_adapter.size(), m_frontend.size(), m_demux.size());
77
78         CONNECT(m_releaseCachedChannelTimer.timeout, eDVBResourceManager::releaseCachedChannel);
79 }
80
81
82 DEFINE_REF(eDVBAdapterLinux);
83 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
84 {
85                 // scan frontends
86         int num_fe = 0;
87         
88         eDebug("scanning for frontends..");
89         while (1)
90         {
91                 struct stat s;
92                 char filename[128];
93 #if HAVE_DVB_API_VERSION < 3
94                 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
95 #else
96                 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
97 #endif
98                 if (stat(filename, &s))
99                         break;
100                 ePtr<eDVBFrontend> fe;
101
102                 int ok = 0;
103                 fe = new eDVBFrontend(m_nr, num_fe, ok);
104                 if (ok)
105                         m_frontend.push_back(fe);
106                 ++num_fe;
107         }
108         
109                 // scan demux
110         int num_demux = 0;
111         while (1)
112         {
113                 struct stat s;
114                 char filename[128];
115 #if HAVE_DVB_API_VERSION < 3
116                 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
117 #else
118                 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
119 #endif
120                 if (stat(filename, &s))
121                         break;
122                 ePtr<eDVBDemux> demux;
123                 
124                 demux = new eDVBDemux(m_nr, num_demux);
125                 m_demux.push_back(demux);
126                         
127                 ++num_demux;
128         }
129 }
130
131 int eDVBAdapterLinux::getNumDemux()
132 {
133         return m_demux.size();
134 }
135
136 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
137 {
138         eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
139         while (nr && (i != m_demux.end()))
140         {
141                 --nr;
142                 ++i;
143         }
144         
145         if (i != m_demux.end())
146                 demux = *i;
147         else
148                 return -1;
149                 
150         return 0;
151 }
152
153 int eDVBAdapterLinux::getNumFrontends()
154 {
155         return m_frontend.size();
156 }
157
158 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
159 {
160         eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
161         while (nr && (i != m_frontend.end()))
162         {
163                 --nr;
164                 ++i;
165         }
166         
167         if (i != m_frontend.end())
168                 fe = *i;
169         else
170                 return -1;
171                 
172         return 0;
173 }
174
175 int eDVBAdapterLinux::exist(int nr)
176 {
177         struct stat s;
178         char filename[128];
179 #if HAVE_DVB_API_VERSION < 3
180         sprintf(filename, "/dev/dvb/card%d", nr);
181 #else
182         sprintf(filename, "/dev/dvb/adapter%d", nr);
183 #endif
184         if (!stat(filename, &s))
185                 return 1;
186         return 0;
187 }
188
189 eDVBResourceManager::~eDVBResourceManager()
190 {
191         if (instance == this)
192                 instance = 0;
193 }
194
195 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
196 {
197         int num_fe = adapter->getNumFrontends();
198         int num_demux = adapter->getNumDemux();
199         
200         m_adapter.push_back(adapter);
201         
202         int i;
203         for (i=0; i<num_demux; ++i)
204         {
205                 ePtr<eDVBDemux> demux;
206                 if (!adapter->getDemux(demux, i))
207                         m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
208         }
209
210         for (i=0; i<num_fe; ++i)
211         {
212                 ePtr<eDVBFrontend> frontend;
213
214                 if (!adapter->getFrontend(frontend, i))
215                 {
216                         frontend->setSEC(m_sec);
217                         m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
218                 }
219         }
220 }
221
222 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
223 {
224         ePtr<eDVBRegisteredFrontend> best;
225         int bestval = 0;
226
227         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
228                 if (!i->m_inuse)
229                 {
230                         int c = i->m_frontend->isCompatibleWith(feparm);
231                         if (c > bestval)
232                         {
233                                 bestval = c;
234                                 best = i;
235                         }
236                 }
237
238         if (best)
239         {
240                 fe = new eDVBAllocatedFrontend(best);
241                 return 0;
242         }
243         
244         fe = 0;
245         
246         return -1;
247 }
248
249 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
250 {
251         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
252                 if ((!nr) && !i->m_inuse)
253                 {
254                         fe = new eDVBAllocatedFrontend(i);
255                         return 0;
256                 }
257         
258         fe = 0;
259         return -1;
260 }
261
262 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
263 {
264                 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
265                    never use the first one unless we need a decoding demux. */
266
267         eDebug("allocate demux");
268         eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
269         
270         if (i == m_demux.end())
271                 return -1;
272                 
273         int n=0;
274                 /* FIXME: hardware demux policy */
275         if (!(cap & iDVBChannel::capDecode))
276         {
277                 if (m_demux.size() > 2)  /* assumed to be true, otherwise we have lost anyway */
278                 {
279                         ++i, ++n;
280                         ++i, ++n;
281                 }
282         }
283         
284         for (; i != m_demux.end(); ++i, ++n)
285                 if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
286                 {
287                         if ((cap & iDVBChannel::capDecode) && (n >= 2))
288                                 continue;
289                         
290                         demux = new eDVBAllocatedDemux(i);
291                         if (fe)
292                                 demux->get().setSourceFrontend(fe->m_frontend->getID());
293                         else
294                                 demux->get().setSourcePVR(0);
295                         return 0;
296                 }
297         eDebug("demux not found");
298         return -1;
299 }
300
301 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
302 {
303         m_list = list;
304         return 0;
305 }
306
307 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
308 {
309         list = m_list;
310         if (list)
311                 return 0;
312         else
313                 return -ENOENT;
314 }
315
316 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
317 {
318                 /* first, check if a channel is already existing. */
319
320         if (m_cached_channel)
321         {
322                 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
323                 if(channelid==cache_chan->getChannelID())
324                 {
325                         eDebug("use cached_channel");
326                         channel = m_cached_channel;
327                         return 0;
328                 }
329                 m_cached_channel_state_changed_conn.disconnect();
330                 m_cached_channel=0;
331                 m_releaseCachedChannelTimer.stop();
332         }
333
334 //      eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
335         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
336         {
337 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
338                 if (i->m_channel_id == channelid)
339                 {
340 //                      eDebug("found shared channel..");
341                         channel = i->m_channel;
342                         return 0;
343                 }
344         }
345         
346         /* no currently available channel is tuned to this channelid. create a new one, if possible. */
347
348         if (!m_list)
349         {
350                 eDebug("no channel list set!");
351                 return -ENOENT;
352         }
353
354         ePtr<iDVBFrontendParameters> feparm;
355         if (m_list->getChannelFrontendData(channelid, feparm))
356         {
357                 eDebug("channel not found!");
358                 return -ENOENT;
359         }
360
361         /* allocate a frontend. */
362         
363         ePtr<eDVBAllocatedFrontend> fe;
364         
365         if (allocateFrontend(fe, feparm))
366                 return errNoFrontend;
367
368         RESULT res;
369         ePtr<eDVBChannel> ch;
370         ch = new eDVBChannel(this, fe);
371
372         res = ch->setChannel(channelid, feparm);
373         if (res)
374         {
375                 channel = 0;
376                 return errChidNotFound;
377         }
378         m_cached_channel = channel = ch;
379         m_cached_channel_state_changed_conn =
380                 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
381
382         return 0;
383 }
384
385 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
386 {
387         int state=0;
388         chan->getState(state);
389         switch (state)
390         {
391                 case iDVBChannel::state_release:
392                 case iDVBChannel::state_ok:
393                 {
394                         eDebug("stop release channel timer");
395                         m_releaseCachedChannelTimer.stop();
396                         break;
397                 }
398                 case iDVBChannel::state_last_instance:
399                 {
400                         eDebug("start release channel timer");
401                         m_releaseCachedChannelTimer.start(3000, true);
402                         break;
403                 }
404                 default: // ignore all other events
405                         break;
406         }
407 }
408
409 void eDVBResourceManager::releaseCachedChannel()
410 {
411         eDebug("release cached channel (timer timeout)");
412         m_cached_channel=0;
413 }
414
415 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
416 {
417         ePtr<eDVBAllocatedFrontend> fe;
418
419         if (m_cached_channel)
420         {
421                 m_cached_channel_state_changed_conn.disconnect();
422                 m_cached_channel=0;
423                 m_releaseCachedChannelTimer.stop();
424         }
425
426         if (allocateFrontendByIndex(fe, frontend_index))
427                 return errNoFrontend;
428         
429         eDVBChannel *ch;
430         ch = new eDVBChannel(this, fe);
431
432         channel = ch;
433         return 0;
434 }
435
436
437 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
438 {
439         ePtr<eDVBAllocatedDemux> demux;
440
441         if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
442         {
443                 m_cached_channel_state_changed_conn.disconnect();
444                 m_cached_channel=0;
445                 m_releaseCachedChannelTimer.stop();
446         }
447
448         eDVBChannel *ch;
449         ch = new eDVBChannel(this, 0);
450
451         channel = ch;
452         return 0;
453 }
454
455 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
456 {
457         m_active_channels.push_back(active_channel(chid, ch));
458         /* emit */ m_channelAdded(ch);
459         return 0;
460 }
461
462 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
463 {
464         int cnt = 0;
465         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
466         {
467                 if (i->m_channel == ch)
468                 {
469                         i = m_active_channels.erase(i);
470                         ++cnt;
471                 } else
472                         ++i;
473         }
474         ASSERT(cnt == 1);
475         if (cnt == 1)
476                 return 0;
477         return -ENOENT;
478 }
479
480 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
481 {
482         connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
483         return 0;
484 }
485
486 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
487 {
488         ePtr<eDVBRegisteredFrontend> best;
489         int bestval = 0;
490
491         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
492                 if (!i->m_inuse)
493                 {
494                         int c = i->m_frontend->isCompatibleWith(feparm);
495                         if (c > bestval)
496                                 bestval = c;
497                 }
498
499         return bestval>0;
500 }
501
502 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
503 {
504         bool ret=true;
505         if (m_cached_channel)
506         {
507                 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
508                 if(channelid==cache_chan->getChannelID())
509                         return ret;
510         }
511
512                 /* first, check if a channel is already existing. */
513 //      eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
514         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
515         {
516 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
517                 if (i->m_channel_id == channelid)
518                 {
519 //                      eDebug("found shared channel..");
520                         return ret;
521                 }
522         }
523
524         int *decremented_cached_channel_fe_usecount=NULL,
525                 *decremented_fe_usecount=NULL;
526
527         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
528         {
529 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
530                 if (i->m_channel_id == ignore)
531                 {
532                         eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
533                         if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1)  // channel only used once..
534                         {
535                                 ePtr<iDVBFrontend> fe;
536                                 if (!i->m_channel->getFrontend(fe))
537                                 {
538                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
539                                         {
540                                                 if ( &(*fe) == &(*ii->m_frontend) )
541                                                 {
542                                                         --ii->m_inuse;
543                                                         decremented_fe_usecount = &ii->m_inuse;
544                                                         if (channel == &(*m_cached_channel))
545                                                                 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
546                                                         break;
547                                                 }
548                                         }
549                                 }
550                         }
551                         break;
552                 }
553         }
554
555         if (!decremented_cached_channel_fe_usecount)
556         {
557                 if (m_cached_channel)
558                 {
559                         eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
560                         if (channel->getUseCount() == 1)
561                         {
562                                 ePtr<iDVBFrontend> fe;
563                                 if (!channel->getFrontend(fe))
564                                 {
565                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
566                                         {
567                                                 if ( &(*fe) == &(*ii->m_frontend) )
568                                                 {
569                                                         --ii->m_inuse;
570                                                         decremented_cached_channel_fe_usecount = &ii->m_inuse;
571                                                         break;
572                                                 }
573                                         }
574                                 }
575                         }
576                 }
577         }
578         else
579                 decremented_cached_channel_fe_usecount=NULL;
580
581         ePtr<iDVBFrontendParameters> feparm;
582
583         if (!m_list)
584         {
585                 eDebug("no channel list set!");
586                 ret = false;
587                 goto error;
588         }
589
590         if (m_list->getChannelFrontendData(channelid, feparm))
591         {
592                 eDebug("channel not found!");
593                 ret = false;
594                 goto error;
595         }
596
597         ret = canAllocateFrontend(feparm);
598
599 error:
600         if (decremented_fe_usecount)
601                 ++(*decremented_fe_usecount);
602         if (decremented_cached_channel_fe_usecount)
603                 ++(*decremented_cached_channel_fe_usecount);
604
605         return ret;
606 }
607
608 DEFINE_REF(eDVBChannel);
609
610 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
611 {
612         m_frontend = frontend;
613
614         m_pvr_thread = 0;
615         
616         m_skipmode_n = m_skipmode_m = 0;
617         
618         if (m_frontend)
619                 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
620 }
621
622 eDVBChannel::~eDVBChannel()
623 {
624         if (m_channel_id)
625                 m_mgr->removeChannel(this);
626
627         stopFile();
628 }
629
630 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
631 {
632         int state, ourstate = 0;
633         
634                 /* if we are already in shutdown, don't change state. */
635         if (m_state == state_release)
636                 return;
637         
638         if (fe->getState(state))
639                 return;
640         
641         if (state == iDVBFrontend::stateLock)
642         {
643                 eDebug("OURSTATE: ok");
644                 ourstate = state_ok;
645         } else if (state == iDVBFrontend::stateTuning)
646         {
647                 eDebug("OURSTATE: tuning");
648                 ourstate = state_tuning;
649         } else if (state == iDVBFrontend::stateLostLock)
650         {
651                         /* on managed channels, we try to retune in order to re-acquire lock. */
652                 if (m_current_frontend_parameters)
653                 {
654                         eDebug("OURSTATE: lost lock, trying to retune");
655                         ourstate = state_tuning;
656                         m_frontend->get().tune(*m_current_frontend_parameters);
657                 } else
658                         /* on unmanaged channels, we don't do this. the client will do this. */
659                 {
660                         eDebug("OURSTATE: lost lock, unavailable now.");
661                         ourstate = state_unavailable;
662                 }
663         } else if (state == iDVBFrontend::stateFailed)
664         {
665                 eDebug("OURSTATE: failed");
666                 ourstate = state_failed;
667         } else
668                 eFatal("state unknown");
669         
670         if (ourstate != m_state)
671         {
672                 m_state = ourstate;
673                 m_stateChanged(this);
674         }
675 }
676
677 void eDVBChannel::pvrEvent(int event)
678 {
679         switch (event)
680         {
681         case eFilePushThread::evtEOF:
682                 eDebug("eDVBChannel: End of file!");
683                 m_event(this, evtEOF);
684                 break;
685         case eFilePushThread::evtUser: /* start */
686                 eDebug("SOF");
687                 m_event(this, evtSOF);
688                 break;
689         }
690 }
691
692 void eDVBChannel::cueSheetEvent(int event)
693 {
694         switch (event)
695         {
696         case eCueSheet::evtSeek:
697                 eDebug("seek.");
698                 flushPVR(m_cue->m_decoding_demux);
699                 break;
700         case eCueSheet::evtSkipmode:
701         {
702                 {
703                         eSingleLocker l(m_cue->m_lock);
704                         m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
705                         if (m_cue->m_skipmode_ratio)
706                         {
707                                 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
708                                 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
709                                                 /* i agree that this might look a bit like black magic. */
710                                 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
711                                 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
712                                 
713                                 if (m_cue->m_skipmode_ratio < 0)
714                                         m_skipmode_m -= m_skipmode_n;
715         
716                                 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
717                                 
718                                 if (abs(m_skipmode_m) < abs(m_skipmode_n))
719                                 {
720                                         eWarning("something is wrong with this calculation");
721                                         m_skipmode_n = m_skipmode_m = 0;
722                                 }
723                                 
724                         } else
725                         {
726                                 eDebug("skipmode ratio is 0, normal play");
727                                 m_skipmode_n = m_skipmode_m = 0;
728                         }
729                 }
730                 flushPVR(m_cue->m_decoding_demux);
731                 break;
732         }
733         case eCueSheet::evtSpanChanged:
734         {
735                 m_source_span.clear();
736                 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
737                 {
738                         off_t offset_in, offset_out;
739                         pts_t pts_in = i->first, pts_out = i->second;
740                         if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
741                         {
742                                 eDebug("span translation failed.\n");
743                                 continue;
744                         }
745                         eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
746                         m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
747                 }
748                 break;
749         }
750         }
751 }
752
753         /* remember, this gets called from another thread. */
754 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
755 {
756         unsigned int max = 10*1024*1024;
757         
758         if (!m_cue)
759         {
760                 eDebug("no cue sheet. forcing normal play");
761                 start = current_offset;
762                 size = max;
763                 return;
764         }
765
766         eSingleLocker l(m_cue->m_lock);
767         
768         if (!m_cue->m_decoding_demux)
769         {
770                 start = current_offset;
771                 size = max;
772                 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
773                 return;
774         }
775         
776         if (m_skipmode_n)
777         {
778                 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
779                 max = m_skipmode_n;
780         }
781         
782         eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
783         
784         current_offset += m_skipmode_m;
785         
786         while (!m_cue->m_seek_requests.empty())
787         {
788                 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
789                 m_cue->m_seek_requests.pop_front();
790                 int relative = seek.first;
791                 pts_t pts = seek.second;
792
793                 pts_t now = 0;
794                 if (relative)
795                 {
796                         if (!m_cue->m_decoder)
797                         {
798                                 eDebug("no decoder - can't seek relative");
799                                 continue;
800                         }
801                         if (m_cue->m_decoder->getPTS(0, now))
802                         {
803                                 eDebug("decoder getPTS failed, can't seek relative");
804                                 continue;
805                         }
806                         if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
807                         {
808                                 eDebug("seekTo: getCurrentPosition failed!");
809                                 continue;
810                         }
811                 }
812                 
813                 if (relative == 1) /* pts relative */
814                 {
815                         pts += now;
816                         if (pts < 0)
817                                 pts = 0;
818                 }
819
820                 if (relative != 2)
821                         if (pts < 0)
822                                 pts = 0;
823                 
824                 if (relative == 2) /* AP relative */
825                 {
826                         eDebug("AP relative seeking: %lld, at %lld", pts, now);
827                         pts_t nextap;
828                         if (m_tstools.getNextAccessPoint(nextap, now, pts))
829                         {
830                                 pts = now;
831                                 eDebug("AP relative seeking failed!");
832                         } else
833                         {
834                                 eDebug("next ap is %llx\n", pts);
835                                 pts = nextap;
836                         }
837                 }
838                 
839                 off_t offset = 0;
840                 if (m_tstools.getOffset(offset, pts))
841                         continue;
842
843                 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
844                 current_offset = offset;
845         }
846         
847         for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
848         {
849                 if ((current_offset >= i->first) && (current_offset < i->second))
850                 {
851                         start = current_offset;
852                                 /* max can not exceed max(size_t). i->second - current_offset, however, can. */
853                         if ((i->second - current_offset) > max)
854                                 size = max;
855                         else
856                                 size = i->second - current_offset;
857                         eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
858                         return;
859                 }
860                 if (current_offset < i->first)
861                 {
862                                 /* ok, our current offset is in an 'out' zone. */
863                         if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
864                         {
865                                         /* in normal playback, just start at the next zone. */
866                                 start = i->first;
867                                 
868                                         /* size is not 64bit! */
869                                 if ((i->second - i->first) > max)
870                                         size = max;
871                                 else
872                                         size = i->second - i->first;
873
874                                 eDebug("skip");
875                                 if (m_skipmode_m < 0)
876                                 {
877                                         eDebug("reached SOF");
878                                                 /* reached SOF */
879                                         m_skipmode_m = 0;
880                                         m_pvr_thread->sendEvent(eFilePushThread::evtUser);
881                                 }
882                         } else
883                         {
884                                         /* when skipping reverse, however, choose the zone before. */
885                                 --i;
886                                 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
887                                 size_t len;
888                                 
889                                 if ((i->second - i->first) > max)
890                                         len = max;
891                                 else
892                                         len = i->second - i->first;
893
894                                 start = i->second - len;
895                                 eDebug("skipping to %llx, %d", start, len);
896                         }
897                         return;
898                 }
899         }
900         
901         if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
902         {
903                 eDebug("reached SOF");
904                 m_skipmode_m = 0;
905                 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
906         }
907         
908         start = current_offset;
909         size = max;
910         eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
911         return;
912 }
913
914 void eDVBChannel::AddUse()
915 {
916         if (++m_use_count > 1 && m_state == state_last_instance)
917         {
918                 m_state = state_ok;
919                 m_stateChanged(this);
920         }
921 }
922
923 void eDVBChannel::ReleaseUse()
924 {
925         if (!--m_use_count)
926         {
927                 m_state = state_release;
928                 m_stateChanged(this);
929         }
930         else if (m_use_count == 1)
931         {
932                 m_state = state_last_instance;
933                 m_stateChanged(this);
934         }
935 }
936
937 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
938 {
939         if (m_channel_id)
940                 m_mgr->removeChannel(this);
941                 
942         if (!channelid)
943                 return 0;
944
945         if (!m_frontend)
946         {
947                 eDebug("no frontend to tune!");
948                 return -ENODEV;
949         }
950         
951         m_channel_id = channelid;
952         m_mgr->addChannel(channelid, this);
953         m_state = state_tuning;
954                         /* if tuning fails, shutdown the channel immediately. */
955         int res;
956         res = m_frontend->get().tune(*feparm);
957         m_current_frontend_parameters = feparm;
958         
959         if (res)
960         {
961                 m_state = state_release;
962                 m_stateChanged(this);
963                 return res;
964         }
965         
966         return 0;
967 }
968
969 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
970 {
971         connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
972         return 0;
973 }
974
975 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
976 {
977         connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
978         return 0;
979 }
980
981 RESULT eDVBChannel::getState(int &state)
982 {
983         state = m_state;
984         return 0;
985 }
986
987 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
988 {
989         return -1;
990 }
991
992 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
993 {
994         ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
995         
996         if (!our_demux)
997         {
998                 demux = 0;
999                 
1000                 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1001                         return -1;
1002         }
1003         
1004         demux = *our_demux;
1005                 /* don't hold a reference to the decoding demux, we don't need it. */
1006                 
1007                 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1008                    the refcount is lost. thus, decoding demuxes are never allocated. 
1009                    
1010                    this poses a big problem for PiP. */
1011         if (cap & capDecode)
1012                 our_demux = 0;
1013         return 0;
1014 }
1015
1016 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1017 {
1018         frontend = 0;
1019         if (!m_frontend)
1020                 return -ENODEV;
1021         frontend = &m_frontend->get();
1022         if (frontend)
1023                 return 0;
1024         return -ENODEV;
1025 }
1026
1027 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &param)
1028 {
1029         param = m_current_frontend_parameters;
1030         return 0;
1031 }
1032
1033 RESULT eDVBChannel::playFile(const char *file)
1034 {
1035         ASSERT(!m_frontend);
1036         if (m_pvr_thread)
1037         {
1038                 m_pvr_thread->stop();
1039                 delete m_pvr_thread;
1040                 m_pvr_thread = 0;
1041         }
1042         
1043         m_tstools.openFile(file);
1044         
1045                 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1046                    THEN DO A REAL FIX HERE! */
1047         
1048                 /* (this codepath needs to be improved anyway.) */
1049 #if HAVE_DVB_API_VERSION < 3
1050         m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1051 #else
1052         m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1053 #endif
1054         if (m_pvr_fd_dst < 0)
1055         {
1056                 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1057                 return -ENODEV;
1058         }
1059
1060         m_pvr_thread = new eFilePushThread();
1061         m_pvr_thread->enablePVRCommit(1);
1062         m_pvr_thread->setScatterGather(this);
1063
1064         if (m_pvr_thread->start(file, m_pvr_fd_dst))
1065         {
1066                 delete m_pvr_thread;
1067                 m_pvr_thread = 0;
1068                 eDebug("can't open PVR file %s (%m)", file);
1069                 return -ENOENT;
1070         }
1071         CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1072
1073         m_state = state_ok;
1074         m_stateChanged(this);
1075
1076         return 0;
1077 }
1078
1079 void eDVBChannel::stopFile()
1080 {
1081         if (m_pvr_thread)
1082         {
1083                 m_pvr_thread->stop();
1084                 ::close(m_pvr_fd_dst);
1085                 delete m_pvr_thread;
1086                 m_pvr_thread = 0;
1087         }
1088 }
1089
1090 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1091 {
1092         m_conn_cueSheetEvent = 0;
1093         m_cue = cuesheet;
1094         if (m_cue)
1095                 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1096 }
1097
1098 RESULT eDVBChannel::getLength(pts_t &len)
1099 {
1100         return m_tstools.calcLen(len);
1101 }
1102
1103 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1104 {
1105         if (!decoding_demux)
1106                 return -1;
1107         
1108         pts_t now;
1109         
1110         int r;
1111         
1112         if (mode == 0) /* demux */
1113         {
1114                 r = decoding_demux->getSTC(now, 0);
1115                 if (r)
1116                 {
1117                         eDebug("demux getSTC failed");
1118                         return -1;
1119                 }
1120         } else
1121                 now = pos; /* fixup supplied */
1122         
1123         off_t off = 0; /* TODO: fixme */
1124         r = m_tstools.fixupPTS(off, now);
1125         if (r)
1126         {
1127                 eDebug("fixup PTS failed");
1128                 return -1;
1129         }
1130         
1131         pos = now;
1132         
1133         return 0;
1134 }
1135
1136 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1137 {
1138                         /* when seeking, we have to ensure that all buffers are flushed.
1139                            there are basically 3 buffers:
1140                            a.) the filepush's internal buffer
1141                            b.) the PVR buffer (before demux)
1142                            c.) the ratebuffer (after demux)
1143                            
1144                            it's important to clear them in the correct order, otherwise
1145                            the ratebuffer (for example) would immediately refill from
1146                            the not-yet-flushed PVR buffer.
1147                         */
1148
1149         m_pvr_thread->pause();
1150                 /* flush internal filepush buffer */
1151         m_pvr_thread->flush();
1152                 /* HACK: flush PVR buffer */
1153         ::ioctl(m_pvr_fd_dst, 0);
1154         
1155                 /* flush ratebuffers (video, audio) */
1156         if (decoding_demux)
1157                 decoding_demux->flush();
1158
1159                 /* demux will also flush all decoder.. */
1160                 /* resume will re-query the SG */
1161         m_pvr_thread->resume();
1162 }
1163
1164 DEFINE_REF(eCueSheet);
1165
1166 eCueSheet::eCueSheet()
1167 {
1168         m_skipmode_ratio = 0;
1169 }
1170
1171 void eCueSheet::seekTo(int relative, const pts_t &pts)
1172 {
1173         {
1174                 eSingleLock l(m_lock);
1175                 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1176         }
1177         m_event(evtSeek);
1178 }
1179         
1180 void eCueSheet::clear()
1181 {
1182         eSingleLock l(m_lock);
1183         m_spans.clear();
1184 }
1185
1186 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1187 {
1188         {
1189                 eSingleLock l(m_lock);
1190                 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1191         }
1192 }
1193
1194 void eCueSheet::commitSpans()
1195 {
1196         m_event(evtSpanChanged);
1197 }
1198
1199 void eCueSheet::setSkipmode(const pts_t &ratio)
1200 {
1201         {
1202                 eSingleLock l(m_lock);
1203                 m_skipmode_ratio = ratio;
1204         }
1205         m_event(evtSkipmode);
1206 }
1207
1208 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1209 {
1210         m_decoding_demux = demux;
1211         m_decoder = decoder;
1212 }
1213
1214 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1215 {
1216         connection = new eConnection(this, m_event.connect(event));
1217         return 0;
1218 }