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