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