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