fix: the symbolrate for cable somehow got into the sat-setup and vice versa
[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 (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
195                 eWarning("video: VIDEO_STOP: %m");
196 #if HAVE_DVB_API_VERSION > 2
197         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
198                 eWarning("video: DMX_STOP: %m");
199 #endif
200 }
201
202 #if HAVE_DVB_API_VERSION < 3
203 void eDVBVideo::stopPid()
204 {
205         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
206                 eWarning("video: DMX_STOP: %m");
207 }
208 #endif
209
210 void eDVBVideo::flush()
211 {
212         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
213                 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
214 }
215         
216 void eDVBVideo::freeze()
217 {
218         if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
219                 eDebug("video: VIDEO_FREEZE: %m");
220 }
221         
222 void eDVBVideo::unfreeze()
223 {
224         if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
225                 eDebug("video: VIDEO_CONTINUE: %m");
226 }
227         
228 eDVBVideo::~eDVBVideo()
229 {
230         if (m_fd >= 0)
231                 ::close(m_fd);
232         if (m_fd_demux >= 0)
233                 ::close(m_fd_demux);
234 }
235
236 DEFINE_REF(eDVBPCR);
237
238 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
239 {
240         char filename[128];
241 #if HAVE_DVB_API_VERSION < 3
242         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
243 #else
244         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
245 #endif
246         m_fd_demux = ::open(filename, O_RDWR);
247         if (m_fd_demux < 0)
248                 eWarning("%s: %m", filename);
249 }
250
251 int eDVBPCR::startPid(int pid)
252 {
253         if (m_fd_demux < 0)
254                 return -1;
255         dmx_pes_filter_params pes;
256
257         pes.pid      = pid;
258         pes.input    = DMX_IN_FRONTEND;
259         pes.output   = DMX_OUT_DECODER;
260         pes.pes_type = DMX_PES_PCR;
261         pes.flags    = 0;
262         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
263         {
264                 eWarning("video: DMX_SET_PES_FILTER: %m");
265                 return -errno;
266         }
267         if (::ioctl(m_fd_demux, DMX_START) < 0)
268         {
269                 eWarning("video: DMX_START: %m");
270                 return -errno;
271         }
272         return 0;
273 }
274
275 void eDVBPCR::stop()
276 {
277         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
278                 eWarning("video: DMX_STOP: %m");
279 }
280
281 eDVBPCR::~eDVBPCR()
282 {
283         if (m_fd_demux >= 0)
284                 ::close(m_fd_demux);
285 }
286
287 DEFINE_REF(eTSMPEGDecoder);
288
289 int eTSMPEGDecoder::setState()
290 {
291         int res = 0;
292 #if HAVE_DVB_API_VERSION < 3
293         if (m_changed & changeAudio && m_audio)
294                 m_audio->stopPid();
295         if (m_changed & changeVideo && m_video)
296                 m_video->stopPid();
297         if (m_changed & changePCR && m_pcr)
298         {
299                 m_pcr->stop();
300                 m_pcr=0;
301         }
302         if (m_changed & changeAudio && m_audio)
303         {
304                 m_audio->stop();
305                 m_audio=0;
306         }
307         if (m_changed & changeVideo && m_video)
308         {
309                 m_video->stop();
310                 m_video=0;
311         }
312         if (m_changed & changePCR)
313         {
314                 m_pcr = new eDVBPCR(m_demux);
315                 if (m_pcr->startPid(m_pcrpid))
316                 {
317                         eWarning("pcr: startpid failed!");
318                         res = -1;
319                 }
320                 m_changed &= ~changePCR;
321         }
322         if (m_changed & changeVideo)
323         {
324                 m_video = new eDVBVideo(m_demux, 0);
325                 if (m_video->startPid(m_vpid))
326                 {
327                         eWarning("video: startpid failed!");
328                         res = -1;
329                 }
330                 m_changed &= ~changeVideo;
331         }
332         if (m_changed & changeAudio)
333         {
334                 m_audio = new eDVBAudio(m_demux, 0);
335                 if (m_audio->startPid(m_apid, m_atype))
336                 {
337                         eWarning("audio: startpid failed!");
338                         res = -1;
339                 }
340                 m_changed &= ~changeAudio;
341         }
342 #else
343         if (m_changed & changePCR)
344         {
345                 if (m_pcr)
346                         m_pcr->stop();
347                 m_pcr = 0;
348                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
349                 {
350                         m_pcr = new eDVBPCR(m_demux);
351                         if (m_pcr->startPid(m_pcrpid))
352                         {
353                                 eWarning("pcr: startpid failed!");
354                                 res = -1;
355                         }
356                 }
357                 m_changed &= ~changePCR;
358         }
359         if (m_changed & changeVideo)
360         {
361                 if (m_video)
362                         m_video->stop();
363                 m_video = 0;
364                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
365                 {
366                         m_video = new eDVBVideo(m_demux, 0);
367                         if (m_video->startPid(m_vpid))
368                         {
369                                 eWarning("video: startpid failed!");
370                                 res = -1;
371                         }
372                 }
373                 m_changed &= ~changeVideo;
374         }
375         if (m_changed & changeAudio)
376         {
377                 if (m_audio)
378                         m_audio->stop();
379                 m_audio = 0;
380                 if ((m_apid >= 0) && (m_apid < 0x1FFF))
381                 {
382                         m_audio = new eDVBAudio(m_demux, 0);
383                         if (m_audio->startPid(m_apid, m_atype))
384                         {
385                                 eWarning("audio: startpid failed!");
386                                 res = -1;
387                         }
388                 }
389                 m_changed &= ~changeAudio;
390         }
391 #endif
392         return res;
393 }
394
395 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0)
396 {
397         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event);
398 }
399
400 eTSMPEGDecoder::~eTSMPEGDecoder()
401 {
402         m_vpid = m_apid = m_pcrpid = pidNone;
403         m_changed = -1;
404         setState();
405 }
406
407 RESULT eTSMPEGDecoder::setVideoPID(int vpid)
408 {
409         if (m_vpid != vpid)
410         {
411                 m_changed |= changeVideo;
412                 m_vpid = vpid;
413         }
414         return 0;
415 }
416
417 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
418 {
419         if ((m_apid != apid) || (m_atype != type))
420         {
421                 m_changed |= changeAudio;
422                 m_atype = type;
423                 m_apid = apid;
424         }
425         return 0;
426 }
427
428 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
429 {
430         if (m_pcrpid != pcrpid)
431         {
432                 m_changed |= changePCR;
433                 m_pcrpid = pcrpid;
434         }
435         return 0;
436 }
437
438 RESULT eTSMPEGDecoder::setSyncMaster(int who)
439 {
440         return -1;
441 }
442
443 RESULT eTSMPEGDecoder::start()
444 {
445         return setState();
446 }
447
448 RESULT eTSMPEGDecoder::freeze(int cont)
449 {
450         if (m_video)
451                 m_video->freeze();
452
453         if (m_audio)
454                 m_audio->freeze();
455         
456         return 0;
457 }
458
459 RESULT eTSMPEGDecoder::unfreeze()
460 {
461         if (m_video)
462                 m_video->unfreeze();
463
464         if (m_audio)
465                 m_audio->unfreeze();
466         
467         return 0;
468 }
469
470 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
471 {
472         return -1;
473 }
474
475 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
476 {
477         return -1;
478 }
479
480 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
481 {
482         return -1;
483 }
484
485 RESULT eTSMPEGDecoder::setZoom(int what)
486 {
487         return -1;
488 }
489
490 RESULT eTSMPEGDecoder::flush()
491 {
492         if (m_audio)
493                 m_audio->flush();
494         if (m_video)
495                 m_video->flush();
496         return 0;
497 }
498
499 void eTSMPEGDecoder::demux_event(int event)
500 {
501         switch (event)
502         {
503         case eDVBDemux::evtFlush:
504                 flush();
505                 break;
506         default:
507                 break;
508         }
509 }