gl_common: minor cleanup/refactor
[mplayer.git] / stream / stream_dvd_common.c
blobdb566e51368a5c291680aa871ba15aaa58bc5c3e
1 /*
2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include <fcntl.h>
20 #include <inttypes.h>
21 #include <unistd.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <libavutil/intreadwrite.h>
26 #include "config.h"
28 #include <dvdread/ifo_types.h>
30 #ifdef __FreeBSD__
31 #include <sys/cdrio.h>
32 #endif
34 #ifdef __linux__
35 #include <linux/cdrom.h>
36 #include <scsi/sg.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/ioctl.h>
40 #endif
42 #include "mp_msg.h"
43 #include "stream_dvd_common.h"
45 const char * const dvd_audio_stream_types[8] = { "ac3","unknown","mpeg1","mpeg2ext","lpcm","unknown","dts" };
46 const char * const dvd_audio_stream_channels[6] = { "mono", "stereo", "unknown", "unknown", "5.1/6.1", "5.1" };
48 int dvd_speed=0; /* 0 => don't touch speed */
50 void dvd_set_speed(char *device, unsigned speed)
52 #if defined(__linux__) && defined(SG_IO) && defined(GPCMD_SET_STREAMING)
53 int fd;
54 unsigned char buffer[28];
55 unsigned char cmd[12];
56 struct sg_io_hdr sghdr;
57 struct stat st;
59 memset(&st, 0, sizeof(st));
61 if (stat(device, &st) == -1) return;
63 if (!S_ISBLK(st.st_mode)) return; /* not a block device */
65 switch (speed) {
66 case 0: /* don't touch speed setting */
67 return;
68 case -1: /* restore default value */
69 if (dvd_speed == 0) return; /* we haven't touched the speed setting */
70 mp_tmsg(MSGT_OPEN, MSGL_INFO, "Restoring DVD speed... ");
71 break;
72 default: /* limit to <speed> KB/s */
73 // speed < 100 is multiple of DVD single speed (1350KB/s)
74 if (speed < 100)
75 speed *= 1350;
76 mp_tmsg(MSGT_OPEN, MSGL_INFO, "Limiting DVD speed to %dKB/s... ", speed);
77 break;
80 memset(&sghdr, 0, sizeof(sghdr));
81 sghdr.interface_id = 'S';
82 sghdr.timeout = 5000;
83 sghdr.dxfer_direction = SG_DXFER_TO_DEV;
84 sghdr.dxfer_len = sizeof(buffer);
85 sghdr.dxferp = buffer;
86 sghdr.cmd_len = sizeof(cmd);
87 sghdr.cmdp = cmd;
89 memset(cmd, 0, sizeof(cmd));
90 cmd[0] = GPCMD_SET_STREAMING;
91 cmd[10] = sizeof(buffer);
93 memset(buffer, 0, sizeof(buffer));
94 /* first sector 0, last sector 0xffffffff */
95 AV_WB32(buffer + 8, 0xffffffff);
96 if (speed == -1)
97 buffer[0] = 4; /* restore default */
98 else {
99 /* <speed> kilobyte */
100 AV_WB32(buffer + 12, speed);
101 AV_WB32(buffer + 20, speed);
103 /* 1 second */
104 AV_WB16(buffer + 18, 1000);
105 AV_WB16(buffer + 26, 1000);
107 fd = open(device, O_RDWR | O_NONBLOCK);
108 if (fd == -1) {
109 mp_tmsg(MSGT_OPEN, MSGL_INFO, "Couldn't open DVD device for writing, changing DVD speed needs write access.\n");
110 return;
113 if (ioctl(fd, SG_IO, &sghdr) < 0)
114 mp_tmsg(MSGT_OPEN, MSGL_INFO, "failed\n");
115 else
116 mp_tmsg(MSGT_OPEN, MSGL_INFO, "successful\n");
118 close(fd);
119 #endif
123 \brief Converts DVD time structure to milliseconds.
124 \param *dev the DVD time structure to convert
125 \return returns the time in milliseconds
127 int mp_dvdtimetomsec(dvd_time_t *dt)
129 static int framerates[4] = {0, 2500, 0, 2997};
130 int framerate = framerates[(dt->frame_u & 0xc0) >> 6];
131 int msec = (((dt->hour & 0xf0) >> 3) * 5 + (dt->hour & 0x0f)) * 3600000;
132 msec += (((dt->minute & 0xf0) >> 3) * 5 + (dt->minute & 0x0f)) * 60000;
133 msec += (((dt->second & 0xf0) >> 3) * 5 + (dt->second & 0x0f)) * 1000;
134 if(framerate > 0)
135 msec += (((dt->frame_u & 0x30) >> 3) * 5 + (dt->frame_u & 0x0f)) * 100000 / framerate;
136 return msec;