From cf36e3d15b31958927b81b9ec99793c3a99bafc2 Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 13 Sep 2019 15:35:23 +0200 Subject: stream_dvdnav: merge stream_dvd_common Isolate icky DVD garbage into a single file. --- stream/stream_dvdnav.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 3 deletions(-) (limited to 'stream/stream_dvdnav.c') diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index 55ce771896..84d8c8b0f1 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -15,8 +15,6 @@ * with mpv. If not, see . */ -#include - #include "config.h" #if !HAVE_GPL @@ -31,7 +29,17 @@ #include #include +#ifdef __linux__ +#include +#include +#include +#include +#include +#endif + #include +#include +#include #include "osdep/io.h" @@ -44,7 +52,6 @@ #include "stream.h" #include "demux/demux.h" #include "video/out/vo.h" -#include "stream_dvd_common.h" #define TITLE_MENU -1 #define TITLE_LONGEST -2 @@ -87,6 +94,102 @@ static const char *const mp_dvdnav_events[] = { #define LOOKUP_NAME(array, i) \ (((i) >= 0 && (i) < MP_ARRAY_SIZE(array)) ? array[(i)] : "?") +static void dvd_set_speed(stream_t *stream, char *device, unsigned speed) +{ +#if defined(__linux__) && defined(SG_IO) && defined(GPCMD_SET_STREAMING) + int fd; + unsigned char buffer[28]; + unsigned char cmd[12]; + struct sg_io_hdr sghdr; + struct stat st; + + memset(&st, 0, sizeof(st)); + + if (stat(device, &st) == -1) return; + + if (!S_ISBLK(st.st_mode)) return; /* not a block device */ + + switch (speed) { + case 0: /* don't touch speed setting */ + return; + case -1: /* restore default value */ + MP_INFO(stream, "Restoring DVD speed... "); + break; + default: /* limit to KB/s */ + // speed < 100 is multiple of DVD single speed (1350KB/s) + if (speed < 100) + speed *= 1350; + MP_INFO(stream, "Limiting DVD speed to %dKB/s... ", speed); + break; + } + + memset(&sghdr, 0, sizeof(sghdr)); + sghdr.interface_id = 'S'; + sghdr.timeout = 5000; + sghdr.dxfer_direction = SG_DXFER_TO_DEV; + sghdr.dxfer_len = sizeof(buffer); + sghdr.dxferp = buffer; + sghdr.cmd_len = sizeof(cmd); + sghdr.cmdp = cmd; + + memset(cmd, 0, sizeof(cmd)); + cmd[0] = GPCMD_SET_STREAMING; + cmd[10] = sizeof(buffer); + + memset(buffer, 0, sizeof(buffer)); + /* first sector 0, last sector 0xffffffff */ + AV_WB32(buffer + 8, 0xffffffff); + if (speed == -1) + buffer[0] = 4; /* restore default */ + else { + /* kilobyte */ + AV_WB32(buffer + 12, speed); + AV_WB32(buffer + 20, speed); + } + /* 1 second */ + AV_WB16(buffer + 18, 1000); + AV_WB16(buffer + 26, 1000); + + fd = open(device, O_RDWR | O_NONBLOCK | O_CLOEXEC); + if (fd == -1) { + MP_INFO(stream, "Couldn't open DVD device for writing, changing DVD speed needs write access.\n"); + return; + } + + if (ioctl(fd, SG_IO, &sghdr) < 0) + MP_INFO(stream, "failed\n"); + else + MP_INFO(stream, "successful\n"); + + close(fd); +#endif +} + +// Check if this is likely to be an .ifo or similar file. +static int dvd_probe(const char *path, const char *ext, const char *sig) +{ + if (!bstr_case_endswith(bstr0(path), bstr0(ext))) + return false; + + FILE *temp = fopen(path, "rb"); + if (!temp) + return false; + + bool r = false; + + char data[50]; + + assert(strlen(sig) <= sizeof(data)); + + if (fread(data, 50, 1, temp) == 1) { + if (memcmp(data, sig, strlen(sig)) == 0) + r = true; + } + + fclose(temp); + return r; +} + /** * \brief mp_dvdnav_lang_from_aid() returns the language corresponding to audio id 'aid' * \param stream: - stream pointer -- cgit v1.2.3