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