diff options
author | Martin Herkt <lachs0r@srsfckn.biz> | 2016-02-28 23:31:51 +0100 |
---|---|---|
committer | Martin Herkt <lachs0r@srsfckn.biz> | 2016-02-28 23:31:51 +0100 |
commit | 21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979 (patch) | |
tree | b9679cc1d2c7c3cab0f88c370015f34f6d0b27ca /stream | |
parent | d1d6257731866934717353fce484f5f472f845d1 (diff) | |
parent | 1f436f65f2ee4df6419ca68bd6426b8283db6d22 (diff) | |
download | mpv-21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979.tar.bz2 mpv-21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979.tar.xz |
Merge branch 'master' into release/current
Diffstat (limited to 'stream')
-rw-r--r-- | stream/cache.c | 17 | ||||
-rw-r--r-- | stream/cache_file.c | 15 | ||||
-rw-r--r-- | stream/dvb_tune.c | 156 | ||||
-rw-r--r-- | stream/dvb_tune.h | 2 | ||||
-rw-r--r-- | stream/dvbin.h | 3 | ||||
-rw-r--r-- | stream/stream.h | 1 | ||||
-rw-r--r-- | stream/stream_avdevice.c | 14 | ||||
-rw-r--r-- | stream/stream_dvb.c | 133 | ||||
-rw-r--r-- | stream/stream_dvdnav.c | 37 | ||||
-rw-r--r-- | stream/stream_memory.c | 14 |
10 files changed, 239 insertions, 153 deletions
diff --git a/stream/cache.c b/stream/cache.c index ff5dd9fca6..8c18d18b1a 100644 --- a/stream/cache.c +++ b/stream/cache.c @@ -96,7 +96,10 @@ struct priv { bool idle; // cache thread has stopped reading int64_t reads; // number of actual read attempts performed + bool enable_readahead; // actively read beyond read() position int64_t read_filepos; // client read position (mirrors cache->pos) + int64_t read_min; // file position until which the thread should + // read even if readahead is disabled int64_t eof_pos; @@ -208,6 +211,11 @@ static void cache_fill(struct priv *s) goto done; } + if (!s->enable_readahead && s->read_min <= s->max_filepos) { + s->idle = true; + return; + } + if (mp_cancel_test(s->cache->cancel)) goto done; @@ -372,6 +380,10 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg) case STREAM_CTRL_GET_CACHE_IDLE: *(int *)arg = s->idle; return STREAM_OK; + case STREAM_CTRL_SET_READAHEAD: + s->enable_readahead = *(int *)arg; + pthread_cond_signal(&s->wakeup); + return STREAM_OK; case STREAM_CTRL_GET_TIME_LENGTH: *(double *)arg = s->stream_time_length; return s->stream_time_length ? STREAM_OK : STREAM_UNSUPPORTED; @@ -447,6 +459,7 @@ static void cache_execute_control(struct priv *s) } else if (pos_changed || (ok && control_needs_flush(s->control))) { MP_VERBOSE(s, "Dropping cache due to control()\n"); s->read_filepos = stream_tell(s->stream); + s->read_min = s->read_filepos; s->control_flush = true; cache_drop_contents(s); } @@ -503,6 +516,7 @@ static int cache_fill_buffer(struct stream *cache, char *buffer, int max_len) double retry_time = 0; int64_t retry = s->reads - 1; // try at least 1 read on EOF while (1) { + s->read_min = s->read_filepos + max_len + 64 * 1024; readb = read_buffer(s, buffer, max_len, s->read_filepos); s->read_filepos += readb; if (readb > 0) @@ -541,7 +555,7 @@ static int cache_seek(stream_t *cache, int64_t pos) MP_ERR(s, "Attempting to seek before cached data in unseekable stream.\n"); r = 0; } else { - cache->pos = s->read_filepos = pos; + cache->pos = s->read_filepos = s->read_min = pos; s->eof = false; // so that cache_read() will actually wait for new data pthread_cond_signal(&s->wakeup); } @@ -616,6 +630,7 @@ int stream_cache_init(stream_t *cache, stream_t *stream, struct priv *s = talloc_zero(NULL, struct priv); s->log = cache->log; s->eof_pos = -1; + s->enable_readahead = true; cache_drop_contents(s); diff --git a/stream/cache_file.c b/stream/cache_file.c index 901b3f6f3b..4cf7060e83 100644 --- a/stream/cache_file.c +++ b/stream/cache_file.c @@ -1,19 +1,20 @@ /* * This file is part of mpv. * - * mpv is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ + #include <stdio.h> #include <stdint.h> diff --git a/stream/dvb_tune.c b/stream/dvb_tune.c index 7ec4bcd9e8..b83da040d0 100644 --- a/stream/dvb_tune.c +++ b/stream/dvb_tune.c @@ -40,8 +40,62 @@ #include "dvb_tune.h" #include "common/msg.h" -int dvb_get_tuner_type(int fe_fd, struct mp_log *log) +int dvb_get_tuner_types(int fe_fd, struct mp_log *log, int** tuner_types) { +#ifdef DVB_USE_S2API + /* S2API is the DVB API new since 2.6.28. + It allows to query frontends with multiple delivery systems. */ + struct dtv_property p[] = {{ .cmd = DTV_ENUM_DELSYS }}; + struct dtv_properties cmdseq = {.num = 1, .props = p}; + mp_verbose(log, "Querying tuner type via DVBv5 API for frontend FD %d\n", + fe_fd); + if ((ioctl(fe_fd, FE_GET_PROPERTY, &cmdseq)) < -0) { + mp_err(log, "FE_GET_PROPERTY error: %d, FD: %d\n\n", errno, fe_fd); + return 0; + } + int num_tuner_types = p[0].u.buffer.len; + mp_verbose(log, "Number of supported delivery systems: %d\n", num_tuner_types); + if (num_tuner_types == 0) { + mp_err(log, "Frontend FD %d returned no delivery systems!", fe_fd); + return 0; + } + (*tuner_types) = talloc_array(NULL, int, num_tuner_types); + int supported_tuners = 0; + for(;p[0].u.buffer.len > 0; p[0].u.buffer.len--) { + fe_delivery_system_t delsys = p[0].u.buffer.data[p[0].u.buffer.len - 1]; + /* Second level standards like like DVB-T2, DVB-S2 not treated here - + Cards can usually either only do S/T/C or both levels. + DVB-T2 probably needs more implementation details, + DVB-S2 is treated in the DVB-S branch already. */ + switch (delsys) { + case SYS_DVBT: + mp_verbose(log, "Tuner type seems to be DVB-T\n"); + (*tuner_types)[supported_tuners++] = TUNER_TER; + break; + case SYS_DVBC_ANNEX_AC: + mp_verbose(log, "Tuner type seems to be DVB-C\n"); + (*tuner_types)[supported_tuners++] = TUNER_CBL; + break; + case SYS_DVBS: + mp_verbose(log, "Tuner type seems to be DVB-S\n"); + (*tuner_types)[supported_tuners++] = TUNER_SAT; + break; +#ifdef DVB_ATSC + case SYS_ATSC: + mp_verbose(log, "Tuner type seems to be DVB-ATSC\n"); + (*tuner_types)[supported_tuners++] = TUNER_ATSC; + break; +#endif + case SYS_DVBS2: + // We actually handle that in the DVB-S branch, ok to ignore here. + mp_verbose(log, "Tuner supports DVB-S2\n"); + break; + default: + mp_err(log, "Unhandled tuner type: %d\n", delsys); + } + } + return supported_tuners; +#else struct dvb_frontend_info fe_info; int res = ioctl(fe_fd, FE_GET_INFO, &fe_info); if (res < 0) { @@ -49,29 +103,36 @@ int dvb_get_tuner_type(int fe_fd, struct mp_log *log) return 0; } + mp_verbose(log, "Queried tuner type of device named '%s', FD: %d\n", + fe_info.name, fe_fd); switch (fe_info.type) { case FE_OFDM: - mp_verbose(log, "TUNER TYPE SEEMS TO BE DVB-T\n"); - return TUNER_TER; - + mp_verbose(log, "Tuner type seems to be DVB-T\n"); + *tuner_types = talloc_array(NULL, int, 1); + (*tuner_types)[0] = TUNER_TER; + return 1; case FE_QPSK: - mp_verbose(log, "TUNER TYPE SEEMS TO BE DVB-S\n"); - return TUNER_SAT; - + mp_verbose(log, "Tuner type seems to be DVB-S\n"); + *tuner_types = talloc_array(NULL, int, 1); + (*tuner_types)[0] = TUNER_SAT; + return 1; case FE_QAM: - mp_verbose(log, "TUNER TYPE SEEMS TO BE DVB-C\n"); - return TUNER_CBL; - + mp_verbose(log, "Tuner type seems to be DVB-C\n"); + *tuner_types = talloc_array(NULL, int, 1); + (*tuner_types)[0] = TUNER_CBL; + return 1; #ifdef DVB_ATSC case FE_ATSC: - mp_verbose(log, "TUNER TYPE SEEMS TO BE DVB-ATSC\n"); - return TUNER_ATSC; + mp_verbose(log, "Tuner type seems to be DVB-ATSC\n"); + *tuner_types = talloc_array(NULL, int, 1); + (*tuner_types)[0] = TUNER_ATSC; + return 1; #endif default: - mp_err(log, "UNKNOWN TUNER TYPE\n"); + mp_err(log, "Unknown tuner type: %d\n", fe_info.type); return 0; } - +#endif } int dvb_open_devices(dvb_priv_t *priv, int n, int demux_cnt) @@ -80,7 +141,7 @@ int dvb_open_devices(dvb_priv_t *priv, int n, int demux_cnt) char frontend_dev[32], dvr_dev[32], demux_dev[32]; dvb_state_t* state = priv->state; - + sprintf(frontend_dev, "/dev/dvb/adapter%d/frontend0", n); sprintf(dvr_dev, "/dev/dvb/adapter%d/dvr0", n); sprintf(demux_dev, "/dev/dvb/adapter%d/demux0", n); @@ -119,7 +180,7 @@ int dvb_fix_demuxes(dvb_priv_t *priv, int cnt) { int i; char demux_dev[32]; - + dvb_state_t* state = priv->state; sprintf(demux_dev, "/dev/dvb/adapter%d/demux0", state->card); @@ -374,7 +435,7 @@ static int do_diseqc(int secfd, int sat_no, int polv, int hi_lo) (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A); } -static int tune_it(dvb_priv_t *priv, int fd_frontend, +static int tune_it(dvb_priv_t *priv, int fd_frontend, unsigned int freq, unsigned int srate, char pol, int tone, bool is_dvb_s2, int stream_id, fe_spectral_inversion_t specInv, unsigned int diseqc, @@ -387,21 +448,19 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, int timeout) { int hi_lo = 0, dfd; + + dvb_state_t* state = priv->state; + struct dvb_frontend_parameters feparams; - struct dvb_frontend_info fe_info; MP_VERBOSE(priv, "TUNE_IT, fd_frontend %d, freq %lu, srate %lu, " - "pol %c, tone %i, diseqc %u\n", fd_frontend, + "pol %c, tone %i, diseqc %u\n", fd_frontend, (long unsigned int)freq, (long unsigned int)srate, pol, tone, diseqc); memset(&feparams, 0, sizeof(feparams)); - if (ioctl(fd_frontend, FE_GET_INFO, &fe_info) < 0) { - MP_FATAL(priv, "FE_GET_INFO FAILED\n"); - return -1; - } - MP_VERBOSE(priv, "Using DVB card \"%s\"\n", fe_info.name); + MP_VERBOSE(priv, "Using DVB card \"%s\"\n", state->cards[state->card].name); { /* discard stale QPSK events */ @@ -412,8 +471,8 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, } } - switch (fe_info.type) { - case FE_OFDM: + switch (state->tuner_type) { + case TUNER_TER: { if (freq < 1000000) freq *= 1000UL; feparams.frequency = freq; @@ -431,8 +490,9 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, MP_ERR(priv, "ERROR tuning channel\n"); return -1; } - break; - case FE_QPSK: + } + break; + case TUNER_SAT: { // DVB-S if (freq > 2200000) { // this must be an absolute frequency @@ -509,8 +569,35 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, return -1; } #endif - break; - case FE_QAM: + } + break; + case TUNER_CBL: { +#ifdef DVB_USE_S2API + /* S2API is the DVB API new since 2.6.28. + * It is also needed for devices supporting multiple delivery systems, + * commonly DVB-C + DVB-T are supported here. + */ + fe_delivery_system_t delsys = SYS_DVBC_ANNEX_AC; + struct dtv_property p[] = { + { .cmd = DTV_DELIVERY_SYSTEM, .u.data = delsys }, + { .cmd = DTV_FREQUENCY, .u.data = freq }, + { .cmd = DTV_INVERSION, .u.data = specInv }, + { .cmd = DTV_MODULATION, .u.data = modulation }, + { .cmd = DTV_SYMBOL_RATE, .u.data = srate }, + { .cmd = DTV_INNER_FEC, .u.data = HP_CodeRate }, + { .cmd = DTV_TUNE }, + }; + struct dtv_properties cmdseq = { + .num = sizeof(p) / sizeof(p[0]), + .props = p + }; + MP_VERBOSE(priv, "tuning DVB-C to %d, srate=%d using DVBv5 API...\n", + freq, srate); + if ((ioctl(fd_frontend, FE_SET_PROPERTY, &cmdseq)) == -1) { + MP_ERR(priv, "ERROR tuning channel\n"); + return -1; + } +#else feparams.frequency = freq; feparams.inversion = specInv; feparams.u.qam.symbol_rate = srate; @@ -521,9 +608,11 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, MP_ERR(priv, "ERROR tuning channel\n"); return -1; } - break; +#endif + } + break; #ifdef DVB_ATSC - case FE_ATSC: + case TUNER_ATSC: { feparams.frequency = freq; feparams.u.vsb.modulation = modulation; MP_VERBOSE(priv, "tuning ATSC to %d, modulation=%d\n", freq, modulation); @@ -531,7 +620,8 @@ static int tune_it(dvb_priv_t *priv, int fd_frontend, MP_ERR(priv, "ERROR tuning channel\n"); return -1; } - break; + } + break; #endif default: MP_VERBOSE(priv, "Unknown FE type. Aborting\n"); diff --git a/stream/dvb_tune.h b/stream/dvb_tune.h index 50c598f810..dafa1175bd 100644 --- a/stream/dvb_tune.h +++ b/stream/dvb_tune.h @@ -23,7 +23,7 @@ struct mp_log; -int dvb_get_tuner_type(int fe_fd, struct mp_log *log); +int dvb_get_tuner_types(int fe_fd, struct mp_log *log, int** tuner_types); int dvb_open_devices(dvb_priv_t *priv, int n, int demux_cnt); int dvb_fix_demuxes(dvb_priv_t *priv, int cnt); int dvb_set_ts_filt(dvb_priv_t *priv, int fd, uint16_t pid, dmx_pes_type_t pestype); diff --git a/stream/dvbin.h b/stream/dvbin.h index e0688aa79e..9c2eb35e26 100644 --- a/stream/dvbin.h +++ b/stream/dvbin.h @@ -28,9 +28,10 @@ * Version 5 is also called S2API, it adds support for tuning to S2 channels * and is extensible for future delivery systems. Old API is deprecated. * StreamID-implementation only supported since API >=5.2. + * At least DTV_ENUM_DELSYS requires 5.5. */ -#if (DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 2) +#if (DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 5) #define DVB_USE_S2API 1 // This had a different name until API 5.8. diff --git a/stream/stream.h b/stream/stream.h index 11e70bcb7d..ab37c3b4bd 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -72,6 +72,7 @@ enum stream_ctrl { STREAM_CTRL_GET_CACHE_FILL, STREAM_CTRL_GET_CACHE_IDLE, STREAM_CTRL_RESUME_CACHE, + STREAM_CTRL_SET_READAHEAD, // stream_memory.c STREAM_CTRL_SET_CONTENTS, diff --git a/stream/stream_avdevice.c b/stream/stream_avdevice.c index d1fd74f1b3..9734b7b6f5 100644 --- a/stream/stream_avdevice.c +++ b/stream/stream_avdevice.c @@ -1,18 +1,18 @@ /* * This file is part of mpv. * - * mpv is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ #include "config.h" diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c index 8bc6c4e200..43ca8ac2b9 100644 --- a/stream/stream_dvb.c +++ b/stream/stream_dvb.c @@ -758,11 +758,6 @@ int dvb_step_channel(stream_t *stream, int dir) MP_VERBOSE(stream, "DVB_STEP_CHANNEL dir %d\n", dir); - if (priv == NULL) { - MP_ERR(stream, "dvb_step_channel: NULL priv_ptr, quit\n"); - return 0; - } - list = state->list; if (list == NULL) { MP_ERR(stream, "dvb_step_channel: NULL list_ptr, quit\n"); @@ -857,14 +852,14 @@ static void dvbin_close(stream_t *stream) dvb_state_t* state = priv->state; if (state->switching_channel && state->is_on) { - // Prevent state destruction, reset channel-switch. + // Prevent state destruction, reset channel-switch. state->switching_channel = false; pthread_mutex_lock(&global_dvb_state_lock); global_dvb_state->stream_used = false; pthread_mutex_unlock(&global_dvb_state_lock); return; } - + for (int i = state->demux_fds_cnt - 1; i >= 0; i--) { state->demux_fds_cnt--; MP_VERBOSE(stream, "DVBIN_CLOSE, close(%d), fd=%d, COUNT=%d\n", i, @@ -877,7 +872,7 @@ static void dvbin_close(stream_t *stream) state->fe_fd = state->dvr_fd = -1; state->is_on = 0; - + pthread_mutex_lock(&global_dvb_state_lock); dvb_free_state(state); global_dvb_state = NULL; @@ -947,18 +942,19 @@ static int dvb_open(stream_t *stream) } dvb_state_t* state = dvb_get_state(stream); - state->stream_used = true; - pthread_mutex_unlock(&global_dvb_state_lock); - + priv->state = state; if (state == NULL) { MP_ERR(stream, "DVB CONFIGURATION IS EMPTY, exit\n"); + pthread_mutex_unlock(&global_dvb_state_lock); return STREAM_ERROR; } + state->stream_used = true; + pthread_mutex_unlock(&global_dvb_state_lock); if (state->is_on != 1) { - // State could be already initialized, for example, we just did a channel switch. - // The following setup only has to be done once. + // State could be already initialized, for example, we just did a channel switch. + // The following setup only has to be done once. state->card = -1; for (i = 0; i < state->count; i++) { @@ -1000,7 +996,7 @@ static int dvb_open(stream_t *stream) if (!dvb_streaming_start(stream, tuner_type, progname)) return STREAM_ERROR; } - + stream->type = STREAMTYPE_DVB; stream->fill_buffer = dvb_streaming_read; stream->close = dvbin_close; @@ -1031,7 +1027,7 @@ dvb_state_t *dvb_get_state(stream_t *stream) state = malloc(sizeof(dvb_state_t)); if (state == NULL) return NULL; - + state->count = 0; state->switching_channel = false; state->stream_used = true; @@ -1046,78 +1042,89 @@ dvb_state_t *dvb_get_state(stream_t *stream) continue; } - type = dvb_get_tuner_type(fd, log); + mp_verbose(log, "Opened device %s, FD: %d\n", filename, fd); + int* tuner_types = NULL; + int num_tuner_types = dvb_get_tuner_types(fd, log, &tuner_types); close(fd); - if (type != TUNER_SAT && type != TUNER_TER && type != TUNER_CBL && - type != TUNER_ATSC) { + mp_verbose(log, "Frontend device %s offers %d supported delivery systems.\n", + filename, num_tuner_types); + for (int num_tuner_type=0; num_tuner_type<num_tuner_types; num_tuner_type++) { + type = tuner_types[num_tuner_type]; + if (type != TUNER_SAT && type != TUNER_TER && type != TUNER_CBL && + type != TUNER_ATSC) { mp_verbose(log, "DVB_CONFIG, can't detect tuner type of " "card %d, skipping\n", i); continue; - } + } - void *talloc_ctx = talloc_new(NULL); - char *conf_file = NULL; - if (priv->cfg_file && priv->cfg_file[0]) + void *talloc_ctx = talloc_new(NULL); + char *conf_file = NULL; + if (priv->cfg_file && priv->cfg_file[0]) conf_file = priv->cfg_file; - else { + else { switch (type) { case TUNER_TER: - conf_file = mp_find_config_file(talloc_ctx, global, - "channels.conf.ter"); - break; + conf_file = mp_find_config_file(talloc_ctx, global, + "channels.conf.ter"); + break; case TUNER_CBL: - conf_file = mp_find_config_file(talloc_ctx, global, - "channels.conf.cbl"); - break; + conf_file = mp_find_config_file(talloc_ctx, global, + "channels.conf.cbl"); + break; case TUNER_SAT: - conf_file = mp_find_config_file(talloc_ctx, global, - "channels.conf.sat"); - break; + conf_file = mp_find_config_file(talloc_ctx, global, + "channels.conf.sat"); + break; case TUNER_ATSC: - conf_file = mp_find_config_file(talloc_ctx, global, - "channels.conf.atsc"); - break; + conf_file = mp_find_config_file(talloc_ctx, global, + "channels.conf.atsc"); + break; } if (conf_file) { - mp_verbose(log, "Ignoring other channels.conf files.\n"); + mp_verbose(log, "Ignoring other channels.conf files.\n"); } else { - conf_file = mp_find_config_file(talloc_ctx, global, - "channels.conf"); + conf_file = mp_find_config_file(talloc_ctx, global, + "channels.conf"); } - } + } - list = dvb_get_channels(log, priv->cfg_full_transponder, conf_file, - type); - talloc_free(talloc_ctx); + list = dvb_get_channels(log, priv->cfg_full_transponder, conf_file, + type); + talloc_free(talloc_ctx); - if (list == NULL) + if (list == NULL) continue; - size = sizeof(dvb_card_config_t) * (state->count + 1); - tmp = realloc(state->cards, size); + size = sizeof(dvb_card_config_t) * (state->count + 1); + tmp = realloc(state->cards, size); - if (tmp == NULL) { - fprintf(stderr, "DVB_CONFIG, can't realloc %d bytes, skipping\n", - size); + if (tmp == NULL) { + mp_err(log, "DVB_CONFIG, can't realloc %d bytes, skipping\n", + size); + free(list); continue; - } - cards = tmp; + } + cards = tmp; - name = malloc(20); - if (name == NULL) { - fprintf(stderr, "DVB_CONFIG, can't realloc 20 bytes, skipping\n"); + name = malloc(20); + if (name == NULL) { + mp_err(log, "DVB_CONFIG, can't realloc 20 bytes, skipping\n"); + free(list); + free(tmp); continue; - } + } - state->cards = cards; - state->cards[state->count].devno = i; - state->cards[state->count].list = list; - state->cards[state->count].type = type; - snprintf(name, 20, "DVB-%c card n. %d", - type == TUNER_TER ? 'T' : (type == TUNER_CBL ? 'C' : 'S'), - state->count + 1); - state->cards[state->count].name = name; - state->count++; + state->cards = cards; + state->cards[state->count].devno = i; + state->cards[state->count].list = list; + state->cards[state->count].type = type; + snprintf(name, 20, "DVB-%c card n. %d", + type == TUNER_TER ? 'T' : (type == TUNER_CBL ? 'C' : 'S'), + state->count + 1); + state->cards[state->count].name = name; + state->count++; + } + talloc_free(tuner_types); } if (state->count == 0) { diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index e2562dbcbc..d61ca5c937 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -332,8 +332,7 @@ static int control(stream_t *stream, int cmd, void *arg) case STREAM_CTRL_SEEK_TO_TIME: { double *args = arg; double d = args[0]; // absolute target timestamp - double r = args[1]; // if not SEEK_ABSOLUTE, the base time for d - int flags = args[2]; // from SEEK_* flags (demux.h) + int flags = args[1]; // from SEEK_* flags (demux.h) if (flags & SEEK_HR) d -= 10; // fudge offset; it's a hack, because fuck libdvd* int64_t tm = (int64_t)(d * 90000); @@ -344,37 +343,9 @@ static int control(stream_t *stream, int cmd, void *arg) uint32_t pos, len; if (dvdnav_get_position(dvdnav, &pos, &len) != DVDNAV_STATUS_OK) break; - // The following is convoluted, because we have to translate between - // dvdnav's block/CBR-based seeking bullshit, and the player's - // timestamp-based high-level machinery. - if (!(flags & SEEK_ABSOLUTE) && !(flags & SEEK_HR) && priv->duration > 0) - { - int dir = (flags & SEEK_BACKWARD) ? -1 : 1; - // The user is making a relative seek (translated to absolute), - // and we try not to get the user stuck on "boundaries". So try - // to do block based seeks, which should workaround libdvdnav's - // terrible CBR-based seeking. - d -= r; // relative seek amount in seconds - d = d / (priv->duration / 1000.0) * len; // d is now in blocks - d += pos; // absolute target in blocks - if (dir > 0) - d = MPMAX(d, pos + 1.0); - if (dir < 0) - d = MPMIN(d, pos - 1.0); - d += 0.5; // round - uint32_t target = MPCLAMP(d, 0, len); - MP_VERBOSE(stream, "seek from block %lu to %lu, dir=%d\n", - (unsigned long)pos, (unsigned long)target, dir); - if (dvdnav_sector_search(dvdnav, target, SEEK_SET) != DVDNAV_STATUS_OK) - break; - } else { - // "old" method, should be good enough for large seeks. Used for - // hr-seeks (with fudge offset), because I fear that block-based - // seeking might be off too far for large jumps. - MP_VERBOSE(stream, "seek to PTS %f (%"PRId64")\n", d, tm); - if (dvdnav_time_search(dvdnav, tm) != DVDNAV_STATUS_OK) - break; - } + MP_VERBOSE(stream, "seek to PTS %f (%"PRId64")\n", d, tm); + if (dvdnav_time_search(dvdnav, tm) != DVDNAV_STATUS_OK) + break; stream_drop_buffers(stream); d = dvdnav_get_current_time(dvdnav) / 90000.0f; MP_VERBOSE(stream, "landed at: %f\n", d); diff --git a/stream/stream_memory.c b/stream/stream_memory.c index a451e0f722..4bcb860c49 100644 --- a/stream/stream_memory.c +++ b/stream/stream_memory.c @@ -1,18 +1,18 @@ /* * This file is part of mpv. * - * mpv is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ #include <libavutil/common.h> |