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