some changes for better support of old dreambox models
[enigma2.git] / 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 <errno.h>
30
31         /* these are quite new... */
32 #ifndef AUDIO_GET_PTS
33 #define AUDIO_GET_PTS              _IOR('o', 19, __u64)
34 #define VIDEO_GET_PTS              _IOR('o', 57, __u64)
35 #endif
36
37 DEFINE_REF(eDVBAudio);
38
39 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
40 {
41         char filename[128];
42 #if HAVE_DVB_API_VERSION < 3
43         sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);
44 #else
45         sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
46 #endif
47         m_fd = ::open(filename, O_RDWR);
48         if (m_fd < 0)
49                 eWarning("%s: %m", filename);
50 #if HAVE_DVB_API_VERSION < 3
51         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
52 #else
53         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
54 #endif
55         m_fd_demux = ::open(filename, O_RDWR);
56         if (m_fd_demux < 0)
57                 eWarning("%s: %m", filename);
58 }
59
60 #if HAVE_DVB_API_VERSION < 3
61 int eDVBAudio::setPid(int pid, int type)
62 {
63         if ((m_fd < 0) || (m_fd_demux < 0))
64                 return -1;
65
66         int bypass = 0;
67
68         switch (type)
69         {
70         case aMPEG:
71                 bypass = 1;
72                 break;
73         case aAC3:
74                 bypass = 0;
75                 break;
76                 /*
77         case aDTS:
78                 bypass = 2;
79                 break;
80                 */
81         }
82
83         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
84                 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
85
86         dmx_pes_filter_params pes;
87
88         pes.pid      = pid;
89         pes.input    = DMX_IN_FRONTEND;
90         pes.output   = DMX_OUT_DECODER;
91         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
92         pes.flags    = 0;
93         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
94         {
95                 eWarning("audio: DMX_SET_PES_FILTER: %m");
96                 return -errno;
97         }
98
99         return 0;
100 }
101
102 int eDVBAudio::startPid()
103 {
104         if (::ioctl(m_fd_demux, DMX_START) < 0)
105         {
106                 eWarning("audio: DMX_START: %m");
107                 return -errno;
108         }
109         return 0;
110 }
111
112 int eDVBAudio::start()
113 {
114         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
115         {
116                 eWarning("audio: AUDIO_PLAY: %m");
117                 return -errno;
118         }
119         return 0;
120 }
121
122 int eDVBAudio::stopPid()
123 {
124         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
125         {
126                 eWarning("audio: DMX_STOP: %m");
127                 return -errno;
128         }
129         return 0;
130 }
131
132 int eDVBAudio::setAVSync(int val)
133 {
134         if (::ioctl(m_fd, AUDIO_SET_AV_SYNC, val) < 0)
135         {
136                 eWarning("audio: AUDIO_SET_AV_SYNC: %m");
137                 return -errno;
138         }
139         return 0;
140 }
141 #else
142 int eDVBAudio::startPid(int pid, int type)
143 {
144         if ((m_fd < 0) || (m_fd_demux < 0))
145                 return -1;
146         dmx_pes_filter_params pes;
147
148         pes.pid      = pid;
149         pes.input    = DMX_IN_FRONTEND;
150         pes.output   = DMX_OUT_DECODER;
151         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
152         pes.flags    = 0;
153         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
154         {
155                 eWarning("audio: DMX_SET_PES_FILTER: %m");
156                 return -errno;
157         }
158         if (::ioctl(m_fd_demux, DMX_START) < 0)
159         {
160                 eWarning("audio: DMX_START: %m");
161                 return -errno;
162         }
163
164         int bypass = 0;
165
166         switch (type)
167         {
168         case aMPEG:
169                 bypass = 1;
170                 break;
171         case aAC3:
172                 bypass = 0;
173                 break;
174                 /*
175         case aDTS:
176                 bypass = 2;
177                 break;
178                 */
179         }
180
181         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
182                 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
183
184         freeze();
185
186         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
187                 eWarning("audio: AUDIO_PLAY: %m");
188         return 0;
189 }
190 #endif
191
192 void eDVBAudio::stop()
193 {
194 #if HAVE_DVB_API_VERSION > 2
195         flush();
196 #endif
197         if (::ioctl(m_fd, AUDIO_STOP) < 0)
198                 eWarning("audio: AUDIO_STOP: %m");
199 #if HAVE_DVB_API_VERSION > 2
200         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
201                 eWarning("audio: DMX_STOP: %m");
202 #endif
203 }
204
205 void eDVBAudio::flush()
206 {
207         if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
208                 eDebug("audio: AUDIO_CLEAR_BUFFER: %m");
209 }
210
211 void eDVBAudio::freeze()
212 {
213         if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
214                 eDebug("video: AUDIO_PAUSE: %m");
215 }
216
217 void eDVBAudio::unfreeze()
218 {
219         if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
220                 eDebug("video: AUDIO_CONTINUE: %m");
221 }
222
223 void eDVBAudio::setChannel(int channel)
224 {
225         int val = AUDIO_STEREO;
226         switch (channel)
227         {
228         case aMonoLeft: val = AUDIO_MONO_LEFT; break;
229         case aMonoRight: val = AUDIO_MONO_RIGHT; break;
230         default: break;
231         }
232         if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
233                 eDebug("video: AUDIO_CHANNEL_SELECT: %m");
234 }
235
236 int eDVBAudio::getPTS(pts_t &now)
237 {
238         return ::ioctl(m_fd, AUDIO_GET_PTS, &now);
239 }
240
241 eDVBAudio::~eDVBAudio()
242 {
243         unfreeze();
244         if (m_fd >= 0)
245                 ::close(m_fd);
246         if (m_fd_demux >= 0)
247                 ::close(m_fd_demux);
248 }
249
250 DEFINE_REF(eDVBVideo);
251
252 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
253 {
254         char filename[128];
255 #if HAVE_DVB_API_VERSION < 3
256         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
257 #else
258         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
259 #endif
260         m_fd = ::open(filename, O_RDWR);
261         if (m_fd < 0)
262                 eWarning("%s: %m", filename);
263         else
264         {
265                 m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Priority);
266                 CONNECT(m_sn->activated, eDVBVideo::video_event);
267         }
268         eDebug("Video Device: %s", filename);
269 #if HAVE_DVB_API_VERSION < 3
270         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
271 #else
272         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
273 #endif
274         m_fd_demux = ::open(filename, O_RDWR);
275         if (m_fd_demux < 0)
276                 eWarning("%s: %m", filename);
277         eDebug("demux device: %s", filename);
278 }
279
280 // not finally values i think.. !!
281 #define VIDEO_STREAMTYPE_MPEG2 0
282 #define VIDEO_STREAMTYPE_MPEG4_H264 1
283
284 #if HAVE_DVB_API_VERSION < 3
285 int eDVBVideo::setPid(int pid)
286 {
287         if ((m_fd < 0) || (m_fd_demux < 0))
288                 return -1;
289         dmx_pes_filter_params pes;
290
291         pes.pid      = pid;
292         pes.input    = DMX_IN_FRONTEND;
293         pes.output   = DMX_OUT_DECODER;
294         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
295         pes.flags    = 0;
296         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
297         {
298                 eWarning("video: DMX_SET_PES_FILTER: %m");
299                 return -errno;
300         }
301         return 0;
302 }
303
304 int eDVBVideo::startPid()
305 {
306         if (::ioctl(m_fd_demux, DMX_START) < 0)
307         {
308                 eWarning("video: DMX_START: %m");
309                 return -errno;
310         }
311         return 0;
312 }
313
314 int eDVBVideo::start()
315 {
316         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
317         {
318                 eWarning("video: VIDEO_PLAY: %m");
319                 return -errno;
320         }
321         return 0;
322 }
323
324 int eDVBVideo::stopPid()
325 {
326         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
327         {
328                 eWarning("video: DMX_STOP: %m");
329                 return -errno;
330         }
331         return 0;
332 }
333 #else
334 int eDVBVideo::startPid(int pid, int type)
335 {
336         if ((m_fd < 0) || (m_fd_demux < 0))
337                 return -1;
338         dmx_pes_filter_params pes;
339
340         if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE,
341                 type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2) < 0)
342                 eWarning("video: VIDEO_SET_STREAMTYPE: %m");
343
344         pes.pid      = pid;
345         pes.input    = DMX_IN_FRONTEND;
346         pes.output   = DMX_OUT_DECODER;
347         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
348         pes.flags    = 0;
349         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
350         {
351                 eWarning("video: DMX_SET_PES_FILTER: %m");
352                 return -errno;
353         }
354         if (::ioctl(m_fd_demux, DMX_START) < 0)
355         {
356                 eWarning("video: DMX_START: %m");
357                 return -errno;
358         }
359
360         eDebug("FREEZE.\n");
361         freeze();
362
363         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
364                 eWarning("video: VIDEO_PLAY: %m");
365         return 0;
366 }
367 #endif
368
369 void eDVBVideo::stop()
370 {
371 #if HAVE_DVB_API_VERSION > 2
372         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
373                 eWarning("video: DMX_STOP: %m");
374 #endif
375         eDebug("VIDEO_STOP");
376         if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
377                 eWarning("video: VIDEO_STOP: %m");
378 }
379
380 void eDVBVideo::flush()
381 {
382         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
383                 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
384 }
385
386 void eDVBVideo::freeze()
387 {
388         eDebug("VIDEO_FREEZE");
389         if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
390                 eDebug("video: VIDEO_FREEZE: %m");
391 }
392
393 void eDVBVideo::unfreeze()
394 {
395         eDebug("VIDEO_CONTINUE");
396         if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
397                 eDebug("video: VIDEO_CONTINUE: %m");
398 }
399
400 int eDVBVideo::setSlowMotion(int repeat)
401 {
402         m_is_slow_motion = repeat;
403         return ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
404 }
405
406 int eDVBVideo::setFastForward(int skip)
407 {
408         m_is_fast_forward = skip;
409         return ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
410 }
411
412 int eDVBVideo::getPTS(pts_t &now)
413 {
414         return ::ioctl(m_fd, VIDEO_GET_PTS, &now);
415 }
416
417 eDVBVideo::~eDVBVideo()
418 {
419         if (m_sn)
420                 delete m_sn;
421         if (m_is_slow_motion)
422                 setSlowMotion(0);
423         if (m_is_fast_forward)
424                 setFastForward(0);
425         unfreeze();
426         if (m_fd >= 0)
427                 ::close(m_fd);
428         if (m_fd_demux >= 0)
429                 ::close(m_fd_demux);
430 }
431
432 void eDVBVideo::video_event(int)
433 {
434 #if HAVE_DVB_API_VERSION >= 3
435         struct video_event evt;
436         if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
437                 eDebug("VIDEO_GET_EVENT failed(%m)");
438         else
439         {
440                 if (evt.type == VIDEO_EVENT_SIZE_CHANGED)
441                 {
442                         struct iTSMPEGDecoder::videoEvent event;
443                         event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
444                         event.aspect = evt.u.size.aspect_ratio;
445                         event.height = evt.u.size.h;
446                         event.width = evt.u.size.w;
447                         /* emit */ m_event(event);
448                 }
449                 else
450                         eDebug("unhandled DVBAPI Video Event %d", evt.type);
451         }
452 #else
453 #warning "FIXMEE!! Video Events not implemented for old api"
454 #endif
455 }
456
457 RESULT eDVBVideo::connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEvent> &event, ePtr<eConnection> &conn)
458 {
459         conn = new eConnection(this, m_event.connect(event));
460         return 0;
461 }
462
463 DEFINE_REF(eDVBPCR);
464
465 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
466 {
467         char filename[128];
468 #if HAVE_DVB_API_VERSION < 3
469         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
470 #else
471         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
472 #endif
473         m_fd_demux = ::open(filename, O_RDWR);
474         if (m_fd_demux < 0)
475                 eWarning("%s: %m", filename);
476 }
477
478 #if HAVE_DVB_API_VERSION < 3
479 int eDVBPCR::setPid(int pid)
480 {
481         if (m_fd_demux < 0)
482                 return -1;
483         dmx_pes_filter_params pes;
484
485         pes.pid      = pid;
486         pes.input    = DMX_IN_FRONTEND;
487         pes.output   = DMX_OUT_DECODER;
488         pes.pes_type = DMX_PES_PCR;
489         pes.flags    = 0;
490         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
491         {
492                 eWarning("video: DMX_SET_PES_FILTER: %m");
493                 return -errno;
494         }
495         return 0;
496 }
497
498 int eDVBPCR::startPid()
499 {
500         if (m_fd_demux < 0)
501                 return -1;
502         if (::ioctl(m_fd_demux, DMX_START) < 0)
503         {
504                 eWarning("video: DMX_START: %m");
505                 return -errno;
506         }
507         return 0;
508 }
509 #else
510 int eDVBPCR::startPid(int pid)
511 {
512         if (m_fd_demux < 0)
513                 return -1;
514         dmx_pes_filter_params pes;
515
516         pes.pid      = pid;
517         pes.input    = DMX_IN_FRONTEND;
518         pes.output   = DMX_OUT_DECODER;
519         pes.pes_type = DMX_PES_PCR;
520         pes.flags    = 0;
521         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
522         {
523                 eWarning("video: DMX_SET_PES_FILTER: %m");
524                 return -errno;
525         }
526         if (::ioctl(m_fd_demux, DMX_START) < 0)
527         {
528                 eWarning("video: DMX_START: %m");
529                 return -errno;
530         }
531         return 0;
532 }
533 #endif
534
535 void eDVBPCR::stop()
536 {
537         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
538                 eWarning("video: DMX_STOP: %m");
539 }
540
541 eDVBPCR::~eDVBPCR()
542 {
543         if (m_fd_demux >= 0)
544                 ::close(m_fd_demux);
545 }
546
547 DEFINE_REF(eDVBTText);
548
549 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
550 {
551         char filename[128];
552 #if HAVE_DVB_API_VERSION < 3
553         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
554 #else
555         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
556 #endif
557         m_fd_demux = ::open(filename, O_RDWR);
558         if (m_fd_demux < 0)
559                 eWarning("%s: %m", filename);
560 }
561
562 int eDVBTText::startPid(int pid)
563 {
564         if (m_fd_demux < 0)
565                 return -1;
566         dmx_pes_filter_params pes;
567
568         pes.pid      = pid;
569         pes.input    = DMX_IN_FRONTEND;
570         pes.output   = DMX_OUT_DECODER;
571         pes.pes_type = DMX_PES_TELETEXT;
572         pes.flags    = 0;
573         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
574         {
575                 eWarning("video: DMX_SET_PES_FILTER: %m");
576                 return -errno;
577         }
578         if (::ioctl(m_fd_demux, DMX_START) < 0)
579         {
580                 eWarning("video: DMX_START: %m");
581                 return -errno;
582         }
583         return 0;
584 }
585
586 void eDVBTText::stop()
587 {
588         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
589                 eWarning("video: DMX_STOP: %m");
590 }
591
592 eDVBTText::~eDVBTText()
593 {
594         if (m_fd_demux >= 0)
595                 ::close(m_fd_demux);
596 }
597
598 DEFINE_REF(eTSMPEGDecoder);
599
600 int eTSMPEGDecoder::setState()
601 {
602         int res = 0;
603
604         int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
605         int nott = noaudio; /* actually same conditions */
606
607         if ((noaudio && m_audio) || (!m_audio && !noaudio))
608                 m_changed |= changeAudio;
609
610         if ((nott && m_text) || (!m_text && !nott))
611                 m_changed |= changeText;
612
613         bool changed = !!m_changed;
614 #if HAVE_DVB_API_VERSION < 3
615         if (m_changed & changeAudio && m_audio)
616                 m_audio->stopPid();
617         if (m_changed & changeVideo && m_video)
618                 m_video->stopPid();
619         if (m_changed & changePCR && m_pcr)
620         {
621                 m_pcr->stop();
622                 m_pcr=0;
623         }
624         if (m_changed & changeAudio && m_audio)
625         {
626                 m_audio->stop();
627                 m_audio=0;
628         }
629         if (m_changed & changeVideo && m_video)
630         {
631                 m_video->stop();
632                 m_video=0;
633                 m_video_event_conn=0;
634         }
635         if (m_changed & changeVideo)
636         {
637                 m_video = new eDVBVideo(m_demux, m_decoder);
638                 m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
639                 if (m_video->setPid(m_vpid))
640                         res -1;
641         }
642         if (m_changed & changePCR)
643         {
644                 m_pcr = new eDVBPCR(m_demux);
645                 if (m_pcr->setPid(m_pcrpid))
646                         res = -1;
647         }
648         if (m_changed & changeAudio)
649         {
650                 m_audio = new eDVBAudio(m_demux, m_decoder);
651                 if (m_audio->setPid(m_apid, m_atype))
652                         res = -1;
653         }
654         if (m_changed & changePCR && m_pcrpid != -1)
655         {
656                 if (m_pcr->startPid())
657                         res = -1;
658                 m_changed &= ~changePCR;
659         }
660         else if (m_apid != -1 && m_vpid != -1)   // playback
661         {
662                 if (m_audio->setAVSync(1))
663                         res = -1;
664         }
665         
666         if (m_changed & changeVideo)
667         {
668                 if (m_video->startPid() || m_video->start())
669                         res = -1;
670                 m_changed &= ~changeVideo;
671         }
672         if (m_changed & changeAudio)
673         {
674                 if (m_audio->start() || m_audio->startPid())
675                         res = -1;
676                 m_changed &= ~changeAudio;
677         }
678 #else
679         if (m_changed & changePCR)
680         {
681                 if (m_pcr)
682                         m_pcr->stop();
683                 m_pcr = 0;
684                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
685                 {
686                         m_pcr = new eDVBPCR(m_demux);
687                         if (m_pcr->startPid(m_pcrpid))
688                         {
689                                 eWarning("pcr: startpid failed!");
690                                 res = -1;
691                         }
692                 }
693                 m_changed &= ~changePCR;
694         }
695         if (m_changed & changeVideo)
696         {
697                 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
698                 if (m_video)
699                 {
700                         eDebug("STOP");
701                         m_video->stop();
702                         m_video = 0;
703                         m_video_event_conn = 0;
704                 }
705                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
706                 {
707                         eDebug("new video");
708                         m_video = new eDVBVideo(m_demux, m_decoder);
709                         m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
710                         if (m_video->startPid(m_vpid, m_vtype))
711                         {
712                                 eWarning("video: startpid failed!");
713                                 res = -1;
714                         }
715                 }
716                 m_changed &= ~changeVideo;
717         }
718         if (m_changed & changeAudio)
719         {
720                 if (m_audio)
721                         m_audio->stop();
722                 m_audio = 0;
723                 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
724                 {
725                         m_audio = new eDVBAudio(m_demux, m_decoder);
726                         if (m_audio->startPid(m_apid, m_atype))
727                         {
728                                 eWarning("audio: startpid failed!");
729                                 res = -1;
730                         }
731                 }
732                 m_changed &= ~changeAudio;
733         }
734         if (m_changed & changeText)
735         {
736                 if (m_text)
737                         m_text->stop();
738                 m_text = 0;
739                 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
740                 {
741                         m_text = new eDVBTText(m_demux);
742                         if (m_text->startPid(m_textpid))
743                         {
744                                 eWarning("text: startpid failed!");
745                                 res = -1;
746                         }
747                 }
748                 m_changed &= ~changeText;
749         }
750 #endif
751         if (changed && !m_video && m_audio && m_radio_pic.length())
752                 showSinglePic(m_radio_pic.c_str());
753
754         return res;
755 }
756
757 int eTSMPEGDecoder::m_pcm_delay=-1,
758         eTSMPEGDecoder::m_ac3_delay=-1;
759
760 RESULT eTSMPEGDecoder::setPCMDelay(int delay)
761 {
762         if (m_decoder == 0 && delay != m_pcm_delay )
763         {
764                 FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
765                 if (fp)
766                 {
767                         fprintf(fp, "%x", delay*90);
768                         fclose(fp);
769                         m_pcm_delay = delay;
770                         return 0;
771                 }
772         }
773         return -1;
774 }
775
776 RESULT eTSMPEGDecoder::setAC3Delay(int delay)
777 {
778         if ( m_decoder == 0 && delay != m_ac3_delay )
779         {
780                 FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
781                 if (fp)
782                 {
783                         fprintf(fp, "%x", delay*90);
784                         fclose(fp);
785                         m_ac3_delay = delay;
786                         return 0;
787                 }
788         }
789         return -1;
790 }
791
792 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0), m_decoder(decoder)
793 {
794         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn);
795         m_is_ff = m_is_sm = m_is_trickmode = 0;
796 }
797
798 eTSMPEGDecoder::~eTSMPEGDecoder()
799 {
800         m_vpid = m_apid = m_pcrpid = pidNone;
801         m_changed = -1;
802         setState();
803 }
804
805 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
806 {
807         if (m_vpid != vpid)
808         {
809                 m_changed |= changeVideo;
810                 m_vpid = vpid;
811                 m_vtype = type;
812         }
813         return 0;
814 }
815
816 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
817 {
818         if ((m_apid != apid) || (m_atype != type))
819         {
820                 m_changed |= changeAudio;
821                 m_atype = type;
822                 m_apid = apid;
823         }
824         return 0;
825 }
826
827 int eTSMPEGDecoder::m_audio_channel = -1;
828
829 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
830 {
831         if (channel == -1)
832                 channel = ac_stereo;
833         if (m_decoder == 0 && m_audio_channel != channel)
834         {
835                 if (m_audio)
836                 {
837                         m_audio->setChannel(channel);
838                         m_audio_channel=channel;
839                 }
840                 else
841                         eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
842         }
843         return 0;
844 }
845
846 int eTSMPEGDecoder::getAudioChannel()
847 {
848         return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
849 }
850
851 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
852 {
853         if (m_pcrpid != pcrpid)
854         {
855                 m_changed |= changePCR;
856                 m_pcrpid = pcrpid;
857         }
858         return 0;
859 }
860
861 RESULT eTSMPEGDecoder::setTextPID(int textpid)
862 {
863         if (m_textpid != textpid)
864         {
865                 m_changed |= changeText;
866                 m_textpid = textpid;
867         }
868         return 0;
869 }
870
871 RESULT eTSMPEGDecoder::setSyncMaster(int who)
872 {
873         return -1;
874 }
875
876 RESULT eTSMPEGDecoder::start()
877 {
878         RESULT r;
879         r = setState();
880         if (r)
881                 return r;
882         return unfreeze();
883 }
884
885         /* preroll is start in freezed mode. */
886 RESULT eTSMPEGDecoder::preroll()
887 {
888         return setState();
889 }
890
891 RESULT eTSMPEGDecoder::freeze(int cont)
892 {
893         if (m_video)
894                 m_video->freeze();
895
896         if (m_audio)
897                 m_audio->freeze();
898
899         return 0;
900 }
901
902 RESULT eTSMPEGDecoder::unfreeze()
903 {
904         if (m_video)
905                 m_video->unfreeze();
906
907         if (m_audio)
908                 m_audio->unfreeze();
909
910         return 0;
911 }
912
913 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
914 {
915         return -1;
916 }
917
918 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
919 {
920         return -1;
921 }
922
923 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
924 {
925         m_is_ff = frames_to_skip != 0;
926
927         setState();
928
929         if (m_video)
930                 return m_video->setFastForward(frames_to_skip);
931         else
932                 return -1;
933 }
934
935 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
936 {
937         m_is_sm = repeat != 0;
938
939         setState();
940
941         if (m_video)
942                 return m_video->setSlowMotion(repeat);
943         else
944                 return -1;
945 }
946
947 RESULT eTSMPEGDecoder::setZoom(int what)
948 {
949         return -1;
950 }
951
952 RESULT eTSMPEGDecoder::flush()
953 {
954         if (m_audio)
955                 m_audio->flush();
956         if (m_video)
957                 m_video->flush();
958         return 0;
959 }
960
961 void eTSMPEGDecoder::demux_event(int event)
962 {
963         switch (event)
964         {
965         case eDVBDemux::evtFlush:
966                 flush();
967                 break;
968         default:
969                 break;
970         }
971 }
972
973 RESULT eTSMPEGDecoder::setTrickmode(int what)
974 {
975         m_is_trickmode = what;
976         setState();
977         return 0;
978 }
979
980 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
981 {
982         if (what == 0) /* auto */
983                 what = m_video ? 1 : 2;
984
985         if (what == 1) /* video */
986         {
987                 if (m_video)
988                         return m_video->getPTS(pts);
989                 else
990                         return -1;
991         }
992
993         if (what == 2) /* audio */
994         {
995                 if (m_audio)
996                         return m_audio->getPTS(pts);
997                 else
998                         return -1;
999         }
1000
1001         return -1;
1002 }
1003
1004 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
1005 {
1006         m_radio_pic = filename;
1007         return 0;
1008 }
1009
1010 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
1011 {
1012         if (m_decoder == 0)
1013         {
1014                 FILE *f = fopen(filename, "r");
1015                 if (f)
1016                 {
1017                         int vfd = open("/dev/dvb/adapter0/video0", O_RDWR);
1018                         if (vfd > 0)
1019                         {
1020                                 fseek(f, 0, SEEK_END);
1021                                 int length = ftell(f);
1022                                 unsigned char *buffer = new unsigned char[length*2+9];
1023                                 if (ioctl(vfd, VIDEO_FAST_FORWARD, 1) < 0)
1024                                         eDebug("VIDEO_FAST_FORWARD failed (%m)");
1025                                 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
1026                                         eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
1027                                 if (ioctl(vfd, VIDEO_PLAY) < 0)
1028                                         eDebug("VIDEO_PLAY failed (%m)");
1029                                 if (::ioctl(vfd, VIDEO_CONTINUE) < 0)
1030                                         eDebug("video: VIDEO_CONTINUE: %m");
1031                                 int cnt=0;
1032                                 int pos=0;
1033                                 while(cnt<2)
1034                                 {
1035                                         int rd;
1036                                         fseek(f, 0, SEEK_SET);
1037                                         if (!cnt)
1038                                         {
1039                                                 buffer[pos++]=0;
1040                                                 buffer[pos++]=0;
1041                                                 buffer[pos++]=1;
1042                                                 buffer[pos++]=0xE0;
1043                                                 buffer[pos++]=(length*2)>>8;
1044                                                 buffer[pos++]=(length*2)&0xFF;
1045                                                 buffer[pos++]=0x80;
1046                                                 buffer[pos++]=0;
1047                                                 buffer[pos++]=0;
1048                                         }
1049                                         while(1)
1050                                         {
1051                                                 rd = fread(buffer+pos, 1, length, f);
1052                                                 if (rd > 0)
1053                                                         pos += rd;
1054                                                 else
1055                                                         break;
1056                                         }
1057                                         ++cnt;
1058                                 }
1059                                 write(vfd, buffer, pos);
1060                                 usleep(75000);  // i dont like this.. but i dont have a better solution :(
1061                                 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
1062                                         eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
1063                                 if (ioctl(vfd, VIDEO_FAST_FORWARD, 0) < 0)
1064                                         eDebug("VIDEO_FAST_FORWARD failed (%m)");
1065                                 close(vfd);
1066                                 delete [] buffer;
1067                         }
1068                         fclose(f);
1069                 }
1070                 else
1071                 {
1072                         eDebug("couldnt open %s", filename);
1073                         return -1;
1074                 }
1075         }
1076         else
1077         {
1078                 eDebug("only show single pics on first decoder");
1079                 return -1;
1080         }
1081         return 0;
1082 }
1083
1084 RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
1085 {
1086         conn = new eConnection(this, m_video_event.connect(event));
1087         return 0;
1088 }
1089
1090 void eTSMPEGDecoder::video_event(struct videoEvent event)
1091 {
1092         /* emit */ m_video_event(event);
1093 }