fix block artifacts when zap with pallas/vulcan hardware
[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)
53 {       
54         eDebug("setting audio pid to %x", pid);
55         if ((m_fd < 0) || (m_fd_demux < 0))
56                 return -1;
57         dmx_pes_filter_params pes;
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         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
74                 eWarning("audio: AUDIO_PLAY: %m");
75         return 0;
76 }
77         
78 void eDVBAudio::stop()
79 {
80         if (::ioctl(m_fd, AUDIO_STOP) < 0)
81                 eWarning("audio: AUDIO_STOP: %m");
82 #if HAVE_DVB_API_VERSION > 2
83         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
84                 eWarning("audio: DMX_STOP: %m");
85 #endif
86 }
87         
88 #if HAVE_DVB_API_VERSION < 3
89 void eDVBAudio::stopPid()
90 {
91         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
92                 eWarning("audio: DMX_STOP: %m");
93 }
94 #endif
95         
96 eDVBAudio::~eDVBAudio()
97 {
98         if (m_fd >= 0)
99                 ::close(m_fd);
100         if (m_fd_demux >= 0)
101                 ::close(m_fd_demux);
102 }
103
104 DEFINE_REF(eDVBVideo);
105
106 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux)
107 {
108         char filename[128];
109 #if HAVE_DVB_API_VERSION < 3
110         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
111 #else
112         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
113 #endif
114         m_fd = ::open(filename, O_RDWR);
115         if (m_fd < 0)
116                 eWarning("%s: %m", filename);
117 #if HAVE_DVB_API_VERSION < 3
118         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
119 #else
120         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
121 #endif
122         m_fd_demux = ::open(filename, O_RDWR);
123         if (m_fd_demux < 0)
124                 eWarning("%s: %m", filename);
125 }
126         
127 int eDVBVideo::startPid(int pid)
128 {       
129         eDebug("setting video pid to %x", pid);
130         if ((m_fd < 0) || (m_fd_demux < 0))
131                 return -1;
132         dmx_pes_filter_params pes;
133         
134         pes.pid      = pid;
135         pes.input    = DMX_IN_FRONTEND;
136         pes.output   = DMX_OUT_DECODER;
137         pes.pes_type = DMX_PES_VIDEO;
138         pes.flags    = 0;
139         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
140         {
141                 eWarning("video: DMX_SET_PES_FILTER: %m");
142                 return -errno;
143         }
144         if (::ioctl(m_fd_demux, DMX_START) < 0)
145         {
146                 eWarning("video: DMX_START: %m");
147                 return -errno;
148         }
149         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
150                 eWarning("video: VIDEO_PLAY: %m");
151         else
152                 eDebug("video ok");
153         return 0;
154 }
155         
156 void eDVBVideo::stop()
157 {
158         if (::ioctl(m_fd, VIDEO_STOP) < 0)
159                 eWarning("video: VIDEO_STOP: %m");
160 #if HAVE_DVB_API_VERSION > 2
161         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
162                 eWarning("video: DMX_STOP: %m");
163 #endif
164 }
165
166 #if HAVE_DVB_API_VERSION < 3
167 void eDVBVideo::stopPid()
168 {
169         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
170                 eWarning("video: DMX_STOP: %m");
171 }
172 #endif
173
174 eDVBVideo::~eDVBVideo()
175 {
176         if (m_fd >= 0)
177                 ::close(m_fd);
178         if (m_fd_demux >= 0)
179                 ::close(m_fd_demux);
180 }
181
182 DEFINE_REF(eDVBPCR);
183
184 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
185 {
186         char filename[128];
187 #if HAVE_DVB_API_VERSION < 3
188         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
189 #else
190         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
191 #endif
192         m_fd_demux = ::open(filename, O_RDWR);
193         if (m_fd_demux < 0)
194                 eWarning("%s: %m", filename);
195 }
196
197 int eDVBPCR::startPid(int pid)
198 {
199         eDebug("setting pcr pid to %x", pid);
200         if (m_fd_demux < 0)
201                 return -1;
202         dmx_pes_filter_params pes;
203
204         pes.pid      = pid;
205         pes.input    = DMX_IN_FRONTEND;
206         pes.output   = DMX_OUT_DECODER;
207         pes.pes_type = DMX_PES_PCR;
208         pes.flags    = 0;
209         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
210         {
211                 eWarning("video: DMX_SET_PES_FILTER: %m");
212                 return -errno;
213         }
214         if (::ioctl(m_fd_demux, DMX_START) < 0)
215         {
216                 eWarning("video: DMX_START: %m");
217                 return -errno;
218         }
219         return 0;
220 }
221
222 void eDVBPCR::stop()
223 {
224         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
225                 eWarning("video: DMX_STOP: %m");
226 }
227
228 eDVBPCR::~eDVBPCR()
229 {
230         if (m_fd_demux >= 0)
231                 ::close(m_fd_demux);
232 }
233
234 DEFINE_REF(eTSMPEGDecoder);
235
236 int eTSMPEGDecoder::setState()
237 {
238         int res = 0;
239         eDebug("changed %x", m_changed);
240 #if HAVE_DVB_API_VERSION < 3
241         if (m_changed & changeAudio && m_audio)
242                 m_audio->stopPid();
243         if (m_changed & changeVideo && m_video)
244                 m_video->stopPid();
245         if (m_changed & changePCR && m_pcr)
246         {
247                 m_pcr->stop();
248                 m_pcr=0;
249         }
250         if (m_changed & changeAudio && m_audio)
251         {
252                 m_audio->stop();
253                 m_audio=0;
254         }
255         if (m_changed & changeVideo && m_video)
256         {
257                 m_video->stop();
258                 m_video=0;
259         }
260         if (m_changed & changePCR)
261         {
262                 m_pcr = new eDVBPCR(m_demux);
263                 if (m_pcr->startPid(m_pcrpid))
264                 {
265                         eWarning("video: startpid failed!");
266                         res = -1;
267                 }
268                 m_changed &= ~changePCR;
269         }
270         if (m_changed & changeVideo)
271         {
272                 m_video = new eDVBVideo(m_demux, 0);
273                 if (m_video->startPid(m_vpid))
274                 {
275                         eWarning("video: startpid failed!");
276                         res = -1;
277                 }
278                 m_changed &= ~changeVideo;
279         }
280         if (m_changed & changeAudio)
281         {
282                 m_audio = new eDVBAudio(m_demux, 0);
283                 if (m_audio->startPid(m_apid))
284                 {
285                         eWarning("audio: startpid failed!");
286                         res = -1;
287                 }
288                 m_changed &= ~changeAudio;
289         }
290 #else
291         if (m_changed & changePCR)
292         {
293                 if (m_pcr)
294                         m_pcr->stop();
295                 m_pcr = 0;
296                 m_pcr = new eDVBPCR(m_demux);
297                 if (m_pcr->startPid(m_pcrpid))
298                 {
299                         eWarning("video: startpid failed!");
300                         res = -1;
301                 }
302                 m_changed &= ~changePCR;
303         }
304         if (m_changed & changeVideo)
305         {
306                 if (m_video)
307                         m_video->stop();
308                 m_video = 0;
309                 m_video = new eDVBVideo(m_demux, 0);
310                 if (m_video->startPid(m_vpid))
311                 {
312                         eWarning("video: startpid failed!");
313                         res = -1;
314                 }
315                 m_changed &= ~changeVideo;
316         }
317         if (m_changed & changeAudio)
318         {
319                 if (m_audio)
320                         m_audio->stop();
321                 m_audio = 0;
322                 m_audio = new eDVBAudio(m_demux, 0);
323                 if (m_audio->startPid(m_apid))
324                 {
325                         eWarning("audio: startpid failed!");
326                         res = -1;
327                 }
328                 m_changed &= ~changeAudio;
329         }
330 #endif
331         return res;
332 }
333
334 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0)
335 {
336 }
337
338 eTSMPEGDecoder::~eTSMPEGDecoder()
339 {
340         m_vpid = m_apid = m_pcrpid = pidNone;
341         m_changed = -1;
342         setState();
343 }
344
345 RESULT eTSMPEGDecoder::setVideoPID(int vpid)
346 {
347         if (m_vpid != vpid)
348         {
349                 m_changed |= changeVideo;
350                 m_vpid = vpid;
351         }
352         return 0;
353 }
354
355 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
356 {
357         if ((m_apid != apid) || (m_atype != type))
358         {
359                 m_changed |= changeAudio;
360                 m_atype = type;
361                 m_apid = apid;
362         }
363         return 0;
364 }
365
366 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
367 {
368         if (m_pcrpid != pcrpid)
369         {
370                 m_changed |= changePCR;
371                 m_pcrpid = pcrpid;
372         }
373         return -1;
374 }
375
376 RESULT eTSMPEGDecoder::setSyncMaster(int who)
377 {
378         return -1;
379 }
380
381 RESULT eTSMPEGDecoder::start()
382 {
383         return setState();
384 }
385
386 RESULT eTSMPEGDecoder::freeze(int cont)
387 {
388         return -1;
389 }
390
391 RESULT eTSMPEGDecoder::unfreeze()
392 {
393         return -1;
394 }
395
396 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
397 {
398         return -1;
399 }
400
401 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
402 {
403         return -1;
404 }
405
406 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
407 {
408         return -1;
409 }
410
411 RESULT eTSMPEGDecoder::setZoom(int what)
412 {
413         return -1;
414 }