finally fix satfinder with new config
[enigma2.git] / lib / dvb / decoder.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/dvb/decoder.h>
3 #if HAVE_DVB_API_VERSION < 3 
4 #define audioStatus audio_status
5 #define videoStatus video_status
6 #define pesType pes_type
7 #define playState play_state
8 #define audioStreamSource_t audio_stream_source_t
9 #define videoStreamSource_t video_stream_source_t
10 #define streamSource stream_source
11 #define dmxPesFilterParams dmx_pes_filter_params
12 #define DMX_PES_VIDEO DMX_PES_VIDEO0
13 #define DMX_PES_AUDIO DMX_PES_AUDIO0
14 #include <ost/dmx.h>
15 #include <ost/video.h>
16 #include <ost/audio.h>
17 #else
18 #include <linux/dvb/audio.h>
19 #include <linux/dvb/video.h>
20 #include <linux/dvb/dmx.h>
21 #endif
22
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <sys/ioctl.h>
26 #include <errno.h>
27
28         /* these are quite new... */
29 #ifndef AUDIO_GET_PTS
30 #define AUDIO_GET_PTS              _IOR('o', 19, __u64)
31 #define VIDEO_GET_PTS              _IOR('o', 57, __u64)
32 #endif
33
34 DEFINE_REF(eDVBAudio);
35
36 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
37 {
38         char filename[128];
39 #if HAVE_DVB_API_VERSION < 3
40         sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);      
41 #else
42         sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
43 #endif
44         m_fd = ::open(filename, O_RDWR);
45         if (m_fd < 0)
46                 eWarning("%s: %m", filename);
47 #if HAVE_DVB_API_VERSION < 3
48         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
49 #else
50         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
51 #endif  
52         m_fd_demux = ::open(filename, O_RDWR);
53         if (m_fd_demux < 0)
54                 eWarning("%s: %m", filename);
55 }
56         
57 int eDVBAudio::startPid(int pid, int type)
58 {       
59         if ((m_fd < 0) || (m_fd_demux < 0))
60                 return -1;
61         dmx_pes_filter_params pes;
62
63         pes.pid      = pid;
64         pes.input    = DMX_IN_FRONTEND;
65         pes.output   = DMX_OUT_DECODER;
66         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
67         pes.flags    = 0;
68         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
69         {
70                 eWarning("audio: DMX_SET_PES_FILTER: %m");
71                 return -errno;
72         }
73         if (::ioctl(m_fd_demux, DMX_START) < 0)
74         {
75                 eWarning("audio: DMX_START: %m");
76                 return -errno;
77         }
78         
79         int bypass = 0;
80         
81         switch (type)
82         {
83         case aMPEG:
84                 bypass = 1;
85                 break;
86         case aAC3:
87                 bypass = 0;
88                 break;
89                 /*
90         case aDTS:
91                 bypass = 2;
92                 break;
93                 */
94         }
95         
96         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
97                 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
98         
99         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
100                 eWarning("audio: AUDIO_PLAY: %m");
101         return 0;
102 }
103         
104 void eDVBAudio::stop()
105 {
106         if (::ioctl(m_fd, AUDIO_STOP) < 0)
107                 eWarning("audio: AUDIO_STOP: %m");
108 #if HAVE_DVB_API_VERSION > 2
109         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
110                 eWarning("audio: DMX_STOP: %m");
111 #endif
112 }
113         
114 #if HAVE_DVB_API_VERSION < 3
115 void eDVBAudio::stopPid()
116 {
117         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
118                 eWarning("audio: DMX_STOP: %m");
119 }
120 #endif
121
122 void eDVBAudio::flush()
123 {
124         if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
125                 eDebug("audio: AUDIO_CLEAR_BUFFER: %m");
126 }
127
128 void eDVBAudio::freeze()
129 {
130         if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
131                 eDebug("video: AUDIO_PAUSE: %m");
132 }
133
134 void eDVBAudio::unfreeze()
135 {
136         if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
137                 eDebug("video: AUDIO_CONTINUE: %m");
138 }
139
140 void eDVBAudio::setChannel(int channel)
141 {
142         int val = AUDIO_STEREO;
143         switch (channel)
144         {
145         case aMonoLeft: val = AUDIO_MONO_LEFT; break;
146         case aMonoRight: val = AUDIO_MONO_RIGHT; break;
147         default: break;
148         }
149         if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
150                 eDebug("video: AUDIO_CHANNEL_SELECT: %m");
151 }
152
153 int eDVBAudio::getPTS(pts_t &now)
154 {
155         return ::ioctl(m_fd, AUDIO_GET_PTS, &now);
156 }
157
158 eDVBAudio::~eDVBAudio()
159 {
160         if (m_fd >= 0)
161                 ::close(m_fd);
162         if (m_fd_demux >= 0)
163                 ::close(m_fd_demux);
164 }
165
166 DEFINE_REF(eDVBVideo);
167
168 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
169 {
170         char filename[128];
171 #if HAVE_DVB_API_VERSION < 3
172         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
173 #else
174         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
175 #endif
176         m_fd = ::open(filename, O_RDWR);
177         if (m_fd < 0)
178                 eWarning("%s: %m", filename);
179         
180         eDebug("Video Device: %s", filename);
181 #if HAVE_DVB_API_VERSION < 3
182         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
183 #else
184         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
185 #endif
186         m_fd_demux = ::open(filename, O_RDWR);
187         if (m_fd_demux < 0)
188                 eWarning("%s: %m", filename);
189         eDebug("demux device: %s", filename);
190 }
191
192 // not finally values i think.. !!
193 #define VIDEO_STREAMTYPE_MPEG2 0
194 #define VIDEO_STREAMTYPE_MPEG4_H264 1
195
196 int eDVBVideo::startPid(int pid, int type)
197 {       
198         if ((m_fd < 0) || (m_fd_demux < 0))
199                 return -1;
200         dmx_pes_filter_params pes;
201
202         if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE,
203                 type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2) < 0)
204                 eWarning("video: VIDEO_SET_STREAMTYPE: %m");
205
206         pes.pid      = pid;
207         pes.input    = DMX_IN_FRONTEND;
208         pes.output   = DMX_OUT_DECODER;
209         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
210         pes.flags    = 0;
211         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
212         {
213                 eWarning("video: DMX_SET_PES_FILTER: %m");
214                 return -errno;
215         }
216         if (::ioctl(m_fd_demux, DMX_START) < 0)
217         {
218                 eWarning("video: DMX_START: %m");
219                 return -errno;
220         }
221         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
222                 eWarning("video: VIDEO_PLAY: %m");
223         return 0;
224 }
225         
226 void eDVBVideo::stop()
227 {
228 #if HAVE_DVB_API_VERSION > 2
229         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
230                 eWarning("video: DMX_STOP: %m");
231 #endif
232         eDebug("VIDEO_STOP");
233         if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
234                 eWarning("video: VIDEO_STOP: %m");
235 }
236
237 #if HAVE_DVB_API_VERSION < 3
238 void eDVBVideo::stopPid()
239 {
240         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
241                 eWarning("video: DMX_STOP: %m");
242 }
243 #endif
244
245 void eDVBVideo::flush()
246 {
247         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
248                 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
249 }
250         
251 void eDVBVideo::freeze()
252 {
253         if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
254                 eDebug("video: VIDEO_FREEZE: %m");
255 }
256         
257 void eDVBVideo::unfreeze()
258 {
259         if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
260                 eDebug("video: VIDEO_CONTINUE: %m");
261 }
262         
263 int eDVBVideo::setSlowMotion(int repeat)
264 {
265         m_is_slow_motion = repeat;
266         return ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
267 }
268
269 int eDVBVideo::setFastForward(int skip)
270 {
271         m_is_fast_forward = skip;
272         return ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
273 }
274
275 int eDVBVideo::getPTS(pts_t &now)
276 {
277         return ::ioctl(m_fd, VIDEO_GET_PTS, &now);
278 }
279         
280 eDVBVideo::~eDVBVideo()
281 {
282         if (m_is_slow_motion)
283                 setSlowMotion(0);
284         if (m_is_fast_forward)
285                 setFastForward(0);
286         if (m_fd >= 0)
287                 ::close(m_fd);
288         if (m_fd_demux >= 0)
289                 ::close(m_fd_demux);
290 }
291
292 DEFINE_REF(eDVBPCR);
293
294 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
295 {
296         char filename[128];
297 #if HAVE_DVB_API_VERSION < 3
298         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
299 #else
300         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
301 #endif
302         m_fd_demux = ::open(filename, O_RDWR);
303         if (m_fd_demux < 0)
304                 eWarning("%s: %m", filename);
305 }
306
307 int eDVBPCR::startPid(int pid)
308 {
309         if (m_fd_demux < 0)
310                 return -1;
311         dmx_pes_filter_params pes;
312
313         pes.pid      = pid;
314         pes.input    = DMX_IN_FRONTEND;
315         pes.output   = DMX_OUT_DECODER;
316         pes.pes_type = DMX_PES_PCR;
317         pes.flags    = 0;
318         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
319         {
320                 eWarning("video: DMX_SET_PES_FILTER: %m");
321                 return -errno;
322         }
323         if (::ioctl(m_fd_demux, DMX_START) < 0)
324         {
325                 eWarning("video: DMX_START: %m");
326                 return -errno;
327         }
328         return 0;
329 }
330
331 void eDVBPCR::stop()
332 {
333         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
334                 eWarning("video: DMX_STOP: %m");
335 }
336
337 eDVBPCR::~eDVBPCR()
338 {
339         if (m_fd_demux >= 0)
340                 ::close(m_fd_demux);
341 }
342
343 DEFINE_REF(eDVBTText);
344
345 eDVBTText::eDVBTText(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 eDVBTText::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_TELETEXT;
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 eDVBTText::stop()
383 {
384         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
385                 eWarning("video: DMX_STOP: %m");
386 }
387
388 eDVBTText::~eDVBTText()
389 {
390         if (m_fd_demux >= 0)
391                 ::close(m_fd_demux);
392 }
393
394 DEFINE_REF(eTSMPEGDecoder);
395
396 int eTSMPEGDecoder::setState()
397 {
398         int res = 0;
399         
400         int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
401         int nott = noaudio; /* actually same conditions */
402         
403         if ((noaudio && m_audio) || (!m_audio && !noaudio))
404                 m_changed |= changeAudio;
405         
406         if ((nott && m_text) || (!m_text && !nott))
407                 m_changed |= changeText;
408
409         bool changed = !!m_changed;
410 #if HAVE_DVB_API_VERSION < 3
411         if (m_changed & changeAudio && m_audio)
412                 m_audio->stopPid();
413         if (m_changed & changeVideo && m_video)
414                 m_video->stopPid();
415         if (m_changed & changePCR && m_pcr)
416         {
417                 m_pcr->stop();
418                 m_pcr=0;
419         }
420         if (m_changed & changeAudio && m_audio)
421         {
422                 m_audio->stop();
423                 m_audio=0;
424         }
425         if (m_changed & changeVideo && m_video)
426         {
427                 m_video->stop();
428                 m_video=0;
429         }
430         if (m_changed & changePCR)
431         {
432                 m_pcr = new eDVBPCR(m_demux);
433                 if (m_pcr->startPid(m_pcrpid))
434                 {
435                         eWarning("pcr: startpid failed!");
436                         res = -1;
437                 }
438                 m_changed &= ~changePCR;
439         }
440         if (m_changed & changeVideo)
441         {
442                 m_video = new eDVBVideo(m_demux, m_decoder);
443                 if (m_video->startPid(m_vpid))
444                 {
445                         eWarning("video: startpid failed!");
446                         res = -1;
447                 }
448                 m_changed &= ~changeVideo;
449         }
450         if (m_changed & changeAudio)
451         {
452                 m_audio = new eDVBAudio(m_demux, m_decoder);
453                 if (m_audio->startPid(m_apid, m_atype))
454                 {
455                         eWarning("audio: startpid failed!");
456                         res = -1;
457                 }
458                 m_changed &= ~changeAudio;
459         }
460 #else
461         if (m_changed & changePCR)
462         {
463                 if (m_pcr)
464                         m_pcr->stop();
465                 m_pcr = 0;
466                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
467                 {
468                         m_pcr = new eDVBPCR(m_demux);
469                         if (m_pcr->startPid(m_pcrpid))
470                         {
471                                 eWarning("pcr: startpid failed!");
472                                 res = -1;
473                         }
474                 }
475                 m_changed &= ~changePCR;
476         }
477         if (m_changed & changeVideo)
478         {
479                 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
480                 if (m_video)
481                 {
482                         eDebug("STOP");
483                         m_video->stop();
484                 }
485                 m_video = 0;
486                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
487                 {
488                         eDebug("new video");
489                         m_video = new eDVBVideo(m_demux, m_decoder);
490                         if (m_video->startPid(m_vpid, m_vtype))
491                         {
492                                 eWarning("video: startpid failed!");
493                                 res = -1;
494                         }
495                 }
496                 m_changed &= ~changeVideo;
497         }
498         if (m_changed & changeAudio)
499         {
500                 if (m_audio)
501                         m_audio->stop();
502                 m_audio = 0;
503                 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
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                 }
512                 m_changed &= ~changeAudio;
513         }
514         if (m_changed & changeText)
515         {
516                 if (m_text)
517                         m_text->stop();
518                 m_text = 0;
519                 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
520                 {
521                         m_text = new eDVBTText(m_demux);
522                         if (m_text->startPid(m_textpid))
523                         {
524                                 eWarning("text: startpid failed!");
525                                 res = -1;
526                         }
527                 }
528                 m_changed &= ~changeText;
529         }
530 #endif
531         if (changed && !m_video && m_audio && m_radio_pic.length())
532                 showSinglePic(m_radio_pic.c_str());
533
534         return res;
535 }
536
537 int eTSMPEGDecoder::m_pcm_delay=-1,
538         eTSMPEGDecoder::m_ac3_delay=-1;
539
540 RESULT eTSMPEGDecoder::setPCMDelay(int delay)
541 {
542         if (m_decoder == 0 && delay != m_pcm_delay )
543         {
544                 FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
545                 if (fp)
546                 {
547                         fprintf(fp, "%x", delay*90);
548                         fclose(fp);
549                         m_pcm_delay = delay;
550                 }
551         }
552 }
553
554 RESULT eTSMPEGDecoder::setAC3Delay(int delay)
555 {
556         if ( m_decoder == 0 && delay != m_ac3_delay )
557         {
558                 FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
559                 if (fp)
560                 {
561                         fprintf(fp, "%x", delay*90);
562                         fclose(fp);
563                         m_ac3_delay = delay;
564                 }
565         }
566 }
567
568 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0), m_decoder(decoder)
569 {
570         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event);
571         m_is_ff = m_is_sm = m_is_trickmode = 0;
572 }
573
574 eTSMPEGDecoder::~eTSMPEGDecoder()
575 {
576         m_vpid = m_apid = m_pcrpid = pidNone;
577         m_changed = -1;
578         setState();
579 }
580
581 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
582 {
583         if (m_vpid != vpid)
584         {
585                 m_changed |= changeVideo;
586                 m_vpid = vpid;
587                 m_vtype = type;
588         }
589         return 0;
590 }
591
592 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
593 {
594         if ((m_apid != apid) || (m_atype != type))
595         {
596                 m_changed |= changeAudio;
597                 m_atype = type;
598                 m_apid = apid;
599         }
600         return 0;
601 }
602
603 int eTSMPEGDecoder::m_audio_channel = -1;
604
605 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
606 {
607         if (channel == -1)
608                 channel = ac_stereo;
609         if (m_decoder == 0 && m_audio_channel != channel)
610         {
611                 if (m_audio)
612                 {
613                         m_audio->setChannel(channel);
614                         m_audio_channel=channel;
615                 }
616                 else
617                         eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
618         }
619         return 0;
620 }
621
622 int eTSMPEGDecoder::getAudioChannel()
623 {
624         return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
625 }
626
627 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
628 {
629         if (m_pcrpid != pcrpid)
630         {
631                 m_changed |= changePCR;
632                 m_pcrpid = pcrpid;
633         }
634         return 0;
635 }
636
637 RESULT eTSMPEGDecoder::setTextPID(int textpid)
638 {
639         if (m_textpid != textpid)
640         {
641                 m_changed |= changeText;
642                 m_textpid = textpid;
643         }
644         return 0;
645 }
646
647 RESULT eTSMPEGDecoder::setSyncMaster(int who)
648 {
649         return -1;
650 }
651
652 RESULT eTSMPEGDecoder::start()
653 {
654         return setState();
655 }
656
657 RESULT eTSMPEGDecoder::freeze(int cont)
658 {
659         if (m_video)
660                 m_video->freeze();
661
662         if (m_audio)
663                 m_audio->freeze();
664         
665         return 0;
666 }
667
668 RESULT eTSMPEGDecoder::unfreeze()
669 {
670         if (m_video)
671                 m_video->unfreeze();
672
673         if (m_audio)
674                 m_audio->unfreeze();
675         
676         return 0;
677 }
678
679 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
680 {
681         return -1;
682 }
683
684 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
685 {
686         return -1;
687 }
688
689 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
690 {
691         m_is_ff = frames_to_skip != 0;
692         
693         setState();
694         
695         if (m_video)
696                 return m_video->setFastForward(frames_to_skip);
697         else
698                 return -1;
699 }
700
701 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
702 {
703         m_is_sm = repeat != 0;
704         
705         setState();
706         
707         if (m_video)
708                 return m_video->setSlowMotion(repeat);
709         else
710                 return -1;
711 }
712
713 RESULT eTSMPEGDecoder::setZoom(int what)
714 {
715         return -1;
716 }
717
718 RESULT eTSMPEGDecoder::flush()
719 {
720         if (m_audio)
721                 m_audio->flush();
722         if (m_video)
723                 m_video->flush();
724         return 0;
725 }
726
727 void eTSMPEGDecoder::demux_event(int event)
728 {
729         switch (event)
730         {
731         case eDVBDemux::evtFlush:
732                 flush();
733                 break;
734         default:
735                 break;
736         }
737 }
738
739 RESULT eTSMPEGDecoder::setTrickmode(int what)
740 {
741         m_is_trickmode = what;
742         setState();
743         return 0;
744 }
745
746 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
747 {
748         if (what == 0) /* auto */
749                 what = m_video ? 1 : 2;
750
751         if (what == 1) /* video */
752         {
753                 if (m_video)
754                         return m_video->getPTS(pts);
755                 else
756                         return -1;
757         }
758
759         if (what == 2) /* audio */
760         {
761                 if (m_audio)
762                         return m_audio->getPTS(pts);
763                 else
764                         return -1;
765         }
766
767         return -1;
768 }
769
770 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
771 {
772         m_radio_pic = filename;
773 }
774
775 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
776 {
777         if (m_decoder == 0)
778         {
779                 FILE *f = fopen(filename, "r");
780                 if (f)
781                 {
782                         int vfd = open("/dev/dvb/adapter0/video0", O_RDWR);
783                         if (vfd > 0)
784                         {
785                                 fseek(f, 0, SEEK_END);
786                                 int length = ftell(f);
787                                 unsigned char *buffer = new unsigned char[length*3+9];
788                                 if (ioctl(vfd, VIDEO_FAST_FORWARD, 1) < 0)
789                                         eDebug("VIDEO_FAST_FORWARD failed (%m)");
790                                 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
791                                         eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
792                                 if (ioctl(vfd, VIDEO_PLAY) < 0)
793                                         eDebug("VIDEO_PLAY failed (%m)");
794                                 int cnt=0;
795                                 int pos=0;
796                                 while(cnt<3)
797                                 {
798                                         int rd;
799                                         fseek(f, 0, SEEK_SET);
800                                         while(1)
801                                         {
802                                                 if (!cnt)
803                                                 {
804                                                         buffer[pos++]=0;
805                                                         buffer[pos++]=0;
806                                                         buffer[pos++]=1;
807                                                         buffer[pos++]=0xE0;
808                                                         buffer[pos++]=(length*3)>>8;
809                                                         buffer[pos++]=(length*3)&0xFF;
810                                                         buffer[pos++]=0x80;
811                                                         buffer[pos++]=0;
812                                                         buffer[pos++]=0;
813                                                 }
814                                                 rd = fread(buffer+pos, 1, length, f);
815                                                 if (rd > 0)
816                                                         pos += rd;
817                                                 else
818                                                         break;
819                                         }
820                                         ++cnt;
821                                 }
822                                 write(vfd, buffer, pos);
823                                 usleep(75000);  // i dont like this.. but i dont have a better solution :(
824                                 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
825                                         eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
826                                 if (ioctl(vfd, VIDEO_FAST_FORWARD, 0) < 0)
827                                         eDebug("VIDEO_FAST_FORWARD failed (%m)");
828                                 close(vfd);
829                                 delete [] buffer;
830                         }
831                         fclose(f);
832                 }
833                 else
834                 {
835                         eDebug("couldnt open %s", filename);
836                         return -1;
837                 }
838         }
839         else
840         {
841                 eDebug("only show single pics on first decoder");
842                 return -1;
843         }
844         return 0;
845 }