dont spam on AUDIO_GET_PTS
[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), m_is_freezed(0)
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                 /*
191         case aDTS:
192                 bypass = 2;
193                 break;
194                 */
195         }
196
197         eDebugNoNewLine("AUDIO_SET_BYPASS - ");
198         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
199                 eDebug("failed (%m)");
200         else
201                 eDebug("ok");
202         freeze();
203
204         eDebugNoNewLine("AUDIO_PLAY - ");
205         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
206                 eDebug("failed (%m)");
207         else
208                 eDebug("ok");
209         return 0;
210 }
211 #endif
212
213 void eDVBAudio::stop()
214 {
215 #if HAVE_DVB_API_VERSION > 2
216         flush();
217 #endif
218         eDebugNoNewLine("AUDIO_STOP - ");
219         if (::ioctl(m_fd, AUDIO_STOP) < 0)
220                 eDebug("failed (%m)");
221         else
222                 eDebug("ok");
223 #if HAVE_DVB_API_VERSION > 2
224         eDebugNoNewLine("DEMUX_STOP - audio - ");
225         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
226                 eDebug("failed (%m)");
227         else
228                 eDebug("ok");
229 #endif
230 }
231
232 void eDVBAudio::flush()
233 {
234         eDebugNoNewLine("AUDIO_CLEAR_BUFFER - ");
235         if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
236                 eDebug("failed (%m)");
237         else
238                 eDebug("ok");
239 }
240
241 void eDVBAudio::freeze()
242 {
243         if (!m_is_freezed)
244         {
245                 eDebugNoNewLine("AUDIO_PAUSE - ");
246                 if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
247                         eDebug("failed (%m)");
248                 else
249                         eDebug("ok");
250                 m_is_freezed=1;
251         }
252 }
253
254 void eDVBAudio::unfreeze()
255 {
256         if (m_is_freezed)
257         {
258                 eDebugNoNewLine("AUDIO_CONTINUE - ");
259                 if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
260                         eDebug("failed (%m)");
261                 else
262                         eDebug("ok");
263                 m_is_freezed=0;
264         }
265 }
266
267 void eDVBAudio::setChannel(int channel)
268 {
269         int val = AUDIO_STEREO;
270         switch (channel)
271         {
272         case aMonoLeft: val = AUDIO_MONO_LEFT; break;
273         case aMonoRight: val = AUDIO_MONO_RIGHT; break;
274         default: break;
275         }
276         eDebugNoNewLine("AUDIO_CHANNEL_SELECT(%d) - ", val);
277         if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
278                 eDebug("failed (%m)");
279         else
280                 eDebug("ok");
281 }
282
283 int eDVBAudio::getPTS(pts_t &now)
284 {
285         eDebugNoNewLine("AUDIO_GET_PTS - ");
286         if (::ioctl(m_fd, AUDIO_GET_PTS, &now) < 0)
287                 eDebug("failed (%m)");
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)
923         :m_demux(demux), m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eApp)
924 {
925         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn);
926         CONNECT(m_showSinglePicTimer.timeout, eTSMPEGDecoder::finishShowSinglePic);
927         m_is_ff = m_is_sm = m_is_trickmode = 0;
928 }
929
930 eTSMPEGDecoder::~eTSMPEGDecoder()
931 {
932         finishShowSinglePic();
933         m_vpid = m_apid = m_pcrpid = m_textpid = pidNone;
934         m_changed = -1;
935         setState();
936 }
937
938 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
939 {
940         if (m_vpid != vpid)
941         {
942                 m_changed |= changeVideo;
943                 m_vpid = vpid;
944                 m_vtype = type;
945         }
946         return 0;
947 }
948
949 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
950 {
951         if ((m_apid != apid) || (m_atype != type))
952         {
953                 m_changed |= changeAudio;
954                 m_atype = type;
955                 m_apid = apid;
956         }
957         return 0;
958 }
959
960 int eTSMPEGDecoder::m_audio_channel = -1;
961
962 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
963 {
964         if (channel == -1)
965                 channel = ac_stereo;
966         if (m_decoder == 0 && m_audio_channel != channel)
967         {
968                 if (m_audio)
969                 {
970                         m_audio->setChannel(channel);
971                         m_audio_channel=channel;
972                 }
973                 else
974                         eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
975         }
976         return 0;
977 }
978
979 int eTSMPEGDecoder::getAudioChannel()
980 {
981         return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
982 }
983
984 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
985 {
986         if (m_pcrpid != pcrpid)
987         {
988                 m_changed |= changePCR;
989                 m_pcrpid = pcrpid;
990         }
991         return 0;
992 }
993
994 RESULT eTSMPEGDecoder::setTextPID(int textpid)
995 {
996         if (m_textpid != textpid)
997         {
998                 m_changed |= changeText;
999                 m_textpid = textpid;
1000         }
1001         return 0;
1002 }
1003
1004 RESULT eTSMPEGDecoder::setSyncMaster(int who)
1005 {
1006         return -1;
1007 }
1008
1009 RESULT eTSMPEGDecoder::start()
1010 {
1011         RESULT r;
1012         r = setState();
1013         if (r)
1014                 return r;
1015         return unfreeze();
1016 }
1017
1018         /* preroll is start in freezed mode. */
1019 RESULT eTSMPEGDecoder::preroll()
1020 {
1021         return setState();
1022 }
1023
1024 RESULT eTSMPEGDecoder::freeze(int cont)
1025 {
1026         if (m_video)
1027                 m_video->freeze();
1028
1029         if (m_audio)
1030                 m_audio->freeze();
1031
1032         return 0;
1033 }
1034
1035 RESULT eTSMPEGDecoder::unfreeze()
1036 {
1037         if (m_video)
1038                 m_video->unfreeze();
1039
1040         if (m_audio)
1041                 m_audio->unfreeze();
1042
1043         return 0;
1044 }
1045
1046 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
1047 {
1048         return -1;
1049 }
1050
1051 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
1052 {
1053         return -1;
1054 }
1055
1056 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
1057 {
1058         m_is_ff = frames_to_skip != 0;
1059
1060         setState();
1061
1062         if (m_video)
1063                 return m_video->setFastForward(frames_to_skip);
1064         else
1065                 return -1;
1066 }
1067
1068 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
1069 {
1070         m_is_sm = repeat != 0;
1071
1072         setState();
1073
1074         if (m_video)
1075                 return m_video->setSlowMotion(repeat);
1076         else
1077                 return -1;
1078 }
1079
1080 RESULT eTSMPEGDecoder::setZoom(int what)
1081 {
1082         return -1;
1083 }
1084
1085 RESULT eTSMPEGDecoder::flush()
1086 {
1087         if (m_audio)
1088                 m_audio->flush();
1089         if (m_video)
1090                 m_video->flush();
1091         return 0;
1092 }
1093
1094 void eTSMPEGDecoder::demux_event(int event)
1095 {
1096         switch (event)
1097         {
1098         case eDVBDemux::evtFlush:
1099                 flush();
1100                 break;
1101         default:
1102                 break;
1103         }
1104 }
1105
1106 RESULT eTSMPEGDecoder::setTrickmode(int what)
1107 {
1108         m_is_trickmode = what;
1109         setState();
1110         return 0;
1111 }
1112
1113 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
1114 {
1115         if (what == 0) /* auto */
1116                 what = m_video ? 1 : 2;
1117
1118         if (what == 1) /* video */
1119         {
1120                 if (m_video)
1121                         return m_video->getPTS(pts);
1122                 else
1123                         return -1;
1124         }
1125
1126         if (what == 2) /* audio */
1127         {
1128                 if (m_audio)
1129                         return m_audio->getPTS(pts);
1130                 else
1131                         return -1;
1132         }
1133
1134         return -1;
1135 }
1136
1137 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
1138 {
1139         m_radio_pic = filename;
1140         return 0;
1141 }
1142
1143 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
1144 {
1145         if (m_decoder == 0)
1146         {
1147                 eDebug("showSinglePic %s", filename);
1148                 int f = open(filename, O_RDONLY);
1149                 if (f)
1150                 {
1151                         struct stat s;
1152                         fstat(f, &s);
1153                         if (m_video_clip_fd == -1)
1154                                 m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY|O_NONBLOCK);
1155                         if (m_video_clip_fd >= 0)
1156                         {
1157                                 bool seq_end_avail = false;
1158                                 size_t pos=0;
1159                                 unsigned char pes_header[] = { 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x00, 0x00 };
1160                                 unsigned char seq_end[] = { 0x00, 0x00, 0x01, 0xB7 };
1161                                 unsigned char iframe[s.st_size];
1162                                 unsigned char stuffing[8192];
1163                                 memset(stuffing, 0, 8192);
1164                                 read(f, iframe, s.st_size);
1165                                 if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
1166                                         eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
1167                                 if (ioctl(m_video_clip_fd, VIDEO_PLAY) < 0)
1168                                         eDebug("VIDEO_PLAY failed (%m)");
1169                                 if (::ioctl(m_video_clip_fd, VIDEO_CONTINUE) < 0)
1170                                         eDebug("video: VIDEO_CONTINUE: %m");
1171                                 if (::ioctl(m_video_clip_fd, VIDEO_CLEAR_BUFFER) < 0)
1172                                         eDebug("video: VIDEO_CLEAR_BUFFER: %m");
1173                                 while(pos <= (s.st_size-4) && !(seq_end_avail = (!iframe[pos] && !iframe[pos+1] && iframe[pos+2] == 1 && iframe[pos+3] == 0xB7)))
1174                                         ++pos;
1175                                 if ((iframe[3] >> 4) != 0xE) // no pes header
1176                                         write(m_video_clip_fd, pes_header, sizeof(pes_header));
1177                                 write(m_video_clip_fd, iframe, s.st_size);
1178                                 if (!seq_end_avail)
1179                                         write(m_video_clip_fd, seq_end, sizeof(seq_end));
1180                                 write(m_video_clip_fd, stuffing, 8192);
1181                                 m_showSinglePicTimer.start(150, true);
1182                         }
1183                         close(f);
1184                 }
1185                 else
1186                 {
1187                         eDebug("couldnt open %s", filename);
1188                         return -1;
1189                 }
1190         }
1191         else
1192         {
1193                 eDebug("only show single pics on first decoder");
1194                 return -1;
1195         }
1196         return 0;
1197 }
1198
1199 void eTSMPEGDecoder::finishShowSinglePic()
1200 {
1201         if (m_video_clip_fd >= 0)
1202         {
1203                 if (ioctl(m_video_clip_fd, VIDEO_STOP, 0) < 0)
1204                         eDebug("VIDEO_STOP failed (%m)");
1205                 if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
1206                                 eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
1207                 close(m_video_clip_fd);
1208                 m_video_clip_fd = -1;
1209         }
1210 }
1211
1212 RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
1213 {
1214         conn = new eConnection(this, m_video_event.connect(event));
1215         return 0;
1216 }
1217
1218 void eTSMPEGDecoder::video_event(struct videoEvent event)
1219 {
1220         /* emit */ m_video_event(event);
1221 }