| 1123 | /* |
| 1124 | * \brief obtained from the mplayer project |
| 1125 | */ |
| 1126 | void DVDRingBufferPriv::SetDVDSpeed(const char *device, int speed) |
| 1127 | { |
| 1128 | #if defined(__linux__) && defined(SG_IO) && defined(GPCMD_SET_STREAMING) |
| 1129 | int fd; |
| 1130 | unsigned char buffer[28]; |
| 1131 | unsigned char cmd[16]; |
| 1132 | unsigned char sense[16]; |
| 1133 | struct sg_io_hdr sghdr; |
| 1134 | struct stat st; |
| 1135 | |
| 1136 | memset(&sghdr, 0, sizeof(sghdr)); |
| 1137 | memset(buffer, 0, sizeof(buffer)); |
| 1138 | memset(sense, 0, sizeof(sense)); |
| 1139 | memset(cmd, 0, sizeof(cmd)); |
| 1140 | memset(&st, 0, sizeof(st)); |
| 1141 | |
| 1142 | if (stat(device, &st) == -1 ) |
| 1143 | { |
| 1144 | VERBOSE(VB_PLAYBACK, LOC_ERR + |
| 1145 | QString("SetDVDSpeed() Failed. device %1 not found") |
| 1146 | .arg(device)); |
| 1147 | return; |
| 1148 | } |
| 1149 | |
| 1150 | if (!S_ISBLK(st.st_mode)) |
| 1151 | { |
| 1152 | VERBOSE(VB_PLAYBACK, LOC_ERR + |
| 1153 | "SetDVDSpeed() Failed. Not a block device"); |
| 1154 | return; |
| 1155 | } |
| 1156 | |
| 1157 | if ((fd = open(device, O_RDWR | O_NONBLOCK)) == -1) |
| 1158 | { |
| 1159 | VERBOSE(VB_PLAYBACK, LOC_ERR + |
| 1160 | "Changing DVD speed needs write access"); |
| 1161 | return; |
| 1162 | } |
| 1163 | |
| 1164 | if (speed < 100) |
| 1165 | speed *= 1350; |
| 1166 | |
| 1167 | switch(speed) |
| 1168 | { |
| 1169 | case 0: // don't touch speed setting |
| 1170 | return; |
| 1171 | case -1: // restore default value |
| 1172 | { |
| 1173 | speed = 0; |
| 1174 | buffer[0] = 4; |
| 1175 | VERBOSE(VB_PLAYBACK, LOC + "Restored DVD Speed"); |
| 1176 | break; |
| 1177 | } |
| 1178 | default: |
| 1179 | { |
| 1180 | QString msg; |
| 1181 | if (speed < 0) |
| 1182 | msg = "Normal"; |
| 1183 | else |
| 1184 | msg = QString("%1Kb/s").arg(speed); |
| 1185 | VERBOSE(VB_PLAYBACK, LOC + QString("Limit DVD Speed to %1") |
| 1186 | .arg(msg)); |
| 1187 | break; |
| 1188 | } |
| 1189 | } |
| 1190 | |
| 1191 | sghdr.interface_id = 'S'; |
| 1192 | sghdr.timeout = 5000; |
| 1193 | sghdr.dxfer_direction = SG_DXFER_TO_DEV; |
| 1194 | sghdr.mx_sb_len = sizeof(sense); |
| 1195 | sghdr.dxfer_len = sizeof(buffer); |
| 1196 | sghdr.cmd_len = sizeof(cmd); |
| 1197 | sghdr.sbp = sense; |
| 1198 | sghdr.dxferp = buffer; |
| 1199 | sghdr.cmdp = cmd; |
| 1200 | |
| 1201 | cmd[0] = GPCMD_SET_STREAMING; |
| 1202 | cmd[10] = sizeof(buffer); |
| 1203 | |
| 1204 | buffer[8] = 0xff; |
| 1205 | buffer[9] = 0xff; |
| 1206 | buffer[10] = 0xff; |
| 1207 | buffer[11] = 0xff; |
| 1208 | |
| 1209 | buffer[12] = buffer[20] = (speed >> 24) & 0xff; |
| 1210 | buffer[13] = buffer[21] = (speed >> 16) & 0xff; |
| 1211 | buffer[14] = buffer[22] = (speed >> 8) & 0xff; |
| 1212 | buffer[15] = buffer[23] = speed & 0xff; |
| 1213 | |
| 1214 | buffer[18] = buffer[26] = 0x03; |
| 1215 | buffer[19] = buffer[27] = 0xe8; |
| 1216 | |
| 1217 | if (ioctl(fd, SG_IO, &sghdr) < 0) |
| 1218 | VERBOSE(VB_PLAYBACK, LOC_ERR + "Limit DVD Speed Failed"); |
| 1219 | |
| 1220 | VERBOSE(VB_PLAYBACK, LOC + "Limiting DVD Speed Successful"); |
| 1221 | #else |
| 1222 | (void)speed; |
| 1223 | (void)device; |
| 1224 | #endif |
| 1225 | } |
| 1226 | |