diff -Nru dvd/i18n.c dvd-Speed/i18n.c --- dvd/i18n.c 2008-12-23 18:26:32.000000000 +0100 +++ dvd-Speed/i18n.c 2008-12-25 19:59:31.000000000 +0100 @@ -306,6 +306,32 @@ #endif }, { + "Setup.DVD$DVD-ROM Speed", // English + "DVD-ROM-Geschwindigkeit", // Deutsch + "DVD-ROM Speed", // Slovenski + "DVD-ROM Speed", // Italiano + "DVD-ROM Speed", // Nederlands + "DVD-ROM Speed", // Português + "DVD-ROM Speed", // Français + "DVD-ROM Speed", // Norsk + "DVD-ROM Speed", // suomi + "DVD-ROM Speed", // Polski + "DVD-ROM Speed", // Español + "DVD-ROM Speed", // ÅëëçíéêÜ (Greek) + "DVD-ROM Speed", // Svenska + "DVD-ROM Speed", // Romaneste + "DVD-ROM Speed", // Magyar + "DVD-ROM Speed", // Català + "DVD-ROM Speed", // ÀãááÚØÙ (Russian) + "DVD-ROM Speed", // Hrvatski (Croatian) + "DVD-ROM Speed", // Eesti + "DVD-ROM Speed", // Dansk + "DVD-ROM Speed", // Czech +#if VDRVERSNUM >= 10502 + "DVD-ROM Speed" // Türkçe +#endif + }, + { "Setup.DVD$Gain (analog)", "Verstärkung (analog)", // Deutsch "Ojaèanje (analogno)", // Slovenski diff -Nru dvd/player-dvd.c dvd-Speed/player-dvd.c --- dvd/player-dvd.c 2008-12-25 19:58:07.000000000 +0100 +++ dvd-Speed/player-dvd.c 2008-12-25 19:59:31.000000000 +0100 @@ -38,6 +38,11 @@ #include "control-dvd.h" #include "dvd.h" +/* Needed for DvdSetSpeed() */ +#include +#include +#include + /** * this was "weak"'s solution of a forced * SPU only stream choice, @@ -463,6 +468,7 @@ bool cDvdPlayer::HasBitStreamOut = false; bool cDvdPlayer::HasSoftDeviceOut = false; bool cDvdPlayer::SoftDeviceOutActive = false; +bool cDvdPlayer::DvdSetSpeedActive = false; const int cDvdPlayer::MaxAudioTracks = 0x20; const int cDvdPlayer::AudioTrackMask = 0x1F; @@ -875,6 +881,93 @@ return retval; } +/* This function was ripped off of mplayer */ +void cDvdPlayer::DvdSetSpeed(const char *device, int speed) +{ +#if defined(SG_IO) && defined(GPCMD_SET_STREAMING) + int fd; + unsigned char buffer[28]; + unsigned char cmd[12]; + unsigned char sense[16]; + struct sg_io_hdr sghdr; + struct stat st; + + memset(&sghdr, 0, sizeof(sghdr)); + memset(buffer, 0, sizeof(buffer)); + memset(sense, 0, sizeof(sense)); + memset(cmd, 0, sizeof(cmd)); + memset(&st, 0, sizeof(st)); + + if (stat(device, &st) == -1) { + esyslog("ERROR: dvd-plugin: DVD device %s doesn't exist", device); + return; + } + + if (!S_ISBLK(st.st_mode)) { + esyslog("ERROR: dvd-plugin: DVD device %s is not a block device", device); + return; + } + + if ((fd = open(device, O_RDWR | O_NONBLOCK)) == -1) { + esyslog("ERROR: dvd-plugin: Failed to open DVD device %s O_RDWR | O_NONBLOCK", device); + return; + } + + if (speed < 100 && speed > 0) { /* speed times 1350KB/s (DVD single speed) */ + speed *= 1350; + } + + switch (speed) { + case 0: /* don't touch speed setting */ + close(fd); + return; + case -1: /* restore default value */ + speed = 0; + buffer[0] = 4; /* restore default */ + isyslog("dvd-plugin: Restoring initial DVD drive speed"); + break; + default: /* limit to KB/s */ + isyslog("dvd-plugin: Limiting speed to %d KB/s", speed); + break; + } + + sghdr.interface_id = 'S'; + sghdr.timeout = 5000; + sghdr.dxfer_direction = SG_DXFER_TO_DEV; + sghdr.mx_sb_len = sizeof(sense); + sghdr.dxfer_len = sizeof(buffer); + sghdr.cmd_len = sizeof(cmd); + sghdr.sbp = sense; + sghdr.dxferp = buffer; + sghdr.cmdp = cmd; + + cmd[0] = GPCMD_SET_STREAMING; + cmd[10] = sizeof(buffer); + + buffer[8] = 0xff; /* first sector 0, last sector 0xffffffff */ + buffer[9] = 0xff; + buffer[10] = 0xff; + buffer[11] = 0xff; + + buffer[12] = buffer[20] = (speed >> 24) & 0xff; /* kilobyte */ + buffer[13] = buffer[21] = (speed >> 16) & 0xff; + buffer[14] = buffer[22] = (speed >> 8) & 0xff; + buffer[15] = buffer[23] = speed & 0xff; + + buffer[18] = buffer[26] = 0x03; /* 1 second */ + buffer[19] = buffer[27] = 0xe8; + + if (ioctl(fd, SG_IO, &sghdr) < 0) { + esyslog("ERROR: dvd-plugin: DVD speed limiting failed"); + close(fd); + return; + } + isyslog("dvd-plugin: DVD speed limiting successful"); + DvdSetSpeedActive = true; + close(fd); +#endif +} + void cDvdPlayer::Action(void) { memset(event_buf, 0, sizeof(uint8_t)*4096); @@ -900,12 +993,21 @@ } dsyslog("dvd-plugin: SoftDeviceOutActive=%d, HasSoftDeviceOut=%d", SoftDeviceOutActive, HasSoftDeviceOut); + /* Try to reduce drive speed if the user wants us to */ + if (DVDSetup.Speed) + DvdSetSpeed(const_cast(cDVD::getDVD()->DeviceName()), DVDSetup.Speed); + if (dvdnav_open(&nav, const_cast(cDVD::getDVD()->DeviceName())) != DVDNAV_STATUS_OK) { Skins.Message(mtError, tr("Error.DVD$Error opening DVD!")); esyslog("ERROR: dvd-plugin cannot open dvdnav device %s -> input thread ended (pid=%d) !", const_cast(cDVD::getDVD()->DeviceName()), getpid()); active = running = false; nav=NULL; fflush(NULL); + /* Try to restore drive speed if it was previously changed */ + if (DvdSetSpeedActive) { + DvdSetSpeed(const_cast(cDVD::getDVD()->DeviceName()), -1); + DvdSetSpeedActive = false; + } return; } dvdnav_set_readahead_flag(nav, DVDSetup.ReadAHead); @@ -1541,6 +1643,12 @@ dvdnav_close(nav); nav=NULL; + /* Try to restore drive speed if it was previously changed */ + if (DvdSetSpeedActive) { + DvdSetSpeed(const_cast(cDVD::getDVD()->DeviceName()), -1); + DvdSetSpeedActive = false; + } + DEBUGDVD("%s:%d: input thread ended (pid=%d)\n", __FILE__, __LINE__, getpid()); fflush(NULL); } diff -Nru dvd/player-dvd.h dvd-Speed/player-dvd.h --- dvd/player-dvd.h 2008-12-25 19:58:07.000000000 +0100 +++ dvd-Speed/player-dvd.h 2008-12-25 19:59:31.000000000 +0100 @@ -169,6 +169,7 @@ static bool HasBitStreamOut; static bool SoftDeviceOutActive; // currently used to switch for xine static bool HasSoftDeviceOut; // currently used to switch for xine + static bool DvdSetSpeedActive; //dvd stuff int currButtonN; @@ -255,6 +256,7 @@ void DrawSPU(); void HideSPU(); void EmptySPU(); + void DvdSetSpeed(const char*, int); void Pause(void); void Play(void); diff -Nru dvd/po/de_DE.po dvd-Speed/po/de_DE.po --- dvd/po/de_DE.po 2008-12-23 17:56:17.000000000 +0100 +++ dvd-Speed/po/de_DE.po 2008-12-25 20:00:02.000000000 +0100 @@ -51,5 +51,9 @@ msgid "Setup.DVD$ReadAHead" msgstr "ReadAHead" +#: setup-dvd.c:77 +msgid "Setup.DVD$DVD-ROM Speed" +msgstr "DVD-ROM-Geschwindigkeit" + msgid "Setup.DVD$Gain (analog)" msgstr "Verstärkung (analog)" diff -Nru dvd/po/fr_FR.po dvd-Speed/po/fr_FR.po --- dvd/po/fr_FR.po 2008-12-25 19:58:02.000000000 +0100 +++ dvd-Speed/po/fr_FR.po 2008-12-25 19:59:31.000000000 +0100 @@ -70,6 +70,10 @@ msgid "Setup.DVD$ReadAHead" msgstr "Lecture anticipée" +#: setup-dvd.c:77 +msgid "Setup.DVD$DVD-ROM Speed" +msgstr "DVD-ROM Speed" + #: setup-dvd.c:75 msgid "Setup.DVD$Gain (analog)" msgstr "Gain (analogique)" diff -Nru dvd/setup-dvd.c dvd-Speed/setup-dvd.c --- dvd/setup-dvd.c 2007-08-12 18:57:22.000000000 +0200 +++ dvd-Speed/setup-dvd.c 2008-12-25 19:59:31.000000000 +0100 @@ -35,6 +35,7 @@ Gain = 4; AC3dynrng = 0; + Speed = 0; } bool cDVDSetup::SetupParse(const char *Name, const char *Value) @@ -47,6 +48,7 @@ else if (!strcasecmp(Name, "ShowSubtitles")) ShowSubtitles = atoi(Value); else if (!strcasecmp(Name, "HideMainMenu")) HideMainMenu = atoi(Value); else if (!strcasecmp(Name, "ReadAHead")) ReadAHead = atoi(Value); + else if (!strcasecmp(Name, "Speed")) Speed = atoi(Value); else if (!strcasecmp(Name, "Gain")) Gain = atoi(Value); else return false; @@ -72,6 +74,7 @@ Add(new cMenuEditBoolItem(tr("Setup.DVD$Display subtitles"), &data.ShowSubtitles)); Add(new cMenuEditBoolItem(tr("Setup.DVD$Hide Mainmenu Entry"), &data.HideMainMenu)); Add(new cMenuEditBoolItem(tr("Setup.DVD$ReadAHead"), &data.ReadAHead)); + Add(new cMenuEditIntItem( tr("Setup.DVD$DVD-ROM Speed"), &data.Speed, 0, 4)); Add(new cMenuEditIntItem( tr("Setup.DVD$Gain (analog)"), &data.Gain, 0, 10)); } @@ -85,6 +88,7 @@ SetupStore("ShowSubtitles", DVDSetup.ShowSubtitles ); SetupStore("HideMainMenu", DVDSetup.HideMainMenu ); SetupStore("ReadAHead", DVDSetup.ReadAHead ); + SetupStore("Speed", DVDSetup.Speed ); SetupStore("Gain", DVDSetup.Gain ); } diff -Nru dvd/setup-dvd.h dvd-Speed/setup-dvd.h --- dvd/setup-dvd.h 2005-01-05 17:32:21.000000000 +0100 +++ dvd-Speed/setup-dvd.h 2008-12-25 19:59:31.000000000 +0100 @@ -23,6 +23,7 @@ int HideMainMenu; int ReadAHead; int Gain; + int Speed; // AC3 stuff int AC3dynrng;