Merge branch 'bug_474_fix_multicontent_clear'
[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_PCR0 DMX_PES_PCR
16 #define DMX_PES_TELETEXT0 DMX_PES_TELETEXT
17 #define DMX_PES_VIDEO1 DMX_PES_VIDEO
18 #define DMX_PES_AUDIO1 DMX_PES_AUDIO
19 #define DMX_PES_PCR1 DMX_PES_PCR
20 #define DMX_PES_TELETEXT1 DMX_PES_TELETEXT
21 #include <ost/dmx.h>
22 #include <ost/video.h>
23 #include <ost/audio.h>
24 #else
25 #include <linux/dvb/audio.h>
26 #include <linux/dvb/video.h>
27 #include <linux/dvb/dmx.h>
28 #endif
29
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <errno.h>
36
37         /* these are quite new... */
38 #ifndef AUDIO_GET_PTS
39 #define AUDIO_GET_PTS              _IOR('o', 19, __u64)
40 #define VIDEO_GET_PTS              _IOR('o', 57, __u64)
41 #endif
42
43 DEFINE_REF(eDVBAudio);
44
45 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev)
46         :m_demux(demux), m_dev(dev)
47 {
48         char filename[128];
49 #if HAVE_DVB_API_VERSION < 3
50         sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);
51 #else
52         sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
53 #endif
54         m_fd = ::open(filename, O_RDWR);
55         if (m_fd < 0)
56                 eWarning("%s: %m", filename);
57 #if HAVE_DVB_API_VERSION < 3
58         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
59 #else
60         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
61 #endif
62         m_fd_demux = ::open(filename, O_RDWR);
63         if (m_fd_demux < 0)
64                 eWarning("%s: %m", filename);
65 }
66
67 #if HAVE_DVB_API_VERSION < 3
68 int eDVBAudio::setPid(int pid, int type)
69 {
70         if ((m_fd < 0) || (m_fd_demux < 0))
71                 return -1;
72
73         int bypass = 0;
74
75         switch (type)
76         {
77         case aMPEG:
78                 bypass = 1;
79                 break;
80         case aAC3:
81                 bypass = 0;
82                 break;
83                 /*
84         case aDTS:
85                 bypass = 2;
86                 break;
87                 */
88         }
89
90         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
91                 eDebug("failed (%m)");
92
93         dmx_pes_filter_params pes;
94
95         pes.pid      = pid;
96         pes.input    = DMX_IN_FRONTEND;
97         pes.output   = DMX_OUT_DECODER;
98         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
99         pes.flags    = 0;
100         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid);
101         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
102         {
103                 eDebug("failed (%m)");
104                 return -errno;
105         }
106         eDebug("ok");
107
108         return 0;
109 }
110
111 int eDVBAudio::startPid()
112 {
113         eDebugNoNewLine("DEMUX_START - audio - ");
114         if (::ioctl(m_fd_demux, DMX_START) < 0)
115         {
116                 eDebug("failed (%m)");
117                 return -errno;
118         }
119         eDebug("ok");
120         return 0;
121 }
122
123 int eDVBAudio::start()
124 {
125         eDebugNoNewLine("AUDIO_PLAY - ");
126         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
127         {
128                 eDebug("failed (%m)");
129                 return -errno;
130         }
131         eDebug("ok");
132         return 0;
133 }
134
135 int eDVBAudio::stopPid()
136 {
137         eDebugNoNewLine("DEMUX_STOP - audio - ");
138         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
139         {
140                 eDebug("failed (%m)");
141                 return -errno;
142         }
143         eDebug("ok");
144         return 0;
145 }
146
147 int eDVBAudio::setAVSync(int val)
148 {
149         eDebugNoNewLine("AUDIO_SET_AV_SYNC - ");
150         if (::ioctl(m_fd, AUDIO_SET_AV_SYNC, val) < 0)
151         {
152                 eDebug("failed (%m)");
153                 return -errno;
154         }
155         eDebug("ok");
156         return 0;
157 }
158 #else
159 int eDVBAudio::startPid(int pid, int type)
160 {
161         if ((m_fd < 0) || (m_fd_demux < 0))
162                 return -1;
163         dmx_pes_filter_params pes;
164
165         pes.pid      = pid;
166         pes.input    = DMX_IN_FRONTEND;
167         pes.output   = DMX_OUT_DECODER;
168         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
169         pes.flags    = 0;
170         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid);
171         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
172         {
173                 eDebug("failed (%m)");
174                 return -errno;
175         }
176         eDebug("ok");
177         eDebugNoNewLine("DEMUX_START - audio - ");
178         if (::ioctl(m_fd_demux, DMX_START) < 0)
179         {
180                 eDebug("failed (%m)");
181                 return -errno;
182         }
183         eDebug("ok");
184         int bypass = 0;
185
186         switch (type)
187         {
188         case aMPEG:
189                 bypass = 1;
190                 break;
191         case aAC3:
192                 bypass = 0;
193                 break;
194         case aDTS:
195                 bypass = 2;
196                 break;
197         case aAAC:
198                 bypass = 8;
199                 break;
200         case aAACHE:
201                 bypass = 9;
202                 break;
203         case aLPCM:
204                 bypass = 6;
205                 break;
206         }
207
208         eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass);
209         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
210                 eDebug("failed (%m)");
211         else
212                 eDebug("ok");
213         freeze();  // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState
214         eDebugNoNewLine("AUDIO_PLAY - ");
215         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
216                 eDebug("failed (%m)");
217         else
218                 eDebug("ok");
219         return 0;
220 }
221 #endif
222
223 void eDVBAudio::stop()
224 {
225         eDebugNoNewLine("AUDIO_STOP - ");
226         if (::ioctl(m_fd, AUDIO_STOP) < 0)
227                 eDebug("failed (%m)");
228         else
229                 eDebug("ok");
230 #if HAVE_DVB_API_VERSION > 2
231         eDebugNoNewLine("DEMUX_STOP - audio - ");
232         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
233                 eDebug("failed (%m)");
234         else
235                 eDebug("ok");
236 #endif
237 }
238
239 void eDVBAudio::flush()
240 {
241         eDebugNoNewLine("AUDIO_CLEAR_BUFFER - ");
242         if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
243                 eDebug("failed (%m)");
244         else
245                 eDebug("ok");
246 }
247
248 void eDVBAudio::freeze()
249 {
250         eDebugNoNewLine("AUDIO_PAUSE - ");
251         if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
252                 eDebug("failed (%m)");
253         else
254                 eDebug("ok");
255 }
256
257 void eDVBAudio::unfreeze()
258 {
259         eDebugNoNewLine("AUDIO_CONTINUE - ");
260         if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
261                 eDebug("failed (%m)");
262         else
263                 eDebug("ok");
264 }
265
266 void eDVBAudio::setChannel(int channel)
267 {
268         int val = AUDIO_STEREO;
269         switch (channel)
270         {
271         case aMonoLeft: val = AUDIO_MONO_LEFT; break;
272         case aMonoRight: val = AUDIO_MONO_RIGHT; break;
273         default: break;
274         }
275         eDebugNoNewLine("AUDIO_CHANNEL_SELECT(%d) - ", val);
276         if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
277                 eDebug("failed (%m)");
278         else
279                 eDebug("ok");
280 }
281
282 int eDVBAudio::getPTS(pts_t &now)
283 {
284         if (::ioctl(m_fd, AUDIO_GET_PTS, &now) < 0)
285                 eDebug("AUDIO_GET_PTS failed (%m)");
286         return 0;
287 }
288
289 eDVBAudio::~eDVBAudio()
290 {
291         unfreeze();  // why unfreeze here... but not unfreeze video in ~eDVBVideo ?!?
292         if (m_fd >= 0)
293                 ::close(m_fd);
294         if (m_fd_demux >= 0)
295                 ::close(m_fd_demux);
296 }
297
298 DEFINE_REF(eDVBVideo);
299
300 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev)
301         : m_demux(demux), m_dev(dev),
302         m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1)
303 {
304         char filename[128];
305 #if HAVE_DVB_API_VERSION < 3
306         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
307         m_fd_video = ::open("/dev/video", O_RDWR);
308         if (m_fd_video < 0)
309                 eWarning("/dev/video: %m");
310 #else
311         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
312 #endif
313         m_fd = ::open(filename, O_RDWR);
314         if (m_fd < 0)
315                 eWarning("%s: %m", filename);
316         else
317         {
318                 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Priority);
319                 CONNECT(m_sn->activated, eDVBVideo::video_event);
320         }
321         eDebug("Video Device: %s", filename);
322 #if HAVE_DVB_API_VERSION < 3
323         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
324 #else
325         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
326 #endif
327         m_fd_demux = ::open(filename, O_RDWR);
328         if (m_fd_demux < 0)
329                 eWarning("%s: %m", filename);
330         eDebug("demux device: %s", filename);
331 }
332
333 // not finally values i think.. !!
334 #define VIDEO_STREAMTYPE_MPEG2 0
335 #define VIDEO_STREAMTYPE_MPEG4_H264 1
336 #define VIDEO_STREAMTYPE_VC1 3
337 #define VIDEO_STREAMTYPE_MPEG4_Part2 4
338 #define VIDEO_STREAMTYPE_VC1_SM 5
339 #define VIDEO_STREAMTYPE_MPEG1 6
340
341 #if HAVE_DVB_API_VERSION < 3
342 int eDVBVideo::setPid(int pid)
343 {
344         if ((m_fd < 0) || (m_fd_demux < 0))
345                 return -1;
346         dmx_pes_filter_params pes;
347
348         pes.pid      = pid;
349         pes.input    = DMX_IN_FRONTEND;
350         pes.output   = DMX_OUT_DECODER;
351         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
352         pes.flags    = 0;
353         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid);
354         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
355         {
356                 eDebug("failed (%m)");
357                 return -errno;
358         }
359         eDebug("ok");
360         return 0;
361 }
362
363 int eDVBVideo::startPid()
364 {
365         eDebugNoNewLine("DEMUX_START - video - ");
366         if (::ioctl(m_fd_demux, DMX_START) < 0)
367         {
368                 eDebug("failed (%m)");
369                 return -errno;
370         }
371         eDebug("ok");
372         return 0;
373 }
374
375 int eDVBVideo::start()
376 {
377         eDebugNoNewLine("VIDEO_PLAY - ");
378         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
379         {
380                 eDebug("failed (%m)");
381                 return -errno;
382         }
383         eDebug("ok");
384         return 0;
385 }
386
387 int eDVBVideo::stopPid()
388 {
389         eDebugNoNewLine("DEMUX_STOP - video - ");
390         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
391         {
392                 eDebug("failed (%m)");
393                 return -errno;
394         }
395         eDebug("ok");
396         return 0;
397 }
398 #else
399 int eDVBVideo::startPid(int pid, int type)
400 {
401         int streamtype = VIDEO_STREAMTYPE_MPEG2;
402
403         if ((m_fd < 0) || (m_fd_demux < 0))
404                 return -1;
405         dmx_pes_filter_params pes;
406
407         switch(type)
408         {
409         default:
410         case MPEG2:
411                 break;
412         case MPEG4_H264:
413                 streamtype = VIDEO_STREAMTYPE_MPEG4_H264;
414                 break;
415         case MPEG1:
416                 streamtype = VIDEO_STREAMTYPE_MPEG1;
417                 break;
418         case MPEG4_Part2:
419                 streamtype = VIDEO_STREAMTYPE_MPEG4_Part2;
420                 break;
421         case VC1:
422                 streamtype = VIDEO_STREAMTYPE_VC1;
423                 break;
424         case VC1_SM:
425                 streamtype = VIDEO_STREAMTYPE_VC1_SM;
426                 break;
427         }
428
429         eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype);
430         if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0)
431                 eDebug("failed (%m)");
432         else
433                 eDebug("ok");
434
435         pes.pid      = pid;
436         pes.input    = DMX_IN_FRONTEND;
437         pes.output   = DMX_OUT_DECODER;
438         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
439         pes.flags    = 0;
440         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid);
441         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
442         {
443                 eDebug("failed (%m)");
444                 return -errno;
445         }
446         eDebug("ok");
447         eDebugNoNewLine("DEMUX_START - video - ");
448         if (::ioctl(m_fd_demux, DMX_START) < 0)
449         {
450                 eDebug("failed (%m)");
451                 return -errno;
452         }
453         eDebug("ok");
454         freeze();  // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState
455         eDebugNoNewLine("VIDEO_PLAY - ");
456         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
457                 eDebug("failed (%m)");
458         else
459                 eDebug("ok");
460         return 0;
461 }
462 #endif
463
464 void eDVBVideo::stop()
465 {
466 #if HAVE_DVB_API_VERSION > 2
467         eDebugNoNewLine("DEMUX_STOP - video - ");
468         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
469                 eDebug("failed (%m)");
470         else
471                 eDebug("ok");
472 #endif
473         eDebugNoNewLine("VIDEO_STOP - ");
474         if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
475                 eDebug("failed (%m)");
476         else
477                 eDebug("ok");
478 }
479
480 void eDVBVideo::flush()
481 {
482         eDebugNoNewLine("VIDEO_CLEAR_BUFFER - ");
483         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
484                 eDebug("failed (%m)");
485         else
486                 eDebug("ok");
487 }
488
489 void eDVBVideo::freeze()
490 {
491         eDebugNoNewLine("VIDEO_FREEZE - ");
492         if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
493                 eDebug("failed (%m)");
494         else
495                 eDebug("ok");
496 }
497
498 void eDVBVideo::unfreeze()
499 {
500         eDebugNoNewLine("VIDEO_CONTINUE - ");
501         if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
502                 eDebug("failed (%m)");
503         else
504                 eDebug("ok");
505 }
506
507 int eDVBVideo::setSlowMotion(int repeat)
508 {
509         eDebugNoNewLine("VIDEO_SLOWMOTION(%d) - ", repeat);
510         int ret = ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
511         if (ret < 0)
512                 eDebug("failed(%m)");
513         else
514                 eDebug("ok");
515         return ret;
516 }
517
518 int eDVBVideo::setFastForward(int skip)
519 {
520         eDebugNoNewLine("VIDEO_FAST_FORWARD(%d) - ", skip);
521         int ret = ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
522         if (ret < 0)
523                 eDebug("failed(%m)");
524         else
525                 eDebug("ok");
526         return ret;
527 }
528
529 int eDVBVideo::getPTS(pts_t &now)
530 {
531 #if HAVE_DVB_API_VERSION < 3
532         #define VIDEO_GET_PTS_OLD           _IOR('o', 1, unsigned int*)
533         unsigned int pts;
534         int ret = ::ioctl(m_fd_video, VIDEO_GET_PTS_OLD, &pts);
535         now = pts;
536         now *= 2;
537 #else
538         int ret = ::ioctl(m_fd, VIDEO_GET_PTS, &now);
539 #endif
540         if (ret < 0)
541                 eDebug("VIDEO_GET_PTS failed(%m)");
542         return ret;
543 }
544
545 eDVBVideo::~eDVBVideo()
546 {
547         if (m_fd >= 0)
548                 ::close(m_fd);
549         if (m_fd_demux >= 0)
550                 ::close(m_fd_demux);
551 #if HAVE_DVB_API_VERSION < 3
552         if (m_fd_video >= 0)
553                 ::close(m_fd_video);
554 #endif
555 }
556
557 void eDVBVideo::video_event(int)
558 {
559 #if HAVE_DVB_API_VERSION >= 3
560         struct video_event evt;
561         eDebugNoNewLine("VIDEO_GET_EVENT - ");
562         if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
563                 eDebug("failed (%m)");
564         else
565         {
566                 eDebug("ok");
567                 if (evt.type == VIDEO_EVENT_SIZE_CHANGED)
568                 {
569                         struct iTSMPEGDecoder::videoEvent event;
570                         event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
571                         m_aspect = event.aspect = evt.u.size.aspect_ratio == 0 ? 2 : 3;  // convert dvb api to etsi
572                         m_height = event.height = evt.u.size.h;
573                         m_width = event.width = evt.u.size.w;
574                         /* emit */ m_event(event);
575                 }
576                 else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED)
577                 {
578                         struct iTSMPEGDecoder::videoEvent event;
579                         event.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged;
580                         m_framerate = event.framerate = evt.u.frame_rate;
581                         /* emit */ m_event(event);
582                 }
583                 else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/)
584                 {
585                         struct iTSMPEGDecoder::videoEvent event;
586                         event.type = iTSMPEGDecoder::videoEvent::eventProgressiveChanged;
587                         m_progressive = event.progressive = evt.u.frame_rate;
588                         /* emit */ m_event(event);
589                 }
590                 else
591                         eDebug("unhandled DVBAPI Video Event %d", evt.type);
592         }
593 #else
594 #warning "FIXMEE!! Video Events not implemented for old api"
595 #endif
596 }
597
598 RESULT eDVBVideo::connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEvent> &event, ePtr<eConnection> &conn)
599 {
600         conn = new eConnection(this, m_event.connect(event));
601         return 0;
602 }
603
604 static int readMpegProc(const char *str, int decoder)
605 {
606         int val = -1;
607         char tmp[64];
608         sprintf(tmp, "/proc/stb/vmpeg/%d/%s", decoder, str);
609         FILE *f = fopen(tmp, "r");
610         if (f)
611         {
612                 fscanf(f, "%x", &val);
613                 fclose(f);
614         }
615         return val;
616 }
617
618 static int readApiSize(int fd, int &xres, int &yres, int &aspect)
619 {
620 #if HAVE_DVB_API_VERSION >= 3
621         video_size_t size;
622         if (!::ioctl(fd, VIDEO_GET_SIZE, &size))
623         {
624                 xres = size.w;
625                 yres = size.h;
626                 aspect = size.aspect_ratio == 0 ? 2 : 3;  // convert dvb api to etsi
627                 return 0;
628         }
629 //      eDebug("VIDEO_GET_SIZE failed (%m)");
630 #endif
631         return -1;
632 }
633
634 static int readApiFrameRate(int fd, int &framerate)
635 {
636 #if HAVE_DVB_API_VERSION >= 3
637         unsigned int frate;
638         if (!::ioctl(fd, VIDEO_GET_FRAME_RATE, &frate))
639         {
640                 framerate = frate;      
641                 return 0;
642         }
643 //      eDebug("VIDEO_GET_FRAME_RATE failed (%m)");
644 #endif
645         return -1;
646 }
647
648 int eDVBVideo::getWidth()
649 {
650         if (m_width == -1)
651                 readApiSize(m_fd, m_width, m_height, m_aspect);
652         if (m_width == -1)
653                 m_width = readMpegProc("xres", m_dev);
654         return m_width;
655 }
656
657 int eDVBVideo::getHeight()
658 {
659         if (m_height == -1)
660                 readApiSize(m_fd, m_width, m_height, m_aspect);
661         if (m_height == -1)
662                 m_height = readMpegProc("yres", m_dev);
663         return m_height;
664 }
665
666 int eDVBVideo::getAspect()
667 {
668         if (m_aspect == -1)
669                 readApiSize(m_fd, m_width, m_height, m_aspect);
670         if (m_aspect == -1)
671                 m_aspect = readMpegProc("aspect", m_dev);
672         return m_aspect;
673 }
674
675 int eDVBVideo::getProgressive()
676 {
677         if (m_progressive == -1)
678                 m_progressive = readMpegProc("progressive", m_dev);
679         return m_progressive;
680 }
681
682 int eDVBVideo::getFrameRate()
683 {
684         if (m_framerate == -1)
685                 readApiFrameRate(m_fd, m_framerate);
686         if (m_framerate == -1)
687                 m_framerate = readMpegProc("framerate", m_dev);
688         return m_framerate;
689 }
690
691 DEFINE_REF(eDVBPCR);
692
693 eDVBPCR::eDVBPCR(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
694 {
695         char filename[128];
696 #if HAVE_DVB_API_VERSION < 3
697         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
698 #else
699         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
700 #endif
701         m_fd_demux = ::open(filename, O_RDWR);
702         if (m_fd_demux < 0)
703                 eWarning("%s: %m", filename);
704 }
705
706 #if HAVE_DVB_API_VERSION < 3
707 int eDVBPCR::setPid(int pid)
708 {
709         if (m_fd_demux < 0)
710                 return -1;
711         dmx_pes_filter_params pes;
712
713         pes.pid      = pid;
714         pes.input    = DMX_IN_FRONTEND;
715         pes.output   = DMX_OUT_DECODER;
716         pes.pes_type = DMX_PES_PCR;
717         pes.flags    = 0;
718
719         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
720         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
721         {
722                 eDebug("failed (%m)");
723                 return -errno;
724         }
725         eDebug("ok");
726         return 0;
727 }
728
729 int eDVBPCR::startPid()
730 {
731         if (m_fd_demux < 0)
732                 return -1;
733         eDebugNoNewLine("DEMUX_START - pcr - ");
734         if (::ioctl(m_fd_demux, DMX_START) < 0)
735         {
736                 eDebug("failed (%m)");
737                 return -errno;
738         }
739         eDebug("ok");
740         return 0;
741 }
742 #else
743 int eDVBPCR::startPid(int pid)
744 {
745         if (m_fd_demux < 0)
746                 return -1;
747         dmx_pes_filter_params pes;
748
749         pes.pid      = pid;
750         pes.input    = DMX_IN_FRONTEND;
751         pes.output   = DMX_OUT_DECODER;
752         pes.pes_type = m_dev ? DMX_PES_PCR1 : DMX_PES_PCR0; /* FIXME */
753         pes.flags    = 0;
754         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid);
755         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
756         {
757                 eDebug("failed (%m)");
758                 return -errno;
759         }
760         eDebug("ok");
761         eDebugNoNewLine("DEMUX_START - pcr - ");
762         if (::ioctl(m_fd_demux, DMX_START) < 0)
763         {
764                 eDebug("failed (%m)");
765                 return -errno;
766         }
767         eDebug("ok");
768         return 0;
769 }
770 #endif
771
772 void eDVBPCR::stop()
773 {
774         eDebugNoNewLine("DEMUX_STOP - pcr - ");
775         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
776                 eDebug("failed(%m)");
777         else
778                 eDebug("ok");
779 }
780
781 eDVBPCR::~eDVBPCR()
782 {
783         if (m_fd_demux >= 0)
784                 ::close(m_fd_demux);
785 }
786
787 DEFINE_REF(eDVBTText);
788
789 eDVBTText::eDVBTText(eDVBDemux *demux, int dev)
790     :m_demux(demux), m_dev(dev)
791 {
792         char filename[128];
793 #if HAVE_DVB_API_VERSION < 3
794         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
795 #else
796         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
797 #endif
798         m_fd_demux = ::open(filename, O_RDWR);
799         if (m_fd_demux < 0)
800                 eWarning("%s: %m", filename);
801 }
802
803 int eDVBTText::startPid(int pid)
804 {
805         if (m_fd_demux < 0)
806                 return -1;
807         dmx_pes_filter_params pes;
808
809         pes.pid      = pid;
810         pes.input    = DMX_IN_FRONTEND;
811         pes.output   = DMX_OUT_DECODER;
812         pes.pes_type = m_dev ? DMX_PES_TELETEXT1 : DMX_PES_TELETEXT0; // FIXME
813         pes.flags    = 0;
814
815         eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - ttx - ", pid);
816         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
817         {
818                 eDebug("failed(%m)");
819                 return -errno;
820         }
821         eDebug("ok");
822         eDebugNoNewLine("DEMUX_START - ttx - ");
823         if (::ioctl(m_fd_demux, DMX_START) < 0)
824         {
825                 eDebug("failed(%m)");
826                 return -errno;
827         }
828         eDebug("ok");
829         return 0;
830 }
831
832 void eDVBTText::stop()
833 {
834         eDebugNoNewLine("DEMUX_STOP - ttx - ");
835         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
836                 eDebug("failed(%m)");
837         else
838                 eDebug("ok");
839 }
840
841 eDVBTText::~eDVBTText()
842 {
843         if (m_fd_demux >= 0)
844                 ::close(m_fd_demux);
845 }
846
847 DEFINE_REF(eTSMPEGDecoder);
848
849 int eTSMPEGDecoder::setState()
850 {
851         int res = 0;
852
853         int noaudio = (m_state != statePlay) && (m_state != statePause);
854         int nott = noaudio; /* actually same conditions */
855
856         if ((noaudio && m_audio) || (!m_audio && !noaudio))
857                 m_changed |= changeAudio | changeState;
858
859         if ((nott && m_text) || (!m_text && !nott))
860                 m_changed |= changeText | changeState;
861
862         const char *decoder_states[] = {"stop", "pause", "play", "decoderfastforward", "trickmode", "slowmotion"};
863         eDebug("decoder state: %s, vpid=%d, apid=%d", decoder_states[m_state], m_vpid, m_apid);
864
865         int changed = m_changed;
866 #if HAVE_DVB_API_VERSION < 3
867         bool checkAVSync = m_changed & (changeAudio|changeVideo|changePCR);
868         if (m_changed & changeAudio && m_audio)
869                 m_audio->stopPid();
870         if (m_changed & changeVideo && m_video)
871                 m_video->stopPid();
872         if (m_changed & changePCR && m_pcr)
873         {
874                 m_pcr->stop();
875                 m_pcr=0;
876                 if (!(m_pcrpid >= 0 && m_pcrpid < 0x1ff))
877                         m_changed &= ~changePCR;
878         }
879         if (m_changed & changeAudio && m_audio)
880         {
881                 m_audio->stop();
882                 m_audio=0;
883                 if (!(m_apid >= 0 && m_apid < 0x1ff))
884                         m_changed &= ~changeAudio;
885         }
886         if (m_changed & changeVideo && m_video)
887         {
888                 m_video->stop();
889                 m_video=0;
890                 m_video_event_conn=0;
891                 if (!(m_vpid >= 0 && m_vpid < 0x1ff))
892                         m_changed &= ~changeVideo;
893         }
894         if (m_changed & changeVideo)
895         {
896                 m_video = new eDVBVideo(m_demux, m_decoder);
897                 m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
898                 if (m_video->setPid(m_vpid))
899                         res -1;
900         }
901         if (m_changed & changePCR)
902         {
903                 m_pcr = new eDVBPCR(m_demux, m_decoder);
904                 if (m_pcr->setPid(m_pcrpid))
905                         res = -1;
906         }
907         if (m_changed & changeAudio)
908         {
909                 m_audio = new eDVBAudio(m_demux, m_decoder);
910                 if (m_audio->setPid(m_apid, m_atype))
911                         res = -1;
912         }
913         if (m_changed & changePCR)
914         {
915                 if (m_pcr->startPid())
916                         res = -1;
917                 m_changed &= ~changePCR;
918         }
919         else if (checkAVSync && m_audio && m_video)
920         {
921                 if (m_audio->setAVSync(1))
922                         res = -1;
923         }
924         if (m_changed & changeVideo)
925         {
926                 if (m_video->startPid() || m_video->start())
927                         res = -1;
928                 m_changed &= ~changeVideo;
929         }
930         if (m_changed & changeAudio)
931         {
932                 if (m_audio->start() || m_audio->startPid())
933                         res = -1;
934                 m_changed &= ~changeAudio;
935         }
936 #else
937         if (m_changed & changePCR)
938         {
939                 if (m_pcr)
940                         m_pcr->stop();
941                 m_pcr = 0;
942         }
943         if (m_changed & changeVideo)
944         {
945                 if (m_video)
946                 {
947                         m_video->stop();
948                         m_video = 0;
949                         m_video_event_conn = 0;
950                 }
951         }
952         if (m_changed & changeAudio)
953         {
954                 if (m_audio)
955                         m_audio->stop();
956                 m_audio = 0;
957         }
958         if (m_changed & changeText)
959         {
960                 if (m_text)
961                         m_text->stop();
962                 m_text = 0;
963         }
964         if (m_changed & changePCR)
965         {
966                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
967                 {
968                         m_pcr = new eDVBPCR(m_demux, m_decoder);
969                         if (m_pcr->startPid(m_pcrpid))
970                                 res = -1;
971                 }
972                 m_changed &= ~changePCR;
973         }
974         if (m_changed & changeAudio)
975         {
976                 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
977                 {
978                         m_audio = new eDVBAudio(m_demux, m_decoder);
979                         if (m_audio->startPid(m_apid, m_atype))
980                                 res = -1;
981                 }
982                 m_changed &= ~changeAudio;
983         }
984         if (m_changed & changeVideo)
985         {
986                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
987                 {
988                         m_video = new eDVBVideo(m_demux, m_decoder);
989                         m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
990                         if (m_video->startPid(m_vpid, m_vtype))
991                                 res = -1;
992                 }
993                 m_changed &= ~changeVideo;
994         }
995         if (m_changed & changeText)
996         {
997                 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
998                 {
999                         m_text = new eDVBTText(m_demux, m_decoder);
1000                         if (m_text->startPid(m_textpid))
1001                                 res = -1;
1002                 }
1003                 m_changed &= ~changeText;
1004         }
1005 #endif
1006
1007         if (changed & (changeState|changeVideo|changeAudio))
1008         {
1009                                         /* play, slowmotion, fast-forward */
1010                 int state_table[6][4] = 
1011                         {
1012                                 /* [stateStop] =                 */ {0, 0, 0},
1013                                 /* [statePause] =                */ {0, 0, 0},
1014                                 /* [statePlay] =                 */ {1, 0, 0},
1015                                 /* [stateDecoderFastForward] =   */ {1, 0, m_ff_sm_ratio},
1016                                 /* [stateHighspeedFastForward] = */ {1, 0, 1},
1017                                 /* [stateSlowMotion] =           */ {1, m_ff_sm_ratio, 0}
1018                         };
1019                 int *s = state_table[m_state];
1020                 if (changed & (changeState|changeVideo) && m_video)
1021                 {
1022                         m_video->setSlowMotion(s[1]);
1023                         m_video->setFastForward(s[2]);
1024                         if (s[0])
1025                                 m_video->unfreeze();
1026                         else
1027                                 m_video->freeze();
1028                 }
1029                 if (changed & (changeState|changeAudio) && m_audio)
1030                 {
1031                         if (s[0])
1032                                 m_audio->unfreeze();
1033                         else
1034                                 m_audio->freeze();
1035                 }
1036                 m_changed &= ~changeState;
1037         }
1038
1039         if (changed && !m_video && m_audio && m_radio_pic.length())
1040                 showSinglePic(m_radio_pic.c_str());
1041
1042         return res;
1043 }
1044
1045 int eTSMPEGDecoder::m_pcm_delay=-1,
1046         eTSMPEGDecoder::m_ac3_delay=-1;
1047
1048 RESULT eTSMPEGDecoder::setHwPCMDelay(int delay)
1049 {
1050         if (delay != m_pcm_delay )
1051         {
1052                 FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
1053                 if (fp)
1054                 {
1055                         fprintf(fp, "%x", delay*90);
1056                         fclose(fp);
1057                         m_pcm_delay = delay;
1058                         return 0;
1059                 }
1060         }
1061         return -1;
1062 }
1063
1064 RESULT eTSMPEGDecoder::setHwAC3Delay(int delay)
1065 {
1066         if ( delay != m_ac3_delay )
1067         {
1068                 FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
1069                 if (fp)
1070                 {
1071                         fprintf(fp, "%x", delay*90);
1072                         fclose(fp);
1073                         m_ac3_delay = delay;
1074                         return 0;
1075                 }
1076         }
1077         return -1;
1078 }
1079
1080
1081 RESULT eTSMPEGDecoder::setPCMDelay(int delay)
1082 {
1083         return m_decoder == 0 ? setHwPCMDelay(delay) : -1;
1084 }
1085
1086 RESULT eTSMPEGDecoder::setAC3Delay(int delay)
1087 {
1088         return m_decoder == 0 ? setHwAC3Delay(delay) : -1;
1089 }
1090
1091 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder)
1092         : m_demux(demux), 
1093                 m_vpid(-1), m_vtype(-1), m_apid(-1), m_atype(-1), m_pcrpid(-1), m_textpid(-1),
1094                 m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp))
1095 {
1096         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn);
1097         CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic);
1098         m_state = stateStop;
1099 }
1100
1101 eTSMPEGDecoder::~eTSMPEGDecoder()
1102 {
1103         finishShowSinglePic();
1104         m_vpid = m_apid = m_pcrpid = m_textpid = pidNone;
1105         m_changed = -1;
1106         setState();
1107 }
1108
1109 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
1110 {
1111         if ((m_vpid != vpid) || (m_vtype != type))
1112         {
1113                 m_changed |= changeVideo;
1114                 m_vpid = vpid;
1115                 m_vtype = type;
1116         }
1117         return 0;
1118 }
1119
1120 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
1121 {
1122         if ((m_apid != apid) || (m_atype != type))
1123         {
1124                 m_changed |= changeAudio;
1125                 m_atype = type;
1126                 m_apid = apid;
1127         }
1128         return 0;
1129 }
1130
1131 int eTSMPEGDecoder::m_audio_channel = -1;
1132
1133 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
1134 {
1135         if (channel == -1)
1136                 channel = ac_stereo;
1137         if (m_decoder == 0 && m_audio_channel != channel)
1138         {
1139                 if (m_audio)
1140                 {
1141                         m_audio->setChannel(channel);
1142                         m_audio_channel=channel;
1143                 }
1144                 else
1145                         eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
1146         }
1147         return 0;
1148 }
1149
1150 int eTSMPEGDecoder::getAudioChannel()
1151 {
1152         return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
1153 }
1154
1155 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
1156 {
1157         if (m_pcrpid != pcrpid)
1158         {
1159                 m_changed |= changePCR;
1160                 m_pcrpid = pcrpid;
1161         }
1162         return 0;
1163 }
1164
1165 RESULT eTSMPEGDecoder::setTextPID(int textpid)
1166 {
1167         if (m_textpid != textpid)
1168         {
1169                 m_changed |= changeText;
1170                 m_textpid = textpid;
1171         }
1172         return 0;
1173 }
1174
1175 RESULT eTSMPEGDecoder::setSyncMaster(int who)
1176 {
1177         return -1;
1178 }
1179
1180 RESULT eTSMPEGDecoder::set()
1181 {
1182         return setState();
1183 }
1184
1185 RESULT eTSMPEGDecoder::play()
1186 {
1187         if (m_state == statePlay)
1188         {
1189                 if (!m_changed)
1190                         return 0;
1191         } else  
1192         {
1193                 m_state = statePlay;
1194                 m_changed |= changeState;
1195         }
1196         return setState();
1197 }
1198
1199 RESULT eTSMPEGDecoder::pause()
1200 {
1201         if (m_state == statePause)
1202                 return 0;
1203         m_state = statePause;
1204         m_changed |= changeState;
1205         return setState();
1206 }
1207
1208 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
1209 {
1210         if ((m_state == stateDecoderFastForward) && (m_ff_sm_ratio == frames_to_skip))
1211                 return 0;
1212
1213         m_state = stateDecoderFastForward;
1214         m_ff_sm_ratio = frames_to_skip;
1215         m_changed |= changeState;
1216         return setState();
1217
1218 //              return m_video->setFastForward(frames_to_skip);
1219 }
1220
1221 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
1222 {
1223         if ((m_state == stateSlowMotion) && (m_ff_sm_ratio == repeat))
1224                 return 0;
1225
1226         m_state = stateSlowMotion;
1227         m_ff_sm_ratio = repeat;
1228         m_changed |= changeState;
1229         return setState();
1230 }
1231
1232 RESULT eTSMPEGDecoder::setTrickmode()
1233 {
1234         if (m_state == stateTrickmode)
1235                 return 0;
1236
1237         m_state = stateTrickmode;
1238         m_changed |= changeState;
1239         return setState();
1240 }
1241
1242 RESULT eTSMPEGDecoder::flush()
1243 {
1244         if (m_audio)
1245                 m_audio->flush();
1246         if (m_video)
1247                 m_video->flush();
1248         return 0;
1249 }
1250
1251 void eTSMPEGDecoder::demux_event(int event)
1252 {
1253         switch (event)
1254         {
1255         case eDVBDemux::evtFlush:
1256                 flush();
1257                 break;
1258         default:
1259                 break;
1260         }
1261 }
1262
1263 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
1264 {
1265         if (what == 0) /* auto */
1266                 what = m_video ? 1 : 2;
1267
1268         if (what == 1) /* video */
1269         {
1270                 if (m_video)
1271                         return m_video->getPTS(pts);
1272                 else
1273                         return -1;
1274         }
1275
1276         if (what == 2) /* audio */
1277         {
1278                 if (m_audio)
1279                         return m_audio->getPTS(pts);
1280                 else
1281                         return -1;
1282         }
1283
1284         return -1;
1285 }
1286
1287 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
1288 {
1289         m_radio_pic = filename;
1290         return 0;
1291 }
1292
1293 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
1294 {
1295         if (m_decoder == 0)
1296         {
1297                 eDebug("showSinglePic %s", filename);
1298                 int f = open(filename, O_RDONLY);
1299                 if (f >= 0)
1300                 {
1301                         struct stat s;
1302                         fstat(f, &s);
1303                         if (m_video_clip_fd == -1)
1304                                 m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY|O_NONBLOCK);
1305                         if (m_video_clip_fd >= 0)
1306                         {
1307                                 bool seq_end_avail = false;
1308                                 size_t pos=0;
1309                                 unsigned char pes_header[] = { 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x00, 0x00 };
1310                                 unsigned char seq_end[] = { 0x00, 0x00, 0x01, 0xB7 };
1311                                 unsigned char iframe[s.st_size];
1312                                 unsigned char stuffing[8192];
1313                                 int streamtype = VIDEO_STREAMTYPE_MPEG2;
1314                                 memset(stuffing, 0, 8192);
1315                                 read(f, iframe, s.st_size);
1316                                 if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
1317                                         eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
1318                                 if (ioctl(m_video_clip_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0)
1319                                         eDebug("VIDEO_SET_STREAMTYPE failed(%m)");
1320                                 if (ioctl(m_video_clip_fd, VIDEO_PLAY) < 0)
1321                                         eDebug("VIDEO_PLAY failed (%m)");
1322                                 if (ioctl(m_video_clip_fd, VIDEO_CONTINUE) < 0)
1323                                         eDebug("video: VIDEO_CONTINUE: %m");
1324                                 if (ioctl(m_video_clip_fd, VIDEO_CLEAR_BUFFER) < 0)
1325                                         eDebug("video: VIDEO_CLEAR_BUFFER: %m");
1326                                 while(pos <= (s.st_size-4) && !(seq_end_avail = (!iframe[pos] && !iframe[pos+1] && iframe[pos+2] == 1 && iframe[pos+3] == 0xB7)))
1327                                         ++pos;
1328                                 if ((iframe[3] >> 4) != 0xE) // no pes header
1329                                         write(m_video_clip_fd, pes_header, sizeof(pes_header));
1330                                 else
1331                                         iframe[4] = iframe[5] = 0x00;
1332                                 write(m_video_clip_fd, iframe, s.st_size);
1333                                 if (!seq_end_avail)
1334                                         write(m_video_clip_fd, seq_end, sizeof(seq_end));
1335                                 write(m_video_clip_fd, stuffing, 8192);
1336                                 m_showSinglePicTimer->start(150, true);
1337                         }
1338                         close(f);
1339                 }
1340                 else
1341                 {
1342                         eDebug("couldnt open %s", filename);
1343                         return -1;
1344                 }
1345         }
1346         else
1347         {
1348                 eDebug("only show single pics on first decoder");
1349                 return -1;
1350         }
1351         return 0;
1352 }
1353
1354 void eTSMPEGDecoder::finishShowSinglePic()
1355 {
1356         if (m_video_clip_fd >= 0)
1357         {
1358                 if (ioctl(m_video_clip_fd, VIDEO_STOP, 0) < 0)
1359                         eDebug("VIDEO_STOP failed (%m)");
1360                 if (ioctl(m_video_clip_fd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
1361                                 eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
1362                 close(m_video_clip_fd);
1363                 m_video_clip_fd = -1;
1364         }
1365 }
1366
1367 RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
1368 {
1369         conn = new eConnection(this, m_video_event.connect(event));
1370         return 0;
1371 }
1372
1373 void eTSMPEGDecoder::video_event(struct videoEvent event)
1374 {
1375         /* emit */ m_video_event(event);
1376 }
1377
1378 int eTSMPEGDecoder::getVideoWidth()
1379 {
1380         if (m_video)
1381                 return m_video->getWidth();
1382         return -1;
1383 }
1384
1385 int eTSMPEGDecoder::getVideoHeight()
1386 {
1387         if (m_video)
1388                 return m_video->getHeight();
1389         return -1;
1390 }
1391
1392 int eTSMPEGDecoder::getVideoProgressive()
1393 {
1394         if (m_video)
1395                 return m_video->getProgressive();
1396         return -1;
1397 }
1398
1399 int eTSMPEGDecoder::getVideoFrameRate()
1400 {
1401         if (m_video)
1402                 return m_video->getFrameRate();
1403         return -1;
1404 }
1405
1406 int eTSMPEGDecoder::getVideoAspect()
1407 {
1408         if (m_video)
1409                 return m_video->getAspect();
1410         return -1;
1411 }