Merge branch 'master' of /home/tmbinc/enigma2-git 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 <<<<<<< HEAD:lib/dvb/decoder.cpp
299         : m_demux(demux), m_dev(dev),
300         m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1)
301 {
302         char filename[128];
303 #if HAVE_DVB_API_VERSION < 3
304         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
305         m_fd_video = ::open("/dev/video", O_RDWR);
306         if (m_fd_video < 0)
307                 eWarning("/dev/video: %m");
308 #else
309         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
310 #endif
311         m_fd = ::open(filename, O_RDWR);
312         if (m_fd < 0)
313                 eWarning("%s: %m", filename);
314         else
315         {
316                 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Priority);
317                 CONNECT(m_sn->activated, eDVBVideo::video_event);
318         }
319         eDebug("Video Device: %s", filename);
320 #if HAVE_DVB_API_VERSION < 3
321         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
322 #else
323         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
324 #endif
325         m_fd_demux = ::open(filename, O_RDWR);
326         if (m_fd_demux < 0)
327                 eWarning("%s: %m", filename);
328         eDebug("demux device: %s", filename);
329 }
330
331 // not finally values i think.. !!
332 #define VIDEO_STREAMTYPE_MPEG2 0
333 #define VIDEO_STREAMTYPE_MPEG4_H264 1
334 #define VIDEO_STREAMTYPE_VC1 3
335 #define VIDEO_STREAMTYPE_MPEG4_Part2 4
336 #define VIDEO_STREAMTYPE_VC1_SM 5
337 #define VIDEO_STREAMTYPE_MPEG1 6
338
339 #if HAVE_DVB_API_VERSION < 3
340 int eDVBVideo::setPid(int pid)
341 {
342         if ((m_fd < 0) || (m_fd_demux < 0))
343                 return -1;
344         dmx_pes_filter_params pes;
345
346         pes.pid      = pid;
347         pes.input    = DMX_IN_FRONTEND;
348         pes.output   = DMX_OUT_DECODER;
349         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
350         pes.flags    = 0;
351         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid);
352         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
353         {
354                 eDebug("failed (%m)");
355                 return -errno;
356         }
357         eDebug("ok");
358         return 0;
359 }
360
361 int eDVBVideo::startPid()
362 {
363         eDebugNoNewLine("DEMUX_START - video - ");
364         if (::ioctl(m_fd_demux, DMX_START) < 0)
365         {
366                 eDebug("failed (%m)");
367                 return -errno;
368         }
369         eDebug("ok");
370         return 0;
371 }
372
373 int eDVBVideo::start()
374 {
375         eDebugNoNewLine("VIDEO_PLAY - ");
376         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
377         {
378                 eDebug("failed (%m)");
379                 return -errno;
380         }
381         eDebug("ok");
382         return 0;
383 }
384
385 int eDVBVideo::stopPid()
386 {
387         eDebugNoNewLine("DEMUX_STOP - video - ");
388         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
389         {
390                 eDebug("failed (%m)");
391                 return -errno;
392         }
393         eDebug("ok");
394         return 0;
395 }
396 #else
397 int eDVBVideo::startPid(int pid, int type)
398 {
399         int streamtype = VIDEO_STREAMTYPE_MPEG2;
400
401         if ((m_fd < 0) || (m_fd_demux < 0))
402                 return -1;
403         dmx_pes_filter_params pes;
404
405         switch(type)
406         {
407         default:
408         case MPEG2:
409                 break;
410         case MPEG4_H264:
411                 streamtype = VIDEO_STREAMTYPE_MPEG4_H264;
412                 break;
413         case MPEG1:
414                 streamtype = VIDEO_STREAMTYPE_MPEG1;
415                 break;
416         case MPEG4_Part2:
417                 streamtype = VIDEO_STREAMTYPE_MPEG4_Part2;
418                 break;
419         case VC1:
420                 streamtype = VIDEO_STREAMTYPE_VC1;
421                 break;
422         case VC1_SM:
423                 streamtype = VIDEO_STREAMTYPE_VC1_SM;
424                 break;
425         }
426
427         eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype);
428         if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0)
429                 eDebug("failed (%m)");
430         else
431                 eDebug("ok");
432
433         pes.pid      = pid;
434         pes.input    = DMX_IN_FRONTEND;
435         pes.output   = DMX_OUT_DECODER;
436         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
437         pes.flags    = 0;
438         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid);
439         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
440         {
441                 eDebug("failed (%m)");
442                 return -errno;
443         }
444         eDebug("ok");
445         eDebugNoNewLine("DEMUX_START - video - ");
446         if (::ioctl(m_fd_demux, DMX_START) < 0)
447         {
448                 eDebug("failed (%m)");
449                 return -errno;
450         }
451         eDebug("ok");
452         freeze();
453         eDebugNoNewLine("VIDEO_PLAY - ");
454         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
455                 eDebug("failed (%m)");
456         else
457                 eDebug("ok");
458         return 0;
459 }
460 #endif
461
462 void eDVBVideo::stop()
463 {
464 #if HAVE_DVB_API_VERSION > 2
465         eDebugNoNewLine("DEMUX_STOP - video - ");
466         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
467                 eDebug("failed (%m)");
468         else
469                 eDebug("ok");
470 #endif
471         eDebugNoNewLine("VIDEO_STOP - ");
472         if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
473                 eDebug("failed (%m)");
474         else
475                 eDebug("ok");
476 }
477
478 void eDVBVideo::flush()
479 {
480         eDebugNoNewLine("VIDEO_CLEAR_BUFFER - ");
481         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
482                 eDebug("failed (%m)");
483         else
484                 eDebug("ok");
485 }
486
487 void eDVBVideo::freeze()
488 {
489         eDebugNoNewLine("VIDEO_FREEZE - ");
490         if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
491                 eDebug("failed (%m)");
492         else
493                 eDebug("ok");
494 }
495
496 void eDVBVideo::unfreeze()
497 {
498         eDebugNoNewLine("VIDEO_CONTINUE - ");
499         if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
500                 eDebug("failed (%m)");
501         else
502                 eDebug("ok");
503 }
504
505 int eDVBVideo::setSlowMotion(int repeat)
506 {
507         eDebugNoNewLine("VIDEO_SLOWMOTION(%d) - ", repeat);
508         int ret = ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
509         if (ret < 0)
510                 eDebug("failed(%m)");
511         else
512                 eDebug("ok");
513         return ret;
514 }
515
516 int eDVBVideo::setFastForward(int skip)
517 {
518         eDebugNoNewLine("VIDEO_FAST_FORWARD(%d) - ", skip);
519         int ret = ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
520         if (ret < 0)
521                 eDebug("failed(%m)");
522         else
523                 eDebug("ok");
524         return ret;
525 }
526
527 int eDVBVideo::getPTS(pts_t &now)
528 {
529 #if HAVE_DVB_API_VERSION < 3
530         #define VIDEO_GET_PTS_OLD           _IOR('o', 1, unsigned int*)
531         unsigned int pts;
532         int ret = ::ioctl(m_fd_video, VIDEO_GET_PTS_OLD, &pts);
533         now = pts;
534         now *= 2;
535 #else
536         int ret = ::ioctl(m_fd, VIDEO_GET_PTS, &now);
537 #endif
538         if (ret < 0)
539                 eDebug("VIDEO_GET_PTS failed(%m)");
540         return ret;
541 }
542
543 eDVBVideo::~eDVBVideo()
544 {
545         if (m_fd >= 0)
546                 ::close(m_fd);
547         if (m_fd_demux >= 0)
548                 ::close(m_fd_demux);
549 #if HAVE_DVB_API_VERSION < 3
550         if (m_fd_video >= 0)
551                 ::close(m_fd_video);
552 #endif
553 }
554
555 void eDVBVideo::video_event(int)
556 {
557 #if HAVE_DVB_API_VERSION >= 3
558         struct video_event evt;
559         eDebugNoNewLine("VIDEO_GET_EVENT - ");
560         if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
561                 eDebug("failed (%m)");
562         else
563         {
564                 eDebug("ok");
565                 if (evt.type == VIDEO_EVENT_SIZE_CHANGED)
566                 {
567                         struct iTSMPEGDecoder::videoEvent event;
568                         event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
569                         m_aspect = event.aspect = evt.u.size.aspect_ratio == 0 ? 2 : 3;  // convert dvb api to etsi
570                         m_height = event.height = evt.u.size.h;
571                         m_width = event.width = evt.u.size.w;
572                         /* emit */ m_event(event);
573                 }
574                 else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED)
575                 {
576                         struct iTSMPEGDecoder::videoEvent event;
577                         event.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged;
578                         m_framerate = event.framerate = evt.u.frame_rate;
579                         /* emit */ m_event(event);
580                 }
581                 else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/)
582                 {
583                         struct iTSMPEGDecoder::videoEvent event;
584                         event.type = iTSMPEGDecoder::videoEvent::eventProgressiveChanged;
585                         m_progressive = event.progressive = evt.u.frame_rate;
586                         /* emit */ m_event(event);
587                 }
588                 else
589                         eDebug("unhandled DVBAPI Video Event %d", evt.type);
590         }
591 #else
592 #warning "FIXMEE!! Video Events not implemented for old api"
593 #endif
594 }
595
596 RESULT eDVBVideo::connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEvent> &event, ePtr<eConnection> &conn)
597 {
598         conn = new eConnection(this, m_event.connect(event));
599         return 0;
600 }
601
602 static int readMpegProc(char *str, int decoder)
603 {
604         int val = -1;
605         char tmp[64];
606         sprintf(tmp, "/proc/stb/vmpeg/%d/%s", decoder, str);
607         FILE *f = fopen(tmp, "r");
608         if (f)
609         {
610                 fscanf(f, "%x", &val);
611                 fclose(f);
612         }
613         return val;
614 }
615
616 static int readApiSize(int fd, int &xres, int &yres, int &aspect)
617 {
618 #if HAVE_DVB_API_VERSION >= 3
619         video_size_t size;
620         if (!::ioctl(fd, VIDEO_GET_SIZE, &size))
621         {
622                 xres = size.w;
623                 yres = size.h;
624                 aspect = size.aspect_ratio == 0 ? 2 : 3;  // convert dvb api to etsi
625                 return 0;
626         }
627 //      eDebug("VIDEO_GET_SIZE failed (%m)");
628 #endif
629         return -1;
630 }
631
632 static int readApiFrameRate(int fd, int &framerate)
633 {
634 #if HAVE_DVB_API_VERSION >= 3
635         unsigned int frate;
636         if (!::ioctl(fd, VIDEO_GET_FRAME_RATE, &frate))
637         {
638                 framerate = frate;      
639                 return 0;
640         }
641 //      eDebug("VIDEO_GET_FRAME_RATE failed (%m)");
642 #endif
643         return -1;
644 }
645
646 int eDVBVideo::getWidth()
647 {
648         if (m_width == -1)
649                 readApiSize(m_fd, m_width, m_height, m_aspect);
650         if (m_width == -1)
651                 m_width = readMpegProc("xres", m_dev);
652         return m_width;
653 }
654
655 int eDVBVideo::getHeight()
656 {
657         if (m_height == -1)
658                 readApiSize(m_fd, m_width, m_height, m_aspect);
659         if (m_height == -1)
660                 m_height = readMpegProc("yres", m_dev);
661         return m_height;
662 }
663
664 int eDVBVideo::getAspect()
665 {
666         if (m_aspect == -1)
667                 readApiSize(m_fd, m_width, m_height, m_aspect);
668         if (m_aspect == -1)
669                 m_aspect = readMpegProc("aspect", m_dev);
670         return m_aspect;
671 }
672
673 int eDVBVideo::getProgressive()
674 {
675         if (m_progressive == -1)
676                 m_progressive = readMpegProc("progressive", m_dev);
677         return m_progressive;
678 }
679
680 int eDVBVideo::getFrameRate()
681 {
682         if (m_framerate == -1)
683                 readApiFrameRate(m_fd, m_framerate);
684         if (m_framerate == -1)
685                 m_framerate = readMpegProc("framerate", m_dev);
686         return m_framerate;
687 }
688
689 DEFINE_REF(eDVBPCR);
690
691 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
692 {
693         char filename[128];
694 #if HAVE_DVB_API_VERSION < 3
695         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
696 #else
697         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
698 #endif
699         m_fd_demux = ::open(filename, O_RDWR);
700         if (m_fd_demux < 0)
701                 eWarning("%s: %m", filename);
702 }
703
704 #if HAVE_DVB_API_VERSION < 3
705 int eDVBPCR::setPid(int pid)
706 {
707         if (m_fd_demux < 0)
708                 return -1;
709         dmx_pes_filter_params pes;
710
711         pes.pid      = pid;
712         pes.input    = DMX_IN_FRONTEND;
713         pes.output   = DMX_OUT_DECODER;
714         pes.pes_type = DMX_PES_PCR;
715         pes.flags    = 0;
716
717         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
718         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
719         {
720                 eDebug("failed (%m)");
721                 return -errno;
722         }
723         eDebug("ok");
724         return 0;
725 }
726
727 int eDVBPCR::startPid()
728 {
729         if (m_fd_demux < 0)
730                 return -1;
731         eDebugNoNewLine("DEMUX_START - pcr - ");
732         if (::ioctl(m_fd_demux, DMX_START) < 0)
733         {
734                 eDebug("failed (%m)");
735                 return -errno;
736         }
737         eDebug("ok");
738         return 0;
739 }
740 #else
741 int eDVBPCR::startPid(int pid)
742 {
743         if (m_fd_demux < 0)
744                 return -1;
745         dmx_pes_filter_params pes;
746
747         pes.pid      = pid;
748         pes.input    = DMX_IN_FRONTEND;
749         pes.output   = DMX_OUT_DECODER;
750         pes.pes_type = DMX_PES_PCR;
751         pes.flags    = 0;
752         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
753         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
754         {
755                 eDebug("failed (%m)");
756                 return -errno;
757         }
758         eDebug("ok");
759         eDebugNoNewLine("DEMUX_START - pcr - ");
760         if (::ioctl(m_fd_demux, DMX_START) < 0)
761         {
762                 eDebug("failed (%m)");
763                 return -errno;
764         }
765         eDebug("ok");
766         return 0;
767 }
768 #endif
769
770 void eDVBPCR::stop()
771 {
772         eDebugNoNewLine("DEMUX_STOP - pcr - ");
773         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
774                 eDebug("failed(%m)");
775         else
776                 eDebug("ok");
777 }
778
779 eDVBPCR::~eDVBPCR()
780 {
781         if (m_fd_demux >= 0)
782                 ::close(m_fd_demux);
783 }
784
785 DEFINE_REF(eDVBTText);
786
787 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
788 {
789         char filename[128];
790 #if HAVE_DVB_API_VERSION < 3
791         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
792 #else
793         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
794 #endif
795         m_fd_demux = ::open(filename, O_RDWR);
796         if (m_fd_demux < 0)
797                 eWarning("%s: %m", filename);
798 }
799
800 int eDVBTText::startPid(int pid)
801 {
802         if (m_fd_demux < 0)
803                 return -1;
804         dmx_pes_filter_params pes;
805
806         pes.pid      = pid;
807         pes.input    = DMX_IN_FRONTEND;
808         pes.output   = DMX_OUT_DECODER;
809         pes.pes_type = DMX_PES_TELETEXT;
810         pes.flags    = 0;
811
812         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - ttx - ", pid);
813         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
814         {
815                 eDebug("failed(%m)");
816                 return -errno;
817         }
818         eDebug("ok");
819         eDebugNoNewLine("DEMUX_START - pcr - ");
820         if (::ioctl(m_fd_demux, DMX_START) < 0)
821         {
822                 eDebug("failed(%m)");
823                 return -errno;
824         }
825         eDebug("ok");
826         return 0;
827 }
828
829 void eDVBTText::stop()
830 {
831         eDebugNoNewLine("DEMUX_STOP - ttx - ");
832         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
833                 eDebug("failed(%m)");
834         else
835                 eDebug("ok");
836 }
837
838 eDVBTText::~eDVBTText()
839 {
840         if (m_fd_demux >= 0)
841                 ::close(m_fd_demux);
842 }
843
844 DEFINE_REF(eTSMPEGDecoder);
845
846 int eTSMPEGDecoder::setState()
847 {
848         int res = 0;
849
850         int noaudio = (m_state != statePlay) && (m_state != statePause);
851         int nott = noaudio; /* actually same conditions */
852
853         if ((noaudio && m_audio) || (!m_audio && !noaudio))
854                 m_changed |= changeAudio | changeState;
855
856         if ((nott && m_text) || (!m_text && !nott))
857                 m_changed |= changeText | changeState;
858
859         bool changed = !!m_changed;
860 #if HAVE_DVB_API_VERSION < 3
861         bool checkAVSync = m_changed & (changeAudio|changeVideo|changePCR);
862         if (m_changed & changeAudio && m_audio)
863                 m_audio->stopPid();
864         if (m_changed & changeVideo && m_video)
865                 m_video->stopPid();
866         if (m_changed & changePCR && m_pcr)
867         {
868                 m_pcr->stop();
869                 m_pcr=0;
870                 if (!(m_pcrpid >= 0 && m_pcrpid < 0x1ff))
871                         m_changed &= ~changePCR;
872         }
873         if (m_changed & changeAudio && m_audio)
874         {
875                 m_audio->stop();
876                 m_audio=0;
877                 if (!(m_apid >= 0 && m_apid < 0x1ff))
878                         m_changed &= ~changeAudio;
879         }
880         if (m_changed & changeVideo && m_video)
881         {
882                 m_video->stop();
883                 m_video=0;
884                 m_video_event_conn=0;
885                 if (!(m_vpid >= 0 && m_vpid < 0x1ff))
886                         m_changed &= ~changeVideo;
887         }
888         if (m_changed & changeVideo)
889         {
890                 m_video = new eDVBVideo(m_demux, m_decoder);
891                 m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
892                 if (m_video->setPid(m_vpid))
893                         res -1;
894         }
895         if (m_changed & changePCR)
896         {
897                 m_pcr = new eDVBPCR(m_demux);
898                 if (m_pcr->setPid(m_pcrpid))
899                         res = -1;
900         }
901         if (m_changed & changeAudio)
902         {
903                 m_audio = new eDVBAudio(m_demux, m_decoder);
904                 if (m_audio->setPid(m_apid, m_atype))
905                         res = -1;
906         }
907         if (m_changed & changePCR)
908         {
909                 if (m_pcr->startPid())
910                         res = -1;
911                 m_changed &= ~changePCR;
912         }
913         else if (checkAVSync && m_audio && m_video)
914         {
915                 if (m_audio->setAVSync(1))
916                         res = -1;
917         }
918         if (m_changed & changeVideo)
919         {
920                 if (m_video->startPid() || m_video->start())
921                         res = -1;
922                 m_changed &= ~changeVideo;
923         }
924         if (m_changed & changeAudio)
925         {
926                 if (m_audio->start() || m_audio->startPid())
927                         res = -1;
928                 m_changed &= ~changeAudio;
929         }
930 #else
931         if (m_changed & changePCR)
932         {
933                 if (m_pcr)
934                         m_pcr->stop();
935                 m_pcr = 0;
936         }
937         if (m_changed & changeVideo)
938         {
939                 if (m_video)
940                 {
941                         m_video->stop();
942                         m_video = 0;
943                         m_video_event_conn = 0;
944                 }
945         }
946         if (m_changed & changeAudio)
947         {
948                 if (m_audio)
949                         m_audio->stop();
950                 m_audio = 0;
951         }
952         if (m_changed & changeText)
953         {
954                 if (m_text)
955                         m_text->stop();
956                 m_text = 0;
957         }
958         if (m_changed & changePCR)
959         {
960                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
961                 {
962                         m_pcr = new eDVBPCR(m_demux);
963                         if (m_pcr->startPid(m_pcrpid))
964                                 res = -1;
965                 }
966                 m_changed &= ~changePCR;
967         }
968         if (m_changed & changeAudio)
969         {
970                 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
971                 {
972                         m_audio = new eDVBAudio(m_demux, m_decoder);
973                         if (m_audio->startPid(m_apid, m_atype))
974                                 res = -1;
975                 }
976                 m_changed &= ~changeAudio;
977         }
978         if (m_changed & changeVideo)
979         {
980                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
981                 {
982                         m_video = new eDVBVideo(m_demux, m_decoder);
983                         m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
984                         if (m_video->startPid(m_vpid, m_vtype))
985                                 res = -1;
986                 }
987                 m_changed &= ~changeVideo;
988         }
989         if (m_changed & changeText)
990         {
991                 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
992                 {
993                         m_text = new eDVBTText(m_demux);
994                         if (m_text->startPid(m_textpid))
995                                 res = -1;
996                 }
997                 m_changed &= ~changeText;
998         }
999 #endif
1000
1001         if (m_changed & changeState)
1002         {
1003                                         /* play, slowmotion, fast-forward */
1004                 int state_table[6][4] = 
1005                         {
1006                                 /* [stateStop] =                 */ {0, 0, 0},
1007                                 /* [statePause] =                */ {0, 0, 0},
1008                                 /* [statePlay] =                 */ {1, 0, 0},
1009                                 /* [stateDecoderFastForward] =   */ {1, 0, m_ff_sm_ratio},
1010                                 /* [stateHighspeedFastForward] = */ {1, 0, 1},
1011                                 /* [stateSlowMotion] =           */ {1, m_ff_sm_ratio, 0}
1012                         };
1013                 int *s = state_table[m_state];
1014                 if (m_video)
1015                 {
1016                         m_video->setSlowMotion(s[1]);
1017                         m_video->setFastForward(s[2]);
1018                         if (s[0])
1019                                 m_video->unfreeze();
1020                         else
1021                                 m_video->freeze();
1022                 }
1023                 if (m_audio)
1024                 {
1025                         if (s[0])
1026                                 m_audio->unfreeze();
1027                         else
1028                                 m_audio->freeze();
1029                 }
1030                 m_changed &= ~changeState;
1031         }
1032
1033         if (changed && !m_video && m_audio && m_radio_pic.length())
1034                 showSinglePic(m_radio_pic.c_str());
1035
1036         return res;
1037 }
1038
1039 int eTSMPEGDecoder::m_pcm_delay=-1,
1040         eTSMPEGDecoder::m_ac3_delay=-1;
1041
1042 RESULT eTSMPEGDecoder::setPCMDelay(int delay)
1043 {
1044         if (m_decoder == 0 && delay != m_pcm_delay )
1045         {
1046                 FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
1047                 if (fp)
1048                 {
1049                         fprintf(fp, "%x", delay*90);
1050                         fclose(fp);
1051                         m_pcm_delay = delay;
1052                         return 0;
1053                 }
1054         }
1055         return -1;
1056 }
1057
1058 RESULT eTSMPEGDecoder::setAC3Delay(int delay)
1059 {
1060         if ( m_decoder == 0 && delay != m_ac3_delay )
1061         {
1062                 FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
1063                 if (fp)
1064                 {
1065                         fprintf(fp, "%x", delay*90);
1066                         fclose(fp);
1067                         m_ac3_delay = delay;
1068                         return 0;
1069                 }
1070         }
1071         return -1;
1072 }
1073
1074 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder)
1075         :m_demux(demux), m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp))
1076 {
1077         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn);
1078         CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic);
1079         m_state = stateStop;
1080 }
1081
1082 eTSMPEGDecoder::~eTSMPEGDecoder()
1083 {
1084         finishShowSinglePic();
1085         m_vpid = m_apid = m_pcrpid = m_textpid = pidNone;
1086         m_changed = -1;
1087         setState();
1088 }
1089
1090 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
1091 {
1092         if (m_vpid != vpid)
1093         {
1094                 m_changed |= changeVideo;
1095                 m_vpid = vpid;
1096                 m_vtype = type;
1097         }
1098         return 0;
1099 }
1100
1101 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
1102 {
1103         if ((m_apid != apid) || (m_atype != type))
1104         {
1105                 m_changed |= changeAudio;
1106                 m_atype = type;
1107                 m_apid = apid;
1108         }
1109         return 0;
1110 }
1111
1112 int eTSMPEGDecoder::m_audio_channel = -1;
1113
1114 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
1115 {
1116         if (channel == -1)
1117                 channel = ac_stereo;
1118         if (m_decoder == 0 && m_audio_channel != channel)
1119         {
1120                 if (m_audio)
1121                 {
1122                         m_audio->setChannel(channel);
1123                         m_audio_channel=channel;
1124                 }
1125                 else
1126                         eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
1127         }
1128         return 0;
1129 }
1130
1131 int eTSMPEGDecoder::getAudioChannel()
1132 {
1133         return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
1134 }
1135
1136 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
1137 {
1138         if (m_pcrpid != pcrpid)
1139         {
1140                 m_changed |= changePCR;
1141                 m_pcrpid = pcrpid;
1142         }
1143         return 0;
1144 }
1145
1146 RESULT eTSMPEGDecoder::setTextPID(int textpid)
1147 {
1148         if (m_textpid != textpid)
1149         {
1150                 m_changed |= changeText;
1151                 m_textpid = textpid;
1152         }
1153         return 0;
1154 }
1155
1156 RESULT eTSMPEGDecoder::setSyncMaster(int who)
1157 {
1158         return -1;
1159 }
1160
1161 RESULT eTSMPEGDecoder::set()
1162 {
1163         return setState();
1164 }
1165
1166 RESULT eTSMPEGDecoder::play()
1167 {
1168         if (m_state == statePlay)
1169                 return 0;
1170         m_state = statePlay;
1171         m_changed |= changeState;
1172         return setState();
1173 }
1174
1175 RESULT eTSMPEGDecoder::pause()
1176 {
1177         if (m_state == statePause)
1178                 return 0;
1179         m_state = statePause;
1180         m_changed |= changeState;
1181         return setState();
1182 }
1183
1184 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
1185 {
1186         if ((m_state == stateDecoderFastForward) && (m_ff_sm_ratio == frames_to_skip))
1187                 return 0;
1188
1189         m_state = stateDecoderFastForward;
1190         m_ff_sm_ratio = frames_to_skip;
1191         m_changed |= changeState;
1192         return setState();
1193
1194 //              return m_video->setFastForward(frames_to_skip);
1195 }
1196
1197 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
1198 {
1199         if ((m_state == stateSlowMotion) && (m_ff_sm_ratio == repeat))
1200                 return 0;
1201
1202         m_state = stateSlowMotion;
1203         m_ff_sm_ratio = repeat;
1204         m_changed |= changeState;
1205         return setState();
1206 }
1207
1208 RESULT eTSMPEGDecoder::setTrickmode()
1209 {
1210         if (m_state == stateTrickmode)
1211                 return 0;
1212
1213         m_state = stateTrickmode;
1214         m_changed |= changeState;
1215         return setState();
1216 }
1217
1218 RESULT eTSMPEGDecoder::flush()
1219 {
1220         if (m_audio)
1221                 m_audio->flush();
1222         if (m_video)
1223                 m_video->flush();
1224         return 0;
1225 }
1226
1227 void eTSMPEGDecoder::demux_event(int event)
1228 {
1229         switch (event)
1230         {
1231         case eDVBDemux::evtFlush:
1232                 flush();
1233                 break;
1234         default:
1235                 break;
1236         }
1237 }
1238
1239 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
1240 {
1241         if (what == 0) /* auto */
1242                 what = m_video ? 1 : 2;
1243
1244         if (what == 1) /* video */
1245         {
1246                 if (m_video)
1247                         return m_video->getPTS(pts);
1248                 else
1249                         return -1;
1250         }
1251
1252         if (what == 2) /* audio */
1253         {
1254                 if (m_audio)
1255                         return m_audio->getPTS(pts);
1256                 else
1257                         return -1;
1258         }
1259
1260         return -1;
1261 }
1262
1263 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
1264 {
1265         m_radio_pic = filename;
1266         return 0;
1267 }
1268
1269 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
1270 {
1271         if (m_decoder == 0)
1272         {
1273                 eDebug("showSinglePic %s", filename);
1274                 int f = open(filename, O_RDONLY);
1275                 if (f >= 0)
1276                 {
1277                         struct stat s;
1278                         fstat(f, &s);
1279                         if (m_video_clip_fd == -1)
1280                                 m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY|O_NONBLOCK);
1281                         if (m_video_clip_fd >= 0)
1282                         {
1283                                 bool seq_end_avail = false;
1284                                 size_t pos=0;
1285                                 unsigned char pes_header[] = { 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x00, 0x00 };
1286                                 unsigned char seq_end[] = { 0x00, 0x00, 0x01, 0xB7 };
1287                                 unsigned char iframe[s.st_size];
1288                                 unsigned char stuffing[8192];
1289                                 memset(stuffing, 0, 8192);
1290                                 read(f, iframe, s.st_size);
1291                                 if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
1292                                         eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
1293                                 if (ioctl(m_video_clip_fd, VIDEO_PLAY) < 0)
1294                                         eDebug("VIDEO_PLAY failed (%m)");
1295                                 if (::ioctl(m_video_clip_fd, VIDEO_CONTINUE) < 0)
1296                                         eDebug("video: VIDEO_CONTINUE: %m");
1297                                 if (::ioctl(m_video_clip_fd, VIDEO_CLEAR_BUFFER) < 0)
1298                                         eDebug("video: VIDEO_CLEAR_BUFFER: %m");
1299                                 while(pos <= (s.st_size-4) && !(seq_end_avail = (!iframe[pos] && !iframe[pos+1] && iframe[pos+2] == 1 && iframe[pos+3] == 0xB7)))
1300                                         ++pos;
1301                                 if ((iframe[3] >> 4) != 0xE) // no pes header
1302                                         write(m_video_clip_fd, pes_header, sizeof(pes_header));
1303                                 else
1304                                         iframe[4] = iframe[5] = 0x00;
1305                                 write(m_video_clip_fd, iframe, s.st_size);
1306                                 if (!seq_end_avail)
1307                                         write(m_video_clip_fd, seq_end, sizeof(seq_end));
1308                                 write(m_video_clip_fd, stuffing, 8192);
1309                                 m_showSinglePicTimer->start(150, true);
1310                         }
1311                         close(f);
1312                 }
1313                 else
1314                 {
1315                         eDebug("couldnt open %s", filename);
1316                         return -1;
1317                 }
1318         }
1319         else
1320         {
1321                 eDebug("only show single pics on first decoder");
1322                 return -1;
1323         }
1324         return 0;
1325 }
1326
1327 void eTSMPEGDecoder::finishShowSinglePic()
1328 {
1329         if (m_video_clip_fd >= 0)
1330         {
1331                 if (ioctl(m_video_clip_fd, VIDEO_STOP, 0) < 0)
1332                         eDebug("VIDEO_STOP failed (%m)");
1333                 if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
1334                                 eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
1335                 close(m_video_clip_fd);
1336                 m_video_clip_fd = -1;
1337         }
1338 }
1339
1340 RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
1341 {
1342         conn = new eConnection(this, m_video_event.connect(event));
1343         return 0;
1344 }
1345
1346 void eTSMPEGDecoder::video_event(struct videoEvent event)
1347 {
1348         /* emit */ m_video_event(event);
1349 }
1350
1351 int eTSMPEGDecoder::getVideoWidth()
1352 {
1353         if (m_video)
1354                 return m_video->getWidth();
1355         return -1;
1356 }
1357
1358 int eTSMPEGDecoder::getVideoHeight()
1359 {
1360         if (m_video)
1361                 return m_video->getHeight();
1362         return -1;
1363 }
1364
1365 int eTSMPEGDecoder::getVideoProgressive()
1366 {
1367         if (m_video)
1368                 return m_video->getProgressive();
1369         return -1;
1370 }
1371
1372 int eTSMPEGDecoder::getVideoFrameRate()
1373 {
1374         if (m_video)
1375                 return m_video->getFrameRate();
1376         return -1;
1377 }
1378
1379 int eTSMPEGDecoder::getVideoAspect()
1380 {
1381         if (m_video)
1382                 return m_video->getAspect();
1383         return -1;
1384 }