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