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