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