You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(235) |
Aug
(290) |
Sep
(419) |
Oct
(496) |
Nov
(545) |
Dec
(434) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(346) |
Feb
(224) |
Mar
(339) |
Apr
(401) |
May
(366) |
Jun
(570) |
Jul
(491) |
Aug
(369) |
Sep
(479) |
Oct
(681) |
Nov
(752) |
Dec
(998) |
2003 |
Jan
(902) |
Feb
(510) |
Mar
(590) |
Apr
(467) |
May
(529) |
Jun
(210) |
Jul
(208) |
Aug
(219) |
Sep
(155) |
Oct
(497) |
Nov
(416) |
Dec
(400) |
2004 |
Jan
(270) |
Feb
(175) |
Mar
(285) |
Apr
(404) |
May
(271) |
Jun
(323) |
Jul
(196) |
Aug
(145) |
Sep
(238) |
Oct
(260) |
Nov
(382) |
Dec
(437) |
2005 |
Jan
(251) |
Feb
(151) |
Mar
(80) |
Apr
(205) |
May
(266) |
Jun
(125) |
Jul
(308) |
Aug
(184) |
Sep
(188) |
Oct
(221) |
Nov
(132) |
Dec
(98) |
2006 |
Jan
(123) |
Feb
(150) |
Mar
(161) |
Apr
(152) |
May
(115) |
Jun
(259) |
Jul
(265) |
Aug
(81) |
Sep
(185) |
Oct
(121) |
Nov
(86) |
Dec
(257) |
2007 |
Jan
(233) |
Feb
(210) |
Mar
(306) |
Apr
(628) |
May
(347) |
Jun
(373) |
Jul
(71) |
Aug
(122) |
Sep
(53) |
Oct
(66) |
Nov
(156) |
Dec
(451) |
2008 |
Jan
(407) |
Feb
(136) |
Mar
(277) |
Apr
(119) |
May
(254) |
Jun
(162) |
Jul
(53) |
Aug
(43) |
Sep
(6) |
Oct
(3) |
Nov
(58) |
Dec
(51) |
2009 |
Jan
(161) |
Feb
(43) |
Mar
(30) |
Apr
(31) |
May
(15) |
Jun
(9) |
Jul
(1) |
Aug
(13) |
Sep
(1) |
Oct
(32) |
Nov
(319) |
Dec
(66) |
2010 |
Jan
(93) |
Feb
(41) |
Mar
(76) |
Apr
(56) |
May
(15) |
Jun
(21) |
Jul
(35) |
Aug
|
Sep
|
Oct
(6) |
Nov
|
Dec
|
2012 |
Jan
(77) |
Feb
(54) |
Mar
(5) |
Apr
(29) |
May
(35) |
Jun
(63) |
Jul
(26) |
Aug
(22) |
Sep
(3) |
Oct
|
Nov
|
Dec
(8) |
2013 |
Jan
(14) |
Feb
(5) |
Mar
(8) |
Apr
(12) |
May
(4) |
Jun
(2) |
Jul
(8) |
Aug
(10) |
Sep
(90) |
Oct
(21) |
Nov
(28) |
Dec
(12) |
2014 |
Jan
(6) |
Feb
(27) |
Mar
(19) |
Apr
(47) |
May
(67) |
Jun
(22) |
Jul
(6) |
Aug
(19) |
Sep
(1) |
Oct
(2) |
Nov
(15) |
Dec
(11) |
2015 |
Jan
|
Feb
(5) |
Mar
(1) |
Apr
(3) |
May
(1) |
Jun
|
Jul
(2) |
Aug
(4) |
Sep
|
Oct
(1) |
Nov
|
Dec
(10) |
2016 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
(3) |
Jul
|
Aug
(5) |
Sep
(20) |
Oct
(6) |
Nov
(24) |
Dec
(12) |
2017 |
Jan
(37) |
Feb
(159) |
Mar
(206) |
Apr
(167) |
May
(49) |
Jun
(14) |
Jul
(48) |
Aug
(9) |
Sep
(79) |
Oct
(101) |
Nov
(68) |
Dec
(42) |
2018 |
Jan
(70) |
Feb
(76) |
Mar
(152) |
Apr
(161) |
May
(15) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Torsten J. <t....@gm...> - 2018-05-11 17:39:52
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1526060350 -7200 # Node ID ac2674b23cf884267839caa90e88f963a46b647f # Branch default # Parent 0c67e8ced9453c585789661528dbf89d1fb24ea4 Optimize demux_ts. - Use HAVE_ZERO_SAFE_MEM. - Use _X_BE_32 (). - Move read buffer to end of instace struct. - Employ pid index table instead of searching on each packet. - Fast inline memcpy for small packet payloads on x86. - Defer discontinuity handling to buffer send. No need to burn cpu on every ts packet, and to tell engine far early. - Merge some calls to private functions (smaller code with inlining). - New packet reader. - Simplify. - NULL test. - More debug messages. - Silence -Wextra warnings. diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -159,7 +159,7 @@ /* #define LOG */ -/* #define LOG_DYNAMIC_PMT */ +#define LOG_DYNAMIC_PMT #include "group_video.h" @@ -167,6 +167,8 @@ #include <xine/xineutils.h> #include <xine/demux.h> +#include "bswap.h" + /* #define TS_LOG #define TS_PMT_LOG @@ -176,6 +178,33 @@ #define TS_HEADER_LOG // prints out the Transport packet header. */ +/* Packet readers: 1 (original), 2 (fast experimental) */ +#define TS_PACKET_READER 2 + +#if ((defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)) && defined(ARCH_X86) +static void demux_ts_small_memcpy (void *d, const void *s, size_t l) { + __asm__ __volatile__ ( + "cld\n\trep movsb" + : "=D" (d), "=S" (s), "=c" (l) + : "0" (d), "1" (s), "2" (l) + : "cc" + ); +} +#else +# define demux_ts_small_memcpy(d,s,l) memcpy (d, s, l) +#endif + +/* transport stream packet layer */ +#define TSP_sync_byte 0xff000000 +#define TSP_transport_error 0x00800000 +#define TSP_payload_unit_start 0x00400000 +#define TSP_transport_priority 0x00200000 +#define TSP_pid 0x001fff00 +#define TSP_scrambling_control 0x000000c0 +#define TSP_adaptation_field_1 0x00000020 +#define TSP_adaptation_field_0 0x00000010 +#define TSP_continuity_counter 0x0000000f + /* * The maximum number of PIDs we are prepared to handle in a single program * is the number that fits in a single-packet PMT. @@ -185,15 +214,21 @@ /* more PIDS are needed due "auto-detection". 40 spare media entries */ #define MAX_PIDS ((BODY_SIZE - 1 - 13) / 4) + 40 -#define MAX_PMTS 128 +#define MAX_PMTS 126 #define PAT_BUF_SIZE (4 * MAX_PMTS + 20) #define SYNC_BYTE 0x47 -#define MIN_SYNCS 3 -#define NPKT_PER_READ 96 // 96*188 = 94*192 - -#define BUF_SIZE (NPKT_PER_READ * (PKT_SIZE + 4)) +#if TS_PACKET_READER == 1 +# define MIN_SYNCS 3 +# define NPKT_PER_READ 96 // 96*188 = 94*192 +# define BUF_SIZE (NPKT_PER_READ * (PKT_SIZE + 4)) +#endif + +#if TS_PACKET_READER == 2 + /* smallest common multiple of 188 and 192 is 9024 */ +# define BUF_SIZE (2 * 9024) +#endif #define CORRUPT_PES_THRESHOLD 10 @@ -301,9 +336,9 @@ */ typedef struct { unsigned int pid; - fifo_buffer_t *fifo; uint32_t type; int64_t pts; + fifo_buffer_t *fifo; buf_element_t *buf; unsigned int counter; uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */ @@ -366,8 +401,8 @@ uint32_t last_pat_crc; uint32_t transport_stream_id; /* programs */ - uint32_t program_number[MAX_PMTS]; - uint32_t pmt_pid[MAX_PMTS]; + uint32_t program_number[MAX_PMTS + 1]; + uint32_t pmt_pid[MAX_PMTS + 1]; uint8_t *pmt[MAX_PMTS]; int pmt_write_pos[MAX_PMTS]; uint32_t last_pmt_crc; @@ -403,12 +438,13 @@ /* dvb */ xine_event_queue_t *event_queue; + +#if TS_PACKET_READER == 1 /* For syncronisation */ int32_t packet_number; /* NEW: var to keep track of number of last read packets */ int32_t npkt_read; - - uint8_t buf[BUF_SIZE]; /* == PKT_SIZE * NPKT_PER_READ */ +#endif off_t frame_pos; /* current ts packet position in input stream (bytes from beginning) */ @@ -417,6 +453,17 @@ int64_t tbre_time, tbre_lasttime; unsigned int tbre_mode, tbre_pid; + /* 0x00 | media_index (video/audio/subtitle) + * 0x80 | pmt_index (pmt) + * 0xff (special/unused) */ + uint8_t pid_index[0x2000]; [... 1055 lines omitted ...] - } - /* DVBSUB */ - else if (pid == this->spu_pid) { -#ifdef TS_LOG - printf ("demux_ts: SPU pid: 0x%.4x\n", pid); -#endif - demux_ts_buffer_pes (this, originalPkt+data_offset, this->spu_media, - payload_unit_start_indicator, continuity_counter, - data_len); - return; - } + if (pid == 0x1ffb) { + /* printf ("demux_ts: PSIP table. Program Guide etc....not supported yet. PID = 0x1ffb\n"); */ + return; } } @@ -2513,6 +2668,10 @@ } else { this->input->seek (this->input, start_pos, SEEK_SET); } +#if TS_PACKET_READER == 2 + this->buf_pos = 0; + this->buf_size = 0; +#endif } this->send_newpts = 1; @@ -2566,6 +2725,7 @@ static uint32_t demux_ts_get_capabilities(demux_plugin_t *this_gen) { + (void)this_gen; return DEMUX_CAP_AUDIOLANG | DEMUX_CAP_SPULANG; } @@ -2629,7 +2789,7 @@ for (i = 0; i < ts_size; i++) { try_again = 0; if (buf[i] == SYNC_BYTE) { - for (j = 1; j < packs; j++) { + for (j = 1; j < (int)packs; j++) { if (buf[i + j*ts_size] != SYNC_BYTE) { try_again = 1; break; @@ -2686,7 +2846,22 @@ * if we reach this point, the input has been accepted. */ - this = calloc(1, sizeof(*this)); + this = calloc (1, sizeof (*this)); + if (!this) + return NULL; + +#ifndef HAVE_ZERO_SAFE_MEM + this->last_pat_crc = 0; + this->scrambled_npids = 0; + this->audio_tracks_count = 0; + this->last_pmt_crc = 0; + this->spu_langs_count = 0; +# if TS_PACKET_READER == 2 + this->buf_pos = 0; + this->buf_size = 0; +# endif +#endif + this->stream = stream; this->input = input; @@ -2704,26 +2879,28 @@ * Initialise our specialised data. */ - this->last_pat_crc = 0; this->transport_stream_id = -1; for (i = 0; i < MAX_PIDS; i++) { this->media[i].pid = INVALID_PID; +#ifndef HAVE_ZERO_SAFE_MEM this->media[i].buf = NULL; +#endif } for (i = 0; i < MAX_PMTS; i++) { - this->program_number[i] = INVALID_PROGRAM; - this->pmt_pid[i] = INVALID_PID; - this->pmt[i] = NULL; - this->pmt_write_pos[i] = 0; + this->program_number[i] = INVALID_PROGRAM; + this->pmt_pid[i] = INVALID_PID; +#ifndef HAVE_ZERO_SAFE_MEM + this->pmt[i] = NULL; + this->pmt_write_pos[i] = 0; +#endif } - this->scrambled_npids = 0; + memset (this->pid_index, 0xff, sizeof (this->pid_index)); + this->videoPid = INVALID_PID; this->pcr_pid = INVALID_PID; - this->audio_tracks_count = 0; - this->last_pmt_crc = 0; this->rate = 1000000; /* byte/sec */ this->tbre_pid = INVALID_PID; @@ -2732,7 +2909,6 @@ /* DVBSUB */ this->spu_pid = INVALID_PID; - this->spu_langs_count = 0; this->current_spu_channel = -1; /* dvb */ @@ -2750,6 +2926,8 @@ * ts demuxer class */ void *demux_ts_init_class (xine_t *xine, const void *data) { + (void)xine; + (void)data; static const demux_class_t demux_ts_class = { .open_plugin = open_plugin, @@ -2767,4 +2945,3 @@ return (void *)&demux_ts_class; } - |
From: Petri H. <phi...@us...> - 2018-05-09 16:24:35
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525883060 -10800 # Node ID 0c67e8ced9453c585789661528dbf89d1fb24ea4 # Branch default # Parent 4e2b6627c1c6257805890cc0c35815669d6e8509 remove extra if diff --git a/m4/summary.m4 b/m4/summary.m4 --- a/m4/summary.m4 +++ b/m4/summary.m4 @@ -13,7 +13,7 @@ echo " - rtsp - rtp" echo " - net - pnm" echo " - http - ftp" - if test x"$have_gnutls" = x"yes" && echo " - https" + test x"$have_gnutls" = x"yes" && echo " - https" test x"$have_libssh2" = x"yes" && echo " - sftp - scp" test x"$have_libnfs" = x"yes" && echo " - nfs" test x"$enable_mms" != x"no" && echo " - mms" |
From: Petri H. <phi...@us...> - 2018-05-09 16:20:56
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525769917 -10800 # Node ID 3b75aa1c7e6793c78f79d5ae0745259bb7c7fadd # Branch default # Parent 6e4f0b9c5406e5c9df2f1858ab44d13dde69113b input: add TLS layer (using gnutls) diff --git a/src/input/Makefile.am b/src/input/Makefile.am --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -25,7 +25,8 @@ http_helper.la \ input_helper.la \ media_helper.la \ - net_buf_ctrl.la + net_buf_ctrl.la \ + xine_tls.la http_helper_la_SOURCES = http_helper.c http_helper.h http_helper_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) @@ -39,6 +40,10 @@ net_buf_ctrl_la_SOURCES = net_buf_ctrl.c net_buf_ctrl.h net_buf_ctrl_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(PTHREAD_LIBS) +xine_tls_la_SOURCES = xine_tls.c xine_tls.h +xine_tls_la_CFLAGS = $(AM_CFLAGS) $(GNUTLS_CFLAGS) +xine_tls_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(GNUTLS_LIBS) + # # # @@ -186,7 +191,7 @@ pnm.c \ pnm.h xineplug_inp_network_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(LTLIBINTL) \ - libreal.la librtsp.la http_helper.la input_helper.la net_buf_ctrl.la + libreal.la librtsp.la http_helper.la input_helper.la net_buf_ctrl.la xine_tls.la xineplug_inp_rtp_la_SOURCES = input_rtp.c xineplug_inp_rtp_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) net_buf_ctrl.la input_helper.la --git a/src/input/xine_tls.c b/src/input/xine_tls.c new file mode 100644 --- /dev/null +++ b/src/input/xine_tls.c @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2000-2018 the xine project + * Copyright (C) 2018 Petri Hintukainen <phi...@us...> + * + * This file is part of xine, a free video player. + * + * xine 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. + * + * xine 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define LOG_MODULE "input_tls" + +#include "xine_tls.h" + +#include <stdlib.h> +#include <errno.h> + +#ifdef HAVE_GNUTLS +#include <gnutls/gnutls.h> +#include <gnutls/x509.h> +#endif /* HAVE_GNUTLS */ + +#include <xine/xine_internal.h> +#include <xine/xineutils.h> +#include <xine/io_helper.h> + + +struct xine_tls { + xine_stream_t *stream; + int fd; + +#ifdef HAVE_GNUTLS + int enabled; + int need_shutdown; + + gnutls_session_t session; + gnutls_certificate_credentials_t cred; +#endif /* HAVE_GNUTLS */ +}; + +#ifdef HAVE_GNUTLS +static int handle_gnutls_error(xine_tls_t *t, int err) +{ + switch (err) { + case GNUTLS_E_AGAIN: + errno = EAGAIN; + return -1; + default: + xprintf(t->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s\n", gnutls_strerror(err)); + break; + } + + errno = EIO; + return -1; +} +#endif /* HAVE_GNUTLS */ + +ssize_t _x_tls_write(xine_tls_t *t, const void *buf, size_t len) +{ +#ifdef HAVE_GNUTLS + if (t->enabled) { + int ret = gnutls_record_send(t->session, buf, len); + if (ret < 0) + return handle_gnutls_error(t, ret); + return ret; + } +#endif /* HAVE_GNUTLS */ + + return _x_io_tcp_write(t->stream, t->fd, buf, len); +} + +ssize_t _x_tls_read(xine_tls_t *t, void *buf, size_t len) +{ +#ifdef HAVE_GNUTLS + if (t->enabled) { + int ret = gnutls_record_recv(t->session, buf, len); + if (ret < 0) + return handle_gnutls_error(t, ret); + return ret; + } +#endif /* HAVE_GNUTLS */ + + return _x_io_tcp_read(t->stream, t->fd, buf, len); +} + +ssize_t _x_tls_read_line(xine_tls_t *t, char *buf, size_t buf_size) +{ +#ifdef HAVE_GNUTLS + if (t->enabled) { + int i = 0; + ssize_t r; + char c; + + if (buf_size <= 0) + return 0; + + while ((r = _x_tls_read(t, &c, 1)) == 1) { + if (c == '\r' || c == '\n') + break; + if (i+1 == buf_size) + break; + + buf[i] = c; + i++; + } + + if (r == 1 && c == '\r') [... 92 lines omitted ...] + int fh; + + fh = _x_io_tcp_connect(stream, host, port); + if (fh == -1) { + return NULL; + } + + tls = _x_tls_init(stream, fh); + if (!tls) { + _x_io_tcp_close(stream, fh); + } + + return tls; +} + +int _x_tls_handshake(xine_tls_t *t, const char *host, int verify) +{ +#ifndef HAVE_GNUTLS + xprintf(t->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "No TLS support (gnutls disabled in configure)\n"); + return -1; +#else /* HAVE_GNUTLS */ + int ret; + + _x_assert(t->enabled == 0); + + ret = gnutls_global_init(); + if (ret) { + xprintf(t->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "gnutls_global_init() failed: %s (%d)\n", + gnutls_strerror(ret), ret); + return -1; + } + + gnutls_init(&t->session, GNUTLS_CLIENT); + if (host) { + gnutls_server_name_set(t->session, GNUTLS_NAME_DNS, host, strlen(host)); + } + + gnutls_certificate_allocate_credentials(&t->cred); + gnutls_certificate_set_x509_system_trust(t->cred); + gnutls_certificate_set_verify_flags(t->cred, verify ? GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT : 0); + gnutls_credentials_set(t->session, GNUTLS_CRD_CERTIFICATE, t->cred); + + gnutls_transport_set_pull_function(t->session, gnutls_tcp_pull); + gnutls_transport_set_push_function(t->session, gnutls_tcp_push); + gnutls_transport_set_ptr(t->session, t); + + gnutls_priority_set_direct(t->session, "NORMAL", NULL); + + ret = gnutls_handshake(t->session); + if (ret) { + xprintf(t->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "TLS handshake failed: %s (%d)\n", + gnutls_strerror(ret), ret); + return -1; + } + + t->need_shutdown = 1; + + if (verify < 0) + verify = _x_tls_get_verify_tls_cert(t->stream->xine->config); + + if (verify) { + unsigned int status; + if ((ret = gnutls_certificate_verify_peers2(t->session, &status)) < 0) { + xprintf(t->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "Unable to verify peer certificate: %s (%d)\n", + gnutls_strerror(ret), ret); + return -2; + } + if (status & GNUTLS_CERT_INVALID) { + xprintf(t->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "Peer certificate failed verification\n"); + return -2; + } + if (gnutls_certificate_type_get(t->session) != GNUTLS_CRT_X509) { + xprintf(t->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "Unsupported certificate type\n"); + return -2; + } + if (host) { + unsigned int cert_list_size; + gnutls_x509_crt_t cert; + const gnutls_datum_t *cert_list; + gnutls_x509_crt_init(&cert); + cert_list = gnutls_certificate_get_peers(t->session, &cert_list_size); + gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER); + ret = gnutls_x509_crt_check_hostname(cert, host); + gnutls_x509_crt_deinit(cert); + if (!ret) { + xprintf(t->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "The certificate does not match hostname %s\n", + host); + return -3; + } + } + } + + t->enabled = 1; + return 0; +#endif /* HAVE_GNUTLS */ +} + +/* + * config helpers + */ + +void _x_tls_register_config_keys(config_values_t *config) +{ + config->register_bool(config, + "media.network.verify_tls_certificate", + 1, _("Verify server TLS certificate"), + _("If enabled, server TLS certificate is always checked. " + "If check fails, connections to server are not allowed."), + 10, NULL, NULL); +} + +int _x_tls_get_verify_tls_cert(config_values_t *config) +{ + cfg_entry_t *entry; + + entry = config->lookup_entry(config, "media.network.verify_tls_certificate"); + if (entry) { + return entry->num_value; + } + return 1; +} --git a/src/input/xine_tls.h b/src/input/xine_tls.h new file mode 100644 --- /dev/null +++ b/src/input/xine_tls.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2000-2018 the xine project + * Copyright (C) 2018 Petri Hintukainen <phi...@us...> + * + * This file is part of xine, a free video player. + * + * xine 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. + * + * xine 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * input plugin TLS helpers + */ + +#ifndef XINE_INPUT_TLS_H +#define XINE_INPUT_TLS_H + +/* + * xine_tls layer is a simple wrapper for _x_io_tcp_*() functions. + * _x_io_*() functions can be simply replaced with _x_tls_*() functions. + * + * Connection is unencrypted until _x_tls_handshake() is called. + * Unencrypted TCP connection can be used even if TLS support was not compiled in. + */ + +#include <xine/xine_internal.h> + +typedef struct xine_tls xine_tls_t; + +/* + * TCP connection + */ + +xine_tls_t *_x_tls_connect(xine_stream_t *stream, const char *host, int port); +xine_tls_t *_x_tls_init(xine_stream_t *stream, int fd); +void _x_tls_close(xine_tls_t **); /* note: associated socket is also closed */ + +ssize_t _x_tls_read(xine_tls_t *, void *data, size_t len); +ssize_t _x_tls_write(xine_tls_t *, const void *data, size_t len); +ssize_t _x_tls_read_line(xine_tls_t *, char *buf, size_t buf_size); + +/* + * TLS + */ + +/** + * Initialize TLS + * + * @param host Host name to check certificate against (may be NULL ex. if numeric address). + * @param verify verify certificate. 0 - no, 1 - yes, < 0 - fetch value from xine config. + * @return < 0 on error. + */ +int _x_tls_handshake(xine_tls_t *, const char *host, int verify); + +/** + * Shutdown TLS (stop encryption). + * + * Underlying socket remains open. + */ +void _x_tls_shutdown(xine_tls_t *); + +/* + * config helpers + */ + +void _x_tls_register_config_keys(config_values_t *); +int _x_tls_get_verify_tls_cert(config_values_t *); + +#endif /* XINE_INPUT_TLS_H */ |
From: Petri H. <phi...@us...> - 2018-05-09 16:20:56
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525882165 -10800 # Node ID 4e2b6627c1c6257805890cc0c35815669d6e8509 # Branch default # Parent 3b75aa1c7e6793c78f79d5ae0745259bb7c7fadd input_http: add TLS support (https) diff --git a/m4/summary.m4 b/m4/summary.m4 --- a/m4/summary.m4 +++ b/m4/summary.m4 @@ -13,6 +13,7 @@ echo " - rtsp - rtp" echo " - net - pnm" echo " - http - ftp" + if test x"$have_gnutls" = x"yes" && echo " - https" test x"$have_libssh2" = x"yes" && echo " - sftp - scp" test x"$have_libnfs" = x"yes" && echo " - nfs" test x"$enable_mms" != x"no" && echo " - mms" --git a/src/input/input_http.c b/src/input/input_http.c --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -50,10 +50,12 @@ #include "group_network.h" #include "http_helper.h" #include "input_helper.h" +#include "xine_tls.h" #define BUFSIZE 1024 #define DEFAULT_HTTP_PORT 80 +#define DEFAULT_HTTPS_PORT 443 #define TAG_ICY_NAME "icy-name:" #define TAG_ICY_GENRE "icy-genre:" @@ -79,7 +81,7 @@ const char *user_agent; xine_url_t url; - int fh; + xine_tls_t *tls; /** Set to 1 if the stream is a NSV stream. */ unsigned int is_nsv:1; @@ -242,13 +244,13 @@ xine_ui_data_t data; /* get the length of the metadata */ - if (_x_io_tcp_read (this->stream, this->fh, (char*)&len, 1) != 1) + if (_x_tls_read (this->tls, (char*)&len, 1) != 1) return 0; lprintf ("http_plugin_read_metainf: len=%d\n", len); if (len > 0) { - if (_x_io_tcp_read (this->stream, this->fh, metadata_buf, len * 16) != (len * 16)) + if (_x_tls_read (this->tls, metadata_buf, len * 16) != (len * 16)) return 0; metadata_buf[len * 16] = '\0'; @@ -315,7 +317,7 @@ ((this->shoutcast_pos + nlen) >= this->shoutcast_metaint)) { nlen = this->shoutcast_metaint - this->shoutcast_pos; - nlen = _x_io_tcp_read (this->stream, this->fh, &buf[read_bytes], nlen); + nlen = _x_tls_read (this->tls, &buf[read_bytes], nlen); if (nlen < 0) goto error; @@ -324,7 +326,7 @@ this->shoutcast_pos = 0; } else { - nlen = _x_io_tcp_read (this->stream, this->fh, &buf[read_bytes], nlen); + nlen = _x_tls_read (this->tls, &buf[read_bytes], nlen); if (nlen < 0) goto error; @@ -482,52 +484,49 @@ static void http_close(http_input_plugin_t * this) { - if (this->fh != -1) { - _x_io_tcp_close(this->stream, this->fh); - this->fh = -1; - } - + _x_tls_close(&this->tls); _x_url_cleanup(&this->url); } static int http_restart(http_input_plugin_t * this, off_t abs_offset) { /* save old stream */ - int old_fh = this->fh; + xine_tls_t *old_tls = this->tls; off_t old_pos = this->curpos; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "input_http: seek to %" PRId64 ": reconnecting ...\n", + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " + "seek to %" PRId64 ": reconnecting ...\n", (int64_t)abs_offset); - this->fh = -1; + this->tls = NULL; http_close(this); this->curpos = abs_offset; if (this->input_plugin.open(&this->input_plugin) != 1) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "input_http: seek to %" PRId64 " failed (http request failed)\n", + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "seek to %" PRId64 " failed (http request failed)\n", (int64_t)abs_offset); + _x_tls_close(&this->tls); goto fail; } if (this->curpos != abs_offset) { /* something went wrong ... */ - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "input_http: seek to %" PRId64 " failed (server returned invalid range)\n", + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " + "seek to %" PRId64 " failed (server returned invalid range)\n", (int64_t)abs_offset); - _x_io_tcp_close(this->stream, this->fh); + _x_tls_close(&this->tls); goto fail; } /* close old connection */ - _x_io_tcp_close(this->stream, old_fh); + _x_tls_close(&old_tls); return 0; fail: /* restore old stream */ - this->fh = old_fh; + this->tls = old_tls; this->curpos = old_pos; return -1; } @@ -625,6 +624,7 @@ int mpegurl_redirect = 0; char mime_type[256]; [... 32 lines omitted ...] - if (use_proxy) - this->fh = _x_io_tcp_connect (this->stream, this_class->proxyhost, proxyport); - else - this->fh = _x_io_tcp_connect (this->stream, this->url.host, this->url.port); - - if (this->fh == -1) + if (fh == -1) return -2; { @@ -683,16 +687,44 @@ progress = 0; do { report_progress(this->stream, progress); - res = _x_io_select (this->stream, this->fh, XIO_WRITE_READY, 500); + res = _x_io_select (this->stream, fh, XIO_WRITE_READY, 500); progress += (500*100000)/timeout; - } while ((res == XIO_TIMEOUT) && (progress <= 100000)); + } while ((res == XIO_TIMEOUT) && (progress <= 100000) && !_x_action_pending(this->stream)); if (res != XIO_READY) { _x_message(this->stream, XINE_MSG_NETWORK_UNREACHABLE, this->mrl, NULL); + _x_io_tcp_close(this->stream, fh); return -3; } } + /* + * TLS + */ + + _x_assert(this->tls == NULL); + + this->tls = _x_tls_init(this->stream, fh); + if (!this->tls) { + _x_io_tcp_close(this->stream, fh); + return -2; + } + fh = -1; + + if (use_tls) { + int r = _x_tls_handshake(this->tls, this->url.host, -1); + if (r < 0) { + _x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "TLS handshake failed", NULL); + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": TLS handshake failed\n"); + return -4; + } + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": TLS handshake succeed, connection is encrypted\n"); + } + + /* + * Request + */ + if (use_proxy) { if (this->url.port != DEFAULT_HTTP_PORT) { snprintf (buf, sizeof(buf), "GET http://%s:%d%s HTTP/1.0\015\012", @@ -752,14 +784,19 @@ this->user_agent ? " " : "", VERSION); buflen = strlen(buf); - if (_x_io_tcp_write (this->stream, this->fh, buf, buflen) != buflen) { + + if (_x_tls_write(this->tls, buf, buflen) != buflen) { _x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "couldn't send request", NULL); - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_http: couldn't send request\n"); + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": couldn't send request\n"); return -4; } lprintf ("request sent: >%s<\n", buf); + /* + * Response + */ + /* read and parse reply */ done = 0; len = 0; linenum = 0; this->contentlength = 0; @@ -768,7 +805,7 @@ while (!done) { /* fprintf (stderr, "input_http: read...\n"); */ - if (_x_io_tcp_read (this->stream, this->fh, &buf[len], 1) <= 0) { + if (_x_tls_read (this->tls, &buf[len], 1) <= 0) { return -5; } @@ -1042,6 +1079,10 @@ http_input_plugin_t *this; if (strncasecmp (mrl, "http://", 7) && +#ifdef HAVE_TLS + /* do not accept https:// unless TLS support was built in */ + strncasecmp (mrl, "https://", 8) && +#endif strncasecmp (mrl, "unsv://", 7) && strncasecmp (mrl, "peercast://pls/", 15) && !_x_url_user_agent (mrl) /* user agent hacks */) { @@ -1056,7 +1097,7 @@ } this->stream = stream; - this->fh = -1; + this->tls = NULL; this->nbc = nbc_init (this->stream); this->input_plugin.open = http_plugin_open; @@ -1102,7 +1143,7 @@ this->input_class.get_instance = http_class_get_instance; this->input_class.identifier = "http"; - this->input_class.description = N_("http input plugin"); + this->input_class.description = N_("http/https input plugin"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = http_class_dispose; @@ -1157,6 +1198,10 @@ _("A comma-separated list of domain names for which the proxy is to be ignored.\nIf a domain name is prefixed with '=' then it is treated as a host name only (full match required)."), 10, no_proxy_list_change_cb, (void *) this); +#ifdef HAVE_TLS + _x_tls_register_config_keys(config); +#endif + return this; } |
From: Petri H. <phi...@us...> - 2018-05-09 16:20:54
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525780914 -10800 # Node ID 6e4f0b9c5406e5c9df2f1858ab44d13dde69113b # Branch default # Parent 9f55ef73ef80ef0c6aaa028d05970e864ce5fdee configure: check for gnutls diff --git a/m4/input.m4 b/m4/input.m4 --- a/m4/input.m4 +++ b/m4/input.m4 @@ -24,6 +24,7 @@ default_enable_avformat=yes default_enable_sftp=yes default_enable_nfs=yes + default_enable_tls=yes default_with_external_dvdnav=yes case "$host_os" in @@ -249,4 +250,19 @@ fi AM_CONDITIONAL(ENABLE_NFS, test "x$have_libnfs" = "xyes") + dnl TLS support (ftps, https) + XINE_ARG_ENABLE([tls], [Enable TLS support using gnutls (enables secure http (https) and ftp (ftps)]) + if test "x$enable_tls" != "xno"; then + PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.3.0], [have_gnutls=yes], [have_gnutls=no]) + if test x"$hard_enable_tls" = x"yes" && test x"$have_gnutls" != x"yes"; then + AC_MSG_ERROR([TLS support requested, but gnutls not found]) + fi + AC_SUBST(GNUTLS_CFLAGS) + AC_SUBST(GNUTLS_LIBS) + fi + if test x"$have_gnutls" = x"yes"; then + AC_DEFINE([HAVE_GNUTLS], 1, [Define this if you have gnutls installed]) + dnl prepare for other TLS implementations ... + AC_DEFINE([HAVE_TLS], 1, [Define this if you have tls support compiled in]) + fi ]) |
From: Petri H. <phi...@us...> - 2018-05-09 16:20:53
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525760431 -10800 # Node ID 9f55ef73ef80ef0c6aaa028d05970e864ce5fdee # Branch default # Parent c2300d104f3ba8b0e2e0f2f76bf58626c614051b Add configure option to disable mms diff --git a/m4/input.m4 b/m4/input.m4 --- a/m4/input.m4 +++ b/m4/input.m4 @@ -12,6 +12,7 @@ default_enable_dvb=no default_enable_dvd=yes default_enable_gnomevfs=yes + default_enable_mms=yes default_enable_samba=yes default_enable_v4l=no default_enable_v4l2=no @@ -132,7 +133,11 @@ dnl dvdnav XINE_ARG_ENABLE([dvd], [Disable DVD support]) AM_CONDITIONAL([ENABLE_DVD], [test x"$enable_dvd" != x"no"]) - + + dnl mms + XINE_ARG_ENABLE([mms], [Disable MMS support]) + AM_CONDITIONAL([ENABLE_MMS], [test x"$enable_mms" != x"no"]) + dnl XXX: This could be cleaned up so that code does not have to ifdef so much XINE_ARG_WITH([external-dvdnav], [Use external dvdnav library]) if test x"$with_external_dvdnav" != x"no"; then --git a/m4/summary.m4 b/m4/summary.m4 --- a/m4/summary.m4 +++ b/m4/summary.m4 @@ -13,9 +13,9 @@ echo " - rtsp - rtp" echo " - net - pnm" echo " - http - ftp" - echo " - mms" test x"$have_libssh2" = x"yes" && echo " - sftp - scp" test x"$have_libnfs" = x"yes" && echo " - nfs" + test x"$enable_mms" != x"no" && echo " - mms" test x"$have_samba" = x"yes" && echo " - smb" dnl optical discs echo " - cdda" --git a/src/input/Makefile.am b/src/input/Makefile.am --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -122,6 +122,10 @@ in_dvd = xineplug_inp_dvd.la endif +if ENABLE_MMS +in_mms = xineplug_inp_mms.la +endif + if WITH_EXTERNAL_DVDNAV DVD_CFLAGS = $(DVDNAV_CFLAGS) $(DVDREAD_CFLAGS) link_dvdnav = $(DVDNAV_LIBS) $(DVDREAD_LIBS) @@ -153,7 +157,7 @@ $(in_nfs) \ $(in_smb) \ $(in_ssh) \ - xineplug_inp_mms.la \ + $(in_mms) \ $(in_rtp) \ xineplug_inp_network.la \ $(in_pvr) \ |
From: Petri H. <phi...@us...> - 2018-05-09 12:20:18
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525768264 -10800 # Node ID c2300d104f3ba8b0e2e0f2f76bf58626c614051b # Branch default # Parent 84fa5a6272bb44c493f00b2a8188cdad7d0db512 input: reduce code duplication diff --git a/src/input/Makefile.am b/src/input/Makefile.am --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -162,10 +162,10 @@ xineplug_inp_cdda.la xineplug_inp_file_la_SOURCES = input_file.c -xineplug_inp_file_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) +xineplug_inp_file_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) input_helper.la xineplug_inp_test_la_SOURCES = input_test.c -xineplug_inp_test_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) +xineplug_inp_test_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) input_helper.la xineplug_inp_dvd_la_SOURCES = input_dvd.c xineplug_inp_dvd_la_LIBADD = $(XINE_LIB) $(link_dvdnav) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) media_helper.la @@ -199,7 +199,7 @@ xineplug_inp_vcdo_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) media_helper.la xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c -xineplug_inp_stdin_fifo_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) net_buf_ctrl.la +xineplug_inp_stdin_fifo_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) net_buf_ctrl.la input_helper.la xineplug_inp_dvb_la_SOURCES = input_dvb.c xineplug_inp_dvb_la_DEPS = $(XDG_BASEDIR_DEPS) --git a/src/input/input_file.c b/src/input/input_file.c --- a/src/input/input_file.c +++ b/src/input/input_file.c @@ -49,6 +49,8 @@ #include <xine/compat.h> #include <xine/input_plugin.h> +#include "input_helper.h" + #define MAXFILES 65535 #ifndef WIN32 @@ -64,7 +66,6 @@ xine_t *xine; const char *origin_path; - int show_hidden_files; int mrls_allocated_entries; xine_mrl_t **mrls; @@ -165,22 +166,21 @@ static buf_element_t *file_input_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { - file_input_plugin_t *this = (file_input_plugin_t *) this_gen; - buf_element_t *buf = fifo->buffer_pool_alloc (fifo); - - if (todo > buf->max_size) - todo = buf->max_size; - if (todo < 0) { - buf->free_buffer (buf); - return NULL; - } - - buf->type = BUF_DEMUX_BLOCK; - #ifdef HAVE_MMAP if ( file_input_check_mmap(this) ) { + file_input_plugin_t *this = (file_input_plugin_t *) this_gen; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); off_t len = todo; + if (todo > buf->max_size) + todo = buf->max_size; + if (todo < 0) { + buf->free_buffer (buf); + return NULL; + } + + buf->type = BUF_DEMUX_BLOCK; + if ( (this->mmap_curr + len) > (this->mmap_base + this->mmap_len) ) len = (this->mmap_base + this->mmap_len) - this->mmap_curr; @@ -195,34 +195,12 @@ /* free(buf->mem); buf->mem = NULL; */ this->mmap_curr += len; - } else + + return buf; + } #endif - { - off_t num_bytes, total_bytes = 0; - buf->content = buf->mem; - - while (total_bytes < todo) { - num_bytes = read (this->fh, buf->mem + total_bytes, todo-total_bytes); - if (num_bytes <= 0) { - if (num_bytes < 0) { - xine_log (this->stream->xine, XINE_LOG_MSG, - _("input_file: read error (%s)\n"), strerror(errno)); - _x_message(this->stream, XINE_MSG_READ_ERROR, - this->mrl, NULL); - } - buf->free_buffer (buf); - buf = NULL; - break; - } - total_bytes += num_bytes; - } - - if( buf != NULL ) - buf->size = total_bytes; - } - - return buf; + return _x_input_default_read_block(this_gen, fifo, todo); } static off_t file_input_seek (input_plugin_t *this_gen, off_t offset, int origin) { @@ -286,10 +264,6 @@ return 0; } -static uint32_t file_input_get_blocksize (input_plugin_t *this_gen) { - return 0; -} - /* * Return 1 if filepathname is a directory, otherwise 0 */ @@ -439,7 +413,7 @@ this->input_plugin.seek = file_input_seek; this->input_plugin.get_current_pos = file_input_get_current_pos; this->input_plugin.get_length = file_input_get_length; - this->input_plugin.get_blocksize = file_input_get_blocksize; + this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = file_input_get_mrl; this->input_plugin.get_optional_data = file_input_get_optional_data; this->input_plugin.dispose = file_input_dispose; @@ -495,11 +469,7 @@ /* * Callback for config changes. */ -static void file_input_hidden_bool_cb (void *data, xine_cfg_entry_t *cfg) { - file_input_class_t *this = (file_input_class_t *) data; - this->show_hidden_files = cfg->num_value; -} static void file_input_origin_change_cb (void *data, xine_cfg_entry_t *cfg) { file_input_class_t *this = (file_input_class_t *) data; @@ -660,10 +630,13 @@ int num_files = -1; int (*func) () = file_input_sortfiles_default; int already_tried = 0; + int show_hidden_files; *nFiles = 0; memset(current_dir, 0, sizeof(current_dir)); + show_hidden_files = _x_input_get_show_hidden_files(this->xine->config); + /* * No origin location, so got the content of the current directory */ @@ -715,7 +688,7 @@ if(file_input_is_dir(fullfilename)) { /* if user don't want to see hidden files, ignore them */ - if(this->show_hidden_files == 0 && + if (show_hidden_files == 0 && ((strlen(pdirent->d_name) > 1) && (pdirent->d_name[0] == '.' && pdirent->d_name[1] != '.'))) { ; @@ -755,7 +728,7 @@ && (pdirent->d_name[0] == '.' && pdirent->d_name[1] != '.')) { /* if user don't want to see hidden files, ignore them */ - if(this->show_hidden_files) { + if (show_hidden_files) { hide_files[num_hide_files].origin = strdup(current_dir); hide_files[num_hide_files].mrl = _x_asprintf("%s%s", current_dir_slashed, pdirent->d_name); @@ -948,7 +921,6 @@ config_values_t *config = this->xine->config; config->unregister_callback(config, "media.files.origin_path"); - config->unregister_callback(config, "media.files.show_hidden_files"); while(this->mrls_allocated_entries) { this->mrls_allocated_entries--; @@ -995,12 +967,7 @@ 0, file_input_origin_change_cb, (void *) this); } - this->show_hidden_files = config->register_bool(config, - "media.files.show_hidden_files", - 0, _("list hidden files"), - _("If enabled, the browser to select the file to " - "play will also show hidden files."), - 10, file_input_hidden_bool_cb, (void *) this); + _x_input_register_show_hidden_files(config); return this; } --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c --- a/src/input/input_stdin_fifo.c +++ b/src/input/input_stdin_fifo.c @@ -176,35 +176,6 @@ return done; } -static buf_element_t *stdin_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, - off_t todo) { - - off_t total_bytes; - /* stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; */ - buf_element_t *buf = fifo->buffer_pool_alloc (fifo); - - if (todo > buf->max_size) - todo = buf->max_size; - if (todo < 0) { - buf->free_buffer (buf); - return NULL; - } - - buf->content = buf->mem; - buf->type = BUF_DEMUX_BLOCK; - - total_bytes = stdin_plugin_read (this_gen, (char*)buf->content, todo); - - if (total_bytes != todo) { - buf->free_buffer (buf); - return NULL; - } - - buf->size = total_bytes; - - return buf; -} - /* forward reference */ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { @@ -366,7 +337,7 @@ this->input_plugin.open = stdin_plugin_open; this->input_plugin.get_capabilities = _x_input_get_capabilities_preview; this->input_plugin.read = stdin_plugin_read; - this->input_plugin.read_block = stdin_plugin_read_block; + this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = stdin_plugin_seek; this->input_plugin.get_current_pos = stdin_plugin_get_current_pos; this->input_plugin.get_length = stdin_plugin_get_length; --git a/src/input/input_test.c b/src/input/input_test.c --- a/src/input/input_test.c +++ b/src/input/input_test.c @@ -45,6 +45,8 @@ #include <xine/input_plugin.h> #include <xine/video_out.h> +#include "input_helper.h" + /* describe tests here */ static const char * const test_names[] = { "test://", @@ -558,10 +560,6 @@ /* instance functions */ -static uint32_t test_plugin_get_capabilities (input_plugin_t *this_gen) { - return INPUT_CAP_SEEKABLE; -} - static off_t test_plugin_read (input_plugin_t *this_gen, void *buf, off_t len) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; @@ -599,39 +597,16 @@ return len; } -static buf_element_t *test_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, - off_t todo) { - test_input_plugin_t *this = (test_input_plugin_t *) this_gen; - buf_element_t *buf; - - if (!this->buf || (todo < 0)) return NULL; - - buf = fifo->buffer_pool_alloc (fifo); - if (todo > buf->max_size) todo = buf->max_size; - buf->type = BUF_DEMUX_BLOCK; - test_plugin_read (this_gen, buf->content, todo); - - return buf; -} - static off_t test_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; - off_t newpos = offset; - switch (origin) { - case SEEK_SET: break; - case SEEK_CUR: newpos += this->filepos; break; - case SEEK_END: newpos += this->filesize; break; - default: newpos = -1; + offset = _x_input_translate_seek(offset, origin, this->filepos, this->filesize); + + if (offset >= 0) { + this->filepos = offset; } - if ((newpos < 0) || (newpos > this->filesize)) { - errno = EINVAL; - return (off_t)-1; - } - - this->filepos = newpos; - return newpos; + return offset; } static off_t test_plugin_get_current_pos (input_plugin_t *this_gen) { @@ -646,22 +621,12 @@ return this->filesize; } -static uint32_t test_plugin_get_blocksize (input_plugin_t *this_gen) { - return 0; -} - static const char *test_plugin_get_mrl (input_plugin_t *this_gen) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; return test_names[this->index]; } -static int test_plugin_get_optional_data (input_plugin_t *this_gen, void *data, - int data_type) { - - return INPUT_OPTIONAL_UNSUPPORTED; -} - static void test_plugin_dispose (input_plugin_t *this_gen ) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; @@ -690,15 +655,15 @@ this->index = i; this->input_plugin.open = test_plugin_open; - this->input_plugin.get_capabilities = test_plugin_get_capabilities; + this->input_plugin.get_capabilities = _x_input_get_capabilities_seekable; this->input_plugin.read = test_plugin_read; - this->input_plugin.read_block = test_plugin_read_block; + this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = test_plugin_seek; this->input_plugin.get_current_pos = test_plugin_get_current_pos; this->input_plugin.get_length = test_plugin_get_length; - this->input_plugin.get_blocksize = test_plugin_get_blocksize; + this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = test_plugin_get_mrl; - this->input_plugin.get_optional_data = test_plugin_get_optional_data; + this->input_plugin.get_optional_data = _x_input_default_get_optional_data; this->input_plugin.dispose = test_plugin_dispose; this->input_plugin.input_class = cls_gen; --git a/src/xine-engine/builtins.c b/src/xine-engine/builtins.c --- a/src/xine-engine/builtins.c +++ b/src/xine-engine/builtins.c @@ -38,6 +38,8 @@ #undef LOG_MODULE #include "../input/net_buf_ctrl.c" #undef LOG_MODULE +#include "../input/input_helper.c" +#undef LOG_MODULE #include "../input/input_file.c" #undef LOG_MODULE #include "../input/input_stdin_fifo.c" |
From: Petri H. <phi...@us...> - 2018-05-09 12:17:49
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525759937 -10800 # Node ID 84fa5a6272bb44c493f00b2a8188cdad7d0db512 # Branch default # Parent 0e5501b39a697f46a6dc7530fe3a2919db115ee7 Cosmetics (reorder input plugin summary) diff --git a/m4/summary.m4 b/m4/summary.m4 --- a/m4/summary.m4 +++ b/m4/summary.m4 @@ -8,10 +8,17 @@ dnl Input echo " * input plugins:" - echo " - file - net" - echo " - stdin_fifo - rtp" - echo " - http - mms" - echo " - pnm - rtsp" + echo " - file - stdin_fifo" + dnl network + echo " - rtsp - rtp" + echo " - net - pnm" + echo " - http - ftp" + echo " - mms" + test x"$have_libssh2" = x"yes" && echo " - sftp - scp" + test x"$have_libnfs" = x"yes" && echo " - nfs" + test x"$have_samba" = x"yes" && echo " - smb" + dnl optical discs + echo " - cdda" if test x"$enable_vcd" != x"no"; then if test x"$enable_vcdo" != x"no"; then echo " - vcdo - vcd" @@ -19,7 +26,6 @@ echo " - vcd" fi fi - echo " - ftp" if test x"$enable_dvd" != x"no"; then if test x"$with_external_dvdnav" != x"no"; then echo " - dvd (external libs)" @@ -27,17 +33,13 @@ echo " - dvd (*INTERNAL* libs)" fi fi - test x"$enable_vdr" != x"no" && echo " - vdr" - test x"$have_dvb" = x"yes" && echo " - dvb" - test x"$have_gnomevfs" = x"yes" && echo " - gnome-vfs" - test x"$have_samba" = x"yes" && echo " - smb" - test x"$have_v4l" = x"yes" && echo " - v4l" - test x"$have_v4l2" = x"yes" && echo " - v4l2" - echo " - cdda" test x"$have_libbluray" = x"yes" && echo " - bluray" - test x"$have_libssh2" = x"yes" && echo " - sftp" - test x"$have_libssh2" = x"yes" && echo " - scp" - test x"$have_libnfs" = x"yes" && echo " - nfs" + dnl misc + test x"$have_dvb" = x"yes" && echo " - dvb" + test x"$have_v4l" = x"yes" && echo " - v4l" + test x"$have_v4l2" = x"yes" && echo " - v4l2" + test x"$enable_vdr" != x"no" && echo " - vdr" + test x"$have_gnomevfs" = x"yes" && echo " - gnome-vfs" test x"$enable_ffmpeg" != x"no" -a x"$have_avformat" = x"yes" && echo " - avio (libavformat)" echo " - test" echo "" |
From: Petri H. <phi...@us...> - 2018-05-09 11:58:39
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525758863 -10800 # Node ID 0e5501b39a697f46a6dc7530fe3a2919db115ee7 # Branch default # Parent 1791383e3ad1504bef60a38c1efb438652bdbec0 Cosmetics diff --git a/src/input/Makefile.am b/src/input/Makefile.am --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -171,7 +171,16 @@ xineplug_inp_dvd_la_LIBADD = $(XINE_LIB) $(link_dvdnav) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) media_helper.la xineplug_inp_dvd_la_CFLAGS = $(AM_CFLAGS) $(DVD_CFLAGS) -xineplug_inp_network_la_SOURCES = group_network.c group_network.h input_net.c input_http.c input_pnm.c pnm.c pnm.h input_rtsp.c input_ftp.c +xineplug_inp_network_la_SOURCES = \ + group_network.c \ + group_network.h \ + input_ftp.c \ + input_http.c \ + input_net.c \ + input_pnm.c \ + input_rtsp.c \ + pnm.c \ + pnm.h xineplug_inp_network_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(LTLIBINTL) \ libreal.la librtsp.la http_helper.la input_helper.la net_buf_ctrl.la |
From: Torsten J. <t....@gm...> - 2018-05-07 17:29:40
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1525714145 -7200 # Node ID 1791383e3ad1504bef60a38c1efb438652bdbec0 # Branch default # Parent 83664037d4393a4c2bdbd1154a3c144e3a1c2544 demux_qt update 6. - Fast ms time and normpos calculation. - Time based normpos, independent of file chunk structure. - Fix keyframe report normpos (was all 0 due to yet unset data size). - Simplify. diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -374,6 +374,9 @@ unsigned int modification_time; unsigned int timescale; /* base clock frequency is Hz */ unsigned int duration; + int32_t msecs; + uint32_t normpos_mul; + uint32_t normpos_shift; int64_t moov_first_offset; @@ -662,6 +665,8 @@ info->creation_time = 0; info->modification_time = 0; info->duration = 0; + info->normpos_mul = 0; + info->normpos_shift = 0; info->trak_count = 0; info->traks = NULL; info->artist = NULL; @@ -680,6 +685,7 @@ info->last_error = QT_OK; info->demux = demux; info->timescale = 1; + info->msecs = 1; info->video_trak = -1; info->audio_trak = -1; info->chosen_reference = -1; @@ -1708,6 +1714,36 @@ return QT_OK; } +static void qt_normpos_init (qt_info *info) { + uint32_t n = info->msecs, dbits = 32, sbits; + while (!(n & 0x80000000)) + dbits--, n <<= 1; + /* _mul setup limit: sbits <= 64 - 16 + * mbits = 16 + sbits - dbits; + * _mul usage limit: mbits <= 64 - dbits + * 16 + sbits - dbits <= 64 - dbits + * sbits <= 48 + * usage simplifiction: mbits <= 32 + * 16 + sbits - dbits <= 32 + * sbits <= 16 + dbits + */ + sbits = 16 + dbits - 1; /* safety */ + info->normpos_shift = sbits; + info->normpos_mul = ((uint64_t)0xffff << sbits) / (uint32_t)info->msecs; +} + +static int32_t qt_msec_2_normpos (qt_info *info, int32_t msec) { + return ((uint64_t)msec * info->normpos_mul) >> info->normpos_shift; +} + +static int32_t qt_pts_2_msecs (int64_t pts) { +#ifdef ARCH_X86_32 + return (pts * (int32_t)((((uint32_t)1 << 31) + 22) / 45)) >> 32; +#else + return pts / 90; +#endif +} + #define KEYFRAMES_SIZE 1024 static void qt_keyframes_add (qt_trak *trak, qt_frame *f) { xine_keyframes_entry_t *e = trak->keyframes_list; @@ -1719,8 +1755,7 @@ trak->keyframes_size += KEYFRAMES_SIZE; } e += trak->keyframes_used++; - e->msecs = f->pts / 90; - e->normpos = (trak->info->demux->data_size > 0) ? QTF_OFFSET(f[0]) * 65335 / trak->info->demux->data_size : 0; + e->msecs = qt_pts_2_msecs (f->pts); } static void qt_keyframes_size (qt_trak *trak, uint32_t n) { @@ -1738,8 +1773,7 @@ static void qt_keyframes_simple_add (qt_trak *trak, qt_frame *f) { xine_keyframes_entry_t *e = trak->keyframes_list; e += trak->keyframes_used++; - e->msecs = f->pts / 90; - e->normpos = (trak->info->demux->data_size > 0) ? QTF_OFFSET(f[0]) * 65335 / trak->info->demux->data_size : 0; + e->msecs = qt_pts_2_msecs (f->pts); } static qt_error build_frame_table (qt_trak *trak, unsigned int global_timescale) { @@ -2722,39 +2756,62 @@ fragment_scan (info, input); } + /* get real duration */ + { + qt_trak *trak = info->traks; + uint32_t n; + for (n = info->trak_count; n; n--) { + if (trak->frame_count) { + int32_t msecs = qt_pts_2_msecs (trak->frames[trak->frame_count].pts); + if (msecs > info->msecs) + info->msecs = msecs; + } + trak++; + } + } + qt_normpos_init (info); + for (i = 0; i < info->trak_count; i++) { + qt_trak *trak = info->traks + i; #if DEBUG_DUMP_MOOV unsigned int j; /* dump the frame table in debug mode */ - for (j = 0; j < info->traks[i].frame_count; j++) + for (j = 0; j < trak->frame_count; j++) debug_frame_table(" %d: %8X bytes @ %"PRIX64", %"PRId64" pts, media id %d%s\n", j, - info->traks[i].frames[j].size, - QTF_OFFSET(info->traks[i].frames[j]), - info->traks[i].frames[j].pts, - (int)QTF_MEDIA_ID(info->traks[i].frames[j]), - (QTF_KEYFRAME(info->traks[i].frames[j])) ? " (keyframe)" : ""); + trak->frames[j].size, + QTF_OFFSET(trak[0].frames[j]), + trak->frames[j].pts, + (int)QTF_MEDIA_ID(trak[0].frames[j]), + (QTF_KEYFRAME(trak[0].frames[j])) ? " (keyframe)" : ""); #endif /* decide which audio trak and which video trak has the most frames */ - if ((info->traks[i].type == MEDIA_VIDEO) && [... 12 lines omitted ...] + max_video_frames = trak->frame_count; + + if (trak->keyframes_list) { + xine_keyframes_entry_t *e = trak->keyframes_list; + uint32_t n = trak->keyframes_used; + while (n--) { + e->normpos = qt_msec_2_normpos (info, e->msecs); + e++; + } + _x_keyframes_set (info->demux->stream, trak->keyframes_list, trak->keyframes_used); + } + + } else if ((trak->type == MEDIA_AUDIO) && + (trak->frame_count > max_audio_frames)) { info->audio_trak = i; - max_audio_frames = info->traks[i].frame_count; + max_audio_frames = trak->frame_count; } - free (info->traks[i].keyframes_list); - info->traks[i].keyframes_list = NULL; - info->traks[i].keyframes_size = 0; + free (trak->keyframes_list); + trak->keyframes_list = NULL; + trak->keyframes_size = 0; } /* check for references */ @@ -3091,10 +3148,8 @@ while (remaining_sample_bytes) { buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, remaining_sample_bytes); buf->type = trak->properties->codec_buftype; - if( this->data_size ) - buf->extra_info->input_normpos = (int)((double)(QTF_OFFSET(trak->frames[i]) - this->data_start) - * 65535 / this->data_size); - buf->extra_info->input_time = trak->frames[i].pts / 90; + buf->extra_info->input_time = qt_pts_2_msecs (trak->frames[i].pts); + buf->extra_info->input_normpos = qt_msec_2_normpos (&this->qt, buf->extra_info->input_time); buf->pts = trak->frames[i].pts + (int64_t)trak->frames[i].ptsoffs; buf->decoder_flags |= BUF_FLAG_FRAMERATE; @@ -3154,9 +3209,8 @@ while (remaining_sample_bytes) { buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, remaining_sample_bytes); buf->type = trak->properties->codec_buftype; - if( this->data_size ) - buf->extra_info->input_normpos = (int)((double)(QTF_OFFSET(trak->frames[i]) - this->data_start) - * 65535 / this->data_size); + buf->extra_info->input_time = qt_pts_2_msecs (trak->frames[i].pts); + buf->extra_info->input_normpos = qt_msec_2_normpos (&this->qt, buf->extra_info->input_time); /* The audio chunk is often broken up into multiple 8K buffers when * it is sent to the audio decoder. Only attach the proper timestamp * to the first buffer. This is for the linear PCM decoder which @@ -3166,7 +3220,6 @@ if ((buf->type == BUF_AUDIO_LPCM_BE) || (buf->type == BUF_AUDIO_LPCM_LE)) { if (first_buf) { - buf->extra_info->input_time = trak->frames[i].pts / 90; buf->pts = trak->frames[i].pts; first_buf = 0; } else { @@ -3174,7 +3227,6 @@ buf->pts = 0; } } else { - buf->extra_info->input_time = trak->frames[i].pts / 90; buf->pts = trak->frames[i].pts; } @@ -3495,11 +3547,14 @@ int best_index; int left, middle, right; +#ifdef QT_OFFSET_SEEK int found; +#endif if (!trak->frame_count) return QT_OK; +#ifdef QT_OFFSET_SEEK /* perform a binary search on the trak, testing the offset * boundaries first; offset request has precedent over time request */ if (start_pos) { @@ -3526,8 +3581,14 @@ best_index = middle; } - } else { - int64_t pts = 90 * start_time; + } else +#else + if (start_pos) { + start_time = (uint64_t)(start_pos & 0xffff) * (uint32_t)trak->info->msecs / 0xffff; + } +#endif + { + int64_t pts = (int64_t)90 * start_time; if (pts <= trak->frames[0].pts) best_index = 0; @@ -3562,8 +3623,10 @@ int i; int64_t keyframe_pts = -1; +#ifdef QT_OFFSET_SEEK start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); +#endif /* short-circuit any attempts to seek in a non-seekable stream, including * seeking in the forward direction; this may change later */ @@ -3642,13 +3705,8 @@ } static int demux_qt_get_stream_length (demux_plugin_t *this_gen) { - demux_qt_t *this = (demux_qt_t *) this_gen; - - if (this->qt.timescale == 0) - return 0; - - return (int)((int64_t) 1000 * this->qt.duration / this->qt.timescale); + return this->qt.msecs; } static uint32_t demux_qt_get_capabilities(demux_plugin_t *this_gen) { |
From: Petri H. <phi...@us...> - 2018-05-07 10:05:24
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525687504 -10800 # Node ID 83664037d4393a4c2bdbd1154a3c144e3a1c2544 # Branch default # Parent 366b2f964ecac310965014a8ef9c128bbeb8dfd0 ipmovie: check seek result diff --git a/src/demuxers/demux_ipmovie.c b/src/demuxers/demux_ipmovie.c --- a/src/demuxers/demux_ipmovie.c +++ b/src/demuxers/demux_ipmovie.c @@ -203,12 +203,14 @@ case OPCODE_END_OF_STREAM: lprintf("end of stream\n"); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_END_OF_CHUNK: lprintf("end of chunk\n"); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_CREATE_TIMER: @@ -261,7 +263,8 @@ case OPCODE_START_STOP_AUDIO: lprintf("start/stop audio\n"); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_INIT_VIDEO_BUFFERS: @@ -296,12 +299,14 @@ case OPCODE_UNKNOWN_14: case OPCODE_UNKNOWN_15: lprintf("unknown (but documented) opcode %02X\n", opcode_type); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_SEND_BUFFER: lprintf("send buffer\n"); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_AUDIO_FRAME: @@ -314,7 +319,8 @@ opcode_size -= 6; this->audio_frame_count += (opcode_size / this->wave.nChannels / (this->wave.wBitsPerSample / 8)); - this->input->seek(this->input, 6, SEEK_CUR); + if (this->input->seek(this->input, 6, SEEK_CUR) < 0) + return CHUNK_BAD; } else this->audio_frame_count += (opcode_size - 6) / this->wave.nChannels; @@ -353,23 +359,27 @@ this->audio_fifo->put (this->audio_fifo, buf); } }else{ - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; } break; case OPCODE_SILENCE_FRAME: lprintf("silence frame\n"); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_INIT_VIDEO_MODE: lprintf("initialize video mode\n"); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_CREATE_GRADIENT: lprintf("create gradient\n"); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_SET_PALETTE: @@ -408,7 +418,8 @@ case OPCODE_SET_PALETTE_COMPRESSED: lprintf("set palette compressed\n"); - this->input->seek(this->input, opcode_size, SEEK_CUR); + if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) + return CHUNK_BAD; break; case OPCODE_SET_DECODING_MAP: @@ -533,7 +544,8 @@ return 0; /* file is qualified; skip over the signature bytes (+ 6 unknown) in the stream */ - this->input->seek(this->input, IPMOVIE_SIGNATURE_SIZE+6, SEEK_SET); + if (this->input->seek(this->input, IPMOVIE_SIGNATURE_SIZE+6, SEEK_SET) < 0) + return 0; /* process the first chunk which should be CHUNK_INIT_VIDEO */ if (process_ipmovie_chunk(this) != CHUNK_INIT_VIDEO) |
From: Petri H. <phi...@us...> - 2018-05-07 10:04:02
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525686086 -10800 # Node ID 366b2f964ecac310965014a8ef9c128bbeb8dfd0 # Branch default # Parent fe5e00ae4659a2d271cc9fbb4a977c90e91b4299 demux_ts: enable seeking when input supports slow seek diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c --- a/src/demuxers/demux_ts.c +++ b/src/demuxers/demux_ts.c @@ -2499,7 +2499,7 @@ start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); - if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) { + if (this->input->get_capabilities(this->input) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)) { if ((!start_pos) && (start_time)) { |
From: Petri H. <phi...@us...> - 2018-05-07 10:04:02
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1523815790 -10800 # Node ID fe5e00ae4659a2d271cc9fbb4a977c90e91b4299 # Branch default # Parent 538f7599aa30c41fdebf756d3a97581775a4336b http: support (slow) seeking diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ + * Add seeking support to http input plugin. + xine-lib (1.2.9) 2018-01-11 * Add LIBXINE_VERBOSITY environment var override. * Add auto gapless switch. --git a/src/input/input_http.c b/src/input/input_http.c --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -88,6 +88,9 @@ /** Set to 1 if the stream is ShoutCast. */ unsigned int shoutcast_mode:1; + /* set to 1 if server replied with Accept-Ranges: bytes */ + unsigned int accept_range:1; + /* ShoutCast */ int shoutcast_metaint; off_t shoutcast_pos; @@ -465,6 +468,9 @@ !strncmp(this->url.uri + strlen(this->url.uri) - 4, ".nsv", 4)) caps |= INPUT_CAP_RIP_FORBIDDEN; + if (this->accept_range) { + caps |= INPUT_CAP_SLOW_SEEKABLE; + } return caps; } @@ -484,11 +490,70 @@ _x_url_cleanup(&this->url); } +static int http_restart(http_input_plugin_t * this, off_t abs_offset) +{ + /* save old stream */ + int old_fh = this->fh; + off_t old_pos = this->curpos; + + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "input_http: seek to %" PRId64 ": reconnecting ...\n", + (int64_t)abs_offset); + + this->fh = -1; + http_close(this); + + this->curpos = abs_offset; + if (this->input_plugin.open(&this->input_plugin) != 1) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "input_http: seek to %" PRId64 " failed (http request failed)\n", + (int64_t)abs_offset); + goto fail; + } + + if (this->curpos != abs_offset) { + /* something went wrong ... */ + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "input_http: seek to %" PRId64 " failed (server returned invalid range)\n", + (int64_t)abs_offset); + _x_io_tcp_close(this->stream, this->fh); + goto fail; + } + + /* close old connection */ + _x_io_tcp_close(this->stream, old_fh); + + return 0; + + fail: + /* restore old stream */ + this->fh = old_fh; + this->curpos = old_pos; + return -1; +} + static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; + off_t abs_offset; - return _x_input_seek_preview(this_gen, offset, origin, - &this->curpos, this->contentlength, this->preview_size); + abs_offset = _x_input_seek_preview(this_gen, offset, origin, + &this->curpos, this->contentlength, this->preview_size); + + if (abs_offset < 0 && this->accept_range) { + + abs_offset = _x_input_translate_seek(offset, origin, this->curpos, this->contentlength); + if (abs_offset < 0) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "input_http: invalid seek request (%d, %" PRId64 ")\n", + origin, (int64_t)offset); + return -1; + } + + if (http_restart(this, abs_offset) < 0) + return -1; + } + + return abs_offset; } static const char* http_plugin_get_mrl (input_plugin_t *this_gen) { @@ -603,8 +668,6 @@ else this->fh = _x_io_tcp_connect (this->stream, this->url.host, this->url.port); - this->curpos = 0; - if (this->fh == -1) return -2; @@ -650,6 +713,15 @@ snprintf (buf + buflen, sizeof(buf) - buflen, "Host: %s\015\012", this->url.host); + if (this->curpos > 0) { + /* restart from offset */ + buflen = strlen(buf); + snprintf (buf + buflen, sizeof(buf) - buflen, "Range: bytes=%" PRId64 "-\015\012", + (int64_t)this->curpos/*, (int64_t)this->contentlength - 1*/); + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_http: requesting restart from offset %" PRId64 "\n", + (int64_t)this->curpos); + } + buflen = strlen(buf); if (use_proxy && this_class->proxyuser && strlen(this_class->proxyuser)) { char *proxyauth; @@ -691,6 +763,7 @@ /* read and parse reply */ done = 0; len = 0; linenum = 0; this->contentlength = 0; + this->curpos = 0; while (!done) { /* fprintf (stderr, "input_http: read...\n"); */ @@ -772,6 +845,39 @@ } } + if (!strncasecmp(buf, "Content-Range", 13)) { + intmax_t contentlength, range_start, range_end; + if (sscanf(buf, "Content-Range: bytes %" SCNdMAX "-%" SCNdMAX "/%" SCNdMAX, + &range_start, &range_end, &contentlength) == 3) { + this->curpos = range_start; + this->contentlength = contentlength; + if (contentlength != range_end + 1) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "input_http: Reveived invalid content range: \'%s\'\n", buf); + /* truncate - there won't be more data anyway */ + this->contentlength = range_end + 1; + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "input_http: Stream starting at offset %" PRIdMAX "\n", range_start); + } + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "input_http: Error parsing \'%s\'\n", buf); + } + } + + if (!strncasecmp(buf, "Accept-Ranges", 13)) { + if (strstr(buf + 14, "bytes")) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "input_http: Server supports request ranges. Enabling seeking support.\n"); + this->accept_range = 1; + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, + "input_http: Unknown value in header \'%s\'\n", buf + 14); + this->accept_range = 0; + } + } + if (!strncasecmp(buf, "Location: ", 10)) { char *href = (buf + 10); @@ -892,6 +998,12 @@ } } + if (this->curpos > 0) { + /* restarting after seek */ + this->preview_size = 0; + return 1; + } + /* * fill preview buffer */ |
From: Petri H. <phi...@us...> - 2018-05-07 05:33:04
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1525077943 -10800 # Node ID 538f7599aa30c41fdebf756d3a97581775a4336b # Branch default # Parent c29602c42c5461773552bc3a378bc944435a8abb vo_none: drop unused variables diff --git a/src/video_out/video_out_none.c b/src/video_out/video_out_none.c --- a/src/video_out/video_out_none.c +++ b/src/video_out/video_out_none.c @@ -44,19 +44,16 @@ int height; double ratio; int format; - xine_t *xine; } vo_none_frame_t; typedef struct { vo_driver_t vo_driver; - config_values_t *config; int ratio; xine_t *xine; } vo_none_driver_t; typedef struct { video_driver_class_t driver_class; - config_values_t *config; xine_t *xine; } vo_none_class_t; @@ -253,7 +250,6 @@ driver = calloc(1, sizeof(vo_none_driver_t)); - driver->config = class->config; driver->xine = class->xine; driver->ratio = XINE_VO_ASPECT_AUTO; @@ -287,7 +283,6 @@ this->driver_class.description = N_("xine video output plugin which displays nothing"); this->driver_class.dispose = default_video_driver_class_dispose; - this->config = xine->config; this->xine = xine; return this; |
From: Torsten J. <t....@gm...> - 2018-05-05 15:00:02
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1525532370 -7200 # Node ID c29602c42c5461773552bc3a378bc944435a8abb # Branch default # Parent 9276a5491faf3a25385ea1074517d84de6a515aa demux_qt update 5. - Embed qt_info. - More frame builder optimization. diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -169,8 +169,10 @@ /** * @brief Network bandwidth, cribbed from src/input/input_mms.c */ -static const int64_t bandwidths[]={14400,19200,28800,33600,34430,57600, - 115200,262200,393216,524300,1544000,10485800}; +static const uint32_t bandwidths[] = { + 14400, 19200, 28800, 33600, 34430, 57600, + 115200, 262200, 393216, 524300, 1544000, 10485800 +}; /* these are things that can go wrong */ typedef enum { @@ -320,7 +322,8 @@ unsigned int samples; unsigned int sample_size; unsigned int sample_size_count; - unsigned int sample_size_bits; + unsigned int sample_size_bytes; + unsigned int sample_size_shift; unsigned char *sample_size_table; /* sync samples, a.k.a., keyframes */ @@ -425,7 +428,7 @@ int status; - qt_info *qt; + qt_info qt; xine_bmiheader bih; unsigned int current_frame; unsigned int last_frame; @@ -652,11 +655,7 @@ /* create a qt_info structure or return NULL if no memory */ static qt_info *create_qt_info (demux_qt_t *demux) { - qt_info *info; - - info = calloc (1, sizeof (*info)); - if (!info) - return NULL; + qt_info *info = &demux->qt; #ifndef HAVE_ZERO_SAFE_MEM info->compressed_header = 0; @@ -723,8 +722,7 @@ free(info->comment); free(info->composer); free(info->year); - free(info); - info = NULL; + memset (info, 0, sizeof (*info)); } } @@ -811,7 +809,14 @@ return numBytes; } -#define WRITE_BE_32(v,p) { \ +#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) +# define WRITE_BE_32(v,p) { \ + uint8_t *wp = (uint8_t *)(p); \ + int32_t n = __builtin_bswap32 ((int32_t)(v)); \ + __builtin_memcpy (wp, &n, 4); \ +} +#else +# define WRITE_BE_32(v,p) { \ unsigned char *wp = (unsigned char *)(p); \ uint32_t wv = (v); \ wp[0] = wv >> 24; \ @@ -819,6 +824,7 @@ wp[2] = wv >> 8; \ wp[3] = wv; \ } +#endif /* find sub atoms somewhere inside this atom */ static void find_embedded_atoms (uint8_t *atom, @@ -875,8 +881,8 @@ "edtsmdiaminfdinfstbl" /* look into these from "moov" (intentionally hide "trak"). */ "udtametailstiprosinfrmrarmdardrfrmvc"; - unsigned int atomtype, atomsize, subtype = 0, subsize = 0; - unsigned int i = 8, j, n, left; + unsigned int atomtype, atomsize, subsize = 0; + unsigned int i = 8, n, left; if (!atom || !types || !found) return 0; @@ -902,8 +908,9 @@ } for (; i + 8 <= atomsize; i += subsize) { - subsize = _X_BE_32 (&atom[i]); - subtype = _X_BE_32 (&atom[i + 4]); + unsigned int j; + uint32_t subtype = _X_BE_32 (&atom[i + 4]); + subsize = _X_BE_32 (&atom[i]); if (subsize == 0) { subsize = atomsize - i; WRITE_BE_32 (subsize, &atom[i]); @@ -973,7 +980,8 @@ trak->samples = 0; trak->sample_size = 0; trak->sample_size_count = 0; - trak->sample_size_bits = 0; + trak->sample_size_bytes = 0; + trak->sample_size_shift = 0; trak->sample_size_table = NULL; trak->sync_sample_count = 0; trak->sync_sample_table = NULL; @@ -1319,6 +1327,10 @@ else if (trak->type == MEDIA_AUDIO) do { +#ifndef HAVE_ZERO_SAFE_MEM + p->s.audio.wave_size = 0; + p->s.audio.wave = NULL; +#endif if (isize < 0x22) break; @@ -1440,11 +1452,11 @@ p->s.audio.samples_per_packet; [... 722 lines omitted ...] /* seek all supported audio traks */ - for (i = 0; i < this->qt->audio_trak_count; i++) { - audio_trak = &this->qt->traks[this->qt->audio_traks[i]]; + for (i = 0; i < this->qt.audio_trak_count; i++) { + audio_trak = &this->qt.traks[this->qt.audio_traks[i]]; this->status = binary_seek(audio_trak, start_pos, start_time); if (this->status != DEMUX_OK) return this->status; @@ -3561,8 +3602,8 @@ * back to the first audio frame that has a pts less than or equal to * that of the keyframe; do not go through with this process there is * no video trak */ - if (keyframe_pts >= 0) for (i = 0; i < this->qt->audio_trak_count; i++) { - audio_trak = &this->qt->traks[this->qt->audio_traks[i]]; + if (keyframe_pts >= 0) for (i = 0; i < this->qt.audio_trak_count; i++) { + audio_trak = &this->qt.traks[this->qt.audio_traks[i]]; if (keyframe_pts > audio_trak->frames[audio_trak->frame_count - 1].pts) { /* whoops, this trak is too short, mark it finished */ audio_trak->current_frame = audio_trak->frame_count; @@ -3574,7 +3615,7 @@ } } - this->qt->seek_flag = 1; + this->qt.seek_flag = 1; this->status = DEMUX_OK; /* @@ -3590,7 +3631,7 @@ static void demux_qt_dispose (demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; - free_qt_info(this->qt); + free_qt_info (&this->qt); free(this); } @@ -3604,10 +3645,10 @@ demux_qt_t *this = (demux_qt_t *) this_gen; - if (this->qt->timescale == 0) + if (this->qt.timescale == 0) return 0; - return (int)((int64_t) 1000 * this->qt->duration / this->qt->timescale); + return (int)((int64_t) 1000 * this->qt.duration / this->qt.timescale); } static uint32_t demux_qt_get_capabilities(demux_plugin_t *this_gen) { @@ -3627,10 +3668,10 @@ case DEMUX_OPTIONAL_DATA_AUDIOLANG: { char *str = data; int channel = *((int *)data); - if ((channel < 0) || (channel >= this->qt->audio_trak_count)) { + if ((channel < 0) || (channel >= this->qt.audio_trak_count)) { strcpy (str, "none"); } else { - int lang = this->qt->traks[this->qt->audio_traks[channel]].lang; + int lang = this->qt.traks[this->qt.audio_traks[channel]].lang; if ((lang < 0x400) || (lang == 0x7fff)) { sprintf (str, "%d", channel); } else { @@ -3670,7 +3711,9 @@ return NULL; } - this = calloc(1, sizeof(demux_qt_t)); + this = calloc (1, sizeof (demux_qt_t)); + if (!this) + return NULL; this->stream = stream; this->input = input; @@ -3694,26 +3737,23 @@ this->status = DEMUX_FINISHED; - if ((this->qt = create_qt_info (this)) == NULL) { - free (this); - return NULL; - } + create_qt_info (this); switch (stream->content_detection_method) { case METHOD_BY_CONTENT: - last_error = open_qt_file(this->qt, this->input, this->bandwidth); + last_error = open_qt_file (&this->qt, this->input, this->bandwidth); if (last_error == QT_DRM_NOT_SUPPORTED) { /* special consideration for DRM-protected files */ - if (this->qt->last_error == QT_DRM_NOT_SUPPORTED) + if (this->qt.last_error == QT_DRM_NOT_SUPPORTED) _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "DRM-protected Quicktime file", NULL); } else if (last_error != QT_OK) { - free_qt_info (this->qt); + free_qt_info (&this->qt); free (this); return NULL; } @@ -3721,8 +3761,8 @@ break; default: - if (open_qt_file(this->qt, this->input, this->bandwidth) != QT_OK) { - free_qt_info (this->qt); + if (open_qt_file (&this->qt, this->input, this->bandwidth) != QT_OK) { + free_qt_info (&this->qt); free (this); return NULL; } @@ -3730,9 +3770,9 @@ break; } - if (this->qt->fragment_count > 0) + if (this->qt.fragment_count > 0) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, - _("demux_qt: added %d fragments\n"), this->qt->fragment_count); + _("demux_qt: added %d fragments\n"), this->qt.fragment_count); return &this->demux_plugin; } |
From: Torsten J. <t....@gm...> - 2018-04-30 14:21:09
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1525098030 -7200 # Node ID c4384d89b26eef080af83284298089a71ef36201 # Branch default # Parent cc309b867ac2d46366485be2de2c3bbcbad0a09f demux_qt update 4. - Fix little endian 24bit audio regression from update 3. - Minor audio param parser optimization. diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -1142,6 +1142,10 @@ isize = atomsize; p->properties_atom = item; p->properties_atom_size = isize; +#ifndef HAVE_ZERO_SAFE_MEM + p->decoder_config_len = 0; + p->decoder_config = NULL; +#endif p->media_id = k + 1; p->codec_fourcc = _X_ME_32 (item + 4); _x_tag32_me2str (p->codec_str, p->codec_fourcc); @@ -1318,15 +1322,30 @@ if (isize < 0x22) break; - /* fetch audio parameters */ - p->s.audio.sample_rate = _X_BE_16 (item + 0x20); - p->s.audio.channels = item[0x19]; - p->s.audio.bits = item[0x1b]; - + /* fetch audio parameters, assume uncompressed */ + p->s.audio.sample_rate = _X_BE_16 (item + 0x20); + p->s.audio.channels = + p->s.audio.samples_per_frame = + p->s.audio.samples_per_packet = item[0x19]; + p->s.audio.bits = item[0x1b]; + p->s.audio.bytes_per_sample = + p->s.audio.bytes_per_packet = p->s.audio.bits / 8; + p->s.audio.bytes_per_frame = p->s.audio.bytes_per_sample * p->s.audio.samples_per_frame; + + /* 24-bit audio doesn't always declare itself properly, and can be big- or little-endian */ + if ((p->codec_fourcc == IN24_FOURCC) && (isize >= 0x52)) { + p->s.audio.bits = 24; + if (_X_BE_32 (item + 0x4c) == ENDA_ATOM && item[0x51]) + p->codec_fourcc = NI42_FOURCC; + } p->codec_buftype = _x_formattag_to_buf_audio (p->codec_fourcc); + + /* see if the trak deserves a promotion to VBR */ + p->s.audio.vbr = (_X_BE_16 (item + 0x1c) == 0xFFFE) ? 1 : 0; /* in mp4 files the audio fourcc is always 'mp4a' - the codec is * specified by the object type id field in the esds atom */ if (p->codec_fourcc == MP4A_FOURCC) { + p->s.audio.vbr = 1; if (p->object_type_id == 221) { p->codec_buftype = BUF_AUDIO_VORBIS; memcpy (p->codec_str, "vorbis", 7); @@ -1335,24 +1354,26 @@ memcpy (p->codec_str, "mp3", 4); } } - - /* 24-bit audio doesn't always declare itself properly, and can be big- or little-endian */ - if ((p->codec_fourcc == IN24_FOURCC) && (isize >= 0x52)) { - p->s.audio.bits = 24; - if (_X_BE_32 (item + 0x4c) == ENDA_ATOM && item[0x51]) - p->codec_fourcc = NI42_FOURCC; + /* if this is MP4 audio, mark the trak as VBR */ + else if ((p->codec_fourcc == SAMR_FOURCC) || + (p->codec_fourcc == AC_3_FOURCC) || + (p->codec_fourcc == EAC3_FOURCC) || + (p->codec_fourcc == QCLP_FOURCC)) { + p->s.audio.vbr = 1; } - /* assume uncompressed audio parameters */ - p->s.audio.bytes_per_sample = p->s.audio.bits / 8; - p->s.audio.samples_per_frame = p->s.audio.channels; - p->s.audio.bytes_per_frame = p->s.audio.bytes_per_sample * p->s.audio.samples_per_frame; - p->s.audio.samples_per_packet = p->s.audio.samples_per_frame; - p->s.audio.bytes_per_packet = p->s.audio.bytes_per_sample; + else if (p->codec_fourcc == ALAC_FOURCC) { + p->s.audio.vbr = 1; + if (isize >= 0x24 + 36) { + /* further, FFmpeg's ALAC decoder requires 36 out-of-band bytes */ + p->decoder_config_len = 36; + p->decoder_config = item + 0x24; + } + } /* special case time: A lot of CBR audio codecs stored in the * early days lacked the extra header; compensate */ - if (p->codec_fourcc == IMA4_FOURCC) { + else if (p->codec_fourcc == IMA4_FOURCC) { p->s.audio.samples_per_packet = 64; p->s.audio.bytes_per_packet = 34; p->s.audio.bytes_per_frame = 34 * p->s.audio.channels; @@ -1384,6 +1405,11 @@ p->s.audio.samples_per_frame = 2 * p->s.audio.channels; } + else if (p->codec_fourcc == DRMS_FOURCC) { + last_error = QT_DRM_NOT_SUPPORTED; + goto free_trak; + } + /* it's time to dig a little deeper to determine the real audio * properties; if a the stsd compressor atom has 0x24 bytes, it * appears to be a handler for uncompressed data; if there are an @@ -1414,30 +1440,11 @@ p->s.audio.samples_per_packet; } - /* see if the trak deserves a promotion to VBR */ - p->s.audio.vbr = (_X_BE_16 (item + 0x1c) == 0xFFFE) ? 1 : 0; - - /* if this is MP4 audio, mark the trak as VBR */ - if ((p->codec_fourcc == MP4A_FOURCC) || - (p->codec_fourcc == SAMR_FOURCC) || - (p->codec_fourcc == AC_3_FOURCC) || - (p->codec_fourcc == EAC3_FOURCC) || - (p->codec_fourcc == QCLP_FOURCC)) - p->s.audio.vbr = 1; - - else if ((p->codec_fourcc == ALAC_FOURCC) && (isize >= 0x24 + 36)) { - p->s.audio.vbr = 1; - /* further, FFmpeg's ALAC decoder requires 36 out-of-band bytes */ - p->decoder_config_len = 36; - p->decoder_config = item + 0x24; - } - - else if (p->codec_fourcc == DRMS_FOURCC) { - last_error = QT_DRM_NOT_SUPPORTED; - goto free_trak; - } - /* check for a MS-style WAVE format header */ +#ifndef HAVE_ZERO_SAFE_MEM + p->s.audio.wave_size = 0; + p->s.audio.wave = NULL; +#endif if ((isize >= 0x50) && (_X_BE_32 (item + 0x38) == WAVE_ATOM) && (_X_BE_32 (item + 0x40) == FRMA_ATOM) && @@ -1455,13 +1462,7 @@ } memcpy (p->s.audio.wave, item + 0x50, wave_size); _x_waveformatex_le2me (p->s.audio.wave); - } else { - p->s.audio.wave_size = 0; - p->s.audio.wave = NULL; } - } else { - p->s.audio.wave_size = 0; - p->s.audio.wave = NULL; } k++; |
From: Torsten J. <t....@gm...> - 2018-04-30 14:21:06
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1525098035 -7200 # Node ID 9276a5491faf3a25385ea1074517d84de6a515aa # Branch default # Parent c4384d89b26eef080af83284298089a71ef36201 Fix keyframes log. diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -3091,15 +3091,17 @@ int _x_keyframes_set (xine_stream_t *stream, xine_keyframes_entry_t *list, int size) { int n = (size + KF_MASK) & ~KF_MASK; pthread_mutex_lock (&stream->index_mutex); - free (stream->index_array); + if (stream->index_array) { + xprintf (stream->xine, XINE_VERBOSITY_DEBUG, + "keyframes: deleting index.\n"); + free (stream->index_array); + } stream->index_lastadd = 0; stream->index_array = (list && (n > 0)) ? malloc (n * sizeof (xine_keyframes_entry_t)) : NULL; if (!stream->index_array) { stream->index_used = 0; stream->index_size = 0; pthread_mutex_unlock (&stream->index_mutex); - xprintf (stream->xine, XINE_VERBOSITY_DEBUG, - "keyframes: deleting index.\n"); return 1; } memcpy (stream->index_array, list, size * sizeof (xine_keyframes_entry_t)); |
From: Petri H. <phi...@us...> - 2018-04-29 10:06:34
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1524900325 -10800 # Node ID cc309b867ac2d46366485be2de2c3bbcbad0a09f # Branch default # Parent 724dfa67b6778c39470185e41377b9a4e700e4d9 Fix leaks diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c --- a/src/demuxers/demux_avi.c +++ b/src/demuxers/demux_avi.c @@ -693,6 +693,13 @@ return &(AVI_A->audio_idx.aindex[AVI_A->audio_posc]); } +static void free_superindex(avisuperindex_chunk **p) { + if (*p) { + _x_freep(&(*p)->aIndex); + } + _x_freep(p); +} + static void AVI_close(avi_t *AVI){ int i; @@ -700,7 +707,10 @@ _x_freep(&AVI->video_idx.vindex); _x_freep(&AVI->bih); + free_superindex(&AVI->video_superindex); + for(i=0; i<AVI->n_audio; i++) { + free_superindex(&AVI->audio[i]->audio_superindex); _x_freep(&AVI->audio[i]->audio_idx.aindex); _x_freep(&AVI->audio[i]->wavex); _x_freep(&AVI->audio[i]); --git a/src/demuxers/demux_vc1es.c b/src/demuxers/demux_vc1es.c --- a/src/demuxers/demux_vc1es.c +++ b/src/demuxers/demux_vc1es.c @@ -330,6 +330,9 @@ return NULL; } + if ( input->seek( input, SCRATCH_SIZE, SEEK_SET ) != SCRATCH_SIZE ) + return NULL; + this = calloc(1, sizeof(demux_vc1_es_t)); if (!this) return NULL; @@ -356,9 +359,6 @@ this->status = DEMUX_FINISHED; - if ( input->seek( input, SCRATCH_SIZE, SEEK_SET ) != SCRATCH_SIZE ) - return NULL; - return &this->demux_plugin; } |
From: Torsten J. <t....@gm...> - 2018-04-28 14:00:18
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1524923995 -7200 # Node ID 724dfa67b6778c39470185e41377b9a4e700e4d9 # Branch default # Parent 64c6af122269a86cc0e21c22393595cd1791fe57 demux_qt update 3. - Save 25% on frame lists (~1Mb per 1 hour trak). - Fix standard edit list last frame. - Optimize standard edit list parser. - Fix fragment edit list initial delay. - Enable edit lists for legacy audio. - Remove unreachable code. - Debug list traks. - Fix typo. - Simplify trak properties parser. - Prepare for multi media_id mode. diff --git a/src/demuxers/demux_qt.c b/src/demuxers/demux_qt.c --- a/src/demuxers/demux_qt.c +++ b/src/demuxers/demux_qt.c @@ -194,8 +194,13 @@ } media_type; +/* TJ. Cinematic movies reach > 200000 frames easily, so we better save space here. + * offset / file size should well fit into 48 bits :-) */ typedef struct { - int64_t offset; + union { + int64_t offset; + uint8_t bytes[8]; + } _ffs; unsigned int size; /* pts actually is dts for reordered video. Edit list and frame duration code relies on that, so keep the offset separately @@ -203,9 +208,15 @@ Value is small enough for plain int. */ int ptsoffs; int64_t pts; - int keyframe; - unsigned int media_id; } qt_frame; +#define QTF_OFFSET(f) ((f)._ffs.offset & ~((uint64_t)0xffff << 48)) +#ifdef WORDS_BIGENDIAN +# define QTF_KEYFRAME(f) ((f)._ffs.bytes[0]) +# define QTF_MEDIA_ID(f) ((f)._ffs.bytes[1]) +#else +# define QTF_KEYFRAME(f) ((f)._ffs.bytes[7]) +# define QTF_MEDIA_ID(f) ((f)._ffs.bytes[6]) +#endif typedef struct { int64_t track_duration; @@ -224,55 +235,44 @@ int qtim_version; } reference_t; -typedef union { - - struct { - /* the media id that corresponds to this trak */ - unsigned int media_id; - - /* offset into the stsd atom of the properties atom */ - unsigned int properties_offset; - - unsigned int codec_fourcc; - unsigned int codec_buftype; - unsigned int width; - unsigned int height; - int palette_count; - palette_entry_t palette[PALETTE_COUNT]; - int depth; - int edit_list_compensation; /* special trick for edit lists */ - - unsigned char *properties_atom; - unsigned int properties_atom_size; - } video; - - struct { - /* the media id that corresponds to this trak */ - unsigned int media_id; - - /* offset into the stsd atom of the properties atom */ - unsigned int properties_offset; - - unsigned int codec_fourcc; - unsigned int codec_buftype; - unsigned int sample_rate; - unsigned int channels; - unsigned int bits; - unsigned int vbr; - unsigned int wave_size; - xine_waveformatex *wave; - - /* special audio parameters */ - unsigned int samples_per_packet; - unsigned int bytes_per_packet; - unsigned int bytes_per_frame; - unsigned int bytes_per_sample; - unsigned int samples_per_frame; - - unsigned char *properties_atom; - unsigned int properties_atom_size; - } audio; - +typedef struct { + /* the media id that corresponds to this trak */ + unsigned int media_id; + unsigned int codec_fourcc; + unsigned int codec_buftype; + unsigned char *properties_atom; + unsigned char *decoder_config; + unsigned int properties_atom_size; + unsigned int decoder_config_len; + char codec_str[20]; + /* formattag-like field that specifies codec in mp4 files */ + int object_type_id; + union { + struct { + unsigned int width; + unsigned int height; + int depth; + int edit_list_compensation; /* special trick for edit lists */ + + int palette_count; + palette_entry_t palette[PALETTE_COUNT]; + } video; + struct { + unsigned int sample_rate; + unsigned int channels; + unsigned int bits; + unsigned int vbr; + + unsigned int wave_size; + xine_waveformatex *wave; + /* special audio parameters */ + unsigned int samples_per_packet; + unsigned int bytes_per_packet; + unsigned int bytes_per_frame; + unsigned int bytes_per_sample; + unsigned int samples_per_frame; + } audio; + } s; } properties_t; [... 1847 lines omitted ...] } - if (!audio_trak->properties->audio.codec_buftype && - audio_trak->properties->audio.codec_fourcc) { - audio_trak->properties->audio.codec_buftype = BUF_AUDIO_UNKNOWN; - _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, - audio_trak->properties->audio.codec_fourcc); - } - - if ((audio_trak->properties->audio.codec_buftype == 0) || + if ((audio_trak->properties->codec_buftype == 0) || (audio_index >= MAX_AUDIO_TRAKS) || (this->audio_fifo == NULL)) continue; @@ -3364,31 +3390,31 @@ audio_trak->audio_index = audio_index; /* set the audio bitrate field (only for CBR audio) */ - if (!audio_trak->properties->audio.vbr) { + if (!audio_trak->properties->s.audio.vbr) { audio_bitrate = - audio_trak->properties->audio.sample_rate / - audio_trak->properties->audio.samples_per_frame * - audio_trak->properties->audio.bytes_per_frame * - audio_trak->properties->audio.channels * + audio_trak->properties->s.audio.sample_rate / + audio_trak->properties->s.audio.samples_per_frame * + audio_trak->properties->s.audio.bytes_per_frame * + audio_trak->properties->s.audio.channels * 8; _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, audio_bitrate); } buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = audio_trak->properties->audio.codec_buftype | audio_index; + buf->type = audio_trak->properties->codec_buftype | audio_index; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; - buf->decoder_info[1] = audio_trak->properties->audio.sample_rate; - buf->decoder_info[2] = audio_trak->properties->audio.bits; - buf->decoder_info[3] = audio_trak->properties->audio.channels; - - if( audio_trak->properties->audio.wave_size ) { - if (audio_trak->properties->audio.wave_size > (unsigned int)buf->max_size) + buf->decoder_info[1] = audio_trak->properties->s.audio.sample_rate; + buf->decoder_info[2] = audio_trak->properties->s.audio.bits; + buf->decoder_info[3] = audio_trak->properties->s.audio.channels; + + if( audio_trak->properties->s.audio.wave_size ) { + if (audio_trak->properties->s.audio.wave_size > (unsigned int)buf->max_size) buf->size = buf->max_size; else - buf->size = audio_trak->properties->audio.wave_size; - memcpy(buf->content, audio_trak->properties->audio.wave, buf->size); + buf->size = audio_trak->properties->s.audio.wave_size; + memcpy (buf->content, audio_trak->properties->s.audio.wave, buf->size); } else { buf->size = 0; buf->content = NULL; @@ -3396,14 +3422,14 @@ this->audio_fifo->put (this->audio_fifo, buf); - if( audio_trak->decoder_config ) { + if (audio_trak->properties->decoder_config) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); - buf->type = audio_trak->properties->audio.codec_buftype | audio_index; + buf->type = audio_trak->properties->codec_buftype | audio_index; buf->size = 0; buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG; - buf->decoder_info[2] = audio_trak->decoder_config_len; - buf->decoder_info_ptr[2] = audio_trak->decoder_config; + buf->decoder_info[2] = audio_trak->properties->decoder_config_len; + buf->decoder_info_ptr[2] = audio_trak->properties->decoder_config; this->audio_fifo->put (this->audio_fifo, buf); } @@ -3411,10 +3437,10 @@ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_STSD_ATOM; - buf->decoder_info[2] = audio_trak->properties->audio.properties_atom_size; - buf->decoder_info_ptr[2] = audio_trak->properties->audio.properties_atom; + buf->decoder_info[2] = audio_trak->properties->properties_atom_size - 4; + buf->decoder_info_ptr[2] = audio_trak->properties->properties_atom + 4; buf->size = 0; - buf->type = audio_trak->properties->audio.codec_buftype | audio_index; + buf->type = audio_trak->properties->codec_buftype | audio_index; this->audio_fifo->put (this->audio_fifo, buf); this->qt->audio_trak_count = ++audio_index; @@ -3435,9 +3461,9 @@ /* perform a binary search on the trak, testing the offset * boundaries first; offset request has precedent over time request */ if (start_pos) { - if (start_pos <= trak->frames[0].offset) + if (start_pos <= (off_t)QTF_OFFSET(trak->frames[0])) best_index = 0; - else if (start_pos >= trak->frames[trak->frame_count - 1].offset) + else if (start_pos >= (off_t)QTF_OFFSET(trak->frames[trak->frame_count - 1])) best_index = trak->frame_count - 1; else { left = 0; @@ -3446,10 +3472,10 @@ while (!found) { middle = (left + right + 1) / 2; - if ((start_pos >= trak->frames[middle].offset) && - (start_pos < trak->frames[middle + 1].offset)) { + if ((start_pos >= (off_t)QTF_OFFSET(trak->frames[middle])) && + (start_pos < (off_t)QTF_OFFSET(trak->frames[middle + 1]))) { found = 1; - } else if (start_pos < trak->frames[middle].offset) { + } else if (start_pos < (off_t)QTF_OFFSET(trak->frames[middle])) { right = middle - 1; } else { left = middle; @@ -3514,7 +3540,7 @@ return this->status; /* search back in the video trak for the nearest keyframe */ while (video_trak->current_frame) { - if (video_trak->frames[video_trak->current_frame].keyframe) { + if (QTF_KEYFRAME(video_trak->frames[video_trak->current_frame])) { break; } video_trak->current_frame--; |
From: Torsten J. <t....@gm...> - 2018-04-28 14:00:17
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1524923990 -7200 # Node ID 64c6af122269a86cc0e21c22393595cd1791fe57 # Branch default # Parent 5abd264ec8fe3d1634602478cde435054b04ace1 Add fast x86 _X_?E_16 (). Partial register write is not optimal, but the alternative is an extra temp register... diff --git a/src/xine-engine/bswap.h b/src/xine-engine/bswap.h --- a/src/xine-engine/bswap.h +++ b/src/xine-engine/bswap.h @@ -96,6 +96,22 @@ # define _X_LE_32(x) ({ uint32_t tempi; __builtin_memcpy (&tempi, (x), 4); tempi; }) # define _X_LE_64(x) ({ uint64_t tempi; __builtin_memcpy (&tempi, (x), 8); tempi; }) # endif +# if defined(ARCH_X86) + /* These machines have true (u)int16_t. */ +# undef _X_BE_16 +# undef _X_LE_16 +# define _X_BE_16(x) ({ \ + uint16_t tempi; \ + __builtin_memcpy (&tempi, (x), 2); \ + __asm__ __volatile__ ( \ + "rolw\t$8, %0" \ + : "=r" (tempi) \ + : "0" (tempi) \ + : "cc" \ + ); \ + tempi; }) +# define _X_LE_16(x) ({ uint16_t tempi; __builtin_memcpy (&tempi, (x), 2); tempi; }) +# endif #endif #ifdef WORDS_BIGENDIAN |
From: Torsten J. <t....@gm...> - 2018-04-28 14:00:17
|
# HG changeset patch # User Torsten Jager <t....@gm...> # Date 1524923985 -7200 # Node ID 5abd264ec8fe3d1634602478cde435054b04ace1 # Branch default # Parent 455aca0352dd4e638c9f351339c46e1f42847e79 asfheader: silence warnings. diff --git a/src/demuxers/asfheader.c b/src/demuxers/asfheader.c --- a/src/demuxers/asfheader.c +++ b/src/demuxers/asfheader.c @@ -566,6 +566,10 @@ data_type = _X_LE_16 (p); p += 2; data_len = _X_LE_32 (p); p += 4; + /* not used yet */ + (void)index; + (void)data_type; + stream_id = asf_header_get_stream_id (&header->pub, stream); if (data_len >= 4) { @@ -611,6 +615,8 @@ return 0; data_length = _X_LE_32 (p + 16 + 2); lprintf("parse_asf_header_extension: length: %"PRIu32"\n", data_length); + /* used in LOG mode only */ + (void)data_length; while (!asf_reader_eos(&reader)) { @@ -747,6 +753,8 @@ asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 4 + 2); object_count = _X_LE_32 (p); + /* not used yet */ + (void)object_count; while (!asf_reader_eos(&reader)) { |
From: Petri H. <phi...@us...> - 2018-04-27 10:08:40
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1524823672 -10800 # Node ID 455aca0352dd4e638c9f351339c46e1f42847e79 # Branch default # Parent ec800689d8cceeb84a1ed6bd571fad68c93ecdf9 Fix implicit conversion error when comparing negative int and size_t diff --git a/src/input/input_http.c b/src/input/input_http.c --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -850,11 +850,10 @@ if (len == -1) done = 1; - else - len = 0; + len = 0; } else len ++; - if ( len >= sizeof(buf) ) { + if ( len >= (int)sizeof(buf) ) { _x_message(this->stream, XINE_MSG_PERMISSION_ERROR, this->mrl, NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: buffer exhausted after %zu bytes."), sizeof(buf)); |
From: Petri H. <phi...@us...> - 2018-04-27 10:08:39
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1524823528 -10800 # Node ID ec800689d8cceeb84a1ed6bd571fad68c93ecdf9 # Branch default # Parent e77333b063d5930776223f4f46a429445b507fe6 Fix possible leak diff --git a/src/input/input_http.c b/src/input/input_http.c --- a/src/input/input_http.c +++ b/src/input/input_http.c @@ -914,8 +914,10 @@ lprintf("preview_size=%"PRId64"\n", this->preview_size); this->curpos = 0; - if (*mime_type) + if (*mime_type) { + free(this->mime_type); this->mime_type = strdup (mime_type); + } return 1; } |
From: Petri H. <phi...@us...> - 2018-04-27 10:02:06
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1524823109 -10800 # Node ID e77333b063d5930776223f4f46a429445b507fe6 # Branch default # Parent 07a9496c3af481e372ad5fbf20115501165ff44a ftp: set INPUT_CAP_SLOW_SEEKABLE when server supports restarting from file offset diff --git a/src/input/input_ftp.c b/src/input/input_ftp.c --- a/src/input/input_ftp.c +++ b/src/input/input_ftp.c @@ -643,6 +643,13 @@ return result; } +static uint32_t _ftp_get_capabilities (input_plugin_t *this_gen) +{ + ftp_input_plugin_t *this = (ftp_input_plugin_t *)this_gen; + + return INPUT_CAP_PREVIEW | (this->cap_rest ? INPUT_CAP_SLOW_SEEKABLE : 0); +} + static input_plugin_t *_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { ftp_input_class_t *class = (ftp_input_class_t *)cls_gen; @@ -666,7 +673,7 @@ this->fd_data = -1; this->input_plugin.open = _ftp_open; - this->input_plugin.get_capabilities = _x_input_get_capabilities_preview; + this->input_plugin.get_capabilities = _ftp_get_capabilities; this->input_plugin.read = _ftp_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = _ftp_seek; |
From: Petri H. <phi...@us...> - 2018-04-27 10:02:03
|
# HG changeset patch # User Petri Hintukainen <phi...@us...> # Date 1524822998 -10800 # Node ID 07a9496c3af481e372ad5fbf20115501165ff44a # Branch default # Parent 42d000904c70a2f883d78abfdc43e30462e96d4c Set XINE_STREAM_INFO_SEEKABLE for GUI when input announces INPUT_CAP_SLOW_SEEKABLE diff --git a/src/xine-engine/xine_interface.c b/src/xine-engine/xine_interface.c --- a/src/xine-engine/xine_interface.c +++ b/src/xine-engine/xine_interface.c @@ -721,7 +721,7 @@ case XINE_STREAM_INFO_SEEKABLE: if (stream->input_plugin) - return stream->input_plugin->get_capabilities (stream->input_plugin) & INPUT_CAP_SEEKABLE; + return stream->input_plugin->get_capabilities (stream->input_plugin) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE); return 0; case XINE_STREAM_INFO_HAS_CHAPTERS: |