Merge commit 'origin/master' into tmbinc/FixTimingBugs
[vuplus_dvbapp] / 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 <sys/types.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32
33         /* these are quite new... */
34 #ifndef AUDIO_GET_PTS
35 #define AUDIO_GET_PTS              _IOR('o', 19, __u64)
36 #define VIDEO_GET_PTS              _IOR('o', 57, __u64)
37 #endif
38
39 DEFINE_REF(eDVBAudio);
40
41 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev)
42         :m_demux(demux), m_dev(dev)
43 {
44         char filename[128];
45 #if HAVE_DVB_API_VERSION < 3
46         sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);
47 #else
48         sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
49 #endif
50         m_fd = ::open(filename, O_RDWR);
51         if (m_fd < 0)
52                 eWarning("%s: %m", filename);
53 #if HAVE_DVB_API_VERSION < 3
54         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
55 #else
56         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
57 #endif
58         m_fd_demux = ::open(filename, O_RDWR);
59         if (m_fd_demux < 0)
60                 eWarning("%s: %m", filename);
61 }
62
63 #if HAVE_DVB_API_VERSION < 3
64 int eDVBAudio::setPid(int pid, int type)
65 {
66         if ((m_fd < 0) || (m_fd_demux < 0))
67                 return -1;
68
69         int bypass = 0;
70
71         switch (type)
72         {
73         case aMPEG:
74                 bypass = 1;
75                 break;
76         case aAC3:
77                 bypass = 0;
78                 break;
79                 /*
80         case aDTS:
81                 bypass = 2;
82                 break;
83                 */
84         }
85
86         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
87                 eDebug("failed (%m)");
88
89         dmx_pes_filter_params pes;
90
91         pes.pid      = pid;
92         pes.input    = DMX_IN_FRONTEND;
93         pes.output   = DMX_OUT_DECODER;
94         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
95         pes.flags    = 0;
96         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid);
97         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
98         {
99                 eDebug("failed (%m)");
100                 return -errno;
101         }
102         eDebug("ok");
103
104         return 0;
105 }
106
107 int eDVBAudio::startPid()
108 {
109         eDebugNoNewLine("DEMUX_START - audio - ");
110         if (::ioctl(m_fd_demux, DMX_START) < 0)
111         {
112                 eDebug("failed (%m)");
113                 return -errno;
114         }
115         eDebug("ok");
116         return 0;
117 }
118
119 int eDVBAudio::start()
120 {
121         eDebugNoNewLine("AUDIO_PLAY - ");
122         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
123         {
124                 eDebug("failed (%m)");
125                 return -errno;
126         }
127         eDebug("ok");
128         return 0;
129 }
130
131 int eDVBAudio::stopPid()
132 {
133         eDebugNoNewLine("DEMUX_STOP - audio - ");
134         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
135         {
136                 eDebug("failed (%m)");
137                 return -errno;
138         }
139         eDebug("ok");
140         return 0;
141 }
142
143 int eDVBAudio::setAVSync(int val)
144 {
145         eDebugNoNewLine("AUDIO_SET_AV_SYNC - ");
146         if (::ioctl(m_fd, AUDIO_SET_AV_SYNC, val) < 0)
147         {
148                 eDebug("failed (%m)");
149                 return -errno;
150         }
151         eDebug("ok");
152         return 0;
153 }
154 #else
155 int eDVBAudio::startPid(int pid, int type)
156 {
157         if ((m_fd < 0) || (m_fd_demux < 0))
158                 return -1;
159         dmx_pes_filter_params pes;
160
161         pes.pid      = pid;
162         pes.input    = DMX_IN_FRONTEND;
163         pes.output   = DMX_OUT_DECODER;
164         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
165         pes.flags    = 0;
166         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid);
167         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
168         {
169                 eDebug("failed (%m)");
170                 return -errno;
171         }
172         eDebug("ok");
173         eDebugNoNewLine("DEMUX_START - audio - ");
174         if (::ioctl(m_fd_demux, DMX_START) < 0)
175         {
176                 eDebug("failed (%m)");
177                 return -errno;
178         }
179         eDebug("ok");
180         int bypass = 0;
181
182         switch (type)
183         {
184         case aMPEG:
185                 bypass = 1;
186                 break;
187         case aAC3:
188                 bypass = 0;
189                 break;
190         case aDTS:
191                 bypass = 2;
192                 break;
193         case aAAC:
194                 bypass = 8;
195                 break;
196         case aAACHE:
197                 bypass = 9;
198                 break;
199         }
200
201         eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass);
202         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
203                 eDebug("failed (%m)");
204         else
205                 eDebug("ok");
206         freeze();
207
208         eDebugNoNewLine("AUDIO_PLAY - ");
209         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
210                 eDebug("failed (%m)");
211         else
212                 eDebug("ok");
213         return 0;
214 }
215 #endif
216
217 void eDVBAudio::stop()
218 {
219 #if HAVE_DVB_API_VERSION > 2
220         flush();
221 #endif
222         eDebugNoNewLine("AUDIO_STOP - ");
223         if (::ioctl(m_fd, AUDIO_STOP) < 0)
224                 eDebug("failed (%m)");
225         else
226                 eDebug("ok");
227 #if HAVE_DVB_API_VERSION > 2
228         eDebugNoNewLine("DEMUX_STOP - audio - ");
229         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
230                 eDebug("failed (%m)");
231         else
232                 eDebug("ok");
233 #endif
234 }
235
236 void eDVBAudio::flush()
237 {
238         eDebugNoNewLine("AUDIO_CLEAR_BUFFER - ");
239         if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
240                 eDebug("failed (%m)");
241         else
242                 eDebug("ok");
243 }
244
245 void eDVBAudio::freeze()
246 {
247         eDebugNoNewLine("AUDIO_PAUSE - ");
248         if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
249                 eDebug("failed (%m)");
250         else
251                 eDebug("ok");
252 }
253
254 void eDVBAudio::unfreeze()
255 {
256         eDebugNoNewLine("AUDIO_CONTINUE - ");
257         if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
258                 eDebug("failed (%m)");
259         else
260                 eDebug("ok");
261 }
262
263 void eDVBAudio::setChannel(int channel)
264 {
265         int val = AUDIO_STEREO;
266         switch (channel)
267         {
268         case aMonoLeft: val = AUDIO_MONO_LEFT; break;
269         case aMonoRight: val = AUDIO_MONO_RIGHT; break;
270         default: break;
271         }
272         eDebugNoNewLine("AUDIO_CHANNEL_SELECT(%d) - ", val);
273         if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
274                 eDebug("failed (%m)");
275         else
276                 eDebug("ok");
277 }
278
279 int eDVBAudio::getPTS(pts_t &now)
280 {
281         if (::ioctl(m_fd, AUDIO_GET_PTS, &now) < 0)
282                 eDebug("AUDIO_GET_PTS failed (%m)");
283         return 0;
284 }
285
286 eDVBAudio::~eDVBAudio()
287 {
288         unfreeze();
289         if (m_fd >= 0)
290                 ::close(m_fd);
291         if (m_fd_demux >= 0)
292                 ::close(m_fd_demux);
293 }
294
295 DEFINE_REF(eDVBVideo);
296
297 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev)
298         : m_demux(demux), m_dev(dev),
299         m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1)
300 {
301         char filename[128];
302 #if HAVE_DVB_API_VERSION < 3
303         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
304         m_fd_video = ::open("/dev/video", O_RDWR);
305         if (m_fd_video < 0)
306                 eWarning("/dev/video: %m");
307 #else
308         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
309 #endif
310         m_fd = ::open(filename, O_RDWR);
311         if (m_fd < 0)
312                 eWarning("%s: %m", filename);
313         else
314         {
315                 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Priority);
316                 CONNECT(m_sn->activated, eDVBVideo::video_event);
317         }
318         eDebug("Video Device: %s", filename);
319 #if HAVE_DVB_API_VERSION < 3
320         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
321 #else
322         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
323 #endif
324         m_fd_demux = ::open(filename, O_RDWR);
325         if (m_fd_demux < 0)
326                 eWarning("%s: %m", filename);
327         eDebug("demux device: %s", filename);
328 }
329
330 // not finally values i think.. !!
331 #define VIDEO_STREAMTYPE_MPEG2 0
332 #define VIDEO_STREAMTYPE_MPEG4_H264 1
333 #define VIDEO_STREAMTYPE_VC1 3
334 #define VIDEO_STREAMTYPE_MPEG4_Part2 4
335 #define VIDEO_STREAMTYPE_VC1_SM 5
336 #define VIDEO_STREAMTYPE_MPEG1 6
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         int streamtype = VIDEO_STREAMTYPE_MPEG2;
399
400         if ((m_fd < 0) || (m_fd_demux < 0))
401                 return -1;
402         dmx_pes_filter_params pes;
403
404         switch(type)
405         {
406         default:
407         case MPEG2:
408                 break;
409         case MPEG4_H264:
410                 streamtype = VIDEO_STREAMTYPE_MPEG4_H264;
411                 break;
412         case MPEG1:
413                 streamtype = VIDEO_STREAMTYPE_MPEG1;
414                 break;
415         case MPEG4_Part2:
416                 streamtype = VIDEO_STREAMTYPE_MPEG4_Part2;
417                 break;
418         case VC1:
419                 streamtype = VIDEO_STREAMTYPE_VC1;
420                 break;
421         case VC1_SM:
422                 streamtype = VIDEO_STREAMTYPE_VC1_SM;
423                 break;
424         }
425
426         eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype);
427         if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0)
428                 eDebug("failed (%m)");
429         else
430                 eDebug("ok");
431
432         pes.pid      = pid;
433         pes.input    = DMX_IN_FRONTEND;
434         pes.output   = DMX_OUT_DECODER;
435         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
436         pes.flags    = 0;
437         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid);
438         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
439         {
440                 eDebug("failed (%m)");
441                 return -errno;
442         }
443         eDebug("ok");
444         eDebugNoNewLine("DEMUX_START - video - ");
445         if (::ioctl(m_fd_demux, DMX_START) < 0)
446         {
447                 eDebug("failed (%m)");
448                 return -errno;
449         }
450         eDebug("ok");
451         freeze();
452         eDebugNoNewLine("VIDEO_PLAY - ");
453         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
454                 eDebug("failed (%m)");
455         else
456                 eDebug("ok");
457         return 0;
458 }
459 #endif
460
461 void eDVBVideo::stop()
462 {
463 #if HAVE_DVB_API_VERSION > 2
464         eDebugNoNewLine("DEMUX_STOP - video - ");
465         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
466                 eDebug("failed (%m)");
467         else
468                 eDebug("ok");
469 #endif
470         eDebugNoNewLine("VIDEO_STOP - ");
471         if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
472                 eDebug("failed (%m)");
473         else
474                 eDebug("ok");
475 }
476
477 void eDVBVideo::flush()
478 {
479         eDebugNoNewLine("VIDEO_CLEAR_BUFFER - ");
480         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
481                 eDebug("failed (%m)");
482         else
483                 eDebug("ok");
484 }
485
486 void eDVBVideo::freeze()
487 {
488         eDebugNoNewLine("VIDEO_FREEZE - ");
489         if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
490                 eDebug("failed (%m)");
491         else
492                 eDebug("ok");
493 }
494
495 void eDVBVideo::unfreeze()
496 {
497         eDebugNoNewLine("VIDEO_CONTINUE - ");
498         if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
499                 eDebug("failed (%m)");
500         else
501                 eDebug("ok");
502 }
503
504 int eDVBVideo::setSlowMotion(int repeat)
505 {
506         eDebugNoNewLine("VIDEO_SLOWMOTION(%d) - ", repeat);
507         int ret = ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
508         if (ret < 0)
509                 eDebug("failed(%m)");
510         else
511                 eDebug("ok");
512         return ret;
513 }
514
515 int eDVBVideo::setFastForward(int skip)
516 {
517         eDebugNoNewLine("VIDEO_FAST_FORWARD(%d) - ", skip);
518         int ret = ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
519         if (ret < 0)
520                 eDebug("failed(%m)");
521         else
522                 eDebug("ok");
523         return ret;
524 }
525
526 int eDVBVideo::getPTS(pts_t &now)
527 {
528 #if HAVE_DVB_API_VERSION < 3
529         #define VIDEO_GET_PTS_OLD           _IOR('o', 1, unsigned int*)
530         unsigned int pts;
531         int ret = ::ioctl(m_fd_video, VIDEO_GET_PTS_OLD, &pts);
532         now = pts;
533         now *= 2;
534 #else
535         int ret = ::ioctl(m_fd, VIDEO_GET_PTS, &now);
536 #endif
537         if (ret < 0)
538                 eDebug("VIDEO_GET_PTS failed(%m)");
539         return ret;
540 }
541
542 eDVBVideo::~eDVBVideo()
543 {
544         if (m_fd >= 0)
545                 ::close(m_fd);
546         if (m_fd_demux >= 0)
547                 ::close(m_fd_demux);
548 #if HAVE_DVB_API_VERSION < 3
549         if (m_fd_video >= 0)
550                 ::close(m_fd_video);
551 #endif
552 }
553
554 void eDVBVideo::video_event(int)
555 {
556 #if HAVE_DVB_API_VERSION >= 3
557         struct video_event evt;
558         eDebugNoNewLine("VIDEO_GET_EVENT - ");
559         if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
560                 eDebug("failed (%m)");
561         else
562         {
563                 eDebug("ok");
564                 if (evt.type == VIDEO_EVENT_SIZE_CHANGED)
565                 {
566                         struct iTSMPEGDecoder::videoEvent event;
567                         event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
568                         m_aspect = event.aspect = evt.u.size.aspect_ratio == 0 ? 2 : 3;  // convert dvb api to etsi
569                         m_height = event.height = evt.u.size.h;
570                         m_width = event.width = evt.u.size.w;
571                         /* emit */ m_event(event);
572                 }
573                 else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED)
574                 {
575                         struct iTSMPEGDecoder::videoEvent event;
576                         event.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged;
577                         m_framerate = event.framerate = evt.u.frame_rate;
578                         /* emit */ m_event(event);
579                 }
580                 else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/)
581                 {
582                         struct iTSMPEGDecoder::videoEvent event;
583                         event.type = iTSMPEGDecoder::videoEvent::eventProgressiveChanged;
584                         m_progressive = event.progressive = evt.u.frame_rate;
585                         /* emit */ m_event(event);
586                 }
587                 else
588                         eDebug("unhandled DVBAPI Video Event %d", evt.type);
589         }
590 #else
591 #warning "FIXMEE!! Video Events not implemented for old api"
592 #endif
593 }
594
595 RESULT eDVBVideo::connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEvent> &event, ePtr<eConnection> &conn)
596 {
597         conn = new eConnection(this, m_event.connect(event));
598         return 0;
599 }
600
601 static int readMpegProc(char *str, int decoder)
602 {
603         int val = -1;
604         char tmp[64];
605         sprintf(tmp, "/proc/stb/vmpeg/%d/%s", decoder, str);
606         FILE *f = fopen(tmp, "r");
607         if (f)
608         {
609                 fscanf(f, "%x", &val);
610                 fclose(f);
611         }
612         return val;
613 }
614
615 static int readApiSize(int fd, int &xres, int &yres, int &aspect)
616 {
617 #if HAVE_DVB_API_VERSION >= 3
618         video_size_t size;
619         if (!::ioctl(fd, VIDEO_GET_SIZE, &size))
620         {
621                 xres = size.w;
622                 yres = size.h;
623                 aspect = size.aspect_ratio == 0 ? 2 : 3;  // convert dvb api to etsi
624                 return 0;
625         }
626 //      eDebug("VIDEO_GET_SIZE failed (%m)");
627 #endif
628         return -1;
629 }
630
631 static int readApiFrameRate(int fd, int &framerate)
632 {
633 #if HAVE_DVB_API_VERSION >= 3
634         unsigned int frate;
635         if (!::ioctl(fd, VIDEO_GET_FRAME_RATE, &frate))
636         {
637                 framerate = frate;      
638                 return 0;
639         }
640 //      eDebug("VIDEO_GET_FRAME_RATE failed (%m)");
641 #endif
642         return -1;
643 }
644
645 int eDVBVideo::getWidth()
646 {
647         if (m_width == -1)
648                 readApiSize(m_fd, m_width, m_height, m_aspect);
649         if (m_width == -1)
650                 m_width = readMpegProc("xres", m_dev);
651         return m_width;
652 }
653
654 int eDVBVideo::getHeight()
655 {
656         if (m_height == -1)
657                 readApiSize(m_fd, m_width, m_height, m_aspect);
658         if (m_height == -1)
659                 m_height = readMpegProc("yres", m_dev);
660         return m_height;
661 }
662
663 int eDVBVideo::getAspect()
664 {
665         if (m_aspect == -1)
666                 readApiSize(m_fd, m_width, m_height, m_aspect);
667         if (m_aspect == -1)
668                 m_aspect = readMpegProc("aspect", m_dev);
669         return m_aspect;
670 }
671
672 int eDVBVideo::getProgressive()
673 {
674         if (m_progressive == -1)
675                 m_progressive = readMpegProc("progressive", m_dev);
676         return m_progressive;
677 }
678
679 int eDVBVideo::getFrameRate()
680 {
681         if (m_framerate == -1)
682                 readApiFrameRate(m_fd, m_framerate);
683         if (m_framerate == -1)
684                 m_framerate = readMpegProc("framerate", m_dev);
685         return m_framerate;
686 }
687
688 DEFINE_REF(eDVBPCR);
689
690 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
691 {
692         char filename[128];
693 #if HAVE_DVB_API_VERSION < 3
694         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
695 #else
696         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
697 #endif
698         m_fd_demux = ::open(filename, O_RDWR);
699         if (m_fd_demux < 0)
700                 eWarning("%s: %m", filename);
701 }
702
703 #if HAVE_DVB_API_VERSION < 3
704 int eDVBPCR::setPid(int pid)
705 {
706         if (m_fd_demux < 0)
707                 return -1;
708         dmx_pes_filter_params pes;
709
710         pes.pid      = pid;
711         pes.input    = DMX_IN_FRONTEND;
712         pes.output   = DMX_OUT_DECODER;
713         pes.pes_type = DMX_PES_PCR;
714         pes.flags    = 0;
715
716         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
717         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
718         {
719                 eDebug("failed (%m)");
720                 return -errno;
721         }
722         eDebug("ok");
723         return 0;
724 }
725
726 int eDVBPCR::startPid()
727 {
728         if (m_fd_demux < 0)
729                 return -1;
730         eDebugNoNewLine("DEMUX_START - pcr - ");
731         if (::ioctl(m_fd_demux, DMX_START) < 0)
732         {
733                 eDebug("failed (%m)");
734                 return -errno;
735         }
736         eDebug("ok");
737         return 0;
738 }
739 #else
740 int eDVBPCR::startPid(int pid)
741 {
742         if (m_fd_demux < 0)
743                 return -1;
744         dmx_pes_filter_params pes;
745
746         pes.pid      = pid;
747         pes.input    = DMX_IN_FRONTEND;
748         pes.output   = DMX_OUT_DECODER;
749         pes.pes_type = DMX_PES_PCR;
750         pes.flags    = 0;
751         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
752         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
753         {
754                 eDebug("failed (%m)");
755                 return -errno;
756         }
757         eDebug("ok");
758         eDebugNoNewLine("DEMUX_START - pcr - ");
759         if (::ioctl(m_fd_demux, DMX_START) < 0)
760         {
761                 eDebug("failed (%m)");
762                 return -errno;
763         }
764         eDebug("ok");
765         return 0;
766 }
767 #endif
768
769 void eDVBPCR::stop()
770 {
771         eDebugNoNewLine("DEMUX_STOP - pcr - ");
772         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
773                 eDebug("failed(%m)");
774         else
775                 eDebug("ok");
776 }
777
778 eDVBPCR::~eDVBPCR()
779 {
780         if (m_fd_demux >= 0)
781                 ::close(m_fd_demux);
782 }
783
784 DEFINE_REF(eDVBTText);
785
786 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
787 {
788         char filename[128];
789 #if HAVE_DVB_API_VERSION < 3
790         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
791 #else
792         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
793 #endif
794         m_fd_demux = ::open(filename, O_RDWR);
795         if (m_fd_demux < 0)
796                 eWarning("%s: %m", filename);
797 }
798
799 int eDVBTText::startPid(int pid)
800 {
801         if (m_fd_demux < 0)
802                 return -1;
803         dmx_pes_filter_params pes;
804
805         pes.pid      = pid;
806         pes.input    = DMX_IN_FRONTEND;
807         pes.output   = DMX_OUT_DECODER;
808         pes.pes_type = DMX_PES_TELETEXT;
809         pes.flags    = 0;
810
811         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - ttx - ", pid);
812         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
813         {
814                 eDebug("failed(%m)");
815                 return -errno;
816         }
817         eDebug("ok");
818         eDebugNoNewLine("DEMUX_START - pcr - ");
819         if (::ioctl(m_fd_demux, DMX_START) < 0)
820         {
821                 eDebug("failed(%m)");
822                 return -errno;
823         }
824         eDebug("ok");
825         return 0;
826 }
827
828 void eDVBTText::stop()
829 {
830         eDebugNoNewLine("DEMUX_STOP - ttx - ");
831         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
832                 eDebug("failed(%m)");
833         else
834                 eDebug("ok");
835 }
836
837 eDVBTText::~eDVBTText()
838 {
839         if (m_fd_demux >= 0)
840                 ::close(m_fd_demux);
841 }
842
843 DEFINE_REF(eTSMPEGDecoder);
844
845 int eTSMPEGDecoder::setState()
846 {
847         int res = 0;
848
849         int noaudio = (m_state != statePlay) && (m_state != statePause);
850         int nott = noaudio; /* actually same conditions */
851
852         if ((noaudio && m_audio) || (!m_audio && !noaudio))
853                 m_changed |= changeAudio | changeState;
854
855         if ((nott && m_text) || (!m_text && !nott))
856                 m_changed |= changeText | changeState;
857
858         const char *decoder_states[] = {"stop", "pause", "play", "decoderfastforward", "trickmode", "slowmotion"};
859         eDebug("decoder state: %s, vpid=%d, apid=%d", decoder_states[m_state], m_vpid, m_apid);
860
861         bool changed = !!m_changed;
862 #if HAVE_DVB_API_VERSION < 3
863         bool checkAVSync = m_changed & (changeAudio|changeVideo|changePCR);
864         if (m_changed & changeAudio && m_audio)
865                 m_audio->stopPid();
866         if (m_changed & changeVideo && m_video)
867                 m_video->stopPid();
868         if (m_changed & changePCR && m_pcr)
869         {
870                 m_pcr->stop();
871                 m_pcr=0;
872                 if (!(m_pcrpid >= 0 && m_pcrpid < 0x1ff))
873                         m_changed &= ~changePCR;
874         }
875         if (m_changed & changeAudio && m_audio)
876         {
877                 m_audio->stop();
878                 m_audio=0;
879                 if (!(m_apid >= 0 && m_apid < 0x1ff))
880                         m_changed &= ~changeAudio;
881         }
882         if (m_changed & changeVideo && m_video)
883         {
884                 m_video->stop();
885                 m_video=0;
886                 m_video_event_conn=0;
887                 if (!(m_vpid >= 0 && m_vpid < 0x1ff))
888                         m_changed &= ~changeVideo;
889         }
890         if (m_changed & changeVideo)
891         {
892                 m_video = new eDVBVideo(m_demux, m_decoder);
893                 m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
894                 if (m_video->setPid(m_vpid))
895                         res -1;
896         }
897         if (m_changed & changePCR)
898         {
899                 m_pcr = new eDVBPCR(m_demux);
900                 if (m_pcr->setPid(m_pcrpid))
901                         res = -1;
902         }
903         if (m_changed & changeAudio)
904         {
905                 m_audio = new eDVBAudio(m_demux, m_decoder);
906                 if (m_audio->setPid(m_apid, m_atype))
907                         res = -1;
908         }
909         if (m_changed & changePCR)
910         {
911                 if (m_pcr->startPid())
912                         res = -1;
913                 m_changed &= ~changePCR;
914         }
915         else if (checkAVSync && m_audio && m_video)
916         {
917                 if (m_audio->setAVSync(1))
918                         res = -1;
919         }
920         if (m_changed & changeVideo)
921         {
922                 if (m_video->startPid() || m_video->start())
923                         res = -1;
924                 m_changed &= ~changeVideo;
925         }
926         if (m_changed & changeAudio)
927         {
928                 if (m_audio->start() || m_audio->startPid())
929                         res = -1;
930                 m_changed &= ~changeAudio;
931         }
932 #else
933         if (m_changed & changePCR)
934         {
935                 if (m_pcr)
936                         m_pcr->stop();
937                 m_pcr = 0;
938         }
939         if (m_changed & changeVideo)
940         {
941                 if (m_video)
942                 {
943                         m_video->stop();
944                         m_video = 0;
945                         m_video_event_conn = 0;
946                 }
947         }
948         if (m_changed & changeAudio)
949         {
950                 if (m_audio)
951                         m_audio->stop();
952                 m_audio = 0;
953         }
954         if (m_changed & changeText)
955         {
956                 if (m_text)
957                         m_text->stop();
958                 m_text = 0;
959         }
960         if (m_changed & changePCR)
961         {
962                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
963                 {
964                         m_pcr = new eDVBPCR(m_demux);
965                         if (m_pcr->startPid(m_pcrpid))
966                                 res = -1;
967                 }
968                 m_changed &= ~changePCR;
969         }
970         if (m_changed & changeAudio)
971         {
972                 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
973                 {
974                         m_audio = new eDVBAudio(m_demux, m_decoder);
975                         if (m_audio->startPid(m_apid, m_atype))
976                                 res = -1;
977                 }
978                 m_changed &= ~changeAudio;
979         }
980         if (m_changed & changeVideo)
981         {
982                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
983                 {
984                         m_video = new eDVBVideo(m_demux, m_decoder);
985                         m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
986                         if (m_video->startPid(m_vpid, m_vtype))
987                                 res = -1;
988                 }
989                 m_changed &= ~changeVideo;
990         }
991         if (m_changed & changeText)
992         {
993                 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
994                 {
995                         m_text = new eDVBTText(m_demux);
996                         if (m_text->startPid(m_textpid))
997                                 res = -1;
998                 }
999                 m_changed &= ~changeText;
1000         }
1001 #endif
1002
1003         if (m_changed & changeState)
1004         {
1005                                         /* play, slowmotion, fast-forward */
1006                 int state_table[6][4] = 
1007                         {
1008                                 /* [stateStop] =                 */ {0, 0, 0},
1009                                 /* [statePause] =                */ {0, 0, 0},
1010                                 /* [statePlay] =                 */ {1, 0, 0},
1011                                 /* [stateDecoderFastForward] =   */ {1, 0, m_ff_sm_ratio},
1012                                 /* [stateHighspeedFastForward] = */ {1, 0, 1},
1013                                 /* [stateSlowMotion] =           */ {1, m_ff_sm_ratio, 0}
1014                         };
1015                 int *s = state_table[m_state];
1016                 if (m_video)
1017                 {
1018                         m_video->setSlowMotion(s[1]);
1019                         m_video->setFastForward(s[2]);
1020                         if (s[0])
1021                                 m_video->unfreeze();
1022                         else
1023                                 m_video->freeze();
1024                 }
1025                 if (m_audio)
1026                 {
1027                         if (s[0])
1028                                 m_audio->unfreeze();
1029                         else
1030                                 m_audio->freeze();
1031                 }
1032                 m_changed &= ~changeState;
1033         }
1034
1035         if (changed && !m_video && m_audio && m_radio_pic.length())
1036                 showSinglePic(m_radio_pic.c_str());
1037
1038         return res;
1039 }
1040
1041 int eTSMPEGDecoder::m_pcm_delay=-1,
1042         eTSMPEGDecoder::m_ac3_delay=-1;
1043
1044 RESULT eTSMPEGDecoder::setPCMDelay(int delay)
1045 {
1046         if (m_decoder == 0 && delay != m_pcm_delay )
1047         {
1048                 FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
1049                 if (fp)
1050                 {
1051                         fprintf(fp, "%x", delay*90);
1052                         fclose(fp);
1053                         m_pcm_delay = delay;
1054                         return 0;
1055                 }
1056         }
1057         return -1;
1058 }
1059
1060 RESULT eTSMPEGDecoder::setAC3Delay(int delay)
1061 {
1062         if ( m_decoder == 0 && delay != m_ac3_delay )
1063         {
1064                 FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
1065                 if (fp)
1066                 {
1067                         fprintf(fp, "%x", delay*90);
1068                         fclose(fp);
1069                         m_ac3_delay = delay;
1070                         return 0;
1071                 }
1072         }
1073         return -1;
1074 }
1075
1076 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder)
1077         : m_demux(demux), 
1078                 m_vpid(-1), m_vtype(-1), m_apid(-1), m_atype(-1), m_pcrpid(-1), m_textpid(-1),
1079                 m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp))
1080 {
1081         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn);
1082         CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic);
1083         m_state = stateStop;
1084 }
1085
1086 eTSMPEGDecoder::~eTSMPEGDecoder()
1087 {
1088         finishShowSinglePic();
1089         m_vpid = m_apid = m_pcrpid = m_textpid = pidNone;
1090         m_changed = -1;
1091         setState();
1092 }
1093
1094 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
1095 {
1096         if (m_vpid != vpid)
1097         {
1098                 m_changed |= changeVideo;
1099                 m_vpid = vpid;
1100                 m_vtype = type;
1101         }
1102         return 0;
1103 }
1104
1105 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
1106 {
1107         if ((m_apid != apid) || (m_atype != type))
1108         {
1109                 m_changed |= changeAudio;
1110                 m_atype = type;
1111                 m_apid = apid;
1112         }
1113         return 0;
1114 }
1115
1116 int eTSMPEGDecoder::m_audio_channel = -1;
1117
1118 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
1119 {
1120         if (channel == -1)
1121                 channel = ac_stereo;
1122         if (m_decoder == 0 && m_audio_channel != channel)
1123         {
1124                 if (m_audio)
1125                 {
1126                         m_audio->setChannel(channel);
1127                         m_audio_channel=channel;
1128                 }
1129                 else
1130                         eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
1131         }
1132         return 0;
1133 }
1134
1135 int eTSMPEGDecoder::getAudioChannel()
1136 {
1137         return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
1138 }
1139
1140 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
1141 {
1142         if (m_pcrpid != pcrpid)
1143         {
1144                 m_changed |= changePCR;
1145                 m_pcrpid = pcrpid;
1146         }
1147         return 0;
1148 }
1149
1150 RESULT eTSMPEGDecoder::setTextPID(int textpid)
1151 {
1152         if (m_textpid != textpid)
1153         {
1154                 m_changed |= changeText;
1155                 m_textpid = textpid;
1156         }
1157         return 0;
1158 }
1159
1160 RESULT eTSMPEGDecoder::setSyncMaster(int who)
1161 {
1162         return -1;
1163 }
1164
1165 RESULT eTSMPEGDecoder::set()
1166 {
1167         return setState();
1168 }
1169
1170 RESULT eTSMPEGDecoder::play()
1171 {
1172         if (m_state == statePlay)
1173                 return 0;
1174         m_state = statePlay;
1175         m_changed |= changeState;
1176         return setState();
1177 }
1178
1179 RESULT eTSMPEGDecoder::pause()
1180 {
1181         if (m_state == statePause)
1182                 return 0;
1183         m_state = statePause;
1184         m_changed |= changeState;
1185         return setState();
1186 }
1187
1188 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
1189 {
1190         if ((m_state == stateDecoderFastForward) && (m_ff_sm_ratio == frames_to_skip))
1191                 return 0;
1192
1193         m_state = stateDecoderFastForward;
1194         m_ff_sm_ratio = frames_to_skip;
1195         m_changed |= changeState;
1196         return setState();
1197
1198 //              return m_video->setFastForward(frames_to_skip);
1199 }
1200
1201 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
1202 {
1203         if ((m_state == stateSlowMotion) && (m_ff_sm_ratio == repeat))
1204                 return 0;
1205
1206         m_state = stateSlowMotion;
1207         m_ff_sm_ratio = repeat;
1208         m_changed |= changeState;
1209         return setState();
1210 }
1211
1212 RESULT eTSMPEGDecoder::setTrickmode()
1213 {
1214         if (m_state == stateTrickmode)
1215                 return 0;
1216
1217         m_state = stateTrickmode;
1218         m_changed |= changeState;
1219         return setState();
1220 }
1221
1222 RESULT eTSMPEGDecoder::flush()
1223 {
1224         if (m_audio)
1225                 m_audio->flush();
1226         if (m_video)
1227                 m_video->flush();
1228         return 0;
1229 }
1230
1231 void eTSMPEGDecoder::demux_event(int event)
1232 {
1233         switch (event)
1234         {
1235         case eDVBDemux::evtFlush:
1236                 flush();
1237                 break;
1238         default:
1239                 break;
1240         }
1241 }
1242
1243 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
1244 {
1245         if (what == 0) /* auto */
1246                 what = m_video ? 1 : 2;
1247
1248         if (what == 1) /* video */
1249         {
1250                 if (m_video)
1251                         return m_video->getPTS(pts);
1252                 else
1253                         return -1;
1254         }
1255
1256         if (what == 2) /* audio */
1257         {
1258                 if (m_audio)
1259                         return m_audio->getPTS(pts);
1260                 else
1261                         return -1;
1262         }
1263
1264         return -1;
1265 }
1266
1267 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
1268 {
1269         m_radio_pic = filename;
1270         return 0;
1271 }
1272
1273 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
1274 {
1275         if (m_decoder == 0)
1276         {
1277                 eDebug("showSinglePic %s", filename);
1278                 int f = open(filename, O_RDONLY);
1279                 if (f >= 0)
1280                 {
1281                         struct stat s;
1282                         fstat(f, &s);
1283                         if (m_video_clip_fd == -1)
1284                                 m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY|O_NONBLOCK);
1285                         if (m_video_clip_fd >= 0)
1286                         {
1287                                 bool seq_end_avail = false;
1288                                 size_t pos=0;
1289                                 unsigned char pes_header[] = { 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x00, 0x00 };
1290                                 unsigned char seq_end[] = { 0x00, 0x00, 0x01, 0xB7 };
1291                                 unsigned char iframe[s.st_size];
1292                                 unsigned char stuffing[8192];
1293                                 memset(stuffing, 0, 8192);
1294                                 read(f, iframe, s.st_size);
1295                                 if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
1296                                         eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
1297                                 if (ioctl(m_video_clip_fd, VIDEO_PLAY) < 0)
1298                                         eDebug("VIDEO_PLAY failed (%m)");
1299                                 if (::ioctl(m_video_clip_fd, VIDEO_CONTINUE) < 0)
1300                                         eDebug("video: VIDEO_CONTINUE: %m");
1301                                 if (::ioctl(m_video_clip_fd, VIDEO_CLEAR_BUFFER) < 0)
1302                                         eDebug("video: VIDEO_CLEAR_BUFFER: %m");
1303                                 while(pos <= (s.st_size-4) && !(seq_end_avail = (!iframe[pos] && !iframe[pos+1] && iframe[pos+2] == 1 && iframe[pos+3] == 0xB7)))
1304                                         ++pos;
1305                                 if ((iframe[3] >> 4) != 0xE) // no pes header
1306                                         write(m_video_clip_fd, pes_header, sizeof(pes_header));
1307                                 else
1308                                         iframe[4] = iframe[5] = 0x00;
1309                                 write(m_video_clip_fd, iframe, s.st_size);
1310                                 if (!seq_end_avail)
1311                                         write(m_video_clip_fd, seq_end, sizeof(seq_end));
1312                                 write(m_video_clip_fd, stuffing, 8192);
1313                                 m_showSinglePicTimer->start(150, true);
1314                         }
1315                         close(f);
1316                 }
1317                 else
1318                 {
1319                         eDebug("couldnt open %s", filename);
1320                         return -1;
1321                 }
1322         }
1323         else
1324         {
1325                 eDebug("only show single pics on first decoder");
1326                 return -1;
1327         }
1328         return 0;
1329 }
1330
1331 void eTSMPEGDecoder::finishShowSinglePic()
1332 {
1333         if (m_video_clip_fd >= 0)
1334         {
1335                 if (ioctl(m_video_clip_fd, VIDEO_STOP, 0) < 0)
1336                         eDebug("VIDEO_STOP failed (%m)");
1337                 if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
1338                                 eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
1339                 close(m_video_clip_fd);
1340                 m_video_clip_fd = -1;
1341         }
1342 }
1343
1344 RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
1345 {
1346         conn = new eConnection(this, m_video_event.connect(event));
1347         return 0;
1348 }
1349
1350 void eTSMPEGDecoder::video_event(struct videoEvent event)
1351 {
1352         /* emit */ m_video_event(event);
1353 }
1354
1355 int eTSMPEGDecoder::getVideoWidth()
1356 {
1357         if (m_video)
1358                 return m_video->getWidth();
1359         return -1;
1360 }
1361
1362 int eTSMPEGDecoder::getVideoHeight()
1363 {
1364         if (m_video)
1365                 return m_video->getHeight();
1366         return -1;
1367 }
1368
1369 int eTSMPEGDecoder::getVideoProgressive()
1370 {
1371         if (m_video)
1372                 return m_video->getProgressive();
1373         return -1;
1374 }
1375
1376 int eTSMPEGDecoder::getVideoFrameRate()
1377 {
1378         if (m_video)
1379                 return m_video->getFrameRate();
1380         return -1;
1381 }
1382
1383 int eTSMPEGDecoder::getVideoAspect()
1384 {
1385         if (m_video)
1386                 return m_video->getAspect();
1387         return -1;
1388 }