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