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