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