show "Current Transponder" entry in ChannelSelection -> Satellites
[enigma2.git] / lib / dvb / decoder.cpp
1 #include <lib/base/ebase.h>
2 #include <lib/base/eerror.h>
3 #include <lib/dvb/decoder.h>
4 #if HAVE_DVB_API_VERSION < 3 
5 #define audioStatus audio_status
6 #define videoStatus video_status
7 #define pesType pes_type
8 #define playState play_state
9 #define audioStreamSource_t audio_stream_source_t
10 #define videoStreamSource_t video_stream_source_t
11 #define streamSource stream_source
12 #define dmxPesFilterParams dmx_pes_filter_params
13 #define DMX_PES_VIDEO0 DMX_PES_VIDEO
14 #define DMX_PES_AUDIO0 DMX_PES_AUDIO
15 #define DMX_PES_VIDEO1 DMX_PES_VIDEO
16 #define DMX_PES_AUDIO1 DMX_PES_AUDIO
17 #include <ost/dmx.h>
18 #include <ost/video.h>
19 #include <ost/audio.h>
20 #else
21 #include <linux/dvb/audio.h>
22 #include <linux/dvb/video.h>
23 #include <linux/dvb/dmx.h>
24 #endif
25
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <sys/ioctl.h>
29 #include <errno.h>
30
31         /* these are quite new... */
32 #ifndef AUDIO_GET_PTS
33 #define AUDIO_GET_PTS              _IOR('o', 19, __u64)
34 #define VIDEO_GET_PTS              _IOR('o', 57, __u64)
35 #endif
36
37 DEFINE_REF(eDVBAudio);
38
39 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev)
40         :m_demux(demux), m_dev(dev), m_is_freezed(0)
41 {
42         char filename[128];
43 #if HAVE_DVB_API_VERSION < 3
44         sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);
45 #else
46         sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
47 #endif
48         m_fd = ::open(filename, O_RDWR);
49         if (m_fd < 0)
50                 eWarning("%s: %m", filename);
51 #if HAVE_DVB_API_VERSION < 3
52         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
53 #else
54         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
55 #endif
56         m_fd_demux = ::open(filename, O_RDWR);
57         if (m_fd_demux < 0)
58                 eWarning("%s: %m", filename);
59 }
60
61 #if HAVE_DVB_API_VERSION < 3
62 int eDVBAudio::setPid(int pid, int type)
63 {
64         if ((m_fd < 0) || (m_fd_demux < 0))
65                 return -1;
66
67         int bypass = 0;
68
69         switch (type)
70         {
71         case aMPEG:
72                 bypass = 1;
73                 break;
74         case aAC3:
75                 bypass = 0;
76                 break;
77                 /*
78         case aDTS:
79                 bypass = 2;
80                 break;
81                 */
82         }
83
84         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
85                 eDebug("failed (%m)");
86
87         dmx_pes_filter_params pes;
88
89         pes.pid      = pid;
90         pes.input    = DMX_IN_FRONTEND;
91         pes.output   = DMX_OUT_DECODER;
92         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
93         pes.flags    = 0;
94         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid);
95         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
96         {
97                 eDebug("failed (%m)");
98                 return -errno;
99         }
100         eDebug("ok");
101
102         return 0;
103 }
104
105 int eDVBAudio::startPid()
106 {
107         eDebugNoNewLine("DEMUX_START - audio - ");
108         if (::ioctl(m_fd_demux, DMX_START) < 0)
109         {
110                 eDebug("failed (%m)");
111                 return -errno;
112         }
113         eDebug("ok");
114         return 0;
115 }
116
117 int eDVBAudio::start()
118 {
119         eDebugNoNewLine("AUDIO_PLAY - ");
120         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
121         {
122                 eDebug("failed (%m)");
123                 return -errno;
124         }
125         eDebug("ok");
126         return 0;
127 }
128
129 int eDVBAudio::stopPid()
130 {
131         eDebugNoNewLine("DEMUX_STOP - audio - ");
132         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
133         {
134                 eDebug("failed (%m)");
135                 return -errno;
136         }
137         eDebug("ok");
138         return 0;
139 }
140
141 int eDVBAudio::setAVSync(int val)
142 {
143         eDebugNoNewLine("AUDIO_SET_AV_SYNC - ");
144         if (::ioctl(m_fd, AUDIO_SET_AV_SYNC, val) < 0)
145         {
146                 eDebug("failed (%m)");
147                 return -errno;
148         }
149         eDebug("ok");
150         return 0;
151 }
152 #else
153 int eDVBAudio::startPid(int pid, int type)
154 {
155         if ((m_fd < 0) || (m_fd_demux < 0))
156                 return -1;
157         dmx_pes_filter_params pes;
158
159         pes.pid      = pid;
160         pes.input    = DMX_IN_FRONTEND;
161         pes.output   = DMX_OUT_DECODER;
162         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
163         pes.flags    = 0;
164         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid);
165         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
166         {
167                 eDebug("failed (%m)");
168                 return -errno;
169         }
170         eDebug("ok");
171         eDebugNoNewLine("DEMUX_START - audio - ");
172         if (::ioctl(m_fd_demux, DMX_START) < 0)
173         {
174                 eDebug("failed (%m)");
175                 return -errno;
176         }
177         eDebug("ok");
178         int bypass = 0;
179
180         switch (type)
181         {
182         case aMPEG:
183                 bypass = 1;
184                 break;
185         case aAC3:
186                 bypass = 0;
187                 break;
188                 /*
189         case aDTS:
190                 bypass = 2;
191                 break;
192                 */
193         }
194
195         eDebugNoNewLine("AUDIO_SET_BYPASS - ");
196         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
197                 eDebug("failed (%m)");
198         else
199                 eDebug("ok");
200         freeze();
201
202         eDebugNoNewLine("AUDIO_PLAY - ");
203         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
204                 eDebug("failed (%m)");
205         else
206                 eDebug("ok");
207         return 0;
208 }
209 #endif
210
211 void eDVBAudio::stop()
212 {
213 #if HAVE_DVB_API_VERSION > 2
214         flush();
215 #endif
216         eDebugNoNewLine("AUDIO_STOP - ");
217         if (::ioctl(m_fd, AUDIO_STOP) < 0)
218                 eDebug("failed (%m)");
219         else
220                 eDebug("ok");
221 #if HAVE_DVB_API_VERSION > 2
222         eDebugNoNewLine("DEMUX_STOP - audio - ");
223         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
224                 eDebug("failed (%m)");
225         else
226                 eDebug("ok");
227 #endif
228 }
229
230 void eDVBAudio::flush()
231 {
232         eDebugNoNewLine("AUDIO_CLEAR_BUFFER - ");
233         if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
234                 eDebug("failed (%m)");
235         else
236                 eDebug("ok");
237 }
238
239 void eDVBAudio::freeze()
240 {
241         if (!m_is_freezed)
242         {
243                 eDebugNoNewLine("AUDIO_PAUSE - ");
244                 if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
245                         eDebug("failed (%m)");
246                 else
247                         eDebug("ok");
248                 m_is_freezed=1;
249         }
250 }
251
252 void eDVBAudio::unfreeze()
253 {
254         if (m_is_freezed)
255         {
256                 eDebugNoNewLine("AUDIO_CONTINUE - ");
257                 if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
258                         eDebug("failed (%m)");
259                 else
260                         eDebug("ok");
261                 m_is_freezed=0;
262         }
263 }
264
265 void eDVBAudio::setChannel(int channel)
266 {
267         int val = AUDIO_STEREO;
268         switch (channel)
269         {
270         case aMonoLeft: val = AUDIO_MONO_LEFT; break;
271         case aMonoRight: val = AUDIO_MONO_RIGHT; break;
272         default: break;
273         }
274         eDebugNoNewLine("AUDIO_CHANNEL_SELECT(%d) - ", val);
275         if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
276                 eDebug("failed (%m)");
277         else
278                 eDebug("ok");
279 }
280
281 int eDVBAudio::getPTS(pts_t &now)
282 {
283         eDebugNoNewLine("AUDIO_GET_PTS - ");
284         if (::ioctl(m_fd, AUDIO_GET_PTS, &now) < 0)
285                 eDebug("failed (%m)");
286         else
287                 eDebug("ok");
288         return 0;
289 }
290
291 eDVBAudio::~eDVBAudio()
292 {
293         unfreeze();
294         if (m_fd >= 0)
295                 ::close(m_fd);
296         if (m_fd_demux >= 0)
297                 ::close(m_fd_demux);
298 }
299
300 DEFINE_REF(eDVBVideo);
301
302 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev)
303         :m_demux(demux), m_dev(dev), m_is_slow_motion(0), m_is_fast_forward(0), m_is_freezed(0)
304 {
305         char filename[128];
306 #if HAVE_DVB_API_VERSION < 3
307         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
308         m_fd_video = ::open("/dev/video", O_RDWR);
309         if (m_fd_video < 0)
310                 eWarning("/dev/video: %m");
311 #else
312         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
313 #endif
314         m_fd = ::open(filename, O_RDWR);
315         if (m_fd < 0)
316                 eWarning("%s: %m", filename);
317         else
318         {
319                 m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Priority);
320                 CONNECT(m_sn->activated, eDVBVideo::video_event);
321         }
322         eDebug("Video Device: %s", filename);
323 #if HAVE_DVB_API_VERSION < 3
324         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
325 #else
326         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
327 #endif
328         m_fd_demux = ::open(filename, O_RDWR);
329         if (m_fd_demux < 0)
330                 eWarning("%s: %m", filename);
331         eDebug("demux device: %s", filename);
332 }
333
334 // not finally values i think.. !!
335 #define VIDEO_STREAMTYPE_MPEG2 0
336 #define VIDEO_STREAMTYPE_MPEG4_H264 1
337
338 #if HAVE_DVB_API_VERSION < 3
339 int eDVBVideo::setPid(int pid)
340 {
341         if ((m_fd < 0) || (m_fd_demux < 0))
342                 return -1;
343         dmx_pes_filter_params pes;
344
345         pes.pid      = pid;
346         pes.input    = DMX_IN_FRONTEND;
347         pes.output   = DMX_OUT_DECODER;
348         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
349         pes.flags    = 0;
350         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid);
351         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
352         {
353                 eDebug("failed (%m)");
354                 return -errno;
355         }
356         eDebug("ok");
357         return 0;
358 }
359
360 int eDVBVideo::startPid()
361 {
362         eDebugNoNewLine("DEMUX_START - video - ");
363         if (::ioctl(m_fd_demux, DMX_START) < 0)
364         {
365                 eDebug("failed (%m)");
366                 return -errno;
367         }
368         eDebug("ok");
369         return 0;
370 }
371
372 int eDVBVideo::start()
373 {
374         eDebugNoNewLine("VIDEO_PLAY - ");
375         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
376         {
377                 eDebug("failed (%m)");
378                 return -errno;
379         }
380         eDebug("ok");
381         return 0;
382 }
383
384 int eDVBVideo::stopPid()
385 {
386         eDebugNoNewLine("DEMUX_STOP - video - ");
387         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
388         {
389                 eDebug("failed (%m)");
390                 return -errno;
391         }
392         eDebug("ok");
393         return 0;
394 }
395 #else
396 int eDVBVideo::startPid(int pid, int type)
397 {
398         if ((m_fd < 0) || (m_fd_demux < 0))
399                 return -1;
400         dmx_pes_filter_params pes;
401
402         eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ",type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2);
403         if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE,
404                 type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2) < 0)
405                 eDebug("failed (%m)");
406         else
407                 eDebug("ok");
408
409         pes.pid      = pid;
410         pes.input    = DMX_IN_FRONTEND;
411         pes.output   = DMX_OUT_DECODER;
412         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
413         pes.flags    = 0;
414         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid);
415         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
416         {
417                 eDebug("failed (%m)");
418                 return -errno;
419         }
420         eDebug("ok");
421         eDebugNoNewLine("DEMUX_START - video - ");
422         if (::ioctl(m_fd_demux, DMX_START) < 0)
423         {
424                 eDebug("failed (%m)");
425                 return -errno;
426         }
427         eDebug("ok");
428         freeze();
429         eDebugNoNewLine("VIDEO_PLAY - ");
430         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
431                 eDebug("failed (%m)");
432         else
433                 eDebug("ok");
434         return 0;
435 }
436 #endif
437
438 void eDVBVideo::stop()
439 {
440 #if HAVE_DVB_API_VERSION > 2
441         eDebugNoNewLine("DEMUX_STOP - video - ");
442         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
443                 eDebug("failed (%m)");
444         else
445                 eDebug("ok");
446 #endif
447         eDebugNoNewLine("VIDEO_STOP - ");
448         if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
449                 eDebug("failed (%m)");
450         else
451                 eDebug("ok");
452 }
453
454 void eDVBVideo::flush()
455 {
456         eDebugNoNewLine("VIDEO_CLEAR_BUFFER - ");
457         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
458                 eDebug("failed (%m)");
459         else
460                 eDebug("ok");
461 }
462
463 void eDVBVideo::freeze()
464 {
465         if (!m_is_freezed)
466         {
467                 eDebugNoNewLine("VIDEO_FREEZE - ");
468                 if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
469                         eDebug("failed (%m)");
470                 else
471                         eDebug("ok");
472                 m_is_freezed=1;
473         }
474 }
475
476 void eDVBVideo::unfreeze()
477 {
478         if (m_is_freezed)
479         {
480                 eDebugNoNewLine("VIDEO_CONTINUE - ");
481                 if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
482                         eDebug("failed (%m)");
483                 else
484                         eDebug("ok");
485                 m_is_freezed=0;
486         }
487 }
488
489 int eDVBVideo::setSlowMotion(int repeat)
490 {
491         eDebugNoNewLine("VIDEO_SLOWMOTION - ");
492         m_is_slow_motion = repeat;
493         int ret = ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
494         if (ret < 0)
495                 eDebug("failed(%m)");
496         else
497                 eDebug("ok");
498         return ret;
499 }
500
501 int eDVBVideo::setFastForward(int skip)
502 {
503         eDebugNoNewLine("VIDEO_FAST_FORWARD - ");
504         m_is_fast_forward = skip;
505         int ret = ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
506         if (ret < 0)
507                 eDebug("failed(%m)");
508         else
509                 eDebug("ok");
510         return ret;
511 }
512
513 int eDVBVideo::getPTS(pts_t &now)
514 {
515 #if HAVE_DVB_API_VERSION < 3
516         #define VIDEO_GET_PTS_OLD           _IOR('o', 1, unsigned int*)
517         unsigned int pts;
518         int ret = ::ioctl(m_fd_video, VIDEO_GET_PTS_OLD, &pts);
519         now = pts;
520         now *= 2;
521 #else
522         int ret = ::ioctl(m_fd, VIDEO_GET_PTS, &now);
523 #endif
524         if (ret < 0)
525                 eDebug("VIDEO_GET_PTS failed(%m)");
526         return ret;
527 }
528
529 eDVBVideo::~eDVBVideo()
530 {
531         if (m_sn)
532                 delete m_sn;
533         if (m_is_slow_motion)
534                 setSlowMotion(0);
535         if (m_is_fast_forward)
536                 setFastForward(0);
537         unfreeze();
538         if (m_fd >= 0)
539                 ::close(m_fd);
540         if (m_fd_demux >= 0)
541                 ::close(m_fd_demux);
542 #if HAVE_DVB_API_VERSION < 3
543         if (m_fd_video >= 0)
544                 ::close(m_fd_video);
545 #endif
546 }
547
548 void eDVBVideo::video_event(int)
549 {
550 #if HAVE_DVB_API_VERSION >= 3
551         struct video_event evt;
552         eDebugNoNewLine("VIDEO_GET_EVENT - ");
553         if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
554                 eDebug("failed (%m)");
555         else
556         {
557                 eDebug("ok");
558                 if (evt.type == VIDEO_EVENT_SIZE_CHANGED)
559                 {
560                         struct iTSMPEGDecoder::videoEvent event;
561                         event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
562                         event.aspect = evt.u.size.aspect_ratio;
563                         event.height = evt.u.size.h;
564                         event.width = evt.u.size.w;
565                         /* emit */ m_event(event);
566                 }
567                 else
568                         eDebug("unhandled DVBAPI Video Event %d", evt.type);
569         }
570 #else
571 #warning "FIXMEE!! Video Events not implemented for old api"
572 #endif
573 }
574
575 RESULT eDVBVideo::connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEvent> &event, ePtr<eConnection> &conn)
576 {
577         conn = new eConnection(this, m_event.connect(event));
578         return 0;
579 }
580
581 DEFINE_REF(eDVBPCR);
582
583 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
584 {
585         char filename[128];
586 #if HAVE_DVB_API_VERSION < 3
587         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
588 #else
589         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
590 #endif
591         m_fd_demux = ::open(filename, O_RDWR);
592         if (m_fd_demux < 0)
593                 eWarning("%s: %m", filename);
594 }
595
596 #if HAVE_DVB_API_VERSION < 3
597 int eDVBPCR::setPid(int pid)
598 {
599         if (m_fd_demux < 0)
600                 return -1;
601         dmx_pes_filter_params pes;
602
603         pes.pid      = pid;
604         pes.input    = DMX_IN_FRONTEND;
605         pes.output   = DMX_OUT_DECODER;
606         pes.pes_type = DMX_PES_PCR;
607         pes.flags    = 0;
608
609         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
610         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
611         {
612                 eDebug("failed (%m)");
613                 return -errno;
614         }
615         eDebug("ok");
616         return 0;
617 }
618
619 int eDVBPCR::startPid()
620 {
621         if (m_fd_demux < 0)
622                 return -1;
623         eDebugNoNewLine("DEMUX_START - pcr - ");
624         if (::ioctl(m_fd_demux, DMX_START) < 0)
625         {
626                 eDebug("failed (%m)");
627                 return -errno;
628         }
629         eDebug("ok");
630         return 0;
631 }
632 #else
633 int eDVBPCR::startPid(int pid)
634 {
635         if (m_fd_demux < 0)
636                 return -1;
637         dmx_pes_filter_params pes;
638
639         pes.pid      = pid;
640         pes.input    = DMX_IN_FRONTEND;
641         pes.output   = DMX_OUT_DECODER;
642         pes.pes_type = DMX_PES_PCR;
643         pes.flags    = 0;
644         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
645         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
646         {
647                 eDebug("failed (%m)");
648                 return -errno;
649         }
650         eDebug("ok");
651         eDebugNoNewLine("DEMUX_START - pcr - ");
652         if (::ioctl(m_fd_demux, DMX_START) < 0)
653         {
654                 eDebug("failed (%m)");
655                 return -errno;
656         }
657         eDebug("ok");
658         return 0;
659 }
660 #endif
661
662 void eDVBPCR::stop()
663 {
664         eDebugNoNewLine("DEMUX_STOP - pcr - ");
665         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
666                 eDebug("failed(%m)");
667         else
668                 eDebug("ok");
669 }
670
671 eDVBPCR::~eDVBPCR()
672 {
673         if (m_fd_demux >= 0)
674                 ::close(m_fd_demux);
675 }
676
677 DEFINE_REF(eDVBTText);
678
679 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
680 {
681         char filename[128];
682 #if HAVE_DVB_API_VERSION < 3
683         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
684 #else
685         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
686 #endif
687         m_fd_demux = ::open(filename, O_RDWR);
688         if (m_fd_demux < 0)
689                 eWarning("%s: %m", filename);
690 }
691
692 int eDVBTText::startPid(int pid)
693 {
694         if (m_fd_demux < 0)
695                 return -1;
696         dmx_pes_filter_params pes;
697
698         pes.pid      = pid;
699         pes.input    = DMX_IN_FRONTEND;
700         pes.output   = DMX_OUT_DECODER;
701         pes.pes_type = DMX_PES_TELETEXT;
702         pes.flags    = 0;
703
704         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - ttx - ", pid);
705         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
706         {
707                 eDebug("failed(%m)");
708                 return -errno;
709         }
710         eDebug("ok");
711         eDebugNoNewLine("DEMUX_START - pcr - ");
712         if (::ioctl(m_fd_demux, DMX_START) < 0)
713         {
714                 eDebug("failed(%m)");
715                 return -errno;
716         }
717         eDebug("ok");
718         return 0;
719 }
720
721 void eDVBTText::stop()
722 {
723         eDebugNoNewLine("DEMUX_STOP - ttx - ");
724         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
725                 eDebug("failed(%m)");
726         else
727                 eDebug("ok");
728 }
729
730 eDVBTText::~eDVBTText()
731 {
732         if (m_fd_demux >= 0)
733                 ::close(m_fd_demux);
734 }
735
736 DEFINE_REF(eTSMPEGDecoder);
737
738 int eTSMPEGDecoder::setState()
739 {
740         int res = 0;
741
742         int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
743         int nott = noaudio; /* actually same conditions */
744
745         if ((noaudio && m_audio) || (!m_audio && !noaudio))
746                 m_changed |= changeAudio;
747
748         if ((nott && m_text) || (!m_text && !nott))
749                 m_changed |= changeText;
750
751         bool changed = !!m_changed;
752 #if HAVE_DVB_API_VERSION < 3
753         bool checkAVSync = m_changed & (changeAudio|changeVideo|changePCR);
754         if (m_changed & changeAudio && m_audio)
755                 m_audio->stopPid();
756         if (m_changed & changeVideo && m_video)
757                 m_video->stopPid();
758         if (m_changed & changePCR && m_pcr)
759         {
760                 m_pcr->stop();
761                 m_pcr=0;
762                 if (!(m_pcrpid >= 0 && m_pcrpid < 0x1ff))
763                         m_changed &= ~changePCR;
764         }
765         if (m_changed & changeAudio && m_audio)
766         {
767                 m_audio->stop();
768                 m_audio=0;
769                 if (!(m_apid >= 0 && m_apid < 0x1ff))
770                         m_changed &= ~changeAudio;
771         }
772         if (m_changed & changeVideo && m_video)
773         {
774                 m_video->stop();
775                 m_video=0;
776                 m_video_event_conn=0;
777                 if (!(m_vpid >= 0 && m_vpid < 0x1ff))
778                         m_changed &= ~changeVideo;
779         }
780         if (m_changed & changeVideo)
781         {
782                 m_video = new eDVBVideo(m_demux, m_decoder);
783                 m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
784                 if (m_video->setPid(m_vpid))
785                         res -1;
786         }
787         if (m_changed & changePCR)
788         {
789                 m_pcr = new eDVBPCR(m_demux);
790                 if (m_pcr->setPid(m_pcrpid))
791                         res = -1;
792         }
793         if (m_changed & changeAudio)
794         {
795                 m_audio = new eDVBAudio(m_demux, m_decoder);
796                 if (m_audio->setPid(m_apid, m_atype))
797                         res = -1;
798         }
799         if (m_changed & changePCR)
800         {
801                 if (m_pcr->startPid())
802                         res = -1;
803                 m_changed &= ~changePCR;
804         }
805         else if (checkAVSync && m_audio && m_video)
806         {
807                 if (m_audio->setAVSync(1))
808                         res = -1;
809         }
810         if (m_changed & changeVideo)
811         {
812                 if (m_video->startPid() || m_video->start())
813                         res = -1;
814                 m_changed &= ~changeVideo;
815         }
816         if (m_changed & changeAudio)
817         {
818                 if (m_audio->start() || m_audio->startPid())
819                         res = -1;
820                 m_changed &= ~changeAudio;
821         }
822 #else
823         if (m_changed & changePCR)
824         {
825                 if (m_pcr)
826                         m_pcr->stop();
827                 m_pcr = 0;
828                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
829                 {
830                         m_pcr = new eDVBPCR(m_demux);
831                         if (m_pcr->startPid(m_pcrpid))
832                                 res = -1;
833                 }
834                 m_changed &= ~changePCR;
835         }
836         if (m_changed & changeVideo)
837         {
838                 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
839                 if (m_video)
840                 {
841                         m_video->stop();
842                         m_video = 0;
843                         m_video_event_conn = 0;
844                 }
845                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
846                 {
847                         m_video = new eDVBVideo(m_demux, m_decoder);
848                         m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
849                         if (m_video->startPid(m_vpid, m_vtype))
850                                 res = -1;
851                 }
852                 m_changed &= ~changeVideo;
853         }
854         if (m_changed & changeAudio)
855         {
856                 if (m_audio)
857                         m_audio->stop();
858                 m_audio = 0;
859                 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
860                 {
861                         m_audio = new eDVBAudio(m_demux, m_decoder);
862                         if (m_audio->startPid(m_apid, m_atype))
863                                 res = -1;
864                 }
865                 m_changed &= ~changeAudio;
866         }
867         if (m_changed & changeText)
868         {
869                 if (m_text)
870                         m_text->stop();
871                 m_text = 0;
872                 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
873                 {
874                         m_text = new eDVBTText(m_demux);
875                         if (m_text->startPid(m_textpid))
876                                 res = -1;
877                 }
878                 m_changed &= ~changeText;
879         }
880 #endif
881         if (changed && !m_video && m_audio && m_radio_pic.length())
882                 showSinglePic(m_radio_pic.c_str());
883
884         return res;
885 }
886
887 int eTSMPEGDecoder::m_pcm_delay=-1,
888         eTSMPEGDecoder::m_ac3_delay=-1;
889
890 RESULT eTSMPEGDecoder::setPCMDelay(int delay)
891 {
892         if (m_decoder == 0 && delay != m_pcm_delay )
893         {
894                 FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
895                 if (fp)
896                 {
897                         fprintf(fp, "%x", delay*90);
898                         fclose(fp);
899                         m_pcm_delay = delay;
900                         return 0;
901                 }
902         }
903         return -1;
904 }
905
906 RESULT eTSMPEGDecoder::setAC3Delay(int delay)
907 {
908         if ( m_decoder == 0 && delay != m_ac3_delay )
909         {
910                 FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
911                 if (fp)
912                 {
913                         fprintf(fp, "%x", delay*90);
914                         fclose(fp);
915                         m_ac3_delay = delay;
916                         return 0;
917                 }
918         }
919         return -1;
920 }
921
922 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0), m_decoder(decoder)
923 {
924         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn);
925         m_is_ff = m_is_sm = m_is_trickmode = 0;
926 }
927
928 eTSMPEGDecoder::~eTSMPEGDecoder()
929 {
930         m_vpid = m_apid = m_pcrpid = pidNone;
931         m_changed = -1;
932         setState();
933 }
934
935 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
936 {
937         if (m_vpid != vpid)
938         {
939                 m_changed |= changeVideo;
940                 m_vpid = vpid;
941                 m_vtype = type;
942         }
943         return 0;
944 }
945
946 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
947 {
948         if ((m_apid != apid) || (m_atype != type))
949         {
950                 m_changed |= changeAudio;
951                 m_atype = type;
952                 m_apid = apid;
953         }
954         return 0;
955 }
956
957 int eTSMPEGDecoder::m_audio_channel = -1;
958
959 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
960 {
961         if (channel == -1)
962                 channel = ac_stereo;
963         if (m_decoder == 0 && m_audio_channel != channel)
964         {
965                 if (m_audio)
966                 {
967                         m_audio->setChannel(channel);
968                         m_audio_channel=channel;
969                 }
970                 else
971                         eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
972         }
973         return 0;
974 }
975
976 int eTSMPEGDecoder::getAudioChannel()
977 {
978         return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
979 }
980
981 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
982 {
983         if (m_pcrpid != pcrpid)
984         {
985                 m_changed |= changePCR;
986                 m_pcrpid = pcrpid;
987         }
988         return 0;
989 }
990
991 RESULT eTSMPEGDecoder::setTextPID(int textpid)
992 {
993         if (m_textpid != textpid)
994         {
995                 m_changed |= changeText;
996                 m_textpid = textpid;
997         }
998         return 0;
999 }
1000
1001 RESULT eTSMPEGDecoder::setSyncMaster(int who)
1002 {
1003         return -1;
1004 }
1005
1006 RESULT eTSMPEGDecoder::start()
1007 {
1008         RESULT r;
1009         r = setState();
1010         if (r)
1011                 return r;
1012         return unfreeze();
1013 }
1014
1015         /* preroll is start in freezed mode. */
1016 RESULT eTSMPEGDecoder::preroll()
1017 {
1018         return setState();
1019 }
1020
1021 RESULT eTSMPEGDecoder::freeze(int cont)
1022 {
1023         if (m_video)
1024                 m_video->freeze();
1025
1026         if (m_audio)
1027                 m_audio->freeze();
1028
1029         return 0;
1030 }
1031
1032 RESULT eTSMPEGDecoder::unfreeze()
1033 {
1034         if (m_video)
1035                 m_video->unfreeze();
1036
1037         if (m_audio)
1038                 m_audio->unfreeze();
1039
1040         return 0;
1041 }
1042
1043 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
1044 {
1045         return -1;
1046 }
1047
1048 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
1049 {
1050         return -1;
1051 }
1052
1053 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
1054 {
1055         m_is_ff = frames_to_skip != 0;
1056
1057         setState();
1058
1059         if (m_video)
1060                 return m_video->setFastForward(frames_to_skip);
1061         else
1062                 return -1;
1063 }
1064
1065 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
1066 {
1067         m_is_sm = repeat != 0;
1068
1069         setState();
1070
1071         if (m_video)
1072                 return m_video->setSlowMotion(repeat);
1073         else
1074                 return -1;
1075 }
1076
1077 RESULT eTSMPEGDecoder::setZoom(int what)
1078 {
1079         return -1;
1080 }
1081
1082 RESULT eTSMPEGDecoder::flush()
1083 {
1084         if (m_audio)
1085                 m_audio->flush();
1086         if (m_video)
1087                 m_video->flush();
1088         return 0;
1089 }
1090
1091 void eTSMPEGDecoder::demux_event(int event)
1092 {
1093         switch (event)
1094         {
1095         case eDVBDemux::evtFlush:
1096                 flush();
1097                 break;
1098         default:
1099                 break;
1100         }
1101 }
1102
1103 RESULT eTSMPEGDecoder::setTrickmode(int what)
1104 {
1105         m_is_trickmode = what;
1106         setState();
1107         return 0;
1108 }
1109
1110 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
1111 {
1112         if (what == 0) /* auto */
1113                 what = m_video ? 1 : 2;
1114
1115         if (what == 1) /* video */
1116         {
1117                 if (m_video)
1118                         return m_video->getPTS(pts);
1119                 else
1120                         return -1;
1121         }
1122
1123         if (what == 2) /* audio */
1124         {
1125                 if (m_audio)
1126                         return m_audio->getPTS(pts);
1127                 else
1128                         return -1;
1129         }
1130
1131         return -1;
1132 }
1133
1134 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
1135 {
1136         m_radio_pic = filename;
1137         return 0;
1138 }
1139
1140 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
1141 {
1142         if (m_decoder == 0)
1143         {
1144                 FILE *f = fopen(filename, "r");
1145                 if (f)
1146                 {
1147                         int vfd = open("/dev/dvb/adapter0/video0", O_RDWR);
1148                         if (vfd > 0)
1149                         {
1150                                 fseek(f, 0, SEEK_END);
1151                                 int length = ftell(f);
1152                                 unsigned char *buffer = new unsigned char[length*2+9];
1153                                 if (ioctl(vfd, VIDEO_FAST_FORWARD, 1) < 0)
1154                                         eDebug("VIDEO_FAST_FORWARD failed (%m)");
1155                                 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
1156                                         eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
1157                                 if (ioctl(vfd, VIDEO_PLAY) < 0)
1158                                         eDebug("VIDEO_PLAY failed (%m)");
1159                                 if (::ioctl(vfd, VIDEO_CONTINUE) < 0)
1160                                         eDebug("video: VIDEO_CONTINUE: %m");
1161                                 int cnt=0;
1162                                 int pos=0;
1163                                 while(cnt<2)
1164                                 {
1165                                         int rd;
1166                                         fseek(f, 0, SEEK_SET);
1167                                         if (!cnt)
1168                                         {
1169                                                 buffer[pos++]=0;
1170                                                 buffer[pos++]=0;
1171                                                 buffer[pos++]=1;
1172                                                 buffer[pos++]=0xE0;
1173                                                 buffer[pos++]=(length*2)>>8;
1174                                                 buffer[pos++]=(length*2)&0xFF;
1175                                                 buffer[pos++]=0x80;
1176                                                 buffer[pos++]=0;
1177                                                 buffer[pos++]=0;
1178                                         }
1179                                         while(1)
1180                                         {
1181                                                 rd = fread(buffer+pos, 1, length, f);
1182                                                 if (rd > 0)
1183                                                         pos += rd;
1184                                                 else
1185                                                         break;
1186                                         }
1187                                         ++cnt;
1188                                 }
1189                                 write(vfd, buffer, pos);
1190                                 usleep(75000);  // i dont like this.. but i dont have a better solution :(
1191                                 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
1192                                         eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
1193                                 if (ioctl(vfd, VIDEO_FAST_FORWARD, 0) < 0)
1194                                         eDebug("VIDEO_FAST_FORWARD failed (%m)");
1195                                 close(vfd);
1196                                 delete [] buffer;
1197                         }
1198                         fclose(f);
1199                 }
1200                 else
1201                 {
1202                         eDebug("couldnt open %s", filename);
1203                         return -1;
1204                 }
1205         }
1206         else
1207         {
1208                 eDebug("only show single pics on first decoder");
1209                 return -1;
1210         }
1211         return 0;
1212 }
1213
1214 RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
1215 {
1216         conn = new eConnection(this, m_video_event.connect(event));
1217         return 0;
1218 }
1219
1220 void eTSMPEGDecoder::video_event(struct videoEvent event)
1221 {
1222         /* emit */ m_video_event(event);
1223 }