0f8190de9b6e3164e332bf4ab343262a604e0c59
[vuplus_dvbapp] / 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.pes_type = 
129         pes.flags    = 0;
130         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
131         {
132                 eWarning("video: DMX_SET_PES_FILTER: %m");
133                 return -errno;
134         }
135         if (::ioctl(m_fd_demux, DMX_START, &pes) < 0)
136         {
137                 eWarning("video: DMX_START: %m");
138                 return -errno;
139         }
140         
141         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
142                 eWarning("video: VIDEO_PLAY: %m");
143         else
144                 eDebug("video ok");
145         return 0;
146 }
147         
148 void eDVBVideo::stop()
149 {
150         if (::ioctl(m_fd, VIDEO_STOP) < 0)
151                 eWarning("video: VIDEO_STOP: %m");
152         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
153                 eWarning("video: DMX_STOP: %m");
154 }
155         
156 eDVBVideo::~eDVBVideo()
157 {
158         if (m_fd >= 0)
159                 ::close(m_fd);
160         if (m_fd_demux >= 0)
161                 ::close(m_fd_demux);
162 }
163
164 DEFINE_REF(eTSMPEGDecoder);
165
166 int eTSMPEGDecoder::setState()
167 {
168         int res = 0;
169         eDebug("changed %x", m_changed);
170         if (m_changed & changeAudio)
171         {
172                 if (m_audio)
173                         m_audio->stop();
174                 m_audio = 0;
175                 m_audio = new eDVBAudio(m_demux, 0);
176                 if (m_audio->startPid(m_apid))
177                 {
178                         eWarning("audio: startpid failed!");
179                         res = -1;
180                 }
181                 m_changed &= ~changeAudio;
182         }
183         if (m_changed & changeVideo)
184         {
185                 if (m_video)
186                         m_video->stop();
187                 m_video = 0;
188                 m_video = new eDVBVideo(m_demux, 0);
189                 if (m_video->startPid(m_vpid))
190                 {
191                         eWarning("video: startpid failed!");
192                         res = -1;
193                 }
194                 m_changed &= ~changeVideo;
195         }
196         return res;
197 }
198
199 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux)
200 {
201 }
202
203 eTSMPEGDecoder::~eTSMPEGDecoder()
204 {
205         m_vpid = m_apid = m_pcrpid = pidNone;
206         m_changed = -1;
207         setState();
208 }
209
210 RESULT eTSMPEGDecoder::setVideoPID(int vpid)
211 {
212         if (m_vpid != vpid)
213         {
214                 m_changed |= changeVideo;
215                 m_vpid = vpid;
216         }
217         return 0;
218 }
219
220 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
221 {
222         if ((m_apid != apid) || (m_atype != type))
223         {
224                 m_changed |= changeAudio;
225                 m_atype = type;
226                 m_apid = apid;
227         }
228         return 0;
229 }
230
231 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
232 {
233         if (m_pcrpid != pcrpid)
234         {
235                 m_changed |= changeAudio;
236                 m_pcrpid = pcrpid;
237         }
238         return -1;
239 }
240
241 RESULT eTSMPEGDecoder::setSyncMaster(int who)
242 {
243         return -1;
244 }
245
246 RESULT eTSMPEGDecoder::start()
247 {
248         return setState();
249 }
250
251 RESULT eTSMPEGDecoder::freeze(int cont)
252 {
253         return -1;
254 }
255
256 RESULT eTSMPEGDecoder::unfreeze()
257 {
258         return -1;
259 }
260
261 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
262 {
263         return -1;
264 }
265
266 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
267 {
268         return -1;
269 }
270
271 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
272 {
273         return -1;
274 }
275
276 RESULT eTSMPEGDecoder::setZoom(int what)
277 {
278         return -1;
279 }