convert event_id from string to long
[enigma2.git] / lib / dvb / decoder.cpp
1 #include <config.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_VIDEO DMX_PES_VIDEO0
14 #define DMX_PES_AUDIO DMX_PES_AUDIO0
15 #include <ost/dmx.h>
16 #include <ost/video.h>
17 #include <ost/audio.h>
18 #else
19 #include <linux/dvb/audio.h>
20 #include <linux/dvb/video.h>
21 #include <linux/dvb/dmx.h>
22 #endif
23
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <sys/ioctl.h>
27 #include <errno.h>
28
29 DEFINE_REF(eDVBAudio);
30
31 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux)
32 {
33         char filename[128];
34 #if HAVE_DVB_API_VERSION < 3
35         sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);      
36 #else
37         sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
38 #endif
39         m_fd = ::open(filename, O_RDWR);
40         if (m_fd < 0)
41                 eWarning("%s: %m", filename);
42 #if HAVE_DVB_API_VERSION < 3
43         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
44 #else
45         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
46 #endif  
47         m_fd_demux = ::open(filename, O_RDWR);
48         if (m_fd_demux < 0)
49                 eWarning("%s: %m", filename);
50 }
51         
52 int eDVBAudio::startPid(int pid, int type)
53 {       
54         if ((m_fd < 0) || (m_fd_demux < 0))
55                 return -1;
56         dmx_pes_filter_params pes;
57
58         pes.pid      = pid;
59         pes.input    = DMX_IN_FRONTEND;
60         pes.output   = DMX_OUT_DECODER;
61         pes.pes_type = DMX_PES_AUDIO;  // DMX_PES_AUDIO0
62         pes.flags    = 0;
63         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
64         {
65                 eWarning("audio: DMX_SET_PES_FILTER: %m");
66                 return -errno;
67         }
68         if (::ioctl(m_fd_demux, DMX_START) < 0)
69         {
70                 eWarning("audio: DMX_START: %m");
71                 return -errno;
72         }
73         
74         int bypass = 0;
75         
76         switch (type)
77         {
78         case aMPEG:
79                 bypass = 1;
80                 break;
81         case aAC3:
82                 bypass = 0;
83                 break;
84                 /*
85         case aDTS:
86                 bypass = 2;
87                 break;
88                 */
89         }
90         
91         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
92                 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
93         
94         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
95                 eWarning("audio: AUDIO_PLAY: %m");
96         return 0;
97 }
98         
99 void eDVBAudio::stop()
100 {
101         if (::ioctl(m_fd, AUDIO_STOP) < 0)
102                 eWarning("audio: AUDIO_STOP: %m");
103 #if HAVE_DVB_API_VERSION > 2
104         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
105                 eWarning("audio: DMX_STOP: %m");
106 #endif
107 }
108         
109 #if HAVE_DVB_API_VERSION < 3
110 void eDVBAudio::stopPid()
111 {
112         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
113                 eWarning("audio: DMX_STOP: %m");
114 }
115 #endif
116
117 void eDVBAudio::flush()
118 {
119         if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
120                 eDebug("audio: AUDIO_CLEAR_BUFFER: %m");
121 }
122
123 void eDVBAudio::freeze()
124 {
125         if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
126                 eDebug("video: AUDIO_PAUSE: %m");
127 }
128
129 void eDVBAudio::unfreeze()
130 {
131         if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
132                 eDebug("video: AUDIO_CONTINUE: %m");
133 }
134         
135 eDVBAudio::~eDVBAudio()
136 {
137         if (m_fd >= 0)
138                 ::close(m_fd);
139         if (m_fd_demux >= 0)
140                 ::close(m_fd_demux);
141 }
142
143 DEFINE_REF(eDVBVideo);
144
145 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux)
146 {
147         char filename[128];
148 #if HAVE_DVB_API_VERSION < 3
149         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
150 #else
151         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
152 #endif
153         m_fd = ::open(filename, O_RDWR);
154         if (m_fd < 0)
155                 eWarning("%s: %m", filename);
156 #if HAVE_DVB_API_VERSION < 3
157         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
158 #else
159         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
160 #endif
161         m_fd_demux = ::open(filename, O_RDWR);
162         if (m_fd_demux < 0)
163                 eWarning("%s: %m", filename);
164 }
165         
166 int eDVBVideo::startPid(int pid)
167 {       
168         if ((m_fd < 0) || (m_fd_demux < 0))
169                 return -1;
170         dmx_pes_filter_params pes;
171
172         pes.pid      = pid;
173         pes.input    = DMX_IN_FRONTEND;
174         pes.output   = DMX_OUT_DECODER;
175         pes.pes_type = DMX_PES_VIDEO;
176         pes.flags    = 0;
177         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
178         {
179                 eWarning("video: DMX_SET_PES_FILTER: %m");
180                 return -errno;
181         }
182         if (::ioctl(m_fd_demux, DMX_START) < 0)
183         {
184                 eWarning("video: DMX_START: %m");
185                 return -errno;
186         }
187         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
188                 eWarning("video: VIDEO_PLAY: %m");
189         return 0;
190 }
191         
192 void eDVBVideo::stop()
193 {
194 #if HAVE_DVB_API_VERSION > 2
195         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
196                 eWarning("video: DMX_STOP: %m");
197 #endif
198         eDebug("VIDEO_STOP");
199         if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
200                 eWarning("video: VIDEO_STOP: %m");
201 }
202
203 #if HAVE_DVB_API_VERSION < 3
204 void eDVBVideo::stopPid()
205 {
206         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
207                 eWarning("video: DMX_STOP: %m");
208 }
209 #endif
210
211 void eDVBVideo::flush()
212 {
213         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
214                 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
215 }
216         
217 void eDVBVideo::freeze()
218 {
219         if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
220                 eDebug("video: VIDEO_FREEZE: %m");
221 }
222         
223 void eDVBVideo::unfreeze()
224 {
225         if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
226                 eDebug("video: VIDEO_CONTINUE: %m");
227 }
228         
229 int eDVBVideo::setSlowMotion(int repeat)
230 {
231         m_is_slow_motion = repeat;
232         return ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
233 }
234
235 int eDVBVideo::setFastForward(int skip)
236 {
237         m_is_fast_forward = skip;
238         return ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
239 }
240         
241 eDVBVideo::~eDVBVideo()
242 {
243         if (m_is_slow_motion)
244                 setSlowMotion(0);
245         if (m_is_fast_forward)
246                 setFastForward(0);
247         if (m_fd >= 0)
248                 ::close(m_fd);
249         if (m_fd_demux >= 0)
250                 ::close(m_fd_demux);
251 }
252
253 DEFINE_REF(eDVBPCR);
254
255 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
256 {
257         char filename[128];
258 #if HAVE_DVB_API_VERSION < 3
259         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
260 #else
261         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
262 #endif
263         m_fd_demux = ::open(filename, O_RDWR);
264         if (m_fd_demux < 0)
265                 eWarning("%s: %m", filename);
266 }
267
268 int eDVBPCR::startPid(int pid)
269 {
270         if (m_fd_demux < 0)
271                 return -1;
272         dmx_pes_filter_params pes;
273
274         pes.pid      = pid;
275         pes.input    = DMX_IN_FRONTEND;
276         pes.output   = DMX_OUT_DECODER;
277         pes.pes_type = DMX_PES_PCR;
278         pes.flags    = 0;
279         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
280         {
281                 eWarning("video: DMX_SET_PES_FILTER: %m");
282                 return -errno;
283         }
284         if (::ioctl(m_fd_demux, DMX_START) < 0)
285         {
286                 eWarning("video: DMX_START: %m");
287                 return -errno;
288         }
289         return 0;
290 }
291
292 void eDVBPCR::stop()
293 {
294         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
295                 eWarning("video: DMX_STOP: %m");
296 }
297
298 eDVBPCR::~eDVBPCR()
299 {
300         if (m_fd_demux >= 0)
301                 ::close(m_fd_demux);
302 }
303
304 DEFINE_REF(eDVBTText);
305
306 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
307 {
308         char filename[128];
309 #if HAVE_DVB_API_VERSION < 3
310         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
311 #else
312         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
313 #endif
314         m_fd_demux = ::open(filename, O_RDWR);
315         if (m_fd_demux < 0)
316                 eWarning("%s: %m", filename);
317 }
318
319 int eDVBTText::startPid(int pid)
320 {
321         if (m_fd_demux < 0)
322                 return -1;
323         dmx_pes_filter_params pes;
324
325         pes.pid      = pid;
326         pes.input    = DMX_IN_FRONTEND;
327         pes.output   = DMX_OUT_DECODER;
328         pes.pes_type = DMX_PES_TELETEXT;
329         pes.flags    = 0;
330         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
331         {
332                 eWarning("video: DMX_SET_PES_FILTER: %m");
333                 return -errno;
334         }
335         if (::ioctl(m_fd_demux, DMX_START) < 0)
336         {
337                 eWarning("video: DMX_START: %m");
338                 return -errno;
339         }
340         return 0;
341 }
342
343 void eDVBTText::stop()
344 {
345         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
346                 eWarning("video: DMX_STOP: %m");
347 }
348
349 eDVBTText::~eDVBTText()
350 {
351         if (m_fd_demux >= 0)
352                 ::close(m_fd_demux);
353 }
354
355 DEFINE_REF(eTSMPEGDecoder);
356
357 int eTSMPEGDecoder::setState()
358 {
359         int res = 0;
360         
361         int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
362         int nott = noaudio; /* actually same conditions */
363
364         if ((noaudio && m_audio) || (!m_audio && !noaudio))
365                 m_changed |= changeAudio;
366         
367         if ((nott && m_text) || (!m_text && !nott))
368                 m_changed |= changeText;
369         
370 #if HAVE_DVB_API_VERSION < 3
371         if (m_changed & changeAudio && m_audio)
372                 m_audio->stopPid();
373         if (m_changed & changeVideo && m_video)
374                 m_video->stopPid();
375         if (m_changed & changePCR && m_pcr)
376         {
377                 m_pcr->stop();
378                 m_pcr=0;
379         }
380         if (m_changed & changeAudio && m_audio)
381         {
382                 m_audio->stop();
383                 m_audio=0;
384         }
385         if (m_changed & changeVideo && m_video)
386         {
387                 m_video->stop();
388                 m_video=0;
389         }
390         if (m_changed & changePCR)
391         {
392                 m_pcr = new eDVBPCR(m_demux);
393                 if (m_pcr->startPid(m_pcrpid))
394                 {
395                         eWarning("pcr: startpid failed!");
396                         res = -1;
397                 }
398                 m_changed &= ~changePCR;
399         }
400         if (m_changed & changeVideo)
401         {
402                 m_video = new eDVBVideo(m_demux, 0);
403                 if (m_video->startPid(m_vpid))
404                 {
405                         eWarning("video: startpid failed!");
406                         res = -1;
407                 }
408                 m_changed &= ~changeVideo;
409         }
410         if (m_changed & changeAudio)
411         {
412                 m_audio = new eDVBAudio(m_demux, 0);
413                 if (m_audio->startPid(m_apid, m_atype))
414                 {
415                         eWarning("audio: startpid failed!");
416                         res = -1;
417                 }
418                 m_changed &= ~changeAudio;
419         }
420 #else
421         if (m_changed & changePCR)
422         {
423                 if (m_pcr)
424                         m_pcr->stop();
425                 m_pcr = 0;
426                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
427                 {
428                         m_pcr = new eDVBPCR(m_demux);
429                         if (m_pcr->startPid(m_pcrpid))
430                         {
431                                 eWarning("pcr: startpid failed!");
432                                 res = -1;
433                         }
434                 }
435                 m_changed &= ~changePCR;
436         }
437         if (m_changed & changeVideo)
438         {
439                 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
440                 if (m_video)
441                 {       
442                         eDebug("STOP");
443                         m_video->stop();
444                 }
445                 m_video = 0;
446                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
447                 {
448                         eDebug("new video");
449                         m_video = new eDVBVideo(m_demux, 0);
450                         if (m_video->startPid(m_vpid))
451                         {
452                                 eWarning("video: startpid failed!");
453                                 res = -1;
454                         }
455                 }
456                 m_changed &= ~changeVideo;
457         }
458         if (m_changed & changeAudio)
459         {
460                 if (m_audio)
461                         m_audio->stop();
462                 m_audio = 0;
463                 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
464                 {
465                         m_audio = new eDVBAudio(m_demux, 0);
466                         if (m_audio->startPid(m_apid, m_atype))
467                         {
468                                 eWarning("audio: startpid failed!");
469                                 res = -1;
470                         }
471                 }
472                 m_changed &= ~changeAudio;
473         }
474         if (m_changed & changeText)
475         {
476                 if (m_text)
477                         m_text->stop();
478                 m_text = 0;
479                 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
480                 {
481                         m_text = new eDVBTText(m_demux);
482                         if (m_text->startPid(m_textpid))
483                         {
484                                 eWarning("text: startpid failed!");
485                                 res = -1;
486                         }
487                 }
488                 m_changed &= ~changeText;
489         }
490 #endif
491         return res;
492 }
493
494 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0)
495 {
496         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event);
497         m_is_ff = m_is_sm = m_is_trickmode = 0;
498 }
499
500 eTSMPEGDecoder::~eTSMPEGDecoder()
501 {
502         m_vpid = m_apid = m_pcrpid = pidNone;
503         m_changed = -1;
504         setState();
505 }
506
507 RESULT eTSMPEGDecoder::setVideoPID(int vpid)
508 {
509         if (m_vpid != vpid)
510         {
511                 m_changed |= changeVideo;
512                 m_vpid = vpid;
513         }
514         return 0;
515 }
516
517 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
518 {
519         if ((m_apid != apid) || (m_atype != type))
520         {
521                 m_changed |= changeAudio;
522                 m_atype = type;
523                 m_apid = apid;
524         }
525         return 0;
526 }
527
528 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
529 {
530         if (m_pcrpid != pcrpid)
531         {
532                 m_changed |= changePCR;
533                 m_pcrpid = pcrpid;
534         }
535         return 0;
536 }
537
538 RESULT eTSMPEGDecoder::setTextPID(int textpid)
539 {
540         if (m_textpid != textpid)
541         {
542                 m_changed |= changeText;
543                 m_textpid = textpid;
544         }
545         return 0;
546 }
547
548 RESULT eTSMPEGDecoder::setSyncMaster(int who)
549 {
550         return -1;
551 }
552
553 RESULT eTSMPEGDecoder::start()
554 {
555         return setState();
556 }
557
558 RESULT eTSMPEGDecoder::freeze(int cont)
559 {
560         if (m_video)
561                 m_video->freeze();
562
563         if (m_audio)
564                 m_audio->freeze();
565         
566         return 0;
567 }
568
569 RESULT eTSMPEGDecoder::unfreeze()
570 {
571         if (m_video)
572                 m_video->unfreeze();
573
574         if (m_audio)
575                 m_audio->unfreeze();
576         
577         return 0;
578 }
579
580 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
581 {
582         return -1;
583 }
584
585 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
586 {
587         return -1;
588 }
589
590 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
591 {
592         m_is_ff = frames_to_skip != 0;
593         
594         setState();
595         
596         if (m_video)
597                 return m_video->setFastForward(frames_to_skip);
598         else
599                 return -1;
600 }
601
602 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
603 {
604         m_is_sm = repeat != 0;
605         
606         setState();
607         
608         if (m_video)
609                 return m_video->setSlowMotion(repeat);
610         else
611                 return -1;
612 }
613
614 RESULT eTSMPEGDecoder::setZoom(int what)
615 {
616         return -1;
617 }
618
619 RESULT eTSMPEGDecoder::flush()
620 {
621         if (m_audio)
622                 m_audio->flush();
623         if (m_video)
624                 m_video->flush();
625         return 0;
626 }
627
628 void eTSMPEGDecoder::demux_event(int event)
629 {
630         switch (event)
631         {
632         case eDVBDemux::evtFlush:
633                 flush();
634                 break;
635         default:
636                 break;
637         }
638 }
639
640 RESULT eTSMPEGDecoder::setTrickmode(int what)
641 {
642         m_is_trickmode = what;
643         setState();
644         return 0;
645 }