0b3619adfd584bdf9b1652bf4ef27acaaeb3b41e
[vuplus_dvbapp] / lib / dvb / decoder.cpp
1 #include <lib/dvb/decoder.h>
2 #include <linux/dvb/audio.h>
3 #include <linux/dvb/video.h>
4 #include <linux/dvb/dmx.h>
5
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <sys/ioctl.h>
9 #include <errno.h>
10
11 DEFINE_REF(eDVBAudio);
12
13 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux)
14 {
15         char filename[128];
16         sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
17         m_fd = ::open(filename, O_RDWR);
18         if (m_fd < 0)
19                 eWarning("%s: %m", filename);
20         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
21         m_fd_demux = ::open(filename, O_RDWR);
22         if (m_fd_demux < 0)
23                 eWarning("%s: %m", filename);
24 }
25         
26 int eDVBAudio::startPid(int pid)
27 {       
28         eDebug("setting audio pid to %x", pid);
29         if ((m_fd < 0) || (m_fd_demux < 0))
30                 return -1;
31         dmx_pes_filter_params pes;
32         
33         pes.pid      = pid;
34         pes.input    = DMX_IN_FRONTEND;
35         pes.output   = DMX_OUT_DECODER;
36         pes.pes_type = DMX_PES_AUDIO0;
37         pes.flags    = 0;
38         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
39         {
40                 eWarning("audio: DMX_SET_PES_FILTER: %m");
41                 return -errno;
42         }
43         if (::ioctl(m_fd_demux, DMX_START, &pes) < 0)
44         {
45                 eWarning("audio: DMX_START: %m");
46                 return -errno;
47         }
48         
49         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
50                 eWarning("audio: AUDIO_PLAY: %m");
51         return 0;
52 }
53         
54 void eDVBAudio::stop()
55 {
56         if (::ioctl(m_fd, AUDIO_STOP) < 0)
57                 eWarning("audio: AUDIO_STOP: %m");
58         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
59                 eWarning("audio: DMX_STOP: %m");
60 }
61         
62 eDVBAudio::~eDVBAudio()
63 {
64         if (m_fd >= 0)
65                 ::close(m_fd);
66         if (m_fd_demux >= 0)
67                 ::close(m_fd_demux);
68 }
69
70 DEFINE_REF(eDVBVideo);
71
72 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux)
73 {
74         char filename[128];
75         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
76         m_fd = ::open(filename, O_RDWR);
77         if (m_fd < 0)
78                 eWarning("%s: %m", filename);
79         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
80         m_fd_demux = ::open(filename, O_RDWR);
81         if (m_fd_demux < 0)
82                 eWarning("%s: %m", filename);
83 }
84         
85 int eDVBVideo::startPid(int pid)
86 {       
87         if ((m_fd < 0) || (m_fd_demux < 0))
88                 return -1;
89         dmx_pes_filter_params pes;
90         
91         pes.pid      = pid;
92         pes.input    = DMX_IN_FRONTEND;
93         pes.output   = DMX_OUT_DECODER;
94         pes.pes_type = DMX_PES_VIDEO0;
95         pes.flags    = 0;
96         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
97         {
98                 eWarning("video: DMX_SET_PES_FILTER: %m");
99                 return -errno;
100         }
101         if (::ioctl(m_fd_demux, DMX_START, &pes) < 0)
102         {
103                 eWarning("video: DMX_START: %m");
104                 return -errno;
105         }
106         
107         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
108                 eWarning("video: VIDEO_PLAY: %m");
109         else
110                 eDebug("video ok");
111         return 0;
112 }
113         
114 void eDVBVideo::stop()
115 {
116         if (::ioctl(m_fd, VIDEO_STOP) < 0)
117                 eWarning("video: VIDEO_STOP: %m");
118         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
119                 eWarning("video: DMX_STOP: %m");
120 }
121         
122 eDVBVideo::~eDVBVideo()
123 {
124         if (m_fd >= 0)
125                 ::close(m_fd);
126         if (m_fd_demux >= 0)
127                 ::close(m_fd_demux);
128 }
129
130 DEFINE_REF(eTSMPEGDecoder);
131
132 int eTSMPEGDecoder::setState()
133 {
134         int res = 0;
135         eDebug("changed %x", m_changed);
136         if (m_changed & changeAudio)
137         {
138                 if (m_audio)
139                         m_audio->stop();
140                 m_audio = 0;
141                 m_audio = new eDVBAudio(m_demux, 0);
142                 if (m_audio->startPid(m_apid))
143                 {
144                         eWarning("audio: startpid failed!");
145                         res = -1;
146                 }
147                 m_changed &= ~changeAudio;
148         }
149         if (m_changed & changeVideo)
150         {
151                 if (m_video)
152                         m_video->stop();
153                 m_video = 0;
154                 m_video = new eDVBVideo(m_demux, 0);
155                 if (m_video->startPid(m_vpid))
156                 {
157                         eWarning("video: startpid failed!");
158                         res = -1;
159                 }
160                 m_changed &= ~changeVideo;
161         }
162         return res;
163 }
164
165 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux)
166 {
167 }
168
169 eTSMPEGDecoder::~eTSMPEGDecoder()
170 {
171         m_vpid = m_apid = m_pcrpid = pidNone;
172         m_changed = -1;
173         setState();
174 }
175
176 RESULT eTSMPEGDecoder::setVideoPID(int vpid)
177 {
178         if (m_vpid != vpid)
179         {
180                 m_changed |= changeVideo;
181                 m_vpid = vpid;
182         }
183         return 0;
184 }
185
186 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
187 {
188         if ((m_apid != apid) || (m_atype != type))
189         {
190                 m_changed |= changeAudio;
191                 m_atype = type;
192                 m_apid = apid;
193         }
194         return 0;
195 }
196
197 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
198 {
199         if (m_pcrpid != pcrpid)
200         {
201                 m_changed |= changeAudio;
202                 m_pcrpid = pcrpid;
203         }
204         return -1;
205 }
206
207 RESULT eTSMPEGDecoder::setSyncMaster(int who)
208 {
209         return -1;
210 }
211
212 RESULT eTSMPEGDecoder::start()
213 {
214         return setState();
215 }
216
217 RESULT eTSMPEGDecoder::freeze(int cont)
218 {
219         return -1;
220 }
221
222 RESULT eTSMPEGDecoder::unfreeze()
223 {
224         return -1;
225 }
226
227 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
228 {
229         return -1;
230 }
231
232 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
233 {
234         return -1;
235 }
236
237 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
238 {
239         return -1;
240 }
241
242 RESULT eTSMPEGDecoder::setZoom(int what)
243 {
244         return -1;
245 }