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