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