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