1 | Index: libmythtv/DVDRingBuffer.cpp |
---|
2 | =================================================================== |
---|
3 | --- libmythtv/DVDRingBuffer.cpp (revision 13250) |
---|
4 | +++ libmythtv/DVDRingBuffer.cpp (working copy) |
---|
5 | @@ -1,17 +1,8 @@ |
---|
6 | #include <unistd.h> |
---|
7 | -#ifdef __linux__ |
---|
8 | -#include <linux/cdrom.h> |
---|
9 | -#include <scsi/sg.h> |
---|
10 | -#include <sys/types.h> |
---|
11 | -#include <sys/stat.h> |
---|
12 | -#include <sys/ioctl.h> |
---|
13 | -#include <fcntl.h> |
---|
14 | -#include <unistd.h> |
---|
15 | -#endif |
---|
16 | |
---|
17 | - |
---|
18 | #include "DVDRingBuffer.h" |
---|
19 | #include "mythcontext.h" |
---|
20 | +#include "mythmediamonitor.h" |
---|
21 | #include "iso639.h" |
---|
22 | |
---|
23 | #include "NuppelVideoPlayer.h" |
---|
24 | @@ -1150,109 +1141,22 @@ |
---|
25 | Seek(cellStart); |
---|
26 | } |
---|
27 | |
---|
28 | -/* |
---|
29 | - * \brief obtained from the mplayer project |
---|
30 | - */ |
---|
31 | void DVDRingBufferPriv::SetDVDSpeed(const char *device, int speed) |
---|
32 | { |
---|
33 | -#if defined(__linux__) && defined(SG_IO) && defined(GPCMD_SET_STREAMING) |
---|
34 | - int fd; |
---|
35 | - unsigned char buffer[28]; |
---|
36 | - unsigned char cmd[16]; |
---|
37 | - unsigned char sense[16]; |
---|
38 | - struct sg_io_hdr sghdr; |
---|
39 | - struct stat st; |
---|
40 | + // |
---|
41 | + // If it is OK to determine and lock the MythMediaDevice in |
---|
42 | + // OpenFile() and unlock in CloseDVD(), this can be done |
---|
43 | + // more efficiently. |
---|
44 | + MediaMonitor *mon = MediaMonitor::GetMediaMonitor(); |
---|
45 | |
---|
46 | - memset(&sghdr, 0, sizeof(sghdr)); |
---|
47 | - memset(buffer, 0, sizeof(buffer)); |
---|
48 | - memset(sense, 0, sizeof(sense)); |
---|
49 | - memset(cmd, 0, sizeof(cmd)); |
---|
50 | - memset(&st, 0, sizeof(st)); |
---|
51 | - |
---|
52 | - if (stat(device, &st) == -1 ) |
---|
53 | - { |
---|
54 | - VERBOSE(VB_PLAYBACK, LOC_ERR + |
---|
55 | - QString("SetDVDSpeed() Failed. device %1 not found") |
---|
56 | - .arg(device)); |
---|
57 | - return; |
---|
58 | - } |
---|
59 | - |
---|
60 | - if (!S_ISBLK(st.st_mode)) |
---|
61 | - { |
---|
62 | - VERBOSE(VB_PLAYBACK, LOC_ERR + |
---|
63 | - "SetDVDSpeed() Failed. Not a block device"); |
---|
64 | - return; |
---|
65 | - } |
---|
66 | - |
---|
67 | - if ((fd = open(device, O_RDWR | O_NONBLOCK)) == -1) |
---|
68 | - { |
---|
69 | - VERBOSE(VB_PLAYBACK, LOC_ERR + |
---|
70 | - "Changing DVD speed needs write access"); |
---|
71 | - return; |
---|
72 | - } |
---|
73 | - |
---|
74 | - if (speed > 0 && speed < 100) |
---|
75 | - speed *= 1350; |
---|
76 | - |
---|
77 | - switch(speed) |
---|
78 | - { |
---|
79 | - case 0: // don't touch speed setting |
---|
80 | - return; |
---|
81 | - case -1: // restore default value |
---|
82 | + if (mon != NULL ) { |
---|
83 | + MythMediaDevice *pMedia = mon->GetMedia(device); |
---|
84 | + if (mon->ValidateAndLock(pMedia)) |
---|
85 | { |
---|
86 | - speed = 0; |
---|
87 | - buffer[0] = 4; |
---|
88 | - VERBOSE(VB_PLAYBACK, LOC + "Restored DVD Speed"); |
---|
89 | - break; |
---|
90 | + pMedia->setSpeed(speed); |
---|
91 | + mon->Unlock(pMedia); |
---|
92 | } |
---|
93 | - default: |
---|
94 | - { |
---|
95 | - QString msg; |
---|
96 | - if (speed < 0) |
---|
97 | - msg = "Normal"; |
---|
98 | - else |
---|
99 | - msg = QString("%1Kb/s").arg(speed); |
---|
100 | - VERBOSE(VB_PLAYBACK, LOC + QString("Limit DVD Speed to %1") |
---|
101 | - .arg(msg)); |
---|
102 | - break; |
---|
103 | - } |
---|
104 | } |
---|
105 | - |
---|
106 | - sghdr.interface_id = 'S'; |
---|
107 | - sghdr.timeout = 5000; |
---|
108 | - sghdr.dxfer_direction = SG_DXFER_TO_DEV; |
---|
109 | - sghdr.mx_sb_len = sizeof(sense); |
---|
110 | - sghdr.dxfer_len = sizeof(buffer); |
---|
111 | - sghdr.cmd_len = sizeof(cmd); |
---|
112 | - sghdr.sbp = sense; |
---|
113 | - sghdr.dxferp = buffer; |
---|
114 | - sghdr.cmdp = cmd; |
---|
115 | - |
---|
116 | - cmd[0] = GPCMD_SET_STREAMING; |
---|
117 | - cmd[10] = sizeof(buffer); |
---|
118 | - |
---|
119 | - buffer[8] = 0xff; |
---|
120 | - buffer[9] = 0xff; |
---|
121 | - buffer[10] = 0xff; |
---|
122 | - buffer[11] = 0xff; |
---|
123 | - |
---|
124 | - buffer[12] = buffer[20] = (speed >> 24) & 0xff; |
---|
125 | - buffer[13] = buffer[21] = (speed >> 16) & 0xff; |
---|
126 | - buffer[14] = buffer[22] = (speed >> 8) & 0xff; |
---|
127 | - buffer[15] = buffer[23] = speed & 0xff; |
---|
128 | - |
---|
129 | - buffer[18] = buffer[26] = 0x03; |
---|
130 | - buffer[19] = buffer[27] = 0xe8; |
---|
131 | - |
---|
132 | - if (ioctl(fd, SG_IO, &sghdr) < 0) |
---|
133 | - VERBOSE(VB_PLAYBACK, LOC_ERR + "Limit DVD Speed Failed"); |
---|
134 | - |
---|
135 | - close(fd); |
---|
136 | - VERBOSE(VB_PLAYBACK, LOC + "Limiting DVD Speed Successful"); |
---|
137 | -#else |
---|
138 | - (void)speed; |
---|
139 | - (void)device; |
---|
140 | -#endif |
---|
141 | } |
---|
142 | |
---|
143 | /** |
---|
144 | Index: libmyth/mythmediamonitor.h |
---|
145 | =================================================================== |
---|
146 | --- libmyth/mythmediamonitor.h (revision 13250) |
---|
147 | +++ libmyth/mythmediamonitor.h (working copy) |
---|
148 | @@ -65,6 +65,7 @@ |
---|
149 | // first validate the pointer with ValidateAndLock(), if true is returned |
---|
150 | // it is safe to dereference the pointer. When finished call Unlock() |
---|
151 | QValueList<MythMediaDevice*> GetMedias(MediaType mediatype); |
---|
152 | + MythMediaDevice* GetMedia(const QString &path); |
---|
153 | |
---|
154 | void MonitorRegisterExtensions(uint mediaType, const QString &extensions); |
---|
155 | |
---|
156 | Index: libmyth/mythmedia.cpp |
---|
157 | =================================================================== |
---|
158 | --- libmyth/mythmedia.cpp (revision 13250) |
---|
159 | +++ libmyth/mythmedia.cpp (working copy) |
---|
160 | @@ -273,6 +273,17 @@ |
---|
161 | return MEDIAERR_UNSUPPORTED; |
---|
162 | } |
---|
163 | |
---|
164 | +bool MythMediaDevice::isSameDevice(const QString &path) |
---|
165 | +{ |
---|
166 | + return (path == m_DevicePath); |
---|
167 | +} |
---|
168 | + |
---|
169 | +void MythMediaDevice::setSpeed(int speed) |
---|
170 | +{ |
---|
171 | + (void)speed; |
---|
172 | + return; |
---|
173 | +} |
---|
174 | + |
---|
175 | MediaError MythMediaDevice::lock() |
---|
176 | { |
---|
177 | // We just open the device here, which may or may not do the trick, |
---|
178 | Index: libmyth/mythmediamonitor.cpp |
---|
179 | =================================================================== |
---|
180 | --- libmyth/mythmediamonitor.cpp (revision 13250) |
---|
181 | +++ libmyth/mythmediamonitor.cpp (working copy) |
---|
182 | @@ -379,6 +379,31 @@ |
---|
183 | } |
---|
184 | } |
---|
185 | |
---|
186 | +/** \fn MediaMonitor::GetMedia(const QString& path) |
---|
187 | + * \brief Get media device by pathname. Must be locked with ValidateAndLock(). |
---|
188 | + * |
---|
189 | + * \sa ValidateAndLock(MythMediaDevice *pMedia) |
---|
190 | + * \sa Unlock(MythMediaDevice *pMedia) |
---|
191 | + */ |
---|
192 | +MythMediaDevice* MediaMonitor::GetMedia(const QString& path) |
---|
193 | +{ |
---|
194 | + QMutexLocker locker(&m_DevicesLock); |
---|
195 | + |
---|
196 | + QValueList<MythMediaDevice*>::iterator it = m_Devices.begin(); |
---|
197 | + for (;it != m_Devices.end(); it++) |
---|
198 | + { |
---|
199 | + if ((*it)->isSameDevice(path) && |
---|
200 | + (((*it)->getStatus() == MEDIASTAT_USEABLE) || |
---|
201 | + ((*it)->getStatus() == MEDIASTAT_MOUNTED) || |
---|
202 | + ((*it)->getStatus() == MEDIASTAT_NOTMOUNTED))) |
---|
203 | + { |
---|
204 | + return(*it); |
---|
205 | + } |
---|
206 | + } |
---|
207 | + |
---|
208 | + return NULL; |
---|
209 | +} |
---|
210 | + |
---|
211 | /** \fn MediaMonitor::GetMedias(MediaType mediatype) |
---|
212 | * \brief Ask for available media. Must be locked with ValidateAndLock(). |
---|
213 | * |
---|
214 | Index: libmyth/mythcdrom-linux.cpp |
---|
215 | =================================================================== |
---|
216 | --- libmyth/mythcdrom-linux.cpp (revision 13250) |
---|
217 | +++ libmyth/mythcdrom-linux.cpp (working copy) |
---|
218 | @@ -2,11 +2,16 @@ |
---|
219 | #include "mythcdrom-linux.h" |
---|
220 | #include <sys/ioctl.h> // ioctls |
---|
221 | #include <linux/cdrom.h> // old ioctls for cdrom |
---|
222 | +#include <scsi/sg.h> |
---|
223 | +#include <fcntl.h> |
---|
224 | #include <errno.h> |
---|
225 | #include "mythcontext.h" |
---|
226 | #include <linux/iso_fs.h> |
---|
227 | #include <unistd.h> |
---|
228 | |
---|
229 | +#define LOC QString("mythcdrom-linux: ") |
---|
230 | +#define LOC_ERR QString("mythcdrom-linux, Error: ") |
---|
231 | + |
---|
232 | #define ASSUME_WANT_AUDIO 1 |
---|
233 | |
---|
234 | class MythCDROMLinux: public MythCDROM |
---|
235 | @@ -22,6 +27,8 @@ |
---|
236 | virtual bool checkOK(void); |
---|
237 | virtual MediaStatus checkMedia(void); |
---|
238 | virtual MediaError eject(bool open_close = true); |
---|
239 | + virtual void setSpeed(int speed); |
---|
240 | + virtual bool isSameDevice(const QString &path); |
---|
241 | virtual MediaError lock(void); |
---|
242 | virtual MediaError unlock(void); |
---|
243 | }; |
---|
244 | @@ -309,3 +316,134 @@ |
---|
245 | |
---|
246 | return MythMediaDevice::unlock(); |
---|
247 | } |
---|
248 | + |
---|
249 | +bool MythCDROMLinux::isSameDevice(const QString &path) |
---|
250 | +{ |
---|
251 | + dev_t new_rdev; |
---|
252 | + struct stat sb; |
---|
253 | + |
---|
254 | + if (stat(path, &sb) < 0) |
---|
255 | + { |
---|
256 | + VERBOSE(VB_IMPORTANT, "MythCDROMLinux::SameDevice() -- " + |
---|
257 | + QString("Failed to stat '%1'") |
---|
258 | + .arg(path) + ENO); |
---|
259 | + return false; |
---|
260 | + } |
---|
261 | + new_rdev = sb.st_rdev; |
---|
262 | + |
---|
263 | + // Check against m_DevicePath... |
---|
264 | + if (stat(m_DevicePath, &sb) < 0) |
---|
265 | + { |
---|
266 | + VERBOSE(VB_IMPORTANT, "MythCDROMLinux::SameDevice() -- " + |
---|
267 | + QString("Failed to stat '%1'") |
---|
268 | + .arg(m_DevicePath) + ENO); |
---|
269 | + return false; |
---|
270 | + } |
---|
271 | + return (sb.st_rdev == new_rdev); |
---|
272 | +} |
---|
273 | + |
---|
274 | +#if defined(SG_IO) && defined(GPCMD_SET_STREAMING) |
---|
275 | +/* |
---|
276 | + * \brief obtained from the mplayer project |
---|
277 | + */ |
---|
278 | +void MythCDROMLinux::setSpeed(int speed) |
---|
279 | +{ |
---|
280 | + int fd; |
---|
281 | + unsigned char buffer[28]; |
---|
282 | + unsigned char cmd[16]; |
---|
283 | + unsigned char sense[16]; |
---|
284 | + struct sg_io_hdr sghdr; |
---|
285 | + struct stat st; |
---|
286 | + int rate = 0; |
---|
287 | + |
---|
288 | + memset(&sghdr, 0, sizeof(sghdr)); |
---|
289 | + memset(buffer, 0, sizeof(buffer)); |
---|
290 | + memset(sense, 0, sizeof(sense)); |
---|
291 | + memset(cmd, 0, sizeof(cmd)); |
---|
292 | + memset(&st, 0, sizeof(st)); |
---|
293 | + |
---|
294 | + if (stat(m_DevicePath, &st) == -1 ) |
---|
295 | + { |
---|
296 | + VERBOSE(VB_IMPORTANT, LOC_ERR + |
---|
297 | + QString("setSpeed() Failed. device %1 not found") |
---|
298 | + .arg(m_DevicePath)); |
---|
299 | + return; |
---|
300 | + } |
---|
301 | + |
---|
302 | + if (!S_ISBLK(st.st_mode)) |
---|
303 | + { |
---|
304 | + VERBOSE(VB_IMPORTANT, LOC_ERR + |
---|
305 | + "MythCDROMLinux::SetSpeed() Failed. Not a block device"); |
---|
306 | + return; |
---|
307 | + } |
---|
308 | + |
---|
309 | + if ((fd = open(m_DevicePath, O_RDWR | O_NONBLOCK)) == -1) |
---|
310 | + { |
---|
311 | + VERBOSE(VB_IMPORTANT, LOC_ERR + |
---|
312 | + "Changing DVD speed needs write access"); |
---|
313 | + return; |
---|
314 | + } |
---|
315 | + |
---|
316 | + if (speed < 0) |
---|
317 | + speed = -1; |
---|
318 | + |
---|
319 | + switch(speed) |
---|
320 | + { |
---|
321 | + case 0: // don't touch speed setting |
---|
322 | + return; |
---|
323 | + case -1: // restore default value |
---|
324 | + { |
---|
325 | + rate = 0; |
---|
326 | + buffer[0] = 4; |
---|
327 | + VERBOSE(VB_IMPORTANT, LOC + "Restored DVD Speed"); |
---|
328 | + break; |
---|
329 | + } |
---|
330 | + default: |
---|
331 | + { |
---|
332 | + // Speed in Kilobyte/Second. 177KB/s is the maximum data rate |
---|
333 | + // for standard Audio CD's. |
---|
334 | + |
---|
335 | + rate = (speed > 0 && speed < 100) ? speed * 177 : speed; |
---|
336 | + |
---|
337 | + VERBOSE(VB_IMPORTANT, LOC + QString("Limit DVD Speed to %1KB/s") |
---|
338 | + .arg(rate)); |
---|
339 | + break; |
---|
340 | + } |
---|
341 | + } |
---|
342 | + |
---|
343 | + sghdr.interface_id = 'S'; |
---|
344 | + sghdr.timeout = 5000; |
---|
345 | + sghdr.dxfer_direction = SG_DXFER_TO_DEV; |
---|
346 | + sghdr.mx_sb_len = sizeof(sense); |
---|
347 | + sghdr.dxfer_len = sizeof(buffer); |
---|
348 | + sghdr.cmd_len = sizeof(cmd); |
---|
349 | + sghdr.sbp = sense; |
---|
350 | + sghdr.dxferp = buffer; |
---|
351 | + sghdr.cmdp = cmd; |
---|
352 | + |
---|
353 | + cmd[0] = GPCMD_SET_STREAMING; |
---|
354 | + cmd[10] = sizeof(buffer); |
---|
355 | + |
---|
356 | + buffer[8] = 0xff; |
---|
357 | + buffer[9] = 0xff; |
---|
358 | + buffer[10] = 0xff; |
---|
359 | + buffer[11] = 0xff; |
---|
360 | + |
---|
361 | + buffer[12] = buffer[20] = (rate >> 24) & 0xff; |
---|
362 | + buffer[13] = buffer[21] = (rate >> 16) & 0xff; |
---|
363 | + buffer[14] = buffer[22] = (rate >> 8) & 0xff; |
---|
364 | + buffer[15] = buffer[23] = rate & 0xff; |
---|
365 | + |
---|
366 | + // Note: 0x3e8 == 1000, hence speed = data amount per 1000 milliseconds. |
---|
367 | + buffer[18] = buffer[26] = 0x03; |
---|
368 | + buffer[19] = buffer[27] = 0xe8; |
---|
369 | + |
---|
370 | + // On my system (2.6.18 + ide-cd), SG_IO succeeds without doing anything, |
---|
371 | + // while CDROM_SELECT_SPEED works... |
---|
372 | + if (ioctl(fd, CDROM_SELECT_SPEED, speed) < 0) { |
---|
373 | + if (ioctl(fd, SG_IO, &sghdr) < 0) |
---|
374 | + VERBOSE(VB_IMPORTANT, LOC_ERR + "Limit DVD Speed Failed"); |
---|
375 | + } |
---|
376 | + else VERBOSE(VB_IMPORTANT, LOC + "Limiting DVD Speed Successful"); |
---|
377 | +} |
---|
378 | +#endif |
---|
379 | Index: libmyth/mythmedia.h |
---|
380 | =================================================================== |
---|
381 | --- libmyth/mythmedia.h (revision 13250) |
---|
382 | +++ libmyth/mythmedia.h (working copy) |
---|
383 | @@ -81,6 +81,8 @@ |
---|
384 | virtual MediaError testMedia() { return MEDIAERR_UNSUPPORTED; } |
---|
385 | virtual bool openDevice(); |
---|
386 | virtual bool closeDevice(); |
---|
387 | + virtual bool isSameDevice(const QString &path); |
---|
388 | + virtual void setSpeed(int speed); |
---|
389 | virtual MediaStatus checkMedia() = 0; // Derived classes MUST implement this. |
---|
390 | virtual MediaError eject(bool open_close = true); |
---|
391 | virtual MediaError lock(); |
---|