- fix event info
[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, &pes) < 0)
69         {
70                 eWarning("audio: DMX_START: %m");
71                 return -errno;
72         }
73         
74         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
75                 eWarning("audio: AUDIO_PLAY: %m");
76         return 0;
77 }
78         
79 void eDVBAudio::stop()
80 {
81         if (::ioctl(m_fd, AUDIO_STOP) < 0)
82                 eWarning("audio: AUDIO_STOP: %m");
83         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
84                 eWarning("audio: DMX_STOP: %m");
85 }
86         
87 eDVBAudio::~eDVBAudio()
88 {
89         if (m_fd >= 0)
90                 ::close(m_fd);
91         if (m_fd_demux >= 0)
92                 ::close(m_fd_demux);
93 }
94
95 DEFINE_REF(eDVBVideo);
96
97 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux)
98 {
99         char filename[128];
100 #if HAVE_DVB_API_VERSION < 3
101         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
102 #else
103         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
104 #endif
105         m_fd = ::open(filename, O_RDWR);
106         if (m_fd < 0)
107                 eWarning("%s: %m", filename);
108 #if HAVE_DVB_API_VERSION < 3
109         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
110 #else
111         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
112 #endif
113         m_fd_demux = ::open(filename, O_RDWR);
114         if (m_fd_demux < 0)
115                 eWarning("%s: %m", filename);
116 }
117         
118 int eDVBVideo::startPid(int pid)
119 {       
120         if ((m_fd < 0) || (m_fd_demux < 0))
121                 return -1;
122         dmx_pes_filter_params pes;
123         
124         pes.pid      = pid;
125         pes.input    = DMX_IN_FRONTEND;
126         pes.output   = DMX_OUT_DECODER;
127         pes.pes_type = DMX_PES_VIDEO;
128         pes.flags    = 0;
129         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
130         {
131                 eWarning("video: DMX_SET_PES_FILTER: %m");
132                 return -errno;
133         }
134         if (::ioctl(m_fd_demux, DMX_START, &pes) < 0)
135         {
136                 eWarning("video: DMX_START: %m");
137                 return -errno;
138         }
139         
140         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
141                 eWarning("video: VIDEO_PLAY: %m");
142         else
143                 eDebug("video ok");
144         return 0;
145 }
146         
147 void eDVBVideo::stop()
148 {
149         if (::ioctl(m_fd, VIDEO_STOP) < 0)
150                 eWarning("video: VIDEO_STOP: %m");
151         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
152                 eWarning("video: DMX_STOP: %m");
153 }
154         
155 eDVBVideo::~eDVBVideo()
156 {
157         if (m_fd >= 0)
158                 ::close(m_fd);
159         if (m_fd_demux >= 0)
160                 ::close(m_fd_demux);
161 }
162
163 DEFINE_REF(eTSMPEGDecoder);
164
165 int eTSMPEGDecoder::setState()
166 {
167         int res = 0;
168         eDebug("changed %x", m_changed);
169         if (m_changed & changeAudio)
170         {
171                 if (m_audio)
172                         m_audio->stop();
173                 m_audio = 0;
174                 m_audio = new eDVBAudio(m_demux, 0);
175                 if (m_audio->startPid(m_apid))
176                 {
177                         eWarning("audio: startpid failed!");
178                         res = -1;
179                 }
180                 m_changed &= ~changeAudio;
181         }
182         if (m_changed & changeVideo)
183         {
184                 if (m_video)
185                         m_video->stop();
186                 m_video = 0;
187                 m_video = new eDVBVideo(m_demux, 0);
188                 if (m_video->startPid(m_vpid))
189                 {
190                         eWarning("video: startpid failed!");
191                         res = -1;
192                 }
193                 m_changed &= ~changeVideo;
194         }
195         return res;
196 }
197
198 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux)
199 {
200 }
201
202 eTSMPEGDecoder::~eTSMPEGDecoder()
203 {
204         m_vpid = m_apid = m_pcrpid = pidNone;
205         m_changed = -1;
206         setState();
207 }
208
209 RESULT eTSMPEGDecoder::setVideoPID(int vpid)
210 {
211         if (m_vpid != vpid)
212         {
213                 m_changed |= changeVideo;
214                 m_vpid = vpid;
215         }
216         return 0;
217 }
218
219 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
220 {
221         if ((m_apid != apid) || (m_atype != type))
222         {
223                 m_changed |= changeAudio;
224                 m_atype = type;
225                 m_apid = apid;
226         }
227         return 0;
228 }
229
230 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
231 {
232         if (m_pcrpid != pcrpid)
233         {
234                 m_changed |= changeAudio;
235                 m_pcrpid = pcrpid;
236         }
237         return -1;
238 }
239
240 RESULT eTSMPEGDecoder::setSyncMaster(int who)
241 {
242         return -1;
243 }
244
245 RESULT eTSMPEGDecoder::start()
246 {
247         return setState();
248 }
249
250 RESULT eTSMPEGDecoder::freeze(int cont)
251 {
252         return -1;
253 }
254
255 RESULT eTSMPEGDecoder::unfreeze()
256 {
257         return -1;
258 }
259
260 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
261 {
262         return -1;
263 }
264
265 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
266 {
267         return -1;
268 }
269
270 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
271 {
272         return -1;
273 }
274
275 RESULT eTSMPEGDecoder::setZoom(int what)
276 {
277         return -1;
278 }