summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--lib/strndup.c60
-rw-r--r--lib/strsep.c98
-rw-r--r--src/demuxers/demux_asf.c146
-rw-r--r--src/demuxers/demux_ts.c6
-rw-r--r--src/input/input_dvb.c34
6 files changed, 209 insertions, 137 deletions
diff --git a/ChangeLog b/ChangeLog
index 4c32a405f..8c675fdb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -58,6 +58,8 @@ xine-lib (1.1.9) (unreleased)
* Build fix for when using Linux 2.6.23 headers. [Bug 1820958]
* Implemented decoding of XML character entities with codes >= 256.
This requires conversion to UTF-8 of entities with codes >= 128.
+ * Fixed ATSC support. [Bug 1749508]
+ * Fixed a possible DVB plugin crash when switching channels.
xine-lib (1.1.8)
* Send a channel-changed event to the frontend when receiving the SYNC
diff --git a/lib/strndup.c b/lib/strndup.c
index 9f347db87..1e01aa018 100644
--- a/lib/strndup.c
+++ b/lib/strndup.c
@@ -1,16 +1,56 @@
+/* $NetBSD: strndup.c,v 1.4 2007/07/03 12:11:09 nakayama Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ * Modified for xine project.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
#include "config.h"
-#ifdef HAVE_STDLIB_H
+#include <errno.h>
#include <stdlib.h>
-#endif
-
#include <string.h>
-char *xine_private_strndup(const char *s, size_t n) {
- char *ret;
-
- ret = malloc (n + 1);
- strncpy(ret, s, n);
- ret[n] = '\0';
- return ret;
+char *
+xine_private_strndup(const char *str, size_t n)
+{
+ size_t len;
+ char *copy;
+
+ if (!str)
+ return (NULL);
+
+ for (len = 0; len < n && str[len]; len++)
+ continue;
+
+ if (!(copy = malloc(len + 1)))
+ return (NULL);
+ memcpy(copy, str, len);
+ copy[len] = '\0';
+ return (copy);
}
diff --git a/lib/strsep.c b/lib/strsep.c
index d63a12f56..3170e4867 100644
--- a/lib/strsep.c
+++ b/lib/strsep.c
@@ -1,36 +1,72 @@
-#include "config.h"
-#include <string.h>
-
-char *xine_private_strsep(char **stringp, const char *delim) {
- char *begin, *end;
+/* $OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
- begin = *stringp;
- if(begin == NULL)
- return NULL;
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
- if(delim[0] == '\0' || delim[1] == '\0') {
- char ch = delim[0];
-
- if(ch == '\0')
- end = NULL;
- else {
- if(*begin == ch)
- end = begin;
- else if(*begin == '\0')
- end = NULL;
- else
- end = strchr(begin + 1, ch);
- }
- }
- else
- end = strpbrk(begin, delim);
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
- if(end) {
- *end++ = '\0';
- *stringp = end;
- }
- else
- *stringp = NULL;
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ */
+char *
+xine_private_strsep(char **stringp, const char *delim)
+{
+ char *s;
+ const char *spanp;
+ int c, sc;
+ char *tok;
- return begin;
+ if ((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
}
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index 447228fb0..742fa6541 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.c
@@ -1536,108 +1536,90 @@ static int demux_asf_parse_asx_references( demux_asf_t *this) {
ENTRYREF, MOREINFO, PARAM, REPEAT, TITLE
*/
- const char *version = xml_parser_get_property (xml_tree, "VERSION");
+ const char *base_href = NULL;
- if (version) {
- int version_major, version_minor = 0;
+ for (asx_entry = xml_tree->child; asx_entry; asx_entry = asx_entry->next)
+ {
+ const char *ref_base_href = base_href;
- if((sscanf (version, "%d.%d", &version_major, &version_minor) == 2 ||
- sscanf (version, "%d", &version_major) == 1) &&
- (version_major == 3 && version_minor == 0))
+ if (!strcasecmp (asx_entry->name, "ENTRY"))
{
- const char *base_href = NULL;
+ /* Attributes: CLIENTSKIP, SKIPIFREF
+ * Child elements: ABSTRACT, AUTHOR, BASE, COPYRIGHT, DURATION,
+ ENDMARKER, MOREINFO, PARAM, REF, STARTMARKER,
+ STARTTIME, TITLE
+ */
+ const char *href = NULL;
+ const char *title = NULL;
+ uint32_t start_time = (uint32_t)-1;
+ uint32_t duration = (uint32_t)-1;
- for (asx_entry = xml_tree->child; asx_entry; asx_entry = asx_entry->next)
+ for (asx_ref = asx_entry->child; asx_ref; asx_ref = asx_ref->next)
{
- const char *ref_base_href = base_href;
-
- if (!strcasecmp (asx_entry->name, "ENTRY"))
+ if (!strcasecmp(asx_ref->name, "REF"))
{
- /* Attributes: CLIENTSKIP, SKIPIFREF
- * Child elements: ABSTRACT, AUTHOR, BASE, COPYRIGHT, DURATION,
- ENDMARKER, MOREINFO, PARAM, REF, STARTMARKER,
- STARTTIME, TITLE
+ xml_node_t *asx_sub;
+ /* Attributes: HREF
+ * Child elements: DURATION, ENDMARKER, STARTMARKER, STARTTIME
+ */
+
+ /* FIXME: multiple REFs => alternative streams
+ * (and per-ref start times and durations?).
+ * Just the one title, though.
*/
- const char *href = NULL;
- const char *title = NULL;
- uint32_t start_time = (uint32_t)-1;
- uint32_t duration = (uint32_t)-1;
+ href = xml_parser_get_property (asx_ref, "HREF");
- for (asx_ref = asx_entry->child; asx_ref; asx_ref = asx_ref->next)
+ for (asx_sub = asx_ref->child; asx_sub; asx_sub = asx_sub->next)
{
- if (!strcasecmp(asx_ref->name, "REF"))
- {
- xml_node_t *asx_sub;
- /* Attributes: HREF
- * Child elements: DURATION, ENDMARKER, STARTMARKER, STARTTIME
- */
-
- /* FIXME: multiple REFs => alternative streams
- * (and per-ref start times and durations?).
- * Just the one title, though.
- */
- href = xml_parser_get_property (asx_ref, "HREF");
-
- for (asx_sub = asx_ref->child; asx_sub; asx_sub = asx_sub->next)
- {
- if (!strcasecmp (asx_sub->name, "STARTTIME"))
- start_time = asx_get_time_value (asx_sub);
- else if (!strcasecmp (asx_sub->name, "DURATION"))
- duration = asx_get_time_value (asx_sub);
- }
- }
-
- else if (!strcasecmp (asx_ref->name, "TITLE"))
- {
- if (!title)
- title = asx_ref->data;
- }
-
- else if (!strcasecmp (asx_ref->name, "STARTTIME"))
- {
- if (start_time == (uint32_t)-1)
- start_time = asx_get_time_value (asx_ref);
- }
-
- else if (!strcasecmp (asx_ref->name, "DURATION"))
- {
- if (duration == (uint32_t)-1)
- duration = asx_get_time_value (asx_ref);
- }
-
- else if (!strcasecmp (asx_ref->name, "BASE"))
- /* Attributes: HREF */
- ref_base_href = xml_parser_get_property (asx_entry, "HREF");
+ if (!strcasecmp (asx_sub->name, "STARTTIME"))
+ start_time = asx_get_time_value (asx_sub);
+ else if (!strcasecmp (asx_sub->name, "DURATION"))
+ duration = asx_get_time_value (asx_sub);
}
+ }
+
+ else if (!strcasecmp (asx_ref->name, "TITLE"))
+ {
+ if (!title)
+ title = asx_ref->data;
+ }
- /* FIXME: prepend ref_base_href to href */
- if (href && *href)
- _x_demux_send_mrl_reference (this->stream, 0, href, title,
- start_time == (uint32_t)-1 ? 0 : start_time,
- duration == (uint32_t)-1 ? -1 : duration);
+ else if (!strcasecmp (asx_ref->name, "STARTTIME"))
+ {
+ if (start_time == (uint32_t)-1)
+ start_time = asx_get_time_value (asx_ref);
}
- else if (!strcasecmp (asx_entry->name, "ENTRYREF"))
+ else if (!strcasecmp (asx_ref->name, "DURATION"))
{
- /* Attributes: HREF, CLIENTBIND */
- const char *href = xml_parser_get_property (asx_entry, "HREF");
- if (href && *href)
- _x_demux_send_mrl_reference (this->stream, 0, href, NULL, 0, -1);
+ if (duration == (uint32_t)-1)
+ duration = asx_get_time_value (asx_ref);
}
- else if (!strcasecmp (asx_entry->name, "BASE"))
+ else if (!strcasecmp (asx_ref->name, "BASE"))
/* Attributes: HREF */
- base_href = xml_parser_get_property (asx_entry, "HREF");
+ ref_base_href = xml_parser_get_property (asx_entry, "HREF");
}
+
+ /* FIXME: prepend ref_base_href to href */
+ if (href && *href)
+ _x_demux_send_mrl_reference (this->stream, 0, href, title,
+ start_time == (uint32_t)-1 ? 0 : start_time,
+ duration == (uint32_t)-1 ? -1 : duration);
}
- else
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _("demux_asf: Wrong ASX version: %s\n"), version);
-
+
+ else if (!strcasecmp (asx_entry->name, "ENTRYREF"))
+ {
+ /* Attributes: HREF, CLIENTBIND */
+ const char *href = xml_parser_get_property (asx_entry, "HREF");
+ if (href && *href)
+ _x_demux_send_mrl_reference (this->stream, 0, href, NULL, 0, -1);
+ }
+
+ else if (!strcasecmp (asx_entry->name, "BASE"))
+ /* Attributes: HREF */
+ base_href = xml_parser_get_property (asx_entry, "HREF");
}
- else
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "demux_asf: Unable to find VERSION tag from ASX.\n");
}
else
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index 52d6c7690..19f5c2d19 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -369,8 +369,8 @@ static void demux_ts_build_crc32_table(demux_ts_t*this) {
}
static uint32_t demux_ts_compute_crc32(demux_ts_t*this, uint8_t *data,
- uint32_t length, uint32_t crc32) {
- uint32_t i;
+ int32_t length, uint32_t crc32) {
+ int32_t i;
for(i = 0; i < length; i++) {
crc32 = (crc32 << 8) ^ this->crc32_table[(crc32 >> 24) ^ data[i]];
@@ -521,7 +521,7 @@ static void demux_ts_parse_pat (demux_ts_t*this, unsigned char *original_pkt,
unsigned char *pkt, unsigned int pusi) {
uint32_t table_id;
uint32_t section_syntax_indicator;
- uint32_t section_length;
+ int32_t section_length;
uint32_t transport_stream_id;
uint32_t version_number;
uint32_t current_next_indicator;
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
index 1715c5a2f..17c855062 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -3198,26 +3198,38 @@ static char **dvb_class_get_autoplay_list(input_class_t * this_gen,
dvb_input_class_t *class = (dvb_input_class_t *) this_gen;
channel_t *channels=NULL;
char foobuffer[BUFSIZE];
- int ch, apch, num_channels;
+ int ch, apch, num_channels = 0;
int default_channel = -1;
xine_cfg_entry_t lastchannel_enable = {0};
xine_cfg_entry_t lastchannel;
- num_channels = 0;
+ /* need to probe card here to get fe_type to read in channels.conf */
+ tuner_t *tuner;
+ xine_cfg_entry_t adapter;
- if (!(channels = load_channels(class->xine, NULL, &num_channels, 0))) {
- static char *placefile = NULL;
+ xine_config_lookup_entry(class->xine, "media.dvb.adapter", &adapter);
+
+ if (!(tuner = tuner_init(class->xine,adapter.num_value))) {
+ xprintf(class->xine, XINE_VERBOSITY_LOG, _("input_dvb: cannot open dvb device\n"));
+ class->mrls[0]="Sorry, No DVB input device found.";
+ *num_files=1;
+ return class->mrls;
+ }
+
+ if (!(channels = load_channels(class->xine, NULL, &num_channels, tuner->feinfo.type))) {
/* channels.conf not found in .xine */
- class->mrls[0]="Sorry, no channels.conf found.";
- class->mrls[1]="Please run the scan utility from the DVB";
- class->mrls[2]="drivers apps package and place the file in";
- if (!placefile)
- asprintf (&placefile, "%s/"PACKAGE"/", xdgConfigHome(class->xine->basedir_handle));
- class->mrls[3]=placefile;
- *num_files=4;
+ class->mrls[0]="Sorry, No valid channels.conf found";
+ class->mrls[1]="for the selected DVB device.";
+ class->mrls[2]="Please run the dvbscan utility";
+ class->mrls[3]="from the dvb drivers apps package";
+ class->mrls[4]="and place the file in ~/.xine/";
+ *num_files=5;
+ tuner_dispose(tuner);
return class->mrls;
}
+ tuner_dispose(tuner);
+
if (xine_config_lookup_entry(class->xine, "media.dvb.remember_channel", &lastchannel_enable)
&& lastchannel_enable.num_value
&& xine_config_lookup_entry(class->xine, "media.dvb.last_channel", &lastchannel))