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