summaryrefslogtreecommitdiff
path: root/src/input
diff options
context:
space:
mode:
Diffstat (limited to 'src/input')
-rw-r--r--src/input/Makefile.am6
-rw-r--r--src/input/base64.c6
-rw-r--r--src/input/base64.h6
-rw-r--r--src/input/dvb/Makefile.am2
-rw-r--r--src/input/dvb/dmx.h6
-rw-r--r--src/input/http_helper.c41
-rw-r--r--src/input/http_helper.h13
-rw-r--r--src/input/input_cdda.c897
-rw-r--r--src/input/input_dvb.c680
-rw-r--r--src/input/input_dvd.c323
-rw-r--r--src/input/input_file.c222
-rw-r--r--src/input/input_gnome_vfs.c17
-rw-r--r--src/input/input_http.c317
-rw-r--r--src/input/input_mms.c87
-rw-r--r--src/input/input_net.c110
-rw-r--r--src/input/input_plugin.h150
-rw-r--r--src/input/input_pnm.c64
-rw-r--r--src/input/input_pvr.c483
-rw-r--r--src/input/input_rtp.c146
-rw-r--r--src/input/input_rtsp.c69
-rw-r--r--src/input/input_smb.c137
-rw-r--r--src/input/input_stdin_fifo.c47
-rw-r--r--src/input/input_v4l.c892
-rw-r--r--src/input/input_vcd.c297
-rw-r--r--src/input/libdvdnav/Makefile.am2
-rw-r--r--src/input/libdvdnav/bswap.h2
-rw-r--r--src/input/libdvdnav/diff_against_cvs.patch2
-rw-r--r--src/input/libdvdnav/dvd_reader.c26
-rw-r--r--src/input/libdvdnav/dvd_reader.h4
-rw-r--r--src/input/libdvdnav/ifo_read.c6
-rw-r--r--src/input/libdvdnav/md5.c2
-rw-r--r--src/input/libdvdnav/remap.c1
-rw-r--r--src/input/libreal/asmrp.c44
-rw-r--r--src/input/libreal/real.c121
-rw-r--r--src/input/libreal/real.h2
-rw-r--r--src/input/libreal/rmff.c208
-rw-r--r--src/input/libreal/rmff.h24
-rw-r--r--src/input/libreal/sdpplin.c74
-rw-r--r--src/input/libreal/sdpplin.h10
-rw-r--r--src/input/librtsp/rtsp.c148
-rw-r--r--src/input/librtsp/rtsp.h4
-rw-r--r--src/input/librtsp/rtsp_session.c48
-rw-r--r--src/input/librtsp/rtsp_session.h2
-rw-r--r--src/input/media_helper.c24
-rw-r--r--src/input/mms.c148
-rw-r--r--src/input/mms.h8
-rw-r--r--src/input/mmsh.c98
-rw-r--r--src/input/mmsh.h8
-rw-r--r--src/input/net_buf_ctrl.c34
-rw-r--r--src/input/net_buf_ctrl.h16
-rw-r--r--src/input/pnm.c147
-rw-r--r--src/input/pnm.h2
-rw-r--r--src/input/sha1.c14
-rw-r--r--src/input/sha1.h2
-rw-r--r--src/input/vcd/Makefile.am1
-rw-r--r--src/input/vcd/libcdio/FreeBSD/freebsd.c2
-rw-r--r--src/input/vcd/libcdio/MSWindows/aspi32.c4
-rw-r--r--src/input/vcd/libcdio/cdio/Makefile.am2
-rw-r--r--src/input/vcd/libvcd/Makefile.am2
-rw-r--r--src/input/vcd/xine-extra.c44
-rw-r--r--src/input/vcd/xine-extra.h30
-rw-r--r--src/input/vcd/xineplug_inp_vcd.c610
-rw-r--r--src/input/videodev2.h136
63 files changed, 3704 insertions, 3376 deletions
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
index 81dd62eca..0748c8f29 100644
--- a/src/input/Makefile.am
+++ b/src/input/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
EXTRA_DIST = input_dvd.c input_vcd.c input_gnome_vfs.c input_rtp.c
@@ -45,7 +46,10 @@ endif
if WIN32
else
in_rtp = xineplug_inp_rtp.la
-in_dvb = xineplug_inp_dvb.la
+endif
+
+if DVB
+in_dvb = xineplug_inp_dvb.la
endif
AM_CFLAGS = -D_LARGEFILE64_SOURCE $(GNOME_VFS_CFLAGS) $(ALSA_CFLAGS) $(DVD_CFLAGS)
diff --git a/src/input/base64.c b/src/input/base64.c
index ffb039802..17fa6f48a 100644
--- a/src/input/base64.c
+++ b/src/input/base64.c
@@ -25,17 +25,17 @@
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2000 Robert Kaye
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
-
+
This library 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
Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
diff --git a/src/input/base64.h b/src/input/base64.h
index 5cc94d7f0..107704a6a 100644
--- a/src/input/base64.h
+++ b/src/input/base64.h
@@ -25,17 +25,17 @@
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2000 Robert Kaye
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
-
+
This library 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
Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
diff --git a/src/input/dvb/Makefile.am b/src/input/dvb/Makefile.am
index 229ac21bf..84310507c 100644
--- a/src/input/dvb/Makefile.am
+++ b/src/input/dvb/Makefile.am
@@ -2,4 +2,4 @@ include $(top_srcdir)/misc/Makefile.common
noinst_HEADERS = \
dmx.h \
- frontend.h
+ frontend.h
diff --git a/src/input/dvb/dmx.h b/src/input/dvb/dmx.h
index 51d3c48cd..018c7de59 100644
--- a/src/input/dvb/dmx.h
+++ b/src/input/dvb/dmx.h
@@ -1,4 +1,4 @@
-/*
+/*
* dmx.h
*
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
@@ -149,7 +149,7 @@ struct dmx_event
typedef struct dmx_caps {
uint32_t caps;
- int num_decoders;
+ int num_decoders;
} dmx_caps_t;
typedef enum {
@@ -164,7 +164,7 @@ typedef enum {
} dmx_source_t;
-#define DMX_START _IO('o',41)
+#define DMX_START _IO('o',41)
#define DMX_STOP _IO('o',42)
#define DMX_SET_FILTER _IOW('o',43,struct dmx_sct_filter_params)
#define DMX_SET_PES_FILTER _IOW('o',44,struct dmx_pes_filter_params)
diff --git a/src/input/http_helper.c b/src/input/http_helper.c
index 4883763b0..eb28140ff 100644
--- a/src/input/http_helper.c
+++ b/src/input/http_helper.c
@@ -29,8 +29,18 @@
#include "xine_internal.h"
#include "http_helper.h"
+
+const char *_x_url_user_agent (const char *url)
+{
+ if (!strncasecmp (url, "qthttp://", 9))
+ return "QuickTime"; /* needed for Apple trailers */
+ return NULL;
+}
+
int _x_parse_url (char *url, char **proto, char** host, int *port,
- char **user, char **password, char **uri) {
+ char **user, char **password, char **uri,
+ const char **user_agent)
+{
char *start = NULL;
char *authcolon = NULL;
char *at = NULL;
@@ -55,14 +65,17 @@ int _x_parse_url (char *url, char **proto, char** host, int *port,
*password = NULL;
*uri = NULL;
- /* proto */
+ /* proto */
start = strstr(url, "://");
if (!start || (start == url))
goto error;
-
+
end = start + strlen(start) - 1;
*proto = strndup(url, start - url);
+ if (user_agent)
+ *user_agent = _x_url_user_agent (url);
+
/* user:password */
start += 3;
at = strchr(start, '@');
@@ -72,10 +85,10 @@ int _x_parse_url (char *url, char **proto, char** host, int *port,
semicolon = strchr(start, ';');
if (semicolon && (!slash || (semicolon < slash)))
slash = semicolon;
-
+
if (at && slash && (at > slash))
at = NULL;
-
+
if (at) {
authcolon = strchr(start, ':');
if(authcolon && authcolon < at) {
@@ -166,7 +179,7 @@ int _x_parse_url (char *url, char **proto, char** host, int *port,
escapechars++;
it++;
}
-
+
if ( escapechars == 0 )
*uri = strdup(start);
else {
@@ -185,14 +198,15 @@ int _x_parse_url (char *url, char **proto, char** host, int *port,
} else
*it = start[i];
}
+ *it = '\0';
}
}
} else {
*uri = strdup("/");
}
-
+
return 1;
-
+
error:
if (*proto) {
free (*proto);
@@ -217,7 +231,7 @@ error:
free (*uri);
*uri = NULL;
}
- return 0;
+ return 0;
}
char *_x_canonicalise_url (const char *base, const char *url) {
@@ -240,8 +254,7 @@ char *_x_canonicalise_url (const char *base, const char *url) {
++cut;
}
base_length = cut ? (size_t)(cut - base) : strlen (base);
- ret = malloc (base_length + strlen (url) + 1);
- sprintf (ret, "%.*s%s", (int)base_length, base, url);
+ asprintf (&ret, "%.*s%s", (int)base_length, base, url);
return ret;
}
@@ -254,11 +267,11 @@ static int check_url(char *url, int ok) {
char *proto, *host, *user, *password, *uri;
int port;
int res;
-
+
printf("--------------------------------\n");
printf("url=%s\n", url);
res = _x_parse_url (url,
- &proto, &host, &port, &user, &password, &uri);
+ &proto, &host, &port, &user, &password, &uri, NULL);
if (res) {
printf("proto=%s, host=%s, port=%d, user=%s, password=%s, uri=%s\n",
proto, host, port, user, password, uri);
@@ -297,7 +310,7 @@ static int check_paste(const char *base, const char *url, const char *ok) {
int main(int argc, char** argv) {
char *proto, host, port, user, password, uri;
int res = 0;
-
+
res += check_url("http://www.toto.com/test1.asx", 1);
res += check_url("http://www.toto.com:8080/test2.asx", 1);
res += check_url("http://titi:pass@www.toto.com:8080/test3.asx", 1);
diff --git a/src/input/http_helper.h b/src/input/http_helper.h
index 3ce3f2b7c..68299a2ea 100644
--- a/src/input/http_helper.h
+++ b/src/input/http_helper.h
@@ -24,6 +24,16 @@
#define HTTP_HELPER_H
/*
+ * user agent finder, using modified protcol names
+ * {proto}://...
+ * e.g. "qthttp://example.com/foo.mov" → "QuickTime"
+ *
+ * return:
+ * NULL or user agent prefix
+ */
+const char *_x_url_user_agent (const char *url);
+
+/*
* url parser
* {proto}://{user}:{password}@{host}:{port}{uri}
* {proto}://{user}:{password}@{[host]}:{port}{uri}
@@ -33,7 +43,8 @@
* 1 valid url
*/
int _x_parse_url (char *url, char **proto, char** host, int *port,
- char **user, char **password, char **uri);
+ char **user, char **password, char **uri,
+ const char **user_agent);
/*
* canonicalise url, given base
diff --git a/src/input/input_cdda.c b/src/input/input_cdda.c
index fd4dd1fa9..1751f031c 100644
--- a/src/input/input_cdda.c
+++ b/src/input/input_cdda.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2005 the xine project
+ * Copyright (C) 2000-2008 the xine project
*
* This file is part of xine, a free video player.
*
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
- * Compact Disc Digital Audio (CDDA) Input Plugin
+ * Compact Disc Digital Audio (CDDA) Input Plugin
* by Mike Melanson (melanson@pcisys.net)
*/
@@ -44,6 +44,7 @@
# include <sys/ioctl.h>
#else
/* for WIN32 */
+# include <windef.h>
# include <winioctl.h>
#endif
@@ -70,6 +71,8 @@
#define DEFAULT_CDDA_DEVICE "/vol/dev/aliases/cdrom0"
#elif defined(WIN32)
#define DEFAULT_CDDA_DEVICE "d:\\"
+#elif defined(__OpenBSD__)
+#define DEFAULT_CDDA_DEVICE "/dev/rcd0c"
#else
#define DEFAULT_CDDA_DEVICE "/dev/cdrom"
#endif
@@ -110,7 +113,7 @@ typedef struct _cdrom_toc {
*************************************************************************/
#define MAX_TRACKS 99
-#define CACHED_FRAMES 500
+#define CACHED_FRAMES 100
typedef struct {
int start;
@@ -126,8 +129,8 @@ typedef struct {
int enabled;
char *server;
int port;
- char *cache_dir;
-
+ char *cache_dir;
+
char *cdiscid;
char *disc_title;
char *disc_year;
@@ -135,7 +138,7 @@ typedef struct {
char *disc_category;
int fd;
- unsigned long disc_id;
+ uint32_t disc_id;
int disc_length;
trackinfo_t *track;
@@ -175,7 +178,7 @@ typedef struct {
char *cdda_device;
int cddb_error;
-
+
cdda_input_plugin_t *ip;
int show_hidden_files;
@@ -183,7 +186,7 @@ typedef struct {
int mrls_allocated_entries;
xine_mrl_t **mrls;
-
+
char *autoplaylist[MAX_TRACKS];
} cdda_input_class_t;
@@ -315,54 +318,54 @@ struct SRB_ExecSCSICmd
#ifdef LOG
static void print_cdrom_toc(cdrom_toc *toc) {
-
+
int i;
int time1;
int time2;
int timediff;
-
+
printf("\ntoc:\n");
printf("\tfirst track = %d\n", toc->first_track);
printf("\tlast track = %d\n", toc->last_track);
printf("\ttotal tracks = %d\n", toc->total_tracks);
printf("\ntoc entries:\n");
-
-
+
+
printf("leadout track: Control: %d MSF: %02d:%02d:%04d, first frame = %d\n",
toc->leadout_track.track_mode,
toc->leadout_track.first_frame_minute,
toc->leadout_track.first_frame_second,
toc->leadout_track.first_frame_frame,
toc->leadout_track.first_frame);
-
+
/* fetch each toc entry */
- if (toc->first_track > 0) {
- for (i = toc->first_track; i <= toc->last_track; i++) {
+ if (toc->first_track > 0) {
+ for (i = toc->first_track; i <= toc->last_track; i++) {
printf("\ttrack mode = %d", toc->toc_entries[i-1].track_mode);
- printf("\ttrack %d, audio, MSF: %02d:%02d:%02d, first frame = %d\n",
- i,
+ printf("\ttrack %d, audio, MSF: %02d:%02d:%02d, first frame = %d\n",
+ i,
toc->toc_entries[i-1].first_frame_minute,
toc->toc_entries[i-1].first_frame_second,
toc->toc_entries[i-1].first_frame_frame,
toc->toc_entries[i-1].first_frame);
-
- time1 = ((toc->toc_entries[i-1].first_frame_minute * 60) +
+
+ time1 = ((toc->toc_entries[i-1].first_frame_minute * 60) +
toc->toc_entries[i-1].first_frame_second);
-
+
if (i == toc->last_track) {
time2 = ((toc->leadout_track.first_frame_minute * 60) +
toc->leadout_track.first_frame_second);
}
else {
- time2 = ((toc->toc_entries[i].first_frame_minute * 60) +
+ time2 = ((toc->toc_entries[i].first_frame_minute * 60) +
toc->toc_entries[i].first_frame_second);
}
-
+
timediff = time2 - time1;
-
+
printf("\t time: %02d:%02d\n", timediff/60, timediff%60);
}
- }
+ }
}
#endif
@@ -370,7 +373,7 @@ static cdrom_toc * init_cdrom_toc(void) {
cdrom_toc *toc;
- toc = (cdrom_toc *) xine_xmalloc(sizeof (cdrom_toc));
+ toc = calloc(1, sizeof (cdrom_toc));
toc->first_track = toc->last_track = toc->total_tracks = 0;
toc->toc_entries = NULL;
@@ -416,12 +419,11 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
toc->ignore_last_track = 0;
}
toc->total_tracks = toc->last_track - toc->first_track + 1;
-
+
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -529,10 +531,9 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
toc->total_tracks = toc->last_track - toc->first_track + 1;
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -612,7 +613,7 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f
return 0;
}
-#elif defined(__FreeBSD_kernel__) || defined(__NetBSD__)
+#elif defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/cdio.h>
@@ -625,7 +626,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
struct ioc_toc_header tochdr;
#if defined(__FreeBSD_kernel__)
struct ioc_read_toc_single_entry tocentry;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
struct ioc_read_toc_entry tocentry;
struct cd_toc_entry data;
#endif
@@ -642,10 +643,9 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
toc->total_tracks = toc->last_track - toc->first_track + 1;
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -661,7 +661,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
perror("CDIOREADTOCENTRY");
return -1;
}
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
memset(&data, 0, sizeof(data));
tocentry.data_len = sizeof(data);
tocentry.data = &data;
@@ -682,7 +682,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
(tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
(tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) +
tocentry.entry.addr.msf.frame;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
toc->toc_entries[i-1].track_mode = (tocentry.data->control & 0x04) ? 1 : 0;
toc->toc_entries[i-1].first_frame_minute = tocentry.data->addr.msf.minute;
toc->toc_entries[i-1].first_frame_second = tocentry.data->addr.msf.second;
@@ -704,7 +704,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
perror("CDIOREADTOCENTRY");
return -1;
}
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
memset(&data, 0, sizeof(data));
tocentry.data_len = sizeof(data);
tocentry.data = &data;
@@ -725,7 +725,7 @@ static int read_cdrom_toc(int fd, cdrom_toc *toc) {
(tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
(tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) +
tocentry.entry.addr.msf.frame;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
toc->leadout_track.track_mode = (tocentry.data->control & 0x04) ? 1 : 0;
toc->leadout_track.first_frame_minute = tocentry.data->addr.msf.minute;
toc->leadout_track.first_frame_second = tocentry.data->addr.msf.second;
@@ -763,7 +763,7 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f
perror("CDIOCREADAUDIO");
return -1;
}
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
scsireq_t req;
int nblocks = 1;
@@ -790,7 +790,7 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f
return -1;
}
#endif
-
+
data += CD_RAW_FRAME_SIZE;
frame++;
num_frames--;
@@ -807,45 +807,44 @@ static int read_cdrom_toc(cdda_input_plugin_t *this_gen, cdrom_toc *toc) {
/* This is for ASPI which obviously isn't supported! */
lprintf("Windows ASPI support is not complete yet!\n");
return -1;
-
+
}
else
{
DWORD dwBytesReturned;
CDROM_TOC cdrom_toc;
int i;
-
+
if( DeviceIoControl( this_gen->h_device_handle,
IOCTL_CDROM_READ_TOC,
NULL, 0, &cdrom_toc, sizeof(CDROM_TOC),
&dwBytesReturned, NULL ) == 0 )
{
#ifdef LOG
- DWORD dw;
+ DWORD dw;
printf( "input_cdda: could not read TOCHDR\n" );
dw = GetLastError();
- printf("GetLastError returned %u\n", dw);
+ printf("GetLastError returned %u\n", dw);
#endif
return -1;
}
-
+
toc->first_track = cdrom_toc.FirstTrack;
toc->last_track = cdrom_toc.LastTrack;
toc->total_tracks = toc->last_track - toc->first_track + 1;
-
+
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
-
+
/* fetch each toc entry */
for (i = toc->first_track; i <= toc->last_track; i++) {
-
+
toc->toc_entries[i-1].track_mode = (cdrom_toc.TrackData[i-1].Control & 0x04) ? 1 : 0;
toc->toc_entries[i-1].first_frame_minute = cdrom_toc.TrackData[i-1].Address[1];
toc->toc_entries[i-1].first_frame_second = cdrom_toc.TrackData[i-1].Address[2];
@@ -867,7 +866,7 @@ static int read_cdrom_toc(cdda_input_plugin_t *this_gen, cdrom_toc *toc) {
(toc->leadout_track.first_frame_minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) +
(toc->leadout_track.first_frame_second * CD_FRAMES_PER_SECOND) +
toc->leadout_track.first_frame_frame;
- }
+ }
return 0;
}
@@ -884,37 +883,37 @@ static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_f
/* This is for ASPI which obviously isn't supported! */
lprintf("Windows ASPI support is not complete yet!\n");
return -1;
-
+
}
else
{
memset(data, 0, CD_RAW_FRAME_SIZE * num_frames);
-
+
while( num_frames ) {
-
+
#ifdef LOG
/*printf("\t Raw read frame %d\n", frame);*/
#endif
raw_read_info.DiskOffset.QuadPart = frame * CD_SECTOR_SIZE;
raw_read_info.SectorCount = 1;
raw_read_info.TrackMode = CDDA;
-
+
/* read a frame */
if( DeviceIoControl( this_gen->h_device_handle,
IOCTL_CDROM_RAW_READ,
- &raw_read_info, sizeof(RAW_READ_INFO), data,
+ &raw_read_info, sizeof(RAW_READ_INFO), data,
CD_RAW_FRAME_SIZE,
&dwBytesReturned, NULL ) == 0 )
{
#ifdef LOG
- DWORD dw;
+ DWORD dw;
printf( "input_cdda: could not read frame\n" );
dw = GetLastError();
- printf("GetLastError returned %u\n", dw);
+ printf("GetLastError returned %u\n", dw);
#endif
return -1;
}
-
+
data += CD_RAW_FRAME_SIZE;
frame++;
num_frames--;
@@ -1020,7 +1019,7 @@ network_command( xine_stream_t *stream, int socket, char *data_buf, char *msg, .
if( n ) {
if( !data_buf ) {
if (stream)
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
"input_cdda: protocol error, data returned but no buffer provided.\n");
return -1;
}
@@ -1036,13 +1035,13 @@ network_command( xine_stream_t *stream, int socket, char *data_buf, char *msg, .
#ifndef WIN32
-static int network_connect(xine_stream_t *stream, char *url )
+static int network_connect(xine_stream_t *stream, const char *got_url )
{
- char *host;
+ char *host, *url;
int port;
int fd;
- url = strdup(url);
+ url = strdup(got_url);
parse_url(url, &host, &port);
if( !host || !strlen(host) || !port )
@@ -1081,10 +1080,9 @@ static int network_read_cdrom_toc(xine_stream_t *stream, int fd, cdrom_toc *toc)
toc->total_tracks = toc->last_track - toc->first_track + 1;
/* allocate space for the toc entries */
- toc->toc_entries =
- (cdrom_toc_entry *)malloc(toc->total_tracks * sizeof(cdrom_toc_entry));
+ toc->toc_entries = calloc(toc->total_tracks, sizeof(cdrom_toc_entry));
if (!toc->toc_entries) {
- perror("malloc");
+ perror("calloc");
return -1;
}
@@ -1146,12 +1144,12 @@ static int network_read_cdrom_frames(xine_stream_t *stream, int fd, int first_fr
*/
static void cdda_device_cb(void *data, xine_cfg_entry_t *cfg) {
cdda_input_class_t *class = (cdda_input_class_t *) data;
-
+
class->cdda_device = cfg->str_value;
}
static void enable_cddb_changed_cb(void *data, xine_cfg_entry_t *cfg) {
cdda_input_class_t *class = (cdda_input_class_t *) data;
-
+
if(class->ip) {
cdda_input_plugin_t *this = class->ip;
@@ -1162,7 +1160,7 @@ static void enable_cddb_changed_cb(void *data, xine_cfg_entry_t *cfg) {
}
static void server_changed_cb(void *data, xine_cfg_entry_t *cfg) {
cdda_input_class_t *class = (cdda_input_class_t *) data;
-
+
if(class->ip) {
cdda_input_plugin_t *this = class->ip;
@@ -1173,7 +1171,7 @@ static void server_changed_cb(void *data, xine_cfg_entry_t *cfg) {
}
static void port_changed_cb(void *data, xine_cfg_entry_t *cfg) {
cdda_input_class_t *class = (cdda_input_class_t *) data;
-
+
if(class->ip) {
cdda_input_plugin_t *this = class->ip;
@@ -1184,7 +1182,7 @@ static void port_changed_cb(void *data, xine_cfg_entry_t *cfg) {
}
static void cachedir_changed_cb(void *data, xine_cfg_entry_t *cfg) {
cdda_input_class_t *class = (cdda_input_class_t *) data;
-
+
if(class->ip) {
cdda_input_plugin_t *this = class->ip;
@@ -1194,7 +1192,7 @@ static void cachedir_changed_cb(void *data, xine_cfg_entry_t *cfg) {
#ifdef CDROM_SELECT_SPEED
static void speed_changed_cb(void *data, xine_cfg_entry_t *cfg) {
cdda_input_class_t *class = (cdda_input_class_t *) data;
-
+
if (class->ip) {
cdda_input_plugin_t *this = class->ip;
if (this->fd != -1)
@@ -1211,21 +1209,21 @@ static void speed_changed_cb(void *data, xine_cfg_entry_t *cfg) {
static int _cdda_is_cd_changed(cdda_input_plugin_t *this) {
#ifdef CDROM_MEDIA_CHANGED
int err, cd_changed=0;
-
+
if(this == NULL || this->fd < 0)
return -1;
-
+
if((err = ioctl(this->fd, CDROM_MEDIA_CHANGED, cd_changed)) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_cdda: ioctl(CDROM_MEDIA_CHANGED) failed: %s.\n", strerror(errno));
return -1;
}
-
+
switch(err) {
case 1:
return 1;
break;
-
+
default:
return 0;
break;
@@ -1235,7 +1233,7 @@ static int _cdda_is_cd_changed(cdda_input_plugin_t *this) {
#else
/*
* At least on solaris, CDROM_MEDIA_CHANGED does not exist. Just return an
- * error for now
+ * error for now
*/
return -1;
#endif
@@ -1245,18 +1243,18 @@ static int _cdda_is_cd_changed(cdda_input_plugin_t *this) {
* create a directory, in safe mode
*/
static void _cdda_mkdir_safe(xine_t *xine, char *path) {
-
+
if(path == NULL)
return;
-
+
#ifndef WIN32
{
struct stat pstat;
-
+
if((stat(path, &pstat)) < 0) {
/* file or directory no exist, create it */
if(mkdir(path, 0755) < 0) {
- xprintf(xine, XINE_VERBOSITY_DEBUG,
+ xprintf(xine, XINE_VERBOSITY_DEBUG,
"input_cdda: mkdir(%s) failed: %s.\n", path, strerror(errno));
return;
}
@@ -1273,10 +1271,10 @@ static void _cdda_mkdir_safe(xine_t *xine, char *path) {
HANDLE hList;
TCHAR szDir[MAX_PATH+3];
WIN32_FIND_DATA FileData;
-
+
// Get the proper directory path
sprintf(szDir, "%s\\*", path);
-
+
// Get the first file
hList = FindFirstFile(szDir, &FileData);
if (hList == INVALID_HANDLE_VALUE)
@@ -1284,9 +1282,9 @@ static void _cdda_mkdir_safe(xine_t *xine, char *path) {
if(_mkdir(path) != 0) {
xprintf(xine, XINE_VERBOSITY_DEBUG, "input_cdda: mkdir(%s) failed.\n", path);
return;
- }
+ }
}
-
+
FindClose(hList);
}
#endif /* WIN32 */
@@ -1312,18 +1310,15 @@ static void _cdda_mkdir_recursive_safe(xine_t *xine, char *path) {
if(p && strlen(p)) {
#ifdef WIN32
- if (*buf2 != '\0') {
+ if (*buf2 != '\0') {
#endif
-
- int size = strlen(buf2);
- snprintf(buf2 + size, sizeof(buf2) - size, "/%s", p);
-
+ size_t size = strlen(buf2);
+ snprintf(buf2 + size, sizeof(buf2) - size, "/%s", p);
#ifdef WIN32
- }
- else {
- snprintf(buf2, sizeof(buf2), "%s", p);
- }
-
+ }
+ else {
+ snprintf(buf2, sizeof(buf2), "%s", p);
+ }
#endif /* WIN32 */
_cdda_mkdir_safe(xine, buf2);
@@ -1336,10 +1331,10 @@ static void _cdda_mkdir_recursive_safe(xine_t *xine, char *path) {
*/
static char *_cdda_cddb_get_default_location(void) {
static char buf[XINE_PATH_MAX + XINE_NAME_MAX + 1];
-
+
memset(&buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "%s/.xine/cddbcache", (xine_get_homedir()));
-
+
return buf;
}
@@ -1359,12 +1354,12 @@ static int _cdda_cddb_socket_read(cdda_input_plugin_t *this, char *str, int size
* Send a command to socket
*/
static int _cdda_cddb_send_command(cdda_input_plugin_t *this, char *cmd) {
-
+
if((this == NULL) || (this->cddb.fd < 0) || (cmd == NULL))
return -1;
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, ">>> %s\n", cmd);
-
+
return (int)_x_io_tcp_write(this->stream, this->cddb.fd, cmd, strlen(cmd));
}
@@ -1434,37 +1429,102 @@ static int _cdda_cddb_handle_code(char *buf) {
break;
}
}
-
+
return err;
}
+static inline char *_cdda_append (/*const*/ char *first, const char *second)
+{
+ if (!first)
+ return strdup (second);
+
+ char *result = (char *) realloc (first, strlen (first) + strlen (second) + 1);
+ strcat (result, second);
+ return result;
+}
+
+static void _cdda_parse_cddb_info (cdda_input_plugin_t *this, char *buffer, char **dtitle)
+{
+ /* buffer should be no more than 2048 bytes... */
+ char buf[2048];
+ int track_no;
+
+ if (sscanf (buffer, "DTITLE=%s", &buf[0]) == 1) {
+ char *pt = strchr (buffer, '=');
+ if (pt) {
+ ++pt;
+
+ *dtitle = _cdda_append (*dtitle, pt);
+ pt = strdup (*dtitle);
+
+ char *title = strstr (pt, " / ");
+ if (title)
+ {
+ *title = 0;
+ title += 3;
+ free (this->cddb.disc_artist);
+ this->cddb.disc_artist = strdup (pt);
+ }
+ else
+ title = pt;
+
+ free (this->cddb.disc_title);
+ this->cddb.disc_title = strdup (title);
+
+ free (pt);
+ }
+ }
+ else if (sscanf (buffer, "DYEAR=%s", &buf[0]) == 1) {
+ char *pt = strchr (buffer, '=');
+ if (pt && strlen (pt) == 5)
+ this->cddb.disc_year = strdup (pt + 1);
+ }
+ else if(sscanf(buffer, "DGENRE=%s", &buf[0]) == 1) {
+ char *pt = strchr(buffer, '=');
+ if (pt)
+ this->cddb.disc_category = strdup (pt + 1);
+ }
+ else if (sscanf (buffer, "TTITLE%d=%s", &track_no, &buf[0]) == 2) {
+ char *pt = strchr(buffer, '=');
+ this->cddb.track[track_no].title = _cdda_append (this->cddb.track[track_no].title, pt + 1);
+ }
+ else if (!strncmp (buffer, "EXTD=", 5))
+ {
+ if (!this->cddb.disc_year)
+ {
+ int nyear;
+ char *y = strstr (buffer, "YEAR:");
+ if (y && sscanf (y + 5, "%4d", &nyear) == 1)
+ asprintf (&this->cddb.disc_year, "%d", nyear);
+ }
+ }
+}
+
/*
* Try to load cached cddb infos
*/
static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
char cdir[XINE_PATH_MAX + XINE_NAME_MAX + 1];
+ size_t cdir_size = 0;
DIR *dir;
if(this == NULL)
return 0;
-
- memset(&cdir, 0, sizeof(cdir));
- snprintf(cdir, sizeof(cdir), "%s", this->cddb.cache_dir);
-
+
+ cdir_size = snprintf(cdir, sizeof(cdir), "%s", this->cddb.cache_dir);
+
if((dir = opendir(cdir)) != NULL) {
struct dirent *pdir;
-
+
while((pdir = readdir(dir)) != NULL) {
char discid[9];
-
- memset(&discid, 0, sizeof(discid));
- snprintf(discid, sizeof(discid), "%08lx", this->cddb.disc_id);
-
+
+ snprintf(discid, sizeof(discid), "%08" PRIx32, this->cddb.disc_id);
+
if(!strcasecmp(pdir->d_name, discid)) {
FILE *fd;
- int size = strlen(cdir);
-
- snprintf(cdir + size, sizeof(cdir) - size, "/%s", discid);
+
+ cdir_size += snprintf(cdir + cdir_size, sizeof(cdir) - cdir_size, "/%s", discid);
if((fd = fopen(cdir, "r")) == NULL) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_cdda: fopen(%s) failed: %s.\n", cdir, strerror(errno));
@@ -1472,101 +1532,30 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
return 0;
}
else {
- char buffer[256], *ln;
- char buf[256];
- int tnum;
+ char buffer[2048], *ln;
char *dtitle = NULL;
-
- while ((ln = fgets(buffer, 255, fd)) != NULL) {
-
- buffer[strlen(buffer) - 1] = '\0';
-
- if (sscanf(buffer, "DTITLE=%s", &buf[0]) == 1) {
- char *pt, *artist, *title;
-
- pt = strrchr(buffer, '=');
- if (pt) {
- pt++;
-
- if (dtitle != NULL)
- {
- dtitle = (char *) realloc(dtitle, strlen(dtitle) + strlen(pt) + 1);
- strcat(dtitle, pt);
- pt = dtitle;
- }
- dtitle = strdup(pt);
-
- artist = pt;
- title = strstr(pt, " / ");
- if (title) {
- *title++ = '\0';
- title += 2;
- }
- else {
- title = artist;
- artist = NULL;
- }
-
- if (artist)
- this->cddb.disc_artist = strdup(artist);
-
- this->cddb.disc_title = strdup(title);
- }
- }
- else if (sscanf(buffer, "DYEAR=%s", &buf[0]) == 1) {
- char *pt;
- pt = strrchr(buffer, '=');
- pt++;
- if (pt != NULL && strlen(pt) == 4)
- this->cddb.disc_year = strdup(pt);
- }
- else if (sscanf(buffer, "TTITLE%d=%s", &tnum, &buf[0]) == 2) {
- char *pt;
-
- pt = strrchr(buffer, '=');
- if (pt)
- pt++;
- if (this->cddb.track[tnum].title == NULL)
- this->cddb.track[tnum].title = strdup(pt);
- else
- {
- this->cddb.track[tnum].title
- = (char *) realloc(this->cddb.track[tnum].title, strlen(this->cddb.track[tnum].title) + strlen(pt) + 1);
- strcat(this->cddb.track[tnum].title, pt);
- }
- }
- else {
- if (!strncmp(buffer, "EXTD=", 5)) {
- char *y;
- int nyear;
-
- y = strstr(buffer, "YEAR:");
- if(y) {
- if (sscanf(y+5, "%4d", &nyear) == 1) {
- char year[5];
-
- snprintf(year, 5, "%d", nyear);
- if (this->cddb.disc_year == NULL)
- this->cddb.disc_year = strdup(year);
- }
- }
- }
- }
+ while ((ln = fgets(buffer, sizeof (buffer) - 1, fd)) != NULL) {
+
+ int length = strlen (buffer);
+ if (length && buffer[length - 1] == '\n')
+ buffer[length - 1] = '\0';
+
+ _cdda_parse_cddb_info (this, buffer, &dtitle);
}
fclose(fd);
free(dtitle);
}
-
+
closedir(dir);
return 1;
}
}
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "input_cdda: cached entry for disc ID %08lx not found.\n", this->cddb.disc_id);
+ "input_cdda: cached entry for disc ID %08" PRIx32 " not found.\n", this->cddb.disc_id);
closedir(dir);
}
-
+
return 0;
}
@@ -1576,19 +1565,19 @@ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) {
static void _cdda_save_cached_cddb_infos(cdda_input_plugin_t *this, char *filecontent) {
char cfile[XINE_PATH_MAX + XINE_NAME_MAX + 1];
FILE *fd;
-
+
if((this == NULL) || (filecontent == NULL))
return;
-
+
memset(&cfile, 0, sizeof(cfile));
/* Ensure "~/.xine/cddbcache" exist */
snprintf(cfile, sizeof(cfile), "%s", this->cddb.cache_dir);
-
+
_cdda_mkdir_recursive_safe(this->stream->xine, cfile);
-
- snprintf(cfile, sizeof(cfile), "%s/%08lx", this->cddb.cache_dir, this->cddb.disc_id);
-
+
+ snprintf(cfile, sizeof(cfile), "%s/%08" PRIx32 , this->cddb.cache_dir, this->cddb.disc_id);
+
if((fd = fopen(cfile, "w")) == NULL) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_cdda: fopen(%s) failed: %s.\n", cfile, strerror(errno));
@@ -1598,7 +1587,7 @@ static void _cdda_save_cached_cddb_infos(cdda_input_plugin_t *this, char *fileco
fprintf(fd, "%s", filecontent);
fclose(fd);
}
-
+
}
/*
@@ -1626,7 +1615,7 @@ static int _cdda_cddb_socket_open(cdda_input_plugin_t *this) {
* Close the socket
*/
static void _cdda_cddb_socket_close(cdda_input_plugin_t *this) {
-
+
if((this == NULL) || (this->cddb.fd < 0))
return;
@@ -1646,7 +1635,7 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
if(this == NULL) {
return 0;
}
-
+
if(_cdda_load_cached_cddb_infos(this)) {
this->cddb.have_cddb_info = 1;
return 1;
@@ -1726,22 +1715,21 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
/* Send query command */
memset(&buffer, 0, sizeof(buffer));
- sprintf(buffer, "cddb query %08lx %d ", this->cddb.disc_id, this->cddb.num_tracks);
+ size_t size = sprintf(buffer, "cddb query %08" PRIx32 " %d ", this->cddb.disc_id, this->cddb.num_tracks);
for (i = 0; i < this->cddb.num_tracks; i++) {
- int size = strlen(buffer);
- snprintf(buffer + size, sizeof(buffer) - size, "%d ", this->cddb.track[i].start);
+ size += snprintf(buffer + size, sizeof(buffer) - size, "%d ", this->cddb.track[i].start);
}
- snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "%d\n", this->cddb.disc_length);
+ snprintf(buffer + strlen(buffer), sizeof(buffer) - size, "%d\n", this->cddb.disc_length);
if ((err = _cdda_cddb_send_command(this, buffer)) <= 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_cdda: error while sending cddb query command.\n");
_cdda_cddb_socket_close(this);
- return 0;
+ return 0;
}
memset(&buffer, 0, sizeof(buffer));
err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1);
- if (err < 0 || (((err = _cdda_cddb_handle_code(buffer)) != 200) && (err != 210))) {
+ if (err < 0 || (((err = _cdda_cddb_handle_code(buffer)) != 200) && (err != 210) && (err != 211))) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_cdda: cddb query command returned error code '%03d'.\n", err);
_cdda_cddb_socket_close(this);
@@ -1761,8 +1749,8 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
i++;
}
}
-
- if (err == 210) {
+
+ if ((err == 210) || (err == 211)) {
memset(&buffer, 0, sizeof(buffer));
err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1);
if (err < 0) {
@@ -1792,7 +1780,7 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
return 0;
}
}
- }
+ }
/* Send read command */
memset(&buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "cddb read %s %s\n", this->cddb.disc_category, this->cddb.cdiscid);
@@ -1811,95 +1799,21 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
_cdda_cddb_socket_close(this);
return 0;
}
-
+
this->cddb.have_cddb_info = 1;
memset(&buffercache, 0, sizeof(buffercache));
while (strcmp(buffer, ".")) {
- char buf[2048];
- int tnum;
- int bufsize = strlen(buffercache);
+ size_t bufsize = strlen(buffercache);
memset(&buffer, 0, sizeof(buffer));
_cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1);
snprintf(buffercache + bufsize, sizeof(buffercache) - bufsize, "%s\n", buffer);
- if (sscanf(buffer, "DTITLE=%s", &buf[0]) == 1) {
- char *pt, *artist, *title;
-
- pt = strrchr(buffer, '=');
- if (pt) {
- pt++;
-
- if (dtitle != NULL)
- {
- dtitle = (char *) realloc(dtitle, strlen(dtitle) + strlen(pt) + 1);
- strcat(dtitle, pt);
- pt = dtitle;
- }
- dtitle = strdup(pt);
-
- artist = pt;
- title = strstr(pt, " / ");
- if (title) {
- *title++ = '\0';
- title += 2;
- }
- else {
- title = artist;
- artist = NULL;
- }
-
- if (artist) {
- this->cddb.disc_artist = strdup(artist);
- }
- this->cddb.disc_title = strdup(title);
- }
- }
- else if(sscanf(buffer, "DYEAR=%s", &buf[0]) == 1) {
- char *pt;
-
- pt = strrchr(buffer, '=');
- pt++;
- if (pt != NULL && strlen(pt) == 4)
- this->cddb.disc_year = strdup(pt);
- }
- else if (sscanf(buffer, "TTITLE%d=%s", &tnum, &buf[0]) == 2) {
- char *pt;
-
- pt = strrchr(buffer, '=');
- if (pt) {
- pt++;
- if (this->cddb.track[tnum].title == NULL)
- this->cddb.track[tnum].title = strdup(pt);
- else
- {
- this->cddb.track[tnum].title
- = (char *) realloc(this->cddb.track[tnum].title, strlen(this->cddb.track[tnum].title) + strlen(pt) + 1);
- strcat(this->cddb.track[tnum].title, pt);
- }
- }
- }
- else {
- if (!strncmp(buffer, "EXTD=", 5)) {
- char *y;
- int nyear;
-
- y = strstr(buffer, "YEAR:");
- if (y) {
- if (sscanf(y+5, "%4d", &nyear) == 1) {
- char year[5];
-
- snprintf(year, 5, "%d", nyear);
- if (this->cddb.disc_year == NULL)
- this->cddb.disc_year = strdup(year);
- }
- }
- }
- }
+ _cdda_parse_cddb_info (this, buffer, &dtitle);
}
free(dtitle);
-
+
/* Save cddb info and close socket */
_cdda_save_cached_cddb_infos(this, buffercache);
_cdda_cddb_socket_close(this);
@@ -1915,24 +1829,24 @@ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) {
*/
static unsigned int _cdda_cddb_sum(int n) {
unsigned int ret = 0;
-
+
while(n > 0) {
ret += (n % 10);
n /= 10;
}
return ret;
}
-static unsigned long _cdda_calc_cddb_id(cdda_input_plugin_t *this) {
+static uint32_t _cdda_calc_cddb_id(cdda_input_plugin_t *this) {
int i, tsum = 0;
-
+
if(this == NULL || (this->cddb.num_tracks <= 0))
return 0;
-
+
for(i = 0; i < this->cddb.num_tracks; i++)
tsum += _cdda_cddb_sum((this->cddb.track[i].start / CD_FRAMES_PER_SECOND));
-
+
return ((tsum % 0xff) << 24
- | (this->cddb.disc_length - (this->cddb.track[0].start / CD_FRAMES_PER_SECOND)) << 8
+ | (this->cddb.disc_length - (this->cddb.track[0].start / CD_FRAMES_PER_SECOND)) << 8
| this->cddb.num_tracks);
}
@@ -1979,7 +1893,7 @@ static void _cdda_cdindex(cdda_input_plugin_t *this, cdrom_toc *toc) {
/*
* return cbbd disc id.
*/
-static unsigned long _cdda_get_cddb_id(cdda_input_plugin_t *this) {
+static uint32_t _cdda_get_cddb_id(cdda_input_plugin_t *this) {
if(this == NULL || (this->cddb.num_tracks <= 0))
return 0;
@@ -2001,22 +1915,22 @@ static void _cdda_free_cddb_info(cdda_input_plugin_t *this) {
}
free(this->cddb.track);
-
+
if(this->cddb.cdiscid)
free(this->cddb.cdiscid);
-
+
if(this->cddb.disc_title)
free(this->cddb.disc_title);
-
+
if(this->cddb.disc_artist)
free(this->cddb.disc_artist);
if(this->cddb.disc_category)
free(this->cddb.disc_category);
-
+
if(this->cddb.disc_year)
free(this->cddb.disc_year);
-
+
}
}
/*
@@ -2024,12 +1938,12 @@ static void _cdda_free_cddb_info(cdda_input_plugin_t *this) {
*/
static int cdda_open(cdda_input_plugin_t *this_gen,
- char *cdda_device, cdrom_toc *toc, int *fdd) {
+ const char *cdda_device, cdrom_toc *toc, int *fdd) {
#ifndef WIN32
int fd = -1;
if ( !cdda_device ) return -1;
-
+
*fdd = -1;
if (this_gen)
@@ -2044,7 +1958,7 @@ static int cdda_open(cdda_input_plugin_t *this_gen,
if (this_gen)
this_gen->fd = fd;
-
+
#ifdef CDROM_SELECT_SPEED
if (this_gen->stream) {
int speed;
@@ -2074,17 +1988,17 @@ static int cdda_open(cdda_input_plugin_t *this_gen,
else
return -1;
- /* We are going to assume that we are opening a
+ /* We are going to assume that we are opening a
* device and not a file!
*/
if( WIN_NT )
{
char psz_win32_drive[7];
-
+
lprintf( "using winNT/2K/XP ioctl layer" );
-
+
sprintf( psz_win32_drive, "\\\\.\\%c:", cdda_device[0] );
-
+
this_gen->h_device_handle = CreateFile( psz_win32_drive, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
@@ -2100,89 +2014,89 @@ static int cdda_open(cdda_input_plugin_t *this_gen,
DWORD dwSupportInfo;
int i, j, i_hostadapters;
char c_drive = cdda_device[0];
-
+
hASPI = LoadLibrary( "wnaspi32.dll" );
if( hASPI != NULL )
{
- (FARPROC) lpGetSupport = GetProcAddress( hASPI,
+ lpGetSupport = GetProcAddress( hASPI,
"GetASPI32SupportInfo" );
- (FARPROC) lpSendCommand = GetProcAddress( hASPI,
+ lpSendCommand = GetProcAddress( hASPI,
"SendASPI32Command" );
}
-
+
if( hASPI == NULL || lpGetSupport == NULL || lpSendCommand == NULL )
{
lprintf( "unable to load aspi or get aspi function pointers" );
-
+
if( hASPI ) FreeLibrary( hASPI );
return -1;
}
-
+
/* ASPI support seems to be there */
-
+
dwSupportInfo = lpGetSupport();
-
+
if( HIBYTE( LOWORD ( dwSupportInfo ) ) == SS_NO_ADAPTERS )
{
lprintf( "no host adapters found (aspi)" );
FreeLibrary( hASPI );
return -1;
}
-
+
if( HIBYTE( LOWORD ( dwSupportInfo ) ) != SS_COMP )
{
lprintf( "unable to initalize aspi layer" );
-
+
FreeLibrary( hASPI );
return -1;
}
-
+
i_hostadapters = LOBYTE( LOWORD( dwSupportInfo ) );
if( i_hostadapters == 0 )
{
FreeLibrary( hASPI );
return -1;
}
-
+
c_drive = c_drive > 'Z' ? c_drive - 'a' : c_drive - 'A';
-
+
for( i = 0; i < i_hostadapters; i++ )
{
for( j = 0; j < 15; j++ )
{
struct SRB_GetDiskInfo srbDiskInfo;
-
+
srbDiskInfo.SRB_Cmd = SC_GET_DISK_INFO;
srbDiskInfo.SRB_HaId = i;
srbDiskInfo.SRB_Flags = 0;
srbDiskInfo.SRB_Hdr_Rsvd = 0;
srbDiskInfo.SRB_Target = j;
srbDiskInfo.SRB_Lun = 0;
-
+
lpSendCommand( (void*) &srbDiskInfo );
-
+
if( (srbDiskInfo.SRB_Status == SS_COMP) &&
(srbDiskInfo.SRB_Int13HDriveInfo == c_drive) )
{
/* Make sure this is a cdrom device */
struct SRB_GDEVBlock srbGDEVBlock;
-
+
memset( &srbGDEVBlock, 0, sizeof(struct SRB_GDEVBlock) );
srbGDEVBlock.SRB_Cmd = SC_GET_DEV_TYPE;
srbGDEVBlock.SRB_HaId = i;
srbGDEVBlock.SRB_Target = j;
-
+
lpSendCommand( (void*) &srbGDEVBlock );
-
+
if( ( srbGDEVBlock.SRB_Status == SS_COMP ) &&
( srbGDEVBlock.SRB_DeviceType == DTYPE_CDROM ) )
{
this_gen->i_sid = MAKEWORD( i, j );
this_gen->hASPI = (long)hASPI;
this_gen->lpSendCommand = lpSendCommand;
-
+
lprintf( "using aspi layer" );
-
+
return 0;
}
else
@@ -2194,12 +2108,12 @@ static int cdda_open(cdda_input_plugin_t *this_gen,
}
}
}
-
+
FreeLibrary( hASPI );
-
+
lprintf( "unable to get haid and target (aspi)" );
}
-
+
#endif /* WIN32 */
return -1;
@@ -2244,26 +2158,18 @@ static int cdda_close(cdda_input_plugin_t *this_gen) {
static uint32_t cdda_plugin_get_capabilities (input_plugin_t *this_gen) {
- return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK;
+ return INPUT_CAP_SEEKABLE;
}
static off_t cdda_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
- /* only allow reading in block-sized chunks */
-
- return 0;
-}
-
-static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
- off_t nlen) {
-
cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen;
- buf_element_t *buf;
- unsigned char frame_data[CD_RAW_FRAME_SIZE];
int err = 0;
- if (nlen != CD_RAW_FRAME_SIZE)
+ /* only allow reading in block-sized chunks */
+
+ if (len != CD_RAW_FRAME_SIZE)
return 0;
if (this->current_frame > this->last_frame)
@@ -2278,9 +2184,9 @@ static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buf
this->cache_last = this->current_frame + CACHED_FRAMES - 1;
if( this->cache_last > this->last_frame )
this->cache_last = this->last_frame;
-
-#ifndef WIN32
- if ( this->fd != -1 )
+
+#ifndef WIN32
+ if ( this->fd != -1 )
#else
if ( this->h_device_handle )
#endif /* WIN32 */
@@ -2296,15 +2202,27 @@ static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buf
if( err < 0 )
return 0;
-
- memcpy(frame_data, this->cache[this->current_frame-this->cache_first], CD_RAW_FRAME_SIZE);
+
+ memcpy(buf, this->cache[this->current_frame-this->cache_first], CD_RAW_FRAME_SIZE);
this->current_frame++;
+ return CD_RAW_FRAME_SIZE;
+}
+
+static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
+ off_t nlen) {
+
+ buf_element_t *buf;
+
buf = fifo->buffer_pool_alloc(fifo);
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
- buf->size = CD_RAW_FRAME_SIZE;
- memcpy(buf->mem, frame_data, CD_RAW_FRAME_SIZE);
+
+ buf->size = cdda_plugin_read(this_gen, buf->content, nlen);
+ if (buf->size == 0) {
+ buf->free_buffer(buf);
+ buf = NULL;
+ }
return buf;
}
@@ -2342,7 +2260,7 @@ static off_t cdda_plugin_get_length (input_plugin_t *this_gen) {
static uint32_t cdda_plugin_get_blocksize (input_plugin_t *this_gen) {
- return CD_RAW_FRAME_SIZE;
+ return 0;
}
static const char* cdda_plugin_get_mrl (input_plugin_t *this_gen) {
@@ -2383,7 +2301,7 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
int fd = -1;
char *cdda_device;
int err = -1;
-
+
lprintf("cdda_plugin_open\n");
/* get the CD TOC */
@@ -2394,7 +2312,7 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
else
cdda_device = class->cdda_device;
-#ifndef WIN32
+#ifndef WIN32
if( strchr(cdda_device,':') ) {
fd = network_connect(this->stream, cdda_device);
if( fd != -1 ) {
@@ -2412,7 +2330,7 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
return 0;
}
-#ifndef WIN32
+#ifndef WIN32
err = read_cdrom_toc(this->fd, toc);
#else
err = read_cdrom_toc(this, toc);
@@ -2424,18 +2342,18 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
}
-
- if ( (err < 0) || (toc->first_track > (this->track + 1)) ||
+
+ if ( (err < 0) || (toc->first_track > (this->track + 1)) ||
(toc->last_track < (this->track + 1))) {
cdda_close(this);
-
+
free_cdrom_toc(toc);
return 0;
}
/* set up the frame boundaries for this particular track */
- this->first_frame = this->current_frame =
+ this->first_frame = this->current_frame =
toc->toc_entries[this->track].first_frame;
if (this->track + 1 == toc->last_track)
this->last_frame = toc->leadout_track.first_frame - 1;
@@ -2446,8 +2364,8 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
this->cache_first = this->cache_last = -1;
/* get the Musicbrainz CDIndex */
- _cdda_cdindex (this, toc);
-
+ _cdda_cdindex (this, toc);
+
/*
* CDDB
*/
@@ -2458,26 +2376,26 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
if(this->cddb.num_tracks) {
int t;
- this->cddb.track = (trackinfo_t *) xine_xmalloc(sizeof(trackinfo_t) * this->cddb.num_tracks);
+ this->cddb.track = (trackinfo_t *) calloc(this->cddb.num_tracks, sizeof(trackinfo_t));
for(t = 0; t < this->cddb.num_tracks; t++) {
- int length = (toc->toc_entries[t].first_frame_minute * CD_SECONDS_PER_MINUTE +
+ int length = (toc->toc_entries[t].first_frame_minute * CD_SECONDS_PER_MINUTE +
toc->toc_entries[t].first_frame_second);
-
- this->cddb.track[t].start = (length * CD_FRAMES_PER_SECOND +
+
+ this->cddb.track[t].start = (length * CD_FRAMES_PER_SECOND +
toc->toc_entries[t].first_frame_frame);
this->cddb.track[t].title = NULL;
}
-
+
}
- this->cddb.disc_length = (toc->leadout_track.first_frame_minute * CD_SECONDS_PER_MINUTE +
+ this->cddb.disc_length = (toc->leadout_track.first_frame_minute * CD_SECONDS_PER_MINUTE +
toc->leadout_track.first_frame_second);
this->cddb.disc_id = _cdda_get_cddb_id(this);
if((this->cddb.have_cddb_info == 0) || (_cdda_is_cd_changed(this) == 1))
_cdda_cddb_retrieve(this);
-
+
if(this->cddb.disc_title) {
lprintf("Disc Title: %s\n", this->cddb.disc_title);
@@ -2485,17 +2403,36 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
}
if(this->cddb.track[this->track].title) {
- lprintf("Track %d Title: %s\n", this->track+1, this->cddb.track[this->track].title);
+ /* Check for track 'titles' of the form <artist> / <title>. */
+ char *pt;
+ pt = strstr(this->cddb.track[this->track].title, " / ");
+ if (pt != NULL) {
+ char *track_artist;
+ track_artist = strdup(this->cddb.track[this->track].title);
+ track_artist[pt - this->cddb.track[this->track].title] = 0;
+ lprintf("Track %d Artist: %s\n", this->track+1, track_artist);
+
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ARTIST, track_artist);
+ free(track_artist);
+ pt += 3;
+ }
+ else {
+ if(this->cddb.disc_artist) {
+ lprintf("Disc Artist: %s\n", this->cddb.disc_artist);
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TITLE, this->cddb.track[this->track].title);
- }
-
- if(this->cddb.disc_artist) {
- lprintf("Disc Artist: %s\n", this->cddb.disc_artist);
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ARTIST, this->cddb.disc_artist);
+ }
+
+ pt = this->cddb.track[this->track].title;
+ }
+ lprintf("Track %d Title: %s\n", this->track+1, pt);
- _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ARTIST, this->cddb.disc_artist);
+ char tracknum[4];
+ snprintf(tracknum, 4, "%d", this->track+1);
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TRACK_NUMBER, tracknum);
+ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TITLE, pt);
}
-
+
if(this->cddb.disc_category) {
lprintf("Disc Category: %s\n", this->cddb.disc_category);
@@ -2513,13 +2450,140 @@ static int cdda_plugin_open (input_plugin_t *this_gen ) {
return 1;
}
-static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
+static xine_mrl_t** cdda_class_get_dir(input_class_t *this_gen,
+ const char *filename,
+ int *num_files) {
+ cdda_input_class_t *this = (cdda_input_class_t *) this_gen;
+ cdda_input_plugin_t *ip;
+ cdrom_toc *toc;
+ char *base_mrl;
+ int len, frame;
+ const char * device;
+ int fd, i, err = -1;
+ int num_tracks;
+
+ if (filename && *filename) {
+ device = filename;
+ if (strncasecmp(device,"cdda:/",6) == 0) {
+ device += 6;
+ while ('/' == *device)
+ device++;
+ device--;
+ }
+ }
+ else {
+ device = this->cdda_device;
+ }
+ lprintf("cdda_class_get_dir for >%s<\n", device);
+
+ /* get the CD TOC */
+ toc = init_cdrom_toc();
+
+ fd = -1;
+
+ /* we create a new instance because getting a directory of a cd
+ * should not affect another cd that might be playing. */
+ ip = (cdda_input_plugin_t *)xine_xmalloc(sizeof(cdda_input_plugin_t));
+ ip->stream = NULL;
+ ip->fd = -1;
+ ip->net_fd = -1;
+
+#ifndef WIN32
+ if( strchr(device,':') ) {
+ fd = network_connect(ip->stream, device);
+ if( fd != -1 ) {
+ err = network_read_cdrom_toc(ip->stream, fd, toc);
+ }
+ }
+#endif
+
+ if (fd == -1) {
+ if (cdda_open(ip, device, toc, &fd) == -1) {
+ lprintf("cdda_class_get_dir: opening >%s< failed %s\n",
+ device, strerror(errno));
+ free(ip);
+ return NULL;
+ }
+
+#ifndef WIN32
+ err = read_cdrom_toc(fd, toc);
+#else
+ err = read_cdrom_toc(ip, toc);
+#endif /* WIN32 */
+ }
+
+#ifdef LOG
+ print_cdrom_toc(toc);
+#endif
+
+ cdda_close(ip);
+
+ if ( err < 0 ) {
+ free(ip);
+ return NULL;
+ }
+
+ num_tracks = toc->last_track - toc->first_track + 1;
+
+ /* this could be done in read_cdrom_toc, but it seems other code doesn't use it */
+ frame = toc->leadout_track.first_frame;
+ for ( i = num_tracks-1 ; i >= 0 ; i--) {
+ toc->toc_entries[i].total_frames = frame - toc->toc_entries[i].first_frame;
+ frame = toc->toc_entries[i].first_frame;
+ }
+
+ if (toc->ignore_last_track)
+ num_tracks--;
+
+ len = strlen(device) + 5;
+ base_mrl = xine_xmalloc(len+1);
+ sprintf(base_mrl, "cdda:%s", device);
+
+ /* allocate space for the mrls's if needed. */
+ if (num_tracks+1 > this->mrls_allocated_entries) {
+ this->mrls = realloc(this->mrls, (num_tracks+1) * sizeof(xine_mrl_t*));
+ }
+ for (i = 0 ; i < num_tracks ; i++) {
+ if (i < this->mrls_allocated_entries) {
+ if (this->mrls[i]->origin)
+ free(this->mrls[i]->origin);
+ if (this->mrls[i]->mrl)
+ free(this->mrls[i]->mrl);
+ if (this->mrls[i]->link) {
+ free(this->mrls[i]->link);
+ this->mrls[i]->link = NULL;
+ }
+ }
+ else {
+ this->mrls[i] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[i]->link = NULL;
+ this->mrls_allocated_entries++;
+ }
+ this->mrls[i]->origin = strdup(base_mrl);
+ this->mrls[i]->mrl = xine_xmalloc(len+4);
+ sprintf( this->mrls[i]->mrl, "%s/%d", base_mrl, i+toc->first_track);
+ this->mrls[i]->type = mrl_cda | mrl_file_blockdev;
+ this->mrls[i]->size = toc->toc_entries[i].total_frames * CD_RAW_FRAME_SIZE;
+ }
+ /* Clean up */
+ while(this->mrls_allocated_entries > num_tracks) {
+ MRL_ZERO(this->mrls[this->mrls_allocated_entries - 1]);
+ free(this->mrls[this->mrls_allocated_entries--]);
+ }
+ free_cdrom_toc(toc);
+ free(ip);
+
+ this->mrls[num_tracks] = NULL;
+ *num_files = num_tracks;
+ return this->mrls;
+}
+
+static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
int *num_files) {
cdda_input_class_t *this = (cdda_input_class_t *) this_gen;
cdda_input_plugin_t *ip = this->ip;
cdrom_toc *toc;
- char trackmrl[20];
int fd, i, err = -1;
int num_tracks;
@@ -2528,8 +2592,8 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
/* free old playlist */
for( i = 0; this->autoplaylist[i]; i++ ) {
free( this->autoplaylist[i] );
- this->autoplaylist[i] = NULL;
- }
+ this->autoplaylist[i] = NULL;
+ }
/* get the CD TOC */
toc = init_cdrom_toc();
@@ -2541,7 +2605,7 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
* device we are going to open; but it is possible that this function
* gets called, before a plugin instance has been created;
* let's create a dummy instance in such a condition */
- ip = (cdda_input_plugin_t *)xine_xmalloc(sizeof(cdda_input_plugin_t));
+ ip = calloc(1, sizeof(cdda_input_plugin_t));
ip->stream = NULL;
ip->fd = -1;
ip->net_fd = -1;
@@ -2575,20 +2639,18 @@ static char ** cdda_class_get_autoplay_list (input_class_t *this_gen,
print_cdrom_toc(toc);
#endif
- cdda_close(ip);
-
+ cdda_close(ip);
+
if ( err < 0 ) {
if (ip != this->ip) free(ip);
return NULL;
}
-
+
num_tracks = toc->last_track - toc->first_track;
if (toc->ignore_last_track)
num_tracks--;
- for ( i = 0; i <= num_tracks; i++ ) {
- sprintf(trackmrl,"cdda:/%d",i+toc->first_track);
- this->autoplaylist[i] = strdup(trackmrl);
- }
+ for ( i = 0; i <= num_tracks; i++ )
+ asprintf(&this->autoplaylist[i],"cdda:/%d",i+toc->first_track);
*num_files = toc->last_track - toc->first_track + 1;
@@ -2642,20 +2704,20 @@ static input_plugin_t *cdda_class_get_instance (input_class_t *cls_gen, xine_str
} else
return NULL;
- this = (cdda_input_plugin_t *) xine_xmalloc (sizeof (cdda_input_plugin_t));
-
+ this = calloc(1, sizeof (cdda_input_plugin_t));
+
class->ip = this;
this->stream = stream;
this->mrl = strdup(mrl);
this->cdda_device = cdda_device;
-
+
/* CD tracks start from 1; internal data structure indexes from 0 */
this->track = track - 1;
this->cddb.track = NULL;
this->fd = -1;
this->net_fd = -1;
this->class = (input_class_t *) class;
-
+
this->input_plugin.open = cdda_plugin_open;
this->input_plugin.get_capabilities = cdda_plugin_get_capabilities;
this->input_plugin.read = cdda_plugin_read;
@@ -2668,24 +2730,24 @@ static input_plugin_t *cdda_class_get_instance (input_class_t *cls_gen, xine_str
this->input_plugin.get_optional_data = cdda_plugin_get_optional_data;
this->input_plugin.dispose = cdda_plugin_dispose;
this->input_plugin.input_class = cls_gen;
-
+
/*
* Lookup config entries.
*/
- if(xine_config_lookup_entry(this->stream->xine, "media.audio_cd.use_cddb",
- &enable_entry))
+ if(xine_config_lookup_entry(this->stream->xine, "media.audio_cd.use_cddb",
+ &enable_entry))
enable_cddb_changed_cb(class, &enable_entry);
- if(xine_config_lookup_entry(this->stream->xine, "media.audio_cd.cddb_server",
- &server_entry))
+ if(xine_config_lookup_entry(this->stream->xine, "media.audio_cd.cddb_server",
+ &server_entry))
server_changed_cb(class, &server_entry);
-
- if(xine_config_lookup_entry(this->stream->xine, "media.audio_cd.cddb_port",
- &port_entry))
+
+ if(xine_config_lookup_entry(this->stream->xine, "media.audio_cd.cddb_port",
+ &port_entry))
port_changed_cb(class, &port_entry);
- if(xine_config_lookup_entry(this->stream->xine, "media.audio_cd.cddb_cachedir",
- &cachedir_entry))
+ if(xine_config_lookup_entry(this->stream->xine, "media.audio_cd.cddb_cachedir",
+ &cachedir_entry))
cachedir_changed_cb(class, &cachedir_entry);
class->cddb_error = cddb_error;
@@ -2731,7 +2793,7 @@ static void *init_plugin (xine_t *xine, void *data) {
cdda_input_class_t *this;
config_values_t *config;
- this = (cdda_input_class_t *) xine_xmalloc (sizeof (cdda_input_class_t));
+ this = calloc(1, sizeof (cdda_input_class_t));
this->xine = xine;
this->config = xine->config;
@@ -2740,8 +2802,7 @@ static void *init_plugin (xine_t *xine, void *data) {
this->input_class.get_instance = cdda_class_get_instance;
this->input_class.get_identifier = cdda_class_get_identifier;
this->input_class.get_description = cdda_class_get_description;
- /* this->input_class.get_dir = cdda_class_get_dir; */
- this->input_class.get_dir = NULL;
+ this->input_class.get_dir = cdda_class_get_dir;
this->input_class.get_autoplay_list = cdda_class_get_autoplay_list;
this->input_class.dispose = cdda_class_dispose;
this->input_class.eject_media = cdda_class_eject_media;
@@ -2749,15 +2810,15 @@ static void *init_plugin (xine_t *xine, void *data) {
this->mrls = NULL;
this->mrls_allocated_entries = 0;
this->ip = NULL;
-
- this->cdda_device = config->register_filename(config, "media.audio_cd.device",
+
+ this->cdda_device = config->register_filename(config, "media.audio_cd.device",
DEFAULT_CDDA_DEVICE, XINE_CONFIG_STRING_IS_DEVICE_NAME,
_("device used for CD audio"),
_("The path to the device, usually a "
"CD or DVD drive, which you intend to use "
"for playing audio CDs."),
10, cdda_device_cb, (void *) this);
-
+
config->register_bool(config, "media.audio_cd.use_cddb", 1,
_("query CDDB"), _("Enables CDDB queries, which will give you "
"convenient title and track names for your audio CDs.\n"
@@ -2765,7 +2826,7 @@ static void *init_plugin (xine_t *xine, void *data) {
"is retrieved from an internet server which might collect a profile "
"of your listening habits."),
10, enable_cddb_changed_cb, (void *) this);
-
+
config->register_string(config, "media.audio_cd.cddb_server", CDDB_SERVER,
_("CDDB server name"), _("The CDDB server used to retrieve the "
"title and track information from.\nThis setting is security critical, "
@@ -2773,18 +2834,18 @@ static void *init_plugin (xine_t *xine, void *data) {
"and could answer the queries with malicious replies. Be sure to enter "
"a server you can trust."), XINE_CONFIG_SECURITY,
server_changed_cb, (void *) this);
-
+
config->register_num(config, "media.audio_cd.cddb_port", CDDB_PORT,
_("CDDB server port"), _("The server port used to retrieve the "
"title and track information from."), XINE_CONFIG_SECURITY,
port_changed_cb, (void *) this);
-
- config->register_filename(config, "media.audio_cd.cddb_cachedir",
+
+ config->register_filename(config, "media.audio_cd.cddb_cachedir",
(_cdda_cddb_get_default_location()), XINE_CONFIG_STRING_IS_DIRECTORY_NAME,
_("CDDB cache directory"), _("The replies from the CDDB server will be "
"cached in this directory.\nThis setting is security critical, because files "
"with uncontrollable names will be created in this directory. Be sure to use "
- "a dedicated directory not used for anything but CDDB caching."), XINE_CONFIG_SECURITY,
+ "a dedicated directory not used for anything but CDDB caching."), XINE_CONFIG_SECURITY,
cachedir_changed_cb, (void *) this);
#ifdef CDROM_SELECT_SPEED
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
index 795b843c5..e6abfd3d5 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -1,18 +1,18 @@
/*
- * Copyright (C) 2000-2005 the xine project
- *
+ * Copyright (C) 2000-2008 the xine project
+ *
* 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
@@ -30,7 +30,7 @@
* 01-Feb-2005 Pekka Jääskeläinen <poj@iki.fi>
*
* - This history log started.
- * - Disabled the automatic EPG updater thread until EPG demuxer
+ * - Disabled the automatic EPG updater thread until EPG demuxer
* is done (it caused pausing of video stream), now EPG is
* updated only on demand when the EPG OSD is displayed and
* no data is in cache.
@@ -39,10 +39,10 @@
* - Now tuning to an erroneus channel shouldn't hang but stop
* the playback and output a log describing the error.
* - Style cleanups here and there.
- *
+ *
* 06-Apr-2006 Jack Steven Kelliher
* - Add ATSC support
- *
+ *
* TODO/Wishlist: (not in any order)
* - Parse all Administrative PIDs - NIT,SDT,CAT etc
* - As per James' suggestion, we need a way for the demuxer
@@ -52,7 +52,7 @@
* Alevtd can read it.
* - Allow the user to view one set of PIDs (channel) while
* recording another on the same transponder - this will require either remuxing or
- * perhaps bypassing the TS demuxer completely - we could easily have access to the
+ * perhaps bypassing the TS demuxer completely - we could easily have access to the
* individual audio/video streams via seperate read calls, so send them to the decoders
* and save the TS output to disk instead of passing it to the demuxer.
* This also gives us full control over the streams being played..hmm..control...
@@ -60,20 +60,20 @@
* - Allow the user to find and tune new stations from within xine, and
* do away with the need for dvbscan & channels.conf file.
* - Enable use of Conditional Access devices for scrambled content.
- * - if multiple cards are available, optionally use these to record/gather si info,
+ * - if multiple cards are available, optionally use these to record/gather si info,
* and leave primary card for viewing.
* - allow for handing off of EPG data to specialised frontends, instead of displaying via
* OSD - this will allow for filtering/searching of epg data - useful for automatic recording :)
*/
-/* pthread.h must be included first so rest of the headers are imported
- thread safely (on some systems). */
-#include <pthread.h>
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+/* pthread.h must be included first so rest of the headers are imported
+ thread safely (on some systems). */
+#include <pthread.h>
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -117,7 +117,7 @@
#define DVB_NOPID 0xffff
-/* define stream types
+/* define stream types
* administrative/system PIDs first */
#define INTERNAL_FILTER 0
#define PATFILTER 1
@@ -190,7 +190,7 @@
#define EPG_PIXELS_BETWEEN_TEXT_ROWS 2
#define EPG_PIXELS_BETWEEN_PROGRAM_ENTRIES 2
-/* How many pixels the background of the OSD is bigger than the text area?
+/* How many pixels the background of the OSD is bigger than the text area?
The margin is for each side of the background box. */
#define EPG_BACKGROUND_MARGIN 5
@@ -201,10 +201,10 @@
/* How many seconds an EPG entry with the running flag on can be "late"
according to the system time before discarding it as an old program?
-
- This margin is needed because in channel list OSD some EPG entries of
+
+ This margin is needed because in channel list OSD some EPG entries of
some channels may be updated a very long ago (if user has watched another
- channel in different mux) so we have to resort to system clock for
+ channel in different mux) so we have to resort to system clock for
figuring out the current program. */
#define MAX_EPG_ENTRY_LATENESS 5*60.0
@@ -226,13 +226,13 @@ typedef struct {
int fd_subfilter[MAX_SUBTITLES];
struct dvb_frontend_info feinfo;
-
+
int adapter_num;
char frontend_device[100];
- char dvr_device[100];
+ char dvr_device[100];
char demux_device[100];
-
+
struct dmx_pes_filter_params pesFilterParams[MAX_FILTERS];
struct dmx_pes_filter_params subFilterParams[MAX_SUBTITLES];
struct dmx_sct_filter_params sectFilterParams[MAX_FILTERS];
@@ -244,16 +244,16 @@ typedef struct {
typedef struct {
/* Program's name. */
- char *progname;
+ char *progname;
/* Textual description of the program. */
char *description;
/* The content type string. */
- char *content;
+ char *content;
/* Age recommendation. 0 if not available. */
- int rating;
+ int rating;
time_t starttime;
@@ -262,7 +262,7 @@ typedef struct {
char duration_minutes;
/* Is this program running currently according to EPG data? */
- char running;
+ char running;
} epg_entry_t;
@@ -286,11 +286,12 @@ typedef struct {
xine_t *xine;
- char *mrls[5];
+ char *mrls[6];
- int numchannels;
+ int numchannels;
char *autoplaylist[MAX_AUTOCHANNELS];
+ char *default_channels_conf_filename;
} dvb_input_class_t;
typedef struct {
@@ -320,22 +321,25 @@ typedef struct {
osd_object_t *rec_osd;
osd_object_t *name_osd;
osd_object_t *paused_osd;
- osd_object_t *proginfo_osd;
+ osd_object_t *proginfo_osd;
osd_object_t *channel_osd;
osd_object_t *background;
-
+
xine_event_queue_t *event_queue;
/* CRC table for PAT rebuilding */
unsigned long crc32_table[256];
-
+
/* scratch buffer for forward seeking */
char seek_buf[BUFSIZE];
+ /* Is the GUI enabled at all? */
+ int dvb_gui_enabled;
+
/* simple vcr-like functionality */
int record_fd;
int record_paused;
/* centre cutout zoom */
- int zoom_ok;
+ int zoom_ok;
/* Is EPG displaying? */
int epg_displaying;
@@ -344,8 +348,8 @@ typedef struct {
pthread_t epg_updater_thread;
/* buffer for EIT data */
- /*char *eitbuffer;*/
- int num_streams_in_this_ts;
+ /*char *eitbuffer;*/
+ int num_streams_in_this_ts;
/* number of timedout reads in plugin_read */
int read_failcount;
#ifdef DVB_NO_BUFFERING
@@ -369,6 +373,7 @@ static const Param bw_list [] = {
{ "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ },
{ "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ },
{ "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ },
+ { "BANDWIDTH_AUTO", BANDWIDTH_AUTO },
{ NULL, 0 }
};
@@ -391,6 +396,7 @@ static const Param guard_list [] = {
{"GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32},
{"GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4},
{"GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8},
+ {"GUARD_INTERVAL_AUTO", GUARD_INTERVAL_AUTO},
{ NULL, 0 }
};
@@ -399,6 +405,7 @@ static const Param hierarchy_list [] = {
{ "HIERARCHY_2", HIERARCHY_2 },
{ "HIERARCHY_4", HIERARCHY_4 },
{ "HIERARCHY_NONE", HIERARCHY_NONE },
+ { "HIERARCHY_AUTO", HIERARCHY_AUTO },
{ NULL, 0 }
};
@@ -417,12 +424,14 @@ static const Param qam_list [] = {
{ "QAM_256", QAM_256 },
{ "QAM_32", QAM_32 },
{ "QAM_64", QAM_64 },
+ { "QAM_AUTO", QAM_AUTO },
{ NULL, 0 }
};
static const Param transmissionmode_list [] = {
{ "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K },
{ "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K },
+ { "TRANSMISSION_MODE_AUTO", TRANSMISSION_MODE_AUTO },
{ NULL, 0 }
};
@@ -455,7 +464,7 @@ static void ts_build_crc32_table(dvb_input_plugin_t *this) {
}
}
-static uint32_t ts_compute_crc32(dvb_input_plugin_t *this, uint8_t *data,
+static uint32_t ts_compute_crc32(dvb_input_plugin_t *this, uint8_t *data,
uint32_t length, uint32_t crc32) {
uint32_t i;
@@ -479,7 +488,7 @@ static unsigned int getbits(unsigned char *buffer, unsigned int bitpos, unsigned
}
-static int find_descriptor(uint8_t tag, const unsigned char *buf, int descriptors_loop_len,
+static int find_descriptor(uint8_t tag, const unsigned char *buf, int descriptors_loop_len,
const unsigned char **desc, int *desc_len)
{
@@ -513,11 +522,11 @@ time_t dvb_mjdtime (char *buf)
int i;
unsigned int year, month, day, hour, min, sec;
unsigned long int mjd;
- struct tm *tma = xine_xmalloc(sizeof(struct tm));
+ struct tm *tma = calloc(1, sizeof(struct tm));
time_t t;
_x_assert(tma != NULL);
-
+
mjd = (unsigned int)(buf[0] & 0xff) << 8;
mjd +=(unsigned int)(buf[1] & 0xff);
hour =(unsigned char)bcdtoint(buf[2] & 0xff);
@@ -526,14 +535,14 @@ time_t dvb_mjdtime (char *buf)
year =(unsigned long)((mjd - 15078.2)/365.25);
month=(unsigned long)((mjd - 14956.1 - (unsigned long)(year * 365.25))/30.6001);
day = mjd - 14956 - (unsigned long)(year * 365.25) - (unsigned long)(month * 30.6001);
-
+
if (month == 14 || month == 15)
i = 1;
else
i = 0;
year += i;
month = month - 1 - i * 12;
-
+
tma->tm_sec=sec;
tma->tm_min=min;
tma->tm_hour=hour;
@@ -543,7 +552,7 @@ time_t dvb_mjdtime (char *buf)
t = timegm(tma);
-
+
free(tma);
return t;
}
@@ -565,39 +574,38 @@ static void tuner_dispose(tuner_t * this)
for (x = 0; x < MAX_SUBTITLES; x++)
if (this->fd_subfilter[x] >= 0)
close(this->fd_subfilter[x]);
-
+
if(this)
free(this);
}
-static tuner_t *tuner_init(xine_t * xine, int adapter)
+static tuner_t *XINE_MALLOC tuner_init(xine_t * xine, int adapter)
{
tuner_t *this;
int x;
int test_video;
- char *video_device=xine_xmalloc(200);
+ char *video_device=malloc(100);
_x_assert(video_device != NULL);
-
- this = (tuner_t *) xine_xmalloc(sizeof(tuner_t));
+
+ this = calloc(1, sizeof(tuner_t));
_x_assert(this != NULL);
xprintf(this->xine, XINE_VERBOSITY_DEBUG, "tuner_init adapter=%d\n", adapter);
this->fd_frontend = -1;
- for (x = 0; x < MAX_FILTERS; x++)
- this->fd_pidfilter[x] = 0;
+ memset(this->fd_pidfilter, 0, sizeof(this->fd_pidfilter));
this->xine = xine;
this->adapter_num = adapter;
-
+
snprintf(this->frontend_device,100,"/dev/dvb/adapter%i/frontend0",this->adapter_num);
snprintf(this->demux_device,100,"/dev/dvb/adapter%i/demux0",this->adapter_num);
snprintf(this->dvr_device,100,"/dev/dvb/adapter%i/dvr0",this->adapter_num);
snprintf(video_device,100,"/dev/dvb/adapter%i/video0",this->adapter_num);
-
+
if ((this->fd_frontend = open(this->frontend_device, O_RDWR)) < 0) {
xprintf(this->xine, XINE_VERBOSITY_DEBUG, "FRONTEND DEVICE: %s\n", strerror(errno));
tuner_dispose(this);
@@ -633,7 +641,7 @@ static tuner_t *tuner_init(xine_t * xine, int adapter)
xprintf(this->xine,XINE_VERBOSITY_DEBUG,"input_dvb: couldn't set INTERNAL to nonblock: %s\n",strerror(errno));
/* and the frontend */
fcntl(this->fd_frontend, F_SETFL, O_NONBLOCK);
-
+
xprintf(this->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Frontend is <%s> ",this->feinfo.name);
if(this->feinfo.type==FE_QPSK) xprintf(this->xine,XINE_VERBOSITY_DEBUG,"SAT Card\n");
if(this->feinfo.type==FE_QAM) xprintf(this->xine,XINE_VERBOSITY_DEBUG,"CAB Card\n");
@@ -648,7 +656,7 @@ static tuner_t *tuner_init(xine_t * xine, int adapter)
}
free(video_device);
-
+
return this;
}
@@ -660,7 +668,7 @@ static int dvb_set_pidfilter(dvb_input_plugin_t * this, int filter, ushort pid,
if(this->channels[this->channel].pid [filter] !=DVB_NOPID) {
ioctl(tuner->fd_pidfilter[filter], DMX_STOP);
}
-
+
this->channels[this->channel].pid [filter] = pid;
tuner->pesFilterParams[filter].pid = pid;
tuner->pesFilterParams[filter].input = DMX_IN_FRONTEND;
@@ -683,7 +691,7 @@ static int dvb_set_sectfilter(dvb_input_plugin_t * this, int filter, ushort pid,
if(this->channels[this->channel].pid [filter] !=DVB_NOPID) {
ioctl(tuner->fd_pidfilter[filter], DMX_STOP);
}
-
+
this->channels[this->channel].pid [filter] = pid;
tuner->sectFilterParams[filter].pid = pid;
memset(&tuner->sectFilterParams[filter].filter.filter,0,DMX_FILTER_SIZE);
@@ -717,14 +725,14 @@ static int extract_channel_from_string_internal(channel_t * channel,char * str,f
<bw>:<fec_hp>:<fec_lp>:<qam>:
<transmissionm>:<guardlist>:<hierarchinfo>:<vpid>:<apid>
(DVBA) ATSC: <channel name>:<frequency>:<qam>:<vpid>:<apid>
-
+
<channel name> = any string not containing ':'
<frequency> = unsigned long
<polarisation> = 'v' or 'h'
<sat_no> = unsigned long, usually 0 :D
<sym_rate> = symbol rate in MSyms/sec
-
-
+
+
<inversion> = INVERSION_ON | INVERSION_OFF | INVERSION_AUTO
<fec> = FEC_1_2, FEC_2_3, FEC_3_4 .... FEC_AUTO ... FEC_NONE
<qam> = QPSK, QAM_128, QAM_16, ATSC ...
@@ -741,7 +749,7 @@ static int extract_channel_from_string_internal(channel_t * channel,char * str,f
char *field, *tmp;
tmp = str;
-
+
/* find the channel name */
if(!(field = strsep(&tmp,":")))return -1;
channel->name = strdup(field);
@@ -762,8 +770,8 @@ static int extract_channel_from_string_internal(channel_t * channel,char * str,f
channel->tone = 0;
}
channel->front_param.inversion = INVERSION_AUTO;
-
- /* find out the polarisation */
+
+ /* find out the polarisation */
if(!(field = strsep(&tmp, ":")))return -1;
channel->pol = (field[0] == 'h' ? 0 : 1);
@@ -779,7 +787,7 @@ static int extract_channel_from_string_internal(channel_t * channel,char * str,f
break;
case FE_QAM:
channel->front_param.frequency = freq;
-
+
/* find out the inversion */
if(!(field = strsep(&tmp, ":")))return -1;
channel->front_param.inversion = find_param(inversion_list, field);
@@ -797,10 +805,10 @@ static int extract_channel_from_string_internal(channel_t * channel,char * str,f
channel->front_param.u.qam.modulation = find_param(qam_list, field);
break;
case FE_OFDM:
- /* DVB-T frequency is in kHz - workaround broken channels.confs */
- if (freq < 1000000)
- freq*=1000;
-
+ /* DVB-T frequency is in kHz - workaround broken channels.confs */
+ if (freq < 1000000)
+ freq*=1000;
+
channel->front_param.frequency = freq;
/* find out the inversion */
@@ -836,7 +844,7 @@ static int extract_channel_from_string_internal(channel_t * channel,char * str,f
break;
case FE_ATSC:
channel->front_param.frequency = freq;
-
+
/* find out the qam */
if(!(field = strsep(&tmp, ":")))return -1;
channel->front_param.u.vsb.modulation = find_param(atsc_list, field);
@@ -862,9 +870,9 @@ static int extract_channel_from_string_internal(channel_t * channel,char * str,f
/* some channel.conf files are generated with the service ID 1 to the right
this needs investigation */
if ((field = strsep(&tmp, ":")))
- if(strtoul(field,NULL,0)>0)
+ if(strtoul(field,NULL,0)>0)
channel->service_id = strtoul(field, NULL, 0);
-
+
return 0;
}
@@ -881,14 +889,15 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
FILE *f;
char str[BUFSIZE];
- char filename[BUFSIZE];
channel_t *channels = NULL;
int num_channels = 0;
int num_alloc = 0;
- int i;
struct stat st;
-
- snprintf(filename, BUFSIZE, "%s/.xine/channels.conf", xine_get_homedir());
+ xine_cfg_entry_t channels_conf;
+ char *filename;
+
+ xine_config_lookup_entry(xine, "media.dvb.channels_conf", &channels_conf);
+ filename = channels_conf.str_value;
f = fopen(filename, "r");
if (!f) {
@@ -904,25 +913,25 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
}
/*
- * load channel list
+ * load channel list
*/
while ( fgets (str, BUFSIZE, f)) {
channel_t channel = {0};
- /* lose trailing spaces & control characters */
- i = strlen (str);
+ /* lose trailing spaces & control characters */
+ size_t i = strlen (str);
while (i && str[i - 1] <= ' ')
--i;
if (i == 0)
continue;
str[i] = 0;
- if (extract_channel_from_string(&channel,str,fe_type) < 0)
+ if (extract_channel_from_string(&channel,str,fe_type) < 0)
continue;
if (num_channels >= num_alloc) {
- channel_t *new_channels = xine_xmalloc((num_alloc += 32) * sizeof (channel_t));
+ channel_t *new_channels = calloc((num_alloc += 32), sizeof (channel_t));
_x_assert(new_channels != NULL);
memcpy(new_channels, channels, num_channels * sizeof (channel_t));
free(channels);
@@ -933,8 +942,7 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
/* Initially there's no EPG data in the EPG structs. */
channels[num_channels].epg_count = 0;
- for (i = 0; i < MAX_EPG_ENTRIES_PER_CHANNEL; ++i)
- channels[num_channels].epg[i] = NULL;
+ memset(channels[num_channels].epg, 0, sizeof(channels[num_channels].epg));
num_channels++;
}
@@ -943,14 +951,14 @@ static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch
/* free any trailing unused entries */
channels = realloc (channels, num_channels * sizeof (channel_t));
- if(num_channels > 0)
+ if(num_channels > 0)
xprintf (xine, XINE_VERBOSITY_DEBUG, "input_dvb: found %d channels...\n", num_channels);
else {
xprintf (xine, XINE_VERBOSITY_DEBUG, "input_dvb: no channels found in the file: giving up.\n");
free(channels);
return NULL;
}
-
+
*num_ch = num_channels;
return channels;
}
@@ -1044,7 +1052,7 @@ static int tuner_tune_it (tuner_t *this, struct dvb_frontend_parameters
}
xprintf(this->xine, XINE_VERBOSITY_DEBUG, "input_dvb: tuner_tune_it - waiting for lock...\n" );
-
+
do {
status = 0;
if (ioctl(this->fd_frontend, FE_READ_STATUS, &status) < 0) {
@@ -1071,25 +1079,25 @@ static int tuner_tune_it (tuner_t *this, struct dvb_frontend_parameters
usleep(10000);
xprintf(this->xine, XINE_VERBOSITY_DEBUG, "Trying to get lock...");
} while (!(status & FE_TIMEDOUT));
-
- /* inform the user of frontend status */
+
+ /* inform the user of frontend status */
xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Tuner status: ");
/* if (ioctl(this->fd_frontend, FE_READ_STATUS, &status) >= 0){ */
- if (status & FE_HAS_SIGNAL)
+ if (status & FE_HAS_SIGNAL)
xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_SIGNAL");
- if (status & FE_TIMEDOUT)
+ if (status & FE_TIMEDOUT)
xprintf(this->xine,XINE_VERBOSITY_LOG," FE_TIMEDOUT");
- if (status & FE_HAS_LOCK)
+ if (status & FE_HAS_LOCK)
xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_LOCK");
- if (status & FE_HAS_CARRIER)
+ if (status & FE_HAS_CARRIER)
xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_CARRIER");
- if (status & FE_HAS_VITERBI)
+ if (status & FE_HAS_VITERBI)
xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_VITERBI");
- if (status & FE_HAS_SYNC)
+ if (status & FE_HAS_SYNC)
xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_SYNC");
/* } */
xprintf(this->xine,XINE_VERBOSITY_LOG,"\n");
-
+
strength=0;
if(ioctl(this->fd_frontend,FE_READ_BER,&strength) >= 0)
xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Bit error rate: %i\n",strength);
@@ -1101,9 +1109,9 @@ static int tuner_tune_it (tuner_t *this, struct dvb_frontend_parameters
strength=0;
if(ioctl(this->fd_frontend,FE_READ_SNR,&strength) >= 0)
xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Signal/Noise Ratio: %u\n",strength);
-
+
if (status & FE_HAS_LOCK && !(status & FE_TIMEDOUT)) {
- xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Lock achieved at %lu Hz\n",(unsigned long)front_param->frequency);
+ xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Lock achieved at %lu Hz\n",(unsigned long)front_param->frequency);
return 1;
} else {
xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Unable to achieve lock at %lu Hz\n",(unsigned long)front_param->frequency);
@@ -1112,13 +1120,13 @@ static int tuner_tune_it (tuner_t *this, struct dvb_frontend_parameters
}
-/* Parse the PMT, and add filters for all stream types associated with
- * the 'channel'. We leave it to the demuxer to sort out which PIDs to
+/* Parse the PMT, and add filters for all stream types associated with
+ * the 'channel'. We leave it to the demuxer to sort out which PIDs to
* use. to simplify things slightly, (and because the demuxer can't handle it)
* allow only one of each media type */
static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int section_length)
{
-
+
int program_info_len;
int pcr_pid;
int has_video=0;
@@ -1144,29 +1152,33 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se
switch (buf[0]) {
case 0x01:
case 0x02:
+ case 0x10:
+ case 0x1b:
if(!has_video) {
xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding VIDEO : PID 0x%04x\n", elementary_pid);
dvb_set_pidfilter(this, VIDFILTER, elementary_pid, DMX_PES_VIDEO, DMX_OUT_TS_TAP);
has_video=1;
- }
+ }
break;
-
+
case 0x03:
case 0x04:
+ case 0x0f:
+ case 0x11:
if(!has_audio) {
xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding AUDIO : PID 0x%04x\n", elementary_pid);
dvb_set_pidfilter(this, AUDFILTER, elementary_pid, DMX_PES_AUDIO, DMX_OUT_TS_TAP);
has_audio=1;
}
break;
-
+
case 0x06:
if (find_descriptor(0x56, buf + 5, descriptor_len, NULL, NULL)) {
if(!has_text) {
xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding TELETEXT : PID 0x%04x\n", elementary_pid);
dvb_set_pidfilter(this,TXTFILTER, elementary_pid, DMX_PES_OTHER,DMX_OUT_TS_TAP);
has_text=1;
- }
+ }
break;
} else if (find_descriptor (0x59, buf + 5, descriptor_len, NULL, NULL)) {
/* Note: The subtitling descriptor can also signal
@@ -1187,7 +1199,7 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se
this->tuner->subFilterParams[has_subs].flags = DMX_IMMEDIATE_START;
if (ioctl(this->tuner->fd_subfilter[has_subs], DMX_SET_PES_FILTER, &this->tuner->subFilterParams[has_subs]) < 0)
{
- xprintf(this->tuner->xine, XINE_VERBOSITY_DEBUG, "input_dvb: set_pid: %s\n", strerror(errno));
+ xprintf(this->tuner->xine, XINE_VERBOSITY_DEBUG, "input_dvb: set_pid: %s\n", strerror(errno));
break;
}
has_subs++;
@@ -1195,7 +1207,7 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se
break;
} else if (find_descriptor (0x6a, buf + 5, descriptor_len, NULL, NULL)) {
if(!has_ac3) {
- dvb_set_pidfilter(this, AC3FILTER, elementary_pid, DMX_PES_OTHER,DMX_OUT_TS_TAP);
+ dvb_set_pidfilter(this, AC3FILTER, elementary_pid, DMX_PES_OTHER,DMX_OUT_TS_TAP);
xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding AC3 : PID 0x%04x\n", elementary_pid);
has_ac3=1;
}
@@ -1203,7 +1215,7 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se
}
break;
case 0x81: /* AC3 audio */
- fprintf(stderr, " pid type 0x%x, has audio %d\n",buf[0],has_audio);
+ fprintf(stderr, " pid type 0x%x, has audio %d\n",buf[0],has_audio);
if(!has_audio) {
xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding AUDIO : PID 0x%04x\n", elementary_pid);
dvb_set_pidfilter(this, AUDFILTER, elementary_pid, DMX_PES_AUDIO, DMX_OUT_TS_TAP);
@@ -1211,7 +1223,7 @@ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int se
}
break;
- };
+ };
buf += descriptor_len + 5;
section_length -= descriptor_len + 5;
@@ -1222,14 +1234,14 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
char *tmpbuffer;
char *bufptr;
- int service_id;
+ int service_id;
int result;
- int section_len;
- int x;
+ int section_len;
+ int x;
struct pollfd pfd;
-
+
tuner_t *tuner = this->tuner;
- tmpbuffer = xine_xmalloc (8192);
+ tmpbuffer = calloc(1, 8192);
_x_assert(tmpbuffer != NULL);
@@ -1241,8 +1253,8 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Setting up Internal PAT filter\n");
xine_usec_sleep(500000);
-
- /* first - the PAT. retrieve the entire section...*/
+
+ /* first - the PAT. retrieve the entire section...*/
dvb_set_sectfilter(this, INTERNAL_FILTER, 0, DMX_PES_OTHER, 0, 0xff);
/* wait for up to 15 seconds */
@@ -1255,13 +1267,13 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
return;
}
result = read (tuner->fd_pidfilter[INTERNAL_FILTER], tmpbuffer, 3);
-
+
if(result!=3)
xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: error reading PAT table - no data!\n");
section_len = getbits(tmpbuffer,12,12);
result = read (tuner->fd_pidfilter[INTERNAL_FILTER], tmpbuffer+5,section_len);
-
+
if(result!=section_len)
xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: error reading in the PAT table\n");
@@ -1269,7 +1281,7 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
bufptr+=10;
this->num_streams_in_this_ts=0;
- section_len-=5;
+ section_len-=5;
while(section_len>4){
service_id = getbits (bufptr,0,16);
@@ -1281,7 +1293,7 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
section_len-=4;
bufptr+=4;
if(service_id>0) /* ignore NIT table for now */
- this->num_streams_in_this_ts++;
+ this->num_streams_in_this_ts++;
}
bufptr = tmpbuffer;
@@ -1306,7 +1318,7 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
ioctl(tuner->fd_pidfilter[INTERNAL_FILTER], DMX_STOP);
parse_pmt(this,tmpbuffer+8,section_len);
-
+
/*
dvb_set_pidfilter(this, TSDTFILTER, 0x02,DMX_PES_OTHER,DMX_OUT_TS_TAP);
dvb_set_pidfilter(this, RSTFILTER, 0x13,DMX_PES_OTHER,DMX_OUT_TS_TAP);
@@ -1319,8 +1331,8 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
/* we use the section filter for EIT because we are guarenteed a complete section */
if(ioctl(tuner->fd_pidfilter[EITFILTER],DMX_SET_BUFFER_SIZE,8192*this->num_streams_in_this_ts)<0)
- xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: couldn't increase buffer size for EIT: %s \n",strerror(errno));
- dvb_set_sectfilter(this, EITFILTER, 0x12,DMX_PES_OTHER,0x4e, 0xff);
+ xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: couldn't increase buffer size for EIT: %s \n",strerror(errno));
+ dvb_set_sectfilter(this, EITFILTER, 0x12,DMX_PES_OTHER,0x4e, 0xff);
xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Setup of PID filters complete\n");
@@ -1332,7 +1344,7 @@ static void dvb_parse_si(dvb_input_plugin_t *this) {
static int channel_index(dvb_input_plugin_t* this, unsigned int service_id) {
unsigned int n;
for (n=0; n < this->num_channels; n++)
- if (this->channels[n].service_id == service_id)
+ if (this->channels[n].service_id == service_id)
return n;
return -1;
@@ -1347,7 +1359,7 @@ static int compare_epg_by_starttime(const void* a, const void* b) {
return -1;
} else if ((*epg_a)->starttime > (*epg_b)->starttime) {
return 1;
- }
+ }
return 0;
}
@@ -1370,7 +1382,7 @@ static void pthread_sleep(int seconds) {
struct timespec timeout;
/* Create a dummy mutex which doesn't unlock for sure while waiting. */
- pthread_mutex_init(&dummy_mutex, NULL);
+ pthread_mutex_init(&dummy_mutex, NULL);
pthread_mutex_lock(&dummy_mutex);
/* Create a dummy condition variable. */
@@ -1410,7 +1422,7 @@ static void* epg_data_updater(void *t) {
}
#endif
-/* This function parses the EIT table and saves the data used in
+/* This function parses the EIT table and saves the data used in
EPG OSD of all channels found in the currently tuned stream. */
static void load_epg_data(dvb_input_plugin_t *this)
{
@@ -1419,7 +1431,7 @@ static void load_epg_data(dvb_input_plugin_t *this)
int descriptor_id;
int section_len = 0;
unsigned int service_id=-1;
- int n;
+ int n;
char *eit = NULL;
char *foo = NULL;
char *seen_channels = NULL;
@@ -1434,21 +1446,18 @@ static void load_epg_data(dvb_input_plugin_t *this)
pthread_mutex_lock(&this->channel_change_mutex);
/* seen_channels array is used to store information of channels that were
- already "found" in the stream. This information is used to initialize the
- channel's EPG structs when the EPG information for the channel is seen in
+ already "found" in the stream. This information is used to initialize the
+ channel's EPG structs when the EPG information for the channel is seen in
the stream the first time. */
- seen_channels = xine_xmalloc(this->num_channels*sizeof(char));
+ seen_channels = calloc(this->num_channels, sizeof(char));
_x_assert(seen_channels != NULL);
- for (i = 0; i < this->num_channels; i++) {
- seen_channels[i] = 0;
- }
- foo = xine_xmalloc(8192);
+ foo = calloc(1, 8192);
_x_assert(foo != NULL);
fd.fd = this->tuner->fd_pidfilter[EITFILTER];
fd.events = POLLPRI;
-
+
for (loops = 0; loops <= this->num_streams_in_this_ts*2; loops++) {
eit = foo;
@@ -1457,7 +1466,7 @@ static void load_epg_data(dvb_input_plugin_t *this)
pthread_mutex_unlock(&this->channel_change_mutex);
free(seen_channels);
free(foo);
- return;
+ return;
}
n = read(this->tuner->fd_pidfilter[EITFILTER], eit, 3);
table_id = getbits(eit, 0, 8);
@@ -1470,8 +1479,8 @@ static void load_epg_data(dvb_input_plugin_t *this)
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,"input_dvb: load_epg_data(): unknown service_id: %d!\n", service_id);
continue;
}
-
-
+
+
if (section_len > 15) {
current_channel = &this->channels[current_channel_index];
@@ -1489,23 +1498,23 @@ static void load_epg_data(dvb_input_plugin_t *this)
continue;
}
- /* Initialize the EPG struct if there's not one we can reuse.
+ /* Initialize the EPG struct if there's not one we can reuse.
Allocate space for the strings. */
if (current_channel->epg[current_channel->epg_count] == NULL) {
current_channel->epg[current_channel->epg_count] =
- xine_xmalloc(sizeof(epg_entry_t));
+ calloc(1, sizeof(epg_entry_t));
_x_assert(current_channel->epg[current_channel->epg_count] != NULL);
- current_channel->epg[current_channel->epg_count]->progname =
- xine_xmalloc((MAX_EPG_PROGRAM_NAME_LENGTH + 1) * sizeof(char));
+ current_channel->epg[current_channel->epg_count]->progname =
+ malloc(MAX_EPG_PROGRAM_NAME_LENGTH + 1);
_x_assert(current_channel->epg[current_channel->epg_count]->progname != NULL);
current_channel->epg[current_channel->epg_count]->description =
- xine_xmalloc((MAX_EPG_PROGRAM_DESCRIPTION_LENGTH + 1) * sizeof(char));
+ malloc(MAX_EPG_PROGRAM_DESCRIPTION_LENGTH + 1);
_x_assert(current_channel->epg[current_channel->epg_count]->description != NULL);
- current_channel->epg[current_channel->epg_count]->content =
- xine_xmalloc((MAX_EPG_CONTENT_TYPE_LENGTH + 1) * sizeof(char));
+ current_channel->epg[current_channel->epg_count]->content =
+ malloc(MAX_EPG_CONTENT_TYPE_LENGTH + 1);
_x_assert(current_channel->epg[current_channel->epg_count]->content != NULL);
current_channel->epg[current_channel->epg_count]->running = 0;
@@ -1519,12 +1528,12 @@ static void load_epg_data(dvb_input_plugin_t *this)
1 not running
2 starts in a few seconds
3 pausing
- 4 running
+ 4 running
*/
if (getbits(foo,192,3) == 4){
- current_epg->running = 1;
+ current_epg->running = 1;
} else {
- current_epg->running = 0;
+ current_epg->running = 0;
}
@@ -1537,7 +1546,7 @@ static void load_epg_data(dvb_input_plugin_t *this)
current_epg->duration_minutes = (char)bcdtoint(eit[22] & 0xff);
descriptor_id = eit[26];
- eit += 27;
+ eit += 27;
section_len -= 27;
/* run the descriptor loop for the length of section_len */
while (section_len > 1)
@@ -1550,23 +1559,23 @@ static void load_epg_data(dvb_input_plugin_t *this)
desc_len = getbits(eit, 0, 8);
- /* Let's get the EPG data only in the wanted language. */
+ /* Let's get the EPG data only in the wanted language. */
if (xine_config_lookup_entry(
- this->stream->xine,
+ this->stream->xine,
"media.dvd.language", &language) &&
- language.str_value && strlen(language.str_value) >= 2 &&
+ language.str_value && strlen(language.str_value) >= 2 &&
strncasecmp(language.str_value, &eit[1], 2)) {
-
+
#ifdef DEBUG_EPG
printf("input_dvb: EPG Skipping language: %C%C%C\n",
- eit[1],eit[2],eit[3]);
- printf("input_dvb: EPG language.str_value: %s\n",
+ eit[1],eit[2],eit[3]);
+ printf("input_dvb: EPG language.str_value: %s\n",
language.str_value);
-#endif
+#endif
break;
- }
+ }
/* program name */
name_len = (unsigned char)eit[4];
@@ -1575,20 +1584,20 @@ static void load_epg_data(dvb_input_plugin_t *this)
break;
}
- /* the first char of the string contains sometimes the character
+ /* the first char of the string contains sometimes the character
encoding information, which should not be copied to the
string. (FIXME - we ought to be using this byte to change charsets)*/
-
+
if (!isalnum(*(eit + 5)))
skip_byte = 1;
else
skip_byte = 0;
- memcpy(current_epg->progname, eit + 5 + skip_byte,
- name_len - skip_byte);
+ memcpy(current_epg->progname, eit + 5 + skip_byte,
+ name_len - skip_byte);
current_epg->progname[name_len - skip_byte] = '\0';
- /* detailed program information (max 256 chars)*/
+ /* detailed program information (max 256 chars)*/
text_len = (unsigned char)eit[5 + name_len];
if (text_len == 0) {
current_epg->description[0] = '\0';
@@ -1600,7 +1609,7 @@ static void load_epg_data(dvb_input_plugin_t *this)
else
skip_byte = 0;
- memcpy(current_epg->description, eit + 6 + name_len + skip_byte,
+ memcpy(current_epg->description, eit + 6 + name_len + skip_byte,
text_len - skip_byte);
current_epg->description[text_len - skip_byte] = '\0';
}
@@ -1616,7 +1625,7 @@ static void load_epg_data(dvb_input_plugin_t *this)
snprintf(current_epg->content, MAX_EPG_CONTENT_TYPE_LENGTH, "%s", content[content_bits]);
}
break;
- case 0x55: { /* Parental Rating descriptor describes minimum recommened age -3 */
+ case 0x55: { /* Parental Rating descriptor describes minimum recommened age -3 */
/* A rating value of 0 means that there is no rating defined. Ratings
greater than 0xF are "defined by broadcaster", which is not supported
@@ -1626,7 +1635,7 @@ static void load_epg_data(dvb_input_plugin_t *this)
else
current_epg->rating = 0;
}
- break;
+ break;
default:
break;
}
@@ -1635,41 +1644,42 @@ static void load_epg_data(dvb_input_plugin_t *this)
eit += getbits(eit, 0, 8);
descriptor_id = eit[1];
eit += 2;
- }
+ }
/* Store the entry if we got enough data. */
- if (current_epg->progname && strlen(current_epg->progname))
+ if (current_epg->progname && strlen(current_epg->progname))
current_channel->epg_count++;
}
}
/* Sort the EPG arrays by starttime. */
for (i = 0; i < this->num_channels; ++i) {
- if (!seen_channels[i])
+ if (!seen_channels[i])
continue;
- qsort(this->channels[i].epg, this->channels[i].epg_count,
+ qsort(this->channels[i].epg, this->channels[i].epg_count,
sizeof(epg_entry_t*), compare_epg_by_starttime);
}
free(seen_channels);
- free(foo);
+ free(foo);
pthread_mutex_unlock(&this->channel_change_mutex);
}
/* Prints text to an area, tries to cut the lines in between words. */
-static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, char* text,
- int x, int y, int row_space,
+static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, const char* text,
+ int x, int y, int row_space,
int max_x, int max_y, int* height, int color_base) {
/* The position of the text to be printed. */
- char* cursor = text;
+ const char* cursor = text;
+ const char *const text_end = text + strlen(text);
/* The line to be printed next. */
char text_line[512];
int text_width, text_height;
- int old_line_length, line_cursor;
- char* bound, *old_bound;
-
+ size_t old_line_length, line_cursor;
+ const char* bound, *old_bound;
+
*height = 0;
- while (cursor < text + strlen(text)) {
+ while (cursor < text_end) {
bound = cursor;
line_cursor = 0;
text_line[0] = '\0';
@@ -1681,12 +1691,12 @@ static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, char*
line_cursor = old_line_length;
/* Strip leading white space. */
- while (isspace(*bound))
+ while (isspace(*bound))
bound++;
-
+
/* Copy text to the text_line until end of word or end of string. */
while (!isspace(*bound) && *bound != '\0') {
- text_line[line_cursor] = *bound;
+ text_line[line_cursor] = *bound;
bound++;
line_cursor++;
}
@@ -1699,13 +1709,13 @@ static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, char*
if (x + text_width > max_x) {
/* It didn't fit, restore the old line and stop trying to fit more.*/
text_line[old_line_length] = '\0';
-
+
/* If no words did fit to the line, fit as many characters as possible in it. */
if (old_line_length == 0) {
text_width = 0;
bound = bound - line_cursor + 1; /* rewind to the beginning of the word */
line_cursor = 0;
- while (!isspace(*bound) &&
+ while (!isspace(*bound) &&
*bound != '\0') {
text_line[line_cursor++] = *bound++;
text_line[line_cursor] = '\0';
@@ -1724,10 +1734,10 @@ static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, char*
bound = old_bound;
break;
}
-
+
/* OK, it did fit, let's try to fit some more. */
- } while (bound < text + strlen(text));
-
+ } while (bound < text_end);
+
if (y + text_height + row_space > max_y) {
break;
}
@@ -1738,7 +1748,7 @@ static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, char*
}
}
-/* Finds the EPG of the ith next program. 0 means the current program, 1 next.
+/* Finds the EPG of the ith next program. 0 means the current program, 1 next.
If not found, returns NULL. All these functions expect the EPG entries
are sorted by starting time. */
static epg_entry_t* ith_next_epg(channel_t* channel, int count) {
@@ -1746,14 +1756,14 @@ static epg_entry_t* ith_next_epg(channel_t* channel, int count) {
int counter = 0;
/* Discard the entries of past programs. */
- while (counter + 1 < channel->epg_count &&
+ while (counter + 1 < channel->epg_count &&
difftime(channel->epg[counter + 1]->starttime, current_time) < 0.0)
counter++;
/* Check whether the previous program has still the running bit on,
and if it's not more late than the given margin, assume it's still
running. */
- if (counter >= 1 && channel->epg[counter - 1]->running &&
+ if (counter >= 1 && channel->epg[counter - 1]->running &&
difftime(current_time, channel->epg[counter]->starttime) < MAX_EPG_ENTRY_LATENESS) {
counter--;
}
@@ -1768,13 +1778,13 @@ static epg_entry_t* ith_next_epg(channel_t* channel, int count) {
ago. In that case do not return any EPG. This fixes the "very last
program of the day sticking until morning" bug. */
if (counter == channel->epg_count - 1) {
- if (difftime(current_time,
- channel->epg[counter]->starttime +
+ if (difftime(current_time,
+ channel->epg[counter]->starttime +
channel->epg[counter]->duration_hours*60*60 +
channel->epg[counter]->duration_minutes*60) > MAX_EPG_ENTRY_LATENESS) {
return NULL;
}
- }
+ }
return channel->epg[counter];
}
@@ -1785,7 +1795,7 @@ static epg_entry_t* current_epg(channel_t* channel) {
#ifdef DEBUG_EPG
if (next != NULL)
printf("input_dvb: EPG current: %s (%d)\n", next->progname, next->running);
-#endif
+#endif
return next;
}
@@ -1795,13 +1805,13 @@ static epg_entry_t* next_epg(channel_t* channel) {
#ifdef DEBUG_EPG
if (next != NULL)
printf("input_dvb: EPG next: %s (%d)\n", next->progname, next->running);
-#endif
+#endif
return next;
}
/* Displays the program info of an EPG entry in OSD.
-
+
x,y The upper left coordinates of the program information area.
max_x, max_y The maximum right coordinate of the program information area.
last_y The position of y after printing the entry.
@@ -1810,7 +1820,7 @@ static epg_entry_t* next_epg(channel_t* channel) {
Returns the height of the entry in the OSD in pixels.
*/
static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
- epg_entry_t* epg_data, osd_renderer_t* renderer,
+ epg_entry_t* epg_data, osd_renderer_t* renderer,
osd_object_t* osd) {
char* buffer;
int time_width, text_width, dummy;
@@ -1825,7 +1835,7 @@ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
if (epg_data == NULL || epg_data->progname == NULL)
return;
- buffer = xine_xmalloc(512);
+ buffer = calloc(1, 512);
_x_assert(buffer != NULL);
@@ -1842,15 +1852,14 @@ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
/*Content type and rating, if any. */
if (strlen(epg_data->content) > 3) {
-
- snprintf(buffer, 94, "%s", epg_data->content);
+ strncpy(buffer, epg_data->content, 94-1);
prog_rating = epg_data->rating;
if (prog_rating > 0) {
snprintf(buffer + strlen(buffer), 7, " (%i+)", prog_rating);
}
if (!renderer->set_font(osd, "sans", EPG_CONTENT_FONT_SIZE)) {
- print_error("Setting content type font failed.");
+ print_error("Setting content type font failed.");
}
renderer->get_text_size(osd, buffer, &content_width, &dummy);
renderer->render_text(osd, max_x - 2 - content_width, y, buffer, OSD_TEXT3);
@@ -1858,14 +1867,14 @@ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
text_width = max_x - x - time_width - content_width - 2;
- renderer->set_font(osd, "sans", EPG_TITLE_FONT_SIZE);
+ renderer->set_font(osd, "sans", EPG_TITLE_FONT_SIZE);
render_text_area(renderer, osd, epg_data->progname,
- x + time_width, y, EPG_PIXELS_BETWEEN_TEXT_ROWS,
- x + text_width + time_width, max_y, &text_height,
+ x + time_width, y, EPG_PIXELS_BETWEEN_TEXT_ROWS,
+ x + text_width + time_width, max_y, &text_height,
OSD_TEXT4);
- if (text_height == 0)
+ if (text_height == 0)
*last_y = y + time_height;
else
*last_y = y + text_height;
@@ -1873,7 +1882,7 @@ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
/* Print the description. */
if (epg_data->description && strlen(epg_data->description) > 0) {
renderer->set_font(osd, "sans", EPG_DESCRIPTION_FONT_SIZE);
- sprintf(buffer, "%s", epg_data->description);
+ strcpy(buffer, epg_data->description);
/* If the description is not complete (i.e., there is no comma at the end),
add "..." to the end. In my locale they often seem to send incomplete description
texts :( */
@@ -1884,15 +1893,15 @@ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y,
/* If duration_hours is zero, do not print them. */
if (epg_data->duration_hours > 0)
- sprintf(buffer + strlen(buffer), " (%dh%02dmin)",
+ sprintf(buffer + strlen(buffer), " (%dh%02dmin)",
epg_data->duration_hours, epg_data->duration_minutes);
else if (epg_data->duration_minutes > 0)
- sprintf(buffer + strlen(buffer), " (%dmin)",
+ sprintf(buffer + strlen(buffer), " (%dmin)",
epg_data->duration_minutes);
- render_text_area(renderer, osd, buffer, x + time_width,
- *last_y + EPG_PIXELS_BETWEEN_TEXT_ROWS,
- EPG_PIXELS_BETWEEN_TEXT_ROWS,
+ render_text_area(renderer, osd, buffer, x + time_width,
+ *last_y + EPG_PIXELS_BETWEEN_TEXT_ROWS,
+ EPG_PIXELS_BETWEEN_TEXT_ROWS,
max_x, max_y, &text_height, OSD_TEXT3);
*last_y += EPG_PIXELS_BETWEEN_TEXT_ROWS + text_height;
@@ -1914,7 +1923,7 @@ static void show_eit(dvb_input_plugin_t *this) {
if (!this->epg_displaying) {
#ifndef EPG_UPDATE_IN_BACKGROUND
- if (current_epg(&this->channels[this->channel]) == NULL ||
+ if (current_epg(&this->channels[this->channel]) == NULL ||
next_epg(&this->channels[this->channel]) == NULL) {
load_epg_data(this);
}
@@ -1924,12 +1933,12 @@ static void show_eit(dvb_input_plugin_t *this) {
this->stream->osd_renderer->hide(this->proginfo_osd, 0);
this->stream->osd_renderer->clear(this->proginfo_osd);
- /* Channel Name */
+ /* Channel Name */
if (!this->stream->osd_renderer->set_font(
this->proginfo_osd, "sans", EPG_CHANNEL_FONT_SIZE)) {
print_error("Error setting channel name font.");
}
-
+
this->stream->osd_renderer->render_text(
this->proginfo_osd, 0, 0, this->channels[this->channel].name, OSD_TEXT4);
@@ -1947,11 +1956,11 @@ static void show_eit(dvb_input_plugin_t *this) {
this->proginfo_osd, this->channels[this->channel].name, &temp1, &temp2);
this->stream->osd_renderer->render_text(
- this->proginfo_osd, EPG_WIDTH - 45,
+ this->proginfo_osd, EPG_WIDTH - 45,
EPG_CHANNEL_FONT_SIZE - EPG_CLOCK_FONT_SIZE, clock, OSD_TEXT4);
-
+
show_program_info(0, EPG_CHANNEL_FONT_SIZE + 2, EPG_WIDTH, EPG_HEIGHT, &y_pos,
- current_epg(&this->channels[this->channel]),
+ current_epg(&this->channels[this->channel]),
this->stream->osd_renderer,
this->proginfo_osd);
y = y_pos;
@@ -1962,11 +1971,11 @@ static void show_eit(dvb_input_plugin_t *this) {
this->proginfo_osd);
y = y_pos;
- window_width =
+ window_width =
this->stream->video_out->get_property(
this->stream->video_out, VO_PROP_WINDOW_WIDTH);
- window_height =
+ window_height =
this->stream->video_out->get_property(
this->stream->video_out, VO_PROP_WINDOW_HEIGHT);
@@ -1983,8 +1992,8 @@ static void show_eit(dvb_input_plugin_t *this) {
this->stream->osd_renderer->set_text_palette(
this->background, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT3);
this->stream->osd_renderer->filled_rect(
- this->background, 0, 0,
- EPG_WIDTH + EPG_BACKGROUND_MARGIN*2,
+ this->background, 0, 0,
+ EPG_WIDTH + EPG_BACKGROUND_MARGIN*2,
y + EPG_BACKGROUND_MARGIN*2, 4);
/* In case video is downscaled and the EPG fits, show it unscaled to make it
@@ -1998,8 +2007,8 @@ static void show_eit(dvb_input_plugin_t *this) {
centered_y = (centered_y > 0)?(centered_y):(EPG_TOP);
this->stream->osd_renderer->set_position(
- this->proginfo_osd,
- centered_x + EPG_BACKGROUND_MARGIN,
+ this->proginfo_osd,
+ centered_x + EPG_BACKGROUND_MARGIN,
centered_y + EPG_BACKGROUND_MARGIN);
this->stream->osd_renderer->set_position(this->background, centered_x, centered_y);
@@ -2015,15 +2024,15 @@ static void show_eit(dvb_input_plugin_t *this) {
/* Center the OSD to stream. */
this->stream->osd_renderer->set_position(
- this->proginfo_osd,
- centered_x + EPG_BACKGROUND_MARGIN,
+ this->proginfo_osd,
+ centered_x + EPG_BACKGROUND_MARGIN,
centered_y + EPG_BACKGROUND_MARGIN);
this->stream->osd_renderer->set_position(this->background, centered_x, centered_y);
this->stream->osd_renderer->show(this->background, 0);
this->stream->osd_renderer->show(this->proginfo_osd, 0);
}
-
+
} else {
this->epg_displaying = 0;
this->stream->osd_renderer->hide (this->proginfo_osd,0);
@@ -2053,7 +2062,7 @@ static int tuner_set_channel (dvb_input_plugin_t *this, channel_t *c) {
if (lastchannel.num_value){
/* Remember last watched channel. never show this entry*/
config->update_num(config, "media.dvb.last_channel", this->channel+1);
- }
+ }
#ifdef DVB_NO_BUFFERING
this->newchannel=1;
#endif
@@ -2083,14 +2092,14 @@ static void osd_show_channel (dvb_input_plugin_t *this, int channel) {
this->channel_osd, 110, 10+i*35,
this->channels[channel_to_print].name,
(channel_to_print == channel)?(OSD_TEXT4):(OSD_TEXT3));
-
+
if ((current_program = current_epg(&this->channels[channel_to_print])) &&
current_program->progname && strlen(current_program->progname) > 0) {
this->stream->osd_renderer->set_font(this->channel_osd, "sans", 16);
render_text_area(this->stream->osd_renderer, this->channel_osd,
- current_program->progname, 400, 10+i*35,
+ current_program->progname, 400, 10+i*35,
-5, CHSEL_WIDTH, 10+i*35+CHSEL_CHANNEL_FONT_SIZE+2,
&temp, (channel_to_print == channel)?(OSD_TEXT4):(OSD_TEXT3));
}
@@ -2113,19 +2122,19 @@ static void osd_show_channel (dvb_input_plugin_t *this, int channel) {
}
static int switch_channel(dvb_input_plugin_t *this, int channel) {
-
+
int x;
xine_event_t event;
xine_pids_data_t data;
xine_ui_data_t ui_data;
-
- /* control_nop appears to stop an occasional (quite long) pause between
+
+ /* control_nop appears to stop an occasional (quite long) pause between
channel-changes, which the user may see as a lockup. */
_x_demux_control_nop(this->stream, BUF_FLAG_END_STREAM);
- _x_demux_flush_engine(this->stream);
+ _x_demux_flush_engine(this->stream);
pthread_mutex_lock (&this->channel_change_mutex);
-
+
close (this->fd);
this->tuned_in = 0;
@@ -2133,9 +2142,9 @@ static int switch_channel(dvb_input_plugin_t *this, int channel) {
close(this->tuner->fd_pidfilter[x]);
this->tuner->fd_pidfilter[x] = open(this->tuner->demux_device, O_RDWR);
}
-
+
if (!tuner_set_channel (this, &this->channels[channel])) {
- xprintf (this->class->xine, XINE_VERBOSITY_LOG,
+ xprintf (this->class->xine, XINE_VERBOSITY_LOG,
_("input_dvb: tuner_set_channel failed\n"));
pthread_mutex_unlock (&this->channel_change_mutex);
return 0;
@@ -2169,7 +2178,7 @@ static int switch_channel(dvb_input_plugin_t *this, int channel) {
this->tuned_in = 1;
pthread_mutex_unlock (&this->channel_change_mutex);
-
+
/* now read the pat, find all accociated PIDs and add them to the stream */
dvb_parse_si(this);
@@ -2181,7 +2190,7 @@ static int switch_channel(dvb_input_plugin_t *this, int channel) {
/* show eit for this channel if necessary */
if (this->epg_displaying==1){
- this->epg_displaying=0;
+ this->epg_displaying=0;
show_eit(this);
}
return 1;
@@ -2190,7 +2199,7 @@ static int switch_channel(dvb_input_plugin_t *this, int channel) {
static void do_record (dvb_input_plugin_t *this) {
struct tm *tma;
- time_t *t;
+ time_t *t;
char filename [256];
char dates[64];
int x=0;
@@ -2207,7 +2216,7 @@ static void do_record (dvb_input_plugin_t *this) {
this->stream->osd_renderer->hide (this->paused_osd, 0);
this->record_paused=0;
} else {
- t=xine_xmalloc(sizeof(time_t));
+ t=calloc(1, sizeof(time_t));
_x_assert(t != NULL);
@@ -2216,7 +2225,7 @@ static void do_record (dvb_input_plugin_t *this) {
free(t);
t = NULL;
strftime(dates,63,"%Y-%m-%d_%H%M",tma);
-
+
if (xine_config_lookup_entry(this->stream->xine, "media.capture.save_dir", &savedir)){
if(strlen(savedir.str_value)>1){
if((dir = opendir(savedir.str_value))==NULL){
@@ -2242,7 +2251,7 @@ static void do_record (dvb_input_plugin_t *this) {
this->record_fd = open (filename, O_CREAT | O_APPEND | O_WRONLY, 0644);
this->stream->osd_renderer->clear (this->rec_osd);
-
+
this->stream->osd_renderer->render_text (this->rec_osd, 10, 10, "Recording to:",
OSD_TEXT3);
@@ -2258,7 +2267,7 @@ static void dvb_event_handler (dvb_input_plugin_t *this) {
xine_event_t *event;
static int channel_menu_visible = 0;
- static int next_channel = -1;
+ static int next_channel = -1;
while ((event = xine_event_get (this->event_queue))) {
@@ -2284,7 +2293,7 @@ static void dvb_event_handler (dvb_input_plugin_t *this) {
}
else
this->stream->osd_renderer->hide(this->channel_osd, 0);
- }
+ }
#ifdef LEFT_MOUSE_DOES_EPG
else { /* show EPG on left click of videowindow */
show_eit(this);
@@ -2443,27 +2452,27 @@ static void dvb_event_handler (dvb_input_plugin_t *this) {
static void ts_rewrite_packets (dvb_input_plugin_t *this, unsigned char * originalPkt, int len) {
#define PKT_SIZE 188
-#define BODY_SIZE (188-4)
+#define BODY_SIZE (188-4)
unsigned int sync_byte;
unsigned int data_offset;
unsigned int data_len;
- unsigned int pid;
+ unsigned int pid;
while(len>0){
-
+
sync_byte = originalPkt[0];
pid = ((originalPkt[1] << 8) | originalPkt[2]) & 0x1fff;
-
+
/*
* Discard packets that are obviously bad.
*/
data_offset = 4;
originalPkt+=data_offset;
-
+
if (pid == 0 && sync_byte==0x47) {
unsigned long crc;
-
+
originalPkt[3]=13; /* section length including CRC - first 3 bytes */
originalPkt[2]=0x80;
originalPkt[7]=0; /* section number */
@@ -2474,13 +2483,13 @@ static void ts_rewrite_packets (dvb_input_plugin_t *this, unsigned char * origin
originalPkt[12]=this->channels[this->channel].pmtpid & 0xff;
crc= ts_compute_crc32 (this, originalPkt+1, 12, 0xffffffff);
-
+
originalPkt[13]=(crc>>24) & 0xff;
originalPkt[14]=(crc>>16) & 0xff;
originalPkt[15]=(crc>>8) & 0xff;
originalPkt[16]=crc & 0xff;
memset(originalPkt+17,0xFF,PKT_SIZE-21); /* stuff the remainder */
-
+
}
data_len = PKT_SIZE - data_offset;
@@ -2499,44 +2508,42 @@ static off_t dvb_plugin_read (input_plugin_t *this_gen,
if (!this->tuned_in)
return 0;
- dvb_event_handler (this);
+ if (this->dvb_gui_enabled)
+ dvb_event_handler (this);
#ifdef LOG_READS
xprintf(this->class->xine,XINE_VERBOSITY_DEBUG,
"input_dvb: reading %" PRIdMAX " bytes...\n", (intmax_t)len);
#endif
-#ifndef DVB_NO_BUFFERING
- nbc_check_buffers (this->nbc);
-#endif
/* protect against channel changes */
have_mutex = pthread_mutex_lock(&this->channel_change_mutex);
total=0;
-
- while (total<len){
+
+ while (total<len){
pfd.fd = this->fd;
pfd.events = POLLPRI | POLLIN | POLLERR;
pfd.revents = 0;
-
+
if (!this->tuned_in) {
pthread_mutex_unlock( &this->channel_change_mutex );
xprintf(this->class->xine, XINE_VERBOSITY_LOG,
"input_dvb: Channel \"%s\" could not be tuned in. "
"Possibly erroneus settings in channels.conf "
- "(frequency changed?).\n",
+ "(frequency changed?).\n",
this->channels[this->channel].name);
return 0;
}
-
- if (poll(&pfd, 1, 1500) < 1) {
+
+ if (poll(&pfd, 1, 1500) < 1) {
xprintf(this->class->xine, XINE_VERBOSITY_LOG,
"input_dvb: No data available. Signal Lost?? \n");
- _x_demux_control_end(this->stream, BUF_FLAG_END_USER);
+ _x_demux_control_end(this->stream, BUF_FLAG_END_USER);
this->read_failcount++;
break;
}
- if (this->read_failcount) {
- /* signal/stream regained after loss -
+ if (this->read_failcount) {
+ /* signal/stream regained after loss -
kick the net_buf_control layer. */
this->read_failcount=0;
xprintf(this->class->xine,XINE_VERBOSITY_LOG,
@@ -2546,22 +2553,22 @@ static off_t dvb_plugin_read (input_plugin_t *this_gen,
if (pfd.revents & POLLPRI || pfd.revents & POLLIN) {
n = read (this->fd, &buf[total], len-total);
- } else
+ } else
if (pfd.revents & POLLERR) {
xprintf(this->class->xine, XINE_VERBOSITY_LOG,
"input_dvb: No data available. Signal Lost?? \n");
- _x_demux_control_end(this->stream, BUF_FLAG_END_USER);
+ _x_demux_control_end(this->stream, BUF_FLAG_END_USER);
this->read_failcount++;
break;
- }
+ }
#ifdef LOG_READS
xprintf(this->class->xine,XINE_VERBOSITY_DEBUG,
- "input_dvb: got %" PRIdMAX " bytes (%" PRIdMAX "/%" PRIdMAX " bytes read)\n",
+ "input_dvb: got %" PRIdMAX " bytes (%" PRIdMAX "/%" PRIdMAX " bytes read)\n",
(intmax_t)n, (intmax_t)total, (intmax_t)len);
#endif
-
- if (n > 0){
+
+ if (n > 0){
this->curpos += n;
total += n;
} else if (n < 0 && errno!=EAGAIN) {
@@ -2578,7 +2585,7 @@ static off_t dvb_plugin_read (input_plugin_t *this_gen,
/* no data for several seconds - tell the user a possible reason */
if(this->read_failcount==5){
- _x_message(this->stream,1,"DVB Signal Lost. Please check connections.", NULL);
+ _x_message(this->stream,1,"DVB Signal Lost. Please check connections.", NULL);
}
#ifdef DVB_NO_BUFFERING
if(this->newchannel){
@@ -2595,6 +2602,12 @@ static buf_element_t *dvb_plugin_read_block (input_plugin_t *this_gen,
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
int total_bytes;
+ 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;
@@ -2660,7 +2673,7 @@ static void dvb_plugin_dispose (input_plugin_t *this_gen) {
}
if (this->nbc) {
- nbc_close (this->nbc);
+ nbc_close (this->nbc);
this->nbc = NULL;
}
@@ -2764,7 +2777,12 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
xine_cfg_entry_t zoomdvb;
xine_cfg_entry_t adapter;
xine_cfg_entry_t lastchannel;
-
+ xine_cfg_entry_t gui_enabled;
+
+ xine_config_lookup_entry(this->stream->xine, "media.dvb.gui_enabled", &gui_enabled);
+ this->dvb_gui_enabled = gui_enabled.num_value;
+ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("input_dvb: DVB GUI %s\n"), this->dvb_gui_enabled ? "enabled" : "disabled");
+
xine_config_lookup_entry(this->stream->xine, "media.dvb.adapter", &adapter);
if (!(tuner = tuner_init(this->class->xine,adapter.num_value))) {
@@ -2780,7 +2798,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
* and assume that its format is valid for our tuner type
*/
- if (!(channels = load_channels(this->class->xine, this->stream, &num_channels, tuner->feinfo.type)))
+ if (!(channels = load_channels(this->class->xine, this->stream, &num_channels, tuner->feinfo.type)))
{
/* failed to load the channels */
tuner_dispose(tuner);
@@ -2816,13 +2834,13 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
} else {
/*
* try a partial match too
- * be smart and compare starting from the first char, then from
+ * be smart and compare starting from the first char, then from
* the second etc..
* Yes, this is expensive, but it happens really often
* that the channels have really ugly names, sometimes prefixed
* by numbers...
*/
- int chanlen = strlen(channame);
+ size_t chanlen = strlen(channame);
int offset = 0;
xprintf(this->class->xine, XINE_VERBOSITY_LOG,
@@ -2834,7 +2852,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
if (strlen(channels[idx].name) > offset) {
if (strncasecmp(channels[idx].name + offset, channame, chanlen) == 0) {
xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("input_dvb: found matching channel %s\n"), channels[idx].name);
- break;
+ break;
}
}
idx++;
@@ -2857,6 +2875,8 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
if (lastchannel.num_value) {
if (xine_config_lookup_entry(this->class->xine, "media.dvb.last_channel", &lastchannel)){
this->channel = lastchannel.num_value -1;
+ if (this->channel < 0 || this->channel >= num_channels)
+ this->channel = 0; /* out of range? default */
}else{
xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("input_dvb: invalid channel specification, defaulting to channel 0\n"));
this->channel = 0;
@@ -2876,7 +2896,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
}
ptr = this->mrl;
ptr += 7;
- channels = xine_xmalloc(sizeof(channel_t));
+ channels = calloc(1, sizeof(channel_t));
_x_assert(channels != NULL);
if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0) {
free(channels);
@@ -2896,7 +2916,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
}
ptr = this->mrl;
ptr += 7;
- channels = xine_xmalloc(sizeof(channel_t));
+ channels = calloc(1, sizeof(channel_t));
_x_assert(channels != NULL);
if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0) {
free(channels);
@@ -2905,12 +2925,12 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
return 0;
}
this->channel = 0;
- } else if (strncasecmp(this->mrl, "dvbc://", 7) == 0)
+ } else if (strncasecmp(this->mrl, "dvbc://", 7) == 0)
{
/*
* This is dvbc://<channel name>:<qam tuning parameters>
*/
- if (tuner->feinfo.type != FE_QAM)
+ if (tuner->feinfo.type != FE_QAM)
{
xprintf(this->class->xine, XINE_VERBOSITY_LOG,
_("input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-C)\n"));
@@ -2919,7 +2939,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
}
ptr = this->mrl;
ptr += 7;
- channels = xine_xmalloc(sizeof(channel_t));
+ channels = calloc(1, sizeof(channel_t));
_x_assert(channels != NULL);
if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0)
{
@@ -2929,15 +2949,15 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
return 0;
}
this->channel = 0;
- } else if (strncasecmp(this->mrl, "dvba://", 7) == 0)
+ } else if (strncasecmp(this->mrl, "dvba://", 7) == 0)
{
- fprintf(stderr,"input_dvb: 2a %x\n",tuner->feinfo.type);
+ fprintf(stderr,"input_dvb: 2a %x\n",tuner->feinfo.type);
/*
* This is dvba://<channel name>:<atsc tuning parameters>
*/
- if (tuner->feinfo.type != FE_ATSC)
+ if (tuner->feinfo.type != FE_ATSC)
{
- fprintf(stderr,"input_dvb: FAILED 1\n");
+ fprintf(stderr,"input_dvb: FAILED 1\n");
xprintf(this->class->xine, XINE_VERBOSITY_LOG,
_("input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-A)\n"));
tuner_dispose(tuner);
@@ -2945,11 +2965,11 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
}
ptr = this->mrl;
ptr += 7;
- channels = xine_xmalloc(sizeof(channel_t));
+ channels = calloc(1, sizeof(channel_t));
_x_assert(channels != NULL);
if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0)
{
- fprintf(stderr,"input_dvb: FAILED 2\n");
+ fprintf(stderr,"input_dvb: FAILED 2\n");
free(channels);
channels = NULL;
tuner_dispose(tuner);
@@ -2965,7 +2985,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
this->tuner = tuner;
this->channels = channels;
this->num_channels = num_channels;
-
+
if (!tuner_set_channel(this, &this->channels[this->channel])) {
xprintf(this->class->xine, XINE_VERBOSITY_LOG,
_("input_dvb: tuner_set_channel failed\n"));
@@ -2978,7 +2998,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
return 0;
}
this->tuned_in = 1;
-
+
/* now read the pat, find all accociated PIDs and add them to the stream */
dvb_parse_si(this);
@@ -2990,16 +3010,17 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
this->event_queue = xine_event_new_queue(this->stream);
#ifdef EPG_UPDATE_IN_BACKGROUND
- /* Start the EPG updater thread. */
- this->epg_updater_stop = 0;
- if (pthread_create(&this->epg_updater_thread, NULL,
- epg_data_updater, this) != 0) {
- xprintf(
- this->class->xine, XINE_VERBOSITY_LOG,
- _("input_dvb: cannot create EPG updater thread\n"));
- return 0;
-
- }
+ if (this->dvb_gui_enabled) {
+ /* Start the EPG updater thread. */
+ this->epg_updater_stop = 0;
+ if (pthread_create(&this->epg_updater_thread, NULL,
+ epg_data_updater, this) != 0) {
+ xprintf(
+ this->class->xine, XINE_VERBOSITY_LOG,
+ _("input_dvb: cannot create EPG updater thread\n"));
+ return 0;
+ }
+ }
#endif
/*
* this osd is used to draw the "recording" sign
@@ -3018,8 +3039,8 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
this->stream->osd_renderer->set_position(this->channel_osd, 20, 10);
this->stream->osd_renderer->set_encoding(this->channel_osd, NULL);
- /*
- * this osd is for displaying currently shown channel name
+ /*
+ * this osd is for displaying currently shown channel name
*/
this->name_osd = this->stream->osd_renderer->new_object(this->stream->osd_renderer, 301, 61);
this->stream->osd_renderer->set_position(this->name_osd, 20, 10);
@@ -3027,8 +3048,8 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
this->stream->osd_renderer->set_encoding(this->name_osd, NULL);
this->stream->osd_renderer->set_text_palette(this->name_osd, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT3);
- /*
- * this osd is for displaying Recording Paused
+ /*
+ * this osd is for displaying Recording Paused
*/
this->paused_osd = this->stream->osd_renderer->new_object(this->stream->osd_renderer, 301, 161);
this->stream->osd_renderer->set_position(this->paused_osd, 10, 50);
@@ -3036,10 +3057,10 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
this->stream->osd_renderer->set_encoding(this->paused_osd, NULL);
this->stream->osd_renderer->set_text_palette(this->paused_osd, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT3);
- /*
+ /*
* This osd is for displaying Program Information (EIT), i.e., EPG.
*/
- this->proginfo_osd =
+ this->proginfo_osd =
this->stream->osd_renderer->new_object(
this->stream->osd_renderer, EPG_WIDTH, EPG_HEIGHT);
@@ -3048,10 +3069,10 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
this->stream->osd_renderer->set_text_palette(this->proginfo_osd, XINE_TEXTPALETTE_WHITE_NONE_TRANSLUCID, OSD_TEXT3);
this->stream->osd_renderer->set_text_palette(this->proginfo_osd, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT4);
- this->background =
+ this->background =
this->stream->osd_renderer->new_object(
- this->stream->osd_renderer,
- EPG_WIDTH + EPG_BACKGROUND_MARGIN*2,
+ this->stream->osd_renderer,
+ EPG_WIDTH + EPG_BACKGROUND_MARGIN*2,
EPG_HEIGHT + EPG_BACKGROUND_MARGIN*2);
this->epg_displaying = 0;
@@ -3085,7 +3106,7 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
/* Clear all pids, the pmt will tell us which to use */
for (x = 0; x < MAX_FILTERS; x++){
this->channels[this->channel].pid[x] = DVB_NOPID;
- }
+ }
return 1;
@@ -3109,7 +3130,7 @@ static input_plugin_t *dvb_class_get_instance (input_class_t *class_gen,
fprintf(stderr, "input_dvb: continuing in get_instance\n");
- this = (dvb_input_plugin_t *) xine_xmalloc (sizeof(dvb_input_plugin_t));
+ this = calloc(1, sizeof(dvb_input_plugin_t));
_x_assert(this != NULL);
@@ -3121,16 +3142,16 @@ static input_plugin_t *dvb_class_get_instance (input_class_t *class_gen,
this->fd = -1;
this->tuned_in = 0;
#ifndef DVB_NO_BUFFERING
- this->nbc = nbc_init (this->stream);
+ this->nbc = nbc_init (this->stream);
#else
- this->nbc = NULL;
+ this->nbc = NULL;
#endif
this->osd = NULL;
this->event_queue = NULL;
this->record_fd = -1;
this->read_failcount = 0;
this->epg_updater_stop = 0;
-
+
this->input_plugin.open = dvb_plugin_open;
this->input_plugin.get_capabilities = dvb_plugin_get_capabilities;
this->input_plugin.read = dvb_plugin_read;
@@ -3164,7 +3185,9 @@ static void dvb_class_dispose(input_class_t * this_gen)
{
dvb_input_class_t *class = (dvb_input_class_t *) this_gen;
int x;
-
+
+ free(class->default_channels_conf_filename);
+
for(x=0;x<class->numchannels;x++)
free(class->autoplaylist[x]);
@@ -3181,7 +3204,6 @@ 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 = 0;
int default_channel = -1;
xine_cfg_entry_t lastchannel_enable = {0};
@@ -3211,7 +3233,7 @@ static char **dvb_class_get_autoplay_list(input_class_t * this_gen,
tuner_dispose(tuner);
return class->mrls;
}
-
+
tuner_dispose(tuner);
if (xine_config_lookup_entry(class->xine, "media.dvb.remember_channel", &lastchannel_enable)
@@ -3226,21 +3248,19 @@ static char **dvb_class_get_autoplay_list(input_class_t * this_gen,
for (ch = 0, apch = !!lastchannel_enable.num_value;
ch < num_channels && ch < MAX_AUTOCHANNELS;
++ch, ++apch) {
- snprintf(foobuffer, BUFSIZE, "dvb://%s", channels[ch].name);
- free(class->autoplaylist[apch]);
- class->autoplaylist[apch] = strdup(foobuffer);
- _x_assert(class->autoplaylist[apch] != NULL);
+ free(class->autoplaylist[apch]);
+ asprintf(&(class->autoplaylist[apch]), "dvb://%s", channels[ch].name);
+ _x_assert(class->autoplaylist[apch] != NULL);
}
if (lastchannel_enable.num_value){
+ free(class->autoplaylist[0]);
if (default_channel != -1)
/* plugin has been used before - channel is valid */
- sprintf (foobuffer, "dvb://%s", channels[default_channel].name);
+ asprintf (&(class->autoplaylist[0]), "dvb://%s", channels[default_channel].name);
else
/* set a reasonable default - the first channel */
- sprintf (foobuffer, "dvb://%s", num_channels ? channels[0].name : "0");
- free(class->autoplaylist[0]);
- class->autoplaylist[0]=strdup(foobuffer);
+ asprintf (&(class->autoplaylist[0]), "dvb://%s", num_channels ? channels[0].name : "0");
}
free_channel_list(channels, num_channels);
@@ -3256,7 +3276,7 @@ static void *init_class (xine_t *xine, void *data) {
dvb_input_class_t *this;
config_values_t *config = xine->config;
- this = (dvb_input_class_t *) xine_xmalloc (sizeof (dvb_input_class_t));
+ this = calloc(1, sizeof (dvb_input_class_t));
_x_assert(this != NULL);
this->xine = xine;
@@ -3276,6 +3296,10 @@ static void *init_class (xine_t *xine, void *data) {
this->mrls[4] = "dvba://";
this->mrls[5] = 0;
+ asprintf(&this->default_channels_conf_filename,
+ "%s/.xine/channels.conf",
+ xine_get_homedir());
+
xprintf(this->xine,XINE_VERBOSITY_DEBUG,"init class succeeded\n");
/* Enable remembering of last watched channel */
@@ -3307,8 +3331,20 @@ static void *init_class (xine_t *xine, void *data) {
"really have more than 1 card "
"in your system."),
0, NULL, (void *) this);
-
+ /* set to 0 to turn off the GUI built into this input plugin */
+ config->register_bool(config, "media.dvb.gui_enabled",
+ 1,
+ _("Enable the DVB GUI"),
+ _("Enable the DVB GUI, mouse controlled recording and channel switching."),
+ 21, NULL, NULL);
+ /* Override the default channels file */
+ config->register_filename(config, "media.dvb.channels_conf",
+ this->default_channels_conf_filename,
+ XINE_CONFIG_STRING_IS_FILENAME,
+ _("DVB Channels config file"),
+ _("DVB Channels config file to use instead of the ~/.xine/channels.conf file."),
+ 21, NULL, NULL);
return this;
}
diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c
index a891b9877..400f82aca 100644
--- a/src/input/input_dvd.c
+++ b/src/input/input_dvd.c
@@ -1,26 +1,26 @@
-/*
- * Copyright (C) 2000-2005 the xine project,
+/*
+ * Copyright (C) 2000-2005 the xine project,
* Rich Wareham <richwareham@users.sourceforge.net>
- *
+ *
* 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
*/
/* This file was origninally part of the xine-dvdnav project
- * at http://dvd.sf.net/.
+ * at http://dvd.sf.net/.
*/
/* TODO:
@@ -53,7 +53,9 @@
#include <dlfcn.h>
#ifndef WIN32
+#if ! defined(__GNU__)
#include <sys/mount.h>
+#endif
#include <sys/wait.h>
#include <sys/poll.h>
@@ -115,10 +117,13 @@
/* There really isn't a default on Windows! */
#define DVD_PATH "d:\\"
#define RDVD_PATH "d:\\"
+#elif defined(__OpenBSD__)
+#define DVD_PATH "/dev/rcd0c"
+#define RDVD_PATH "/dev/rcd0c"
#else
#define DVD_PATH "/dev/dvd"
#define RDVD_PATH "/dev/rdvd"
-#endif
+#endif
/* Some misc. defines */
#ifdef DVD_VIDEO_LB_LEN
@@ -148,7 +153,7 @@
/* Array to hold MRLs returned by get_autoplay_list */
#define MAX_DIR_ENTRIES 1250
-#define MAX_STR_LEN 255
+#define MAX_STR_LEN 255
#if defined (__FreeBSD__)
# define off64_t off_t
@@ -171,7 +176,7 @@ typedef struct {
xine_stream_t *stream;
xine_event_queue_t *event_queue;
-
+
int pause_timer; /* Cell still-time timer */
int pause_counter;
time_t pause_end_time;
@@ -181,7 +186,7 @@ typedef struct {
int64_t pg_start;
int32_t buttonN;
int typed_buttonN;/* for XINE_EVENT_INPUT_NUMBER_* */
-
+
int32_t mouse_buttonN;
int mouse_in;
@@ -190,13 +195,13 @@ typedef struct {
int seekable; /* are we seekable? */
int mode; /* MODE_NAVIGATE / MODE_TITLE */
int tt, pr; /* title / chapter */
-
+
/* xine specific variables */
const char *current_dvd_device; /* DVD device currently open */
char *mrl; /* Current MRL */
dvdnav_t *dvdnav; /* Handle for libdvdnav */
const char *dvd_name;
-
+
/* special buffer handling for libdvdnav caching */
pthread_mutex_t buf_mutex;
void *source;
@@ -235,16 +240,16 @@ static void xine_dvd_send_button_update(dvd_input_plugin_t *this, int mode);
/* Callback on device name change */
static void device_change_cb(void *data, xine_cfg_entry_t *cfg) {
dvd_input_class_t *class = (dvd_input_class_t *) data;
-
+
class->dvd_device = cfg->str_value;
}
static uint32_t dvd_plugin_get_capabilities (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
-
+
trace_print("Called\n");
- return INPUT_CAP_BLOCK |
+ return INPUT_CAP_BLOCK |
/* TODO: figure out if there is any "allow copying" flag on DVD.
* maybe set INPUT_CAP_RIP_FORBIDDEN only for encrypted media?
*/
@@ -252,7 +257,7 @@ static uint32_t dvd_plugin_get_capabilities (input_plugin_t *this_gen) {
#if CAN_SEEK
(this->seekable ? INPUT_CAP_SEEKABLE : 0) |
#endif
- INPUT_CAP_AUDIOLANG | INPUT_CAP_SPULANG | INPUT_CAP_CHAPTERS;
+ INPUT_CAP_AUDIOLANG | INPUT_CAP_SPULANG | INPUT_CAP_CHAPTERS;
}
static void read_ahead_cb(void *this_gen, xine_cfg_entry_t *entry) {
@@ -269,7 +274,7 @@ static void read_ahead_cb(void *this_gen, xine_cfg_entry_t *entry) {
dvdnav_set_readahead_flag(this->dvdnav, entry->num_value);
}
}
-
+
static void seek_mode_cb(void *this_gen, xine_cfg_entry_t *entry) {
dvd_input_class_t *class = (dvd_input_class_t*)this_gen;
@@ -284,7 +289,7 @@ static void seek_mode_cb(void *this_gen, xine_cfg_entry_t *entry) {
dvdnav_set_PGC_positioning_flag(this->dvdnav, !entry->num_value);
}
}
-
+
static void region_changed_cb (void *this_gen, xine_cfg_entry_t *entry) {
dvd_input_class_t *class = (dvd_input_class_t*)this_gen;
@@ -307,10 +312,10 @@ static void language_changed_cb(void *this_gen, xine_cfg_entry_t *entry) {
return;
class->language = entry->str_value[0] << 8 | entry->str_value[1];
-
+
if(class->ip) {
dvd_input_plugin_t *this = class->ip;
-
+
dvdnav_menu_language_select(this->dvdnav, entry->str_value);
dvdnav_audio_language_select(this->dvdnav, entry->str_value);
dvdnav_spu_language_select(this->dvdnav, entry->str_value);
@@ -337,29 +342,32 @@ static void send_mouse_enter_leave_event(dvd_input_plugin_t *this, int direction
spu_event.direction = direction;
spu_event.button = this->mouse_buttonN;
-
+
event.type = XINE_EVENT_SPU_BUTTON;
event.stream = this->stream;
event.data = &spu_event;
event.data_length = sizeof(spu_event);
xine_event_send(this->stream, &event);
-
+
this->mouse_in = direction;
}
if(!direction)
this->mouse_buttonN = -1;
}
-
+
static int update_title_display(dvd_input_plugin_t *this) {
- char ui_title[MAX_STR_LEN + 1];
- xine_event_t uevent;
xine_ui_data_t data;
+ xine_event_t uevent = {
+ .type = XINE_EVENT_UI_SET_TITLE,
+ .stream = this->stream,
+ .data = &data,
+ .data_length = sizeof(data)
+ };
int tt=-1, pr=-1;
- size_t ui_str_length=0;
int num_tt = 0;
- if(!this || !(this->stream))
+ if(!this || !(this->stream))
return 0;
/* Set title/chapter display */
@@ -377,24 +385,24 @@ static int update_title_display(dvd_input_plugin_t *this) {
dvdnav_get_number_of_titles(this->dvdnav, &num_tt );
-
- if(tt >= 1) {
+
+ if(tt >= 1) {
int num_angle = 0, cur_angle = 0;
int num_part = 0;
- /* no menu here */
+ /* no menu here */
/* Reflect angle info if appropriate */
dvdnav_get_number_of_parts(this->dvdnav, tt, &num_part);
dvdnav_get_angle_info(this->dvdnav, &cur_angle, &num_angle);
if(num_angle > 1) {
- snprintf(ui_title, MAX_STR_LEN,
- "Title %i, Chapter %i, Angle %i of %i",
- tt,pr,cur_angle, num_angle);
+ data.str_len = snprintf(data.str, sizeof(data.str),
+ "Title %i, Chapter %i, Angle %i of %i",
+ tt,pr,cur_angle, num_angle);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,cur_angle);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,num_angle);
} else {
- snprintf(ui_title, MAX_STR_LEN,
- "Title %i, Chapter %i",
- tt,pr);
+ data.str_len = snprintf(data.str, sizeof(data.str),
+ "Title %i, Chapter %i",
+ tt,pr);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0);
}
@@ -403,9 +411,9 @@ static int update_title_display(dvd_input_plugin_t *this) {
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,pr);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_COUNT,num_part);
} else if (tt == 0 && dvdnav_menu_table[pr]) {
- snprintf(ui_title, MAX_STR_LEN,
- "DVD %s Menu",
- dvdnav_menu_table[pr]);
+ data.str_len = snprintf(data.str, sizeof(data.str),
+ "DVD %s Menu",
+ dvdnav_menu_table[pr]);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_NUMBER,tt);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_COUNT,num_tt);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,0);
@@ -413,7 +421,8 @@ static int update_title_display(dvd_input_plugin_t *this) {
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0);
} else {
- strcpy(ui_title, "DVD Menu");
+ strcpy(data.str, "DVD Menu");
+ data.str_len = strlen(data.str);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_NUMBER,0);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_COUNT,num_tt);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,0);
@@ -421,22 +430,15 @@ static int update_title_display(dvd_input_plugin_t *this) {
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0);
_x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0);
}
- ui_str_length = strlen(ui_title);
-
+
if (this->dvd_name && this->dvd_name[0] &&
- (ui_str_length + strlen(this->dvd_name) < MAX_STR_LEN)) {
- snprintf(ui_title+ui_str_length, MAX_STR_LEN - ui_str_length,
- ", %s", this->dvd_name);
+ (data.str_len + strlen(this->dvd_name) < sizeof(data.str))) {
+ data.str_len += snprintf(data.str+data.str_len, sizeof(data.str) - data.str_len,
+ ", %s", this->dvd_name);
}
#ifdef INPUT_DEBUG
- printf("input_dvd: Changing title to read '%s'\n", ui_title);
+ printf("input_dvd: Changing title to read '%s'\n", data.str);
#endif
- uevent.type = XINE_EVENT_UI_SET_TITLE;
- uevent.stream = this->stream;
- uevent.data = &data;
- uevent.data_length = sizeof(data);;
- memcpy(data.str, ui_title, strlen(ui_title) + 1);
- data.str_len = strlen(ui_title) + 1;
xine_event_send(this->stream, &uevent);
return 1;
@@ -444,16 +446,16 @@ static int update_title_display(dvd_input_plugin_t *this) {
static void dvd_plugin_dispose (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
-
+
trace_print("Called\n");
-
+
if (this->event_queue)
xine_event_dispose_queue (this->event_queue);
-
+
((dvd_input_class_t *)this_gen->input_class)->ip = NULL;
if (this->dvdnav)
dvdnav_close(this->dvdnav);
-
+
pthread_mutex_lock(&this->buf_mutex);
if (this->mem_stack) {
/* raise the freeing flag, so that the plugin will be freed as soon
@@ -487,11 +489,11 @@ static void dvd_build_mrl_list(dvd_input_plugin_t *this) {
this->class->num_mrls = 0;
}
- if (dvdnav_open(&(this->dvdnav),
+ if (dvdnav_open(&(this->dvdnav),
this->dvd_device) == DVDNAV_STATUS_ERR) {
return;
}
-
+
this->current_dvd_device = this->dvd_device;
this->opened = 1;
@@ -513,7 +515,7 @@ static void dvd_build_mrl_list(dvd_input_plugin_t *this) {
/* allocate enough memory for:
* - a list of pointers to mrls sizeof(xine_mrl_t *) * (num_mrls+1)
- * - possible alignment of the mrl array
+ * - possible alignment of the mrl array
* - an array of mrl structures sizeof(xine_mrl_t) * num_mrls
* - enough chars for every filename sizeof(char)*25 * num_mrls
* - "dvd:/000000.000000\0" = 25 chars
@@ -521,7 +523,7 @@ static void dvd_build_mrl_list(dvd_input_plugin_t *this) {
if ((this->mrls = (xine_mrl_t **) malloc(sizeof(xine_mrl_t *) + num_mrls *
(sizeof(xine_mrl_t*) + sizeof(xine_mrl_t) + 25*sizeof(char)) +
xine_mrl_alignment))) {
-
+
/* the first mrl struct comes after the pointer list */
xine_mrl_t *mrl = PTR_ALIGN(&this->mrls[num_mrls+1], xine_mrl_alignment);
@@ -554,7 +556,7 @@ static void dvd_build_mrl_list(dvd_input_plugin_t *this) {
static void dvd_plugin_free_buffer(buf_element_t *buf) {
dvd_input_plugin_t *this = buf->source;
-
+
pthread_mutex_lock(&this->buf_mutex);
/* give this buffer back to libdvdnav */
dvdnav_free_cache_block(this->dvdnav, buf->mem);
@@ -574,7 +576,7 @@ static void dvd_plugin_free_buffer(buf_element_t *buf) {
}
}
-static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
+static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t nlen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
buf_element_t *buf;
@@ -595,7 +597,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
while(!finished) {
dvd_handle_events(this);
-
+
if (block != buf->mem) {
/* if we already have a dvdnav cache block, give it back first */
dvdnav_free_cache_block(this->dvdnav, block);
@@ -613,17 +615,17 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
}
switch(event) {
- case DVDNAV_BLOCK_OK:
+ case DVDNAV_BLOCK_OK:
{
buf->content = block;
buf->type = BUF_DEMUX_BLOCK;
/* Make sure we don't think we are still paused */
this->pause_timer = 0;
-
+
/* we got a block, so we might be seekable here */
this->seekable = 1;
-
+
finished = 1;
}
break;
@@ -635,7 +637,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
(dvdnav_still_event_t*)block;
buf->type = BUF_CONTROL_NOP;
finished = 1;
-
+
/* stills are not seekable */
this->seekable = 0;
@@ -656,7 +658,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
xine_usec_sleep(50000);
break;
}
- if ((this->pause_timer != 0xff) &&
+ if ((this->pause_timer != 0xff) &&
(time(NULL) >= this->pause_end_time)) {
this->pause_timer = 0;
this->pause_end_time = 0;
@@ -676,7 +678,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
break;
case DVDNAV_SPU_STREAM_CHANGE:
{
- dvdnav_spu_stream_change_event_t *stream_event =
+ dvdnav_spu_stream_change_event_t *stream_event =
(dvdnav_spu_stream_change_event_t*) (block);
buf->content = block;
buf->type = BUF_CONTROL_SPU_CHANNEL;
@@ -694,7 +696,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
break;
case DVDNAV_AUDIO_STREAM_CHANGE:
{
- dvdnav_audio_stream_change_event_t *stream_event =
+ dvdnav_audio_stream_change_event_t *stream_event =
(dvdnav_audio_stream_change_event_t*) (block);
buf->content = block;
buf->type = BUF_CONTROL_AUDIO_CHANNEL;
@@ -728,7 +730,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
break;
case DVDNAV_CELL_CHANGE:
{
- dvdnav_cell_change_event_t *cell_event =
+ dvdnav_cell_change_event_t *cell_event =
(dvdnav_cell_change_event_t*) (block);
xine_event_t event;
@@ -738,14 +740,14 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
event.data = NULL;
event.data_length = 0;
xine_event_send(this->stream, &event);
-
+
if( !update_title_display(this) ) {
if (buf->mem != block) dvdnav_free_cache_block(this->dvdnav, block);
buf->free_buffer(buf);
/* return NULL to indicate end of stream */
return NULL;
}
-
+
this->pg_length = cell_event->pg_length;
this->pgc_length = cell_event->pgc_length;
this->cell_start = cell_event->cell_start;
@@ -797,7 +799,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
break;
}
}
-
+
if (block != buf->mem) {
/* we have received a buffer from the libdvdnav cache, store all
* necessary values to reconstruct xine's buffer and modify it according to
@@ -833,7 +835,7 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
}
pthread_mutex_unlock(&this->buf_mutex);
}
-
+
if (this->pg_length && this->pgc_length) {
switch (((dvd_input_class_t *)this->input_plugin.input_class)->seek_mode) {
case 0: /* PGC based seeking */
@@ -846,13 +848,16 @@ static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen,
break;
}
}
-
+
return buf;
}
static off_t dvd_plugin_read (input_plugin_t *this_gen, char *ch_buf, off_t len) {
/* dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; */
+ if (len < 4)
+ return -1;
+
/* FIXME: Tricking the demux_mpeg_block plugin */
ch_buf[0] = 0;
ch_buf[1] = 0;
@@ -860,7 +865,7 @@ static off_t dvd_plugin_read (input_plugin_t *this_gen, char *ch_buf, off_t len)
ch_buf[3] = 0xba;
return 1;
}
-
+
static off_t dvd_plugin_get_current_pos (input_plugin_t *this_gen){
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
uint32_t pos=0;
@@ -877,28 +882,28 @@ static off_t dvd_plugin_get_current_pos (input_plugin_t *this_gen){
static off_t dvd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
-
+
trace_print("Called\n");
if(!this || !this->dvdnav) {
return -1;
}
-
+
dvdnav_sector_search(this->dvdnav, offset / DVD_BLOCK_SIZE , origin);
return dvd_plugin_get_current_pos(this_gen);
}
static off_t dvd_plugin_seek_time (input_plugin_t *this_gen, int time_offset, int origin) {
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
-
+
trace_print("Called\n");
-
+
if(!this || !this->dvdnav || origin != SEEK_SET) {
return -1;
}
-
+
dvdnav_time_search(this->dvdnav, time_offset * 90);
-
+
return dvd_plugin_get_current_pos(this_gen);
}
@@ -907,7 +912,7 @@ static off_t dvd_plugin_get_length (input_plugin_t *this_gen) {
uint32_t pos=0;
uint32_t length=1;
dvdnav_status_t result;
-
+
trace_print("Called\n");
if(!this || !this->dvdnav) {
@@ -925,7 +930,7 @@ static uint32_t dvd_plugin_get_blocksize (input_plugin_t *this_gen) {
static const char* dvd_plugin_get_mrl (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
-
+
trace_print("Called\n");
return this->mrl;
@@ -937,17 +942,17 @@ static void xine_dvd_send_button_update(dvd_input_plugin_t *this, int mode) {
if (!this || !this->stream || _x_stream_info_get(this->stream,XINE_STREAM_INFO_IGNORE_SPU))
return;
-
+
if (!this->stream->spu_decoder_plugin ||
this->stream->spu_decoder_streamtype != ((BUF_SPU_DVD >> 16) & 0xFF)) {
/* the proper SPU decoder has not been initialized yet,
* so we send a dummy buffer to trigger this */
buf_element_t *buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo);
-
+
buf->size = 0;
buf->type = BUF_SPU_DVD;
this->stream->video_fifo->insert(this->stream->video_fifo, buf);
-
+
while (!this->stream->spu_decoder_plugin ||
this->stream->spu_decoder_streamtype != ((BUF_SPU_DVD >> 16) & 0xFF))
xine_usec_sleep(50000);
@@ -956,7 +961,7 @@ static void xine_dvd_send_button_update(dvd_input_plugin_t *this, int mode) {
dvdnav_get_current_highlight(this->dvdnav, &button);
if (button == this->buttonN && (mode == 0) ) return;
-
+
this->buttonN = button; /* Avoid duplicate sending of button info */
#ifdef INPUT_DEBUG
@@ -971,11 +976,11 @@ static void xine_dvd_send_button_update(dvd_input_plugin_t *this, int mode) {
static void dvd_handle_events(dvd_input_plugin_t *this) {
dvd_input_class_t *class = (dvd_input_class_t*)this->input_plugin.input_class;
- config_values_t *config = class->config; /* Pointer to XineRC config file */
+ config_values_t *config = class->config; /* Pointer to XineRC config file */
xine_event_t *event;
while ((event = xine_event_get(this->event_queue))) {
-
+
if(!this->dvdnav) {
xine_event_free(event);
return;
@@ -1049,7 +1054,7 @@ static void dvd_handle_events(dvd_input_plugin_t *this) {
}
}
break;
- case XINE_EVENT_INPUT_ANGLE_NEXT:
+ case XINE_EVENT_INPUT_ANGLE_NEXT:
{
int num = 0, current = 0;
dvdnav_get_angle_info(this->dvdnav, &current, &num);
@@ -1066,7 +1071,7 @@ static void dvd_handle_events(dvd_input_plugin_t *this) {
update_title_display(this);
}
break;
- case XINE_EVENT_INPUT_ANGLE_PREVIOUS:
+ case XINE_EVENT_INPUT_ANGLE_PREVIOUS:
{
int num = 0, current = 0;
dvdnav_get_angle_info(this->dvdnav, &current, &num);
@@ -1095,7 +1100,7 @@ static void dvd_handle_events(dvd_input_plugin_t *this) {
}
}
break;
- case XINE_EVENT_INPUT_MOUSE_BUTTON:
+ case XINE_EVENT_INPUT_MOUSE_BUTTON:
{
pci_t nav_pci;
if(!this->stream || !this->stream->spu_decoder_plugin) {
@@ -1103,7 +1108,7 @@ static void dvd_handle_events(dvd_input_plugin_t *this) {
}
if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) {
xine_input_data_t *input = event->data;
- if((input->button == 1) && dvdnav_mouse_activate(this->dvdnav,
+ if((input->button == 1) && dvdnav_mouse_activate(this->dvdnav,
&nav_pci, input->x, input->y) == DVDNAV_STATUS_OK) {
xine_dvd_send_button_update(this, 1);
@@ -1129,7 +1134,7 @@ static void dvd_handle_events(dvd_input_plugin_t *this) {
dvdnav_button_select(this->dvdnav, &nav_pci, *but);
}
break;
- case XINE_EVENT_INPUT_MOUSE_MOVE:
+ case XINE_EVENT_INPUT_MOUSE_MOVE:
{
pci_t nav_pci;
if(!this->stream || !this->stream->spu_decoder_plugin)
@@ -1139,19 +1144,19 @@ static void dvd_handle_events(dvd_input_plugin_t *this) {
/* printf("input_dvd: Mouse move (x,y) = (%i,%i)\n", input->x, input->y); */
if(dvdnav_mouse_select(this->dvdnav, &nav_pci, input->x, input->y) == DVDNAV_STATUS_OK) {
int32_t button;
-
+
dvdnav_get_current_highlight(this->dvdnav, &button);
-
+
if(this->mouse_buttonN != button) {
this->mouse_buttonN = button;
send_mouse_enter_leave_event(this, 1);
}
-
+
}
else {
if(this->mouse_in)
send_mouse_enter_leave_event(this, 0);
-
+
}
}
}
@@ -1231,14 +1236,14 @@ static void dvd_handle_events(dvd_input_plugin_t *this) {
case XINE_EVENT_INPUT_NUMBER_1:
this->typed_buttonN++;
case XINE_EVENT_INPUT_NUMBER_0:
- {
+ {
pci_t nav_pci;
if(!this->stream || !this->stream->spu_decoder_plugin)
return;
if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) {
if (dvdnav_button_select_and_activate(this->dvdnav, &nav_pci, this->typed_buttonN) == DVDNAV_STATUS_OK) {
xine_dvd_send_button_update(this, 1);
-
+
if(this->mouse_in)
send_mouse_enter_leave_event(this, 0);
}
@@ -1250,23 +1255,23 @@ static void dvd_handle_events(dvd_input_plugin_t *this) {
case XINE_EVENT_INPUT_NUMBER_10_ADD:
this->typed_buttonN += 10;
}
-
+
xine_event_free(event);
}
return;
}
-static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
+static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
- dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
-
+ dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen;
+
switch(data_type) {
case INPUT_OPTIONAL_DATA_AUDIOLANG: {
uint16_t lang;
int channel = *((int *)data);
int8_t dvd_channel;
-
+
/* Be paranoid */
if(this && this->stream && this->dvdnav) {
@@ -1277,7 +1282,7 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
else
return INPUT_OPTIONAL_UNSUPPORTED;
}
-
+
if (channel == -1)
dvd_channel = dvdnav_get_audio_logical_stream(this->dvdnav, this->stream->audio_channel_auto);
else
@@ -1285,7 +1290,7 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
if(dvd_channel != -1) {
lang = dvdnav_audio_stream_to_lang(this->dvdnav, dvd_channel);
-
+
if(lang != 0xffff)
sprintf(data, " %c%c", lang >> 8, lang & 0xff);
/* TODO: provide long version in XINE_META_INFO_FULL_LANG */
@@ -1298,7 +1303,7 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
return INPUT_OPTIONAL_SUCCESS;
}
}
- }
+ }
return INPUT_OPTIONAL_UNSUPPORTED;
}
break;
@@ -1308,12 +1313,12 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
uint16_t lang;
int channel = *((int *)data);
int8_t dvd_channel;
-
+
/* Be paranoid */
if(this && this->stream && this->dvdnav) {
if(!(dvdnav_is_domain_vts(this->dvdnav))) {
- sprintf(data, "%s", "menu");
+ strcpy(data, "menu");
if (channel <= 0)
return INPUT_OPTIONAL_SUCCESS;
else
@@ -1336,7 +1341,7 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
return INPUT_OPTIONAL_SUCCESS;
} else {
if(channel == -1) {
- sprintf(data, "%s", "none");
+ strcpy(data, "none");
return INPUT_OPTIONAL_SUCCESS;
}
}
@@ -1344,14 +1349,14 @@ static int dvd_plugin_get_optional_data (input_plugin_t *this_gen,
return INPUT_OPTIONAL_UNSUPPORTED;
}
break;
-
+
}
-
+
return INPUT_OPTIONAL_UNSUPPORTED;
}
#ifdef __sun
-/*
+/*
* Check the environment, if we're running under sun's
* vold/rmmount control.
*/
@@ -1369,10 +1374,7 @@ check_solaris_vold_device(dvd_input_class_t *this)
(volume_action = getenv("VOLUME_ACTION")) != NULL &&
strcmp(volume_action, "insert") == 0) {
- device = malloc(strlen(volume_device) + strlen(volume_name) + 2);
- if (device == NULL)
- return;
- sprintf(device, "%s/%s", volume_device, volume_name);
+ asprintf(&device, "%s/%s", volume_device, volume_name);
if (stat(device, &stb) != 0 || !S_ISCHR(stb.st_mode)) {
free(device);
return;
@@ -1386,7 +1388,7 @@ check_solaris_vold_device(dvd_input_class_t *this)
static int dvd_parse_try_open(dvd_input_plugin_t *this, const char *locator)
{
const char *intended_dvd_device;
-
+
/* FIXME: we temporarily special-case "dvd:/" for compatibility;
* actually "dvd:/" should play a DVD image stored in /, but for
* now we have it use the default device */
@@ -1408,7 +1410,7 @@ static int dvd_parse_try_open(dvd_input_plugin_t *this, const char *locator)
xine_setenv("DVDCSS_RAW_DEVICE", raw_device.str_value, 1);
intended_dvd_device = class->dvd_device;
}
-
+
/* attempt to open DVD */
if (this->opened) {
if (intended_dvd_device == this->current_dvd_device) {
@@ -1418,7 +1420,7 @@ static int dvd_parse_try_open(dvd_input_plugin_t *this, const char *locator)
/* Changing DVD device */
dvdnav_close(this->dvdnav);
this->dvdnav = NULL;
- this->opened = 0;
+ this->opened = 0;
}
}
if (!this->opened) {
@@ -1427,14 +1429,14 @@ static int dvd_parse_try_open(dvd_input_plugin_t *this, const char *locator)
this->current_dvd_device = intended_dvd_device;
}
}
-
+
return this->opened;
}
static int dvd_parse_mrl(dvd_input_plugin_t *this, char **locator, char **title_part)
{
*title_part = NULL;
-
+
if (dvd_parse_try_open(this, *locator)) {
return MODE_NAVIGATE;
} else {
@@ -1459,7 +1461,7 @@ static int dvd_parse_mrl(dvd_input_plugin_t *this, char **locator, char **title_
*locator = "";
} else
return MODE_FAIL;
-
+
if (dvd_parse_try_open(this, *locator))
if (strlen(*title_part))
return MODE_TITLE;
@@ -1473,25 +1475,25 @@ static int dvd_parse_mrl(dvd_input_plugin_t *this, char **locator, char **title_
static int dvd_plugin_open (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
dvd_input_class_t *class = (dvd_input_class_t*)this_gen->input_class;
-
+
char *locator, *locator_orig;
char *title_part;
xine_event_t event;
xine_cfg_entry_t region_entry, lang_entry, cfg_entry;
-
+
trace_print("Called\n");
/* we already checked the "dvd:/" MRL before */
locator_orig = locator = strdup (this->mrl + (sizeof("dvd:") - 1));
/* FIXME: call a generic xine-lib MRL parser here to pre-parse
- * the MRL for ?title=<title>&part=<part> stuff and to expand
+ * the MRL for ?title=<title>&part=<part> stuff and to expand
* escaped characters properly */
_x_mrl_unescape (locator);
this->mode = dvd_parse_mrl(this, &locator, &title_part);
-
+
if (this->mode == MODE_FAIL) {
/* opening failed and we have nothing left to try */
xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvd: Error opening DVD device\n"));
@@ -1505,26 +1507,26 @@ static int dvd_plugin_open (input_plugin_t *this_gen) {
dvdnav_get_title_string(this->dvdnav, &this->dvd_name);
if(this->dvd_name)
_x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->dvd_name);
-
+
/* Set region code */
- if (xine_config_lookup_entry (this->stream->xine, "media.dvd.region",
- &region_entry))
+ if (xine_config_lookup_entry (this->stream->xine, "media.dvd.region",
+ &region_entry))
region_changed_cb (class, &region_entry);
-
+
/* Set languages */
if (xine_config_lookup_entry (this->stream->xine, "media.dvd.language",
- &lang_entry))
+ &lang_entry))
language_changed_cb (class, &lang_entry);
-
+
/* Set cache usage */
if (xine_config_lookup_entry(this->stream->xine, "media.dvd.readahead",
&cfg_entry))
read_ahead_cb(class, &cfg_entry);
-
+
/* Set seek mode */
if (xine_config_lookup_entry(this->stream->xine, "media.dvd.seek_behaviour",
&cfg_entry))
- seek_mode_cb(class, &cfg_entry);
+ seek_mode_cb(class, &cfg_entry);
/* Set single chapter mode */
if (xine_config_lookup_entry(this->stream->xine, "media.dvd.play_single_chapter",
@@ -1535,7 +1537,7 @@ static int dvd_plugin_open (input_plugin_t *this_gen) {
char *delimiter;
int tt, pr;
int titles, parts;
-
+
/* a <title>.<part> was specified -> resume parsing */
/* See if there is a period. */
@@ -1545,7 +1547,7 @@ static int dvd_plugin_open (input_plugin_t *this_gen) {
tt = strtol(title_part, NULL, 10);
dvdnav_get_number_of_titles(this->dvdnav, &titles);
if((tt < 0) || (tt > titles)) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_dvd: Title %i is out of range (1 to %i).\n", tt, titles);
dvdnav_close(this->dvdnav);
this->dvdnav = NULL;
@@ -1559,7 +1561,7 @@ static int dvd_plugin_open (input_plugin_t *this_gen) {
pr = strtol(delimiter+1, NULL, 10);
dvdnav_get_number_of_parts(this->dvdnav, tt, &parts);
if ((pr < 0) || (pr > parts)) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_dvd: Part %i is out of range (1 to %i).\n", pr, parts);
dvdnav_close(this->dvdnav);
this->dvdnav = NULL;
@@ -1620,19 +1622,19 @@ static input_plugin_t *dvd_class_get_instance (input_class_t *class_gen, xine_st
static char *handled_mrl = "dvd:/";
trace_print("Called\n");
-
+
/* Check we can handle this MRL */
if (strncasecmp (data, handled_mrl, strlen(handled_mrl) ) != 0)
return NULL;
- this = (dvd_input_plugin_t *) xine_xmalloc (sizeof (dvd_input_plugin_t));
+ this = calloc(1, sizeof (dvd_input_plugin_t));
if (!this) {
return NULL;
}
this->mem_stack = 0;
this->mem_stack_max = 1024;
- this->mem = xine_xmalloc(sizeof(unsigned char *) * this->mem_stack_max);
+ this->mem = calloc(this->mem_stack_max, sizeof(unsigned char *));
if (!this->mem) {
free(this);
return NULL;
@@ -1670,9 +1672,9 @@ static input_plugin_t *dvd_class_get_instance (input_class_t *class_gen, xine_st
pthread_mutex_init(&this->buf_mutex, NULL);
this->freeing = 0;
-
+
this->event_queue = xine_event_new_queue (this->stream);
-
+
/* config callbacks may react now */
class->ip = this;
@@ -1693,7 +1695,7 @@ static const char *dvd_class_get_identifier (input_class_t *this_gen) {
/* FIXME: adapt to new api. */
#if 0
-static xine_mrl_t **dvd_class_get_dir (input_class_t *this_gen,
+static xine_mrl_t **dvd_class_get_dir (input_class_t *this_gen,
const char *filename, int *nFiles) {
dvd_input_class_t *this = (dvd_input_class_t*)this_gen;
@@ -1710,11 +1712,11 @@ static xine_mrl_t **dvd_class_get_dir (input_class_t *this_gen,
}
#endif
-static char **dvd_class_get_autoplay_list (input_class_t *this_gen,
+static char **dvd_class_get_autoplay_list (input_class_t *this_gen,
int *num_files) {
dvd_input_class_t *this = (dvd_input_class_t *) this_gen;
- trace_print("get_autoplay_list entered\n");
+ trace_print("get_autoplay_list entered\n");
this->filelist[0] = "dvd:/";
this->filelist[1] = NULL;
@@ -1758,10 +1760,10 @@ static void *init_class (xine_t *xine, void *data) {
printf("input_dvd.c: config = %p\n", config);
#endif
- this = (dvd_input_class_t *) xine_xmalloc (sizeof (dvd_input_class_t));
+ this = (dvd_input_class_t *) calloc(1, sizeof (dvd_input_class_t));
if (!this)
return NULL;
-
+
this->input_class.get_instance = dvd_class_get_instance;
this->input_class.get_identifier = dvd_class_get_identifier;
this->input_class.get_description = dvd_class_get_description;
@@ -1772,7 +1774,7 @@ static void *init_class (xine_t *xine, void *data) {
this->input_class.get_autoplay_list = dvd_class_get_autoplay_list;
this->input_class.dispose = dvd_class_dispose;
this->input_class.eject_media = dvd_class_eject_media;
-
+
this->config = config;
this->xine = xine;
@@ -1797,7 +1799,7 @@ static void *init_class (xine_t *xine, void *data) {
static const char *decrypt_modes[] = { "key", "disc", "title", NULL };
char *css_cache_default, *css_cache;
int mode;
-
+
raw_device = config->register_filename(config, "media.dvd.raw_device",
RDVD_PATH, XINE_CONFIG_STRING_IS_DEVICE_NAME,
_("raw device set up for DVD access"),
@@ -1812,16 +1814,15 @@ static void *init_class (xine_t *xine, void *data) {
"(man raw) for further information."),
10, NULL, NULL);
if (raw_device) xine_setenv("DVDCSS_RAW_DEVICE", raw_device, 0);
-
+
mode = config->register_enum(config, "media.dvd.css_decryption_method", 0,
decrypt_modes, _("CSS decryption method"),
_("Selects the decryption method libdvdcss will use to descramble "
"copy protected DVDs. Try the various methods, if you have problems "
"playing scrambled DVDs."), 20, NULL, NULL);
xine_setenv("DVDCSS_METHOD", decrypt_modes[mode], 0);
-
- css_cache_default = (char *)malloc(strlen(xine_get_homedir()) + 10);
- sprintf(css_cache_default, "%s/.dvdcss/", xine_get_homedir());
+
+ asprintf(&css_cache_default, "%s/.dvdcss/", xine_get_homedir());
css_cache = config->register_filename(config, "media.dvd.css_cache_path", css_cache_default, XINE_CONFIG_STRING_IS_DIRECTORY_NAME,
_("path to the title key cache"),
_("Since cracking the copy protection of scrambled DVDs can "
@@ -1834,7 +1835,7 @@ static void *init_class (xine_t *xine, void *data) {
if (strlen(css_cache) > 0)
xine_setenv("DVDCSS_CACHE", css_cache, 0);
free(css_cache_default);
-
+
if(xine->verbosity > XINE_VERBOSITY_NONE)
xine_setenv("DVDCSS_VERBOSE", "2", 0);
@@ -1843,7 +1844,7 @@ static void *init_class (xine_t *xine, void *data) {
dlclose(dvdcss);
}
-
+
config->register_num(config, "media.dvd.region",
1,
_("region the DVD player claims to be in (1 to 8)"),
@@ -1915,7 +1916,7 @@ static void *init_class (xine_t *xine, void *data) {
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "DVD", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_file.c b/src/input/input_file.c
index f81103dcd..208a5420e 100644
--- a/src/input/input_file.c
+++ b/src/input/input_file.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2000-2005 the xine project
- *
+ *
* 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
@@ -63,18 +63,18 @@ typedef struct {
xine_t *xine;
config_values_t *config;
-
+
char *origin_path;
int show_hidden_files;
int mrls_allocated_entries;
xine_mrl_t **mrls;
-
+
} file_input_class_t;
typedef struct {
input_plugin_t input_plugin;
-
+
xine_stream_t *stream;
int fh;
@@ -145,15 +145,18 @@ static int check_mmap_file(file_input_plugin_t *this) {
static off_t file_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
file_input_plugin_t *this = (file_input_plugin_t *) this_gen;
+ if (len < 0)
+ return -1;
+
#ifdef HAVE_MMAP
if ( check_mmap_file(this) ) {
off_t l = len;
if ( (this->mmap_curr + len) > (this->mmap_base + this->mmap_len) )
l = (this->mmap_base + this->mmap_len) - this->mmap_curr;
-
+
memcpy(buf, this->mmap_curr, l);
this->mmap_curr += l;
-
+
return l;
}
#endif
@@ -166,6 +169,13 @@ static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buf
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
@@ -181,7 +191,7 @@ static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buf
/* FIXME: it's completely illegal to free buffer->mem here
* - buffer->mem has not been allocated by malloc
- * - demuxers expect buffer->mem != NULL
+ * - demuxers expect buffer->mem != NULL
*/
/* free(buf->mem); buf->mem = NULL; */
@@ -190,7 +200,7 @@ static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buf
#endif
{
off_t num_bytes, total_bytes = 0;
-
+
buf->content = buf->mem;
while (total_bytes < todo) {
@@ -208,11 +218,11 @@ static buf_element_t *file_plugin_read_block (input_plugin_t *this_gen, fifo_buf
}
total_bytes += num_bytes;
}
-
+
if( buf != NULL )
buf->size = total_bytes;
}
-
+
return buf;
}
@@ -286,7 +296,7 @@ static uint32_t file_plugin_get_blocksize (input_plugin_t *this_gen) {
*/
static int is_a_dir(char *filepathname) {
struct stat pstat;
-
+
stat(filepathname, &pstat);
return (S_ISDIR(pstat.st_mode));
@@ -298,9 +308,9 @@ static const char* file_plugin_get_mrl (input_plugin_t *this_gen) {
return this->mrl;
}
-static int file_plugin_get_optional_data (input_plugin_t *this_gen,
+static int file_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
-
+
return INPUT_OPTIONAL_UNSUPPORTED;
}
@@ -407,7 +417,7 @@ static int file_plugin_open (input_plugin_t *this_gen ) {
return 1;
}
-static input_plugin_t *file_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
+static input_plugin_t *file_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
const char *data) {
/* file_input_class_t *cls = (file_input_class_t *) cls_gen; */
@@ -421,7 +431,7 @@ static input_plugin_t *file_class_get_instance (input_class_t *cls_gen, xine_str
return NULL;
}
- this = (file_input_plugin_t *) xine_xmalloc (sizeof (file_input_plugin_t));
+ this = (file_input_plugin_t *) calloc(1, sizeof (file_input_plugin_t));
this->stream = stream;
this->mrl = mrl;
this->fh = -1;
@@ -474,12 +484,12 @@ static input_plugin_t *file_class_get_instance (input_class_t *cls_gen, xine_str
*/
static void 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 origin_change_cb(void *data, xine_cfg_entry_t *cfg) {
file_input_class_t *this = (file_input_class_t *) data;
-
+
this->origin_path = cfg->str_value;
}
@@ -530,20 +540,20 @@ static int _strverscmp(const char *s1, const char *s2) {
c2 = *p2++;
state |= (c1 == '0') + (ISDIGIT(c1) != 0);
}
-
+
state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT(c2) != 0))];
-
+
switch(state) {
case CMP:
return diff;
-
+
case LEN:
while(ISDIGIT(*p1++))
if(!ISDIGIT(*p2++))
return 1;
-
+
return ISDIGIT(*p2) ? -1 : diff;
-
+
default:
return state;
}
@@ -573,11 +583,11 @@ static uint32_t get_file_type(char *filepathname, char *origin, xine_t *xine) {
return file_type;
}
}
-
+
file_type |= mrl_file;
-
+
mode = pstat.st_mode;
-
+
if(S_ISLNK(mode))
file_type |= mrl_file_symlink;
else if(S_ISDIR(mode))
@@ -597,10 +607,10 @@ static uint32_t get_file_type(char *filepathname, char *origin, xine_t *xine) {
if(mode & S_IXUGO)
file_type |= mrl_file_exec;
}
-
+
if(filepathname[strlen(filepathname) - 1] == '~')
file_type |= mrl_file_backup;
-
+
return file_type;
}
@@ -628,7 +638,7 @@ static const char *file_class_get_identifier (input_class_t *this_gen) {
return "file";
}
-static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
+static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
const char *filename, int *nFiles) {
/* FIXME: this code needs cleanup badly */
@@ -650,7 +660,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
*nFiles = 0;
memset(current_dir, 0, sizeof(current_dir));
- /*
+ /*
* No origin location, so got the content of the current directory
*/
if(!filename) {
@@ -658,7 +668,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
}
else {
snprintf(current_dir, XINE_PATH_MAX, "%s", filename);
-
+
/* Remove exceed '/' */
while((current_dir[strlen(current_dir) - 1] == '/') && strlen(current_dir) > 1)
current_dir[strlen(current_dir) - 1] = '\0';
@@ -666,14 +676,14 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
/* Store new origin path */
try_again_from_home:
-
+
this->config->update_string(this->config, "media.files.origin_path", current_dir);
if(strcasecmp(current_dir, "/"))
snprintf(current_dir_slashed, sizeof(current_dir_slashed), "%s/", current_dir);
else
sprintf(current_dir_slashed, "/");
-
+
/*
* Ooch!
*/
@@ -688,31 +698,28 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
return NULL;
}
-
- dir_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
- hide_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
- norm_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
-
+
+ dir_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
+ hide_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
+ norm_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
+
while((pdirent = readdir(pdir)) != NULL) {
-
+
memset(fullfilename, 0, sizeof(fullfilename));
snprintf(fullfilename, sizeof(fullfilename), "%s/%s", current_dir, pdirent->d_name);
-
+
if(is_a_dir(fullfilename)) {
-
+
/* if user don't want to see hidden files, ignore them */
- if(this->show_hidden_files == 0 &&
+ if(this->show_hidden_files == 0 &&
((strlen(pdirent->d_name) > 1)
&& (pdirent->d_name[0] == '.' && pdirent->d_name[1] != '.'))) {
;
}
else {
-
- dir_files[num_dir_files].mrl = (char *)
- xine_xmalloc(strlen(current_dir_slashed) + 1 + strlen(pdirent->d_name) + 1);
-
+
dir_files[num_dir_files].origin = strdup(current_dir);
- sprintf(dir_files[num_dir_files].mrl, "%s%s",
+ asprintf(&(dir_files[num_dir_files].mrl), "%s%s",
current_dir_slashed, pdirent->d_name);
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = get_file_type(fullfilename, current_dir, this->xine);
@@ -722,20 +729,21 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
if(dir_files[num_dir_files].type & mrl_file_symlink) {
char linkbuf[XINE_PATH_MAX + XINE_NAME_MAX + 1];
int linksize;
-
+
memset(linkbuf, 0, sizeof(linkbuf));
linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX);
-
- if(linksize < 0)
+
+ if(linksize < 0)
xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_file: readlink() failed: %s\n", strerror(errno));
else {
- dir_files[num_dir_files].link = (char *) xine_xmalloc(linksize + 1);
- strncpy(dir_files[num_dir_files].link, linkbuf, linksize);
+ dir_files[num_dir_files].link =
+ strndup(linkbuf, linksize);
+
dir_files[num_dir_files].type |= get_file_type(dir_files[num_dir_files].link, current_dir, this->xine);
}
}
-
+
num_dir_files++;
}
@@ -746,80 +754,72 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
/* if user don't want to see hidden files, ignore them */
if(this->show_hidden_files) {
- hide_files[num_hide_files].mrl = (char *)
- xine_xmalloc(strlen(current_dir_slashed) + 1 + strlen(pdirent->d_name) + 1);
-
hide_files[num_hide_files].origin = strdup(current_dir);
- sprintf(hide_files[num_hide_files].mrl, "%s%s",
+ asprintf(&(hide_files[num_hide_files].mrl), "%s%s",
current_dir_slashed, pdirent->d_name);
hide_files[num_hide_files].link = NULL;
hide_files[num_hide_files].type = get_file_type(fullfilename, current_dir, this->xine);
hide_files[num_hide_files].size = get_file_size(fullfilename, current_dir);
-
+
/* The file is a link, follow it */
if(hide_files[num_hide_files].type & mrl_file_symlink) {
char linkbuf[XINE_PATH_MAX + XINE_NAME_MAX + 1];
int linksize;
-
+
memset(linkbuf, 0, sizeof(linkbuf));
linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX);
-
+
if(linksize < 0) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_file: readlink() failed: %s\n", strerror(errno));
}
else {
- hide_files[num_hide_files].link = (char *)
- xine_xmalloc(linksize + 1);
- strncpy(hide_files[num_hide_files].link, linkbuf, linksize);
+ hide_files[num_hide_files].link =
+ strndup(linkbuf, linksize);
hide_files[num_hide_files].type |= get_file_type(hide_files[num_hide_files].link, current_dir, this->xine);
}
}
-
+
num_hide_files++;
}
} /* So a *normal* one. */
else {
- norm_files[num_norm_files].mrl = (char *)
- xine_xmalloc(strlen(current_dir_slashed) + 1 + strlen(pdirent->d_name) + 1);
-
norm_files[num_norm_files].origin = strdup(current_dir);
- sprintf(norm_files[num_norm_files].mrl, "%s%s",
+ asprintf(&(norm_files[num_norm_files].mrl), "%s%s",
current_dir_slashed, pdirent->d_name);
norm_files[num_norm_files].link = NULL;
norm_files[num_norm_files].type = get_file_type(fullfilename, current_dir, this->xine);
norm_files[num_norm_files].size = get_file_size(fullfilename, current_dir);
-
+
/* The file is a link, follow it */
if(norm_files[num_norm_files].type & mrl_file_symlink) {
char linkbuf[XINE_PATH_MAX + XINE_NAME_MAX + 1];
int linksize;
-
+
memset(linkbuf, 0, sizeof(linkbuf));
linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX);
-
+
if(linksize < 0) {
xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_file: readlink() failed: %s\n", strerror(errno));
}
else {
- norm_files[num_norm_files].link = (char *)
- xine_xmalloc(linksize + 1);
- strncpy(norm_files[num_norm_files].link, linkbuf, linksize);
+ norm_files[num_norm_files].link =
+ strndup(linkbuf, linksize);
norm_files[num_norm_files].type |= get_file_type(norm_files[num_norm_files].link, current_dir, this->xine);
}
}
-
+
num_norm_files++;
}
-
+
num_files++;
}
-
+
closedir(pdir);
-
+
/*
* Ok, there are some files here, so sort
* them then store them into global mrls array.
@@ -834,27 +834,27 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
*/
if(num_dir_files)
qsort(dir_files, num_dir_files, sizeof(xine_mrl_t), func);
-
+
if(num_hide_files)
qsort(hide_files, num_hide_files, sizeof(xine_mrl_t), func);
-
+
if(num_norm_files)
qsort(norm_files, num_norm_files, sizeof(xine_mrl_t), func);
-
+
/*
* Add directories entries
*/
for(i = 0; i < num_dir_files; i++) {
-
+
if(num_files >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
-
- MRL_DUPLICATE(&dir_files[i], this->mrls[num_files]);
+
+ MRL_DUPLICATE(&dir_files[i], this->mrls[num_files]);
num_files++;
}
@@ -863,21 +863,21 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
* Add hidden files entries
*/
for(i = 0; i < num_hide_files; i++) {
-
+
if(num_files >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
-
- MRL_DUPLICATE(&hide_files[i], this->mrls[num_files]);
+
+ MRL_DUPLICATE(&hide_files[i], this->mrls[num_files]);
num_files++;
}
-
- /*
+
+ /*
* Add other files entries
*/
for(i = 0; i < num_norm_files; i++) {
@@ -885,29 +885,29 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
if(num_files >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}
else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
- MRL_DUPLICATE(&norm_files[i], this->mrls[num_files]);
+ MRL_DUPLICATE(&norm_files[i], this->mrls[num_files]);
num_files++;
}
-
+
/* Some cleanups before leaving */
for(i = num_dir_files; i == 0; i--)
MRL_ZERO(&dir_files[i]);
free(dir_files);
-
+
for(i = num_hide_files; i == 0; i--)
MRL_ZERO(&hide_files[i]);
free(hide_files);
-
+
for(i = num_norm_files; i == 0; i--)
MRL_ZERO(&norm_files[i]);
free(norm_files);
-
+
}
else {
free(hide_files);
@@ -915,12 +915,12 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
free(norm_files);
return NULL;
}
-
+
/*
* Inform caller about files found number.
*/
*nFiles = num_files;
-
+
/*
* Freeing exceeded mrls if exists.
*/
@@ -928,7 +928,7 @@ static xine_mrl_t **file_class_get_dir (input_class_t *this_gen,
MRL_ZERO(this->mrls[this->mrls_allocated_entries - 1]);
free(this->mrls[this->mrls_allocated_entries--]);
}
-
+
/*
* This is useful to let UI know where it should stops ;-).
*/
@@ -965,12 +965,12 @@ static void *init_plugin (xine_t *xine, void *data) {
file_input_class_t *this;
config_values_t *config;
- this = (file_input_class_t *) xine_xmalloc (sizeof (file_input_class_t));
+ this = (file_input_class_t *) calloc(1, sizeof (file_input_class_t));
this->xine = xine;
this->config = xine->config;
config = xine->config;
-
+
this->input_class.get_instance = file_class_get_instance;
this->input_class.get_identifier = file_class_get_identifier;
this->input_class.get_description = file_class_get_description;
@@ -979,12 +979,12 @@ static void *init_plugin (xine_t *xine, void *data) {
this->input_class.dispose = file_class_dispose;
this->input_class.eject_media = NULL;
- this->mrls = (xine_mrl_t **) xine_xmalloc(sizeof(xine_mrl_t*));
+ this->mrls = (xine_mrl_t **) calloc(1, sizeof(xine_mrl_t*));
this->mrls_allocated_entries = 0;
{
char current_dir[XINE_PATH_MAX + 1];
-
+
if(getcwd(current_dir, sizeof(current_dir)) == NULL)
strcpy(current_dir, ".");
@@ -995,14 +995,14 @@ static void *init_plugin (xine_t *xine, void *data) {
"start at this location."),
0, origin_change_cb, (void *) this);
}
-
- this->show_hidden_files = config->register_bool(config,
- "media.files.show_hidden_files",
+
+ 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, hidden_bool_cb, (void *) this);
-
+
return this;
}
@@ -1011,7 +1011,7 @@ static void *init_plugin (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "FILE", XINE_VERSION_CODE, NULL, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c
index 0848b9206..cf97074ee 100644
--- a/src/input/input_gnome_vfs.c
+++ b/src/input/input_gnome_vfs.c
@@ -1,19 +1,19 @@
/*
* Copyright (C) 2000-2003 the xine project
* 2002 Bastien Nocera <hadess@hadess.net>
- *
+ *
* This file is part of totem,
- *
+ *
* 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
@@ -121,6 +121,13 @@ gnomevfs_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
off_t total_bytes;
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;
@@ -223,7 +230,7 @@ static const char
}
static int
-gnomevfs_plugin_get_optional_data (input_plugin_t *this_gen,
+gnomevfs_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type)
{
D ("input_gnomevfs: get optional data, type %08x\n", data_type);
diff --git a/src/input/input_http.c b/src/input/input_http.c
index af696ca14..35fff8ce0 100644
--- a/src/input/input_http.c
+++ b/src/input/input_http.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2000-2004 the xine project
- *
+ *
* 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
@@ -68,31 +68,35 @@ typedef struct {
input_plugin_t input_plugin;
xine_stream_t *stream;
-
+
int fh;
char *mrl;
- nbc_t *nbc;
+ nbc_t *nbc;
off_t curpos;
off_t contentlength;
-
+
char buf[BUFSIZE];
char proxybuf[BUFSIZE];
char auth[BUFSIZE];
char proxyauth[BUFSIZE];
-
+
+ char *mime_type;
+
char *proto;
char *user;
char *password;
char *host;
int port;
char *uri;
-
+
+ const char *user_agent;
+
char preview[MAX_PREVIEW_SIZE];
off_t preview_size;
-
+
/* Last.FM streaming server */
unsigned char is_lastfm;
@@ -108,7 +112,7 @@ typedef struct {
/* scratch buffer for forward seeking */
char seek_buf[BUFSIZE];
-
+
} http_input_plugin_t;
typedef struct {
@@ -136,7 +140,7 @@ static void proxy_host_change_cb (void *this_gen, xine_cfg_entry_t *cfg) {
static void proxy_port_change_cb(void *this_gen, xine_cfg_entry_t *cfg) {
http_input_class_t *this = (http_input_class_t *)this_gen;
-
+
this->proxyport = cfg->num_value;
}
@@ -168,17 +172,17 @@ static int _x_use_proxy(http_input_class_t *this, const char *host) {
struct hostent *info;
size_t i = 0, host_len, noprox_len;
- /*
- * get full host name
+ /*
+ * get full host name
*/
if ((info = gethostbyname(host)) == NULL) {
- xine_log(this->xine, XINE_LOG_MSG,
+ xine_log(this->xine, XINE_LOG_MSG,
_("input_http: gethostbyname(%s) failed: %s\n"), host,
hstrerror(h_errno));
return 1;
}
if (!info->h_name) return 1;
-
+
if ( info->h_addr_list[0] ) {
/* \177\0\0\1 is the *octal* representation of 127.0.0.1 */
if ( info->h_addrtype == AF_INET && !memcmp(info->h_addr_list[0], "\177\0\0\1", 4) ) {
@@ -235,26 +239,16 @@ static int http_plugin_basicauth (const char *user, const char *password, char*
char *tmp;
char *sptr;
char *dptr;
- int totlen;
+ size_t count;
int enclen;
- int count;
-
- totlen = strlen (user) + 1;
- if(password != NULL)
- totlen += strlen (password);
-
- enclen = ((totlen + 2) / 3 ) * 4 + 1;
-
+
+ count = asprintf(&tmp, "%s:%s", user, (password != NULL) ? password : "");
+
+ enclen = ((count + 2) / 3 ) * 4 + 1;
+
if (len < enclen)
return -1;
-
- tmp = malloc (sizeof(char) * (totlen + 1));
- strcpy (tmp, user);
- strcat (tmp, ":");
- if (password != NULL)
- strcat (tmp, password);
-
- count = strlen(tmp);
+
sptr = tmp;
dptr = dest;
while (count >= 3) {
@@ -266,29 +260,29 @@ static int http_plugin_basicauth (const char *user, const char *password, char*
sptr += 3;
dptr += 4;
}
-
+
if (count > 0) {
dptr[0] = enctable[(sptr[0] & 0xFC) >> 2];
dptr[1] = enctable[(sptr[0] & 0x3) << 4];
dptr[2] = '=';
-
+
if (count > 1) {
dptr[1] = enctable[((sptr[0] & 0x3) << 4) | ((sptr[1] & 0xF0) >> 4)];
dptr[2] = enctable[(sptr[1] & 0x0F) << 2];
}
-
+
dptr[3] = '=';
dptr += 4;
}
-
+
dptr[0] = '\0';
-
+
free(tmp);
return 0;
}
static int http_plugin_read_metainf (http_input_plugin_t *this) {
-
+
char metadata_buf[255 * 16];
unsigned char len = 0;
char *title_end;
@@ -296,19 +290,19 @@ static int http_plugin_read_metainf (http_input_plugin_t *this) {
const char *radio;
xine_event_t uevent;
xine_ui_data_t data;
-
+
/* get the length of the metadata */
if (_x_io_tcp_read (this->stream, this->fh, (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))
return 0;
-
+
metadata_buf[len * 16] = '\0';
-
+
lprintf ("http_plugin_read_metainf: %s\n", metadata_buf);
/* Extract the title of the current song */
@@ -321,13 +315,13 @@ static int http_plugin_read_metainf (http_input_plugin_t *this) {
}
if ((title_end = strstr(songtitle, terminator))) {
*title_end = '\0';
-
+
if ((!this->shoutcast_songtitle ||
(strcmp(songtitle, this->shoutcast_songtitle))) &&
(strlen(songtitle) > 0)) {
-
+
lprintf ("http_plugin_read_metainf: songtitle: %s\n", songtitle);
-
+
if (this->shoutcast_songtitle)
free(this->shoutcast_songtitle);
this->shoutcast_songtitle = strdup(songtitle);
@@ -364,7 +358,7 @@ static off_t http_plugin_read_int (http_input_plugin_t *this,
char *buf, off_t total) {
int read_bytes = 0;
int nlen;
-
+
lprintf("total=%"PRId64"\n", total);
while (total) {
nlen = total;
@@ -379,7 +373,7 @@ static off_t http_plugin_read_int (http_input_plugin_t *this,
if (!http_plugin_read_metainf(this))
goto error;
this->shoutcast_pos = 0;
-
+
} else {
nlen = _x_io_tcp_read (this->stream, this->fh, &buf[read_bytes], nlen);
if (nlen < 0)
@@ -406,7 +400,7 @@ static off_t http_plugin_read_int (http_input_plugin_t *this,
this->shoutcast_pos += nlen;
}
-
+
/* end of file */
if (nlen == 0)
return read_bytes;
@@ -414,9 +408,9 @@ static off_t http_plugin_read_int (http_input_plugin_t *this,
total -= nlen;
}
return read_bytes;
-
+
error:
- if (!_x_action_pending(this->stream))
+ if (!_x_action_pending(this->stream))
_x_message (this->stream, XINE_MSG_READ_ERROR, this->host, NULL);
xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error %d\n"), errno);
return read_bytes;
@@ -429,6 +423,9 @@ static off_t http_plugin_read (input_plugin_t *this_gen,
num_bytes = 0;
+ if (nlen < 0)
+ return -1;
+
if (this->curpos < this->preview_size) {
if (nlen > (this->preview_size - this->curpos))
@@ -445,10 +442,10 @@ static off_t http_plugin_read (input_plugin_t *this_gen,
n = nlen - num_bytes;
- if (n) {
+ if (n > 0) {
int read_bytes;
read_bytes = http_plugin_read_int (this, &buf[num_bytes], n);
-
+
if (read_bytes < 0)
return read_bytes;
@@ -466,7 +463,7 @@ static int resync_nsv(http_input_plugin_t *this) {
lprintf("resyncing NSV stream\n");
while ((pos < 3) && (read_bytes < (1024*1024))) {
-
+
if (http_plugin_read_int(this, (char*)&c, 1) != 1)
return 1;
@@ -498,7 +495,7 @@ static int resync_nsv(http_input_plugin_t *this) {
if (pos == 3) {
lprintf("NSV stream resynced\n");
} else {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"http: cannot resync NSV stream!\n");
return 0;
}
@@ -511,6 +508,13 @@ static buf_element_t *http_plugin_read_block (input_plugin_t *this_gen, fifo_buf
off_t total_bytes;
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;
@@ -562,7 +566,7 @@ static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -576,15 +580,15 @@ static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin
if( this->curpos <= this->preview_size )
this->curpos = offset;
else
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"http: cannot seek back! (%" PRIdMAX " > %" PRIdMAX ")\n",
(intmax_t)this->curpos, (intmax_t)offset);
-
+
} else {
offset -= this->curpos;
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -602,17 +606,20 @@ static const char* http_plugin_get_mrl (input_plugin_t *this_gen) {
}
static int http_plugin_get_optional_data (input_plugin_t *this_gen,
- void *data, int data_type) {
+ void *const data, int data_type) {
+ void **const ptr = (void **const) data;
http_input_plugin_t *this = (http_input_plugin_t *) this_gen;
switch (data_type) {
case INPUT_OPTIONAL_DATA_PREVIEW:
-
memcpy (data, this->preview, this->preview_size);
return this->preview_size;
- break;
+ case INPUT_OPTIONAL_DATA_MIME_TYPE:
+ *ptr = this->mime_type;
+ case INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE:
+ return *this->mime_type ? INPUT_OPTIONAL_SUCCESS : INPUT_OPTIONAL_UNSUPPORTED;
}
return INPUT_OPTIONAL_UNSUPPORTED;
@@ -625,7 +632,7 @@ static void http_plugin_dispose (input_plugin_t *this_gen ) {
close(this->fh);
this->fh = -1;
}
-
+
if (this->nbc) {
nbc_close (this->nbc);
this->nbc = NULL;
@@ -637,6 +644,7 @@ static void http_plugin_dispose (input_plugin_t *this_gen ) {
if (this->user) free(this->user);
if (this->password) free(this->password);
if (this->uri) free(this->uri);
+ if (this->mime_type) free(this->mime_type);
free (this);
}
@@ -644,7 +652,7 @@ static void report_progress (xine_stream_t *stream, int p) {
xine_event_t event;
xine_progress_data_t prg;
-
+
prg.description = _("Connecting HTTP server...");
prg.percent = p;
@@ -661,13 +669,15 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
int done, len, linenum;
int httpcode;
int res;
- int buflen;
+ size_t buflen;
int use_proxy;
int proxyport;
int mpegurl_redirect = 0;
-
+ char mime_type[256];
+
+ mime_type[0] = 0;
use_proxy = this_class->proxyhost && strlen(this_class->proxyhost);
-
+
if (use_proxy) {
if (this_class->proxyuser && strlen(this_class->proxyuser)) {
if (http_plugin_basicauth (this_class->proxyuser,
@@ -678,10 +688,11 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
}
}
}
-
-
+
+
if (!_x_parse_url(this->mrl, &this->proto, &this->host, &this->port,
- &this->user, &this->password, &this->uri)) {
+ &this->user, &this->password, &this->uri,
+ &this->user_agent)) {
_x_message(this->stream, XINE_MSG_GENERAL_WARNING, "malformed url", NULL);
return 0;
}
@@ -689,14 +700,14 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
if (this->port == 0)
this->port = DEFAULT_HTTP_PORT;
-
+
if (this->user && strlen(this->user)) {
if (http_plugin_basicauth (this->user, this->password, this->auth, BUFSIZE)) {
_x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "basic auth error", NULL);
return -1;
}
}
-
+
if (this_class->proxyport == 0)
proxyport = DEFAULT_HTTP_PORT;
else
@@ -710,10 +721,10 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
printf ("input_http: password : >%s<\n", this->password);
printf ("input_http: path : >%s<\n", this->uri);
-
+
if (use_proxy)
printf (" via proxy >%s:%d<", this_class->proxyhost, proxyport);
-
+
printf ("\n");
}
@@ -723,13 +734,13 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
this->fh = _x_io_tcp_connect (this->stream, this_class->proxyhost, proxyport);
else
this->fh = _x_io_tcp_connect (this->stream, this->host, this->port);
-
+
this->curpos = 0;
-
+
if (this->fh == -1)
return -2;
- {
+ {
uint32_t timeout, progress;
xine_cfg_entry_t cfgentry;
if (xine_config_lookup_entry (this->stream->xine, "media.network.timeout", &cfgentry)) {
@@ -753,43 +764,40 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
if (use_proxy) {
if (this->port != DEFAULT_HTTP_PORT) {
- snprintf (this->buf, BUFSIZE, "GET http://%s:%d%s HTTP/1.0\015\012",
- this->host, this->port, this->uri);
+ buflen = snprintf (this->buf, BUFSIZE, "GET http://%s:%d%s HTTP/1.0\015\012",
+ this->host, this->port, this->uri);
} else {
- snprintf (this->buf, BUFSIZE, "GET http://%s%s HTTP/1.0\015\012",
- this->host, this->uri);
+ buflen = snprintf (this->buf, BUFSIZE, "GET http://%s%s HTTP/1.0\015\012",
+ this->host, this->uri);
}
- }
+ }
else
- snprintf (this->buf, BUFSIZE, "GET %s HTTP/1.0\015\012", this->uri);
-
- buflen = strlen(this->buf);
+ buflen = snprintf (this->buf, BUFSIZE, "GET %s HTTP/1.0\015\012", this->uri);
+
if (this->port != DEFAULT_HTTP_PORT)
- snprintf (this->buf + buflen, BUFSIZE - buflen, "Host: %s:%d\015\012",
- this->host, this->port);
+ buflen += snprintf (this->buf + buflen, BUFSIZE - buflen, "Host: %s:%d\015\012",
+ this->host, this->port);
else
- snprintf (this->buf + buflen, BUFSIZE - buflen, "Host: %s\015\012",
- this->host);
-
- buflen = strlen(this->buf);
+ buflen += snprintf (this->buf + buflen, BUFSIZE - buflen, "Host: %s\015\012",
+ this->host);
+
if (this_class->proxyuser && strlen(this_class->proxyuser)) {
- snprintf (this->buf + buflen, BUFSIZE - buflen,
- "Proxy-Authorization: Basic %s\015\012", this->proxyauth);
- buflen = strlen(this->buf);
+ buflen += snprintf (this->buf + buflen, BUFSIZE - buflen,
+ "Proxy-Authorization: Basic %s\015\012", this->proxyauth);
}
if (this->user && strlen(this->user)) {
- snprintf (this->buf + buflen, BUFSIZE - buflen,
- "Authorization: Basic %s\015\012", this->auth);
- buflen = strlen(this->buf);
+ buflen += snprintf (this->buf + buflen, BUFSIZE - buflen,
+ "Authorization: Basic %s\015\012", this->auth);
}
-
- snprintf(this->buf + buflen, BUFSIZE - buflen,
- "User-Agent: xine/%s\015\012"
- "Accept: */*\015\012"
- "Icy-MetaData: 1\015\012"
- "\015\012",
- VERSION);
- buflen = strlen(this->buf);
+
+ buflen += snprintf(this->buf + buflen, BUFSIZE - buflen,
+ "User-Agent: %s%sxine/%s\015\012"
+ "Accept: */*\015\012"
+ "Icy-MetaData: 1\015\012"
+ "\015\012",
+ this->user_agent ? this->user_agent : "",
+ this->user_agent ? " " : "",
+ VERSION);
if (_x_io_tcp_write (this->stream, this->fh, this->buf, buflen) != buflen) {
_x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "couldn't send request", NULL);
xprintf(this_class->xine, XINE_VERBOSITY_DEBUG, "input_http: couldn't send request\n");
@@ -813,14 +821,14 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
this->buf[len] = '\0';
len--;
-
+
if (len >= 0 && this->buf[len] == '\015') {
this->buf[len] = '\0';
len--;
}
linenum++;
-
+
lprintf ("answer: >%s<\n", this->buf);
if (linenum == 1) {
@@ -836,13 +844,13 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
&httpcode, httpstatus) != 2)
) {
_x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "invalid http answer", NULL);
- xine_log (this->stream->xine, XINE_LOG_MSG,
+ xine_log (this->stream->xine, XINE_LOG_MSG,
_("input_http: invalid http answer\n"));
return -6;
}
if (httpcode >= 300 && httpcode < 400) {
- xine_log (this->stream->xine, XINE_LOG_MSG,
+ xine_log (this->stream->xine, XINE_LOG_MSG,
_("input_http: 3xx redirection: >%d %s<\n"),
httpcode, httpstatus);
} else if (httpcode == 404) {
@@ -860,7 +868,7 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
} else if (httpcode < 200 || httpcode >= 300) {
_x_message(this->stream, XINE_MSG_CONNECTION_REFUSED, "http status not 2xx: ",
httpstatus, NULL);
- xine_log (this->stream->xine, XINE_LOG_MSG,
+ xine_log (this->stream->xine, XINE_LOG_MSG,
_("input_http: http status not 2xx: >%d %s<\n"),
httpcode, httpstatus);
return -9;
@@ -868,18 +876,18 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
} else {
if (this->contentlength == 0) {
intmax_t contentlength;
-
+
if (sscanf(this->buf, "Content-Length: %" SCNdMAX , &contentlength) == 1) {
- xine_log (this->stream->xine, XINE_LOG_MSG,
+ xine_log (this->stream->xine, XINE_LOG_MSG,
_("input_http: content length = %" PRIdMAX " bytes\n"),
contentlength);
this->contentlength = (off_t)contentlength;
}
}
-
+
if (!strncasecmp(this->buf, "Location: ", 10)) {
char *href = (this->buf + 10);
-
+
lprintf ("trying to open target of redirection: >%s<\n", href);
href = _x_canonicalise_url (this->mrl, href);
@@ -907,13 +915,13 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
(this->buf + sizeof(TAG_ICY_NAME) - 1 +
(*(this->buf + sizeof(TAG_ICY_NAME) - 1) == ' ')));
}
-
+
if (!strncasecmp(this->buf, TAG_ICY_GENRE, sizeof(TAG_ICY_GENRE) - 1)) {
_x_meta_info_set(this->stream, XINE_META_INFO_GENRE,
(this->buf + sizeof(TAG_ICY_GENRE) - 1 +
(*(this->buf + sizeof(TAG_ICY_GENRE) - 1) == ' ')));
}
-
+
/* icy-notice1 is always the same */
if (!strncasecmp(this->buf, TAG_ICY_NOTICE2, sizeof(TAG_ICY_NOTICE2) - 1)) {
char *end;
@@ -924,17 +932,21 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
(this->buf + sizeof(TAG_ICY_NOTICE2) - 1 +
(*(this->buf + sizeof(TAG_ICY_NOTICE2) - 1) == ' ')));
}
-
+
/* metadata interval (in byte) */
if (sscanf(this->buf, TAG_ICY_METAINT"%d", &this->shoutcast_metaint) == 1) {
lprintf("shoutcast_metaint: %d\n", this->shoutcast_metaint);
this->shoutcast_mode = 1;
this->shoutcast_pos = 0;
}
-
+
/* content type */
if (!strncasecmp(this->buf, TAG_CONTENT_TYPE, sizeof(TAG_CONTENT_TYPE) - 1)) {
- if (!strncasecmp(this->buf + sizeof(TAG_CONTENT_TYPE) - 1, "video/nsv", 9)) {
+ const char *type = this->buf + sizeof (TAG_CONTENT_TYPE) - 1;
+ while (isspace (*type))
+ ++type;
+ sprintf (mime_type, "%.255s", type);
+ if (!strncasecmp (type, "video/nsv", 9)) {
lprintf("shoutcast nsv detected\n");
this->is_nsv = 1;
}
@@ -944,7 +956,7 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
this->is_lastfm = 1;
}
}
-
+
if (len == -1)
done = 1;
else
@@ -977,7 +989,7 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
*newline = '\0';
lprintf("mpegurl pointing to %s\n", buf);
-
+
href = _x_canonicalise_url (this->mrl, buf);
free(this->mrl);
this->mrl = href;
@@ -992,20 +1004,23 @@ static int http_plugin_open (input_plugin_t *this_gen ) {
if (this->is_nsv) {
if (!resync_nsv(this))
return -11;
-
+
/* the first 3 chars are "NSV" */
this->preview_size = http_plugin_read_int (this, this->preview + 3, MAX_PREVIEW_SIZE - 3);
} else {
this->preview_size = http_plugin_read_int (this, this->preview, MAX_PREVIEW_SIZE);
}
if (this->preview_size < 0) {
+ this->preview_size = 0;
xine_log (this->stream->xine, XINE_LOG_MSG, _("input_http: read error %d\n"), errno);
return -12;
}
-
+
lprintf("preview_size=%"PRId64"\n", this->preview_size);
this->curpos = 0;
-
+ if (*mime_type)
+ this->mime_type = strdup (mime_type);
+
return 1;
}
@@ -1016,25 +1031,25 @@ static input_plugin_t *http_class_get_instance (input_class_t *cls_gen, xine_str
const char *mrl) {
/* http_input_class_t *cls = (http_input_class_t *) cls_gen;*/
http_input_plugin_t *this;
-
- if (strncasecmp (mrl, "http://", 7) &&
+
+ if (strncasecmp (mrl, "http://", 7) &&
strncasecmp (mrl, "unsv://", 7) &&
- strncasecmp (mrl, "peercast://pls/", 15)) {
+ strncasecmp (mrl, "peercast://pls/", 15) &&
+ !_x_url_user_agent (mrl) /* user agent hacks */) {
return NULL;
}
- this = (http_input_plugin_t *) xine_xmalloc(sizeof(http_input_plugin_t));
+ this = calloc(1, sizeof(http_input_plugin_t));
if (!strncasecmp (mrl, "peercast://pls/", 15)) {
- this->mrl = xine_xmalloc (30 + strlen(mrl) - 15);
- sprintf (this->mrl, "http://127.0.0.1:7144/stream/%s", mrl+15);
- } else {
+ asprintf (&this->mrl, "http://127.0.0.1:7144/stream/%s", mrl+15);
+ } else {
this->mrl = strdup (mrl);
}
-
+
this->stream = stream;
this->fh = -1;
this->nbc = nbc_init (this->stream);
-
+
this->input_plugin.open = http_plugin_open;
this->input_plugin.get_capabilities = http_plugin_get_capabilities;
this->input_plugin.read = http_plugin_read;
@@ -1061,7 +1076,7 @@ static const char *http_class_get_identifier (input_class_t *this_gen) {
static void http_class_dispose (input_class_t *this_gen) {
http_input_class_t *this = (http_input_class_t *) this_gen;
-
+
if(this->proxyhost_env)
free(this->proxyhost_env);
@@ -1073,7 +1088,7 @@ static void *init_class (xine_t *xine, void *data) {
config_values_t *config;
char *proxy_env;
- this = (http_input_class_t *) xine_xmalloc (sizeof (http_input_class_t));
+ this = calloc(1, sizeof (http_input_class_t));
this->xine = xine;
this->config = xine->config;
@@ -1087,28 +1102,24 @@ static void *init_class (xine_t *xine, void *data) {
this->input_class.dispose = http_class_dispose;
this->input_class.eject_media = NULL;
- /*
- * honour http_proxy envvar
+ /*
+ * honour http_proxy envvar
*/
- if((proxy_env = getenv("http_proxy")) && (strlen(proxy_env))) {
+ if((proxy_env = getenv("http_proxy")) && *proxy_env) {
int proxy_port = DEFAULT_HTTP_PORT;
- char *http_proxy = xine_xmalloc(strlen(proxy_env) + 1);
char *p;
-
+
if(!strncmp(proxy_env, "http://", 7))
proxy_env += 7;
-
- sprintf(http_proxy, "%s", proxy_env);
-
- if((p = strrchr(&http_proxy[0], ':')) && (strlen(p) > 1)) {
+
+ this->proxyhost_env = strdup(proxy_env);
+
+ if((p = strrchr(this->proxyhost_env, ':')) && (strlen(p) > 1)) {
*p++ = '\0';
proxy_port = (int) strtol(p, &p, 10);
}
-
- this->proxyhost_env = strdup(http_proxy);
+
this->proxyport_env = proxy_port;
-
- free(http_proxy);
}
else
proxy_env = NULL; /* proxy_env can be "" */
@@ -1116,7 +1127,7 @@ static void *init_class (xine_t *xine, void *data) {
/*
* proxy settings
*/
- this->proxyhost = config->register_string(config,
+ this->proxyhost = config->register_string(config,
"media.network.http_proxy_host", proxy_env ? this->proxyhost_env : "",
_("HTTP proxy host"), _("The hostname of the HTTP proxy."), 10,
proxy_host_change_cb, (void *) this);
@@ -1124,13 +1135,13 @@ static void *init_class (xine_t *xine, void *data) {
"media.network.http_proxy_port", proxy_env ? this->proxyport_env : DEFAULT_HTTP_PORT,
_("HTTP proxy port"), _("The port number of the HTTP proxy."), 10,
proxy_port_change_cb, (void *) this);
-
+
/* registered entries could be empty. Don't ignore envvar */
if(!strlen(this->proxyhost) && (proxy_env && strlen(proxy_env))) {
config->update_string(config, "media.network.http_proxy_host", this->proxyhost_env);
config->update_num(config, "media.network.http_proxy_port", this->proxyport_env);
}
-
+
this->proxyuser = config->register_string(config,
"media.network.http_proxy_user", "", _("HTTP proxy username"),
_("The user name for the HTTP proxy."), 10,
@@ -1143,7 +1154,7 @@ static void *init_class (xine_t *xine, void *data) {
"media.network.http_no_proxy", "", _("Domains for which to ignore the HTTP proxy"),
_("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);
-
+
return this;
}
@@ -1152,7 +1163,7 @@ static void *init_class (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "http", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_mms.c b/src/input/input_mms.c
index 6a1e729e6..05c6722ed 100644
--- a/src/input/input_mms.c
+++ b/src/input/input_mms.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2002-2003 the xine project
- *
+ *
* 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
@@ -76,26 +76,26 @@ typedef struct {
char *mrl;
- nbc_t *nbc;
+ nbc_t *nbc;
char scratch[1025];
int bandwidth;
int protocol; /* mmst or mmsh */
-
+
} mms_input_plugin_t;
typedef struct {
input_class_t input_class;
-
+
mms_input_plugin_t *ip;
int protocol; /* autoprobe, mmst or mmsh */
xine_t *xine;
} mms_input_class_t;
-static off_t mms_plugin_read (input_plugin_t *this_gen,
+static off_t mms_plugin_read (input_plugin_t *this_gen,
char *buf, off_t len) {
mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen;
off_t n = 0;
@@ -122,9 +122,16 @@ static buf_element_t *mms_plugin_read_block (input_plugin_t *this_gen,
lprintf ("mms_plugin_read_block: %"PRId64" bytes...\n", todo);
+ 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 = mms_plugin_read (this_gen, (char*)buf->content, todo);
if (total_bytes != todo) {
@@ -138,7 +145,7 @@ static buf_element_t *mms_plugin_read_block (input_plugin_t *this_gen,
}
static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
- mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen;
+ mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen;
off_t dest = 0;
off_t curpos = 0;
@@ -153,7 +160,7 @@ static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
curpos = mmsh_get_current_pos (this->mmsh);
break;
}
-
+
switch (origin) {
case SEEK_SET:
dest = offset;
@@ -170,7 +177,7 @@ static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
printf ("input_mms: cannot seek back!\n");
return curpos;
}
-
+
while (curpos < dest) {
int n = 0;
int diff;
@@ -188,7 +195,7 @@ static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
n = mmsh_read (this->mmsh, this->scratch, diff);
break;
}
-
+
curpos += n;
if (n < diff)
@@ -204,7 +211,7 @@ static off_t mms_plugin_seek_time (input_plugin_t *this_gen, int time_offset, in
off_t curpos = 0;
lprintf ("seek_time %d msec, origin %d\n", time_offset, origin);
-
+
switch (this->protocol) {
case PROTOCOL_MMST:
if (origin == SEEK_SET)
@@ -217,12 +224,12 @@ static off_t mms_plugin_seek_time (input_plugin_t *this_gen, int time_offset, in
curpos = mmsh_get_current_pos (this->mmsh);
break;
}
-
+
return curpos;
}
static off_t mms_plugin_get_length (input_plugin_t *this_gen) {
- mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen;
+ mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen;
off_t length = 0;
if (!this->mms)
@@ -254,7 +261,7 @@ static uint32_t mms_plugin_get_blocksize (input_plugin_t *this_gen) {
static off_t mms_plugin_get_current_pos (input_plugin_t *this_gen){
mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen;
off_t curpos = 0;
-
+
switch (this->protocol) {
case PROTOCOL_MMST:
curpos = mms_get_current_pos(this->mms);
@@ -272,10 +279,10 @@ static void mms_plugin_dispose (input_plugin_t *this_gen) {
if (this->mms)
mms_close (this->mms);
-
+
if (this->mmsh)
mmsh_close (this->mmsh);
-
+
this->mms = NULL;
this->mmsh = NULL;
@@ -283,10 +290,10 @@ static void mms_plugin_dispose (input_plugin_t *this_gen) {
nbc_close (this->nbc);
this->nbc = NULL;
}
-
+
if(this->mrl)
free(this->mrl);
-
+
free (this);
}
@@ -296,7 +303,7 @@ static const char* mms_plugin_get_mrl (input_plugin_t *this_gen) {
return this->mrl;
}
-static int mms_plugin_get_optional_data (input_plugin_t *this_gen,
+static int mms_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen;
@@ -312,7 +319,7 @@ static int mms_plugin_get_optional_data (input_plugin_t *this_gen,
break;
}
break;
-
+
default:
return INPUT_OPTIONAL_UNSUPPORTED;
break;
@@ -350,7 +357,7 @@ static int mms_plugin_open (input_plugin_t *this_gen) {
mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen;
mms_t *mms = NULL;
mmsh_t *mmsh = NULL;
-
+
switch (this->protocol) {
case PROTOCOL_UNDEFINED:
mms = mms_connect (this->stream, this->mrl, this->bandwidth);
@@ -368,18 +375,18 @@ static int mms_plugin_open (input_plugin_t *this_gen) {
mmsh = mmsh_connect (this->stream, this->mrl, this->bandwidth);
break;
}
-
+
if (!mms && !mmsh) {
return 0;
}
-
+
this->mms = mms;
this->mmsh = mmsh;
-
+
return 1;
}
-static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
+static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
const char *data) {
mms_input_class_t *cls = (mms_input_class_t *) cls_gen;
@@ -387,7 +394,7 @@ static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stre
char *mrl = strdup(data);
xine_cfg_entry_t bandwidth_entry;
int protocol;
-
+
lprintf ("trying to open '%s'\n", mrl);
if (!strncasecmp (mrl, "mms://", 6)) {
@@ -401,16 +408,16 @@ static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stre
return NULL;
}
- this = (mms_input_plugin_t *) xine_xmalloc (sizeof (mms_input_plugin_t));
+ this = calloc(1, sizeof (mms_input_plugin_t));
cls->ip = this;
this->stream = stream;
this->mms = NULL;
this->mmsh = NULL;
this->protocol = protocol;
- this->mrl = mrl;
+ this->mrl = mrl;
this->nbc = nbc_init (this->stream);
- if (xine_config_lookup_entry (stream->xine, "media.network.bandwidth",
+ if (xine_config_lookup_entry (stream->xine, "media.network.bandwidth",
&bandwidth_entry)) {
bandwidth_changed_cb(cls, &bandwidth_entry);
}
@@ -429,7 +436,7 @@ static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stre
this->input_plugin.get_optional_data = mms_plugin_get_optional_data;
this->input_plugin.input_class = cls_gen;
-
+
return &this->input_plugin;
}
@@ -449,7 +456,7 @@ static void mms_class_dispose (input_class_t *this_gen) {
mms_input_class_t *this = (mms_input_class_t *) this_gen;
this->xine->config->unregister_callback(this->xine->config,
- "media.network.bandwidth");
+ "media.network.bandwidth");
this->xine->config->unregister_callback(this->xine->config,
"media.network.mms_protocol");
free (this);
@@ -459,7 +466,7 @@ static void *init_class (xine_t *xine, void *data) {
mms_input_class_t *this;
- this = (mms_input_class_t *) xine_xmalloc (sizeof (mms_input_class_t));
+ this = calloc(1, sizeof (mms_input_class_t));
this->xine = xine;
this->ip = NULL;
@@ -481,12 +488,12 @@ static void *init_class (xine_t *xine, void *data) {
0, bandwidth_changed_cb, (void*) this);
this->protocol = xine->config->register_enum(xine->config,
- "media.network.mms_protocol",
- 0,
- mms_protocol_strs,
+ "media.network.mms_protocol",
+ 0,
+ mms_protocol_strs,
_("MMS protocol"),
_("Select the protocol to encapsulate MMS.\nTCP is better but you may need HTTP behind a firewall."),
- 20,
+ 20,
protocol_changed_cb, (void*)this);
return this;
@@ -497,7 +504,7 @@ static void *init_class (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "mms", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_net.c b/src/input/input_net.c
index fe78c93f4..55339b2bb 100644
--- a/src/input/input_net.c
+++ b/src/input/input_net.c
@@ -1,18 +1,18 @@
-/*
+/*
* Copyright (C) 2000-2003 the xine project
- *
+ *
* 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
@@ -21,9 +21,9 @@
* other end and you can watch tv anywhere in the house ..)
*
* how to set up mp1e for use with this plugin:
- *
+ *
* use mp1 to capture the live stream, e.g.
- * mp1e -b 1200 -R 4,32 -a 0 -B 160 -v >live.mpg
+ * mp1e -b 1200 -R 4,32 -a 0 -B 160 -v >live.mpg
*
* add an extra service "xine" to /etc/services and /etc/inetd.conf, e.g.:
* /etc/services:
@@ -78,11 +78,11 @@ typedef struct {
input_plugin_t input_plugin;
xine_stream_t *stream;
-
+
int fh;
char *mrl;
char *host_port;
-
+
char preview[MAX_PREVIEW_SIZE];
off_t preview_size;
@@ -122,21 +122,21 @@ static int host_connect_attempt_ipv4(struct in_addr ia, int port, xine_t *xine)
return -1;
}
- sin.sin_family = AF_INET;
+ sin.sin_family = AF_INET;
sin.sin_addr = ia;
sin.sin_port = htons(port);
-
+
#ifndef WIN32
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && errno != EINPROGRESS)
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && errno != EINPROGRESS)
#else
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && WSAGetLastError() != WSAEINPROGRESS)
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && WSAGetLastError() != WSAEINPROGRESS)
#endif
{
xine_log(xine, XINE_LOG_MSG,
_("input_net: connect(): %s\n"), strerror(errno));
close(s);
return -1;
- }
+ }
return s;
}
@@ -144,7 +144,7 @@ static int host_connect_attempt_ipv4(struct in_addr ia, int port, xine_t *xine)
static int host_connect_attempt(int family, struct sockaddr* sin, int addrlen, xine_t *xine) {
int s;
-
+
s = socket(family, SOCK_STREAM, IPPROTO_TCP);
if (s==-1) {
xine_log(xine, XINE_LOG_MSG,
@@ -153,16 +153,16 @@ static int host_connect_attempt(int family, struct sockaddr* sin, int addrlen, x
}
#ifndef WIN32
- if (connect(s, sin, addrlen)==-1 && errno != EINPROGRESS)
+ if (connect(s, sin, addrlen)==-1 && errno != EINPROGRESS)
#else
- if (connect(s, sin, addrlen)==-1 && WSAGetLastError() != WSAEINPROGRESS)
+ if (connect(s, sin, addrlen)==-1 && WSAGetLastError() != WSAEINPROGRESS)
#endif
{
xine_log(xine, XINE_LOG_MSG,
_("input_net: connect(): %s\n"), strerror(errno));
close(s);
return -1;
- }
+ }
return s;
}
@@ -173,14 +173,14 @@ static int host_connect_ipv4(const char *host, int port, xine_t *xine) {
struct hostent *h;
int i;
int s;
-
+
h = gethostbyname(host);
if (h==NULL) {
xine_log(xine, XINE_LOG_MSG,
_("input_net: unable to resolve '%s'.\n"), host);
return -1;
}
-
+
for (i=0; h->h_addr_list[i]; i++) {
struct in_addr ia;
memcpy (&ia, h->h_addr_list[i],4);
@@ -205,36 +205,36 @@ static int host_connect(const char *host, int port, xine_t *xine) {
int error;
char strport[16];
int s;
-
+
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
- hints.ai_family = PF_UNSPEC;
-
+ hints.ai_family = PF_UNSPEC;
+
snprintf(strport, sizeof(strport), "%d", port);
lprintf("Resolving host '%s' at port '%s'\n", host, strport);
error = getaddrinfo(host, strport, &hints, &res);
-
+
if (error) {
-
+
xine_log(xine, XINE_LOG_MSG,
_("input_net: unable to resolve '%s'.\n"), host);
return -1;
}
-
+
/* We loop over all addresses and try to connect */
tmpaddr = res;
while (tmpaddr) {
-
- s = host_connect_attempt (tmpaddr->ai_family,
+
+ s = host_connect_attempt (tmpaddr->ai_family,
tmpaddr->ai_addr, tmpaddr->ai_addrlen, xine);
if (s != -1)
return s;
tmpaddr = tmpaddr->ai_next;
}
-
+
xine_log(xine, XINE_LOG_MSG,
_("input_net: unable to connect to '%s'.\n"), host);
return -1;
@@ -246,13 +246,16 @@ static int host_connect(const char *host, int port, xine_t *xine) {
#define LOW_WATER_MARK 50
#define HIGH_WATER_MARK 100
-static off_t net_plugin_read (input_plugin_t *this_gen,
+static off_t net_plugin_read (input_plugin_t *this_gen,
char *buf, off_t len) {
net_input_plugin_t *this = (net_input_plugin_t *) this_gen;
off_t n, total;
lprintf("reading %" PRIdMAX " bytes...\n", (intmax_t)len);
+ if (len < 0)
+ return -1;
+
total=0;
if (this->curpos < this->preview_size) {
n = this->preview_size - this->curpos;
@@ -270,7 +273,7 @@ static off_t net_plugin_read (input_plugin_t *this_gen,
n = _x_read_abort (this->stream, this->fh, &buf[total], len-total);
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_net: got %" PRIdMAX " bytes (%" PRIdMAX "/%" PRIdMAX " bytes read)\n", (intmax_t)n, (intmax_t)total, (intmax_t)len);
-
+
if (n < 0) {
_x_message(this->stream, XINE_MSG_READ_ERROR, this->host_port, NULL);
return 0;
@@ -282,15 +285,22 @@ static off_t net_plugin_read (input_plugin_t *this_gen,
return total;
}
-static buf_element_t *net_plugin_read_block (input_plugin_t *this_gen,
+static buf_element_t *net_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t todo) {
/* net_input_plugin_t *this = (net_input_plugin_t *) this_gen; */
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
off_t total_bytes;
+ 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 = net_plugin_read (this_gen, (char*)buf->content, todo);
if (total_bytes != todo) {
@@ -331,7 +341,7 @@ static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -353,7 +363,7 @@ static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
offset -= this->curpos;
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -371,7 +381,7 @@ static const char* net_plugin_get_mrl (input_plugin_t *this_gen) {
return this->mrl;
}
-static int net_plugin_get_optional_data (input_plugin_t *this_gen,
+static int net_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
net_input_plugin_t *this = (net_input_plugin_t *) this_gen;
@@ -394,10 +404,10 @@ static void net_plugin_dispose (input_plugin_t *this_gen ) {
close(this->fh);
this->fh = -1;
}
-
+
free (this->mrl);
free (this->host_port);
-
+
if (this->nbc) {
nbc_close (this->nbc);
this->nbc = NULL;
@@ -454,33 +464,33 @@ static input_plugin_t *net_class_get_instance (input_class_t *cls_gen, xine_stre
if (!strncasecmp (mrl, "tcp://", 6)) {
filename = (char *) &mrl[6];
-
+
if((!filename) || (strlen(filename) == 0)) {
return NULL;
}
-
+
nbc = nbc_init (stream);
-
+
} else if (!strncasecmp (mrl, "slave://", 8)) {
-
+
filename = (char *) &mrl[8];
-
+
if((!filename) || (strlen(filename) == 0)) {
return NULL;
}
-
+
/* the only difference for slave:// is that network buffering control
* is not used. otherwise, dvd still menus are not displayed (it freezes
* with "buffering..." all the time)
*/
-
+
nbc = NULL;
-
+
} else {
return NULL;
}
- this = xine_xmalloc(sizeof(net_input_plugin_t));
+ this = calloc(1, sizeof(net_input_plugin_t));
this->mrl = strdup(mrl);
this->host_port = strdup(filename);
this->stream = stream;
@@ -509,7 +519,7 @@ static input_plugin_t *net_class_get_instance (input_class_t *cls_gen, xine_stre
/*
* net plugin class
*/
-
+
static const char *net_class_get_description (input_class_t *this_gen) {
return _("net input plugin as shipped with xine");
}
@@ -528,7 +538,7 @@ static void *init_class (xine_t *xine, void *data) {
net_input_class_t *this;
- this = (net_input_class_t *) xine_xmalloc(sizeof(net_input_class_t));
+ this = calloc(1, sizeof(net_input_class_t));
this->config = xine->config;
this->xine = xine;
@@ -548,7 +558,7 @@ static void *init_class (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT, 17, "tcp", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h
index 1d1e5cf53..c2cfd6455 100644
--- a/src/input/input_plugin.h
+++ b/src/input/input_plugin.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2000-2004 the xine project
- *
+ *
* 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
@@ -36,7 +36,7 @@
#endif
#define INPUT_PLUGIN_IFACE_VERSION 17
-
+
typedef struct input_class_s input_class_t ;
typedef struct input_plugin_s input_plugin_t;
@@ -55,7 +55,7 @@ struct input_class_s {
const char* (*get_identifier) (input_class_t *this);
/*
- * return human readable (verbose = 1 line) description for
+ * return human readable (verbose = 1 line) description for
* this plugin class
*/
const char* (*get_description) (input_class_t *this);
@@ -97,7 +97,7 @@ struct input_plugin_s {
* return capabilities of the current playable entity. See
* get_current_pos below for a description of a "playable entity"
* Capabilities a created by "OR"ing a mask of constants listed
- * below which start "INPUT_CAP".
+ * below which start "INPUT_CAP".
*
* depending on the values set, some of the functions below
* will or will not get called or should (not) be able to
@@ -128,7 +128,7 @@ struct input_plugin_s {
/*
- * seek position, return new position
+ * seek position, return new position
*
* if seeking failed, -1 is returned
*/
@@ -136,7 +136,7 @@ struct input_plugin_s {
/*
- * seek to time position, return new position
+ * seek to time position, return new position
* time_offset is given in miliseconds
*
* if seeking failed, -1 is returned
@@ -153,7 +153,7 @@ struct input_plugin_s {
*/
off_t (*get_current_pos) (input_plugin_t *this);
-
+
/*
* get current time position in stream in miliseconds.
*
@@ -165,7 +165,7 @@ struct input_plugin_s {
/*
* return number of bytes in the next playable entity or -1 if the
* input is unlimited, as would be the case in a network stream.
- *
+ *
* A "playable entity" tends to be the entities listed in a playback
* list or the units on which playback control generally works on.
* It might be the number of bytes in a VCD "segment" or "track" (if
@@ -186,7 +186,7 @@ struct input_plugin_s {
* return block size in bytes of next complete playable entity (if
* supported, 0 otherwise). See the description above under
* get_length for a description of a "complete playable entity".
- *
+ *
* this block size is only used for mpeg streams stored on
* a block oriented storage media, e.g. DVDs and VCDs, to speed
* up the demuxing process. only set this (and the INPUT_CAP_BLOCK
@@ -231,11 +231,11 @@ struct input_plugin_s {
#define INPUT_CAP_NOCAP 0x00000000
/*
- * INPUT_CAP_SEEKABLE:
- * seek () works reliably.
+ * INPUT_CAP_SEEKABLE:
+ * seek () works reliably.
* even for plugins that do not have this flag set
- * it is a good idea to implement the seek() function
- * in a "best effort" style anyway, so at least
+ * it is a good idea to implement the seek() function
+ * in a "best effort" style anyway, so at least
* throw away data for network streams when seeking forward
*/
@@ -243,9 +243,9 @@ struct input_plugin_s {
/*
* INPUT_CAP_BLOCK:
- * means more or less that a block device sits behind
- * this input plugin. get_blocksize must be implemented.
- * will be used for fast and efficient demuxing of
+ * means more or less that a block device sits behind
+ * this input plugin. get_blocksize must be implemented.
+ * will be used for fast and efficient demuxing of
* mpeg streams (demux_mpeg_block).
*/
@@ -254,8 +254,8 @@ struct input_plugin_s {
/*
* INPUT_CAP_AUDIOLANG:
* INPUT_CAP_SPULANG:
- * input plugin knows something about audio/spu languages,
- * e.g. knows that audio stream #0 is english,
+ * input plugin knows something about audio/spu languages,
+ * e.g. knows that audio stream #0 is english,
* audio stream #1 is german, ...
* *((int *)data) will provide the requested channel number
* and awaits the language back in (char *)data
@@ -263,20 +263,20 @@ struct input_plugin_s {
#define INPUT_CAP_AUDIOLANG 0x00000008
#define INPUT_CAP_SPULANG 0x00000010
-
-/*
+
+/*
* INPUT_CAP_PREVIEW:
- * get_optional_data can handle INPUT_OPTIONAL_DATA_PREVIEW
- * so a non-seekable stream plugin can povide the first
- * few bytes for demuxers to look at them and decide wheter
- * they can handle the stream or not. the preview data must
- * be buffered and delivered again through subsequent
+ * get_optional_data can handle INPUT_OPTIONAL_DATA_PREVIEW
+ * so a non-seekable stream plugin can povide the first
+ * few bytes for demuxers to look at them and decide wheter
+ * they can handle the stream or not. the preview data must
+ * be buffered and delivered again through subsequent
* read() calls.
- * caller must provide a buffer allocated with at least
+ * caller must provide a buffer allocated with at least
* MAX_PREVIEW_SIZE bytes.
*/
-#define INPUT_CAP_PREVIEW 0x00000040
+#define INPUT_CAP_PREVIEW 0x00000040
/*
* INPUT_CAP_CHAPTERS:
@@ -307,6 +307,13 @@ struct input_plugin_s {
#define INPUT_OPTIONAL_DATA_SPULANG 3
#define INPUT_OPTIONAL_DATA_PREVIEW 7
+/* buffer is a const char **; the string is freed by the input plugin. */
+#define INPUT_OPTIONAL_DATA_MIME_TYPE 8
+/* buffer is unused; true if the demuxer should be determined by the MIME type */
+#define INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE 9
+/* buffer is a const char **; the string is static or freed by the input plugin. */
+#define INPUT_OPTIONAL_DATA_DEMUXER 10
+
#define MAX_MRL_ENTRIES 255
#define MAX_PREVIEW_SIZE 4096
@@ -333,65 +340,38 @@ struct input_plugin_s {
/*
* Freeing/zeroing all of entries of given mrl.
*/
-#define MRL_ZERO(m) { \
- if((m)) { \
- if((m)->origin) \
- free((m)->origin); \
- if((m)->mrl) \
- free((m)->mrl); \
- if((m)->link) \
- free((m)->link); \
- (m)->origin = NULL; \
- (m)->mrl = NULL; \
- (m)->link = NULL; \
- (m)->type = 0; \
- (m)->size = (off_t) 0; \
- } \
-}
+#define MRL_ZERO(m) { \
+ if((m)) { \
+ free((m)->origin); \
+ free((m)->mrl); \
+ free((m)->link); \
+ (m)->origin = NULL; \
+ (m)->mrl = NULL; \
+ (m)->link = NULL; \
+ (m)->type = 0; \
+ (m)->size = (off_t) 0; \
+ } \
+ }
/*
* Duplicate two mrls entries (s = source, d = destination).
*/
-#define MRL_DUPLICATE(s, d) { \
- _x_assert((s) != NULL); \
- _x_assert((d) != NULL); \
- \
- if((s)->origin) { \
- if((d)->origin) { \
- (d)->origin = (char *) realloc((d)->origin, strlen((s)->origin) + 1); \
- sprintf((d)->origin, "%s", (s)->origin); \
- } \
- else \
- (d)->origin = strdup((s)->origin); \
- } \
- else \
- (d)->origin = NULL; \
- \
- if((s)->mrl) { \
- if((d)->mrl) { \
- (d)->mrl = (char *) realloc((d)->mrl, strlen((s)->mrl) + 1); \
- sprintf((d)->mrl, "%s", (s)->mrl); \
- } \
- else \
- (d)->mrl = strdup((s)->mrl); \
- } \
- else \
- (d)->mrl = NULL; \
- \
- if((s)->link) { \
- if((d)->link) { \
- (d)->link = (char *) realloc((d)->link, strlen((s)->link) + 1); \
- sprintf((d)->link, "%s", (s)->link); \
- } \
- else \
- (d)->link = strdup((s)->link); \
- } \
- else \
- (d)->link = NULL; \
- \
- (d)->type = (s)->type; \
- (d)->size = (s)->size; \
-}
+#define MRL_DUPLICATE(s, d) { \
+ _x_assert((s) != NULL); \
+ _x_assert((d) != NULL); \
+ \
+ free((d)->origin); \
+ (d)->origin = (s)->origin ? strdup((s)->origin) : NULL; \
+ \
+ free((d)->mrl); \
+ (d)->mrl = (s)->mrl ? strdup((s)->mrl) : NULL; \
+ \
+ free((d)->link); \
+ (d)->link = (s)->link ? strdup((s)->link) : NULL; \
+ \
+ (d)->type = (s)->type; \
+ (d)->size = (s)->size; \
+ }
/*
* Duplicate two arrays of mrls (s = source, d = destination).
diff --git a/src/input/input_pnm.c b/src/input/input_pnm.c
index 680c5b1e8..6d9809a6a 100644
--- a/src/input/input_pnm.c
+++ b/src/input/input_pnm.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2002-2003 the xine project
- *
+ *
* 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
@@ -61,36 +61,35 @@ typedef struct {
input_plugin_t input_plugin;
xine_stream_t *stream;
-
+
pnm_t *pnm;
char *mrl;
off_t curpos;
- nbc_t *nbc;
+ nbc_t *nbc;
char scratch[BUFSIZE];
} pnm_input_plugin_t;
-static off_t pnm_plugin_read (input_plugin_t *this_gen,
+static off_t pnm_plugin_read (input_plugin_t *this_gen,
char *buf, off_t len) {
pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen;
off_t n;
lprintf ("pnm_plugin_read: %"PRId64" bytes ...\n", len);
- nbc_check_buffers (this->nbc);
-
n = pnm_read (this->pnm, buf, len);
- this->curpos += n;
+ if (n >= 0)
+ this->curpos += n;
return n;
}
-static buf_element_t *pnm_plugin_read_block (input_plugin_t *this_gen,
+static buf_element_t *pnm_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t todo) {
/*pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; */
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
@@ -98,9 +97,16 @@ static buf_element_t *pnm_plugin_read_block (input_plugin_t *this_gen,
lprintf ("pnm_plugin_read_block: %"PRId64" bytes...\n", todo);
+ 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 = pnm_plugin_read (this_gen, (char*)buf->content, todo);
if (total_bytes != todo) {
@@ -125,10 +131,16 @@ static off_t pnm_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- this->curpos += pnm_plugin_read (this_gen, this->scratch, BUFSIZE);
+ off_t n = pnm_plugin_read (this_gen, this->scratch, BUFSIZE);
+ if (n <= 0)
+ return this->curpos;
+ this->curpos += n;
}
- this->curpos += pnm_plugin_read (this_gen, this->scratch, offset);
+ off_t n = pnm_plugin_read (this_gen, this->scratch, offset);
+ if (n <= 0)
+ return this->curpos;
+ this->curpos += n;
}
return this->curpos;
@@ -137,7 +149,7 @@ static off_t pnm_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
static off_t pnm_plugin_get_length (input_plugin_t *this_gen) {
/*
- pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen;
+ pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen;
off_t length;
*/
@@ -174,10 +186,10 @@ static void pnm_plugin_dispose (input_plugin_t *this_gen) {
nbc_close (this->nbc);
this->nbc = NULL;
}
-
+
if(this->mrl)
free(this->mrl);
-
+
free (this);
}
@@ -187,7 +199,7 @@ static const char* pnm_plugin_get_mrl (input_plugin_t *this_gen) {
return this->mrl;
}
-static int pnm_plugin_get_optional_data (input_plugin_t *this_gen,
+static int pnm_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen;
@@ -215,11 +227,11 @@ static int pnm_plugin_open (input_plugin_t *this_gen) {
}
this->pnm = pnm;
-
+
return 1;
}
-static input_plugin_t *pnm_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
+static input_plugin_t *pnm_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
const char *data) {
/* pnm_input_class_t *cls = (pnm_input_class_t *) cls_gen; */
@@ -231,13 +243,13 @@ static input_plugin_t *pnm_class_get_instance (input_class_t *cls_gen, xine_stre
return NULL;
}
- this = (pnm_input_plugin_t *) xine_xmalloc (sizeof (pnm_input_plugin_t));
+ this = calloc(1, sizeof (pnm_input_plugin_t));
this->stream = stream;
this->pnm = NULL;
- this->mrl = mrl;
+ this->mrl = mrl;
this->nbc = nbc_init (this->stream);
-
+
this->input_plugin.open = pnm_plugin_open;
this->input_plugin.get_capabilities = pnm_plugin_get_capabilities;
this->input_plugin.read = pnm_plugin_read;
@@ -250,7 +262,7 @@ static input_plugin_t *pnm_class_get_instance (input_class_t *cls_gen, xine_stre
this->input_plugin.dispose = pnm_plugin_dispose;
this->input_plugin.get_optional_data = pnm_plugin_get_optional_data;
this->input_plugin.input_class = cls_gen;
-
+
return &this->input_plugin;
}
@@ -276,7 +288,7 @@ static void *init_class (xine_t *xine, void *data) {
pnm_input_class_t *this;
- this = (pnm_input_class_t *) xine_xmalloc (sizeof (pnm_input_class_t));
+ this = calloc(1, sizeof (pnm_input_class_t));
this->xine = xine;
@@ -296,7 +308,7 @@ static void *init_class (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT, 17, "pnm", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c
index f07e98133..5e7f7bca9 100644
--- a/src/input/input_pvr.c
+++ b/src/input/input_pvr.c
@@ -4,17 +4,17 @@
* This plugin was sponsored by 1Control
*
* 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
@@ -32,26 +32,26 @@
* - audio.synchronization.av_sync_method=resample
* - ivtv driver (01 Jul 2003 cvs is known to work)
*
- * MRL:
+ * MRL:
* pvr:/<prefix_to_tmp_files>!<prefix_to_saved_files>!<max_page_age>
*
- * usage:
+ * usage:
* xine pvr:/<prefix_to_tmp_files>\!<prefix_to_saved_files>\!<max_page_age>
*/
/**************************************************************************
-
+
Programmer's note (or how to write your PVR frontend):
-
+
- in order to use live pause functionality you must capture data to disk.
this is done using XINE_EVENT_SET_V4L2 event. it is important to set the
inputs/channel/frequency you want to capture data from.
-
+
comments:
1) session_id must be set: it is used to create the temporary filenames.
-
+
2) if session_id = -1 no data will be recorded to disk (no pause/replay)
-
+
3) if session_id is the same as previous value it will just set the "sync
point". sync point (show_page) may be used by the PVR frontend to tell
that a new show has began. of course, the PVR frontend should be aware
@@ -60,18 +60,18 @@
- when user wants to start recording (that is: temporary data will be made
permanent) it should issue a XINE_EVENT_PVR_SAVE.
mode can be one of the following:
-
+
-1 = do nothing, just set the name (see below)
0 = truncate current session and save from now on
1 = save from last sync point
2 = save everything on current session
-
+
saving actually means just marking the current pages as not temporary.
when a session is finished, instead of erasing the files they will be
renamed using the save file prefix.
- the permanent name can be set in two ways:
-
+
1) passing a name with the XINE_EVENT_PVR_SAVE before closing the
current session. (id = -1)
2) when a saved session is closed without setting the name, it will be
@@ -81,7 +81,7 @@
pass back a XINE_EVENT_PVR_SAVE with id set. pvr plugin will rename
the files again.
-***************************************************************************/
+***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -167,7 +167,7 @@ typedef struct {
config_values_t *config;
char *devname;
-
+
} pvr_input_class_t;
@@ -175,18 +175,18 @@ typedef struct {
input_plugin_t input_plugin;
pvr_input_class_t *class;
-
+
xine_stream_t *stream;
-
+
xine_event_queue_t *event_queue;
-
+
pvrscr_t *scr;
int scr_tunning;
int speed_before_pause;
-
+
uint32_t session; /* session number used to identify the pvr file */
int new_session; /* force going to realtime for new sessions */
-
+
int dev_fd; /* fd of the mpeg2 encoder device */
int rec_fd; /* fd of the current recording file (session/page) */
int play_fd; /* fd of the current playback (-1 when realtime) */
@@ -200,22 +200,22 @@ typedef struct {
uint32_t show_page; /* first page of current show */
uint32_t save_page; /* first page to save */
uint32_t page_block[MAX_PAGES]; /* first block of each page */
-
+
char *mrl;
char *tmp_prefix;
char *save_prefix;
char *save_name;
xine_list_t *saved_shows;
int saved_id;
-
+
time_t start_time; /* time when recording started */
time_t show_time; /* time when current show started */
-
+
/* buffer to pass data from pvr thread to xine */
uint8_t data[PVR_BLOCK_SIZE];
int valid_data;
int want_data;
-
+
pthread_mutex_t lock;
pthread_mutex_t dev_lock;
pthread_cond_t has_valid_data;
@@ -224,14 +224,14 @@ typedef struct {
int pvr_running;
int pvr_playing;
int pvr_play_paused;
-
+
int preview_buffers;
-
+
/* device properties */
int input;
int channel;
- uint32_t frequency;
-
+ uint32_t frequency;
+
} pvr_input_plugin_t;
typedef struct {
@@ -245,7 +245,7 @@ typedef struct {
* unix System Clock Reference + fine tunning
*
* on an ideal world we would be using scr from mpeg2
- * encoder just like dxr3 does.
+ * encoder just like dxr3 does.
* unfortunately it is not supported by ivtv driver,
* and perhaps not even possible with wintv cards.
*
@@ -279,19 +279,19 @@ static void pvrscr_set_pivot (pvrscr_t *this) {
struct timeval tv;
int64_t pts;
- double pts_calc;
+ double pts_calc;
xine_monotonic_clock(&tv, NULL);
pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
pts = this->cur_pts + pts_calc;
-/* This next part introduces a one off inaccuracy
- * to the scr due to rounding tv to pts.
+/* This next part introduces a one off inaccuracy
+ * to the scr due to rounding tv to pts.
*/
this->cur_time.tv_sec=tv.tv_sec;
this->cur_time.tv_usec=tv.tv_usec;
- this->cur_pts=pts;
+ this->cur_pts=pts;
return ;
}
@@ -303,7 +303,7 @@ static int pvrscr_set_speed (scr_plugin_t *scr, int speed) {
pvrscr_set_pivot( this );
this->xine_speed = speed;
- this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
+ this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
this->speed_tunning;
pthread_mutex_unlock (&this->lock);
@@ -316,7 +316,7 @@ static void pvrscr_speed_tunning (pvrscr_t *this, double factor) {
pvrscr_set_pivot( this );
this->speed_tunning = factor;
- this->speed_factor = (double) this->xine_speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
+ this->speed_factor = (double) this->xine_speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
this->speed_tunning;
pthread_mutex_unlock (&this->lock);
@@ -345,7 +345,7 @@ static void pvrscr_start (scr_plugin_t *scr, int64_t start_vpts) {
this->cur_pts = start_vpts;
pthread_mutex_unlock (&this->lock);
-
+
pvrscr_set_speed (&this->scr, XINE_FINE_SPEED_NORMAL);
}
@@ -354,16 +354,16 @@ static int64_t pvrscr_get_current (scr_plugin_t *scr) {
struct timeval tv;
int64_t pts;
- double pts_calc;
+ double pts_calc;
pthread_mutex_lock (&this->lock);
xine_monotonic_clock(&tv, NULL);
-
+
pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
pts = this->cur_pts + pts_calc;
-
+
pthread_mutex_unlock (&this->lock);
return pts;
@@ -376,10 +376,10 @@ static void pvrscr_exit (scr_plugin_t *scr) {
free(this);
}
-static pvrscr_t* pvrscr_init (void) {
+static pvrscr_t *XINE_MALLOC pvrscr_init (void) {
pvrscr_t *this;
- this = (pvrscr_t *) xine_xmalloc(sizeof(pvrscr_t));
+ this = calloc(1, sizeof(pvrscr_t));
this->scr.interface_version = 3;
this->scr.get_priority = pvrscr_get_priority;
@@ -388,9 +388,9 @@ static pvrscr_t* pvrscr_init (void) {
this->scr.start = pvrscr_start;
this->scr.get_current = pvrscr_get_current;
this->scr.exit = pvrscr_exit;
-
+
pthread_mutex_init (&this->lock, NULL);
-
+
pvrscr_speed_tunning(this, 1.0 );
pvrscr_set_speed (&this->scr, XINE_SPEED_PAUSE);
#ifdef SCRLOG
@@ -405,10 +405,10 @@ static pvrscr_t* pvrscr_init (void) {
static uint32_t block_to_page(pvr_input_plugin_t *this, uint32_t block) {
uint32_t page;
-
+
for( page = 0; page < this->rec_page; page++ ) {
if( block < this->page_block[page+1] )
- break;
+ break;
}
return page;
}
@@ -424,6 +424,9 @@ static uint32_t pvr_plugin_get_capabilities (input_plugin_t *this_gen) {
static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
/*pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;*/
+ if (len < 4)
+ return -1;
+
/* FIXME: Tricking the demux_mpeg_block plugin */
buf[0] = 0;
buf[1] = 0;
@@ -433,7 +436,7 @@ static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
}
-/*
+/*
* this function will adjust playback speed to control buffer utilization.
* we must avoid:
* - overflow: buffer runs full. no data is read from the mpeg2 card so it will discard
@@ -444,15 +447,15 @@ static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
* OBS: use with audio.synchronization.av_sync_method=resample
*/
static void pvr_adjust_realtime_speed(pvr_input_plugin_t *this, fifo_buffer_t *fifo, int speed ) {
-
+
int num_used, num_free;
int scr_tunning = this->scr_tunning;
-
+
num_used = fifo->size(fifo);
num_free = fifo->num_free(fifo);
-
+
if( num_used == 0 && scr_tunning != -2 ) {
-
+
/* buffer is empty. pause it for a while */
this->scr_tunning = -2; /* marked as paused */
pvrscr_speed_tunning(this->scr, 1.0);
@@ -461,77 +464,67 @@ static void pvr_adjust_realtime_speed(pvr_input_plugin_t *this, fifo_buffer_t *f
#ifdef SCRLOG
printf("input_pvr: buffer empty, pausing playback\n" );
#endif
-
+
} else if( scr_tunning == -2 ) {
-
+
/* currently paused, revert to normal if 1/3 full */
if( 2*num_used > num_free ) {
this->scr_tunning = 0;
-
+
pvrscr_speed_tunning(this->scr, 1.0 );
_x_set_speed(this->stream, this->speed_before_pause);
#ifdef SCRLOG
printf("input_pvr: resuming playback\n" );
#endif
}
-
+
} else if( speed == XINE_SPEED_NORMAL && this->play_fd == -1 ) {
-
+
/* when playing realtime, adjust the scr to make xine buffers half full */
if( num_used > 2*num_free )
- scr_tunning = +1; /* play faster */
+ scr_tunning = +1; /* play faster */
else if( num_free > 2*num_used )
scr_tunning = -1; /* play slower */
else if( (scr_tunning > 0 && num_free > num_used) ||
(scr_tunning < 0 && num_used > num_free) )
scr_tunning = 0;
-
+
if( scr_tunning != this->scr_tunning ) {
this->scr_tunning = scr_tunning;
#ifdef SCRLOG
printf("input_pvr: scr_tunning = %d (used: %d free: %d)\n", scr_tunning, num_used, num_free );
#endif
-
+
/* make it play .5% faster or slower */
pvrscr_speed_tunning(this->scr, 1.0 + (0.005 * scr_tunning) );
}
-
+
} else if( this->scr_tunning ) {
this->scr_tunning = 0;
-
+
pvrscr_speed_tunning(this->scr, 1.0 );
}
}
#define PVR_FILENAME "%s%08d_%08d.vob"
-#define PVR_FILENAME_SIZE 1+8+1+8+4+1
static char *make_temp_name(pvr_input_plugin_t *this, int page) {
-
char *filename;
-
- int size = strlen(this->tmp_prefix)+PVR_FILENAME_SIZE;
- filename = malloc(size);
-
- snprintf(filename, size, PVR_FILENAME, this->tmp_prefix, this->session, page);
-
+
+ asprintf(&filename, PVR_FILENAME, this->tmp_prefix, this->session, page);
+
return filename;
}
-
+
#define SAVE_BASE_FILENAME "ch%03d %02d-%02d-%04d %02d:%02d:%02d"
-#define SAVE_BASE_FILENAME_SIZE 2+3+1+2+1+2+1+4+1+2+1+2+1+2+1
-
+
static char *make_base_save_name(int channel, time_t tm) {
-
struct tm rec_time;
char *filename;
-
- int size = SAVE_BASE_FILENAME_SIZE;
- filename = malloc(size);
-
+
localtime_r(&tm, &rec_time);
-
- snprintf(filename, size, SAVE_BASE_FILENAME,
+
+ asprintf(&filename, SAVE_BASE_FILENAME,
channel, rec_time.tm_mon+1, rec_time.tm_mday,
rec_time.tm_year+1900, rec_time.tm_hour, rec_time.tm_min,
rec_time.tm_sec);
@@ -539,17 +532,12 @@ static char *make_base_save_name(int channel, time_t tm) {
}
#define SAVE_FILENAME "%s%s_%04d.vob"
-#define SAVE_FILENAME_SIZE 1+4+4+1
static char *make_save_name(pvr_input_plugin_t *this, char *base, int page) {
-
char *filename;
-
- int size = strlen(this->save_prefix)+strlen(base)+SAVE_FILENAME_SIZE;
- filename = malloc(size);
-
- snprintf(filename, size, SAVE_FILENAME, this->save_prefix, base, page);
-
+
+ asprintf(&filename, SAVE_FILENAME, this->save_prefix, base, page);
+
return filename;
}
@@ -574,27 +562,27 @@ static void pvr_report_realtime (pvr_input_plugin_t *this, int mode) {
* close current recording page and open a new one
*/
static int pvr_break_rec_page (pvr_input_plugin_t *this) {
-
+
char *filename;
-
+
if( this->session == (unsigned)-1 ) /* not recording */
return 1;
-
+
if( this->rec_fd != -1 && this->rec_fd != this->play_fd ) {
- close(this->rec_fd);
+ close(this->rec_fd);
}
-
+
if( this->rec_fd == -1 )
this->rec_page = 0;
else
this->rec_page++;
-
+
this->page_block[this->rec_page] = this->rec_blk;
-
+
filename = make_temp_name(this, this->rec_page);
-
+
lprintf("opening pvr file for writing (%s)\n", filename);
-
+
this->rec_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666 );
if( this->rec_fd == -1 ) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
@@ -603,39 +591,39 @@ static int pvr_break_rec_page (pvr_input_plugin_t *this) {
return 0;
}
free(filename);
-
+
/* erase first_page if old and not to be saved */
- if( this->max_page_age != (unsigned)-1 &&
+ if( this->max_page_age != (unsigned)-1 &&
this->rec_page - this->max_page_age == this->first_page &&
(this->save_page == (unsigned)-1 || this->first_page < this->save_page) ) {
-
+
filename = make_temp_name(this, this->first_page);
lprintf("erasing old pvr file (%s)\n", filename);
-
+
this->first_page++;
if(this->play_fd != -1 && this->play_page < this->first_page) {
this->play_blk = this->page_block[this->first_page];
close(this->play_fd);
this->play_fd = -1;
}
-
+
remove(filename);
free(filename);
- }
+ }
return 1;
}
/*
- * check the status of recording file, open new one as needed and write the current data.
+ * check the status of recording file, open new one as needed and write the current data.
*/
static int pvr_rec_file(pvr_input_plugin_t *this) {
-
+
off_t pos;
if( this->session == (unsigned)-1 ) /* not recording */
return 1;
-
+
/* check if it's time to change page/file */
if( this->rec_fd == -1 || (this->rec_blk - this->page_block[this->rec_page]) >= BLOCKS_PER_PAGE ) {
if( !pvr_break_rec_page(this) )
@@ -643,61 +631,61 @@ static int pvr_rec_file(pvr_input_plugin_t *this) {
}
pos = (off_t)(this->rec_blk - this->page_block[this->rec_page]) * PVR_BLOCK_SIZE;
if( lseek (this->rec_fd, pos, SEEK_SET) != pos ) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: error setting position for writing %" PRIdMAX "\n", (intmax_t)pos);
return 0;
}
if( this->rec_fd != -1 ) {
if( write(this->rec_fd, this->data, PVR_BLOCK_SIZE) < PVR_BLOCK_SIZE ) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: short write to pvr file (out of disk space?)\n");
return 0;
}
this->rec_blk++;
}
-
+
return 1;
}
-/*
+/*
* check for playback mode, switching realtime <-> non-realtime.
* gets data from file in non-realtime mode.
*/
static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t *buffer, int speed) {
-
+
off_t pos;
-
+
/* check for realtime. don't switch back unless enough buffers are
* free to not block the pvr thread */
if( this->new_session ||
(this->play_blk+1 >= this->rec_blk && speed >= XINE_SPEED_NORMAL &&
(this->play_fd == -1 || fifo->size(fifo) < fifo->num_free(fifo))) ) {
-
+
this->play_blk = (this->rec_blk) ? (this->rec_blk-1) : 0;
-
+
if( speed > XINE_SPEED_NORMAL )
_x_set_speed(this->stream, XINE_SPEED_NORMAL);
-
+
if( this->play_fd != -1 ) {
if(this->play_fd != this->rec_fd )
- close(this->play_fd);
+ close(this->play_fd);
this->play_fd = -1;
-
+
lprintf("switching back to realtime\n");
pvr_report_realtime(this,1);
-
+
} else if (this->new_session) {
lprintf("starting new session in realtime\n");
pvr_report_realtime(this,1);
}
-
+
this->want_data = 1;
this->new_session = 0;
-
+
} else {
- if( this->rec_fd == -1 )
+ if( this->rec_fd == -1 )
return 1;
if(speed != XINE_SPEED_PAUSE) {
@@ -711,30 +699,30 @@ static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t
}
}
- if( this->play_fd == -1 ||
+ if( this->play_fd == -1 ||
((this->play_blk - this->page_block[this->play_page]) >= BLOCKS_PER_PAGE) ||
(this->rec_page > this->play_page && this->play_blk >= this->page_block[this->play_page+1]) ) {
-
+
if(this->play_fd == -1) {
lprintf("switching to non-realtime\n");
pvr_report_realtime(this,0);
}
-
+
if( this->play_fd != -1 && this->play_fd != this->rec_fd ) {
- close(this->play_fd);
+ close(this->play_fd);
}
-
+
if( this->play_fd == -1 )
this->play_page = block_to_page(this, this->play_blk);
else
this->play_page++;
-
+
if( this->play_page < this->first_page ) {
this->play_page = this->first_page;
this->play_blk = this->page_block[this->play_page];
}
-
+
/* should be impossible */
if( this->play_page > this->rec_page ||
this->play_blk > this->rec_blk ) {
@@ -747,11 +735,11 @@ static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t
this->play_fd = this->rec_fd;
} else {
char *filename;
-
+
filename = make_temp_name(this, this->play_page);
lprintf("opening pvr file for reading (%s)\n", filename);
-
+
this->play_fd = open(filename, O_RDONLY );
if( this->play_fd == -1 ) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
@@ -764,7 +752,7 @@ static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t
this->want_data = 0;
pthread_cond_signal (&this->wake_pvr);
}
-
+
if(speed != XINE_SPEED_PAUSE) {
pos = (off_t)(this->play_blk - this->page_block[this->play_page]) * PVR_BLOCK_SIZE;
@@ -815,29 +803,29 @@ static void *pvr_loop (void *this_gen) {
int lost_sync;
while( this->pvr_running ) {
-
+
pthread_mutex_lock(&this->lock);
this->valid_data = 0;
pthread_mutex_unlock(&this->lock);
-
+
total_bytes = 0;
do {
-
+
lost_sync = 0;
-
+
pthread_mutex_lock(&this->dev_lock);
while (total_bytes < PVR_BLOCK_SIZE) {
num_bytes = read (this->dev_fd, this->data + total_bytes, PVR_BLOCK_SIZE-total_bytes);
if (num_bytes <= 0) {
- if (num_bytes < 0)
+ if (num_bytes < 0)
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
_("input_pvr: read error (%s)\n"), strerror(errno));
- this->pvr_running = 0;
+ this->pvr_running = 0;
break;
}
total_bytes += num_bytes;
}
-
+
if( this->data[0] || this->data[1] || this->data[2] != 1 || this->data[3] != 0xba ) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "resyncing mpeg stream\n");
@@ -848,28 +836,28 @@ static void *pvr_loop (void *this_gen) {
this->data[0] = 0; this->data[1] = 0; this->data[2] = 1; this->data[3] = 0xba;
total_bytes = 4;
}
- }
+ }
pthread_mutex_unlock(&this->dev_lock);
-
- } while( lost_sync );
-
+
+ } while( lost_sync );
+
pthread_mutex_lock(&this->lock);
-
+
if( !pvr_rec_file(this) ) {
- this->pvr_running = 0;
+ this->pvr_running = 0;
}
-
+
this->valid_data = 1;
pthread_cond_signal (&this->has_valid_data);
- while(this->valid_data && this->play_fd == -1 &&
+ while(this->valid_data && this->play_fd == -1 &&
this->want_data && this->pvr_playing) {
pthread_cond_wait (&this->wake_pvr, &this->lock);
}
-
+
pthread_mutex_unlock(&this->lock);
}
-
+
pthread_exit(NULL);
}
@@ -880,7 +868,7 @@ static void *pvr_loop (void *this_gen) {
* name (save_name) or a default one using channel and time.
*/
static void pvr_finish_recording (pvr_input_plugin_t *this) {
-
+
char *src_filename;
char *save_base;
char *dst_filename;
@@ -889,31 +877,31 @@ static void pvr_finish_recording (pvr_input_plugin_t *this) {
lprintf("finish_recording\n");
if( this->rec_fd != -1 ) {
- close(this->rec_fd);
-
+ close(this->rec_fd);
+
if( this->play_fd != -1 && this->play_fd != this->rec_fd )
close(this->play_fd);
-
+
this->rec_fd = this->play_fd = -1;
-
+
if( this->save_page == this->show_page )
save_base = make_base_save_name(this->channel, this->show_time);
else
save_base = make_base_save_name(this->channel, this->start_time);
-
+
for( i = this->first_page; i <= this->rec_page; i++ ) {
-
+
src_filename = make_temp_name(this, i);
-
+
if( this->save_page == (unsigned)-1 || i < this->save_page ) {
lprintf("erasing old pvr file (%s)\n", src_filename);
remove(src_filename);
} else {
-
+
if( !this->save_name || !strlen(this->save_name) )
dst_filename = make_save_name(this, save_base, i-this->save_page+1);
- else
+ else
dst_filename = make_save_name(this, this->save_name, i-this->save_page+1);
lprintf("moving (%s) to (%s)\n", src_filename, dst_filename);
@@ -923,17 +911,17 @@ static void pvr_finish_recording (pvr_input_plugin_t *this) {
}
free(src_filename);
}
-
+
if( this->save_page != (unsigned)-1 && (!this->save_name || !strlen(this->save_name)) ) {
saved_show_t *show = malloc(sizeof(saved_show_t));
xine_event_t event;
xine_pvr_save_data_t data;
-
+
show->base_name = save_base;
show->id = ++this->saved_id;
show->pages = this->rec_page - this->save_page + 1;
xine_list_push_back (this->saved_shows, show);
-
+
lprintf("sending event with base name [%s]\n", show->base_name);
/* tell frontend the name of the saved show */
@@ -942,18 +930,18 @@ static void pvr_finish_recording (pvr_input_plugin_t *this) {
event.data = &data;
event.data_length = sizeof(data);
gettimeofday(&event.tv, NULL);
-
+
data.mode = 0;
data.id = show->id;
strncpy(data.name, show->base_name, sizeof(data.name));
data.name[sizeof(data.name) - 1] = '\0';
-
+
xine_event_send(this->stream, &event);
} else {
free(save_base);
}
}
-
+
this->first_page = 0;
this->show_page = 0;
this->save_page = -1;
@@ -1016,23 +1004,25 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
/* change input */
if (v4l2_data->input != -1 && v4l2_data->input != this->input) {
- lprintf("change input to:%d\n", v4l2_data->input);
this->input = v4l2_data->input;
/* as of ivtv 0.10.6: must close and reopen to set input */
close(this->dev_fd);
this->dev_fd = open (this->class->devname, O_RDWR);
- if (this->dev_fd == -1) {
+ if (this->dev_fd < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: error opening device %s\n", this->class->devname );
} else {
- if( ioctl(this->dev_fd, VIDIOC_S_INPUT, &this->input) )
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ if( ioctl(this->dev_fd, VIDIOC_S_INPUT, &this->input) == 0 ) {
+ lprintf("Tuner Input set to:%d\n", v4l2_data->input);
+ } else {
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: error setting v4l2 input\n");
+ }
}
}
- /* change channel */
+ /* change channel */
if (v4l2_data->channel != -1 && v4l2_data->channel != this->channel) {
lprintf("change channel to:%d\n", v4l2_data->channel);
this->channel = v4l2_data->channel;
@@ -1040,24 +1030,40 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
/* change frequency */
if (v4l2_data->frequency != -1 && v4l2_data->frequency != this->frequency) {
- lprintf("changing frequency to:%.2f\n", (float)v4l2_data->frequency * 62.5);
+ double freq = (double)v4l2_data->frequency / 1000.0;
struct v4l2_frequency vf;
+ struct v4l2_tuner vt;
+ double fac = 16;
+
+ memset(&vf, 0, sizeof(vf));
+ memset(&vt, 0, sizeof(vt));
+
this->frequency = v4l2_data->frequency;
- vf.frequency = this->frequency;
+
+ if (ioctl(this->dev_fd, VIDIOC_G_TUNER, &vt) == 0) {
+ fac = (vt.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16;
+ }
+
vf.tuner = 0;
- if( ioctl(this->dev_fd, VIDIOC_S_FREQUENCY, &vf) )
+ vf.type = vt.type;
+ vf.frequency = (__u32)(freq * fac);
+
+ if (ioctl(this->dev_fd, VIDIOC_S_FREQUENCY, &vf) == 0) {
+ lprintf("Tuner Frequency set to %d (%f.3 MHz)\n", vf.frequency, vf.frequency / fac);
+ } else {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: error setting v4l2 frequency\n");
+ }
}
pthread_mutex_unlock(&this->dev_lock);
-
+
/* FIXME: also flush the device */
/* _x_demux_flush_engine(this->stream); */
break;
-
-
+
+
case XINE_EVENT_PVR_SAVE:
if( this->session != -1 ) {
switch( save_data->mode ) {
@@ -1090,11 +1096,11 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
if( this->save_name )
free( this->save_name );
this->save_name = NULL;
-
+
if( save_data->id < 0 ) {
/* no id: set name for current recording */
this->save_name = strdup(save_data->name);
-
+
} else {
/* search for the ID of saved shows and rename it
* to the given name. */
@@ -1102,17 +1108,17 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
char *dst_filename;
saved_show_t *show;
xine_list_iterator_t ite;
-
+
pthread_mutex_lock(&this->lock);
-
+
ite = xine_list_front (this->saved_shows);
while (ite) {
show = xine_list_get_value(this->saved_shows, ite);
if( show->id == save_data->id ) {
int i;
-
+
for( i = 0; i < show->pages; i++ ) {
-
+
src_filename = make_save_name(this, show->base_name, i+1);
dst_filename = make_save_name(this, save_data->name, i+1);
@@ -1144,7 +1150,7 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
case XINE_EVENT_SET_MPEG_DATA: {
struct ivtv_ioctl_codec codec;
-
+
pthread_mutex_lock(&this->dev_lock);
/* how lame. we must close and reopen to change bitrate. */
@@ -1155,9 +1161,9 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
_("input_pvr: error opening device %s\n"), this->class->devname );
return;
}
-
+
if (ioctl(this->dev_fd, IVTV_IOC_G_CODEC, &codec) < 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_("input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n"));
} else {
codec.bitrate = mpeg_data->bitrate_mean;
@@ -1172,7 +1178,7 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
pthread_mutex_unlock(&this->dev_lock);
}
break;
-
+
#if 0
default:
printf ("input_pvr: got an event, type 0x%08x\n", event->type);
@@ -1198,7 +1204,15 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff
if( !this->pvr_running ) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: thread died, aborting\n");
- return NULL;
+ return NULL;
+ }
+
+ buf = fifo->buffer_pool_alloc (fifo);
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer(buf);
+ return NULL;
}
if( this->scr_tunning == -2 )
@@ -1206,7 +1220,7 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff
if( this->pvr_play_paused )
speed = XINE_SPEED_PAUSE;
-
+
if( this->pvr_playing && _x_stream_info_get(this->stream, XINE_STREAM_INFO_IGNORE_VIDEO) ) {
/* video decoding has being disabled. avoid tweaking the clock */
this->pvr_playing = 0;
@@ -1218,56 +1232,55 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff
this->pvr_playing = 1;
this->play_blk = this->rec_blk;
}
-
+
if( this->pvr_playing )
pvr_adjust_realtime_speed(this, fifo, speed);
pvr_event_handler(this);
-
- buf = fifo->buffer_pool_alloc (fifo);
+
buf->content = buf->mem;
-
+
pthread_mutex_lock(&this->lock);
-
+
if( this->pvr_playing )
if( !pvr_play_file(this, fifo, buf->content, speed) ) {
buf->free_buffer(buf);
pthread_mutex_unlock(&this->lock);
return NULL;
}
-
+
if( todo == PVR_BLOCK_SIZE && speed != XINE_SPEED_PAUSE &&
this->pvr_playing ) {
buf->type = BUF_DEMUX_BLOCK;
buf->size = PVR_BLOCK_SIZE;
-
+
if(this->play_fd == -1) {
-
+
/* realtime mode: wait for valid data from pvr thread */
this->want_data = 1;
while(!this->valid_data && this->pvr_running)
pthread_cond_wait (&this->has_valid_data, &this->lock);
-
+
this->play_blk = this->rec_blk;
xine_fast_memcpy(buf->content, this->data, PVR_BLOCK_SIZE);
-
+
this->valid_data = 0;
pthread_cond_signal (&this->wake_pvr);
}
pthread_mutex_unlock(&this->lock);
-
+
} else {
pthread_mutex_unlock(&this->lock);
-
+
buf->type = BUF_CONTROL_NOP;
- buf->size = 0;
-
+ buf->size = 0;
+
if(this->preview_buffers)
this->preview_buffers--;
else
xine_usec_sleep (20000);
}
-
+
return buf;
}
@@ -1276,7 +1289,7 @@ static off_t pvr_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;
pthread_mutex_lock(&this->lock);
-
+
switch( origin ) {
case SEEK_SET:
this->play_blk = (offset / PVR_BLOCK_SIZE) + this->page_block[this->first_page];
@@ -1288,18 +1301,18 @@ static off_t pvr_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
this->play_blk = this->rec_blk + (offset / PVR_BLOCK_SIZE);
break;
}
-
+
/* invalidate the fd if needed */
if( this->play_fd != -1 && block_to_page(this,this->play_blk) != this->play_page ) {
if( this->play_fd != this->rec_fd )
- close(this->play_fd);
+ close(this->play_fd);
this->play_fd = -1;
if( this->play_blk >= this->rec_blk )
pvr_report_realtime(this,1);
}
pthread_mutex_unlock(&this->lock);
-
+
return (off_t) (this->play_blk - this->page_block[this->first_page]) * PVR_BLOCK_SIZE;
}
@@ -1326,9 +1339,9 @@ static const char* pvr_plugin_get_mrl (input_plugin_t *this_gen) {
return this->mrl;
}
-static int pvr_plugin_get_optional_data (input_plugin_t *this_gen,
+static int pvr_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
-
+
return INPUT_OPTIONAL_UNSUPPORTED;
}
@@ -1346,11 +1359,11 @@ static void pvr_plugin_dispose (input_plugin_t *this_gen ) {
this->want_data = 0;
pthread_cond_signal (&this->wake_pvr);
pthread_mutex_unlock(&this->lock);
- pthread_join (this->pvr_thread, &p);
+ pthread_join (this->pvr_thread, &p);
lprintf("pvr thread joined\n");
}
-
+
if (this->scr) {
this->stream->xine->clock->unregister_scr(this->stream->xine->clock, &this->scr->scr);
this->scr->scr.exit(&this->scr->scr);
@@ -1363,15 +1376,15 @@ static void pvr_plugin_dispose (input_plugin_t *this_gen ) {
close(this->dev_fd);
pvr_finish_recording(this);
-
+
free (this->mrl);
-
+
if (this->tmp_prefix)
free (this->tmp_prefix);
-
+
if (this->save_prefix)
free (this->save_prefix);
-
+
ite = xine_list_front (this->saved_shows);
while (ite) {
show = xine_list_get_value(this->saved_shows, ite);
@@ -1388,7 +1401,7 @@ static int pvr_plugin_open (input_plugin_t *this_gen ) {
int64_t time;
int err;
struct ivtv_ioctl_codec codec;
-
+
this->session = 0;
this->rec_fd = -1;
this->play_fd = -1;
@@ -1404,7 +1417,7 @@ static int pvr_plugin_open (input_plugin_t *this_gen ) {
this->dev_fd = open (this->class->devname, O_RDWR);
if (this->dev_fd == -1) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_("input_pvr: error opening device %s\n"), this->class->devname );
return 0;
}
@@ -1423,46 +1436,46 @@ static int pvr_plugin_open (input_plugin_t *this_gen ) {
_("input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n"));
}
}
-
- /* register our own scr provider */
+
+ /* register our own scr provider */
time = this->stream->xine->clock->get_current_time(this->stream->xine->clock);
this->scr = pvrscr_init();
this->scr->scr.start(&this->scr->scr, time);
this->stream->xine->clock->register_scr(this->stream->xine->clock, &this->scr->scr);
this->scr_tunning = 0;
-
+
this->event_queue = xine_event_new_queue (this->stream);
-
+
/* enable resample method */
this->stream->xine->config->update_num(this->stream->xine->config,"audio.synchronization.av_sync_method",1);
-
+
this->pvr_running = 1;
-
+
if ((err = pthread_create (&this->pvr_thread,
NULL, pvr_loop, this)) != 0) {
- xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->stream->xine, XINE_VERBOSITY_NONE,
"input_pvr: can't create new thread (%s)\n", strerror(err));
_x_abort();
}
-
+
return 1;
}
-static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
+static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
const char *data) {
pvr_input_class_t *cls = (pvr_input_class_t *) cls_gen;
pvr_input_plugin_t *this;
char *mrl;
char *aux;
-
- if (strncasecmp (data, "pvr:/", 5))
+
+ if (strncasecmp (data, "pvr:/", 5))
return NULL;
-
+
mrl = strdup(data);
aux = &mrl[5];
- this = (pvr_input_plugin_t *) xine_xmalloc (sizeof (pvr_input_plugin_t));
+ this = calloc(1, sizeof (pvr_input_plugin_t));
this->class = cls;
this->stream = stream;
this->dev_fd = -1;
@@ -1472,14 +1485,14 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre
/* decode configuration options from mrl */
if( strlen(aux) ) {
this->tmp_prefix = strdup(aux);
-
+
aux = strchr(this->tmp_prefix,'!');
if( aux ) {
aux[0] = '\0';
this->save_prefix = strdup(aux+1);
aux = strchr(this->save_prefix, '!');
- if( aux ) {
+ if( aux ) {
aux[0] = '\0';
if( atoi(aux+1) )
this->max_page_age = atoi(aux+1);
@@ -1491,11 +1504,11 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre
this->tmp_prefix=strdup("./");
this->save_prefix=strdup("./");
}
-
+
lprintf("tmp_prefix=%s\n", this->tmp_prefix);
lprintf("save_prefix=%s\n", this->save_prefix);
lprintf("max_page_age=%d\n", this->max_page_age);
-
+
this->input_plugin.open = pvr_plugin_open;
this->input_plugin.get_capabilities = pvr_plugin_get_capabilities;
this->input_plugin.read = pvr_plugin_read;
@@ -1513,12 +1526,12 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre
this->event_queue = NULL;
this->save_name = NULL;
this->saved_shows = xine_list_new();
-
+
pthread_mutex_init (&this->lock, NULL);
pthread_mutex_init (&this->dev_lock, NULL);
pthread_cond_init (&this->has_valid_data,NULL);
pthread_cond_init (&this->wake_pvr,NULL);
-
+
return &this->input_plugin;
}
@@ -1546,7 +1559,7 @@ static void *init_plugin (xine_t *xine, void *data) {
pvr_input_class_t *this;
- this = (pvr_input_class_t *) xine_xmalloc (sizeof (pvr_input_class_t));
+ this = calloc(1, sizeof (pvr_input_class_t));
this->xine = xine;
this->config = xine->config;
@@ -1575,7 +1588,7 @@ static void *init_plugin (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "pvr", XINE_VERSION_CODE, NULL, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_rtp.c b/src/input/input_rtp.c
index 25498f289..e91e43f55 100644
--- a/src/input/input_rtp.c
+++ b/src/input/input_rtp.c
@@ -1,18 +1,18 @@
-/*
+/*
* Copyright (C) 2000-2004 the xine project
- *
+ *
* 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
@@ -114,7 +114,7 @@ typedef struct {
input_plugin_t input_plugin;
xine_stream_t *stream;
-
+
char *mrl;
config_values_t *config;
@@ -122,16 +122,16 @@ typedef struct {
int port;
char *interface; /* For multicast, eth0, eth1 etc */
int is_rtp;
-
+
int fh;
-
+
unsigned char *buffer; /* circular buffer */
unsigned char *buffer_get_ptr; /* get pointer used by reader */
unsigned char *buffer_put_ptr; /* put pointer used by writer */
long buffer_count; /* number of bytes in the buffer */
unsigned char packet_buffer[65536];
-
+
int last_input_error;
int input_eof;
@@ -184,7 +184,7 @@ static int host_connect_attempt(struct in_addr ia, int port,
return -1;
}
- saddr.in.sin_family = AF_INET;
+ saddr.in.sin_family = AF_INET;
saddr.in.sin_addr = ia;
saddr.in.sin_port = htons(port);
@@ -193,8 +193,8 @@ static int host_connect_attempt(struct in_addr ia, int port,
LOG_MSG(xine, _("IP address specified is multicast\n"));
multicast = 1; /* boolean true */
}
-
-
+
+
/* Try to increase receive buffer to 1MB to avoid dropping packets */
optval = BUFFER_SIZE;
if ((setsockopt(s, SOL_SOCKET, SO_RCVBUF,
@@ -217,7 +217,7 @@ static int host_connect_attempt(struct in_addr ia, int port,
LOG_MSG(xine, _("bind(): %s.\n"), strerror(errno));
return -1;
}
-
+
/* multicast ? */
if (multicast) {
@@ -250,14 +250,14 @@ static int host_connect_attempt(struct in_addr ia, int port,
&((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr,
sizeof(struct in_addr));
}
-
+
if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
LOG_MSG(xine, _("setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n"),
strerror(errno));
return -1;
}
}
-
+
return s;
}
@@ -271,13 +271,13 @@ static int host_connect(const char *host, int port,
struct hostent *h;
int i;
int s;
-
+
h=gethostbyname(host);
if(h==NULL) {
LOG_MSG(xine, _("unable to resolve '%s'.\n"), host);
return -1;
}
-
+
for(i=0; h->h_addr_list[i]; i++) {
struct in_addr ia;
memcpy(&ia, h->h_addr_list[i],4);
@@ -299,7 +299,7 @@ static void * input_plugin_read_loop(void *arg) {
fd_set read_fds;
while (1) {
-
+
/* System calls are not a thread cancellation point in Linux
* pthreads. However, the RT signal sent to cancel the thread
* will cause recv() to return with EINTR, and we can manually
@@ -339,11 +339,11 @@ static void * input_plugin_read_loop(void *arg) {
}
else {
data = this->packet_buffer;
-
+
if (this->is_rtp) {
int pad, ext;
int csrc;
-
+
/* Do minimal RTP parsing to extract payload. See
* http://www.faqs.org/rfcs/rfc1889.html for header format.
*
@@ -351,7 +351,7 @@ static void * input_plugin_read_loop(void *arg) {
*/
if (length < 12) continue;
-
+
pad = data[0] & 0x20;
ext = data[0] & 0x10;
csrc = data[0] & 0x0f;
@@ -361,7 +361,7 @@ static void * input_plugin_read_loop(void *arg) {
if (ext) {
long hlen;
-
+
if (length < 4) continue;
hlen = (data[2] << 8) | data[3];
@@ -382,12 +382,12 @@ static void * input_plugin_read_loop(void *arg) {
/* insert data into cyclic buffer */
if (length > 0) {
-
- /*
+
+ /*
* if the buffer is full, wait for the reader
- * to signal
- */
-
+ * to signal
+ */
+
pthread_mutex_lock(&this->buffer_ring_mut);
/* wait for enough space to write the whole of the recv'ed data */
while( (BUFFER_SIZE - this->buffer_count) < length )
@@ -399,23 +399,23 @@ static void * input_plugin_read_loop(void *arg) {
timeout.tv_nsec = tv.tv_usec * 1000;
timeout.tv_sec = tv.tv_sec + 2;
-
+
if( pthread_cond_timedwait(&this->writer_cond, &this->buffer_ring_mut, &timeout) != 0 )
{
fprintf( stdout, "input_rtp: buffer ring not read within 2 seconds!\n" );
}
}
-
+
/* Now there's enough space to write some bytes into the buffer
* determine how many bytes can be written. If the buffer wraps
* around, write in two pieces: from the head pointer to the
- * end of the buffer and from the base to the remaining number
+ * end of the buffer and from the base to the remaining number
* of bytes.
*/
{
long buffer_space_remaining = BUFFER_SIZE - (this->buffer_put_ptr - this->buffer);
-
+
if( buffer_space_remaining >= length )
{
/* data fits inside the buffer */
@@ -445,14 +445,17 @@ static void * input_plugin_read_loop(void *arg) {
/* END OF PRIVATES */
/* ***************************************************************** */
-static off_t rtp_plugin_read (input_plugin_t *this_gen,
+static off_t rtp_plugin_read (input_plugin_t *this_gen,
char *buf, off_t length) {
rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen;
struct timeval tv;
struct timespec timeout;
- off_t copied = 0;
-
+ off_t copied = 0;
+
+ if (length < 0)
+ return -1;
+
while(length > 0) {
off_t n;
@@ -469,7 +472,7 @@ static off_t rtp_plugin_read (input_plugin_t *this_gen,
gettimeofday(&tv, NULL);
timeout.tv_nsec = tv.tv_usec * 1000;
timeout.tv_sec = tv.tv_sec + 5;
-
+
if(pthread_cond_timedwait(&this->reader_cond, &this->buffer_ring_mut, &timeout) != 0)
{
/* we timed out, no data available */
@@ -480,9 +483,9 @@ static off_t rtp_plugin_read (input_plugin_t *this_gen,
/* Now determine how many bytes can be read. If the buffer
* will wrap the buffer is read in two pieces, first read
- * to the end of the buffer, wrap the tail pointer and
+ * to the end of the buffer, wrap the tail pointer and
* update the buffer count. Finally read the second piece
- * from the base to the remaining count
+ * from the base to the remaining count
*/
if(length > this->buffer_count) {
n = this->buffer_count;
@@ -490,26 +493,26 @@ static off_t rtp_plugin_read (input_plugin_t *this_gen,
else {
n = length;
}
-
+
if(((this->buffer_get_ptr - this->buffer) + n) > BUFFER_SIZE) {
n = BUFFER_SIZE - (this->buffer_get_ptr - this->buffer);
}
-
+
/* the actual read */
memcpy(buf, this->buffer_get_ptr, n);
buf += n;
copied += n;
length -= n;
-
+
/* update the tail pointer, watch for wrap arounds */
this->buffer_get_ptr += n;
if(this->buffer_get_ptr - this->buffer >= BUFFER_SIZE)
this->buffer_get_ptr = this->buffer;
-
+
this->buffer_count -= n;
-
- /* signal the writer that there's space in the buffer again */
+
+ /* signal the writer that there's space in the buffer again */
pthread_cond_signal(&this->writer_cond);
pthread_mutex_unlock(&this->buffer_ring_mut);
}
@@ -524,6 +527,12 @@ static buf_element_t *rtp_plugin_read_block (input_plugin_t *this_gen,
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
int total_bytes;
+ 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;
@@ -545,7 +554,7 @@ static buf_element_t *rtp_plugin_read_block (input_plugin_t *this_gen,
*/
static off_t rtp_plugin_seek (input_plugin_t *this_gen,
off_t offset, int origin) {
-
+
return -1;
}
@@ -562,7 +571,7 @@ static off_t rtp_plugin_get_length (input_plugin_t *this_gen) {
*/
static off_t rtp_plugin_get_current_pos (input_plugin_t *this_gen){
rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen;
-
+
return this->curpos;
}
@@ -570,7 +579,7 @@ static off_t rtp_plugin_get_current_pos (input_plugin_t *this_gen){
*
*/
static uint32_t rtp_plugin_get_capabilities (input_plugin_t *this_gen) {
-
+
return INPUT_CAP_PREVIEW;
}
@@ -578,7 +587,7 @@ static uint32_t rtp_plugin_get_capabilities (input_plugin_t *this_gen) {
*
*/
static uint32_t rtp_plugin_get_blocksize (input_plugin_t *this_gen) {
-
+
return 0;
}
@@ -587,14 +596,14 @@ static uint32_t rtp_plugin_get_blocksize (input_plugin_t *this_gen) {
*/
static const char* rtp_plugin_get_mrl (input_plugin_t *this_gen) {
rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen;
-
+
return this->mrl;
}
/*
*
*/
-static int rtp_plugin_get_optional_data (input_plugin_t *this_gen,
+static int rtp_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen;
@@ -609,11 +618,14 @@ static int rtp_plugin_get_optional_data (input_plugin_t *this_gen,
if (data_type == INPUT_OPTIONAL_DATA_PREVIEW) {
if (!this->preview_read_done) {
this->preview_size = rtp_plugin_read(this_gen, this->preview, MAX_PREVIEW_SIZE);
+ if (this->preview_size < 0)
+ this->preview_size = 0;
lprintf("Preview data length = %d\n", this->preview_size);
this->preview_read_done = 1;
}
- memcpy(data, this->preview, this->preview_size);
+ if (this->preview_size)
+ memcpy(data, this->preview, this->preview_size);
return this->preview_size;
}
else {
@@ -623,16 +635,16 @@ static int rtp_plugin_get_optional_data (input_plugin_t *this_gen,
static void rtp_plugin_dispose (input_plugin_t *this_gen ) {
rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen;
-
+
if (this->nbc) nbc_close(this->nbc);
-
+
if (this->rtp_running) {
LOG_MSG(this->stream->xine, _("RTP: stopping reading thread...\n"));
pthread_cancel(this->reader_thread);
pthread_join(this->reader_thread, NULL);
LOG_MSG(this->stream->xine, _("RTP: reading thread terminated\n"));
}
-
+
if (this->fh != -1) close(this->fh);
free(this->buffer);
@@ -649,7 +661,7 @@ static int rtp_plugin_open (input_plugin_t *this_gen ) {
this->filename,
this->port,
this->interface);
-
+
this->fh = host_connect(this->filename, this->port,
this->interface, this->stream->xine);
@@ -660,12 +672,12 @@ static int rtp_plugin_open (input_plugin_t *this_gen ) {
this->curpos = 0;
this->rtp_running = 1;
- if ((err = pthread_create(&this->reader_thread, NULL,
+ if ((err = pthread_create(&this->reader_thread, NULL,
input_plugin_read_loop, (void *)this)) != 0) {
LOG_MSG(this->stream->xine, _("input_rtp: can't create new thread (%s)\n"), strerror(err));
_x_abort();
}
-
+
return 1;
}
@@ -679,7 +691,7 @@ static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen,
char *mrl;
int is_rtp = 0;
int port = 7658;
-
+
mrl = strdup(data);
if (!strncasecmp (mrl, "rtp://", 6)) {
@@ -690,12 +702,12 @@ static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen,
filename = &mrl[6];
is_rtp = 0;
}
-
+
if (filename == NULL || strlen(filename) == 0) {
free(mrl);
return NULL;
}
-
+
/* Locate the port number */
pptr=strchr(filename, ':');
iptr = NULL;
@@ -716,8 +728,8 @@ static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen,
}
}
}
-
- this = (rtp_input_plugin_t *) xine_xmalloc(sizeof(rtp_input_plugin_t));
+
+ this = calloc(1, sizeof(rtp_input_plugin_t));
this->stream = stream;
this->mrl = mrl;
this->filename = filename;
@@ -753,8 +765,8 @@ static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen,
this->input_plugin.get_optional_data = rtp_plugin_get_optional_data;
this->input_plugin.dispose = rtp_plugin_dispose;
this->input_plugin.input_class = cls_gen;
-
- this->nbc = NULL;
+
+ this->nbc = NULL;
this->nbc = nbc_init(this->stream);
return &this->input_plugin;
@@ -764,7 +776,7 @@ static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen,
/*
* net plugin class
*/
-
+
static const char *rtp_class_get_description (input_class_t *this_gen) {
return _("RTP and UDP input plugin as shipped with xine");
}
@@ -783,8 +795,8 @@ static void *init_class (xine_t *xine, void *data) {
rtp_input_class_t *this;
-
- this = (rtp_input_class_t *) xine_xmalloc(sizeof(rtp_input_class_t));
+
+ this = calloc(1, sizeof(rtp_input_class_t));
this->config = xine->config;
this->xine = xine;
@@ -804,7 +816,7 @@ static void *init_class (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT, 17, "rtp", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_rtsp.c b/src/input/input_rtsp.c
index 2895edf5d..fbfad0364 100644
--- a/src/input/input_rtsp.c
+++ b/src/input/input_rtsp.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2002-2003 the xine project
- *
+ *
* 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
@@ -69,29 +69,28 @@ typedef struct {
off_t curpos;
- nbc_t *nbc;
+ nbc_t *nbc;
char scratch[BUFSIZE];
} rtsp_input_plugin_t;
-static off_t rtsp_plugin_read (input_plugin_t *this_gen,
+static off_t rtsp_plugin_read (input_plugin_t *this_gen,
char *buf, off_t len) {
rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
off_t n;
lprintf ("rtsp_plugin_read: %"PRId64" bytes ...\n", len);
- nbc_check_buffers (this->nbc);
-
n = rtsp_session_read (this->rtsp, buf, len);
- this->curpos += n;
+ if (n > 0)
+ this->curpos += n;
return n;
}
-static buf_element_t *rtsp_plugin_read_block (input_plugin_t *this_gen,
+static buf_element_t *rtsp_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t todo) {
/*rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; */
buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
@@ -99,9 +98,16 @@ static buf_element_t *rtsp_plugin_read_block (input_plugin_t *this_gen,
lprintf ("rtsp_plugin_read_block: %"PRId64" bytes...\n", todo);
+ 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 = rtsp_plugin_read (this_gen, (char*)buf->content, todo);
if (total_bytes != todo) {
@@ -125,10 +131,16 @@ static off_t rtsp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origi
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- this->curpos += rtsp_plugin_read (this_gen, this->scratch, BUFSIZE);
+ off_t n = rtsp_plugin_read (this_gen, this->scratch, BUFSIZE);
+ if (n <= 0)
+ return this->curpos;
+ this->curpos += n;
}
- this->curpos += rtsp_plugin_read (this_gen, this->scratch, offset);
+ off_t n = rtsp_plugin_read (this_gen, this->scratch, offset);
+ if (n <= 0)
+ return this->curpos;
+ this->curpos += n;
}
return this->curpos;
@@ -139,17 +151,17 @@ static off_t rtsp_plugin_seek_time (input_plugin_t *this_gen, int time_offset, i
rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
lprintf ("seek_time %d msec, origin %d\n", time_offset, origin);
-
+
if (origin == SEEK_SET)
rtsp_session_set_start_time (this->rtsp, time_offset);
-
+
return this->curpos;
}
static off_t rtsp_plugin_get_length (input_plugin_t *this_gen) {
/*
- rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
+ rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
off_t length;
*/
@@ -186,13 +198,13 @@ static void rtsp_plugin_dispose (input_plugin_t *this_gen) {
nbc_close (this->nbc);
this->nbc = NULL;
}
-
+
if(this->mrl)
free(this->mrl);
-
+
if(this->public_mrl)
free(this->public_mrl);
-
+
free (this);
}
@@ -202,7 +214,7 @@ static const char* rtsp_plugin_get_mrl (input_plugin_t *this_gen) {
return this->public_mrl;
}
-static int rtsp_plugin_get_optional_data (input_plugin_t *this_gen,
+static int rtsp_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
@@ -233,11 +245,11 @@ static int rtsp_plugin_open (input_plugin_t *this_gen) {
}
this->rtsp = rtsp;
-
+
return 1;
}
-static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
+static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
const char *mrl) {
/* rtsp_input_class_t *cls = (rtsp_input_class_t *) cls_gen; */
@@ -246,7 +258,7 @@ static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_str
if (strncasecmp (mrl, "rtsp://", 6))
return NULL;
- this = (rtsp_input_plugin_t *) xine_xmalloc (sizeof (rtsp_input_plugin_t));
+ this = calloc(1, sizeof (rtsp_input_plugin_t));
this->stream = stream;
this->rtsp = NULL;
@@ -254,9 +266,8 @@ static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_str
/* since we handle only real streams yet, we can savely add
* an .rm extention to force handling by demux_real.
*/
- this->public_mrl = xine_xmalloc (sizeof (char)*(strlen(this->mrl)+10));
- sprintf(this->public_mrl, "%s.rm", this->mrl);
-
+ asprintf(&this->public_mrl, "%s.rm", this->mrl);
+
this->nbc = nbc_init (stream);
this->input_plugin.open = rtsp_plugin_open;
@@ -272,7 +283,7 @@ static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_str
this->input_plugin.dispose = rtsp_plugin_dispose;
this->input_plugin.get_optional_data = rtsp_plugin_get_optional_data;
this->input_plugin.input_class = cls_gen;
-
+
return &this->input_plugin;
}
@@ -298,7 +309,7 @@ static void *init_class (xine_t *xine, void *data) {
rtsp_input_class_t *this;
- this = (rtsp_input_class_t *) xine_xmalloc (sizeof (rtsp_input_class_t));
+ this = calloc(1, sizeof (rtsp_input_class_t));
this->xine = xine;
@@ -318,7 +329,7 @@ static void *init_class (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT, 17, "rtsp", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/input_smb.c b/src/input/input_smb.c
index 7da9c1454..5d97d7518 100644
--- a/src/input/input_smb.c
+++ b/src/input/input_smb.c
@@ -1,18 +1,18 @@
/*
- * Copyright (C) 2004 the xine project
- *
+ * Copyright (C) 2008 the xine project
+ *
* 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
@@ -41,7 +41,7 @@
typedef struct {
input_class_t input_class;
xine_t *xine;
-
+
int mrls_allocated_entries;
xine_mrl_t **mrls;
} smb_input_class_t;
@@ -51,7 +51,7 @@ typedef struct {
xine_stream_t *stream;
/* File */
- char *mrl;
+ const char *mrl;
int fd;
} smb_input_t;
@@ -69,6 +69,8 @@ smb_plugin_read (input_plugin_t *this_gen, char *buf, off_t len)
smb_input_t *this = (smb_input_t *) this_gen;
off_t n, num_bytes;
+ if (len < 0)
+ return -1;
num_bytes = 0;
while (num_bytes < len)
@@ -89,6 +91,13 @@ smb_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
off_t total_bytes;
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;
@@ -129,7 +138,7 @@ smb_plugin_get_length (input_plugin_t *this_gen)
int e;
struct stat st;
-
+
if (this->fd>=0) e = smbc_fstat(this->fd,&st);
else e = smbc_stat(this->mrl,&st);
@@ -138,7 +147,7 @@ smb_plugin_get_length (input_plugin_t *this_gen)
return st.st_size;
}
-static char*
+static const char*
smb_plugin_get_mrl (input_plugin_t *this_gen)
{
smb_input_t *this = (smb_input_t *) this_gen;
@@ -150,7 +159,7 @@ static uint32_t smb_plugin_get_blocksize (input_plugin_t *this_gen) {
return 0;
}
-static char
+static const char
*smb_class_get_description (input_class_t *this_gen)
{
return _("CIFS/SMB input plugin based on libsmbclient");
@@ -209,20 +218,20 @@ static int _strverscmp(const char *s1, const char *s2) {
c2 = *p2++;
state |= (c1 == '0') + (ISDIGIT(c1) != 0);
}
-
+
state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT(c2) != 0))];
-
+
switch(state) {
case CMP:
return diff;
-
+
case LEN:
while(ISDIGIT(*p1++))
if(!ISDIGIT(*p2++))
return 1;
-
+
return ISDIGIT(*p2) ? -1 : diff;
-
+
default:
return state;
}
@@ -236,9 +245,9 @@ static int _sortfiles_default(const xine_mrl_t *s1, const xine_mrl_t *s2) {
}
-static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
+static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
const char *filename, int *nFiles) {
-
+
smb_input_class_t *this = (smb_input_class_t *) this_gen;
int (*func) () = _sortfiles_default;
int dir;
@@ -254,38 +263,33 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
snprintf(current_path, XINE_PATH_MAX, "smb:/");
snprintf(current_path_smb, XINE_PATH_MAX, "smb://");
}
-
+
if ((dir = smbc_opendir(current_path_smb)) >= 0){
- xine_mrl_t *dir_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
- xine_mrl_t *norm_files = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t) * MAXFILES);
- int num_dir_files=0;
+ xine_mrl_t *dir_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
+ xine_mrl_t *norm_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t));
+ int num_dir_files=0;
int num_norm_files=0;
while ((pdirent = smbc_readdir(dir)) != NULL){
if (pdirent->smbc_type == SMBC_WORKGROUP){
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(
- strlen(current_path) + 1 + strlen(pdirent->name) + 1);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
- }else if (pdirent->smbc_type == SMBC_SERVER){
+ }else if (pdirent->smbc_type == SMBC_SERVER){
if (num_dir_files == 0) {
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup("smb:/");
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(strlen("smb:/") + 4);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", "smb:/", "..");
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", "smb:/", "..");
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
}
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup("smb:/");
- dir_files[num_dir_files].mrl =
- (char *) xine_xmalloc(strlen("smb:/") + 1 + strlen(pdirent->name) + 1);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", "smb:/", pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", "smb:/", pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
} else if (pdirent->smbc_type == SMBC_FILE_SHARE){
@@ -293,9 +297,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(
- strlen(current_path) + 3);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, "..");
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, "..");
dir_files[num_dir_files].type |= mrl_file_directory;
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
@@ -304,28 +306,22 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(
- strlen(current_path) + 1 + strlen(pdirent->name) + 1);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
- }
+ }
} else if (pdirent->smbc_type == SMBC_DIR){
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl =
- (char *) xine_xmalloc(strlen(current_path) + 1 + strlen(pdirent->name) + 1);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, pdirent->name);
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, pdirent->name);
dir_files[num_dir_files].size = pdirent->dirlen;
num_dir_files ++;
}else if (pdirent->smbc_type == SMBC_FILE){
norm_files[num_norm_files].link = NULL;
norm_files[num_norm_files].type = mrl_file | mrl_file_normal;
norm_files[num_norm_files].origin = strdup(current_path);
- norm_files[num_norm_files].mrl =
- (char *) xine_xmalloc(strlen(current_path) + 1 + strlen(pdirent->name) + 1);
- sprintf(norm_files[num_norm_files].mrl, "%s/%s", current_path, pdirent->name);
+ asprintf(&(norm_files[num_norm_files].mrl), "%s/%s", current_path, pdirent->name);
norm_files[num_norm_files].size = pdirent->dirlen;
num_norm_files ++;
}
@@ -335,8 +331,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
if (num_dir_files == 0) {
dir_files[num_dir_files].link = NULL;
dir_files[num_dir_files].origin = strdup(current_path);
- dir_files[num_dir_files].mrl = (char *) xine_xmalloc(strlen(current_path) + 4);
- sprintf(dir_files[num_dir_files].mrl, "%s/%s", current_path, "..");
+ asprintf(&(dir_files[num_dir_files].mrl), "%s/%s", current_path, "..");
dir_files[num_dir_files].type = mrl_file | mrl_file_directory;
dir_files[num_dir_files].size = 0;
num_dir_files ++;
@@ -347,49 +342,49 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
*/
if(num_dir_files)
qsort(dir_files, num_dir_files, sizeof(xine_mrl_t), func);
-
+
if(num_norm_files)
qsort(norm_files, num_norm_files, sizeof(xine_mrl_t), func);
-
+
/*
* Add directories entries
*/
for(i = 0; i < num_dir_files; i++) {
if (num_files >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
- this->mrls = realloc(this->mrls,
+ this->mrls = realloc(this->mrls,
(this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
-
- MRL_DUPLICATE(&dir_files[i], this->mrls[num_files]);
+
+ MRL_DUPLICATE(&dir_files[i], this->mrls[num_files]);
num_files++;
}
-
- /*
+
+ /*
* Add other files entries
*/
for(i = 0; i < num_norm_files; i++) {
if(num_files >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
- this->mrls = realloc(this->mrls,
+ this->mrls = realloc(this->mrls,
(this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[num_files] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t));
}else
memset(this->mrls[num_files], 0, sizeof(xine_mrl_t));
- MRL_DUPLICATE(&norm_files[i], this->mrls[num_files]);
+ MRL_DUPLICATE(&norm_files[i], this->mrls[num_files]);
num_files++;
}
-
+
/* Some cleanups before leaving */
for(i = num_dir_files; i == 0; i--)
MRL_ZERO(&dir_files[i]);
free(dir_files);
-
+
for(i = num_norm_files; i == 0; i--)
MRL_ZERO(&norm_files[i]);
free(norm_files);
@@ -399,13 +394,13 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
current_path, errno, strerror(errno));
*nFiles = 0;
return NULL;
- }
-
+ }
+
/*
* Inform caller about files found number.
*/
*nFiles = num_files;
-
+
/*
* Freeing exceeded mrls if exists.
*/
@@ -413,7 +408,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
MRL_ZERO(this->mrls[this->mrls_allocated_entries - 1]);
free(this->mrls[this->mrls_allocated_entries--]);
}
-
+
/*
* This is useful to let UI know where it should stops ;-).
*/
@@ -423,7 +418,7 @@ static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen,
}
static int
-smb_plugin_get_optional_data (input_plugin_t *this_gen,
+smb_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type)
{
return INPUT_OPTIONAL_UNSUPPORTED;
@@ -437,7 +432,7 @@ smb_plugin_dispose (input_plugin_t *this_gen )
if (this->fd>=0)
smbc_close(this->fd);
if (this->mrl)
- free (this->mrl);
+ free ((char *)this->mrl);
free (this);
}
@@ -448,8 +443,8 @@ smb_plugin_open (input_plugin_t *this_gen )
smb_input_class_t *class = (smb_input_class_t *) this_gen->input_class;
this->fd = smbc_open(this->mrl,O_RDONLY,0);
- xprintf(class->xine, XINE_VERBOSITY_DEBUG,
- "input_smb: open failed for %s: %s\n",
+ xprintf(class->xine, XINE_VERBOSITY_DEBUG,
+ "input_smb: open failed for %s: %s\n",
this->mrl, strerror(errno));
if (this->fd<0) return 0;
@@ -469,13 +464,13 @@ smb_class_get_instance (input_class_t *class_gen, xine_stream_t *stream,
const char *mrl)
{
smb_input_t *this;
-
+
if (mrl == NULL)
return NULL;
if (strncmp (mrl, "smb://",6))
return NULL;
- this = (smb_input_t *)xine_xmalloc(sizeof(smb_input_t));
+ this = calloc(1, sizeof(smb_input_t));
this->stream = stream;
this->mrl = strdup (mrl);
this->fd = -1;
@@ -513,8 +508,8 @@ static void
if (smbc_init(smb_auth,(xine->verbosity >= XINE_VERBOSITY_DEBUG)))
goto _exit_error;
-
- this = (smb_input_class_t *) xine_xmalloc(sizeof(smb_input_class_t));
+
+ this = calloc(1, sizeof(smb_input_class_t));
this->xine = xine;
this->input_class.get_instance = smb_class_get_instance;
@@ -531,7 +526,7 @@ static void
setlocale(LC_MESSAGES, lcl);
free(lcl);
#endif
-
+
return (input_class_t *) this;
}
diff --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c
index 465e9c00b..74f2a1014 100644
--- a/src/input/input_stdin_fifo.c
+++ b/src/input/input_stdin_fifo.c
@@ -2,17 +2,17 @@
* Copyright (C) 2000-2003 the xine project
*
* 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
@@ -78,13 +78,15 @@ static off_t stdin_plugin_get_current_pos (input_plugin_t *this_gen);
-static off_t stdin_plugin_read (input_plugin_t *this_gen,
+static off_t stdin_plugin_read (input_plugin_t *this_gen,
char *buf, off_t len) {
stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen;
off_t n, total;
lprintf ("reading %"PRId64" bytes...\n", len);
+ if (len < 0)
+ return -1;
total=0;
if (this->curpos < this->preview_size) {
@@ -102,7 +104,7 @@ static off_t stdin_plugin_read (input_plugin_t *this_gen,
n = _x_io_file_read (this->stream, this->fh, &buf[total], len - total);
lprintf ("got %"PRId64" bytes (%"PRId64"/%"PRId64" bytes read)\n", n,total,len);
-
+
if (n < 0) {
_x_message(this->stream, XINE_MSG_READ_ERROR, NULL);
return 0;
@@ -114,13 +116,20 @@ static off_t stdin_plugin_read (input_plugin_t *this_gen,
return total;
}
-static buf_element_t *stdin_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
+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;
@@ -146,7 +155,7 @@ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int orig
if ((origin == SEEK_CUR) && (offset >= 0)) {
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -157,18 +166,18 @@ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int orig
if (offset < this->curpos) {
- if( this->curpos <= this->preview_size )
+ if( this->curpos <= this->preview_size )
this->curpos = offset;
else
- xprintf (this->xine, XINE_VERBOSITY_LOG,
- _("stdin: cannot seek back! (%" PRIdMAX " > %" PRIdMAX ")\n"),
+ xprintf (this->xine, XINE_VERBOSITY_LOG,
+ _("stdin: cannot seek back! (%" PRIdMAX " > %" PRIdMAX ")\n"),
(intmax_t)this->curpos, (intmax_t)offset);
} else {
offset -= this->curpos;
for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
- if( !this_gen->read (this_gen, this->seek_buf, BUFSIZE) )
+ if( this_gen->read (this_gen, this->seek_buf, BUFSIZE) <= 0 )
return this->curpos;
}
@@ -185,7 +194,7 @@ static off_t stdin_plugin_get_length(input_plugin_t *this_gen) {
}
static uint32_t stdin_plugin_get_capabilities(input_plugin_t *this_gen) {
-
+
return INPUT_CAP_PREVIEW;
}
@@ -209,17 +218,17 @@ static const char* stdin_plugin_get_mrl (input_plugin_t *this_gen) {
static void stdin_plugin_dispose (input_plugin_t *this_gen ) {
stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen;
- if (this->nbc)
+ if (this->nbc)
nbc_close (this->nbc);
if ((this->fh != STDIN_FILENO) && (this->fh != -1))
close(this->fh);
-
+
free (this->mrl);
free (this);
}
-static int stdin_plugin_get_optional_data (input_plugin_t *this_gen,
+static int stdin_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen;
@@ -270,13 +279,15 @@ static int stdin_plugin_open (input_plugin_t *this_gen ) {
this->preview_size = stdin_plugin_read (&this->input_plugin, this->preview,
MAX_PREVIEW_SIZE);
+ if (this->preview_size < 0)
+ this->preview_size = 0;
this->curpos = 0;
return 1;
}
-static input_plugin_t *stdin_class_get_instance (input_class_t *class_gen,
+static input_plugin_t *stdin_class_get_instance (input_class_t *class_gen,
xine_stream_t *stream, const char *data) {
stdin_input_class_t *class = (stdin_input_class_t *) class_gen;
@@ -311,7 +322,7 @@ static input_plugin_t *stdin_class_get_instance (input_class_t *class_gen,
* => create plugin instance
*/
- this = (stdin_input_plugin_t *) xine_xmalloc(sizeof(stdin_input_plugin_t));
+ this = calloc(1, sizeof(stdin_input_plugin_t));
this->stream = stream;
this->curpos = 0;
@@ -362,7 +373,7 @@ static void *init_class (xine_t *xine, void *data) {
stdin_input_class_t *this;
- this = (stdin_input_class_t *) xine_xmalloc (sizeof (stdin_input_class_t));
+ this = calloc(1, sizeof (stdin_input_class_t));
this->xine = xine;
diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c
index b43a2684a..e3af41f85 100644
--- a/src/input/input_v4l.c
+++ b/src/input/input_v4l.c
@@ -1,19 +1,19 @@
/*
- * Copyright (C) 2003-2004 the xine project
+ * Copyright (C) 2003-2008 the xine project
* Copyright (C) 2003 J.Asselman <j.asselman@itsec-ps.nl>
- *
+ *
* 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
@@ -65,7 +65,7 @@
#define LOG_MODULE "input_v4l"
#define LOG_VERBOSE
/*
-#define LOG
+#define LOG
*/
#include "xine_internal.h"
@@ -91,13 +91,15 @@ static const resolution_t resolutions[] = {
};
#define NUM_RESOLUTIONS (sizeof(resolutions)/sizeof(resolutions[0]))
-#define RADIO_DEV "/dev/v4l/radio0"
-#define VIDEO_DEV "/dev/v4l/video0"
-
-#if !defined(NDELAY) && defined(O_NDELAY)
-#define FNDELAY O_NDELAY
+#define RADIO_DEV "/dev/radio0"
+#define VIDEO_DEV "/dev/video0"
+#ifdef HAVE_ALSA
+#define AUDIO_DEV "plughw:0,0"
#endif
+static char *tv_standard_names[] = { "AUTO", "PAL", "NTSC", "SECAM", "OLD", NULL };
+static int tv_standard_values[] = { VIDEO_MODE_AUTO, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM, -1 };
+
typedef struct pvrscr_s pvrscr_t;
typedef struct {
@@ -107,7 +109,7 @@ typedef struct {
typedef struct {
input_plugin_t input_plugin;
-
+
xine_stream_t *stream;
char *mrl;
@@ -117,7 +119,11 @@ typedef struct {
int old_zoomx;
int old_zoomy;
int audio_only;
-
+
+ buf_element_t *frames_base;
+ void *audio_content_base;
+ void *video_content_base;
+
/* Audio */
buf_element_t *aud_frames;
pthread_mutex_t aud_frames_lock;
@@ -126,32 +132,32 @@ typedef struct {
#ifdef HAVE_ALSA
/* Handle for the PCM device */
snd_pcm_t *pcm_handle;
-
+
/* Record stream (via line 1) */
snd_pcm_stream_t pcm_stream;
-
+
/* Information and configuration for the PCM stream */
snd_pcm_hw_params_t *pcm_hwparams;
/* Name of the PCM device, plughw:0,0?=>soundcard,device*/
- char *pcm_name;
-
+ char *pcm_name;
+
/* Use alsa to capture the sound (for a/v sync) */
char audio_capture;
-
+
int exact_rate; /* Actual sample rate
sndpcm_hw_params_set_rate_near */
int dir; /* exact rate == rate --> dir = 0
exact rate < rate --> dir = -1
exact rate > rate --> dir = 1 */
-
+
unsigned char *pcm_data;
-
+
int64_t pts_aud_start;
#endif
int audio_header_sent;
-
+
int rate; /* Sample rate */
int periods; /* Number of periods */
int periodsize; /* Periodsize in bytes */
@@ -180,9 +186,9 @@ typedef struct {
struct video_audio audio;
struct video_audio audio_saved;
struct video_mbuf gb_buffers;
-
+
int video_header_sent;
-
+
int frame_format;
const resolution_t *resolution;
int frame_size;
@@ -219,13 +225,13 @@ typedef struct {
struct pvrscr_s {
scr_plugin_t scr;
-
+
struct timeval cur_time;
int64_t cur_pts;
int xine_speed;
double speed_factor;
double speed_tuning;
-
+
pthread_mutex_t lock;
};
@@ -240,47 +246,47 @@ static void pvrscr_set_pivot(pvrscr_t *this)
struct timeval tv;
int64_t pts;
double pts_calc;
-
+
xine_monotonic_clock(&tv, NULL);
pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
pts = this->cur_pts + pts_calc;
-
+
/* This next part introduces a one off inaccuracy
* to the scr due to rounding tv to pts.
*/
this->cur_time.tv_sec = tv.tv_sec;
this->cur_time.tv_usec = tv.tv_usec;
this->cur_pts = pts;
-
+
return;
}
static int pvrscr_set_fine_speed (scr_plugin_t *scr, int speed)
{
pvrscr_t *this = (pvrscr_t*) scr;
-
+
pthread_mutex_lock (&this->lock);
-
+
pvrscr_set_pivot( this );
this->xine_speed = speed;
this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
this->speed_tuning;
-
+
pthread_mutex_unlock (&this->lock);
-
+
return speed;
}
static void pvrscr_speed_tuning (pvrscr_t *this, double factor)
{
pthread_mutex_lock (&this->lock);
-
+
pvrscr_set_pivot( this );
this->speed_tuning = factor;
this->speed_factor = (double) this->xine_speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
this->speed_tuning;
-
+
pthread_mutex_unlock (&this->lock);
}
@@ -288,28 +294,28 @@ static void pvrscr_adjust (scr_plugin_t *scr, int64_t vpts)
{
pvrscr_t *this = (pvrscr_t*) scr;
struct timeval tv;
-
+
pthread_mutex_lock (&this->lock);
-
+
xine_monotonic_clock(&tv, NULL);
this->cur_time.tv_sec = tv.tv_sec;
this->cur_time.tv_usec = tv.tv_usec;
this->cur_pts = vpts;
-
+
pthread_mutex_unlock (&this->lock);
}
static void pvrscr_start (scr_plugin_t *scr, int64_t start_vpts)
{
pvrscr_t *this = (pvrscr_t*) scr;
-
+
pthread_mutex_lock (&this->lock);
-
+
xine_monotonic_clock(&this->cur_time, NULL);
this->cur_pts = start_vpts;
pthread_mutex_unlock (&this->lock);
-
+
pvrscr_set_fine_speed (&this->scr, XINE_FINE_SPEED_NORMAL);
}
@@ -319,17 +325,17 @@ static int64_t pvrscr_get_current (scr_plugin_t *scr)
struct timeval tv;
int64_t pts;
double pts_calc;
-
+
pthread_mutex_lock (&this->lock);
-
+
xine_monotonic_clock(&tv, NULL);
-
+
pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
pts = this->cur_pts + pts_calc;
-
+
pthread_mutex_unlock (&this->lock);
-
+
/*printf("returning pts %lld\n", pts);*/
return pts;
}
@@ -337,17 +343,17 @@ static int64_t pvrscr_get_current (scr_plugin_t *scr)
static void pvrscr_exit (scr_plugin_t *scr)
{
pvrscr_t *this = (pvrscr_t*) scr;
-
+
pthread_mutex_destroy (&this->lock);
free(this);
}
-static pvrscr_t* pvrscr_init (void)
+static pvrscr_t *XINE_MALLOC pvrscr_init (void)
{
pvrscr_t *this;
-
- this = (pvrscr_t *) xine_xmalloc(sizeof(pvrscr_t));
-
+
+ this = calloc(1, sizeof(pvrscr_t));
+
this->scr.interface_version = 3;
this->scr.get_priority = pvrscr_get_priority;
this->scr.set_fine_speed = pvrscr_set_fine_speed;
@@ -355,7 +361,7 @@ static pvrscr_t* pvrscr_init (void)
this->scr.start = pvrscr_start;
this->scr.get_current = pvrscr_get_current;
this->scr.exit = pvrscr_exit;
-
+
pthread_mutex_init (&this->lock, NULL);
pvrscr_speed_tuning(this, 1.0 );
@@ -363,7 +369,7 @@ static pvrscr_t* pvrscr_init (void)
#ifdef SCRLOG
printf("input_v4l: scr init complete\n");
#endif
-
+
return this;
}
@@ -374,7 +380,7 @@ static void report_progress (xine_stream_t *stream, int p)
{
xine_event_t event;
xine_progress_data_t prg;
-
+
if (p == SCR_PAUSED) {
prg.description = _("Buffer underrun...");
p = 0;
@@ -384,13 +390,13 @@ static void report_progress (xine_stream_t *stream, int p)
p = 100;
} else
prg.description = _("Adjusting...");
-
+
prg.percent = (p>100)?100:p;
-
+
event.type = XINE_EVENT_PROGRESS;
event.data = &prg;
event.data_length = sizeof (xine_progress_data_t);
-
+
xine_event_send (stream, &event);
}
@@ -406,25 +412,25 @@ static void v4l_event_handler(v4l_input_plugin_t *this);
inline static buf_element_t *alloc_aud_frame (v4l_input_plugin_t *this)
{
buf_element_t *frame;
-
+
lprintf("alloc_aud_frame. trying to get lock...\n");
pthread_mutex_lock (&this->aud_frames_lock) ;
-
+
lprintf("got the lock\n");
-
+
while (!this->aud_frames) {
lprintf("no audio frame available...\n");
pthread_cond_wait (&this->aud_frame_freed, &this->aud_frames_lock);
}
-
+
frame = this->aud_frames;
this->aud_frames = this->aud_frames->next;
-
+
pthread_mutex_unlock (&this->aud_frames_lock);
-
+
lprintf("alloc_aud_frame done\n");
-
+
return frame;
}
@@ -438,10 +444,10 @@ static void store_aud_frame (buf_element_t *frame)
lprintf("store_aud_frame\n");
pthread_mutex_lock (&this->aud_frames_lock) ;
-
+
frame->next = this->aud_frames;
this->aud_frames = frame;
-
+
pthread_cond_signal (&this->aud_frame_freed);
pthread_mutex_unlock (&this->aud_frames_lock);
}
@@ -458,19 +464,19 @@ inline static buf_element_t *alloc_vid_frame (v4l_input_plugin_t *this)
pthread_mutex_lock (&this->vid_frames_lock) ;
lprintf("got the lock\n");
-
+
while (!this->vid_frames) {
lprintf("no video frame available...\n");
pthread_cond_wait (&this->vid_frame_freed, &this->vid_frames_lock);
}
-
+
frame = this->vid_frames;
this->vid_frames = this->vid_frames->next;
-
+
pthread_mutex_unlock (&this->vid_frames_lock);
-
+
lprintf("alloc_vid_frame done\n");
-
+
return frame;
}
@@ -481,50 +487,50 @@ static void store_vid_frame (buf_element_t *frame)
{
v4l_input_plugin_t *this = (v4l_input_plugin_t *) frame->source;
-
+
lprintf("store_vid_frame\n");
-
+
pthread_mutex_lock (&this->vid_frames_lock) ;
frame->next = this->vid_frames;
this->vid_frames = frame;
-
+
pthread_cond_signal (&this->vid_frame_freed);
pthread_mutex_unlock (&this->vid_frames_lock);
}
-static int extract_mrl(v4l_input_plugin_t *this, char *mrl)
+static int extract_mrl(v4l_input_plugin_t *this, char *mrl)
{
char *tuner_name = NULL;
int frequency = 0;
char *locator = NULL;
char *begin = NULL;
-
+
if (mrl == NULL) {
lprintf("Someone passed an empty mrl\n");
return 0;
}
-
+
for (locator = mrl; *locator != '\0' && *locator != '/' ; locator++);
-
+
/* Get tuner name */
if (*locator == '/') {
begin = ++locator;
-
+
for (; *locator != '\0' && *locator != '/' ; locator++);
-
+
tuner_name = (char *) strndup(begin, locator - begin);
-
- /* Get frequency, if available */
+
+ /* Get frequency, if available */
sscanf(locator, "/%d", &frequency);
-
+
/* cannot use xprintf to log in this routine */
lprintf("input_v4l: Tuner name: %s frequency %d\n", tuner_name, frequency );
}
-
+
this->frequency = frequency;
this->tuner_name = tuner_name;
-
+
return 1;
}
@@ -532,30 +538,36 @@ static int set_frequency(v4l_input_plugin_t *this, unsigned long frequency)
{
int ret = 0;
int fd;
-
+
if (this->video_fd > 0)
fd = this->video_fd;
else
fd = this->radio_fd;
-
+
if (frequency != 0) {
+ /* FIXME: Don't assume tuner 0 ? */
+ this->tuner = 0;
+ ret = ioctl(fd, VIDIOCSTUNER, &this->tuner);
+ lprintf("(%d) Response on set tuner to %d\n", ret, this->tuner);
+ this->video_tuner.tuner = this->tuner;
+
if (this->video_tuner.flags & VIDEO_TUNER_LOW) {
this->calc_frequency = frequency * 16;
} else {
this->calc_frequency = (frequency * 16) / 1000;
}
-
+
ret = ioctl(fd, VIDIOCSFREQ, &this->calc_frequency);
lprintf("IOCTL set frequency (%ld) returned: %d\n", frequency, ret);
} else {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: No frequency given. Expected syntax: v4l:/tuner/frequency\n"
"input_v4l: Using currently tuned settings\n");
}
-
+
this->frequency = frequency;
-
+
if (ret < 0)
return ret;
else
@@ -565,11 +577,11 @@ static int set_frequency(v4l_input_plugin_t *this, unsigned long frequency)
static int set_input_source(v4l_input_plugin_t *this, char *input_source)
{
int ret = 0;
-
+
if ((ret = search_by_channel(this, input_source)) != 1) {
ret = search_by_tuner(this, input_source);
}
-
+
return ret;
}
@@ -578,23 +590,23 @@ static int search_by_tuner(v4l_input_plugin_t *this, char *input_source)
int ret = 0;
int fd = 0;
int cur_tuner = 0;
-
+
if (this->video_fd > 0)
fd = this->video_fd;
else
fd = this->radio_fd;
-
+
this->video_tuner.tuner = cur_tuner;
ioctl(fd, VIDIOCGCAP, &this->video_cap);
-
+
lprintf("This device has %d channel(s)\n", this->video_cap.channels);
-
+
for (ret = ioctl(fd, VIDIOCGTUNER, &this->video_tuner);
ret == 0 && this->video_cap.channels > cur_tuner && strstr(this->video_tuner.name, input_source) == NULL;
cur_tuner++) {
-
+
this->video_tuner.tuner = cur_tuner;
-
+
lprintf("(%d) V4L device currently set to: \n", ret);
lprintf("Tuner: %d\n", this->video_tuner.tuner);
lprintf("Name: %s\n", this->video_tuner.name);
@@ -604,7 +616,7 @@ static int search_by_tuner(v4l_input_plugin_t *this, char *input_source)
lprintf("Range: %ld - %ld\n", this->video_tuner.rangelow * 1000 / 16, this->video_tuner.rangehigh * 1000 / 16);
}
}
-
+
lprintf("(%d) V4L device final: \n", ret);
lprintf("Tuner: %d\n", this->video_tuner.tuner);
lprintf("Name: %s\n", this->video_tuner.name);
@@ -613,10 +625,10 @@ static int search_by_tuner(v4l_input_plugin_t *this, char *input_source)
} else {
lprintf("Range: %ld - %ld\n", this->video_tuner.rangelow * 1000 / 16, this->video_tuner.rangehigh * 1000 / 16);
}
-
+
if (strstr(this->video_tuner.name, input_source) == NULL)
return -1;
-
+
return 1;
}
@@ -624,22 +636,23 @@ static int search_by_channel(v4l_input_plugin_t *this, char *input_source)
{
int ret = 0;
int fd = 0;
+ cfg_entry_t *tv_standard_entry;
lprintf("input_source: %s\n", input_source);
-
+
this->input = 0;
-
+
if (this->video_fd > 0)
fd = this->video_fd;
else
fd = this->radio_fd;
-
+
/* Tune into channel */
if (strlen(input_source) > 0) {
for( this->video_channel.channel = 0;
ioctl(fd, VIDIOCGCHAN, &this->video_channel) == 0;
this->video_channel.channel++ ) {
-
+
lprintf("V4L device currently set to:\n");
lprintf("Channel: %d\n", this->video_channel.channel);
lprintf("Name: %s\n", this->video_channel.name);
@@ -653,34 +666,33 @@ static int search_by_channel(v4l_input_plugin_t *this, char *input_source)
break;
}
}
-
+
if (strstr(this->video_channel.name, input_source) == NULL) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("Tuner name not found\n"));
return -1;
}
-
+
+ tv_standard_entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
+ "media.video4linux.tv_standard");
this->tuner_name = input_source;
- ret = ioctl(fd, VIDIOCSCHAN, &this->input);
-
+ if (tv_standard_entry->num_value != 0) {
+ this->video_channel.norm = tv_standard_values[ tv_standard_entry->num_value ];
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "input_v4l: TV Standard configured as STD %s (%d)\n",
+ tv_standard_names[ tv_standard_entry->num_value ], this->video_channel.norm );
+ ret = ioctl(fd, VIDIOCSCHAN, &this->video_channel);
+ } else
+ ret = ioctl(fd, VIDIOCSCHAN, &this->input);
+
lprintf("(%d) Set channel to %d\n", ret, this->input);
-
- /* FIXME: Don't assume tuner 0 ? */
-
- this->tuner = 0;
-
- ret = ioctl(fd, VIDIOCSTUNER, &this->tuner);
-
- lprintf("(%d) Response on set tuner to %d\n", ret, this->tuner);
-
- this->video_tuner.tuner = this->tuner;
} else {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Not setting video source. No source given\n");
}
ret = ioctl(fd, VIDIOCGTUNER, &this->video_tuner);
lprintf("(%d) Flags %d\n", ret, this->video_tuner.flags);
-
+
lprintf("VIDEO_TUNER_PAL %s set\n", this->video_tuner.flags & VIDEO_TUNER_PAL ? "" : "not");
lprintf("VIDEO_TUNER_NTSC %s set\n", this->video_tuner.flags & VIDEO_TUNER_NTSC ? "" : "not");
lprintf("VIDEO_TUNER_SECAM %s set\n", this->video_tuner.flags & VIDEO_TUNER_SECAM ? "" : "not");
@@ -689,7 +701,7 @@ static int search_by_channel(v4l_input_plugin_t *this, char *input_source)
lprintf("VIDEO_TUNER_STEREO_ON %s set\n", this->video_tuner.flags & VIDEO_TUNER_STEREO_ON ? "" : "not");
lprintf("VIDEO_TUNER_RDS_ON %s set\n", this->video_tuner.flags & VIDEO_TUNER_RDS_ON ? "" : "not");
lprintf("VIDEO_TUNER_MBS_ON %s set\n", this->video_tuner.flags & VIDEO_TUNER_MBS_ON ? "" : "not");
-
+
switch (this->video_tuner.mode) {
case VIDEO_MODE_PAL:
lprintf("The tuner is in PAL mode\n");
@@ -705,26 +717,53 @@ static int search_by_channel(v4l_input_plugin_t *this, char *input_source)
break;
}
- return 1;
+ return 1;
}
-static void allocate_audio_frames(v4l_input_plugin_t *this)
+static void allocate_frames(v4l_input_plugin_t *this, unsigned dovideo)
{
+ const size_t framescount = dovideo ? 2*NUM_FRAMES : NUM_FRAMES;
+
+ /* Allocate a single memory area for both audio and video frames */
+ buf_element_t *frames = this->frames_base =
+ calloc(framescount, sizeof(buf_element_t));
+ extra_info_t *infos =
+ calloc(framescount, sizeof(extra_info_t));
+
int i;
-
+
+ uint8_t *audio_content = this->audio_content_base =
+ calloc(NUM_FRAMES, this->periodsize);
+
+ /* Set up audio frames */
for (i = 0; i < NUM_FRAMES; i++) {
- buf_element_t *frame;
-
/* Audio frame */
- frame = xine_xmalloc(sizeof(buf_element_t));
-
- frame->content = xine_xmalloc(this->periodsize);
- frame->type = BUF_AUDIO_LPCM_LE;
- frame->source = this;
- frame->free_buffer = store_aud_frame;
- frame->extra_info = xine_xmalloc(sizeof(extra_info_t));
-
- store_aud_frame(frame);
+ frames[i].content = audio_content;
+ frames[i].type = BUF_AUDIO_LPCM_LE;
+ frames[i].source = this;
+ frames[i].free_buffer = store_aud_frame;
+ frames[i].extra_info = &infos[i];
+
+ audio_content += this->periodsize;
+ store_aud_frame(&frames[i]);
+ }
+
+ if ( dovideo ) {
+ uint8_t *video_content = this->video_content_base =
+ calloc(NUM_FRAMES, this->frame_size);
+
+ /* Set up video frames */
+ for (i = NUM_FRAMES; i < 2*NUM_FRAMES; i++) {
+ /* Video frame */
+ frames[i].content = video_content;
+ frames[i].type = this->frame_format;
+ frames[i].source = this;
+ frames[i].free_buffer = store_vid_frame;
+ frames[i].extra_info = &infos[i];
+
+ video_content += this->frame_size;
+ store_vid_frame(&frames[i]);
+ }
}
}
@@ -733,12 +772,12 @@ static void unmute_audio(v4l_input_plugin_t *this)
int fd;
lprintf("unmute_audio\n");
-
+
if (this->video_fd > 0)
fd = this->video_fd;
else
fd = this->radio_fd;
-
+
ioctl(fd, VIDIOCGAUDIO, &this->audio);
memcpy(&this->audio_saved, &this->audio, sizeof(this->audio));
@@ -747,43 +786,43 @@ static void unmute_audio(v4l_input_plugin_t *this)
ioctl(fd, VIDIOCSAUDIO, &this->audio);
}
-
+
static int open_radio_capture_device(v4l_input_plugin_t *this)
{
int tuner_found = 0;
cfg_entry_t *entry;
-
+
lprintf("open_radio_capture_device\n");
-
+
entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
"media.video4linux.radio_device");
-
+
if((this->radio_fd = open(entry->str_value, O_RDWR)) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "input_v4l: error opening v4l device (%s): %s\n",
+ "input_v4l: error opening v4l device (%s): %s\n",
entry->str_value, strerror(errno));
return 0;
}
-
+
lprintf("Device opened, radio %d\n", this->radio_fd);
-
+
if (set_input_source(this, this->tuner_name) > 0)
tuner_found = 1;
-
+
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0);
-
+
/* Pre-allocate some frames for audio so it doesn't have to be done during
* capture */
- allocate_audio_frames(this);
-
+ allocate_frames(this, 0);
+
this->audio_only = 1;
-
+
/* Unmute audio off video capture device */
unmute_audio(this);
-
- set_frequency(this, this->frequency);
-
+
+ set_frequency(this, this->frequency);
+
if (tuner_found)
return 1;
else
@@ -801,25 +840,25 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
{
int found = 0;
int tuner_found = 0;
- int i, ret;
+ int ret;
unsigned int j;
cfg_entry_t *entry;
-
+
lprintf("open_video_capture_device\n");
-
- entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
+
+ entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
"media.video4linux.video_device");
/* Try to open the video device */
if((this->video_fd = open(entry->str_value, O_RDWR)) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "input_v4l: error opening v4l device (%s): %s\n",
+ "input_v4l: error opening v4l device (%s): %s\n",
entry->str_value, strerror(errno));
return 0;
}
-
+
lprintf("Device opened, tv %d\n", this->video_fd);
-
+
/* figure out the resolution */
for (j = 0; j < NUM_RESOLUTIONS; j++)
{
@@ -831,7 +870,7 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
break;
}
}
-
+
if (found == 0 || resolutions[j].width < this->video_cap.minwidth
|| resolutions[j].height < this->video_cap.minheight)
{
@@ -839,19 +878,15 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
lprintf("Grab device does not support any preset resolutions");
return 0;
}
-
+
this->resolution = &resolutions[j];
-
+
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
_x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1);
-
- /* Pre-allocate some frames for audio and video so it doesn't have to be
- * done during capture */
- allocate_audio_frames(this);
-
+
/* Unmute audio off video capture device */
unmute_audio(this);
-
+
if (strlen(this->tuner_name) > 0) {
/* Tune into source and given frequency */
if (set_input_source(this, this->tuner_name) <= 0)
@@ -859,20 +894,20 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
else
tuner_found = 1;
}
-
- set_frequency(this, this->frequency);
-
+
+ set_frequency(this, this->frequency);
+
/* Test for mmap video access */
ret = ioctl(this->video_fd,VIDIOCGMBUF, &this->gb_buffers);
-
+
if (ret < 0) {
/* Device driver does not support mmap */
/* try to use read based access */
struct video_picture pict;
int val;
-
+
ioctl(this->video_fd, VIDIOCGPICT, &pict);
-
+
/* try to choose a suitable video format */
pict.palette = VIDEO_PALETTE_YUV420P;
ret = ioctl(this->video_fd, VIDIOCSPICT, &pict);
@@ -890,13 +925,13 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
}
else
lprintf("Grab: format YUV 4:2:0\n");
-
+
this->frame_format = pict.palette;
val = 1;
ioctl(this->video_fd, VIDIOCCAPTURE, &val);
-
+
this->use_mmap = 0;
-
+
} else {
/* Good, device driver support mmap. Mmap the memory */
lprintf("using mmap, size %d\n", this->gb_buffers.size);
@@ -910,23 +945,23 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
return 0;
}
this->gb_frame = 0;
-
+
/* start to grab the first frame */
this->gb_buf.frame = (this->gb_frame + 1) % this->gb_buffers.frames;
this->gb_buf.height = resolutions[j].height;
this->gb_buf.width = resolutions[j].width;
this->gb_buf.format = VIDEO_PALETTE_YUV420P;
-
+
ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf);
if (ret < 0 && errno != EAGAIN) {
/* try YUV422 */
this->gb_buf.format = VIDEO_PALETTE_YUV422;
-
+
ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf);
}
else
lprintf("(%d) YUV420 should work\n", ret);
-
+
if (ret < 0) {
if (errno != EAGAIN) {
lprintf("grab device does not support suitable format\n");
@@ -939,7 +974,7 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
this->frame_format = this->gb_buf.format;
this->use_mmap = 1;
}
-
+
switch(this->frame_format) {
case VIDEO_PALETTE_YUV420P:
this->frame_format = BUF_VIDEO_I420;
@@ -950,29 +985,19 @@ static int open_video_capture_device(v4l_input_plugin_t *this)
this->frame_size = resolutions[j].width * resolutions[j].height * 2;
break;
}
-
- for (i = 0; i < NUM_FRAMES; i++) {
- buf_element_t *frame;
-
- frame = xine_xmalloc (sizeof (buf_element_t));
-
- frame->content = xine_xmalloc (this->frame_size);
- frame->type = this->frame_format;
- frame->source = this;
- frame->free_buffer = store_vid_frame;
- frame->extra_info = xine_xmalloc(sizeof(extra_info_t));
-
- store_vid_frame(frame);
- }
-
- /* Strip the vbi / sync signal from the image by zooming in */
+
+ /* Strip the vbi / sync signal from the image by zooming in */
this->old_zoomx = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_X);
this->old_zoomy = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_Y);
-
+
xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 103);
xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, 103);
-
- /* If we made it here, everything went ok */
+
+ /* Pre-allocate some frames for audio and video so it doesn't have to be
+ * done during capture */
+ allocate_frames(this, 1);
+
+ /* If we made it here, everything went ok */
this->audio_only = 0;
if (tuner_found)
return 1;
@@ -996,98 +1021,98 @@ static int open_audio_capture_device(v4l_input_plugin_t *this)
/* Allocate the snd_pcm_hw_params_t structure on the stack. */
snd_pcm_hw_params_alloca(&this->pcm_hwparams);
-
+
/* If we are not capturing video, open the sound device in blocking mode,
* otherwise xine gets too many NULL bufs and doesn't seem to handle them
* correctly. If we are capturing video, open the sound device in non-
* blocking mode, otherwise we will loose video frames while waiting */
if(!this->audio_only)
mode = SND_PCM_NONBLOCK;
-
+
/* Open the PCM device. */
if(snd_pcm_open(&this->pcm_handle, this->pcm_name, this->pcm_stream, mode) < 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Error opening PCM device: %s\n", this->pcm_name);
this->audio_capture = 0;
}
-
+
/* Get parameters */
if (this->audio_capture &&
(snd_pcm_hw_params_any(this->pcm_handle, this->pcm_hwparams) < 0)) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Broken configuration for PCM device: No configurations available\n");
this->audio_capture = 0;
}
-
+
/* Set access type */
if (this->audio_capture &&
(snd_pcm_hw_params_set_access(this->pcm_handle, this->pcm_hwparams,
SND_PCM_ACCESS_RW_INTERLEAVED) < 0)) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Error setting SND_PCM_ACCESS_RW_INTERLEAVED\n");
this->audio_capture = 0;
}
-
+
/* Set sample format */
if (this->audio_capture &&
- (snd_pcm_hw_params_set_format(this->pcm_handle,
+ (snd_pcm_hw_params_set_format(this->pcm_handle,
this->pcm_hwparams, SND_PCM_FORMAT_S16_LE) < 0)) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Error setting SND_PCM_FORMAT_S16_LE\n");
this->audio_capture = 0;
}
-
+
/* Set sample rate */
this->exact_rate = this->rate;
if (this->audio_capture &&
- (snd_pcm_hw_params_set_rate_near(this->pcm_handle, this->pcm_hwparams,
+ (snd_pcm_hw_params_set_rate_near(this->pcm_handle, this->pcm_hwparams,
&this->exact_rate, &this->dir) < 0)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Error setting samplerate\n");
this->audio_capture = 0;
}
if (this->audio_capture && this->dir != 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Samplerate %d Hz is not supported by your hardware\n", this->rate);
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Using %d instead\n", this->exact_rate);
}
-
+
/* Set number of channels */
if (this->audio_capture &&
(snd_pcm_hw_params_set_channels(this->pcm_handle, this->pcm_hwparams, 2) < 0)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting PCM channels\n");
this->audio_capture = 0;
}
-
+
if (this->audio_capture &&
(snd_pcm_hw_params_set_periods(this->pcm_handle, this->pcm_hwparams, this->periods, 0) < 0)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting PCM periods\n");
this->audio_capture = 0;
}
-
+
/* Set buffersize */
if (this->audio_capture &&
- (snd_pcm_hw_params_set_buffer_size_near(this->pcm_handle,
+ (snd_pcm_hw_params_set_buffer_size_near(this->pcm_handle,
this->pcm_hwparams,
&buf_size) < 0)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting PCM buffer size to %d\n", (int)buf_size );
this->audio_capture = 0;
}
-
+
/* Apply HW parameter settings */
if (this->audio_capture &&
(snd_pcm_hw_params(this->pcm_handle, this->pcm_hwparams) < 0)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error Setting PCM HW params\n");
this->audio_capture = 0;
}
-
+
if (this->audio_capture) {
lprintf("Allocating memory for PCM capture :%d\n", this->periodsize);
this->pcm_data = (unsigned char*) malloc(this->periodsize);
} else
- this->pcm_data = NULL;
-
+ this->pcm_data = NULL;
+
lprintf("Audio device succesfully configured\n");
#endif
return 0;
@@ -1103,30 +1128,30 @@ static int v4l_adjust_realtime_speed(v4l_input_plugin_t *this, fifo_buffer_t *fi
{
int num_used, num_free;
int scr_tuning = this->scr_tuning;
-
+
if (fifo == NULL)
return 0;
-
+
num_used = fifo->size(fifo);
num_free = NUM_FRAMES - num_used;
-
+
if (!this->audio_only && num_used == 0 && scr_tuning != SCR_PAUSED) {
/* Buffer is empty, and we did not pause playback */
report_progress(this->stream, SCR_PAUSED);
-
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_v4l: Buffer empty, pausing playback (used: %d, num_free: %d)\n",
num_used, num_free);
-
+
_x_set_speed(this->stream, XINE_SPEED_PAUSE);
this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 0);
-
+
this->scr_tuning = SCR_PAUSED;
/* pvrscr_speed_tuning(this->scr, 0.0); */
-
+
} else if (num_free <= 1 && scr_tuning != SCR_SKIP) {
this->scr_tuning = SCR_SKIP;
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_v4l: Buffer full, skipping (used: %d, free: %d)\n", num_used, num_free);
return 0;
} else if (scr_tuning == SCR_PAUSED) {
@@ -1134,11 +1159,11 @@ static int v4l_adjust_realtime_speed(v4l_input_plugin_t *this, fifo_buffer_t *fi
/* Playback was paused, but we have normal buffer usage again */
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_v4l: Resuming from paused (used: %d, free: %d)\n", num_used, num_free);
-
+
this->scr_tuning = 0;
-
+
pvrscr_speed_tuning(this->scr, 1.0);
-
+
_x_set_speed(this->stream, XINE_SPEED_NORMAL);
this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1);
}
@@ -1163,12 +1188,12 @@ static int v4l_adjust_realtime_speed(v4l_input_plugin_t *this, fifo_buffer_t *fi
(scr_tuning < 0 && num_used > num_free))
/* Buffer usage is ok again. Set playback speed to normal */
scr_tuning = 0;
-
- /* Check if speed adjustment should be changed */
+
+ /* Check if speed adjustment should be changed */
if (scr_tuning != this->scr_tuning) {
this->scr_tuning = scr_tuning;
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
- "input_v4l: scr tuning = %d (used: %d, free: %d)\n",
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "input_v4l: scr tuning = %d (used: %d, free: %d)\n",
scr_tuning, num_used, num_free);
pvrscr_speed_tuning(this->scr, 1.0 + (0.01 * scr_tuning));
}
@@ -1178,13 +1203,13 @@ static int v4l_adjust_realtime_speed(v4l_input_plugin_t *this, fifo_buffer_t *fi
* speed
*/
this->scr_tuning = 0;
-
+
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_v4l: scr tuning resetting (used: %d, free: %d\n", num_used, num_free);
-
+
pvrscr_speed_tuning(this->scr, 1.0);
}
-
+
return 1;
}
@@ -1221,15 +1246,15 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buff
uint8_t *ptr;
static char video = 0;
int speed = _x_get_speed(this->stream);
-
- v4l_event_handler(this);
-
+
+ v4l_event_handler(this);
+
#ifdef HAVE_ALSA
if (!this->audio_header_sent) {
lprintf("sending audio header\n");
-
+
buf = alloc_aud_frame (this);
-
+
buf->size = 0;
buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
@@ -1237,60 +1262,60 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buff
buf->decoder_info[1] = this->exact_rate;
buf->decoder_info[2] = this->bits;
buf->decoder_info[3] = 2;
-
+
this->audio_header_sent = 1;
-
+
return buf;
}
-#endif
-
+#endif
+
if (!this->audio_only && !this->video_header_sent) {
xine_bmiheader bih;
-
+
lprintf("sending video header");
-
+
bih.biSize = sizeof(xine_bmiheader);
bih.biWidth = this->resolution->width;
bih.biHeight = this->resolution->height;
-
+
buf = alloc_vid_frame (this);
-
+
buf->size = sizeof(xine_bmiheader);
buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END;
memcpy(buf->content, &bih, sizeof(xine_bmiheader));
-
+
this->video_header_sent = 1;
-
- return buf;
+
+ return buf;
}
-
+
if (!this->audio_only) {
if (!v4l_adjust_realtime_speed(this, fifo, speed)) {
return NULL;
}
}
-
- if (!this->audio_only)
+
+ if (!this->audio_only)
video = !video;
else
video = 0;
-
+
lprintf("%lld bytes...\n", todo);
-
- if (this->start_time == 0)
+
+ if (this->start_time == 0)
/* Create a start pts value */
this->start_time = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */
-
+
if (video) {
/* Capture video */
buf = alloc_vid_frame (this);
buf->decoder_flags = BUF_FLAG_FRAME_START|BUF_FLAG_FRAME_END;
-
+
this->gb_buf.frame = this->gb_frame;
-
+
lprintf("VIDIOCMCAPTURE\n");
-
+
while (ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf) < 0) {
lprintf("Upper while loop\n");
if (errno == EAGAIN) {
@@ -1302,92 +1327,92 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buff
return NULL;
}
}
-
+
this->gb_frame = (this->gb_frame + 1) % this->gb_buffers.frames;
-
+
while (ioctl(this->video_fd, VIDIOCSYNC, &this->gb_frame) < 0 &&
(errno == EAGAIN || errno == EINTR))
{
lprintf("Waiting for videosync\n");
}
-
+
/* printf ("grabbing frame #%d\n", frame_num); */
-
+
ptr = this->video_buf + this->gb_buffers.offsets[this->gb_frame];
buf->pts = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */
- xine_fast_memcpy (buf->content, ptr, this->frame_size);
+ xine_fast_memcpy (buf->content, ptr, this->frame_size);
}
#ifdef HAVE_ALSA
else if (this->audio_capture) {
/* Record audio */
int pcmreturn;
-
- if ((pcmreturn = snd_pcm_readi(this->pcm_handle, this->pcm_data, (this->periodsize)>> 2)) < 0) {
+
+ if ((pcmreturn = snd_pcm_readi(this->pcm_handle, this->pcm_data, (this->periodsize)>> 2)) < 0) {
switch (pcmreturn) {
case -EAGAIN:
/* No data available at the moment */
break;
case -EBADFD: /* PCM device in wrong state */
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: PCM is not in the right state\n");
break;
case -EPIPE: /* Buffer overrun */
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: PCM buffer Overrun (lost some samples)\n");
/* On buffer overrun we need to re prepare the capturing pcm device */
snd_pcm_prepare(this->pcm_handle);
break;
case -ESTRPIPE: /* Suspend event */
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: PCM suspend event occured\n");
break;
default: /* Unknown */
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Unknown PCM error code: %d\n", pcmreturn);
snd_pcm_prepare(this->pcm_handle);
}
} else {
/* Succesfully read audio data */
-
+
if (this->pts_aud_start) {
buf = alloc_aud_frame (this);
buf->decoder_flags = 0;
}
-
+
/* We want the pts on the start of the sample. As the soundcard starts
* sampling a new sample as soon as the read function returned with a
- * success we will save the current pts and assign the current pts to
+ * success we will save the current pts and assign the current pts to
* that sample when we read it
*/
-
+
/* Assign start pts to sample */
if (buf)
buf->pts = this->pts_aud_start;
-
+
/* Save start pts */
this->pts_aud_start = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */
-
+
if (!buf)
/* Skip first sample as we don't have a good pts for this one */
return NULL;
-
+
lprintf("Audio: Data read: %d [%d, %d]. Pos: %d\n",
pcmreturn, (int) (*this->pcm_data), (int) (*(this->pcm_data + this->periodsize - 3)),
(int) this->curpos);
-
-
+
+
/* Tell decoder the number of bytes we have read */
- buf->size = pcmreturn<<2;
-
+ buf->size = pcmreturn<<2;
+
this->curpos++;
-
+
xine_fast_memcpy(buf->content, this->pcm_data, buf->size);
}
}
#endif
-
+
lprintf("read block done\n");
-
+
return buf;
}
@@ -1397,7 +1422,7 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buff
*/
static off_t v4l_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
-
+
lprintf("seek %lld bytes, origin %d\n", offset, origin);
return this->curpos;
}
@@ -1408,10 +1433,10 @@ static off_t v4l_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
*/
static off_t v4l_plugin_get_length (input_plugin_t *this_gen) {
/*
- v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
+ v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
off_t length;
*/
-
+
return -1;
}
@@ -1421,8 +1446,8 @@ static off_t v4l_plugin_get_length (input_plugin_t *this_gen) {
*/
static uint32_t v4l_plugin_get_capabilities (input_plugin_t *this_gen)
{
- v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
-
+ v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
+
if (this->audio_only)
return 0x10;
else
@@ -1444,26 +1469,26 @@ static uint32_t v4l_plugin_get_blocksize (input_plugin_t *this_gen)
*/
static off_t v4l_plugin_get_current_pos (input_plugin_t *this_gen){
v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
-
+
/*
printf ("current pos is %lld\n", this->curpos);
*/
-
+
return this->curpos;
}
/**
* Event handler.
- *
+ *
* Processes events from a frontend. This way frequencies can be changed
* without closing the v4l plugin.
*/
static void v4l_event_handler (v4l_input_plugin_t *this) {
xine_event_t *event;
-
+
while ((event = xine_event_get (this->event_queue))) {
xine_set_v4l2_data_t *v4l2_data = event->data;
-
+
switch (event->type) {
case XINE_EVENT_SET_V4L2:
if( v4l2_data->input != this->input ||
@@ -1473,25 +1498,25 @@ static void v4l_event_handler (v4l_input_plugin_t *this) {
this->input = v4l2_data->input;
this->channel = v4l2_data->channel;
this->frequency = v4l2_data->frequency;
-
+
lprintf("Switching to input:%d chan:%d freq:%.2f\n",
v4l2_data->input,
v4l2_data->channel,
(float)v4l2_data->frequency);
set_frequency(this, this->frequency);
- _x_demux_flush_engine(this->stream);
+ _x_demux_flush_engine(this->stream);
}
break;
/* default:
-
+
lprintf("Got an event, type 0x%08x\n", event->type);
*/
}
-
+
xine_event_free (event);
}
-}
+}
/**
* Dispose plugin.
@@ -1501,123 +1526,90 @@ static void v4l_event_handler (v4l_input_plugin_t *this) {
*/
static void v4l_plugin_dispose (input_plugin_t *this_gen) {
v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
-
+
if(this->mrl)
free(this->mrl);
-
+
if (this->scr) {
this->stream->xine->clock->unregister_scr(this->stream->xine->clock, &this->scr->scr);
this->scr->scr.exit(&this->scr->scr);
}
-
+
/* Close and free video device */
if (this->tuner_name)
free(this->tuner_name);
-
+
/* Close video device only if device was openend */
if (this->video_fd > 0) {
-
+
/* Restore v4l audio volume */
- lprintf("Restoring v4l audio volume %d\n",
+ lprintf("Restoring v4l audio volume %d\n",
ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio_saved));
ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio_saved);
-
+
/* Unmap memory */
- if (this->video_buf != NULL &&
+ if (this->video_buf != NULL &&
munmap(this->video_buf, this->gb_buffers.size) != 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Could not unmap video memory: %s\n", strerror(errno));
} else
lprintf("Succesfully unmapped video memory (size %d)\n", this->gb_buffers.size);
-
+
lprintf("Closing video filehandler %d\n", this->video_fd);
-
+
/* Now close the video device */
if (close(this->video_fd) != 0)
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: Error while closing video file handler: %s\n", strerror(errno));
else
lprintf("Video device succesfully closed\n");
-
- /* Restore zoom setting */
+
+ /* Restore zoom setting */
xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, this->old_zoomx);
xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, this->old_zoomy);
}
-
+
if (this->radio_fd > 0) {
close(this->radio_fd);
}
-
+
#ifdef HAVE_ALSA
/* Close audio device */
if (this->pcm_handle) {
snd_pcm_drop(this->pcm_handle);
snd_pcm_close(this->pcm_handle);
}
-
+
if (this->pcm_data) {
free(this->pcm_data);
}
-
+
if (this->pcm_name) {
free(this->pcm_name);
}
#endif
-
+
if (this->event_queue)
xine_event_dispose_queue (this->event_queue);
-
- lprintf("Freeing allocated audio frames");
- if (this->aud_frames) {
- buf_element_t *cur_frame = this->aud_frames;
-
- while (cur_frame != NULL) {
- buf_element_t *next_frame = cur_frame->next;
-#ifdef LOG
- printf(".");
-#endif
- if (cur_frame->content)
- free(cur_frame->content);
-
- if (cur_frame->extra_info)
- free(cur_frame->extra_info);
-
- free(cur_frame);
- cur_frame = next_frame;
- }
- }
-#ifdef LOG
- printf("\n");
-#endif
+ /* All the frames, both video and audio, are allocated in a single
+ memory area pointed by the frames_base pointer. The content of
+ the frames is divided in two areas, one pointed by
+ audio_content_base and the other by video_content_base. The
+ extra_info structures are all allocated in the first frame
+ data. */
+ free(this->audio_content_base);
+ free(this->video_content_base);
+ if (this->frames_base)
+ free(this->frames_base->extra_info);
+ free(this->frames_base);
-
- lprintf("Freeing allocated video frames");
- if (this->vid_frames) {
- buf_element_t *cur_frame = this->vid_frames;
-
- while (cur_frame != NULL) {
- buf_element_t *next_frame = cur_frame->next;
-#ifdef LOG
- printf(".");
-#endif
-
- if (cur_frame->content)
- free(cur_frame->content);
-
- if (cur_frame->extra_info)
- free(cur_frame->extra_info);
-
- free(cur_frame);
- cur_frame = next_frame;
- }
- }
#ifdef LOG
printf("\n");
#endif
-
+
free (this);
-
+
lprintf("plugin Bye bye! \n");
}
@@ -1628,11 +1620,11 @@ static void v4l_plugin_dispose (input_plugin_t *this_gen) {
*/
static const char* v4l_plugin_get_mrl (input_plugin_t *this_gen) {
v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
-
+
return this->mrl;
}
-static int v4l_plugin_get_optional_data (input_plugin_t *this_gen,
+static int v4l_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
/* v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; */
@@ -1642,19 +1634,19 @@ static int v4l_plugin_get_optional_data (input_plugin_t *this_gen,
static int v4l_plugin_radio_open (input_plugin_t *this_gen)
{
v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
-
+
if(open_radio_capture_device(this) != 1)
return 0;
-
+
open_audio_capture_device(this);
-
+
#ifdef HAVE_ALSA
this->start_time = 0;
this->pts_aud_start = 0;
this->curpos = 0;
this->event_queue = xine_event_new_queue (this->stream);
-#endif
-
+#endif
+
return 1;
}
@@ -1663,30 +1655,30 @@ static int v4l_plugin_video_open (input_plugin_t *this_gen)
{
v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen;
int64_t time;
-
+
if(!open_video_capture_device(this))
return 0;
-
+
open_audio_capture_device(this);
-
+
#ifdef HAVE_ALSA
this->pts_aud_start = 0;
#endif
this->start_time = 0;
this->curpos = 0;
-
+
/* Register our own scr provider */
time = this->stream->xine->clock->get_current_time(this->stream->xine->clock);
this->scr = pvrscr_init();
this->scr->scr.start(&this->scr->scr, time);
this->stream->xine->clock->register_scr(this->stream->xine->clock, &this->scr->scr);
this->scr_tuning = 0;
-
+
/* enable resample method */
this->stream->xine->config->update_num(this->stream->xine->config, "audio.synchronization.av_sync_method", 1);
-
+
this->event_queue = xine_event_new_queue (this->stream);
-
+
return 1;
}
@@ -1701,46 +1693,50 @@ static input_plugin_t *v4l_class_get_instance (input_class_t *cls_gen,
{
/* v4l_input_class_t *cls = (v4l_input_class_t *) cls_gen; */
v4l_input_plugin_t *this;
+#ifdef HAVE_ALSA
+ cfg_entry_t *entry;
+#endif
char *mrl = strdup(data);
-
+
/* Example mrl: v4l:/Television/62500 */
if(!mrl || strncasecmp(mrl, "v4l:/", 5)) {
free(mrl);
return NULL;
}
-
- this = (v4l_input_plugin_t *) xine_xmalloc (sizeof (v4l_input_plugin_t));
-
+
+ this = calloc(1, sizeof (v4l_input_plugin_t));
+
extract_mrl(this, mrl);
-
- this->stream = stream;
- this->mrl = mrl;
+
+ this->stream = stream;
+ this->mrl = mrl;
this->video_buf = NULL;
this->video_fd = -1;
this->radio_fd = -1;
this->event_queue = NULL;
this->scr = NULL;
#ifdef HAVE_ALSA
- this->pcm_name = NULL;
this->pcm_data = NULL;
this->pcm_hwparams = NULL;
-
+
/* Audio */
this->pcm_stream = SND_PCM_STREAM_CAPTURE;
- this->pcm_name = strdup("plughw:0,0");
+ entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
+ "media.video4linux.audio_device");
+ this->pcm_name = strdup (entry->str_value);
this->audio_capture = 1;
#endif
this->rate = 44100;
this->periods = 2;
this->periodsize = 2 * 8192;
this->bits = 16;
-
+
pthread_mutex_init (&this->aud_frames_lock, NULL);
pthread_cond_init (&this->aud_frame_freed, NULL);
-
+
pthread_mutex_init (&this->vid_frames_lock, NULL);
pthread_cond_init (&this->vid_frame_freed, NULL);
-
+
this->input_plugin.get_capabilities = v4l_plugin_get_capabilities;
this->input_plugin.read = v4l_plugin_read;
this->input_plugin.read_block = v4l_plugin_read_block;
@@ -1752,7 +1748,7 @@ static input_plugin_t *v4l_class_get_instance (input_class_t *cls_gen,
this->input_plugin.dispose = v4l_plugin_dispose;
this->input_plugin.get_optional_data = v4l_plugin_get_optional_data;
this->input_plugin.input_class = cls_gen;
-
+
return &this->input_plugin;
}
@@ -1762,57 +1758,57 @@ static input_plugin_t *v4l_class_get_video_instance (input_class_t *cls_gen,
v4l_input_plugin_t *this = NULL;
int is_ok = 1;
cfg_entry_t *entry;
-
+
this = (v4l_input_plugin_t *) v4l_class_get_instance (cls_gen, stream, data);
-
+
if (this)
this->input_plugin.open = v4l_plugin_video_open;
else
return NULL;
-
- entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
+
+ entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
"media.video4linux.video_device");
-
+
/* Try to open the video device */
if((this->video_fd = open(entry->str_value, O_RDWR)) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "input_v4l: error opening v4l device (%s): %s\n",
+ "input_v4l: error opening v4l device (%s): %s\n",
entry->str_value, strerror(errno));
is_ok = 0;
} else
lprintf("Device opened, tv %d\n", this->video_fd);
-
+
/* Get capabilities */
if (is_ok && ioctl(this->video_fd, VIDIOCGCAP, &this->video_cap) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: v4l card doesn't support some features needed by xine\n");
is_ok = 0;;
}
-
+
if (is_ok && !(this->video_cap.type & VID_TYPE_CAPTURE)) {
/* Capture is not supported by the device. This is a must though! */
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: v4l card doesn't support frame grabbing\n");
is_ok = 0;
}
-
+
if (is_ok && set_input_source(this, this->tuner_name) <= 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: unable to locate the tuner name (%s) on your v4l card\n",
this->tuner_name);
is_ok = 0;
}
-
+
if (this->video_fd > 0) {
close(this->video_fd);
this->video_fd = -1;
}
-
+
if (!is_ok) {
v4l_plugin_dispose((input_plugin_t *) this);
return NULL;
}
-
+
return &this->input_plugin;
}
@@ -1823,45 +1819,45 @@ static input_plugin_t *v4l_class_get_radio_instance (input_class_t *cls_gen,
v4l_input_plugin_t *this = NULL;
int is_ok = 1;
cfg_entry_t *entry;
-
+
if (strstr(data, "Radio") == NULL)
return NULL;
-
+
this = (v4l_input_plugin_t *) v4l_class_get_instance (cls_gen, stream, data);
-
+
if (this)
this->input_plugin.open = v4l_plugin_radio_open;
else
return NULL;
-
- entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
+
+ entry = this->stream->xine->config->lookup_entry(this->stream->xine->config,
"media.video4linux.radio_device");
-
+
if((this->radio_fd = open(entry->str_value, O_RDWR)) < 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- "input_v4l: error opening v4l device (%s): %s\n",
+ "input_v4l: error opening v4l device (%s): %s\n",
entry->str_value, strerror(errno));
is_ok = 0;
} else
lprintf("Device opened, radio %d\n", this->radio_fd);
-
+
if (is_ok && set_input_source(this, this->tuner_name) <= 0) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"input_v4l: unable to locate the tuner name (%s) on your v4l card\n",
this->tuner_name);
is_ok = 0;
}
-
+
if (this->radio_fd > 0) {
close(this->radio_fd);
this->radio_fd = -1;
}
-
+
if (!is_ok) {
v4l_plugin_dispose((input_plugin_t *) this);
return NULL;
}
-
+
return &this->input_plugin;
}
@@ -1870,11 +1866,11 @@ static input_plugin_t *v4l_class_get_radio_instance (input_class_t *cls_gen,
* v4l input plugin class stuff
*/
-static char *v4l_class_get_video_description (input_class_t *this_gen) {
+static const char *v4l_class_get_video_description (input_class_t *this_gen) {
return _("v4l tv input plugin");
}
-static char *v4l_class_get_radio_description (input_class_t *this_gen) {
+static const char *v4l_class_get_radio_description (input_class_t *this_gen) {
return _("v4l radio input plugin");
}
@@ -1884,7 +1880,7 @@ static const char *v4l_class_get_identifier (input_class_t *this_gen) {
static void v4l_class_dispose (input_class_t *this_gen) {
v4l_input_class_t *this = (v4l_input_class_t *) this_gen;
-
+
free (this);
}
@@ -1892,11 +1888,11 @@ static void *init_video_class (xine_t *xine, void *data)
{
v4l_input_class_t *this;
config_values_t *config = xine->config;
-
- this = (v4l_input_class_t *) xine_xmalloc (sizeof (v4l_input_class_t));
-
+
+ this = calloc(1, sizeof (v4l_input_class_t));
+
this->xine = xine;
-
+
this->input_class.get_instance = v4l_class_get_video_instance;
this->input_class.get_identifier = v4l_class_get_identifier;
this->input_class.get_description = v4l_class_get_video_description;
@@ -1904,13 +1900,25 @@ static void *init_video_class (xine_t *xine, void *data)
this->input_class.get_autoplay_list = NULL;
this->input_class.dispose = v4l_class_dispose;
this->input_class.eject_media = NULL;
-
+
config->register_filename (config, "media.video4linux.video_device",
VIDEO_DEV, XINE_CONFIG_STRING_IS_DEVICE_NAME,
_("v4l video device"),
_("The path to your Video4Linux video device."),
10, NULL, NULL);
-
+#ifdef HAVE_ALSA
+ config->register_filename (config, "media.video4linux.audio_device",
+ AUDIO_DEV, 0,
+ _("v4l ALSA audio input device"),
+ _("The name of the audio device which corresponds "
+ "to your Video4Linux video device."),
+ 10, NULL, NULL);
+#endif
+ config->register_enum (config, "media.video4linux.tv_standard", 4 /* old */,
+ tv_standard_names, _("v4l TV standard"),
+ _("Selects the TV standard of the input signals. "
+ "Either: AUTO, PAL, NTSC or SECAM. "), 20, NULL, NULL);
+
return this;
}
@@ -1918,11 +1926,11 @@ static void *init_radio_class (xine_t *xine, void *data)
{
v4l_input_class_t *this;
config_values_t *config = xine->config;
-
- this = (v4l_input_class_t *) xine_xmalloc (sizeof (v4l_input_class_t));
-
+
+ this = calloc(1, sizeof (v4l_input_class_t));
+
this->xine = xine;
-
+
this->input_class.get_instance = v4l_class_get_radio_instance;
this->input_class.get_identifier = v4l_class_get_identifier;
this->input_class.get_description = v4l_class_get_radio_description;
@@ -1930,13 +1938,13 @@ static void *init_radio_class (xine_t *xine, void *data)
this->input_class.get_autoplay_list = NULL;
this->input_class.dispose = v4l_class_dispose;
this->input_class.eject_media = NULL;
-
+
config->register_filename (config, "media.video4linux.radio_device",
RADIO_DEV, XINE_CONFIG_STRING_IS_DEVICE_NAME,
_("v4l radio device"),
_("The path to your Video4Linux radio device."),
10, NULL, NULL);
-
+
return this;
}
@@ -1945,12 +1953,12 @@ static void *init_radio_class (xine_t *xine, void *data)
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "v4l_radio", XINE_VERSION_CODE, NULL, init_radio_class },
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "v4l_tv", XINE_VERSION_CODE, NULL, init_video_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
/*
- * vim:sw=3:sts=3:
+ * vim:sw=3:sts=3:
*/
diff --git a/src/input/input_vcd.c b/src/input/input_vcd.c
index 007fa5946..43980bd52 100644
--- a/src/input/input_vcd.c
+++ b/src/input/input_vcd.c
@@ -1,18 +1,18 @@
-/*
- * Copyright (C) 2000-2006 the xine project
- *
+/*
+ * Copyright (C) 2000-2008 the xine project
+ *
* 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
@@ -84,7 +84,7 @@ typedef struct {
const char *device;
- char *filelist[100];
+ char **filelist;
int mrls_allocated_entries;
xine_mrl_t **mrls;
@@ -92,7 +92,7 @@ typedef struct {
#if defined (__linux__) || defined(__sun)
struct cdrom_tochdr tochdr;
struct cdrom_tocentry tocent[100];
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
struct ioc_toc_header tochdr;
struct cd_toc_entry *tocent;
off_t cur_sec;
@@ -105,11 +105,11 @@ typedef struct {
typedef struct {
input_plugin_t input_plugin;
-
+
vcd_input_class_t *cls;
-
+
xine_stream_t *stream;
-
+
char *mrl;
config_values_t *config;
@@ -117,7 +117,7 @@ typedef struct {
int cur_track;
-#if defined (__linux__) || defined(__sun) || defined (__FreeBSD_kernel__)
+#if defined (__linux__) || defined(__sun) || defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
uint8_t cur_min, cur_sec, cur_frame;
#endif
@@ -136,7 +136,7 @@ typedef struct {
*/
static void device_change_cb (void *data, xine_cfg_entry_t *cfg) {
vcd_input_class_t *this = (vcd_input_class_t *) data;
-
+
this->device = cfg->str_value;
}
@@ -146,7 +146,7 @@ static int input_vcd_read_toc (vcd_input_class_t *this, int fd) {
/* read TOC header */
if ( ioctl(fd, CDROMREADTOCHDR, &this->tochdr) == -1 ) {
- xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_vcd : error in ioctl CDROMREADTOCHDR\n");
return -1;
}
@@ -156,7 +156,7 @@ static int input_vcd_read_toc (vcd_input_class_t *this, int fd) {
this->tocent[i-1].cdte_track = i;
this->tocent[i-1].cdte_format = CDROM_MSF;
if ( ioctl(fd, CDROMREADTOCENTRY, &this->tocent[i-1]) == -1 ) {
- xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_vcd: error in ioctl CDROMREADTOCENTRY for track %d\n", i);
return -1;
}
@@ -166,9 +166,9 @@ static int input_vcd_read_toc (vcd_input_class_t *this, int fd) {
this->tocent[this->tochdr.cdth_trk1].cdte_track = CDROM_LEADOUT;
this->tocent[this->tochdr.cdth_trk1].cdte_format = CDROM_MSF;
- if (ioctl(fd, CDROMREADTOCENTRY,
+ if (ioctl(fd, CDROMREADTOCENTRY,
&this->tocent[this->tochdr.cdth_trk1]) == -1 ) {
- xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_vcd: error in ioctl CDROMREADTOCENTRY for lead-out\n");
return -1;
}
@@ -177,7 +177,7 @@ static int input_vcd_read_toc (vcd_input_class_t *this, int fd) {
return 0;
}
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
static int input_vcd_read_toc (vcd_input_class_t *this, int fd) {
struct ioc_read_toc_entry te;
@@ -185,23 +185,23 @@ static int input_vcd_read_toc (vcd_input_class_t *this, int fd) {
/* read TOC header */
if ( ioctl(fd, CDIOREADTOCHEADER, &this->tochdr) == -1 ) {
- xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_vcd : error in ioctl CDROMREADTOCHDR\n");
return -1;
}
- ntracks = this->tochdr.ending_track
+ ntracks = this->tochdr.ending_track
- this->tochdr.starting_track + 2;
this->tocent = (struct cd_toc_entry *)
xine_xmalloc(sizeof(*this->tocent) * ntracks);
-
+
te.address_format = CD_LBA_FORMAT;
te.starting_track = 0;
te.data_len = ntracks * sizeof(struct cd_toc_entry);
te.data = this->tocent;
-
+
if ( ioctl(fd, CDIOREADTOCENTRYS, &te) == -1 ){
- xprintf (this->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->xine, XINE_VERBOSITY_DEBUG,
"input_vcd: error in ioctl CDROMREADTOCENTRY\n");
return -1;
}
@@ -232,11 +232,11 @@ static int sun_vcd_read(vcd_input_plugin_t *this, long lba, cdsector_t *data)
*/
if (this->controller_type == 0) {
if ( ioctl(this->fd, DKIOCINFO, &cinfo) == 0
- && ((strcmp(cinfo.dki_cname, "ide") == 0)
+ && ((strcmp(cinfo.dki_cname, "ide") == 0)
|| (strncmp(cinfo.dki_cname, "pci", 3) == 0)) )
this->controller_type = SUN_CTRL_ATAPI;
else
- this->controller_type = SUN_CTRL_SCSI;
+ this->controller_type = SUN_CTRL_SCSI;
}
switch (this->controller_type) {
case SUN_CTRL_SCSI:
@@ -247,7 +247,7 @@ static int sun_vcd_read(vcd_input_plugin_t *this, long lba, cdsector_t *data)
cdxa.cdxa_length = 1;
cdxa.cdxa_data = data->subheader;
cdxa.cdxa_format = CDROM_XA_SECTOR_DATA;
-
+
if(ioctl(this->fd,CDROMCDXA,&cdxa)==-1) {
xprintf(this->cls->xine, XINE_VERBOSITY_DEBUG, "CDROMCDXA: %s\n", strerror(errno));
return -1;
@@ -304,12 +304,12 @@ static int sun_vcd_read(vcd_input_plugin_t *this, long lba, cdsector_t *data)
cdb.cdb_opaque[7] = (blocks >> 8) & 0xff;
cdb.cdb_opaque[8] = blocks & 0xff;
cdb.cdb_opaque[9] = (sync << 7) |
- (header_code << 5) |
- (user_data << 4) |
- (edc_ecc << 3) |
- (error_field << 1);
+ (header_code << 5) |
+ (user_data << 4) |
+ (edc_ecc << 3) |
+ (error_field << 1);
cdb.cdb_opaque[10] = sub_channel;
-
+
sc.uscsi_cdb = (caddr_t)&cdb;
sc.uscsi_cdblen = 12;
sc.uscsi_bufaddr = (caddr_t)data->subheader;
@@ -321,7 +321,7 @@ static int sun_vcd_read(vcd_input_plugin_t *this, long lba, cdsector_t *data)
return -1;
}
if (sc.uscsi_status) {
- xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
"scsi command failed with status %d\n", sc.uscsi_status);
return -1;
}
@@ -336,9 +336,9 @@ static int sun_vcd_read(vcd_input_plugin_t *this, long lba, cdsector_t *data)
/* ***************************************************************** */
#if defined (__linux__)
-static off_t vcd_plugin_read (input_plugin_t *this_gen,
+static off_t vcd_plugin_read (input_plugin_t *this_gen,
char *buf, off_t nlen) {
-
+
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
static struct cdrom_msf msf ;
static cdsector_t data;
@@ -348,14 +348,14 @@ static off_t vcd_plugin_read (input_plugin_t *this_gen,
return 0;
do
- {
+ {
end_msf = (struct cdrom_msf0 *)
&this->cls->tocent[this->cur_track+1].cdte_addr.msf;
/*
printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n",
- this->cur_min, this->cur_sec, this->cur_frame,
- end_msf->minute, end_msf->second, end_msf->frame);
+ this->cur_min, this->cur_sec, this->cur_frame,
+ end_msf->minute, end_msf->second, end_msf->frame);
*/
if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second)
@@ -369,7 +369,7 @@ static off_t vcd_plugin_read (input_plugin_t *this_gen,
memcpy (&data, &msf, sizeof (msf));
if (ioctl (this->fd, CDROMREADRAW, &data) == -1) {
- xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
"input_vcd: error in CDROMREADRAW\n");
return 0;
}
@@ -384,17 +384,17 @@ static off_t vcd_plugin_read (input_plugin_t *this_gen,
this->cur_min++;
}
}
-
+
/* Header ID check for padding sector. VCD uses this to keep constant
bitrate so the CD doesn't stop/start */
}
while((data.subheader[2]&~0x01)==0x60);
-
+
memcpy (buf, data.data, VCDSECTORSIZE); /* FIXME */
return VCDSECTORSIZE;
}
-#elif defined (__FreeBSD_kernel__)
-static off_t vcd_plugin_read (input_plugin_t *this_gen,
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
+static off_t vcd_plugin_read (input_plugin_t *this_gen,
char *buf, off_t nlen) {
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
static cdsector_t data;
@@ -418,9 +418,9 @@ static off_t vcd_plugin_read (input_plugin_t *this_gen,
return VCDSECTORSIZE;
}
#elif defined (__sun)
-static off_t vcd_plugin_read (input_plugin_t *this_gen,
+static off_t vcd_plugin_read (input_plugin_t *this_gen,
char *buf, off_t nlen) {
-
+
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
static cdsector_t data;
struct cdrom_msf0 *end_msf;
@@ -430,14 +430,14 @@ static off_t vcd_plugin_read (input_plugin_t *this_gen,
return 0;
do
- {
- end_msf = (struct cdrom_msf0 *)
+ {
+ end_msf = (struct cdrom_msf0 *)
&this->cls->tocent[this->cur_track+1].cdte_addr.msf;
/*
printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n",
- this->cur_min, this->cur_sec, this->cur_frame,
- end_msf->minute, end_msf->second, end_msf->frame);
+ this->cur_min, this->cur_sec, this->cur_frame,
+ end_msf->minute, end_msf->second, end_msf->frame);
*/
if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second)
@@ -460,21 +460,21 @@ static off_t vcd_plugin_read (input_plugin_t *this_gen,
this->cur_min++;
}
}
-
+
/* Header ID check for padding sector. VCD uses this to keep constant
bitrate so the CD doesn't stop/start */
}
while((data.subheader[2]&~0x01)==0x60);
-
+
memcpy (buf, data.data, VCDSECTORSIZE); /* FIXME */
return VCDSECTORSIZE;
}
#endif
#if defined (__linux__)
-static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
+static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t nlen) {
-
+
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
buf_element_t *buf;
static struct cdrom_msf msf ;
@@ -485,13 +485,13 @@ static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
return NULL;
do
- {
+ {
end_msf = &this->cls->tocent[this->cur_track+1].cdte_addr.msf;
/*
printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n",
- this->cur_min, this->cur_sec, this->cur_frame,
- end_msf->minute, end_msf->second, end_msf->frame);
+ this->cur_min, this->cur_sec, this->cur_frame,
+ end_msf->minute, end_msf->second, end_msf->frame);
*/
if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second)
@@ -519,22 +519,22 @@ static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
this->cur_min++;
}
}
-
+
/* Header ID check for padding sector. VCD uses this to keep constant
bitrate so the CD doesn't stop/start */
}
while((data.subheader[2]&~0x01)==0x60);
-
+
buf = fifo->buffer_pool_alloc (fifo);
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
memcpy (buf->mem, data.data, VCDSECTORSIZE); /* FIXME */
return buf;
}
-#elif defined (__FreeBSD_kernel__)
-static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
+static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t nlen) {
-
+
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
buf_element_t *buf;
static cdsector_t data;
@@ -562,9 +562,9 @@ static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
return buf;
}
#elif defined(__sun)
-static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
+static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
fifo_buffer_t *fifo, off_t nlen) {
-
+
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
buf_element_t *buf;
static cdsector_t data;
@@ -575,14 +575,14 @@ static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
return NULL;
do
- {
- end_msf = (struct cdrom_msf0 *)
+ {
+ end_msf = (struct cdrom_msf0 *)
&this->cls->tocent[this->cur_track+1].cdte_addr.msf;
/*
printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n",
- this->cur_min, this->cur_sec, this->cur_frame,
- end_msf->minute, end_msf->second, end_msf->frame);
+ this->cur_min, this->cur_sec, this->cur_frame,
+ end_msf->minute, end_msf->second, end_msf->frame);
*/
if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second)
@@ -606,12 +606,12 @@ static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen,
this->cur_min++;
}
}
-
+
/* Header ID check for padding sector. VCD uses this to keep constant
bitrate so the CD doesn't stop/start */
}
while((data.subheader[2]&~0x01)==0x60);
-
+
buf = fifo->buffer_pool_alloc (fifo);
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
@@ -625,17 +625,17 @@ static off_t vcd_time_to_offset (int min, int sec, int frame) {
return min * 60 * 75 + sec * 75 + frame;
}
-static void vcd_offset_to_time (off_t offset, uint8_t *min, uint8_t *sec,
+static void vcd_offset_to_time (off_t offset, uint8_t *min, uint8_t *sec,
uint8_t *frame) {
*min = offset / (60*75);
offset %= (60*75);
- *sec = offset / 75;
- *frame = offset % 75;
+ *sec = offset / 75;
+ *frame = offset % 75;
}
-static off_t vcd_plugin_seek (input_plugin_t *this_gen,
+static off_t vcd_plugin_seek (input_plugin_t *this_gen,
off_t offset, int origin) {
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
@@ -647,11 +647,11 @@ static off_t vcd_plugin_seek (input_plugin_t *this_gen,
switch (origin) {
case SEEK_SET:
- sector_pos = (offset / VCDSECTORSIZE)
+ sector_pos = (offset / VCDSECTORSIZE)
+ vcd_time_to_offset (start_msf->minute,
start_msf->second,
start_msf->frame);
-
+
vcd_offset_to_time (sector_pos, &this->cur_min,
&this->cur_sec, &this->cur_frame);
@@ -663,8 +663,8 @@ static off_t vcd_plugin_seek (input_plugin_t *this_gen,
break;
case SEEK_CUR:
- if (offset)
- xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
+ if (offset)
+ xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
"input_vcd: SEEK_CUR not implemented for offset != 0\n");
/*
@@ -683,15 +683,15 @@ static off_t vcd_plugin_seek (input_plugin_t *this_gen,
break;
default:
- xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
"input_vcd: error seek to origin %d not implemented!\n", origin);
return 0;
}
return offset ; /* FIXME */
}
-#elif defined (__FreeBSD_kernel__)
-static off_t vcd_plugin_seek (input_plugin_t *this_gen,
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
+static off_t vcd_plugin_seek (input_plugin_t *this_gen,
off_t offset, int origin) {
@@ -700,11 +700,11 @@ static off_t vcd_plugin_seek (input_plugin_t *this_gen,
uint32_t dist ;
off_t sector_pos;
- start =
+ start =
ntohl(this->cls->tocent
[this->cur_track+1 - this->cls->tochdr.starting_track].addr.lba);
- /* printf("seek: start sector:%lu, origin: %d, offset:%qu\n",
+ /* printf("seek: start sector:%lu, origin: %d, offset:%qu\n",
start, origin, offset);
*/
@@ -715,7 +715,7 @@ static off_t vcd_plugin_seek (input_plugin_t *this_gen,
break;
case SEEK_CUR:
- if (offset)
+ if (offset)
xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: SEEK_CUR not implemented for offset != 0\n");
sector_pos = this->cur_sec;
@@ -724,7 +724,7 @@ static off_t vcd_plugin_seek (input_plugin_t *this_gen,
break;
default:
- xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
+ xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG,
"input_vcd: error seek to origin %d not implemented!\n", origin);
return 0;
}
@@ -738,46 +738,46 @@ static off_t vcd_plugin_get_length (input_plugin_t *this_gen) {
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
struct cdrom_msf0 *end_msf, *start_msf;
off_t len ;
-
+
if(this->cls->total_tracks) {
-
+
start_msf = (struct cdrom_msf0 *)
&this->cls->tocent[this->cur_track].cdte_addr.msf;
end_msf = (struct cdrom_msf0 *)
&this->cls->tocent[this->cur_track+1].cdte_addr.msf;
-
+
len = 75 - start_msf->frame;
-
+
if (start_msf->second<60)
len += (59 - start_msf->second) * 75;
-
+
if (end_msf->minute > start_msf->minute) {
len += (end_msf->minute - start_msf->minute-1) * 60 * 75;
-
+
len += end_msf->second * 60;
-
+
len += end_msf->frame ;
}
-
+
return len * VCDSECTORSIZE;
}
return (off_t) 0;
}
-#elif defined (__FreeBSD_kernel__)
+#elif defined (__FreeBSD_kernel__) || defined (__OpenBSD__)
static off_t vcd_plugin_get_length (input_plugin_t *this_gen) {
vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen;
off_t len ;
- len =
+ len =
ntohl(this->cls->tocent
- [this->cur_track+2
+ [this->cur_track+2
- this->cls->tochdr.starting_track].addr.lba)
- ntohl(this->cls->tocent
- [this->cur_track+1
+ [this->cur_track+1
- this->cls->tochdr.starting_track].addr.lba);
-
+
return len * 2352; /*VCDSECTORSIZE;*/
}
@@ -790,7 +790,7 @@ static off_t vcd_plugin_get_current_pos (input_plugin_t *this_gen){
}
static uint32_t vcd_plugin_get_capabilities (input_plugin_t *this_gen) {
-
+
return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK ;
}
@@ -816,7 +816,7 @@ static const char* vcd_plugin_get_mrl (input_plugin_t *this_gen) {
return this->mrl;
}
-static int vcd_plugin_get_optional_data (input_plugin_t *this_gen,
+static int vcd_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
return INPUT_OPTIONAL_UNSUPPORTED;
@@ -843,13 +843,13 @@ static int vcd_plugin_open (input_plugin_t *this_gen) {
while (*filename == '/') filename++;
if (sscanf (filename, "%d", &this->cur_track) != 1) {
- xprintf (cls->xine, XINE_VERBOSITY_LOG,
+ xprintf (cls->xine, XINE_VERBOSITY_LOG,
_("input_vcd: malformed MRL. Use vcdo:/<track #>\n"));
return 0;
}
if (this->cur_track>=this->cls->total_tracks) {
- xprintf (cls->xine, XINE_VERBOSITY_LOG,
+ xprintf (cls->xine, XINE_VERBOSITY_LOG,
_("input_vcd: invalid track %d (valid range: 0 .. %d)\n"),
this->cur_track, this->cls->total_tracks-1);
return 0;
@@ -859,6 +859,10 @@ static int vcd_plugin_open (input_plugin_t *this_gen) {
this->cur_min = this->cls->tocent[this->cur_track].cdte_addr.msf.minute;
this->cur_sec = this->cls->tocent[this->cur_track].cdte_addr.msf.second;
this->cur_frame = this->cls->tocent[this->cur_track].cdte_addr.msf.frame;
+#elif defined (__OpenBSD__)
+ this->cur_min = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.minute;
+ this->cur_sec = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.second;
+ this->cur_frame = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.frame;
#elif defined (__FreeBSD_kernel__)
{
int bsize = 2352;
@@ -866,21 +870,21 @@ static int vcd_plugin_open (input_plugin_t *this_gen) {
xprintf (cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error in CDRIOCSETBLOCKSIZE %d\n", errno);
return 0;
}
-
- this->cur_sec =
+
+ this->cur_sec =
ntohl(this->cls->tocent
[this->cur_track+1 - this->cls->tochdr.starting_track].addr.lba);
-
+
}
#endif
-
+
return 1;
}
-static input_plugin_t *vcd_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
+static input_plugin_t *vcd_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
const char *data) {
- vcd_input_class_t *cls = (vcd_input_class_t *) cls_gen;
+ vcd_input_class_t *cls = (vcd_input_class_t *) cls_gen;
vcd_input_plugin_t *this;
char *mrl = strdup(data);
@@ -888,8 +892,8 @@ static input_plugin_t *vcd_class_get_instance (input_class_t *cls_gen, xine_stre
free (mrl);
return 0;
}
-
- this = (vcd_input_plugin_t *) xine_xmalloc(sizeof(vcd_input_plugin_t));
+
+ this = calloc(1, sizeof(vcd_input_plugin_t));
this->stream = stream;
this->mrl = mrl;
@@ -924,17 +928,26 @@ static const char *vcd_class_get_identifier (input_class_t *this_gen) {
return "vcdo";
}
+static void vcd_filelist_dispose(vcd_input_class_t *this) {
+ if ( this->filelist == NULL ) return;
+
+ char **entry = this->filelist;
+
+ while(*(entry)) {
+ free(*(entry++));
+ }
+
+ free(this->filelist);
+}
+
static void vcd_class_dispose (input_class_t *this_gen) {
vcd_input_class_t *this = (vcd_input_class_t *) this_gen;
- int i;
config_values_t *config = this->xine->config;
config->unregister_callback(config, "media.vcd.device");
- for (i = 0; i < 100; i++)
- free (this->filelist[i]);
-
+ vcd_filelist_dispose(this);
free (this->mrls);
free (this);
}
@@ -946,7 +959,7 @@ static int vcd_class_eject_media (input_class_t *this_gen) {
return media_eject_media (this->xine, this->device);
}
-static xine_mrl_t **vcd_class_get_dir (input_class_t *this_gen, const char *filename,
+static xine_mrl_t **vcd_class_get_dir (input_class_t *this_gen, const char *filename,
int *num_files) {
vcd_input_class_t *this = (vcd_input_class_t *) this_gen;
@@ -957,7 +970,7 @@ static xine_mrl_t **vcd_class_get_dir (input_class_t *this_gen, const char *file
if (filename)
return NULL;
-
+
fd = open (this->device, O_RDONLY|O_EXCL);
if (fd == -1) {
@@ -982,33 +995,19 @@ static xine_mrl_t **vcd_class_get_dir (input_class_t *this_gen, const char *file
/* printf ("%d tracks\n", this->total_tracks); */
for (i=1; i<this->total_tracks; i++) { /* FIXME: check if track 0 contains valid data */
- char mrl[1024];
-
- memset(&mrl, 0, sizeof (mrl));
- sprintf(mrl, "vcdo:/%d",i);
-
if((i-1) >= this->mrls_allocated_entries) {
++this->mrls_allocated_entries;
/* note: 1 extra pointer for terminating NULL */
this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*));
- this->mrls[(i-1)] = (xine_mrl_t *) xine_xmalloc(sizeof(xine_mrl_t));
+ this->mrls[(i-1)] = calloc(1, sizeof(xine_mrl_t));
}
else {
memset(this->mrls[(i-1)], 0, sizeof(xine_mrl_t));
}
-
- if(this->mrls[(i-1)]->mrl) {
- this->mrls[(i-1)]->mrl = (char *)
- realloc(this->mrls[(i-1)]->mrl, strlen(mrl) + 1);
- }
- else {
- this->mrls[(i-1)]->mrl = (char *) xine_xmalloc(strlen(mrl) + 1);
- }
-
- this->mrls[i-1]->origin = NULL;
- sprintf(this->mrls[i-1]->mrl, "%s", mrl);
- this->mrls[i-1]->link = NULL;
- this->mrls[i-1]->type = (0 | mrl_vcd);
+
+ asprintf(&(this->mrls[i-1]->mrl), "vcdo:/%d", i);
+
+ this->mrls[i-1]->type = mrl_vcd;
/* hack */
this->mrls[i-1]->size = vcd_plugin_get_length ((input_plugin_t *) this);
@@ -1024,13 +1023,13 @@ static xine_mrl_t **vcd_class_get_dir (input_class_t *this_gen, const char *file
}
this->mrls[*num_files] = NULL;
-
+
return this->mrls;
}
static char ** vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files) {
- vcd_input_class_t *this = (vcd_input_class_t *) this_gen;
+ vcd_input_class_t *this = (vcd_input_class_t *) this_gen;
int i, fd;
@@ -1055,20 +1054,15 @@ static char ** vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_fi
fd = -1;
*num_files = this->total_tracks - 1;
-
- /* printf ("%d tracks\n", this->total_tracks); */
- for (i = 1; i < this->total_tracks; i++) { /* FIXME: check if track 0 contains valid data */
+ vcd_filelist_dispose(this);
+ this->filelist = calloc(this->total_tracks+1, sizeof(char*));
- if(this->filelist[i - 1] == NULL)
- this->filelist[i - 1] = (char *) realloc(this->filelist[i - 1], sizeof(char *) * 256);
+ /* FIXME: check if track 0 contains valid data */
+ for (i = 1; i < this->total_tracks; i++)
+ asprintf(&this->filelist[i-1], "vcdo:/%d", i);
- sprintf (this->filelist[i - 1], "vcdo:/%d",i);
- /* printf ("list[%d] : %d %s\n", i, this->filelist[i-1], this->filelist[i-1]); */
- }
-
- this->filelist[i - 1] = (char *) realloc(this->filelist[i-1], sizeof(char *));
- this->filelist[i - 1] = NULL;
+ /* printf ("%d tracks\n", this->total_tracks); */
return this->filelist;
}
@@ -1077,9 +1071,8 @@ static void *init_class (xine_t *xine, void *data) {
vcd_input_class_t *this;
config_values_t *config = xine->config;
- int i;
- this = (vcd_input_class_t *) xine_xmalloc (sizeof (vcd_input_class_t));
+ this = calloc(1, sizeof (vcd_input_class_t));
this->xine = xine;
@@ -1097,13 +1090,9 @@ static void *init_class (xine_t *xine, void *data) {
"you intend to play your VideoCDs with."),
10, device_change_cb, (void *)this);
- this->mrls = (xine_mrl_t **) xine_xmalloc(sizeof(xine_mrl_t*));
+ this->mrls = calloc(1, sizeof(xine_mrl_t*));
this->mrls_allocated_entries = 0;
- for (i = 0; i < 100; i++) {
- this->filelist[i] = (char *) xine_xmalloc(sizeof(char *) * 256);
- }
-
return this;
}
@@ -1112,7 +1101,7 @@ static void *init_class (xine_t *xine, void *data) {
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "VCDO", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};
diff --git a/src/input/libdvdnav/Makefile.am b/src/input/libdvdnav/Makefile.am
index 412828261..1cf60a0e2 100644
--- a/src/input/libdvdnav/Makefile.am
+++ b/src/input/libdvdnav/Makefile.am
@@ -46,4 +46,4 @@ noinst_HEADERS = \
dvd_reader.h \
dvd_input.h \
dvd_udf.h \
- bswap.h
+ bswap.h
diff --git a/src/input/libdvdnav/bswap.h b/src/input/libdvdnav/bswap.h
index 2a2d222fe..23f0251d6 100644
--- a/src/input/libdvdnav/bswap.h
+++ b/src/input/libdvdnav/bswap.h
@@ -20,7 +20,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <config.h>
+#include "config.h"
#if defined(WORDS_BIGENDIAN)
/* All bigendian systems are fine, just ignore the swaps. */
diff --git a/src/input/libdvdnav/diff_against_cvs.patch b/src/input/libdvdnav/diff_against_cvs.patch
index 202474fef..6df704e2a 100644
--- a/src/input/libdvdnav/diff_against_cvs.patch
+++ b/src/input/libdvdnav/diff_against_cvs.patch
@@ -323,7 +323,7 @@ diff -u -p -u -r1.5 dvd_reader.h
-#ifdef _MSC_VER
+#ifdef HAVE_CONFIG_H
- #include <config.h>
+ #include "config.h"
+#endif
+#ifdef _MSC_VER
diff --git a/src/input/libdvdnav/dvd_reader.c b/src/input/libdvdnav/dvd_reader.c
index 200a1dbec..1e0d3016b 100644
--- a/src/input/libdvdnav/dvd_reader.c
+++ b/src/input/libdvdnav/dvd_reader.c
@@ -30,7 +30,9 @@
#include <string.h>
#include <unistd.h>
#include <limits.h>
+#ifdef HAVE_DIRENT_H
#include <dirent.h>
+#endif
#ifndef HAVE_GETTIMEOFDAY
# ifdef WIN32
@@ -1037,6 +1039,28 @@ int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset )
return offset;
}
+int32_t DVDFileSeekForce( dvd_file_t *dvd_file, int offset, int force_size )
+{
+ /* Check arguments. */
+ if( dvd_file == NULL || offset < 0 )
+ return -1;
+
+ if( dvd_file->dvd->isImageFile ) {
+ if( force_size < 0 )
+ force_size = (offset - 1) / DVD_VIDEO_LB_LEN + 1;
+ if( dvd_file->filesize < force_size) {
+ dvd_file->filesize = force_size;
+ fprintf(stderr, "libdvdread: Ignored UDF provided size of file.\n");
+ }
+ }
+
+ if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) {
+ return -1;
+ }
+ dvd_file->seek_pos = (uint32_t) offset;
+ return offset;
+}
+
ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
{
unsigned char *secbuf_base, *secbuf;
@@ -1077,7 +1101,7 @@ ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size )
memcpy( data, &(secbuf[ seek_byte ]), byte_size );
free( secbuf_base );
- dvd_file->seek_pos += byte_size;
+ DVDFileSeekForce(dvd_file, dvd_file->seek_pos + byte_size, -1);
return byte_size;
}
diff --git a/src/input/libdvdnav/dvd_reader.h b/src/input/libdvdnav/dvd_reader.h
index bb3f5053b..c7b3f9df8 100644
--- a/src/input/libdvdnav/dvd_reader.h
+++ b/src/input/libdvdnav/dvd_reader.h
@@ -22,7 +22,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
#endif
#ifdef _MSC_VER
@@ -171,6 +171,8 @@ ssize_t DVDReadBlocks( dvd_file_t *, int, size_t, unsigned char * );
*/
int32_t DVDFileSeek( dvd_file_t *, int32_t );
+int32_t DVDFileSeekForce( dvd_file_t *, int, int );
+
/**
* Reads the given number of bytes from the file. This call can only be used
* on the information files, and may not be used for reading from a VOB. This
diff --git a/src/input/libdvdnav/ifo_read.c b/src/input/libdvdnav/ifo_read.c
index 8f47d2a54..bc1ba580b 100644
--- a/src/input/libdvdnav/ifo_read.c
+++ b/src/input/libdvdnav/ifo_read.c
@@ -93,6 +93,10 @@ static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) {
return (DVDFileSeek(dvd_file, (int)offset) == (int)offset);
}
+static inline int32_t DVDFileSeekForce_( dvd_file_t *dvd_file, uint32_t offset, int force_size ) {
+ return (DVDFileSeekForce(dvd_file, (int)offset, force_size) == (int)offset);
+}
+
ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) {
ifo_handle_t *ifofile;
@@ -1507,7 +1511,7 @@ static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile,
unsigned int i;
int info_length;
- if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN))
+ if(!DVDFileSeekForce_(ifofile->file, sector * DVD_BLOCK_LEN, sector))
return 0;
if(!(DVDReadBytes(ifofile->file, vobu_admap, VOBU_ADMAP_SIZE)))
diff --git a/src/input/libdvdnav/md5.c b/src/input/libdvdnav/md5.c
index 2bfdddee4..16b7b0690 100644
--- a/src/input/libdvdnav/md5.c
+++ b/src/input/libdvdnav/md5.c
@@ -21,7 +21,7 @@
/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
#ifdef HAVE_CONFIG_H
-# include <config.h>
+# include "config.h"
#endif
#include <sys/types.h>
diff --git a/src/input/libdvdnav/remap.c b/src/input/libdvdnav/remap.c
index 43c81c66f..df0be29ce 100644
--- a/src/input/libdvdnav/remap.c
+++ b/src/input/libdvdnav/remap.c
@@ -216,6 +216,7 @@ remap_t* remap_loadmap( char *title) {
remap_add_node( map, tmp);
}
}
+ close (fp); /* ignoring errors... */
if (map->nblocks == 0 && map->debug == 0) return NULL;
return map;
diff --git a/src/input/libreal/asmrp.c b/src/input/libreal/asmrp.c
index f7206b583..2c02c2f13 100644
--- a/src/input/libreal/asmrp.c
+++ b/src/input/libreal/asmrp.c
@@ -2,7 +2,7 @@
* Copyright (C) 2002-2004 the xine project
*
* 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
@@ -32,6 +32,10 @@
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -81,7 +85,7 @@ typedef struct {
int sym;
int num;
-
+
char str[ASMRP_MAX_ID];
/* private part */
@@ -95,7 +99,7 @@ typedef struct {
} asmrp_t;
-static asmrp_t *asmrp_new () {
+static asmrp_t *XINE_MALLOC asmrp_new () {
asmrp_t *p;
@@ -111,7 +115,7 @@ static void asmrp_dispose (asmrp_t *p) {
int i;
- for (i=0; i<p->sym_tab_num; i++)
+ for (i=0; i<p->sym_tab_num; i++)
free (p->sym_tab[i].id);
free (p);
@@ -129,7 +133,7 @@ static void asmrp_init (asmrp_t *p, const char *str) {
p->buf = strdup (str);
p->pos = 0;
-
+
asmrp_getch (p);
}
@@ -163,10 +167,10 @@ static void asmrp_string (asmrp_t *p) {
asmrp_getch (p);
}
p->str[l]=0;
-
+
if (p->ch=='"')
asmrp_getch (p);
-
+
p->sym = ASMRP_SYM_STRING;
}
@@ -185,7 +189,7 @@ static void asmrp_identifier (asmrp_t *p) {
asmrp_getch (p);
}
p->str[l]=0;
-
+
p->sym = ASMRP_SYM_ID;
}
@@ -383,10 +387,10 @@ static int asmrp_set_id (asmrp_t *p, char *s, int v) {
lprintf ("new symbol '%s'\n", s);
- }
+ }
p->sym_tab[i].v = v;
-
+
lprintf ("symbol '%s' assigned %d\n", s, v);
return i;
@@ -397,7 +401,7 @@ static int asmrp_condition (asmrp_t *p) ;
static int asmrp_operand (asmrp_t *p) {
int i, ret;
-
+
lprintf ("operand\n");
ret = 0;
@@ -407,7 +411,7 @@ static int asmrp_operand (asmrp_t *p) {
case ASMRP_SYM_DOLLAR:
asmrp_get_sym (p);
-
+
if (p->sym != ASMRP_SYM_ID) {
printf ("error: identifier expected.\n");
_x_abort();
@@ -449,7 +453,7 @@ static int asmrp_operand (asmrp_t *p) {
}
lprintf ("operand done, =%d\n", ret);
-
+
return ret;
}
@@ -499,7 +503,7 @@ static int asmrp_comp_expression (asmrp_t *p) {
}
static int asmrp_condition (asmrp_t *p) {
-
+
int a;
lprintf ("condition\n");
@@ -538,7 +542,7 @@ static void asmrp_assignment (asmrp_t *p) {
lprintf ("empty assignment\n");
return;
}
-
+
if (p->sym != ASMRP_SYM_ID) {
printf ("error: identifier expected\n");
_x_abort ();
@@ -551,7 +555,7 @@ static void asmrp_assignment (asmrp_t *p) {
}
asmrp_get_sym (p);
- if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING)
+ if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING)
&& (p->sym != ASMRP_SYM_ID)) {
printf ("error: number or string expected\n");
_x_abort ();
@@ -562,22 +566,22 @@ static void asmrp_assignment (asmrp_t *p) {
}
static int asmrp_rule (asmrp_t *p) {
-
+
int ret;
lprintf ("rule\n");
ret = 1;
-
+
if (p->sym == ASMRP_SYM_HASH) {
asmrp_get_sym (p);
ret = asmrp_condition (p);
while (p->sym == ASMRP_SYM_COMMA) {
-
+
asmrp_get_sym (p);
-
+
asmrp_assignment (p);
}
diff --git a/src/input/libreal/real.c b/src/input/libreal/real.c
index df50f0440..9b72c7e57 100644
--- a/src/input/libreal/real.c
+++ b/src/input/libreal/real.c
@@ -21,6 +21,10 @@
* adopted from joschkas real tools.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <string.h>
@@ -48,26 +52,23 @@ static const unsigned char xor_table[] = {
#define _X_BE_32C(x,y) do { *(uint32_t *)(x) = be2me_32((y)); } while(0)
#define _X_LE_32C(x,y) do { *(uint32_t *)(x) = le2me_32((y)); } while(0)
-#define MAX(x,y) ((x>y) ? x : y)
-
-
static void hash(char *field, char *param) {
uint32_t a, b, c, d;
-
+
/* fill variables */
a = _X_LE_32(field);
b = _X_LE_32(field+4);
c = _X_LE_32(field+8);
d = _X_LE_32(field+12);
-
+
lprintf("hash input: %x %x %x %x\n", a, b, c, d);
lprintf("hash parameter:\n");
#ifdef LOG
xine_hexdump(param, 64);
#endif
-
+
a = ((b & c) | (~b & d)) + _X_LE_32((param+0x00)) + a - 0x28955B88;
a = ((a << 0x07) | (a >> 0x19)) + b;
d = ((a & b) | (~a & c)) + _X_LE_32((param+0x04)) + d - 0x173848AA;
@@ -100,7 +101,7 @@ static void hash(char *field, char *param) {
c = ((c << 0x11) | (c >> 0x0f)) + d;
b = ((c & d) | (~c & a)) + _X_LE_32((param+0x3c)) + b + 0x49B40821;
b = ((b << 0x16) | (b >> 0x0a)) + c;
-
+
a = ((b & d) | (~d & c)) + _X_LE_32((param+0x04)) + a - 0x09E1DA9E;
a = ((a << 0x05) | (a >> 0x1b)) + b;
d = ((a & c) | (~c & b)) + _X_LE_32((param+0x18)) + d - 0x3FBF4CC0;
@@ -133,7 +134,7 @@ static void hash(char *field, char *param) {
c = ((c << 0x0e) | (c >> 0x12)) + d;
b = ((c & a) | (~a & d)) + _X_LE_32((param+0x30)) + b - 0x72D5B376;
b = ((b << 0x14) | (b >> 0x0c)) + c;
-
+
a = (b ^ c ^ d) + _X_LE_32((param+0x14)) + a - 0x0005C6BE;
a = ((a << 0x04) | (a >> 0x1c)) + b;
d = (a ^ b ^ c) + _X_LE_32((param+0x20)) + d - 0x788E097F;
@@ -166,42 +167,42 @@ static void hash(char *field, char *param) {
c = ((c << 0x10) | (c >> 0x10)) + d;
b = (c ^ d ^ a) + _X_LE_32((param+0x08)) + b - 0x3B53A99B;
b = ((b << 0x17) | (b >> 0x09)) + c;
-
+
a = ((~d | b) ^ c) + _X_LE_32((param+0x00)) + a - 0x0BD6DDBC;
- a = ((a << 0x06) | (a >> 0x1a)) + b;
+ a = ((a << 0x06) | (a >> 0x1a)) + b;
d = ((~c | a) ^ b) + _X_LE_32((param+0x1c)) + d + 0x432AFF97;
- d = ((d << 0x0a) | (d >> 0x16)) + a;
+ d = ((d << 0x0a) | (d >> 0x16)) + a;
c = ((~b | d) ^ a) + _X_LE_32((param+0x38)) + c - 0x546BDC59;
- c = ((c << 0x0f) | (c >> 0x11)) + d;
+ c = ((c << 0x0f) | (c >> 0x11)) + d;
b = ((~a | c) ^ d) + _X_LE_32((param+0x14)) + b - 0x036C5FC7;
- b = ((b << 0x15) | (b >> 0x0b)) + c;
+ b = ((b << 0x15) | (b >> 0x0b)) + c;
a = ((~d | b) ^ c) + _X_LE_32((param+0x30)) + a + 0x655B59C3;
- a = ((a << 0x06) | (a >> 0x1a)) + b;
+ a = ((a << 0x06) | (a >> 0x1a)) + b;
d = ((~c | a) ^ b) + _X_LE_32((param+0x0C)) + d - 0x70F3336E;
- d = ((d << 0x0a) | (d >> 0x16)) + a;
+ d = ((d << 0x0a) | (d >> 0x16)) + a;
c = ((~b | d) ^ a) + _X_LE_32((param+0x28)) + c - 0x00100B83;
- c = ((c << 0x0f) | (c >> 0x11)) + d;
+ c = ((c << 0x0f) | (c >> 0x11)) + d;
b = ((~a | c) ^ d) + _X_LE_32((param+0x04)) + b - 0x7A7BA22F;
- b = ((b << 0x15) | (b >> 0x0b)) + c;
+ b = ((b << 0x15) | (b >> 0x0b)) + c;
a = ((~d | b) ^ c) + _X_LE_32((param+0x20)) + a + 0x6FA87E4F;
- a = ((a << 0x06) | (a >> 0x1a)) + b;
+ a = ((a << 0x06) | (a >> 0x1a)) + b;
d = ((~c | a) ^ b) + _X_LE_32((param+0x3c)) + d - 0x01D31920;
- d = ((d << 0x0a) | (d >> 0x16)) + a;
+ d = ((d << 0x0a) | (d >> 0x16)) + a;
c = ((~b | d) ^ a) + _X_LE_32((param+0x18)) + c - 0x5CFEBCEC;
- c = ((c << 0x0f) | (c >> 0x11)) + d;
+ c = ((c << 0x0f) | (c >> 0x11)) + d;
b = ((~a | c) ^ d) + _X_LE_32((param+0x34)) + b + 0x4E0811A1;
- b = ((b << 0x15) | (b >> 0x0b)) + c;
+ b = ((b << 0x15) | (b >> 0x0b)) + c;
a = ((~d | b) ^ c) + _X_LE_32((param+0x10)) + a - 0x08AC817E;
- a = ((a << 0x06) | (a >> 0x1a)) + b;
+ a = ((a << 0x06) | (a >> 0x1a)) + b;
d = ((~c | a) ^ b) + _X_LE_32((param+0x2c)) + d - 0x42C50DCB;
- d = ((d << 0x0a) | (d >> 0x16)) + a;
+ d = ((d << 0x0a) | (d >> 0x16)) + a;
c = ((~b | d) ^ a) + _X_LE_32((param+0x08)) + c + 0x2AD7D2BB;
- c = ((c << 0x0f) | (c >> 0x11)) + d;
+ c = ((c << 0x0f) | (c >> 0x11)) + d;
b = ((~a | c) ^ d) + _X_LE_32((param+0x24)) + b - 0x14792C6F;
- b = ((b << 0x15) | (b >> 0x0b)) + c;
+ b = ((b << 0x15) | (b >> 0x0b)) + c;
lprintf("hash output: %x %x %x %x\n", a, b, c, d);
-
+
a += _X_LE_32(field);
b += _X_LE_32(field+4);
c += _X_LE_32(field+8);
@@ -217,15 +218,15 @@ static void call_hash (char *key, char *challenge, unsigned int len) {
char *ptr1, *ptr2;
uint32_t a, b, c, d, tmp;
-
+
ptr1=(key+16);
ptr2=(key+20);
-
+
a = _X_LE_32(ptr1);
b = (a >> 3) & 0x3f;
a += len * 8;
_X_LE_32C(ptr1, a);
-
+
if (a < (len << 3))
{
lprintf("not verified: (len << 3) > a true\n");
@@ -235,7 +236,7 @@ static void call_hash (char *key, char *challenge, unsigned int len) {
tmp = _X_LE_32(ptr2) + (len >> 0x1d);
_X_LE_32C(ptr2, tmp);
a = 64 - b;
- c = 0;
+ c = 0;
if (a <= len)
{
@@ -243,7 +244,7 @@ static void call_hash (char *key, char *challenge, unsigned int len) {
hash(key, key+24);
c = a;
d = c + 0x3f;
-
+
while ( d < len ) {
lprintf("not verified: while ( d < len )\n");
hash(key, challenge+d-0x3f);
@@ -252,7 +253,7 @@ static void call_hash (char *key, char *challenge, unsigned int len) {
}
b = 0;
}
-
+
memcpy(key+b+24, challenge+c, len-c);
}
@@ -264,11 +265,11 @@ static void calc_response (char *result, char *field) {
memset (buf1, 0, 64);
*buf1 = 128;
-
+
memcpy (buf2, field+16, 8);
-
+
i = ( _X_LE_32((buf2)) >> 3 ) & 0x3f;
-
+
if (i < 56) {
i = 56 - i;
} else {
@@ -285,7 +286,7 @@ static void calc_response (char *result, char *field) {
static void calc_response_string (char *result, char *challenge) {
-
+
char field[128] = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
@@ -294,15 +295,15 @@ static void calc_response_string (char *result, char *challenge) {
};
char zres[20];
int i;
-
+
/* calculate response */
call_hash(field, challenge, 64);
calc_response(zres,field);
-
+
/* convert zres to ascii string */
for (i=0; i<16; i++ ) {
char a, b;
-
+
a = (zres[i] >> 4) & 15;
b = zres[i] & 15;
@@ -313,7 +314,7 @@ static void calc_response_string (char *result, char *challenge) {
void real_calc_response_and_checksum (char *response, char *chksum, char *challenge) {
- int ch_len, resp_len;
+ size_t ch_len, resp_len;
int i;
char *ptr;
char buf[128];
@@ -341,11 +342,11 @@ void real_calc_response_and_checksum (char *response, char *chksum, char *challe
ch_len=32;
}
if ( ch_len > 56 ) ch_len=56;
-
+
/* copy challenge to buf */
memcpy(ptr, challenge, ch_len);
}
-
+
/* xor challenge bytewise with xor_table */
for (i=0; i<XOR_TABLE_LEN; i++)
ptr[i] = ptr[i] ^ xor_table[i];
@@ -371,7 +372,7 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
int numrules, codec, size;
int i;
-
+
/* MLTI chunk should begin with MLTI */
if ((mlti_chunk[0] != 'M')
@@ -409,13 +410,13 @@ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection
}
mlti_chunk+=2;
-
+
/* now seek to selected codec */
for (i=0; i<codec; i++) {
size=_X_BE_32(mlti_chunk);
mlti_chunk+=size+4;
}
-
+
size=_X_BE_32(mlti_chunk);
#ifdef LOG
@@ -440,16 +441,16 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
int max_packet_size=0;
int avg_packet_size=0;
int duration=0;
-
+
if (!data) return NULL;
desc=sdpplin_parse(data);
if (!desc) return NULL;
-
+
buf=xine_buffer_init(2048);
- header = xine_xmalloc(sizeof(rmff_header_t));
+ header = calloc(1, sizeof(rmff_header_t));
header->fileheader=rmff_new_fileheader(4+desc->stream_count);
header->cont=rmff_new_cont(
@@ -458,7 +459,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
desc->copyright,
desc->abstract);
header->data=rmff_new_dataheader(0,0);
- header->streams = xine_xmalloc(sizeof(rmff_mdpr_t*)*(desc->stream_count+1));
+ header->streams = calloc((desc->stream_count+1), sizeof(rmff_mdpr_t*));
lprintf("number of streams: %u\n", desc->stream_count);
for (i=0; i<desc->stream_count; i++) {
@@ -483,7 +484,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
}
else
len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], &buf);
-
+
header->streams[i]=rmff_new_mdpr(
desc->stream[i]->stream_id,
desc->stream[i]->max_bit_rate,
@@ -507,7 +508,7 @@ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidt
else
avg_packet_size=desc->stream[i]->avg_packet_size;
}
-
+
if (*stream_rules && strlen(*stream_rules) && (*stream_rules)[strlen(*stream_rules)-1] == ',')
(*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */
@@ -576,12 +577,12 @@ int real_get_rdt_chunk(rtsp_t *rtsp_session, unsigned char **buffer) {
n=rtsp_read_data(rtsp_session, header, 6);
if (n<6) return 0;
ts=_X_BE_32(header);
-
- lprintf("ts: %u size: %u, flags: 0x%02x, unknown values: %u 0x%02x 0x%02x\n",
+
+ lprintf("ts: %u size: %u, flags: 0x%02x, unknown values: %u 0x%02x 0x%02x\n",
ts, size, flags1, unknown1, header[4], header[5]);
size+=2;
-
+
ph.object_version=0;
ph.length=size;
ph.stream_number=(flags1>>1)&1;
@@ -592,7 +593,7 @@ int real_get_rdt_chunk(rtsp_t *rtsp_session, unsigned char **buffer) {
rmff_dump_pheader(&ph, *buffer);
size-=12;
n=rtsp_read_data(rtsp_session, (*buffer)+12, size);
-
+
return (n <= 0) ? 0 : n+12;
}
@@ -611,11 +612,11 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
char *mrl=rtsp_get_mrl(rtsp_session);
unsigned int size;
int status;
-
+
/* get challenge */
challenge1=strdup(rtsp_search_answers(rtsp_session,"RealChallenge1"));
lprintf("Challenge1: %s\n", challenge1);
-
+
/* request stream description */
rtsp_schedule_field(rtsp_session, "Accept: application/sdp");
sprintf(buf, "Bandwidth: %u", bandwidth);
@@ -657,10 +658,10 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
lprintf("real: got no ETag!\n");
else
session_id=strdup(rtsp_search_answers(rtsp_session,"ETag"));
-
+
lprintf("Stream description size: %i\n", size);
- description = malloc(sizeof(char)*(size+1));
+ description = malloc(size+1);
if( rtsp_read_data(rtsp_session, description, size) <= 0) {
xine_buffer_free(buf);
@@ -681,7 +682,7 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid
lprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n",
h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams);
-
+
/* setup our streams */
real_calc_response_and_checksum (challenge2, checksum, challenge1);
xine_buffer_ensure_size(buf, strlen(challenge2) + strlen(checksum) + 32);
diff --git a/src/input/libreal/real.h b/src/input/libreal/real.h
index edcd170f8..f299b909b 100644
--- a/src/input/libreal/real.h
+++ b/src/input/libreal/real.h
@@ -20,7 +20,7 @@
* special functions for real streams.
* adopted from joschkas real tools.
*/
-
+
#ifndef HAVE_REAL_H
#define HAVE_REAL_H
diff --git a/src/input/libreal/rmff.c b/src/input/libreal/rmff.c
index 159b81ee6..6a2b761e1 100644
--- a/src/input/libreal/rmff.c
+++ b/src/input/libreal/rmff.c
@@ -21,6 +21,10 @@
* adopted from joschkas real tools
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#define LOG_MODULE "rmff"
#define LOG_VERBOSE
/*
@@ -35,15 +39,19 @@
* writes header data to a buffer
*/
-static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) {
+static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, uint8_t *buffer, int bufsize) {
+
+ if (!fileheader) return 0;
+
+ if (bufsize < RMFF_FILEHEADER_SIZE)
+ return -1;
- if (!fileheader) return;
fileheader->object_id=_X_BE_32(&fileheader->object_id);
fileheader->size=_X_BE_32(&fileheader->size);
fileheader->object_version=_X_BE_16(&fileheader->object_version);
fileheader->file_version=_X_BE_32(&fileheader->file_version);
fileheader->num_headers=_X_BE_32(&fileheader->num_headers);
-
+
memcpy(buffer, fileheader, 8);
memcpy(&buffer[8], &fileheader->object_version, 2);
memcpy(&buffer[10], &fileheader->file_version, 8);
@@ -53,11 +61,17 @@ static void rmff_dump_fileheader(rmff_fileheader_t *fileheader, char *buffer) {
fileheader->file_version=_X_BE_32(&fileheader->file_version);
fileheader->num_headers=_X_BE_32(&fileheader->num_headers);
fileheader->object_id=_X_BE_32(&fileheader->object_id);
+
+ return RMFF_FILEHEADER_SIZE;
}
-static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) {
+static int rmff_dump_prop(rmff_prop_t *prop, uint8_t *buffer, int bufsize) {
+
+ if (!prop) return 0;
+
+ if (bufsize < RMFF_PROPHEADER_SIZE)
+ return -1;
- if (!prop) return;
prop->object_id=_X_BE_32(&prop->object_id);
prop->size=_X_BE_32(&prop->size);
prop->object_version=_X_BE_16(&prop->object_version);
@@ -78,7 +92,7 @@ static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) {
memcpy(&buffer[10], &prop->max_bit_rate, 36);
memcpy(&buffer[46], &prop->num_streams, 2);
memcpy(&buffer[48], &prop->flags, 2);
-
+
prop->size=_X_BE_32(&prop->size);
prop->object_version=_X_BE_16(&prop->object_version);
prop->max_bit_rate=_X_BE_32(&prop->max_bit_rate);
@@ -93,13 +107,19 @@ static void rmff_dump_prop(rmff_prop_t *prop, char *buffer) {
prop->num_streams=_X_BE_16(&prop->num_streams);
prop->flags=_X_BE_16(&prop->flags);
prop->object_id=_X_BE_32(&prop->object_id);
+
+ return RMFF_PROPHEADER_SIZE;
}
-static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) {
+static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, uint8_t *buffer, int bufsize) {
int s1, s2, s3;
- if (!mdpr) return;
+ if (!mdpr) return 0;
+
+ if (bufsize < RMFF_MDPRHEADER_SIZE + mdpr->type_specific_len + mdpr->stream_name_size + mdpr->mime_type_size)
+ return -1;
+
mdpr->object_id=_X_BE_32(&mdpr->object_id);
mdpr->size=_X_BE_32(&mdpr->size);
mdpr->object_version=_X_BE_16(&mdpr->object_version);
@@ -123,7 +143,7 @@ static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) {
memcpy(&buffer[41+s1], &mdpr->mime_type_size, 1);
s2=mdpr->mime_type_size;
memcpy(&buffer[42+s1], mdpr->mime_type, s2);
-
+
mdpr->type_specific_len=_X_BE_32(&mdpr->type_specific_len);
memcpy(&buffer[42+s1+s2], &mdpr->type_specific_len, 4);
mdpr->type_specific_len=_X_BE_32(&mdpr->type_specific_len);
@@ -141,20 +161,26 @@ static void rmff_dump_mdpr(rmff_mdpr_t *mdpr, char *buffer) {
mdpr->duration=_X_BE_32(&mdpr->duration);
mdpr->object_id=_X_BE_32(&mdpr->object_id);
+ return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3;
}
-static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) {
+static int rmff_dump_cont(rmff_cont_t *cont, uint8_t *buffer, int bufsize) {
int p;
- if (!cont) return;
+ if (!cont) return 0;
+
+ if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len +
+ cont->copyright_len + cont->comment_len)
+ return -1;
+
cont->object_id=_X_BE_32(&cont->object_id);
cont->size=_X_BE_32(&cont->size);
cont->object_version=_X_BE_16(&cont->object_version);
memcpy(buffer, cont, 8);
memcpy(&buffer[8], &cont->object_version, 2);
-
+
cont->title_len=_X_BE_16(&cont->title_len);
memcpy(&buffer[10], &cont->title_len, 2);
cont->title_len=_X_BE_16(&cont->title_len);
@@ -181,11 +207,18 @@ static void rmff_dump_cont(rmff_cont_t *cont, char *buffer) {
cont->size=_X_BE_32(&cont->size);
cont->object_version=_X_BE_16(&cont->object_version);
cont->object_id=_X_BE_32(&cont->object_id);
+
+ return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len +
+ cont->copyright_len + cont->comment_len;
}
-static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) {
+static int rmff_dump_dataheader(rmff_data_t *data, uint8_t *buffer, int bufsize) {
+
+ if (!data) return 0;
+
+ if (bufsize < RMFF_DATAHEADER_SIZE)
+ return -1;
- if (!data) return;
data->object_id=_X_BE_32(&data->object_id);
data->size=_X_BE_32(&data->size);
data->object_version=_X_BE_16(&data->object_version);
@@ -195,37 +228,49 @@ static void rmff_dump_dataheader(rmff_data_t *data, char *buffer) {
memcpy(buffer, data, 8);
memcpy(&buffer[8], &data->object_version, 2);
memcpy(&buffer[10], &data->num_packets, 8);
-
+
data->num_packets=_X_BE_32(&data->num_packets);
data->next_data_header=_X_BE_32(&data->next_data_header);
data->size=_X_BE_32(&data->size);
data->object_version=_X_BE_16(&data->object_version);
data->object_id=_X_BE_32(&data->object_id);
+
+ return RMFF_DATAHEADER_SIZE;
}
-int rmff_dump_header(rmff_header_t *h, char *buffer, int max) {
+int rmff_dump_header(rmff_header_t *h, void *buf_gen, int max) {
+ uint8_t *buffer = buf_gen;
- int written=0;
+ int written=0, size;
rmff_mdpr_t **stream=h->streams;
- rmff_dump_fileheader(h->fileheader, &buffer[written]);
- written+=h->fileheader->size;
- rmff_dump_prop(h->prop, &buffer[written]);
- written+=h->prop->size;
- rmff_dump_cont(h->cont, &buffer[written]);
- written+=h->cont->size;
+ if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
+ max -= size;
+ if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
+ max -= size;
+ if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
+ max -= size;
if (stream)
{
while(*stream)
{
- rmff_dump_mdpr(*stream, &buffer[written]);
- written+=(*stream)->size;
+ if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
+ max -= size;
stream++;
}
}
-
- rmff_dump_dataheader(h->data, &buffer[written]);
- written+=18;
+
+ if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0)
+ return -1;
+ written+=size;
return written;
}
@@ -289,12 +334,14 @@ static rmff_prop_t *rmff_scan_prop(const char *data) {
return prop;
}
-static rmff_mdpr_t *rmff_scan_mdpr(const char *data) {
-
- rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t));
+static rmff_mdpr_t *rmff_scan_mdpr(const char *data)
+{
+ rmff_mdpr_t *mdpr = calloc(sizeof(rmff_mdpr_t), 1);
mdpr->object_id=_X_BE_32(data);
mdpr->size=_X_BE_32(&data[4]);
+ if (mdpr->size < 46)
+ goto fail;
mdpr->object_version=_X_BE_16(&data[8]);
if (mdpr->object_version != 0)
{
@@ -308,23 +355,42 @@ static rmff_mdpr_t *rmff_scan_mdpr(const char *data) {
mdpr->start_time=_X_BE_32(&data[28]);
mdpr->preroll=_X_BE_32(&data[32]);
mdpr->duration=_X_BE_32(&data[36]);
-
+
mdpr->stream_name_size=data[40];
- mdpr->stream_name = malloc(sizeof(char)*(mdpr->stream_name_size+1));
+ if (mdpr->size < 46 + mdpr->stream_name_size)
+ goto fail;
+ mdpr->stream_name = malloc(mdpr->stream_name_size+1);
+ if (!mdpr->stream_name)
+ goto fail;
memcpy(mdpr->stream_name, &data[41], mdpr->stream_name_size);
mdpr->stream_name[mdpr->stream_name_size]=0;
-
+
mdpr->mime_type_size=data[41+mdpr->stream_name_size];
- mdpr->mime_type = malloc(sizeof(char)*(mdpr->mime_type_size+1));
+ if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size)
+ goto fail;
+ mdpr->mime_type = malloc(mdpr->mime_type_size+1);
+ if (!mdpr->mime_type)
+ goto fail;
memcpy(mdpr->mime_type, &data[42+mdpr->stream_name_size], mdpr->mime_type_size);
mdpr->mime_type[mdpr->mime_type_size]=0;
-
+
mdpr->type_specific_len=_X_BE_32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]);
- mdpr->type_specific_data = malloc(sizeof(char)*(mdpr->type_specific_len));
- memcpy(mdpr->type_specific_data,
+ if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size + mdpr->type_specific_data)
+ goto fail;
+ mdpr->type_specific_data = malloc(mdpr->type_specific_len);
+ if (!mdpr->type_specific_data)
+ goto fail;
+ memcpy(mdpr->type_specific_data,
&data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len);
-
+
return mdpr;
+
+fail:
+ free (mdpr->stream_name);
+ free (mdpr->mime_type);
+ free (mdpr->type_specific_data);
+ free (mdpr);
+ return NULL;
}
static rmff_cont_t *rmff_scan_cont(const char *data) {
@@ -340,22 +406,22 @@ static rmff_cont_t *rmff_scan_cont(const char *data) {
lprintf("warning: unknown object version in CONT: 0x%04x\n", cont->object_version);
}
cont->title_len=_X_BE_16(&data[10]);
- cont->title = malloc(sizeof(char)*(cont->title_len+1));
+ cont->title = malloc(cont->title_len+1);
memcpy(cont->title, &data[12], cont->title_len);
cont->title[cont->title_len]=0;
pos=cont->title_len+12;
cont->author_len=_X_BE_16(&data[pos]);
- cont->author = malloc(sizeof(char)*(cont->author_len+1));
+ cont->author = malloc(cont->author_len+1);
memcpy(cont->author, &data[pos+2], cont->author_len);
cont->author[cont->author_len]=0;
pos=pos+2+cont->author_len;
cont->copyright_len=_X_BE_16(&data[pos]);
- cont->copyright = malloc(sizeof(char)*(cont->copyright_len+1));
+ cont->copyright = malloc(cont->copyright_len+1);
memcpy(cont->copyright, &data[pos+2], cont->copyright_len);
cont->copyright[cont->copyright_len]=0;
pos=pos+2+cont->copyright_len;
cont->comment_len=_X_BE_16(&data[pos]);
- cont->comment = malloc(sizeof(char)*(cont->comment_len+1));
+ cont->comment = malloc(cont->comment_len+1);
memcpy(cont->comment, &data[pos+2], cont->comment_len);
cont->comment[cont->comment_len]=0;
@@ -378,7 +444,7 @@ static rmff_data_t *rmff_scan_dataheader(const char *data) {
return dh;
}
-
+
rmff_header_t *rmff_scan_header(const char *data) {
rmff_header_t *header = malloc(sizeof(rmff_header_t));
@@ -402,21 +468,18 @@ rmff_header_t *rmff_scan_header(const char *data) {
}
header->fileheader=rmff_scan_fileheader(ptr);
ptr += header->fileheader->size;
-
- header->streams = malloc(sizeof(rmff_mdpr_t*)*(header->fileheader->num_headers));
- for (i=0; i<header->fileheader->num_headers; i++) {
- header->streams[i]=NULL;
- }
-
+
+ header->streams = calloc(header->fileheader->num_headers, sizeof(rmff_mdpr_t*));
+
for (i=1; i<header->fileheader->num_headers; i++) {
chunk_type = _X_BE_32(ptr);
-
+
if (ptr[0] == 0)
{
lprintf("rmff: warning: only %d of %d header found.\n", i, header->fileheader->num_headers);
break;
}
-
+
chunk_size=1;
switch (chunk_type) {
case PROP_TAG:
@@ -425,8 +488,11 @@ rmff_header_t *rmff_scan_header(const char *data) {
break;
case MDPR_TAG:
mdpr=rmff_scan_mdpr(ptr);
- chunk_size=mdpr->size;
- header->streams[mdpr->stream_number]=mdpr;
+ if (mdpr) /* FIXME: what to do if NULL? */
+ {
+ chunk_size=mdpr->size;
+ header->streams[mdpr->stream_number]=mdpr;
+ }
break;
case CONT_TAG:
header->cont=rmff_scan_cont(ptr);
@@ -544,7 +610,7 @@ rmff_prop_t *rmff_new_prop (
prop->data_offset=data_offset;
prop->num_streams=num_streams;
prop->flags=flags;
-
+
return prop;
}
@@ -563,7 +629,7 @@ rmff_mdpr_t *rmff_new_mdpr(
const char *type_specific_data ) {
rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t));
-
+
mdpr->object_id=MDPR_TAG;
mdpr->object_version=0;
@@ -586,10 +652,10 @@ rmff_mdpr_t *rmff_new_mdpr(
mdpr->mime_type_size=strlen(mime_type);
}
mdpr->type_specific_len=type_specific_len;
- mdpr->type_specific_data = malloc(sizeof(char)*type_specific_len);
+ mdpr->type_specific_data = malloc(type_specific_len);
memcpy(mdpr->type_specific_data,type_specific_data,type_specific_len);
mdpr->mlti_data=NULL;
-
+
mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46;
return mdpr;
@@ -606,7 +672,7 @@ rmff_cont_t *rmff_new_cont(const char *title, const char *author, const char *co
cont->author=NULL;
cont->copyright=NULL;
cont->comment=NULL;
-
+
cont->title_len=0;
cont->author_len=0;
cont->copyright_len=0;
@@ -645,11 +711,11 @@ rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header
return data;
}
-
+
void rmff_print_header(rmff_header_t *h) {
rmff_mdpr_t **stream;
-
+
if(!h) {
printf("rmff_print_header: NULL given\n");
return;
@@ -710,7 +776,7 @@ void rmff_print_header(rmff_header_t *h) {
printf("size : %i\n", h->data->size);
printf("packets : %i\n", h->data->num_packets);
printf("next DATA : 0x%08x\n", h->data->next_data_header);
- }
+ }
}
void rmff_fix_header(rmff_header_t *h) {
@@ -738,7 +804,7 @@ void rmff_fix_header(rmff_header_t *h) {
streams++;
}
}
-
+
if (h->prop) {
if (h->prop->size != 50)
{
@@ -775,7 +841,7 @@ void rmff_fix_header(rmff_header_t *h) {
}
num_headers++;
-
+
if (!h->fileheader) {
lprintf("rmff_fix_header: no fileheader, creating one");
@@ -790,31 +856,31 @@ void rmff_fix_header(rmff_header_t *h) {
num_headers++;
if(h->fileheader->num_headers != num_headers) {
- lprintf("rmff_fix_header: setting num_headers from %i to %i\n", h->fileheader->num_headers, num_headers);
+ lprintf("rmff_fix_header: setting num_headers from %i to %i\n", h->fileheader->num_headers, num_headers);
h->fileheader->num_headers=num_headers;
}
if(h->prop) {
if (h->prop->data_offset != header_size) {
- lprintf("rmff_fix_header: setting prop.data_offset from %i to %i\n", h->prop->data_offset, header_size);
+ lprintf("rmff_fix_header: setting prop.data_offset from %i to %i\n", h->prop->data_offset, header_size);
h->prop->data_offset=header_size;
}
if (h->prop->num_packets == 0) {
int p=(int)(h->prop->avg_bit_rate/8.0*(h->prop->duration/1000.0)/h->prop->avg_packet_size);
- lprintf("rmff_fix_header: assuming prop.num_packets=%i\n", p);
+ lprintf("rmff_fix_header: assuming prop.num_packets=%i\n", p);
h->prop->num_packets=p;
}
if (h->data->num_packets == 0) {
- lprintf("rmff_fix_header: assuming data.num_packets=%i\n", h->prop->num_packets);
+ lprintf("rmff_fix_header: assuming data.num_packets=%i\n", h->prop->num_packets);
h->data->num_packets=h->prop->num_packets;
}
-
- lprintf("rmff_fix_header: assuming data.size=%i\n", h->prop->num_packets*h->prop->avg_packet_size);
+
+ lprintf("rmff_fix_header: assuming data.size=%i\n", h->prop->num_packets*h->prop->avg_packet_size);
h->data->size=h->prop->num_packets*h->prop->avg_packet_size;
}
@@ -826,7 +892,7 @@ int rmff_get_header_size(rmff_header_t *h) {
if (!h->prop) return -1;
return h->prop->data_offset+18;
-
+
}
void rmff_free_header(rmff_header_t *h) {
diff --git a/src/input/libreal/rmff.h b/src/input/libreal/rmff.h
index d39942088..20b8b8960 100644
--- a/src/input/libreal/rmff.h
+++ b/src/input/libreal/rmff.h
@@ -32,13 +32,19 @@
#include <string.h>
#include <inttypes.h>
-
#ifndef HAVE_RMFF_H
#define HAVE_RMFF_H
+#include "attributes.h"
#define RMFF_HEADER_SIZE 0x12
+#define RMFF_FILEHEADER_SIZE 18
+#define RMFF_PROPHEADER_SIZE 50
+#define RMFF_MDPRHEADER_SIZE 46
+#define RMFF_CONTHEADER_SIZE 18
+#define RMFF_DATAHEADER_SIZE 18
+
#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
(((long)(unsigned char)(ch3) ) | \
( (long)(unsigned char)(ch2) << 8 ) | \
@@ -92,7 +98,7 @@ typedef struct {
uint32_t data_offset;
uint16_t num_streams;
uint16_t flags;
-
+
} rmff_prop_t;
typedef struct {
@@ -135,11 +141,11 @@ typedef struct {
char *copyright;
uint16_t comment_len;
char *comment;
-
+
} rmff_cont_t;
typedef struct {
-
+
uint32_t object_id;
uint32_t size;
uint16_t object_version;
@@ -172,7 +178,7 @@ typedef struct {
/*
* constructors for header structs
*/
-
+
rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers);
rmff_prop_t *rmff_new_prop (
@@ -214,7 +220,7 @@ rmff_data_t *rmff_new_dataheader(
/*
* reads header infos from data and returns a newly allocated header struct
*/
-rmff_header_t *rmff_scan_header(const char *data);
+rmff_header_t *rmff_scan_header(const char *data) XINE_MALLOC;
/*
* scans a data packet header. Notice, that this function does not allocate
@@ -225,7 +231,7 @@ void rmff_scan_pheader(rmff_pheader_t *h, char *data);
/*
* reads header infos from stream and returns a newly allocated header struct
*/
-rmff_header_t *rmff_scan_header_stream(int fd);
+rmff_header_t *rmff_scan_header_stream(int fd) XINE_MALLOC;
/*
* prints header information in human readible form to stdout
@@ -241,11 +247,11 @@ void rmff_fix_header(rmff_header_t *h);
* returns the size of the header (incl. first data-header)
*/
int rmff_get_header_size(rmff_header_t *h);
-
+
/*
* dumps the header <h> to <buffer>. <max> is the size of <buffer>
*/
-int rmff_dump_header(rmff_header_t *h, char *buffer, int max);
+int rmff_dump_header(rmff_header_t *h, void *buf_gen, int max);
/*
* dumps a packet header
diff --git a/src/input/libreal/sdpplin.c b/src/input/libreal/sdpplin.c
index c62b6bbc1..b7e5218cb 100644
--- a/src/input/libreal/sdpplin.c
+++ b/src/input/libreal/sdpplin.c
@@ -19,7 +19,11 @@
*
* sdp/sdpplin parser.
*/
-
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#define LOG_MODULE "sdpplin"
#define LOG_VERBOSE
/*
@@ -58,9 +62,10 @@ static char *b64_decode(const char *in, char *out, int *size)
dtable['='] = 0;
k=0;
-
+
/*CONSTANTCONDITION*/
- for (j=0; j<strlen(in); j+=4)
+ const size_t in_len = strlen(in);
+ for (j=0; j<in_len; j+=4)
{
char a[4], b[4];
@@ -99,12 +104,12 @@ static char *nl(char *data) {
static int filter(const char *in, const char *filter, char **out) {
- int flen=strlen(filter);
+ size_t flen=strlen(filter);
size_t len;
-
+
if (!in)
return 0;
-
+
len = (strchr(in,'\n')) ? (size_t)(strchr(in,'\n')-in) : strlen(in);
if (!strncmp(in,filter,flen))
@@ -117,16 +122,16 @@ static int filter(const char *in, const char *filter, char **out) {
return len-flen;
}
-
+
return 0;
}
-static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
+static sdpplin_stream_t *XINE_MALLOC sdpplin_parse_stream(char **data) {
- sdpplin_stream_t *desc = xine_xmalloc(sizeof(sdpplin_stream_t));
+ sdpplin_stream_t *desc = calloc(1, sizeof(sdpplin_stream_t));
char *buf=xine_buffer_init(32);
char *decoded=xine_buffer_init(32);
int handled;
-
+
if (filter(*data, "m=", &buf)) {
desc->id = strdup(buf);
} else
@@ -141,9 +146,16 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
while (*data && **data && *data[0]!='m') {
handled=0;
-
+
if(filter(*data,"a=control:streamid=",&buf)) {
- desc->stream_id=atoi(buf);
+ /* This way negative values are mapped to unfeasibly high
+ * values, and will be discarded afterward
+ */
+ unsigned long tmp = strtoul(buf, NULL, 10);
+ if ( tmp > UINT16_MAX )
+ lprintf("stream id out of bound: %lu\n", tmp);
+ else
+ desc->stream_id=tmp;
handled=1;
*data=nl(*data);
}
@@ -163,7 +175,7 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
handled=1;
*data=nl(*data);
}
-
+
if(filter(*data,"a=StartTime:integer;",&buf)) {
desc->start_time=atoi(buf);
handled=1;
@@ -199,14 +211,14 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
if(filter(*data,"a=OpaqueData:buffer;",&buf)) {
decoded = b64_decode(buf, decoded, &(desc->mlti_data_size));
if ( decoded != NULL ) {
- desc->mlti_data = malloc(sizeof(char)*desc->mlti_data_size);
+ desc->mlti_data = malloc(desc->mlti_data_size);
memcpy(desc->mlti_data, decoded, desc->mlti_data_size);
handled=1;
*data=nl(*data);
lprintf("mlti_data_size: %i\n", desc->mlti_data_size);
}
}
-
+
if(filter(*data,"a=ASMRuleBook:string;",&buf)) {
desc->asm_rule_book=strdup(buf);
handled=1;
@@ -226,13 +238,13 @@ static sdpplin_stream_t *sdpplin_parse_stream(char **data) {
xine_buffer_free(buf);
xine_buffer_free(decoded);
-
+
return desc;
}
sdpplin_t *sdpplin_parse(char *data) {
- sdpplin_t *desc = xine_xmalloc(sizeof(sdpplin_t));
+ sdpplin_t *desc = calloc(1, sizeof(sdpplin_t));
sdpplin_stream_t *stream;
char *buf=xine_buffer_init(32);
char *decoded=xine_buffer_init(32);
@@ -244,7 +256,7 @@ sdpplin_t *sdpplin_parse(char *data) {
while (data && *data) {
handled=0;
-
+
if (filter(data, "m=", &buf)) {
if ( ! desc->stream ) {
fprintf(stderr, "sdpplin.c: stream identifier found before stream count, skipping.");
@@ -252,7 +264,10 @@ sdpplin_t *sdpplin_parse(char *data) {
}
stream=sdpplin_parse_stream(&data);
lprintf("got data for stream id %u\n", stream->stream_id);
- desc->stream[stream->stream_id]=stream;
+ if ( stream->stream_id >= desc->stream_count )
+ lprintf("stream id %u is greater than stream count %u\n", stream->stream_id, desc->stream_count);
+ else
+ desc->stream[stream->stream_id]=stream;
continue;
}
@@ -264,7 +279,7 @@ sdpplin_t *sdpplin_parse(char *data) {
data=nl(data);
}
}
-
+
if(filter(data,"a=Author:buffer;",&buf)) {
decoded=b64_decode(buf, decoded, &len);
if ( decoded != NULL ) {
@@ -273,7 +288,7 @@ sdpplin_t *sdpplin_parse(char *data) {
data=nl(data);
}
}
-
+
if(filter(data,"a=Copyright:buffer;",&buf)) {
decoded=b64_decode(buf, decoded, &len);
if ( decoded != NULL ) {
@@ -282,7 +297,7 @@ sdpplin_t *sdpplin_parse(char *data) {
data=nl(data);
}
}
-
+
if(filter(data,"a=Abstract:buffer;",&buf)) {
decoded=b64_decode(buf, decoded, &len);
if ( decoded != NULL ) {
@@ -291,10 +306,17 @@ sdpplin_t *sdpplin_parse(char *data) {
data=nl(data);
}
}
-
+
if(filter(data,"a=StreamCount:integer;",&buf)) {
- desc->stream_count=atoi(buf);
- desc->stream = malloc(sizeof(sdpplin_stream_t*)*desc->stream_count);
+ /* This way negative values are mapped to unfeasibly high
+ * values, and will be discarded afterward
+ */
+ unsigned long tmp = strtoul(buf, NULL, 10);
+ if ( tmp > UINT16_MAX )
+ lprintf("stream count out of bound: %lu\n", tmp);
+ else
+ desc->stream_count = tmp;
+ desc->stream = calloc(desc->stream_count, sizeof(sdpplin_stream_t*));
handled=1;
data=nl(data);
}
@@ -318,7 +340,7 @@ sdpplin_t *sdpplin_parse(char *data) {
xine_buffer_free(buf);
xine_buffer_free(decoded);
-
+
return desc;
}
diff --git a/src/input/libreal/sdpplin.h b/src/input/libreal/sdpplin.h
index cb3b434d4..2296c31e7 100644
--- a/src/input/libreal/sdpplin.h
+++ b/src/input/libreal/sdpplin.h
@@ -19,7 +19,7 @@
*
* sdp/sdpplin parser.
*/
-
+
#ifndef HAVE_SDPPLIN_H
#define HAVE_SDPPLIN_H
@@ -37,7 +37,7 @@ typedef struct {
char *id;
char *bandwidth;
- int stream_id;
+ uint16_t stream_id;
char *range;
char *length;
char *rtpmap;
@@ -81,7 +81,7 @@ typedef struct {
int flags;
int is_real_data_type;
- int stream_count;
+ uint16_t stream_count;
char *title;
char *author;
char *copyright;
@@ -98,10 +98,10 @@ typedef struct {
int duration;
sdpplin_stream_t **stream;
-
+
} sdpplin_t;
-sdpplin_t *sdpplin_parse(char *data);
+sdpplin_t *sdpplin_parse(char *data) XINE_MALLOC;
void sdpplin_free(sdpplin_t *description);
diff --git a/src/input/librtsp/rtsp.c b/src/input/librtsp/rtsp.c
index 530ffc6cf..ebac49079 100644
--- a/src/input/librtsp/rtsp.c
+++ b/src/input/librtsp/rtsp.c
@@ -21,6 +21,10 @@
* *not* RFC 2326 compilant yet.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
@@ -40,7 +44,7 @@
#define LOG_VERBOSE
/*
#define LOG
-*/
+*/
#include "rtsp.h"
#include "io_helper.h"
@@ -65,7 +69,7 @@ struct rtsp_s {
char *server;
unsigned int server_state;
uint32_t server_caps;
-
+
unsigned int cseq;
char *session;
@@ -101,17 +105,17 @@ const char rtsp_protocol_version[]="RTSP/1.0";
* rtsp_get gets a line from stream
* and returns a null terminated string (must be freed).
*/
-
+
static char *rtsp_get(rtsp_t *s) {
char *buffer = malloc(BUF_SIZE);
char *string = NULL;
-
+
if ( _x_io_tcp_read_line(s->stream, s->s, buffer, BUF_SIZE) >= 0 ) {
lprintf("<< '%s'\n", buffer);
string = strdup( buffer );
}
-
+
free(buffer);
return string;
}
@@ -120,10 +124,10 @@ static char *rtsp_get(rtsp_t *s) {
/*
* rtsp_put puts a line on stream
*/
-
+
static void rtsp_put(rtsp_t *s, const char *string) {
- int len=strlen(string);
+ size_t len=strlen(string);
char *buf = malloc(sizeof(char)*len+2);
lprintf(">> '%s'", string);
@@ -133,7 +137,7 @@ static void rtsp_put(rtsp_t *s, const char *string) {
buf[len+1]=0x0a;
_x_io_tcp_write(s->stream, s->s, buf, len+2);
-
+
lprintf("done.\n");
free(buf);
@@ -147,7 +151,7 @@ static int rtsp_get_code(rtsp_t *s, const char *string) {
char buf[4];
int code=0;
-
+
if (!strncmp(string, rtsp_protocol_version, strlen(rtsp_protocol_version)))
{
memcpy(buf, string+strlen(rtsp_protocol_version)+1, 3);
@@ -158,7 +162,7 @@ static int rtsp_get_code(rtsp_t *s, const char *string) {
return RTSP_STATUS_SET_PARAMETER;
}
- if(code != 200)
+ if(code != 200)
xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG, "librtsp: server responds: '%s'\n", string);
return code;
@@ -172,10 +176,8 @@ static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) {
char **payload=s->scheduled;
char *buf;
-
- buf = malloc(strlen(type)+strlen(what)+strlen(rtsp_protocol_version)+3);
-
- sprintf(buf,"%s %s %s",type, what, rtsp_protocol_version);
+
+ asprintf(&buf,"%s %s %s",type, what, rtsp_protocol_version);
rtsp_put(s,buf);
free(buf);
if (payload)
@@ -194,14 +196,13 @@ static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) {
static void rtsp_schedule_standard(rtsp_t *s) {
char tmp[17];
-
+
sprintf(tmp, "Cseq: %u", s->cseq);
rtsp_schedule_field(s, tmp);
-
+
if (s->session) {
char *buf;
- buf = malloc(strlen(s->session)+15);
- sprintf(buf, "Session: %s", s->session);
+ asprintf(&buf, "Session: %s", s->session);
rtsp_schedule_field(s, buf);
free(buf);
}
@@ -209,7 +210,7 @@ static void rtsp_schedule_standard(rtsp_t *s) {
/*
* get the answers, if server responses with something != 200, return NULL
*/
-
+
static int rtsp_get_answers(rtsp_t *s) {
char *answer=NULL;
@@ -217,7 +218,7 @@ static int rtsp_get_answers(rtsp_t *s) {
char **answer_ptr=s->answers;
int code;
int ans_count = 0;
-
+
answer=rtsp_get(s);
if (!answer)
return 0;
@@ -225,55 +226,49 @@ static int rtsp_get_answers(rtsp_t *s) {
free(answer);
rtsp_free_answers(s);
-
+
do { /* while we get answer lines */
-
+
answer=rtsp_get(s);
if (!answer)
return 0;
-
- if (!strncasecmp(answer,"Cseq:",5)) {
- sscanf(answer,"%*s %u",&answer_seq);
+
+ if (!strncasecmp(answer,"Cseq: ",6)) {
+ sscanf(answer+6,"%u",&answer_seq);
if (s->cseq != answer_seq) {
lprintf("warning: Cseq mismatch. got %u, assumed %u", answer_seq, s->cseq);
s->cseq=answer_seq;
}
}
- if (!strncasecmp(answer,"Server:",7)) {
- char *buf = xine_xmalloc(strlen(answer));
- sscanf(answer,"%*s %s",buf);
- if (s->server) free(s->server);
- s->server=strdup(buf);
- free(buf);
+ if (!strncasecmp(answer,"Server: ",8)) {
+ free(s->server);
+ s->server = strdup(answer + 8);
}
- if (!strncasecmp(answer,"Session:",8)) {
- char *buf = xine_xmalloc(strlen(answer));
- sscanf(answer,"%*s %s",buf);
+ if (!strncasecmp(answer,"Session: ",9)) {
+ char *tmp = answer + 9;
if (s->session) {
- if (strcmp(buf, s->session)) {
- xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG,
- "rtsp: warning: setting NEW session: %s\n", buf);
- free(s->session);
- s->session=strdup(buf);
+ if (strcmp(tmp, s->session)) {
+ xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG,
+ "rtsp: warning: setting NEW session: %s\n", tmp);
+ s->session=strdup(tmp);
}
} else
{
- lprintf("setting session id to: %s\n", buf);
+ lprintf("setting session id to: %s\n", tmp);
- s->session=strdup(buf);
+ s->session=strdup(tmp);
}
- free(buf);
}
*answer_ptr=answer;
answer_ptr++;
} while ((strlen(answer)!=0) && (++ans_count < MAX_FIELDS));
-
+
s->cseq++;
-
+
*answer_ptr=NULL;
rtsp_schedule_standard(s);
-
+
return code;
}
@@ -283,7 +278,7 @@ static int rtsp_get_answers(rtsp_t *s) {
int rtsp_send_ok(rtsp_t *s) {
char cseq[16];
-
+
rtsp_put(s, "RTSP/1.0 200 OK");
sprintf(cseq,"CSeq: %u", s->cseq);
rtsp_put(s, cseq);
@@ -304,8 +299,7 @@ int rtsp_request_options(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+16));
- sprintf(buf,"rtsp://%s:%i", s->host, s->port);
+ asprintf(&buf,"rtsp://%s:%i", s->host, s->port);
}
rtsp_send_request(s,"OPTIONS",buf);
free(buf);
@@ -321,19 +315,18 @@ int rtsp_request_describe(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"DESCRIBE",buf);
free(buf);
-
+
return rtsp_get_answers(s);
}
int rtsp_request_setup(rtsp_t *s, const char *what) {
rtsp_send_request(s,"SETUP",what);
-
+
return rtsp_get_answers(s);
}
@@ -345,12 +338,11 @@ int rtsp_request_setparameter(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"SET_PARAMETER",buf);
free(buf);
-
+
return rtsp_get_answers(s);
}
@@ -362,19 +354,18 @@ int rtsp_request_play(rtsp_t *s, const char *what) {
buf=strdup(what);
} else
{
- buf = malloc(sizeof(char)*(strlen(s->host)+strlen(s->path)+16));
- sprintf(buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
+ asprintf(&buf,"rtsp://%s:%i/%s", s->host, s->port, s->path);
}
rtsp_send_request(s,"PLAY",buf);
free(buf);
-
+
return rtsp_get_answers(s);
}
int rtsp_request_tearoff(rtsp_t *s, const char *what) {
rtsp_send_request(s,"TEAROFF",what);
-
+
return rtsp_get_answers(s);
}
@@ -394,7 +385,7 @@ int rtsp_read_data(rtsp_t *s, char *buffer, unsigned int size) {
char *rest=rtsp_get(s);
if (!rest)
return -1;
-
+
seq=-1;
do {
free(rest);
@@ -412,8 +403,7 @@ int rtsp_read_data(rtsp_t *s, char *buffer, unsigned int size) {
}
/* lets make the server happy */
rtsp_put(s, "RTSP/1.0 451 Parameter Not Understood");
- rest = malloc(sizeof(char)*17);
- sprintf(rest,"CSeq: %u", seq);
+ asprintf(&rest,"CSeq: %u", seq);
rtsp_put(s, rest);
free(rest);
rtsp_put(s, "");
@@ -442,14 +432,14 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
char *slash, *colon;
int hostend, i;
size_t pathbegin;
-
+
if (strncmp(mrl,"rtsp://",7))
{
xprintf(stream->xine, XINE_VERBOSITY_LOG, _("rtsp: bad mrl: %s\n"), mrl);
free(s);
return NULL;
}
-
+
mrl_ptr+=7;
for (i=0; i<MAX_FIELDS; i++) {
@@ -463,14 +453,14 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
s->path=NULL;
s->mrl=NULL;
s->mrl=strdup(mrl);
-
+
s->server=NULL;
s->server_state=0;
s->server_caps=0;
-
+
s->cseq=0;
s->session=NULL;
-
+
if (user_agent)
s->user_agent=strdup(user_agent);
else
@@ -480,20 +470,18 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
colon=strchr(mrl_ptr,':');
if(!slash) slash=mrl_ptr+strlen(mrl_ptr)+1;
- if(!colon) colon=slash;
+ if(!colon) colon=slash;
if(colon > slash) colon=slash;
pathbegin=slash-mrl_ptr;
hostend=colon-mrl_ptr;
- s->host = malloc(sizeof(char)*hostend+1);
- strncpy(s->host, mrl_ptr, hostend);
- s->host[hostend]=0;
+ s->host = strndup(mrl_ptr, hostend);
if (pathbegin < strlen(mrl_ptr)) s->path=strdup(mrl_ptr+pathbegin+1);
if (colon != slash) {
char buffer[pathbegin-hostend];
-
+
strncpy(buffer,mrl_ptr+hostend+1, pathbegin-hostend-1);
buffer[pathbegin-hostend-1]=0;
s->port=atoi(buffer);
@@ -529,7 +517,7 @@ rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_ag
/*
- * closes an rtsp connection
+ * closes an rtsp connection
*/
void rtsp_close(rtsp_t *s) {
@@ -542,7 +530,7 @@ void rtsp_close(rtsp_t *s) {
if (s->user_agent) free(s->user_agent);
rtsp_free_answers(s);
rtsp_unschedule_all(s);
- free(s);
+ free(s);
}
/*
@@ -554,7 +542,7 @@ char *rtsp_search_answers(rtsp_t *s, const char *tag) {
char **answer;
char *ptr;
-
+
if (!s->answers) return NULL;
answer=s->answers;
@@ -603,7 +591,7 @@ char *rtsp_get_mrl(rtsp_t *s) {
void rtsp_schedule_field(rtsp_t *s, const char *string) {
int i=0;
-
+
if (!string) return;
while(s->scheduled[i]) {
@@ -613,13 +601,13 @@ void rtsp_schedule_field(rtsp_t *s, const char *string) {
}
/*
- * removes the first scheduled field which prefix matches string.
+ * removes the first scheduled field which prefix matches string.
*/
void rtsp_unschedule_field(rtsp_t *s, const char *string) {
char **ptr=s->scheduled;
-
+
if (!string) return;
while(*ptr) {
@@ -640,7 +628,7 @@ void rtsp_unschedule_field(rtsp_t *s, const char *string) {
void rtsp_unschedule_all(rtsp_t *s) {
char **ptr;
-
+
if (!s->scheduled) return;
ptr=s->scheduled;
@@ -657,7 +645,7 @@ void rtsp_unschedule_all(rtsp_t *s) {
void rtsp_free_answers(rtsp_t *s) {
char **answer;
-
+
if (!s->answers) return;
answer=s->answers;
diff --git a/src/input/librtsp/rtsp.h b/src/input/librtsp/rtsp.h
index dc2624459..a00035aef 100644
--- a/src/input/librtsp/rtsp.h
+++ b/src/input/librtsp/rtsp.h
@@ -20,7 +20,7 @@
* a minimalistic implementation of rtsp protocol,
* *not* RFC 2326 compilant yet.
*/
-
+
#ifndef HAVE_RTSP_H
#define HAVE_RTSP_H
@@ -40,7 +40,7 @@
typedef struct rtsp_s rtsp_t;
-rtsp_t* rtsp_connect (xine_stream_t *stream, const char *mrl, const char *user_agent);
+rtsp_t* rtsp_connect (xine_stream_t *stream, const char *mrl, const char *user_agent) XINE_MALLOC;
int rtsp_request_options(rtsp_t *s, const char *what);
int rtsp_request_describe(rtsp_t *s, const char *what);
diff --git a/src/input/librtsp/rtsp_session.c b/src/input/librtsp/rtsp_session.c
index f3ddb59bc..2ae002662 100644
--- a/src/input/librtsp/rtsp_session.c
+++ b/src/input/librtsp/rtsp_session.c
@@ -20,6 +20,10 @@
* high level interface to rtsp servers.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -78,14 +82,14 @@ const char *rtsp_bandwidth_strs[]={"14.4 Kbps (Modem)", "19.2 Kbps (Modem)",
rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) {
- rtsp_session_t *rtsp_session = xine_xmalloc(sizeof(rtsp_session_t));
+ rtsp_session_t *rtsp_session = calloc(1, sizeof(rtsp_session_t));
xine_t *xine = stream->xine;
char *server;
char *mrl_line=strdup(mrl);
rmff_header_t *h;
int bandwidth_id;
uint32_t bandwidth;
-
+
bandwidth_id = xine->config->register_enum(xine->config, "media.network.bandwidth", 10,
(char **)rtsp_bandwidth_strs,
_("network bandwidth"),
@@ -96,7 +100,7 @@ rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) {
bandwidth = rtsp_bandwidths[bandwidth_id];
rtsp_session->recv = xine_buffer_init(BUF_SIZE);
-
+
connect:
/* connect to server */
@@ -145,18 +149,24 @@ connect:
return NULL;
}
}
-
- rtsp_session->header_left =
+
+ rtsp_session->header_left =
rtsp_session->header_len = rmff_dump_header(h,rtsp_session->header,HEADER_SIZE);
+ if (rtsp_session->header_len < 0) {
+ xprintf (stream->xine, XINE_VERBOSITY_LOG,
+ _("rtsp_session: rtsp server returned overly-large headers, session can not be established.\n"));
+ goto session_abort;
+ }
xine_buffer_copyin(rtsp_session->recv, 0, rtsp_session->header, rtsp_session->header_len);
rtsp_session->recv_size = rtsp_session->header_len;
rtsp_session->recv_read = 0;
-
+
} else
{
xprintf(stream->xine, XINE_VERBOSITY_LOG,
_("rtsp_session: rtsp server type '%s' not supported yet. sorry.\n"), server);
+ session_abort:
rtsp_close(rtsp_session->s);
free(server);
xine_buffer_free(rtsp_session->recv);
@@ -164,29 +174,29 @@ connect:
return NULL;
}
free(server);
-
+
return rtsp_session;
}
void rtsp_session_set_start_time (rtsp_session_t *this, int start_time) {
-
+
if (start_time >= 0)
this->start_time = start_time;
}
static void rtsp_session_play (rtsp_session_t *this) {
-
+
char buf[256];
-
- snprintf (buf, sizeof(buf), "Range: npt=%d.%03d-",
+
+ snprintf (buf, sizeof(buf), "Range: npt=%d.%03d-",
this->start_time/1000, this->start_time%1000);
-
+
rtsp_schedule_field (this->s, buf);
rtsp_request_play (this->s,NULL);
}
int rtsp_session_read (rtsp_session_t *this, char *data, int len) {
-
+
int to_copy;
char *dest=data;
char *source=this->recv + this->recv_read;
@@ -194,22 +204,22 @@ int rtsp_session_read (rtsp_session_t *this, char *data, int len) {
if (len < 0)
return 0;
-
+
if (this->header_left) {
if (len > this->header_left)
len = this->header_left;
-
+
this->header_left -= len;
}
-
+
to_copy = len;
while (to_copy > fill) {
-
+
if (!this->playing) {
rtsp_session_play (this);
this->playing = 1;
}
-
+
memcpy(dest, source, fill);
to_copy -= fill;
dest += fill;
@@ -224,7 +234,7 @@ int rtsp_session_read (rtsp_session_t *this, char *data, int len) {
return len-to_copy;
}
}
-
+
memcpy(dest, source, to_copy);
this->recv_read += to_copy;
diff --git a/src/input/librtsp/rtsp_session.h b/src/input/librtsp/rtsp_session.h
index b47db0730..33ac579e1 100644
--- a/src/input/librtsp/rtsp_session.h
+++ b/src/input/librtsp/rtsp_session.h
@@ -25,7 +25,7 @@
typedef struct rtsp_session_s rtsp_session_t;
-rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl);
+rtsp_session_t *rtsp_session_start(xine_stream_t *stream, char *mrl) XINE_MALLOC;
void rtsp_session_set_start_time(rtsp_session_t *this, int start_time);
diff --git a/src/input/media_helper.c b/src/input/media_helper.c
index 288ed4205..e19ca63e6 100644
--- a/src/input/media_helper.c
+++ b/src/input/media_helper.c
@@ -1,18 +1,18 @@
-/*
- * Copyright (C) 2000-2003 the xine project,
- *
+/*
+ * Copyright (C) 2000-2003 the xine project,
+ *
* 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
@@ -66,14 +66,14 @@ static int media_umount_media(const char *device)
if(waitpid(pid, &status, 0) == -1) {
if (errno != EINTR)
return -1;
- }
+ }
else {
return WEXITSTATUS(status);
}
} while(1);
-
+
return -1;
-}
+}
#endif
int media_eject_media (xine_t *xine, const char *device)
@@ -91,7 +91,7 @@ int media_eject_media (xine_t *xine, const char *device)
return 0;
-#else
+#else
int fd;
@@ -109,14 +109,14 @@ int media_eject_media (xine_t *xine, const char *device)
case CDS_TRAY_OPEN:
if((ret = ioctl(fd, CDROMCLOSETRAY)) != 0) {
#ifdef LOG_MEDIA_EJECT
- printf("input_dvd: CDROMCLOSETRAY failed: %s\n", strerror(errno));
+ printf("input_dvd: CDROMCLOSETRAY failed: %s\n", strerror(errno));
#endif
}
break;
case CDS_DISC_OK:
if((ret = ioctl(fd, CDROMEJECT)) != 0) {
#ifdef LOG_MEDIA_EJECT
- printf("input_dvd: CDROMEJECT failed: %s\n", strerror(errno));
+ printf("input_dvd: CDROMEJECT failed: %s\n", strerror(errno));
#endif
}
break;
diff --git a/src/input/mms.c b/src/input/mms.c
index f11a89cf3..c84ce7beb 100644
--- a/src/input/mms.c
+++ b/src/input/mms.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2002-2004 the xine project
- *
+ *
* 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
@@ -54,7 +54,7 @@
#define LOG_MODULE "mms"
#define LOG_VERBOSE
/*
-#define LOG
+#define LOG
*/
#include "xine_internal.h"
#include "xineutils.h"
@@ -65,8 +65,8 @@
#include "../demuxers/asfheader.h"
-/*
- * mms specific types
+/*
+ * mms specific types
*/
#define MMST_PORT 1755
@@ -107,9 +107,9 @@ struct mms_packet_header_s {
struct mms_s {
xine_stream_t *stream;
-
+
int s;
-
+
/* url parsing */
char *url;
char *proto;
@@ -123,12 +123,12 @@ struct mms_s {
char scmd[CMD_HEADER_LEN + CMD_BODY_LEN];
char *scmd_body; /* pointer to &scmd[CMD_HEADER_LEN] */
int scmd_len; /* num bytes written in header */
-
+
/* receive buffer */
uint8_t buf[BUF_SIZE];
int buf_size;
int buf_read;
-
+
asf_header_t *asf_header;
uint8_t asf_header_buffer[ASF_HEADER_LEN];
uint32_t asf_header_len;
@@ -137,13 +137,13 @@ struct mms_s {
int seq_num;
char guid[37];
int bandwidth;
-
+
off_t current_pos;
int eos;
uint8_t live_flag;
-
- uint8_t playing;
+
+ uint8_t playing;
double start_time;
};
@@ -202,9 +202,9 @@ static void mms_buffer_put_64 (mms_buffer_t *mms_buffer, uint64_t value) {
}
+#ifdef LOG
static void print_command (char *data, int len) {
-#ifdef LOG
int i;
int dir = _X_LE_32 (data + 36) >> 16;
int comm = _X_LE_32 (data + 36) & 0xFFFF;
@@ -230,18 +230,20 @@ static void print_command (char *data, int len) {
for (i = (CMD_HEADER_LEN + CMD_PREFIX_LEN); i < (CMD_HEADER_LEN + CMD_PREFIX_LEN + len); i += 1) {
unsigned char c = data[i];
-
+
if ((c >= 32) && (c < 128))
printf ("%c", c);
else
printf (" %02x ", c);
-
+
}
if (len > CMD_HEADER_LEN)
printf ("\n");
printf ("----------------------------------------------\n");
+}
+#else
+# define print_command(data, len)
#endif
-}
@@ -269,7 +271,7 @@ static int send_command (mms_t *this, int command,
mms_buffer_put_32 (&command_buffer, len8 + 2);
mms_buffer_put_32 (&command_buffer, 0x00030000 | command); /* dir | command */
/* end of the 40 byte command header */
-
+
mms_buffer_put_32 (&command_buffer, prefix1);
mms_buffer_put_32 (&command_buffer, prefix2);
@@ -288,7 +290,7 @@ static int send_command (mms_t *this, int command,
#ifdef USE_ICONV
static iconv_t string_utf16_open() {
- return iconv_open("UTF-16LE", nl_langinfo(CODESET));
+ return iconv_open("UTF-16LE", "UTF-8");
}
static void string_utf16_close(iconv_t url_conv) {
@@ -352,14 +354,14 @@ static int get_packet_header (mms_t *this, mms_packet_header_t *header) {
len = _x_io_tcp_read (this->stream, this->s, (char*)this->buf, 8);
if (len != 8)
goto error;
-
+
if (_X_LE_32(this->buf + 4) == 0xb00bface) {
/* command packet */
header->flags = this->buf[3];
len = _x_io_tcp_read (this->stream, this->s, (char*)(this->buf + 8), 4);
if (len != 4)
goto error;
-
+
header->packet_len = _X_LE_32(this->buf + 8) + 4;
if (header->packet_len > BUF_SIZE - 12) {
header->packet_len = 0;
@@ -381,7 +383,7 @@ static int get_packet_header (mms_t *this, mms_packet_header_t *header) {
}
}
return packet_type;
-
+
error:
lprintf("read error, len=%zd\n", len);
return MMS_PACKET_ERR;
@@ -393,7 +395,7 @@ static int get_packet_command (mms_t *this, uint32_t packet_len) {
int command = 0;
size_t len;
-
+
/* always enter this loop */
lprintf("packet_len: %d bytes\n", packet_len);
@@ -403,18 +405,18 @@ static int get_packet_command (mms_t *this, uint32_t packet_len) {
}
print_command ((char*)this->buf, len);
-
+
/* check protocol type ("MMS ") */
if (_X_LE_32(this->buf + 12) != 0x20534D4D) {
lprintf("unknown protocol type: %c%c%c%c (0x%08X)\n",
this->buf[12], this->buf[13], this->buf[14], this->buf[15],
- _X_LE_32(this->buf + 12));
+ _X_LE_32(this->buf + 12));
return 0;
}
command = _X_LE_32 (this->buf + 36) & 0xFFFF;
lprintf("command = 0x%2x\n", command);
-
+
return command;
}
@@ -429,9 +431,9 @@ static int get_answer (mms_t *this) {
break;
case MMS_PACKET_COMMAND:
command = get_packet_command (this, header.packet_len);
-
+
if (command == 0x1b) {
-
+
if (!send_command (this, 0x1b, 0, 0, 0)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"libmms: failed to send command\n");
@@ -450,7 +452,7 @@ static int get_answer (mms_t *this) {
"libmms: unexpected asf packet\n");
break;
}
-
+
return command;
}
@@ -459,7 +461,7 @@ static int get_asf_header (mms_t *this) {
off_t len;
int stop = 0;
-
+
this->asf_header_read = 0;
this->asf_header_len = 0;
@@ -475,9 +477,9 @@ static int get_asf_header (mms_t *this) {
break;
case MMS_PACKET_COMMAND:
command = get_packet_command (this, header.packet_len);
-
+
if (command == 0x1b) {
-
+
if (!send_command (this, 0x1b, 0, 0, 0)) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"libmms: failed to send command\n");
@@ -558,11 +560,11 @@ static void report_progress (xine_stream_t *stream, int p) {
prg.description = _("Connecting MMS server (over tcp)...");
prg.percent = p;
-
+
event.type = XINE_EVENT_PROGRESS;
event.data = &prg;
event.data_length = sizeof (xine_progress_data_t);
-
+
xine_event_send (stream, &event);
}
@@ -572,11 +574,11 @@ static void report_progress (xine_stream_t *stream, int p) {
*/
static int mms_tcp_connect(mms_t *this) {
int progress, res;
-
+
if (!this->port) this->port = MMST_PORT;
- /*
- * try to connect
+ /*
+ * try to connect
*/
lprintf("try to connect to %s on port %d \n", this->host, this->port);
this->s = _x_io_tcp_connect (this->stream, this->host, this->port);
@@ -624,7 +626,7 @@ static int mms_choose_best_streams(mms_t *this) {
/* choose the best quality for the audio stream */
asf_header_choose_streams (this->asf_header, this->bandwidth, &video_stream, &audio_stream);
-
+
lprintf("selected streams: audio %d, video %d\n", audio_stream, video_stream);
lprintf("disabling other streams\n");
memset (this->scmd_body, 0, 40);
@@ -645,8 +647,8 @@ static int mms_choose_best_streams(mms_t *this) {
}
/* command 0x33 */
- if (!send_command (this, 0x33, this->asf_header->stream_count,
- 0xFFFF | this->asf_header->streams[0]->stream_number << 16,
+ if (!send_command (this, 0x33, this->asf_header->stream_count,
+ 0xFFFF | this->asf_header->streams[0]->stream_number << 16,
this->asf_header->stream_count * 6 + 2)) {
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
"libmms: mms_choose_best_streams failed\n");
@@ -674,11 +676,11 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
mms_t *this;
char str[1024];
int res;
-
+
if (!url)
return NULL;
- this = (mms_t*) xine_xmalloc (sizeof (mms_t));
+ this = calloc(1, sizeof (mms_t));
this->stream = stream;
this->url = strdup (url);
@@ -694,23 +696,23 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
this->eos = 0;
report_progress (stream, 0);
-
+
if (!_x_parse_url (this->url, &this->proto, &this->host, &this->port,
- &this->user, &this->password, &this->uri)) {
+ &this->user, &this->password, &this->uri, NULL)) {
lprintf ("invalid url\n");
goto fail;
}
-
+
if (!mmst_valid_proto(this->proto)) {
lprintf ("unsupported protocol\n");
goto fail;
}
-
+
if (mms_tcp_connect(this)) {
goto fail;
}
report_progress (stream, 30);
-
+
#ifdef USE_ICONV
url_conv = string_utf16_open();
#endif
@@ -730,13 +732,13 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
"libmms: failed to send command 0x01\n");
goto fail;
}
-
+
if ((res = get_answer (this)) != 0x01) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"libmms: unexpected response: %02x (0x01)\n", res);
goto fail;
}
-
+
report_progress (stream, 40);
/* TODO: insert network timing request here */
@@ -769,32 +771,38 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
/* command 0x5 */
{
mms_buffer_t command_buffer;
- char *path;
- int pathlen;
+ char *path, *unescaped;
+ size_t pathlen;
+
+ unescaped = strdup (this->uri);
+ if (!unescaped)
+ goto fail;
+ _x_mrl_unescape (unescaped);
/* remove the first '/' */
- path = this->uri;
- pathlen = strlen(path);
+ path = unescaped;
+ pathlen = strlen (path);
if (pathlen > 1) {
path++;
pathlen--;
}
-
+
lprintf("send command 0x05\n");
mms_buffer_init(&command_buffer, this->scmd_body);
mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */
mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */
string_utf16 (url_conv, this->scmd_body + command_buffer.pos, path, pathlen);
+ free (unescaped);
if (!send_command (this, 5, 1, 0xffffffff, pathlen * 2 + 12))
goto fail;
}
-
+
switch (res = get_answer (this)) {
case 0x06:
{
int xx, yy;
/* no authentication required */
-
+
/* Warning: sdp is not right here */
xx = this->buf[62];
yy = this->buf[63];
@@ -837,7 +845,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
goto fail;
}
}
-
+
if ((res = get_answer (this)) != 0x11) {
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
"libmms: unexpected response: %02x (0x11)\n", res);
@@ -890,7 +898,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
#endif
lprintf("mms_connect: passed\n" );
-
+
return this;
fail:
@@ -916,19 +924,19 @@ fail:
static int get_media_packet (mms_t *this) {
mms_packet_header_t header;
off_t len;
-
+
switch (get_packet_header (this, &header)) {
case MMS_PACKET_ERR:
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
"libmms: failed to read mms packet header\n");
return 0;
break;
-
+
case MMS_PACKET_COMMAND:
{
int command;
command = get_packet_command (this, header.packet_len);
-
+
switch (command) {
case 0x1e:
{
@@ -942,10 +950,10 @@ static int get_media_packet (mms_t *this) {
this->eos = 1;
return 0;
}
-
+
}
break;
-
+
case 0x20:
{
lprintf ("new stream.\n");
@@ -968,7 +976,7 @@ static int get_media_packet (mms_t *this) {
mms_buffer_t command_buffer;
mms_buffer_init(&command_buffer, this->scmd_body);
mms_buffer_put_32 (&command_buffer, 0x00000000); /* 64 byte float timestamp */
- mms_buffer_put_32 (&command_buffer, 0x00000000);
+ mms_buffer_put_32 (&command_buffer, 0x00000000);
mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */
mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */
mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */
@@ -995,10 +1003,10 @@ static int get_media_packet (mms_t *this) {
}
}
break;
-
+
case 0x05:
break;
-
+
default:
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
"unexpected mms command %02x\n", command);
@@ -1039,7 +1047,7 @@ static int get_media_packet (mms_t *this) {
}
break;
}
-
+
lprintf ("get media packet succ\n");
return 1;
@@ -1077,13 +1085,13 @@ int mms_read (mms_t *this, char *data, int len) {
this->asf_header_read += n;
total += n;
this->current_pos += n;
-
+
if (this->asf_header_read == this->asf_header_len)
break;
} else {
int n, bytes_left ;
-
+
if (!this->playing) {
/* send command 0x07 with initial timestamp */
mms_buffer_t command_buffer;
diff --git a/src/input/mms.h b/src/input/mms.h
index a483fa0c6..eaf9a46f4 100644
--- a/src/input/mms.h
+++ b/src/input/mms.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2002-2003 the xine project
- *
+ *
* 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
diff --git a/src/input/mmsh.c b/src/input/mmsh.c
index ae1c62bc1..de2d6ebab 100644
--- a/src/input/mmsh.c
+++ b/src/input/mmsh.c
@@ -138,8 +138,8 @@
#endif
-/*
- * mmsh specific types
+/*
+ * mmsh specific types
*/
@@ -161,10 +161,10 @@ struct mmsh_s {
char str[SCRATCH_SIZE]; /* scratch buffer to built strings */
asf_header_t *asf_header;
- int stream_type;
+ int stream_type;
/* receive buffer */
-
+
/* chunk */
uint16_t chunk_type;
uint16_t chunk_length;
@@ -178,23 +178,21 @@ struct mmsh_s {
uint32_t asf_header_len;
uint32_t asf_header_read;
int seq_num;
-
+
int video_stream;
int audio_stream;
off_t current_pos;
int user_bandwidth;
-
+
int playing;
unsigned int start_time;
};
static int send_command (mmsh_t *this, char *cmd) {
- int length;
-
lprintf ("send_command:\n%s\n", cmd);
- length = strlen(cmd);
+ const size_t length = strlen(cmd);
if (_x_io_tcp_write(this->stream, this->s, cmd, length) != length) {
xprintf (this->stream->xine, XINE_LOG_MSG, _("libmmsh: send error\n"));
return 0;
@@ -203,7 +201,7 @@ static int send_command (mmsh_t *this, char *cmd) {
}
static int get_answer (mmsh_t *this) {
-
+
int done, len, linenum;
char *features;
@@ -224,14 +222,14 @@ static int get_answer (mmsh_t *this) {
this->buf[len] = '\0';
len--;
-
+
if ((len >= 0) && (this->buf[len] == '\015')) {
this->buf[len] = '\0';
len--;
}
linenum++;
-
+
lprintf ("answer: >%s<\n", this->buf);
if (linenum == 1) {
@@ -265,7 +263,7 @@ static int get_answer (mmsh_t *this) {
_("libmmsh: Location redirection not implemented\n"));
return 0;
}
-
+
if (!strncasecmp((char*)this->buf, "Pragma:", 7)) {
features = strstr((char*)(this->buf + 7), "features=");
if (features) {
@@ -281,7 +279,7 @@ static int get_answer (mmsh_t *this) {
}
}
}
-
+
if (len == -1) {
done = 1;
} else {
@@ -316,7 +314,7 @@ static int get_chunk_header (mmsh_t *this) {
}
this->chunk_type = _X_LE_16 (&chunk_header[0]);
this->chunk_length = _X_LE_16 (&chunk_header[2]);
-
+
switch (this->chunk_type) {
case CHUNK_TYPE_DATA:
ext_header_len = 8;
@@ -342,7 +340,7 @@ static int get_chunk_header (mmsh_t *this) {
return 0;
}
}
-
+
switch (this->chunk_type) {
case CHUNK_TYPE_DATA:
this->chunk_seq_number = _X_LE_32 (&ext_header[0]);
@@ -386,7 +384,7 @@ static int get_header (mmsh_t *this) {
lprintf("get_header\n");
this->asf_header_len = 0;
-
+
/* read chunk */
while (1) {
if (get_chunk_header(this)) {
@@ -486,11 +484,11 @@ static void report_progress (xine_stream_t *stream, int p) {
*/
static int mmsh_tcp_connect(mmsh_t *this) {
int progress, res;
-
+
if (!this->port) this->port = MMSH_PORT;
-
- /*
- * try to connect
+
+ /*
+ * try to connect
*/
lprintf("try to connect to %s on port %d \n", this->host, this->port);
@@ -524,24 +522,24 @@ static int mmsh_connect_int(mmsh_t *this, int bandwidth) {
/*
* let the negotiations begin...
*/
-
+
/* first request */
lprintf("first http request\n");
-
+
snprintf (this->str, SCRATCH_SIZE, mmsh_FirstRequest, this->uri,
this->host, this->port, 1);
if (!send_command (this, this->str))
return 0;
- if (!get_answer (this))
+ if (!get_answer (this))
return 0;
get_header (this); /* FIXME: it returns 0 */
if (!interp_header (this))
return 0;
-
+
close (this->s);
report_progress (this->stream, 20);
@@ -550,13 +548,13 @@ static int mmsh_connect_int(mmsh_t *this, int bandwidth) {
lprintf("audio stream %d, video stream %d\n",
this->audio_stream, this->video_stream);
-
+
asf_header_disable_streams (this->asf_header,
this->video_stream, this->audio_stream);
-
+
if (mmsh_tcp_connect(this))
return 0;
-
+
return 1;
}
@@ -567,7 +565,7 @@ static int mmsh_connect_int2(mmsh_t *this, int bandwidth) {
int i;
char stream_selection[10 * ASF_MAX_NUM_STREAMS]; /* 10 chars per stream */
int offset;
-
+
/* second request */
lprintf("second http request\n");
@@ -608,7 +606,7 @@ static int mmsh_connect_int2(mmsh_t *this, int bandwidth) {
if (!send_command (this, this->str))
return 0;
-
+
lprintf("before read \n");
if (!get_answer (this))
@@ -616,11 +614,11 @@ static int mmsh_connect_int2(mmsh_t *this, int bandwidth) {
if (!get_header (this))
return 0;
-
+
#if 0
if (!interp_header (this))
return 0;
-
+
asf_header_disable_streams (this->asf_header,
this->video_stream, this->audio_stream);
#endif
@@ -630,13 +628,13 @@ static int mmsh_connect_int2(mmsh_t *this, int bandwidth) {
mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) {
mmsh_t *this;
-
+
if (!url)
return NULL;
report_progress (stream, 0);
- this = (mmsh_t*) xine_xmalloc (sizeof (mmsh_t));
+ this = calloc(1, sizeof (mmsh_t));
this->stream = stream;
this->url = strdup(url);
@@ -649,28 +647,28 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) {
this->user_bandwidth = bandwidth;
report_progress (stream, 0);
-
+
if (!_x_parse_url (this->url, &this->proto, &this->host, &this->port,
- &this->user, &this->password, &this->uri)) {
+ &this->user, &this->password, &this->uri, NULL)) {
xine_log (this->stream->xine, XINE_LOG_MSG, _("invalid url\n"));
goto fail;
}
-
+
if (!mmsh_valid_proto(this->proto)) {
xine_log (this->stream->xine, XINE_LOG_MSG, _("unsupported protocol\n"));
goto fail;
}
-
+
if (mmsh_tcp_connect(this))
goto fail;
-
+
report_progress (stream, 30);
if (!mmsh_connect_int(this, this->user_bandwidth))
goto fail;
report_progress (stream, 100);
-
+
lprintf("mmsh_connect: passed\n" );
return this;
@@ -719,7 +717,7 @@ static int get_media_packet (mmsh_t *this) {
*/
if (this->chunk_seq_number == 0)
return 0;
-
+
close(this->s);
if (mmsh_tcp_connect(this))
@@ -727,20 +725,20 @@ static int get_media_packet (mmsh_t *this) {
if (!mmsh_connect_int(this, this->user_bandwidth))
return 0;
-
+
this->playing = 0;
/* mmsh_connect_int reads the first data packet */
- /* this->buf_size is set by mmsh_connect_int */
+ /* this->buf_size is set by mmsh_connect_int */
return 2;
case CHUNK_TYPE_DATA:
/* nothing to do */
break;
-
+
case CHUNK_TYPE_RESET:
/* next chunk is an ASF header */
-
+
if (this->chunk_length != 0) {
/* that's strange, don't know what to do */
return 0;
@@ -749,7 +747,7 @@ static int get_media_packet (mmsh_t *this) {
return 0;
interp_header(this);
return 2;
-
+
default:
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
"libmmsh: unexpected chunk type\n");
@@ -757,7 +755,7 @@ static int get_media_packet (mmsh_t *this) {
}
len = _x_io_tcp_read (this->stream, this->s, (char*)this->buf, this->chunk_length);
-
+
if (len == this->chunk_length) {
/* explicit padding with 0 */
if (this->chunk_length > this->asf_header->file->packet_size) {
@@ -814,13 +812,13 @@ int mmsh_read (mmsh_t *this, char *data, int len) {
this->asf_header_read += n;
total += n;
this->current_pos += n;
-
+
if (this->asf_header_read == this->asf_header_len)
- break;
+ break;
} else {
int n, bytes_left ;
-
+
if (!this->playing) {
if (!mmsh_connect_int2 (this, this->user_bandwidth))
break;
diff --git a/src/input/mmsh.h b/src/input/mmsh.h
index 633d3b5f6..09b305adb 100644
--- a/src/input/mmsh.h
+++ b/src/input/mmsh.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2002-2003 the xine project
- *
+ *
* 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
diff --git a/src/input/net_buf_ctrl.c b/src/input/net_buf_ctrl.c
index 624af4081..bd0e5ce13 100644
--- a/src/input/net_buf_ctrl.c
+++ b/src/input/net_buf_ctrl.c
@@ -118,9 +118,9 @@ void nbc_check_buffers (nbc_t *this) {
}
static void display_stats (nbc_t *this) {
- const char *buffering[2] = {" ", "buf"};
- const char *enabled[2] = {"off", "on "};
-
+ const char buffering[2][4] = {" ", "buf"};
+ const char enabled[2][4] = {"off", "on "};
+
printf("bufing: %d, enb: %d\n", this->buffering, this->enabled);
printf("net_buf_ctrl: vid %3d%% %4.1fs %4" PRId64 "kbps %1d, "\
"aud %3d%% %4.1fs %4" PRId64 "kbps %1d, %s %s\r",
@@ -168,7 +168,7 @@ static void nbc_compute_fifo_length(nbc_t *this,
this->video_fifo_free = fifo_free;
this->video_fifo_fill = (100 * fifo_fill) / fifo_div;
this->video_fifo_size = fifo->fifo_data_size;
-
+
if (buf->pts && (this->video_in_disc == 0)) {
if (action == FIFO_PUT) {
this->video_last_pts = buf->pts;
@@ -180,7 +180,7 @@ static void nbc_compute_fifo_length(nbc_t *this,
this->video_first_pts = buf->pts;
}
}
-
+
if (video_br) {
this->video_br = video_br;
this->video_fifo_length_int = (8000 * this->video_fifo_size) / this->video_br;
@@ -201,7 +201,7 @@ static void nbc_compute_fifo_length(nbc_t *this,
this->audio_fifo_free = fifo_free;
this->audio_fifo_fill = (100 * fifo_fill) / fifo_div;
this->audio_fifo_size = fifo->fifo_data_size;
-
+
if (buf->pts && (this->audio_in_disc == 0)) {
if (action == FIFO_PUT) {
this->audio_last_pts = buf->pts;
@@ -213,7 +213,7 @@ static void nbc_compute_fifo_length(nbc_t *this,
this->audio_first_pts = buf->pts;
}
}
-
+
if (audio_br) {
this->audio_br = audio_br;
this->audio_fifo_length_int = (8000 * this->audio_fifo_size) / this->audio_br;
@@ -230,7 +230,7 @@ static void nbc_compute_fifo_length(nbc_t *this,
}
}
}
-
+
/* decoder buffer compensation */
if (has_audio && has_video) {
diff = this->video_first_pts - this->audio_first_pts;
@@ -271,7 +271,7 @@ static void nbc_alloc_cb (fifo_buffer_t *fifo, void *this_gen) {
/* Put callback
* the fifo mutex is locked */
-static void nbc_put_cb (fifo_buffer_t *fifo,
+static void nbc_put_cb (fifo_buffer_t *fifo,
buf_element_t *buf, void *this_gen) {
nbc_t *this = (nbc_t*)this_gen;
int64_t progress = 0;
@@ -285,7 +285,7 @@ static void nbc_put_cb (fifo_buffer_t *fifo,
if ((buf->type & BUF_MAJOR_MASK) != BUF_CONTROL_BASE) {
if (this->enabled) {
-
+
nbc_compute_fifo_length(this, fifo, buf, FIFO_PUT);
if (this->buffering) {
@@ -311,8 +311,8 @@ static void nbc_put_cb (fifo_buffer_t *fifo,
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl: nbc_put_cb: stops buffering\n");
nbc_set_speed_normal(this);
-
- this->high_water_mark += this->high_water_mark / 2;
+
+ this->high_water_mark += this->high_water_mark / 2;
} else {
/* compute the buffering progress
@@ -439,7 +439,7 @@ static void nbc_get_cb (fifo_buffer_t *fifo,
if (this->enabled) {
nbc_compute_fifo_length(this, fifo, buf, FIFO_GET);
-
+
if (!this->buffering) {
/* start buffering if one fifo is empty
*/
@@ -454,7 +454,7 @@ static void nbc_get_cb (fifo_buffer_t *fifo,
this->progress = 0;
report_progress (this->stream, 0);
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"\nnet_buf_ctrl: nbc_get_cb: starts buffering, vid: %d, aud: %d\n",
this->video_fifo_fill, this->audio_fifo_fill);
nbc_set_speed_pause(this);
@@ -495,8 +495,8 @@ static void nbc_get_cb (fifo_buffer_t *fifo,
}
nbc_t *nbc_init (xine_stream_t *stream) {
-
- nbc_t *this = (nbc_t *) xine_xmalloc (sizeof (nbc_t));
+
+ nbc_t *this = calloc(1, sizeof (nbc_t));
fifo_buffer_t *video_fifo = stream->video_fifo;
fifo_buffer_t *audio_fifo = stream->audio_fifo;
double video_fifo_factor, audio_fifo_factor;
@@ -508,7 +508,7 @@ nbc_t *nbc_init (xine_stream_t *stream) {
this->stream = stream;
this->video_fifo = video_fifo;
this->audio_fifo = audio_fifo;
-
+
/* when the FIFO sizes are increased compared to the default configuration,
* apply a factor to the high water mark */
entry = stream->xine->config->lookup_entry(stream->xine->config, "engine.buffers.video_num_buffers");
diff --git a/src/input/net_buf_ctrl.h b/src/input/net_buf_ctrl.h
index 79f698008..6eac63e52 100644
--- a/src/input/net_buf_ctrl.h
+++ b/src/input/net_buf_ctrl.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2000-2003 the xine project
- *
+ *
* 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
@@ -27,14 +27,14 @@
typedef struct nbc_s nbc_t;
-nbc_t *nbc_init (xine_stream_t *xine);
+nbc_t *nbc_init (xine_stream_t *xine) XINE_MALLOC;
-void nbc_check_buffers (nbc_t *this);
+void nbc_check_buffers (nbc_t *this) XINE_DEPRECATED;
void nbc_close (nbc_t *this);
-void nbc_set_high_water_mark(nbc_t *this, int value);
+void nbc_set_high_water_mark(nbc_t *this, int value) XINE_DEPRECATED;
-void nbc_set_low_water_mark(nbc_t *this, int value);
+void nbc_set_low_water_mark(nbc_t *this, int value) XINE_DEPRECATED;
#endif
diff --git a/src/input/pnm.c b/src/input/pnm.c
index 38d65b850..bf24e5f8f 100644
--- a/src/input/pnm.c
+++ b/src/input/pnm.c
@@ -17,10 +17,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
- * pnm protocol implementation
+ * pnm protocol implementation
* based upon code from joschka
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
@@ -90,7 +94,7 @@ struct pnm_s {
/* header of rm files */
#define RM_HEADER_SIZE 0x12
-const unsigned char rm_header[]={
+static const unsigned char rm_header[]={
0x2e, 0x52, 0x4d, 0x46, /* object_id ".RMF" */
0x00, 0x00, 0x00, 0x12, /* header_size 0x12 */
0x00, 0x00, /* object_version 0x00 */
@@ -100,7 +104,7 @@ const unsigned char rm_header[]={
/* data chunk header */
#define PNM_DATA_HEADER_SIZE 18
-const unsigned char pnm_data_header[]={
+static const unsigned char pnm_data_header[]={
'D','A','T','A',
0,0,0,0, /* data chunk size */
0,0, /* object version */
@@ -140,26 +144,26 @@ static const unsigned char pnm_header[] = {
#define PNM_CLIENT_CAPS_SIZE 126
static const unsigned char pnm_client_caps[] = {
- 0x07, 0x8a, 'p','n','r','v',
- 0, 0x90, 'p','n','r','v',
- 0, 0x64, 'd','n','e','t',
- 0, 0x46, 'p','n','r','v',
- 0, 0x32, 'd','n','e','t',
- 0, 0x2b, 'p','n','r','v',
- 0, 0x28, 'd','n','e','t',
- 0, 0x24, 'p','n','r','v',
- 0, 0x19, 'd','n','e','t',
- 0, 0x18, 'p','n','r','v',
- 0, 0x14, 's','i','p','r',
- 0, 0x14, 'd','n','e','t',
- 0, 0x24, '2','8','_','8',
- 0, 0x12, 'p','n','r','v',
- 0, 0x0f, 'd','n','e','t',
- 0, 0x0a, 's','i','p','r',
- 0, 0x0a, 'd','n','e','t',
- 0, 0x08, 's','i','p','r',
- 0, 0x06, 's','i','p','r',
- 0, 0x12, 'l','p','c','J',
+ 0x07, 0x8a, 'p','n','r','v',
+ 0, 0x90, 'p','n','r','v',
+ 0, 0x64, 'd','n','e','t',
+ 0, 0x46, 'p','n','r','v',
+ 0, 0x32, 'd','n','e','t',
+ 0, 0x2b, 'p','n','r','v',
+ 0, 0x28, 'd','n','e','t',
+ 0, 0x24, 'p','n','r','v',
+ 0, 0x19, 'd','n','e','t',
+ 0, 0x18, 'p','n','r','v',
+ 0, 0x14, 's','i','p','r',
+ 0, 0x14, 'd','n','e','t',
+ 0, 0x24, '2','8','_','8',
+ 0, 0x12, 'p','n','r','v',
+ 0, 0x0f, 'd','n','e','t',
+ 0, 0x0a, 's','i','p','r',
+ 0, 0x0a, 'd','n','e','t',
+ 0, 0x08, 's','i','p','r',
+ 0, 0x06, 's','i','p','r',
+ 0, 0x12, 'l','p','c','J',
0, 0x07, '0','5','_','6' };
static const uint32_t pnm_default_bandwidth=10485800;
@@ -175,7 +179,7 @@ static const unsigned char pnm_twentyfour[]={
static const int after_chunks_length=6;
static const unsigned char after_chunks[]={
0x00, 0x00, /* mark */
-
+
0x50, 0x84, /* seems to be fixated */
0x1f, 0x3a /* varies on each request (checksum ?)*/
};
@@ -197,7 +201,7 @@ static const unsigned char after_chunks[]={
* if we have an PNA_TAG, we need a different parsing; see below.
*/
-static unsigned int pnm_get_chunk(pnm_t *p,
+static unsigned int pnm_get_chunk(pnm_t *p,
unsigned int max,
unsigned int *chunk_type,
char *data, int *need_response) {
@@ -208,7 +212,7 @@ static unsigned int pnm_get_chunk(pnm_t *p,
if( max < PREAMBLE_SIZE )
return -1;
-
+
/* get first PREAMBLE_SIZE bytes and ignore checksum */
_x_io_tcp_read (p->stream, p->s, data, CHECKSUM_SIZE);
if (data[0] == 0x72)
@@ -217,7 +221,7 @@ static unsigned int pnm_get_chunk(pnm_t *p,
_x_io_tcp_read (p->stream, p->s, data+CHECKSUM_SIZE, PREAMBLE_SIZE-CHECKSUM_SIZE);
max -= PREAMBLE_SIZE;
-
+
*chunk_type = be2me_32(*((uint32_t *)data));
chunk_size = be2me_32(*((uint32_t *)(data+4)));
@@ -233,10 +237,10 @@ static unsigned int pnm_get_chunk(pnm_t *p,
while(1) {
/* The pna chunk is devided into subchunks.
- * expecting following chunk format (in big endian):
- * 0x4f
- * uint8_t chunk_size
- * uint8_t data[chunk_size]
+ * expecting following chunk format (in big endian):
+ * 0x4f
+ * uint8_t chunk_size
+ * uint8_t data[chunk_size]
*
* if first byte is 'X', we got a message from server
* if first byte is 'F', we got an error
@@ -246,7 +250,7 @@ static unsigned int pnm_get_chunk(pnm_t *p,
return -1;
_x_io_tcp_read (p->stream, p->s, ptr, 2);
max -= 2;
-
+
if (*ptr == 'X') /* checking for server message */
{
xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: got a message from server:\n");
@@ -269,7 +273,7 @@ static unsigned int pnm_get_chunk(pnm_t *p,
xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "%s\n", ptr+3);
return -1;
}
-
+
if (*ptr == 'F') /* checking for server error */
{
/* some error codes after 'F' were ignored */
@@ -315,7 +319,7 @@ static unsigned int pnm_get_chunk(pnm_t *p,
break;
default:
*chunk_type = 0;
- chunk_size = PREAMBLE_SIZE;
+ chunk_size = PREAMBLE_SIZE;
break;
}
@@ -330,7 +334,7 @@ static unsigned int pnm_get_chunk(pnm_t *p,
* uint8_t data[length]
*/
-static int pnm_write_chunk(uint16_t chunk_id, uint16_t length,
+static int pnm_write_chunk(uint16_t chunk_id, uint16_t length,
const char *chunk, char *data) {
uint16_t be_id, be_len;
@@ -341,7 +345,7 @@ static int pnm_write_chunk(uint16_t chunk_id, uint16_t length,
memcpy(data , &be_id , 2);
memcpy(data+2, &be_len, 2);
memcpy(data+4, chunk , length);
-
+
return length+4;
}
@@ -379,7 +383,7 @@ static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {
pnm_guid,&p->buffer[c]);
c+=pnm_write_chunk(PNA_TWENTYFOUR,PNM_TWENTYFOUR_SIZE,
(char*)pnm_twentyfour,&p->buffer[c]);
-
+
/* data after chunks */
memcpy(&p->buffer[c],after_chunks,after_chunks_length);
c+=after_chunks_length;
@@ -402,7 +406,7 @@ static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {
/* some trailing bytes */
p->buffer[c]='y';
p->buffer[c+1]='B';
-
+
_x_io_tcp_write(p->stream,p->s,p->buffer,c+2);
}
@@ -411,8 +415,8 @@ static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {
*/
static void pnm_send_response(pnm_t *p, const char *response) {
-
- int size=strlen(response);
+ /** @TODO should check that sze is always < 256 */
+ size_t size=strlen(response);
p->buffer[0]=0x23;
p->buffer[1]=0;
@@ -472,7 +476,7 @@ static int pnm_get_headers(pnm_t *p, int *need_response) {
xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: error while parsing headers.\n");
return 0;
}
-
+
/* set data offset */
{
uint32_t be_size;
@@ -480,7 +484,7 @@ static int pnm_get_headers(pnm_t *p, int *need_response) {
be_size = be2me_32(size-1);
memcpy(prop_hdr+42, &be_size, 4);
}
-
+
/* read challenge */
memcpy (p->buffer, ptr, PREAMBLE_SIZE);
_x_io_tcp_read (p->stream, p->s, &p->buffer[PREAMBLE_SIZE], 64);
@@ -488,18 +492,18 @@ static int pnm_get_headers(pnm_t *p, int *need_response) {
/* now write a data header */
memcpy(ptr, pnm_data_header, PNM_DATA_HEADER_SIZE);
size+=PNM_DATA_HEADER_SIZE;
-/*
+/*
h=rmff_scan_header(p->header);
rmff_fix_header(h);
p->header_len=rmff_get_header_size(h);
rmff_dump_header(h, p->header, HEADER_SIZE);
*/
p->header_len=size;
-
+
return 1;
}
-/*
+/*
* determine correct stream number by looking at indices
* FIXME: this doesn't work with all streams! There must be
* another way to determine correct stream numbers!
@@ -565,7 +569,7 @@ static int pnm_calc_stream(pnm_t *p) {
return 0;
break;
}
- xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pnm: wow, something very nasty happened in pnm_calc_stream\n");
return 2;
}
@@ -582,7 +586,7 @@ static int pnm_get_stream_chunk(pnm_t *p) {
/* send a keepalive */
/* realplayer seems to do that every 43th package */
- if ((p->packet%43) == 42)
+ if ((p->packet%43) == 42)
{
_x_io_tcp_write(p->stream,p->s,&keepalive,1);
}
@@ -592,10 +596,10 @@ static int pnm_get_stream_chunk(pnm_t *p) {
* <i1> is a 16 bit index (big endian)
* <i2> is a 8 bit index which counts from 0x10 to somewhere
*/
-
+
n = _x_io_tcp_read (p->stream, p->s, p->buffer, 8);
if (n<8) return 0;
-
+
/* skip 8 bytes if 0x62 is read */
if (p->buffer[0] == 0x62)
{
@@ -603,7 +607,7 @@ static int pnm_get_stream_chunk(pnm_t *p) {
if (n<8) return 0;
lprintf("had to seek 8 bytes on 0x62\n");
}
-
+
/* a server message */
if (p->buffer[0] == 'X')
{
@@ -611,7 +615,7 @@ static int pnm_get_stream_chunk(pnm_t *p) {
_x_io_tcp_read (p->stream, p->s, &p->buffer[8], size-5);
p->buffer[size+3]=0;
- xprintf(p->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(p->stream->xine, XINE_VERBOSITY_LOG,
_("input_pnm: got message from server while reading stream:\n%s\n"), &p->buffer[3]);
return 0;
}
@@ -627,10 +631,7 @@ static int pnm_get_stream_chunk(pnm_t *p) {
*/
n=0;
while (p->buffer[0] != 0x5a) {
- int i;
- for (i=1; i<8; i++) {
- p->buffer[i-1]=p->buffer[i];
- }
+ memmove(p->buffer, &p->buffer[1], 8);
_x_io_tcp_read (p->stream, p->s, &p->buffer[7], 1);
n++;
}
@@ -654,14 +655,14 @@ static int pnm_get_stream_chunk(pnm_t *p) {
fof2=be2me_16(*(uint16_t*)(&p->buffer[3]));
if (fof1 != fof2)
{
- xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pnm: frame offsets are different: 0x%04x 0x%04x\n", fof1, fof2);
return 0;
}
/* get first index */
p->seq_current[0]=be2me_16(*(uint16_t*)(&p->buffer[5]));
-
+
/* now read the rest of stream chunk */
n = _x_io_tcp_read (p->stream, p->s, (char*)&p->recv[5], fof1-5);
if (n<(fof1-5)) return 0;
@@ -671,15 +672,15 @@ static int pnm_get_stream_chunk(pnm_t *p) {
/* get timestamp */
p->ts_current=be2me_32(*(uint32_t*)(&p->recv[6]));
-
+
/* get stream number */
stream=pnm_calc_stream(p);
/* saving timestamp */
p->ts_last[stream]=p->ts_current;
-
+
/* constructing a data packet header */
-
+
p->recv[0]=0; /* object version */
p->recv[1]=0;
@@ -690,7 +691,7 @@ static int pnm_get_stream_chunk(pnm_t *p) {
p->recv[4]=0; /* stream number */
p->recv[5]=stream;
-
+
p->recv[10]=p->recv[10] & 0xfe; /* streambox seems to do that... */
p->packet++;
@@ -701,22 +702,22 @@ static int pnm_get_stream_chunk(pnm_t *p) {
}
pnm_t *pnm_connect(xine_stream_t *stream, const char *mrl) {
-
+
char *mrl_ptr=strdup(mrl);
char *slash, *colon;
size_t pathbegin, hostend;
pnm_t *p;
int fd;
int need_response=0;
-
+
if (strncmp(mrl,"pnm://",6))
{
return NULL;
}
-
+
mrl_ptr+=6;
- p = xine_xmalloc(sizeof(pnm_t));
+ p = calloc(1, sizeof(pnm_t));
p->stream = stream;
p->port=7070;
p->url=strdup(mrl);
@@ -726,15 +727,13 @@ pnm_t *pnm_connect(xine_stream_t *stream, const char *mrl) {
colon=strchr(mrl_ptr,':');
if(!slash) slash=mrl_ptr+strlen(mrl_ptr)+1;
- if(!colon) colon=slash;
+ if(!colon) colon=slash;
if(colon > slash) colon=slash;
pathbegin=slash-mrl_ptr;
hostend=colon-mrl_ptr;
- p->host = malloc(sizeof(char)*hostend+1);
- strncpy(p->host, mrl_ptr, hostend);
- p->host[hostend]=0;
+ p->host = strndup(mrl_ptr, hostend);
if (pathbegin < strlen(mrl_ptr)) p->path=strdup(mrl_ptr+pathbegin+1);
if (colon != slash) {
@@ -746,7 +745,7 @@ pnm_t *pnm_connect(xine_stream_t *stream, const char *mrl) {
free(mrl_ptr-6);
lprintf("got mrl: %s %i %s\n",p->host,p->port,p->path);
-
+
fd = _x_io_tcp_connect (stream, p->host, p->port);
if (fd == -1) {
@@ -772,7 +771,7 @@ pnm_t *pnm_connect(xine_stream_t *stream, const char *mrl) {
pnm_send_response(p, pnm_response);
p->ts_last[0]=0;
p->ts_last[1]=0;
-
+
/* copy header to recv */
memcpy(p->recv, p->header, p->header_len);
@@ -783,15 +782,15 @@ pnm_t *pnm_connect(xine_stream_t *stream, const char *mrl) {
}
int pnm_read (pnm_t *this, char *data, int len) {
-
+
int to_copy=len;
char *dest=data;
char *source=(char*)(this->recv + this->recv_read);
int fill=this->recv_size - this->recv_read;
-
+
if (len < 0) return 0;
while (to_copy > fill) {
-
+
memcpy(dest, source, fill);
to_copy -= fill;
dest += fill;
diff --git a/src/input/pnm.h b/src/input/pnm.h
index 838fbadcc..df1f47290 100644
--- a/src/input/pnm.h
+++ b/src/input/pnm.h
@@ -19,7 +19,7 @@
*
* pnm util functions header by joschka
*/
-
+
#ifndef HAVE_PNM_H
#define HAVE_PNM_H
diff --git a/src/input/sha1.c b/src/input/sha1.c
index b70e50d5f..c30825a19 100644
--- a/src/input/sha1.c
+++ b/src/input/sha1.c
@@ -1,14 +1,14 @@
/* (PD) 2001 The Bitzi Corporation
- * Please see file COPYING or http://bitzi.com/publicdomain
+ * Please see file COPYING or http://bitzi.com/publicdomain
* for more info.
*
- * NIST Secure Hash Algorithm
- * heavily modified by Uwe Hollerbach <uh@alumni.caltech edu>
- * from Peter C. Gutmann's implementation as found in
- * Applied Cryptography by Bruce Schneier
- * Further modifications to include the "UNRAVEL" stuff, below
+ * NIST Secure Hash Algorithm
+ * heavily modified by Uwe Hollerbach <uh@alumni.caltech edu>
+ * from Peter C. Gutmann's implementation as found in
+ * Applied Cryptography by Bruce Schneier
+ * Further modifications to include the "UNRAVEL" stuff, below
*
- * This code is in the public domain
+ * This code is in the public domain
*/
#include <string.h>
diff --git a/src/input/sha1.h b/src/input/sha1.h
index 9f2659d60..a81af673b 100644
--- a/src/input/sha1.h
+++ b/src/input/sha1.h
@@ -34,7 +34,7 @@ char *sha_version(void);
#define SHA_VERSION 1
-#ifdef HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
#include "config.h"
#ifdef WORDS_BIGENDIAN
diff --git a/src/input/vcd/Makefile.am b/src/input/vcd/Makefile.am
index 31ec6a44c..61eac753b 100644
--- a/src/input/vcd/Makefile.am
+++ b/src/input/vcd/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_builddir)/misc/Makefile.plugins
include $(top_srcdir)/misc/Makefile.common
SUBDIRS = libcdio libvcd
diff --git a/src/input/vcd/libcdio/FreeBSD/freebsd.c b/src/input/vcd/libcdio/FreeBSD/freebsd.c
index 5a3443e95..bcfe674a5 100644
--- a/src/input/vcd/libcdio/FreeBSD/freebsd.c
+++ b/src/input/vcd/libcdio/FreeBSD/freebsd.c
@@ -29,11 +29,11 @@
static const char _rcsid[] = "$Id: freebsd.c,v 1.1 2005/01/01 02:43:57 rockyb Exp $";
-#include <arpa/inet.h>
#include "freebsd.h"
#ifdef HAVE_FREEBSD_CDROM
+#include <arpa/inet.h>
#include <cdio/sector.h>
static access_mode_t
diff --git a/src/input/vcd/libcdio/MSWindows/aspi32.c b/src/input/vcd/libcdio/MSWindows/aspi32.c
index 238a4b4e9..e62f8a089 100644
--- a/src/input/vcd/libcdio/MSWindows/aspi32.c
+++ b/src/input/vcd/libcdio/MSWindows/aspi32.c
@@ -162,9 +162,9 @@ have_aspi( HMODULE *hASPI,
return false;
}
- (FARPROC) *lpGetSupport = GetProcAddress( *hASPI,
+ *lpGetSupport = (FARPROC)GetProcAddress( *hASPI,
"GetASPI32SupportInfo" );
- (FARPROC) *lpSendCommand = GetProcAddress( *hASPI,
+ *lpSendCommand = (FARPROC)GetProcAddress( *hASPI,
"SendASPI32Command" );
/* make sure that we've got both function addresses */
diff --git a/src/input/vcd/libcdio/cdio/Makefile.am b/src/input/vcd/libcdio/cdio/Makefile.am
index 0910d60e5..4f0d53cc8 100644
--- a/src/input/vcd/libcdio/cdio/Makefile.am
+++ b/src/input/vcd/libcdio/cdio/Makefile.am
@@ -16,4 +16,4 @@ noinst_HEADERS = \
types.h \
util.h \
version.h \
- xa.h
+ xa.h
diff --git a/src/input/vcd/libvcd/Makefile.am b/src/input/vcd/libvcd/Makefile.am
index 01b100aa4..fddbb390f 100644
--- a/src/input/vcd/libvcd/Makefile.am
+++ b/src/input/vcd/libvcd/Makefile.am
@@ -21,7 +21,7 @@ libvcd_SRCS = \
sector.c \
stream.c \
stream_stdio.c \
- util.c
+ util.c
libvcdinfo_SRCS = \
info.c \
diff --git a/src/input/vcd/xine-extra.c b/src/input/vcd/xine-extra.c
index 79c962a79..d211f46a4 100644
--- a/src/input/vcd/xine-extra.c
+++ b/src/input/vcd/xine-extra.c
@@ -1,23 +1,23 @@
-/*
-
+/*
+
Copyright (C) 2002 Rocky Bernstein <rocky@panix.com>
-
+
Program 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.
-
+
This program 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
-
+
These are routines that probably should be in xine, but for whatever
- reason aren't - yet.
+ reason aren't - yet.
*/
#ifdef HAVE_CONFIG_H
@@ -42,11 +42,13 @@ static xine_t *my_xine = NULL;
In short this writes a message to buffer 'buf' and to stdout.
*/
-void
+void
xine_vlog_msg(xine_t *this, int buf, const char *format, va_list args)
{
+ va_list copy;
+ va_copy (copy, args);
xine_vlog(this, buf, format, args);
- vfprintf(stdout, format, args);
+ vfprintf(stdout, format, copy);
}
/*! This routine is like xine_log, except it takes a va_list instead
@@ -56,16 +58,18 @@ xine_vlog_msg(xine_t *this, int buf, const char *format, va_list args)
In short this writes a message to buffer 'buf' and to stderr.
*/
-void
+void
xine_vlog_err(xine_t *this, int buf, const char *format, va_list args)
{
+ va_list copy;
+ va_copy (copy, args);
xine_vlog(this, buf, format, args);
- vfprintf(stderr, format, args);
+ vfprintf(stderr, format, copy);
}
/*! Call this before calling any of the xine_log_msg or xine_log_err
routines. It sets up the xine buffer that will be used in error
- logging.
+ logging.
\return true if everything went okay; false is returned if
logging was already initialized, in which case nothing is done.
@@ -81,12 +85,12 @@ xine_log_init(xine_t *this)
/*! This routine is like xine_log without any xine-specific paramenters.
Before calling this routine you should have set up a xine log buffer via
- xine_log_init().
+ xine_log_init().
In short this writes a message to buffer 'buf' and to stdout.
- \return true if everything went okay; false is there was
- an error, such as logging wasn't initialized. On error, nothing is
+ \return true if everything went okay; false is there was
+ an error, such as logging wasn't initialized. On error, nothing is
logged.
*/
bool
@@ -103,12 +107,12 @@ xine_log_msg(const char *format, ...)
/*! This routine is like xine_log without any xine-specific paramenters.
Before calling this routine you should have set up a xine log buffer via
- xine_log_init().
+ xine_log_init().
In short this writes a message to buffer 'buf' and to stdout.
- \return true if everything went okay; false is there was
- an error, such as logging wasn't initialized. On error, nothing is
+ \return true if everything went okay; false is there was
+ an error, such as logging wasn't initialized. On error, nothing is
logged.
*/
bool
@@ -116,15 +120,15 @@ xine_log_err(const char *format, ...)
{
va_list args;
- va_start(args, format);
if (NULL == my_xine) return false;
+ va_start(args, format);
xine_vlog_err(my_xine, XINE_LOG_MSG, format, args);
va_end(args);
return true;
}
void
-xine_free_mrls(int *num_mrls, xine_mrl_t **mrls)
+xine_free_mrls(int *num_mrls, xine_mrl_t **mrls)
{
(*num_mrls)--;
for ( ; *num_mrls >= 0; (*num_mrls)-- ) {
diff --git a/src/input/vcd/xine-extra.h b/src/input/vcd/xine-extra.h
index 0650f863d..8acf1f291 100644
--- a/src/input/vcd/xine-extra.h
+++ b/src/input/vcd/xine-extra.h
@@ -1,23 +1,23 @@
-/*
-
+/*
+
Copyright (C) 2002 Rocky Bernstein <rocky@panix.com>
-
+
Program 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.
-
+
This program 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
-
+
These are routines that probably should be in xine, but for whatever
- reason aren't - yet.
+ reason aren't - yet.
*/
#ifndef XINE_EXTRA_H
@@ -47,7 +47,7 @@
In short this writes a message to buffer 'buf' and to stdout.
*/
-void
+void
xine_vlog_msg(xine_t *this, int buf, const char *format, va_list args) XINE_FORMAT_PRINTF(3, 0);
/*! This routine is like xine_log, except it takes a va_list instead
@@ -61,7 +61,7 @@ void xine_vlog_err(xine_t *this, int buf, const char *format, va_list args) XINE
/*! Call this before calling any of the xine_log_msg or xine_log_err
routines. It sets up the xine buffer that will be used in error
- logging.
+ logging.
\return true if everything went okay; false is returned if
logging was already initialized, in which case nothing is done.
@@ -71,24 +71,24 @@ bool xine_log_init(xine_t *this);
/*! This routine is like xine_log without any xine-specific paramenters.
Before calling this routine you should have set up a xine log buffer via
- xine_log_init().
+ xine_log_init().
In short this writes a message to buffer 'buf' and to stdout.
- \return true if everything went okay; false is there was
- an error, such as logging wasn't initialized. On error, nothing is
+ \return true if everything went okay; false is there was
+ an error, such as logging wasn't initialized. On error, nothing is
logged.
*/
bool xine_log_msg(const char *format, ...) XINE_FORMAT_PRINTF(1, 2);
/*! This routine is like xine_log without any xine-specific paramenters.
Before calling this routine you should have set up a xine log buffer via
- xine_log_init().
+ xine_log_init().
In short this writes a message to buffer 'buf' and to stdout.
- \return true if everything went okay; false is there was
- an error, such as logging wasn't initialized. On error, nothing is
+ \return true if everything went okay; false is there was
+ an error, such as logging wasn't initialized. On error, nothing is
logged.
*/
bool xine_log_err(const char *format, ...) XINE_FORMAT_PRINTF(1, 2);
diff --git a/src/input/vcd/xineplug_inp_vcd.c b/src/input/vcd/xineplug_inp_vcd.c
index 2e52ccc0f..e238460db 100644
--- a/src/input/vcd/xineplug_inp_vcd.c
+++ b/src/input/vcd/xineplug_inp_vcd.c
@@ -1,26 +1,26 @@
/*
-
+
Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com>
-
+
This program 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.
-
+
This program 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
*/
-/*
+/*
These are plugin routines called by the xine engine. See
Chapter 4. Extending xine's input
- http://xinehq.de/index.php/hackersguide/index.php?resource=5.3&action=default#INPUT
+ http://www.xine-project.org/hackersguide#INPUT
and the comments in input_plugin.h
This is what is referred to below a "the xine plugin spec"
@@ -83,8 +83,8 @@
#define BUF_DEMUX_BLOCK 0x05000000
#endif
-/*
- Convert an autoplay enumeration into an vcdinfo itemtype enumeration.
+/*
+ Convert an autoplay enumeration into an vcdinfo itemtype enumeration.
See definitions in vcdplayer.h and vcdinfo.h to get the below correct.
*/
static const vcdinfo_item_enum_t autoplay2itemtype[]={
@@ -94,7 +94,7 @@ static const vcdinfo_item_enum_t autoplay2itemtype[]={
VCDINFO_ITEM_TYPE_LID /* VCDPLAYER_AUTOPLAY_PBC */
};
-typedef struct vcd_config_s
+typedef struct vcd_config_s
{
char *title_format; /* Format string of GUI display title */
char *comment_format; /* Format string of stream comment meta */
@@ -106,7 +106,7 @@ typedef struct vcd_input_class_s {
input_class_t input_class;
xine_t *xine;
config_values_t *config; /* Pointer to XineRC config file. */
- vcd_input_plugin_t *ip;
+ vcd_input_plugin_t *ip;
vcd_config_t v_config; /* config stuff passed to child */
xine_mrl_t **mrls; /* list of mrl entries for medium */
@@ -114,10 +114,10 @@ typedef struct vcd_input_class_s {
char *vcd_device;/* Device name to use when
none specified in MRL */
/*--------------------------------------------------------------
- Media resource locator (MRL) info.
+ Media resource locator (MRL) info.
For the below offsets, use play_item + mrl_xxx_offset to get index
- into "mrls" array
+ into "mrls" array
---------------------------------------------------------------*/
int mrl_track_offset; /* perhaps -1 for tracks staring with 1*/
int mrl_entry_offset; /* i_tracks for entries starting with 0 */
@@ -130,10 +130,10 @@ typedef struct vcd_input_class_s {
vcd_input_class_t *vcd_class;
struct vcd_input_plugin_tag {
- input_plugin_t input_plugin; /* input plugin interface as defined by
- by player. For xine it contains a
+ input_plugin_t input_plugin; /* input plugin interface as defined by
+ by player. For xine it contains a
structure of functions that need
- to be implemented.
+ to be implemented.
*/
xine_stream_t *stream;
xine_event_queue_t *event_queue;
@@ -155,7 +155,7 @@ struct vcd_input_plugin_tag {
the mouse is not in any "button"
region then this has value -1.
*/
- bool b_mouse_in; /* True if mouse is inside a "button"
+ bool b_mouse_in; /* True if mouse is inside a "button"
region; false otherwise */
vcdplayer_t player ;
@@ -168,13 +168,13 @@ vcd_input_plugin_t my_vcd;
static bool vcd_handle_events (void);
static void vcd_close(vcd_input_class_t *class);
#if LIBVCD_VERSION_NUM >= 23
-static void send_mouse_enter_leave_event(vcd_input_plugin_t *p_this,
+static void send_mouse_enter_leave_event(vcd_input_plugin_t *p_this,
bool b_mouse_in);
#endif
-/*
- If class->vcd_device is NULL or the empty string,
- Use libcdio to find a CD drive with a VCD in it.
+/*
+ If class->vcd_device is NULL or the empty string,
+ Use libcdio to find a CD drive with a VCD in it.
*/
static bool
vcd_get_default_device(vcd_input_class_t *class, bool log_msg_if_fail)
@@ -184,7 +184,7 @@ vcd_get_default_device(vcd_input_class_t *class, bool log_msg_if_fail)
if (NULL == class->vcd_device || strlen(class->vcd_device)==0) {
char **cd_drives=NULL;
- cd_drives = cdio_get_devices_with_cap(NULL,
+ cd_drives = cdio_get_devices_with_cap(NULL,
(CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD|CDIO_FS_UNKNOWN),
true);
if (NULL == cd_drives || NULL == cd_drives[0]) {
@@ -201,8 +201,8 @@ vcd_get_default_device(vcd_input_class_t *class, bool log_msg_if_fail)
}
-static void
-meta_info_assign(int field, xine_stream_t *stream, const char * info)
+static void
+meta_info_assign(int field, xine_stream_t *stream, const char * info)
{
if (NULL != info) {
dbg_print(INPUT_DBG_META, "meta[%d]: %s\n", field, info);
@@ -215,10 +215,10 @@ meta_info_assign(int field, xine_stream_t *stream, const char * info)
/* Set stream information. */
static void
-vcd_set_meta_info (vcd_input_plugin_t *xine_vcd)
+vcd_set_meta_info (vcd_input_plugin_t *xine_vcd)
{
vcdinfo_obj_t *p_vcdinfo= xine_vcd->player.vcd;
- meta_info_assign(XINE_META_INFO_ALBUM, xine_vcd->stream,
+ meta_info_assign(XINE_META_INFO_ALBUM, xine_vcd->stream,
vcdinfo_get_album_id(p_vcdinfo));
meta_info_assign(XINE_META_INFO_ARTIST, xine_vcd->stream,
vcdinfo_get_preparer_id(p_vcdinfo));
@@ -230,40 +230,40 @@ vcd_set_meta_info (vcd_input_plugin_t *xine_vcd)
}
static void
-vcd_force_redisplay (void)
+vcd_force_redisplay (void)
{
#if 1
my_vcd.stream->xine->clock->adjust_clock(my_vcd.stream->xine->clock,
- my_vcd.stream->xine->clock->get_current_time(my_vcd.stream->xine->clock)
+ my_vcd.stream->xine->clock->get_current_time(my_vcd.stream->xine->clock)
+ 30 * 90000 );
#else
/* Alternate method that causes too much disruption... */
- xine_set_param(my_vcd.stream, XINE_PARAM_VO_ASPECT_RATIO,
+ xine_set_param(my_vcd.stream, XINE_PARAM_VO_ASPECT_RATIO,
(xine_get_param(my_vcd.stream, XINE_PARAM_VO_ASPECT_RATIO)));
#endif
}
static void
-vcd_set_aspect_ratio (int i_aspect_ratio)
+vcd_set_aspect_ratio (int i_aspect_ratio)
{
/* Alternate method that causes too much disruption... */
xine_set_param(my_vcd.stream, XINE_PARAM_VO_ASPECT_RATIO, i_aspect_ratio);
}
-/*! Add another MRL to the MRL list inside "this" to be displayed.
- mrl is the string name to add; size is the size of the entry in bytes.
- The number of mrls in "this" is incremented.
+/*! Add another MRL to the MRL list inside "this" to be displayed.
+ mrl is the string name to add; size is the size of the entry in bytes.
+ The number of mrls in "this" is incremented.
*/
static void
-vcd_add_mrl_slot(vcd_input_class_t *this, const char *mrl, off_t size,
+vcd_add_mrl_slot(vcd_input_class_t *this, const char *mrl, off_t size,
unsigned int *i)
{
- dbg_print(INPUT_DBG_MRL, "called to add slot %d: %s, size %u\n",
+ dbg_print(INPUT_DBG_MRL, "called to add slot %d: %s, size %u\n",
*i, mrl, (unsigned int) size);
-
+
this->mrls[*i] = malloc(sizeof(xine_mrl_t));
if (NULL==this->mrls[*i]) {
- LOG_ERR("Can't malloc %zu bytes for MRL slot %u (%s)",
+ LOG_ERR("Can't malloc %zu bytes for MRL slot %u (%s)",
sizeof(xine_mrl_t), *i, mrl);
return;
}
@@ -271,12 +271,10 @@ vcd_add_mrl_slot(vcd_input_class_t *this, const char *mrl, off_t size,
this->mrls[*i]->origin = NULL;
this->mrls[*i]->type = mrl_vcd;
this->mrls[*i]->size = size * M2F2_SECTOR_SIZE;
-
- this->mrls[*i]->mrl = (char *) malloc(strlen(mrl) + 1);
+
+ this->mrls[*i]->mrl = strdup(mrl);
if (NULL==this->mrls[*i]->mrl) {
LOG_ERR("Can't malloc %zu bytes for MRL name %s", sizeof(xine_mrl_t), mrl);
- } else {
- sprintf(this->mrls[*i]->mrl, "%s", mrl);
}
(*i)++;
}
@@ -284,9 +282,9 @@ vcd_add_mrl_slot(vcd_input_class_t *this, const char *mrl, off_t size,
/*!
Return the associated mrl_offset for the given type.
*/
-static int
-vcd_get_mrl_type_offset(vcd_input_plugin_t *inp,
- vcdinfo_item_enum_t type, int *size)
+static int
+vcd_get_mrl_type_offset(vcd_input_plugin_t *inp,
+ vcdinfo_item_enum_t type, int *size)
{
switch (type) {
case VCDINFO_ITEM_TYPE_ENTRY:
@@ -299,7 +297,7 @@ vcd_get_mrl_type_offset(vcd_input_plugin_t *inp,
case VCDINFO_ITEM_TYPE_TRACK:
*size = inp->class->mrl_entry_offset;
return inp->class->mrl_track_offset;
- case VCDINFO_ITEM_TYPE_LID:
+ case VCDINFO_ITEM_TYPE_LID:
/* Play list number (LID) */
*size = (inp->player.i_lids > 0) ? 1 : 0;
return inp->class->mrl_play_offset;
@@ -340,10 +338,10 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
if (!vcd_get_default_device(class, true)) return false;
vcd_device = class->vcd_device;
}
-
+
if (!vcdio_open(vcdplayer, vcd_device)) {
/* Error should have been logged in vcdio_open. If not do the below:
- LOG_ERR(vcdplayer, "%s: %s.\n", _("unable to open"),
+ LOG_ERR(vcdplayer, "%s: %s.\n", _("unable to open"),
class->vcd_device, strerror(errno));
*/
return false;
@@ -361,13 +359,13 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
didn't have to possibly remove rejected LIDs from list done in the
loop below.
*/
- class->num_mrls = vcdplayer->i_tracks + vcdplayer->i_entries
+ class->num_mrls = vcdplayer->i_tracks + vcdplayer->i_entries
+ vcdplayer->i_segments + vcdplayer->i_lids;
if (!vcdplayer->show_rejected && vcdinfo_get_lot(vcdplayer->vcd)) {
/* Remove rejected LIDs from count. */
for (n=0; n<vcdplayer->i_lids; n++) {
- if ( vcdinf_get_lot_offset(vcdinfo_get_lot(vcdplayer->vcd), n)
+ if ( vcdinf_get_lot_offset(vcdinfo_get_lot(vcdplayer->vcd), n)
== PSD_OFS_DISABLED )
class->num_mrls--;
}
@@ -383,24 +381,24 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
}
/* Record MRL's for tracks */
- for (n=1; n<=vcdplayer->i_tracks; n++) {
+ for (n=1; n<=vcdplayer->i_tracks; n++) {
memset(&mrl, 0, sizeof (mrl));
snprintf(mrl, sizeof(mrl), "%s%s@T%u", MRL_PREFIX, vcd_device, n);
vcd_add_mrl_slot(class, mrl, vcdplayer->track[n-1].size, &i);
}
-
+
class->mrl_entry_offset = vcdplayer->i_tracks;
class->mrl_play_offset = class->mrl_entry_offset + i_entries - 1;
/* Record MRL's for entries */
if (i_entries > 0) {
- for (n=0; n<i_entries; n++) {
+ for (n=0; n<i_entries; n++) {
memset(&mrl, 0, sizeof (mrl));
snprintf(mrl, sizeof(mrl), "%s%s@E%u", MRL_PREFIX, vcd_device, n);
vcd_add_mrl_slot(class, mrl, vcdplayer->entry[n].size, &i);
}
}
-
+
/* Record MRL's for LID entries or selection entries*/
class->mrl_segment_offset = class->mrl_play_offset;
if (vcdinfo_get_lot(vcdplayer->vcd)) {
@@ -408,7 +406,7 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
uint16_t ofs = vcdinf_get_lot_offset(vcdinfo_get_lot(vcdplayer->vcd), n);
if (ofs != PSD_OFS_DISABLED || vcdplayer->show_rejected) {
memset(&mrl, 0, sizeof (mrl));
- snprintf(mrl, sizeof(mrl), "%s%s@P%u%s", MRL_PREFIX, vcd_device, n+1,
+ snprintf(mrl, sizeof(mrl), "%s%s@P%u%s", MRL_PREFIX, vcd_device, n+1,
ofs == PSD_OFS_DISABLED ? "*" : "");
vcd_add_mrl_slot(class, mrl, 0, &i);
class->mrl_segment_offset++;
@@ -420,7 +418,7 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
{
segnum_t i_segments = vcdplayer->i_segments;
for (n=0; n<i_segments; n++) {
- vcdinfo_video_segment_type_t segtype
+ vcdinfo_video_segment_type_t segtype
= vcdinfo_get_video_type(p_vcdinfo, n);
char c='S';
switch (segtype) {
@@ -444,10 +442,10 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
vcd_add_mrl_slot(class, mrl, vcdplayer->segment[n].size, &i);
}
}
-
- dbg_print(INPUT_DBG_MRL,
- "offsets are track: %d, entry: %d, play: %d seg: %d\n",
- class->mrl_track_offset, class->mrl_entry_offset,
+
+ dbg_print(INPUT_DBG_MRL,
+ "offsets are track: %d, entry: %d, play: %d seg: %d\n",
+ class->mrl_track_offset, class->mrl_entry_offset,
class->mrl_play_offset, class->mrl_segment_offset);
return true;
@@ -455,9 +453,9 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
/*!
parses a MRL which has the format
-
+
vcd://[vcd_path][@[EPTS]?number]\*?
-
+
Examples
vcd:// - Play (navigate) default device: /dev/cdrom
vcd://@ - same as above
@@ -469,7 +467,7 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
vcd://dev/cdrom@E0 - Play Entry id 0 from default device
vcd://@P1 - probably same as above.
If there is no playback control, MRL will
- get converted into vcd://@E0
+ get converted into vcd://@E0
vcd://@P1* - probably same as above.
vcd://@S0 - Play segment 0 from default device
vcd://@3 - Play track 3 from default device
@@ -477,7 +475,7 @@ vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device)
vcd:///tmp/ntsc.bin@ - Play default item from /tmp/ntsc.bin
vcd:///tmp/ntsc.bin/@E0 - Play entry 0 of /tmp/ntsc.bin
-parameters:
+parameters:
mrl : mrl to parse
default_vcd_device: name of device to use when none given
auto_type : type of selection (entry, track, LID) when none given
@@ -485,10 +483,10 @@ parameters:
*/
static bool
-vcd_parse_mrl(/*in*/ const char *default_vcd_device, /*in*/ char *mrl,
+vcd_parse_mrl(/*in*/ const char *default_vcd_device, /*in*/ char *mrl,
/*out*/ char *device_str, /*out*/ vcdinfo_itemid_t *itemid,
- /*in */ vcdplayer_autoplay_t auto_type,
- /*out*/ bool *used_default)
+ /*in */ vcdplayer_autoplay_t auto_type,
+ /*out*/ bool *used_default)
{
char type_str[2];
int count;
@@ -509,15 +507,15 @@ vcd_parse_mrl(/*in*/ const char *default_vcd_device, /*in*/ char *mrl,
device_str[0] = '/';
device_str[1] = 0;
- count = sscanf (p, "%1023[^@]@%1[EePpSsTt]%u",
+ count = sscanf (p, "%1023[^@]@%1[EePpSsTt]%u",
device_str + 1, type_str, &num);
itemid->num = num;
-
+
switch (count) {
case 1:
/* Matched device, but nothing beyond that */
if (strlen(device_str)!=0 && device_str[0] != ':') {
- /* See if we have old-style MRL with no type specifier.
+ /* See if we have old-style MRL with no type specifier.
If so, we assume "track". */
count = sscanf (p, "%u", &num);
itemid->num = num;
@@ -536,7 +534,7 @@ vcd_parse_mrl(/*in*/ const char *default_vcd_device, /*in*/ char *mrl,
_x_mrl_unescape (device_str);
case 0:
- case EOF:
+ case EOF:
{
/* No device/file given, so use the default device and try again. */
if (NULL == default_vcd_device) return false;
@@ -545,16 +543,16 @@ vcd_parse_mrl(/*in*/ const char *default_vcd_device, /*in*/ char *mrl,
count = sscanf (p, "%1[EePpSsTt]%u", type_str, &num);
type_str[0] = toupper(type_str[0]);
itemid->num = num;
-
+
switch (count) {
case EOF:
/* Default PBC navigation. */
return true;
case 0:
- /* See if we have old-style MRL with no type specifier.
+ /* See if we have old-style MRL with no type specifier.
If so, we assume "track". */
count = sscanf (p, "%u", &num);
- if (1==count) {
+ if (1==count) {
type_str[0] = 'T';
break;
}
@@ -570,45 +568,45 @@ vcd_parse_mrl(/*in*/ const char *default_vcd_device, /*in*/ char *mrl,
/* We have some sort of track/selection/entry number */
switch (type_str[0]) {
- case 'E':
+ case 'E':
itemid->type = VCDINFO_ITEM_TYPE_ENTRY;
break;
- case '\0':
+ case '\0':
/* None specified, use config value. */
itemid->type = (vcdinfo_item_enum_t) auto_type;
*used_default = true;
break;
- case 'P':
+ case 'P':
itemid->type = VCDINFO_ITEM_TYPE_LID;
break;
- case 'S':
+ case 'S':
itemid->type = VCDINFO_ITEM_TYPE_SEGMENT;
break;
- case 'T':
+ case 'T':
itemid->type = VCDINFO_ITEM_TYPE_TRACK;
break;
default: ;
}
-
- if ( 0==itemid->num
- && ( (VCDINFO_ITEM_TYPE_LID == itemid->type)
+
+ if ( 0==itemid->num
+ && ( (VCDINFO_ITEM_TYPE_LID == itemid->type)
|| (VCDINFO_ITEM_TYPE_TRACK == itemid->type) ) )
itemid->num = 1;
return true;
}
-/*!
+/*!
From xine plugin spec:
return capabilities of input source
*/
-static uint32_t
+static uint32_t
vcd_plugin_get_capabilities (input_plugin_t *this_gen)
{
- uint32_t ret =
- INPUT_CAP_AUDIOLANG | INPUT_CAP_BLOCK |
+ uint32_t ret =
+ INPUT_CAP_AUDIOLANG | INPUT_CAP_BLOCK |
INPUT_CAP_CHAPTERS | INPUT_CAP_PREVIEW |
(my_vcd.player.i_still ? 0: INPUT_CAP_SEEKABLE) |
INPUT_CAP_SPULANG;
@@ -620,14 +618,14 @@ vcd_plugin_get_capabilities (input_plugin_t *this_gen)
# if FINISHED
/* If needed, will fill out later... */
-static void
+static void
vcd_read_ahead_cb(void *this_gen, xine_cfg_entry_t *entry)
{
return;
}
#endif
-static void
+static void
vcd_flush_buffers(void)
{
_x_demux_flush_engine(my_vcd.stream);
@@ -638,11 +636,11 @@ vcd_flush_buffers(void)
read nlen bytes, return number of bytes read.
*/
-static off_t
+static off_t
vcd_plugin_read (input_plugin_t *this_gen, char *buf, const off_t nlen)
{
- dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT),
+ dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT),
"Called with nlen %u\n", (unsigned int) nlen);
/* FIXME: Tricking the demux_mpeg_block plugin */
@@ -654,7 +652,7 @@ vcd_plugin_read (input_plugin_t *this_gen, char *buf, const off_t nlen)
}
/* Allocate and return a no-op buffer. This signals the outside
- to do nothing, but in contrast to returning NULL, it doesn't
+ to do nothing, but in contrast to returning NULL, it doesn't
mean the stream has ended. We use this say for still frames.
*/
#define RETURN_NOOP_BUF \
@@ -679,8 +677,8 @@ vcd_plugin_read (input_plugin_t *this_gen, char *buf, const off_t nlen)
function
*/
static buf_element_t *
-vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
- const off_t i_len)
+vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
+ const off_t i_len)
{
vcd_input_plugin_t *vcd_input_plugin= (vcd_input_plugin_t *) this_gen;
vcdplayer_t *p_vcdplayer = &my_vcd.player;
@@ -720,7 +718,7 @@ vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
SLEEP_AND_HANDLE_EVENTS;
}
}
-
+
read_block:
switch (vcdplayer_read(p_vcdplayer, data, i_len)) {
@@ -730,37 +728,37 @@ vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
case READ_ERROR:
/* Some sort of error. */
return NULL;
- case READ_STILL_FRAME:
+ case READ_STILL_FRAME:
{
dbg_print(INPUT_DBG_STILL, "Handled still event wait time %u\n",
p_vcdplayer->i_still);
vcd_input_plugin->pause_end_time = time(NULL) + p_vcdplayer->i_still;
RETURN_NOOP_BUF;
}
-
+
default:
case READ_BLOCK:
/* Read buffer */
p_buf = fifo->buffer_pool_alloc (fifo);
p_buf->type = BUF_DEMUX_BLOCK;
}
-
+
p_buf->content = p_buf->mem;
if (STILL_READING == p_vcdplayer->i_still && 0 == my_vcd.i_old_still) {
- my_vcd.i_old_deinterlace = xine_get_param(my_vcd.stream,
+ my_vcd.i_old_deinterlace = xine_get_param(my_vcd.stream,
XINE_PARAM_VO_DEINTERLACE);
xine_set_param(my_vcd.stream, XINE_PARAM_VO_DEINTERLACE, 0);
- dbg_print(INPUT_DBG_STILL, "going into still, saving deinterlace %d\n",
+ dbg_print(INPUT_DBG_STILL, "going into still, saving deinterlace %d\n",
my_vcd.i_old_deinterlace);
} else if (0 == p_vcdplayer->i_still && 0 != my_vcd.i_old_still) {
- dbg_print(INPUT_DBG_STILL,
+ dbg_print(INPUT_DBG_STILL,
"going out of still, restoring deinterlace\n");
xine_set_param(my_vcd.stream, XINE_PARAM_VO_DEINTERLACE,
my_vcd.i_old_deinterlace);
}
my_vcd.i_old_still = p_vcdplayer->i_still;
-
+
/* Ideally this should probably be i_len. */
memcpy (p_buf->mem, data, M2F2_SECTOR_SIZE);
@@ -770,12 +768,12 @@ vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo,
/*!
From xine plugin spec:
- seek position, return new position
+ seek position, return new position
if seeking failed, -1 is returned
*/
-static off_t
-vcd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin)
+static off_t
+vcd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin)
{
return vcdio_seek (&my_vcd.player, offset, origin);
}
@@ -794,7 +792,7 @@ static off_t old_get_length = 0;
static vcdplayer_slider_length_t old_slider_length;
/* This routine is called a bit. Make reasonably fast. */
-static off_t
+static off_t
vcd_plugin_get_length (input_plugin_t *this_gen) {
vcd_input_plugin_t *ip= (vcd_input_plugin_t *) this_gen;
@@ -803,7 +801,7 @@ vcd_plugin_get_length (input_plugin_t *this_gen) {
int n = vcdplayer->play_item.num;
if (vcdplayer->play_item.num == old_play_item.num
- && vcdplayer->play_item.type == old_play_item.type
+ && vcdplayer->play_item.type == old_play_item.type
&& vcdplayer->slider_length == old_slider_length)
return old_get_length;
@@ -835,7 +833,7 @@ vcd_plugin_get_length (input_plugin_t *this_gen) {
/* This is the only situation where the size of the current play item
is not static. It depends what the current play-item is.
*/
- old_get_length = (vcdplayer->end_lsn - vcdplayer->origin_lsn) *
+ old_get_length = (vcdplayer->end_lsn - vcdplayer->origin_lsn) *
M2F2_SECTOR_SIZE;
return old_get_length;
break;
@@ -845,11 +843,11 @@ vcd_plugin_get_length (input_plugin_t *this_gen) {
/* FIXME? */
return -1;
}
-
+
if (n >= 0 && n < ip->class->num_mrls) {
old_get_length = ip->class->mrls[n]->size;
- dbg_print(INPUT_DBG_MRL, "item: %u, slot %u, size %ld\n",
- vcdplayer->play_item.num,
+ dbg_print(INPUT_DBG_MRL, "item: %u, slot %u, size %ld\n",
+ vcdplayer->play_item.num,
(unsigned int) n, (long int) old_get_length);
}
return old_get_length;
@@ -860,7 +858,7 @@ vcd_plugin_get_length (input_plugin_t *this_gen) {
* get current position in stream.
*
*/
-static off_t
+static off_t
vcd_plugin_get_current_pos (input_plugin_t *this_gen){
// trace_print("Called\n");
return (vcd_plugin_seek (this_gen, 0, SEEK_CUR));
@@ -871,7 +869,7 @@ vcd_plugin_get_current_pos (input_plugin_t *this_gen){
* From xine plugin spec:
* return block size of input source (if supported, 0 otherwise)
*/
-static uint32_t
+static uint32_t
vcd_plugin_get_blocksize (input_plugin_t *this_gen) {
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
@@ -887,7 +885,7 @@ vcd_plugin_get_blocksize (input_plugin_t *this_gen) {
*/
static xine_mrl_t **
-vcd_class_get_dir (input_class_t *this_gen, const char *filename,
+vcd_class_get_dir (input_class_t *this_gen, const char *filename,
int *num_files) {
char intended_vcd_device[MAX_DEVICE_LEN+1]= { '\0', };
@@ -899,7 +897,7 @@ vcd_class_get_dir (input_class_t *this_gen, const char *filename,
bool used_default;
if (filename == NULL) {
- dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT),
+ dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT),
"called with NULL\n");
if ( class->mrls != NULL && NULL != class->mrls[0] ) goto have_mrls;
@@ -908,12 +906,12 @@ vcd_class_get_dir (input_class_t *this_gen, const char *filename,
}
} else {
char *mrl = strdup(filename);
- dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT),
+ dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT),
"called with %s\n", filename);
if (!vcd_get_default_device(class, true)) goto no_mrls;
- if (!vcd_parse_mrl(class->vcd_device, mrl,
- intended_vcd_device, &itemid,
- vcdplayer->default_autoplay, &used_default)) {
+ if (!vcd_parse_mrl(class->vcd_device, mrl,
+ intended_vcd_device, &itemid,
+ vcdplayer->default_autoplay, &used_default)) {
free (mrl);
goto no_mrls;
}
@@ -925,17 +923,17 @@ vcd_class_get_dir (input_class_t *this_gen, const char *filename,
return class->mrls;
no_mrls:
- *num_files = 0;
- return NULL;
+ *num_files = 0;
+ return NULL;
}
#define FREE_AND_NULL(ptr) if (NULL != ptr) free(ptr); ptr = NULL;
static void
-vcd_close(vcd_input_class_t *class)
+vcd_close(vcd_input_class_t *class)
{
xine_free_mrls(&(class->num_mrls), class->mrls);
- FREE_AND_NULL(my_vcd.mrl);
+ FREE_AND_NULL(my_vcd.mrl);
if (my_vcd.player.b_opened)
vcdio_close(&my_vcd.player);
}
@@ -947,15 +945,15 @@ vcd_close(vcd_input_class_t *class)
*
* returns 0 for temporary failures
*/
-static int
-vcd_class_eject_media (input_class_t *this_gen)
+static int
+vcd_class_eject_media (input_class_t *this_gen)
{
int ret;
CdIo_t *cdio=vcdinfo_get_cd_image(my_vcd.player.vcd);
-
+
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
if (NULL == cdio) return 0;
-
+
ret = cdio_eject_media(&cdio);
if ((ret == 0) || (ret == 2)) {
if (my_vcd.player.b_opened)
@@ -968,8 +966,8 @@ vcd_class_eject_media (input_class_t *this_gen)
* From spec:
* return current MRL
*/
-static char *
-vcd_plugin_get_mrl (input_plugin_t *this_gen)
+static const char *
+vcd_plugin_get_mrl (input_plugin_t *this_gen)
{
vcd_input_plugin_t *t = (vcd_input_plugin_t *) this_gen;
vcdplayer_t *vcdplayer = &my_vcd.player;
@@ -987,28 +985,28 @@ vcd_plugin_get_mrl (input_plugin_t *this_gen)
if (-2 == offset) {
/* Bad type. */
- LOG_ERR("%s %d", _("Invalid current entry type"),
+ LOG_ERR("%s %d", _("Invalid current entry type"),
vcdplayer->play_item.type);
- return strdup("");
+ return "";
} else {
n += offset;
if (n < t->class->num_mrls) {
- dbg_print(INPUT_DBG_CALL, "Called, returning %s\n",
+ dbg_print(INPUT_DBG_CALL, "Called, returning %s\n",
t->class->mrls[n]->mrl);
return t->class->mrls[n]->mrl;
} else {
- return strdup("");
+ return "";
}
}
}
/*!
From xine plugin spec:
-
+
return human readable (verbose = 1 line) description for this plugin
*/
-static char *
-vcd_class_get_description (input_class_t *this_gen)
+static const char *
+vcd_class_get_description (input_class_t *this_gen)
{
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
return _("Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... ");
@@ -1027,12 +1025,12 @@ vcd_class_get_identifier (input_class_t *this_gen) {
return SHORT_PLUGIN_NAME;
}
-/*
+/*
Handle all queued keyboard/mouse events. Return TRUE if this causes
a change in the play item.
*/
static bool
-vcd_handle_events (void)
+vcd_handle_events (void)
{
vcdplayer_t *p_vcdplayer = &my_vcd.player;
xine_event_t *p_event;
@@ -1040,7 +1038,7 @@ vcd_handle_events (void)
/* What you add to the last input number entry. It accumulates all of
the 10_ADD keypresses */
- static unsigned int number_addend = 0;
+ static unsigned int number_addend = 0;
while ((p_event = xine_event_get(my_vcd.event_queue))) {
@@ -1050,14 +1048,14 @@ vcd_handle_events (void)
switch(p_event->type) {
case XINE_EVENT_INPUT_NUMBER_10_ADD:
- number_addend += 10;
- dbg_print(INPUT_DBG_EVENT, "10 added to number. Is now: %d\n",
+ number_addend += 10;
+ dbg_print(INPUT_DBG_EVENT, "10 added to number. Is now: %d\n",
number_addend);
break;
/* The method used below is oblivious to XINE_EVENT_INPUT encodings
- In particular, it does not assume XINE_EVENT_INPUT_NUMBE_9 =
- XINE_EVENT_INPUT_NUMBER_0 + 9.
+ In particular, it does not assume XINE_EVENT_INPUT_NUMBE_9 =
+ XINE_EVENT_INPUT_NUMBER_0 + 9.
*/
case XINE_EVENT_INPUT_NUMBER_9:
digit_entered++;
@@ -1081,7 +1079,7 @@ vcd_handle_events (void)
{
number_addend *= 10;
number_addend += digit_entered;
- dbg_print(INPUT_DBG_EVENT,
+ dbg_print(INPUT_DBG_EVENT,
"digit added number is now: %d\n", number_addend);
break;
}
@@ -1090,65 +1088,65 @@ vcd_handle_events (void)
vcdplayer_debug = number_addend;
number_addend = 0;
break;
- case XINE_EVENT_INPUT_MENU1:
+ case XINE_EVENT_INPUT_MENU1:
case XINE_EVENT_INPUT_MENU2:
- case XINE_EVENT_INPUT_NEXT:
+ case XINE_EVENT_INPUT_NEXT:
case XINE_EVENT_INPUT_PREVIOUS:
{
int num = number_addend;
vcdinfo_itemid_t itemid;
-
+
number_addend = 0;
-
+
/* If no number was given it's really the same as 1, not 0. */
if (num == 0) num++;
-
- dbg_print(INPUT_DBG_EVENT,
- "RETURN/NEXT/PREV/DEFAULT (%d) iteration count %d\n",
+
+ dbg_print(INPUT_DBG_EVENT,
+ "RETURN/NEXT/PREV/DEFAULT (%d) iteration count %d\n",
p_event->type, num);
for ( ; num > 0; num--) {
itemid = p_vcdplayer->play_item;
switch (p_event->type) {
- case XINE_EVENT_INPUT_MENU1:
+ case XINE_EVENT_INPUT_MENU1:
if (p_vcdplayer->return_entry == VCDINFO_INVALID_ENTRY) {
LOG_MSG("%s\n", _("selection has no RETURN entry"));
return false;
}
itemid.num = p_vcdplayer->return_entry;
- dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT),
+ dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT),
"RETURN to %d\n", itemid.num);
/* Don't loop around -- doesn't make sense to loop a return*/
- num = 0;
+ num = 0;
break;
- case XINE_EVENT_INPUT_MENU2:
+ case XINE_EVENT_INPUT_MENU2:
if (vcdplayer_pbc_is_on(p_vcdplayer)) {
- lid_t lid=vcdinfo_get_multi_default_lid(p_vcdplayer->vcd,
+ lid_t lid=vcdinfo_get_multi_default_lid(p_vcdplayer->vcd,
p_vcdplayer->i_lid,
p_vcdplayer->i_lsn);
if (VCDINFO_INVALID_LID != lid) {
itemid.num = lid;
- dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT),
+ dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT),
"DEFAULT to %d\n", itemid.num);
} else {
- dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT),
- "no DEFAULT for LID %d\n",
+ dbg_print((INPUT_DBG_PBC|INPUT_DBG_EVENT),
+ "no DEFAULT for LID %d\n",
p_vcdplayer->i_lid);
}
-
+
/* Don't loop around -- doesn't make sense to loop a return*/
- num = 0;
+ num = 0;
} else {
- /* PBC is not on. "default" selection beginning of current
+ /* PBC is not on. "default" selection beginning of current
selection . Alternative: */
LOG_MSG("%s\n", _("DEFAULT selected, but PBC is not on."));
}
break;
- case XINE_EVENT_INPUT_NEXT:
+ case XINE_EVENT_INPUT_NEXT:
if (p_vcdplayer->next_entry == VCDINFO_INVALID_ENTRY) {
LOG_MSG("%s\n", _("selection has no NEXT entry"));
return false;
- }
+ }
itemid.num = p_vcdplayer->next_entry;
dbg_print(INPUT_DBG_PBC, "NEXT to %d\n", itemid.num);
break;
@@ -1160,7 +1158,7 @@ vcd_handle_events (void)
itemid.num = p_vcdplayer->prev_entry;
dbg_print(INPUT_DBG_PBC, "PREVIOUS to %d\n", itemid.num);
break;
- default:
+ default:
LOG_MSG("%s %d\n", _("Unknown event type: "), p_event->type);
}
_x_demux_flush_engine(my_vcd.stream);
@@ -1174,13 +1172,13 @@ vcd_handle_events (void)
/* In the future will have to test to see if we are in a menu
selection. But if not... */
vcdinfo_itemid_t itemid = p_vcdplayer->play_item;
-
+
itemid.num = number_addend;
number_addend = 0;
-
+
if (vcdplayer_pbc_is_on(p_vcdplayer)) {
- lid_t i_next=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
- p_vcdplayer->i_lid,
+ lid_t i_next=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
+ p_vcdplayer->i_lid,
itemid.num);
if (VCDINFO_INVALID_LID != i_next) {
itemid.num = i_next;
@@ -1191,30 +1189,30 @@ vcd_handle_events (void)
}
break;
}
- case XINE_EVENT_INPUT_MOUSE_BUTTON:
+ case XINE_EVENT_INPUT_MOUSE_BUTTON:
if (my_vcd.stream)
{
xine_input_data_t *p_input = p_event->data;
- if (p_input->button == 1)
+ if (p_input->button == 1)
{
#if LIBVCD_VERSION_NUM >= 23
int i_selection;
#endif
- dbg_print(INPUT_DBG_EVENT,
- "Button to x: %d, y: %d, scaled x: %d, scaled y %d\n",
+ dbg_print(INPUT_DBG_EVENT,
+ "Button to x: %d, y: %d, scaled x: %d, scaled y %d\n",
p_input->x, p_input->y,
p_input->x * 255 / p_vcdplayer->max_x,
p_input->y * 255 / p_vcdplayer->max_y);
-
+
#if LIBVCD_VERSION_NUM >= 23
/* xine_dvd_send_button_update(this, 1); */
-
+
if (my_vcd.b_mouse_in)
send_mouse_enter_leave_event(&my_vcd, false);
- i_selection = vcdinfo_get_area_selection(p_vcdplayer->vcd,
- p_vcdplayer->i_lid,
+ i_selection = vcdinfo_get_area_selection(p_vcdplayer->vcd,
+ p_vcdplayer->i_lid,
p_input->x,
p_input->y,
p_vcdplayer->max_x,
@@ -1223,8 +1221,8 @@ vcd_handle_events (void)
if (vcdplayer_pbc_is_on(p_vcdplayer)) {
vcdinfo_itemid_t itemid = p_vcdplayer->play_item;
- lid_t i_next=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
- p_vcdplayer->i_lid,
+ lid_t i_next=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
+ p_vcdplayer->i_lid,
i_selection);
if (VCDINFO_INVALID_LID != i_next) {
itemid.num = i_next;
@@ -1237,33 +1235,33 @@ vcd_handle_events (void)
}
}
break;
- case XINE_EVENT_INPUT_BUTTON_FORCE:
+ case XINE_EVENT_INPUT_BUTTON_FORCE:
break;
- case XINE_EVENT_INPUT_MOUSE_MOVE:
- if (my_vcd.stream)
+ case XINE_EVENT_INPUT_MOUSE_MOVE:
+ if (my_vcd.stream)
{
xine_input_data_t *p_input = p_event->data;
#if LIBVCD_VERSION_NUM >= 23
- int32_t i_selection = vcdinfo_get_area_selection(p_vcdplayer->vcd,
- p_vcdplayer->i_lid,
+ int32_t i_selection = vcdinfo_get_area_selection(p_vcdplayer->vcd,
+ p_vcdplayer->i_lid,
p_input->x,
p_input->y,
p_vcdplayer->max_x,
p_vcdplayer->max_y);
- dbg_print(INPUT_DBG_EVENT, "Move to x: %d, y: %d\n",
+ dbg_print(INPUT_DBG_EVENT, "Move to x: %d, y: %d\n",
p_input->x, p_input->y);
-
+
if (my_vcd.i_mouse_button != i_selection) {
- dbg_print(INPUT_DBG_EVENT, "Old selection: %d, selection: %d\n",
+ dbg_print(INPUT_DBG_EVENT, "Old selection: %d, selection: %d\n",
my_vcd.i_mouse_button, i_selection);
my_vcd.i_mouse_button = i_selection;
- if (i_selection < 0)
+ if (i_selection < 0)
send_mouse_enter_leave_event(&my_vcd, false);
- else
+ else
send_mouse_enter_leave_event(&my_vcd, true);
}
#else
- dbg_print(INPUT_DBG_EVENT, "Move to x: %d, y: %d\n",
+ dbg_print(INPUT_DBG_EVENT, "Move to x: %d, y: %d\n",
p_input->x, p_input->y);
#endif
}
@@ -1294,19 +1292,19 @@ vcd_handle_events (void)
request optional data from input plugin.
*/
-static int
-vcd_get_optional_data (input_plugin_t *this_gen,
+static int
+vcd_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
- dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT),
+ dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT),
"called with %d\n", data_type);
if (NULL == my_vcd.stream) return INPUT_OPTIONAL_UNSUPPORTED;
/* Fill this out more fully... */
switch(data_type) {
-
- case INPUT_OPTIONAL_DATA_AUDIOLANG:
+
+ case INPUT_OPTIONAL_DATA_AUDIOLANG:
{
uint8_t channel;
channel = _x_get_audio_channel(my_vcd.stream);
@@ -1330,8 +1328,8 @@ vcd_get_optional_data (input_plugin_t *this_gen,
}
return INPUT_OPTIONAL_SUCCESS;
}
-
- case INPUT_OPTIONAL_DATA_SPULANG:
+
+ case INPUT_OPTIONAL_DATA_SPULANG:
{
/*uint16_t lang;*/
int8_t channel;
@@ -1342,12 +1340,12 @@ vcd_get_optional_data (input_plugin_t *this_gen,
} else {
sprintf(data, "%1d", channel);
}
-
+
}
default: ;
}
-
+
return INPUT_OPTIONAL_UNSUPPORTED;
}
@@ -1365,7 +1363,7 @@ vcd_get_optional_data (input_plugin_t *this_gen,
*/
static char **
-vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files)
+vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files)
{
vcd_input_class_t *class = (vcd_input_class_t *) this_gen;
static char *filelist[MAX_DIR_ENTRIES];
@@ -1378,9 +1376,9 @@ vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files)
} else {
int i;
int size = 0;
- vcdinfo_item_enum_t itemtype =
+ vcdinfo_item_enum_t itemtype =
autoplay2itemtype[my_vcd.player.default_autoplay];
-
+
int offset = vcd_get_mrl_type_offset(&my_vcd, itemtype, &size);
/* A VCD is not required to have PBC or LID's, default to entry if
@@ -1391,7 +1389,7 @@ vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files)
offset = vcd_get_mrl_type_offset(&my_vcd, itemtype, &size);
}
- /* This is because entries start at 0 while other playable units
+ /* This is because entries start at 0 while other playable units
start at 1. Can remove the below when everything has the same
origin.
*/
@@ -1412,14 +1410,14 @@ vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files)
}
/*!
- Things that need to be done when a stream is closed.
+ Things that need to be done when a stream is closed.
*/
-static void
-vcd_plugin_dispose(input_plugin_t *this_gen)
+static void
+vcd_plugin_dispose(input_plugin_t *this_gen)
{
/* Not sure there's much more to do here...
- In open_plugin we are given a stream which
+ In open_plugin we are given a stream which
we save...
*/
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
@@ -1435,10 +1433,10 @@ vcd_plugin_dispose(input_plugin_t *this_gen)
static vcd_log_handler_t gl_default_vcd_log_handler = NULL;
static cdio_log_handler_t gl_default_cdio_log_handler = NULL;
-/*! This routine is called by libvcd routines on error.
+/*! This routine is called by libvcd routines on error.
Setup is done by init_input_plugin.
*/
-static void
+static void
vcd_log_handler (vcd_log_level_t level, const char message[])
{
switch (level) {
@@ -1455,19 +1453,19 @@ vcd_log_handler (vcd_log_level_t level, const char message[])
LOG_ERR("%s", message);
break;
default:
- LOG_ERR("%s\n%s %d",
- message,
- _("The above message had unknown vcdimager log level"),
+ LOG_ERR("%s\n%s %d",
+ message,
+ _("The above message had unknown vcdimager log level"),
level);
}
-
+
/* gl_default_vcd_log_handler (level, message); */
}
-/*! This routine is called by libcdio routines on error.
+/*! This routine is called by libcdio routines on error.
Setup is done by init_input_plugin.
*/
-static void
+static void
cdio_log_handler (cdio_log_level_t level, const char message[])
{
switch (level) {
@@ -1480,10 +1478,10 @@ cdio_log_handler (cdio_log_level_t level, const char message[])
}
}
-/*! This routine is when xine is not around.
+/*! This routine is when xine is not around.
Setup is done by vcd_class_dispose.
*/
-static void
+static void
uninit_log_handler (vcd_log_level_t level, const char message[])
{
switch (level) {
@@ -1503,25 +1501,25 @@ uninit_log_handler (vcd_log_level_t level, const char message[])
break;
default:
fprintf(stderr, "UNKNOWN ERROR: %s\n%s %d",
- message,
- _("The above message had unknown vcdimager log level"),
+ message,
+ _("The above message had unknown vcdimager log level"),
level);
}
-
+
/* gl_default_vcd_log_handler (level, message); */
}
/*!
- Things that need to be done the vcd plugin is closed.
+ Things that need to be done the vcd plugin is closed.
*/
-static void
+static void
vcd_class_dispose (input_class_t *this_gen) {
vcd_input_class_t *class = (vcd_input_class_t *) this_gen;
class->xine->config->unregister_callback(class->xine->config,
"media.vcd.device");
gl_default_vcd_log_handler = vcd_log_set_handler (uninit_log_handler);
- gl_default_cdio_log_handler =
+ gl_default_cdio_log_handler =
cdio_log_set_handler ((cdio_log_handler_t) uninit_log_handler);
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n");
@@ -1530,22 +1528,22 @@ vcd_class_dispose (input_class_t *this_gen) {
}
/* Update the xine player title text. */
-static void
-vcd_update_title_display(void)
+static void
+vcd_update_title_display(void)
{
xine_event_t uevent;
xine_ui_data_t data;
char *title_str;
-
- title_str = vcdplayer_format_str(&my_vcd.player,
+
+ title_str = vcdplayer_format_str(&my_vcd.player,
my_vcd.v_config.title_format);
meta_info_assign(XINE_META_INFO_TITLE, my_vcd.stream, title_str);
meta_info_assign(XINE_META_INFO_COMMENT, my_vcd.stream,
- vcdplayer_format_str(&my_vcd.player,
+ vcdplayer_format_str(&my_vcd.player,
my_vcd.v_config.comment_format));
- stream_info_assign(XINE_STREAM_INFO_VIDEO_HAS_STILL, my_vcd.stream,
+ stream_info_assign(XINE_STREAM_INFO_VIDEO_HAS_STILL, my_vcd.stream,
my_vcd.player.i_still);
/* Set_str title/chapter display */
@@ -1563,8 +1561,8 @@ vcd_update_title_display(void)
}
#if LIBVCD_VERSION_NUM >= 23
-static void
-send_mouse_enter_leave_event(vcd_input_plugin_t *p_this, bool b_mouse_in)
+static void
+send_mouse_enter_leave_event(vcd_input_plugin_t *p_this, bool b_mouse_in)
{
if (b_mouse_in && p_this->b_mouse_in) {
/* Set up to enter the following "if" statement. */
@@ -1574,16 +1572,16 @@ send_mouse_enter_leave_event(vcd_input_plugin_t *p_this, bool b_mouse_in)
if (b_mouse_in != p_this->b_mouse_in) {
xine_event_t event;
xine_spu_button_t spu_event;
-
+
spu_event.direction = b_mouse_in ? 1 : 0;
spu_event.button = p_this->i_mouse_button;
-
+
event.type = XINE_EVENT_SPU_BUTTON;
event.stream = p_this->stream;
event.data = &spu_event;
event.data_length = sizeof(spu_event);
xine_event_send(p_this->stream, &event);
-
+
p_this->b_mouse_in = b_mouse_in;
}
@@ -1591,22 +1589,22 @@ send_mouse_enter_leave_event(vcd_input_plugin_t *p_this, bool b_mouse_in)
p_this->i_mouse_button = -1;
}
#endif
-
-/*
- Not much special initialization needed here. All of the initialization
+
+/*
+ Not much special initialization needed here. All of the initialization
is either done in the class or when we have an actual MRL we want
to deal with.
*/
-static int
+static int
vcd_plugin_open (input_plugin_t *this_gen ) {
vcd_input_class_t *class = (vcd_input_class_t *) this_gen->input_class;
gl_default_vcd_log_handler = vcd_log_set_handler (vcd_log_handler);
gl_default_cdio_log_handler = cdio_log_set_handler (cdio_log_handler);
- /* actually, this is also done by class initialization. But just in
+ /* actually, this is also done by class initialization. But just in
case... */
- class->ip = &my_vcd;
+ class->ip = &my_vcd;
my_vcd.i_old_still = 0;
return 1;
@@ -1617,17 +1615,17 @@ vcd_plugin_open (input_plugin_t *this_gen ) {
routine is called, xine-lib can read blocks from the thing
specified by the MRL, set the position of the thing specified by the
MRL, get its size or read its current position...
-
+
See vcdplayer_parses_mrl for the for the format that a valid MRL can take.
- Return values:
+ Return values:
pointer to input plugin
NULL on failure
*/
static input_plugin_t *
vcd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream,
- const char *mrl)
+ const char *mrl)
{
vcd_input_class_t *class = (vcd_input_class_t *) class_gen;
@@ -1636,9 +1634,9 @@ vcd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream,
char *check_mrl=NULL;
bool used_default;
- if (mrl == NULL)
+ if (mrl == NULL)
check_mrl = strdup(MRL_PREFIX);
- else
+ else
check_mrl = strdup(mrl);
dbg_print((INPUT_DBG_CALL|INPUT_DBG_EXT), "called with %s\n", mrl);
@@ -1649,7 +1647,7 @@ vcd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream,
vcd_get_default_device(class, false);
- if (!vcd_parse_mrl(class->vcd_device, check_mrl,
+ if (!vcd_parse_mrl(class->vcd_device, check_mrl,
intended_vcd_device, &itemid,
my_vcd.player.default_autoplay, &used_default)) {
dbg_print(INPUT_DBG_MRL, "parsing MRL %s failed\n", check_mrl);
@@ -1669,32 +1667,32 @@ vcd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream,
my_vcd.player.user_data = (void *) class;
/* Do we set PBC (via LID) on? */
- my_vcd.player.i_lid =
- ( VCDINFO_ITEM_TYPE_LID == itemid.type
+ my_vcd.player.i_lid =
+ ( VCDINFO_ITEM_TYPE_LID == itemid.type
&& my_vcd.player.i_lids > itemid.num )
? itemid.num
: VCDINFO_INVALID_ENTRY;
if ( VCDINFO_ITEM_TYPE_LID == itemid.type && used_default) {
- /* LID was selected automatically but we don't have PBC for this VCD.
+ /* LID was selected automatically but we don't have PBC for this VCD.
So silently change LID to track and continue.
*/
itemid.type=VCDINFO_ITEM_TYPE_TRACK;
}
- if ( 0==itemid.num
- && ( (VCDINFO_ITEM_TYPE_LID == itemid.type)
+ if ( 0==itemid.num
+ && ( (VCDINFO_ITEM_TYPE_LID == itemid.type)
|| (VCDINFO_ITEM_TYPE_TRACK == itemid.type) ) )
itemid.num = 1;
- dbg_print(INPUT_DBG_PBC, "Jumping to NUM >%i<, type >%i<\n",
+ dbg_print(INPUT_DBG_PBC, "Jumping to NUM >%i<, type >%i<\n",
itemid.num, itemid.type);
vcd_set_meta_info(&my_vcd);
vcdplayer_play(&my_vcd.player, itemid);
-
- dbg_print(INPUT_DBG_MRL, "Successfully opened MRL %s.\n",
+
+ dbg_print(INPUT_DBG_MRL, "Successfully opened MRL %s.\n",
my_vcd.mrl);
free (check_mrl);
@@ -1733,30 +1731,30 @@ vcd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream,
var = strdup(entry->str_value); \
}
-VCD_STR_CALLBACK(vcd_default_dev_changed_cb,
+VCD_STR_CALLBACK(vcd_default_dev_changed_cb,
my_vcd.class->vcd_device)
-VCD_STR_CALLBACK(vcd_title_format_changed_cb,
+VCD_STR_CALLBACK(vcd_title_format_changed_cb,
my_vcd.v_config.title_format)
-VCD_STR_CALLBACK(vcd_comment_format_changed_cb,
+VCD_STR_CALLBACK(vcd_comment_format_changed_cb,
my_vcd.v_config.comment_format)
VCD_NUM_CALLBACK(vcd_show_rejected_cb, show_rejected)
VCD_NUM_CALLBACK(vcd_autoadvance_cb, autoadvance)
-VCD_ENUM_CALLBACK(vcd_slider_length_cb, vcdplayer_slider_length_t,
+VCD_ENUM_CALLBACK(vcd_slider_length_cb, vcdplayer_slider_length_t,
slider_length)
VCD_ENUM_CALLBACK(vcd_default_autoplay_cb, vcdinfo_item_enum_t,
default_autoplay)
-static void
-vcd_debug_cb(void *this_gen, xine_cfg_entry_t *entry)
+static void
+vcd_debug_cb(void *this_gen, xine_cfg_entry_t *entry)
{
dbg_print(INPUT_DBG_CALL, "Called setting %d\n", entry->num_value);
- vcdplayer_debug = entry->num_value;
+ vcdplayer_debug = entry->num_value;
}
static void *
@@ -1767,7 +1765,7 @@ vcd_init (xine_t *xine, void *data)
dbg_print(INPUT_DBG_CALL, "Called\n");
- class = (vcd_input_class_t *) xine_xmalloc (sizeof (vcd_input_class_t));
+ class = calloc(1, sizeof (vcd_input_class_t));
class->xine = xine;
class->config = config = xine->config;
@@ -1778,7 +1776,7 @@ vcd_init (xine_t *xine, void *data)
class->input_class.get_instance = vcd_class_get_instance;
class->input_class.get_identifier = vcd_class_get_identifier;
class->input_class.get_description = vcd_class_get_description;
- class->input_class.get_dir = vcd_class_get_dir;
+ class->input_class.get_dir = vcd_class_get_dir;
class->input_class.get_autoplay_list = vcd_class_get_autoplay_list;
class->input_class.dispose = vcd_class_dispose;
class->input_class.eject_media = vcd_class_eject_media;
@@ -1794,9 +1792,9 @@ vcd_init (xine_t *xine, void *data)
my_vcd.player.log_msg = (generic_fn) &xine_log_msg;
my_vcd.player.force_redisplay = &vcd_force_redisplay;
my_vcd.player.set_aspect_ratio = &vcd_set_aspect_ratio;
-
+
/*-------------------------------------------------------------
- Playback control-specific fields
+ Playback control-specific fields
--------------------------------------------------------------*/
my_vcd.player.i_lid = VCDINFO_INVALID_ENTRY;
@@ -1812,58 +1810,58 @@ vcd_init (xine_t *xine, void *data)
my_vcd.player.prev_entry = -1;
my_vcd.player.return_entry = -1;
my_vcd.player.default_entry = -1;
-
+
/*--------------------------------------------------------------
Configuration variables
---------------------------------------------------------------*/
- {
+ {
/*Note: these labels have to be listed in the same order as the
- enumeration vcdplayer_autoplay_t in vcdplayer.h.
+ enumeration vcdplayer_autoplay_t in vcdplayer.h.
*/
- static const char *autoplay_modes[] =
+ static const char *autoplay_modes[] =
{ "MPEG track", "entry", "segment", "playback-control item", NULL };
-
+
/*Note: these labels have to be listed in the same order as the
- enumeration vcdplayer_slider_length_t in vcdplayer.h.
+ enumeration vcdplayer_slider_length_t in vcdplayer.h.
*/
- static const char *length_reporting_modes[] =
+ static const char *length_reporting_modes[] =
{ "auto", "track", "entry", NULL };
-
- my_vcd.player.default_autoplay =
- config->register_enum(config,
+
+ my_vcd.player.default_autoplay =
+ config->register_enum(config,
"media.vcd.autoplay",
VCDPLAYER_AUTOPLAY_PBC,
(char **) autoplay_modes,
_("VCD default type to use on autoplay"),
_("The VCD play unit to use when none is specified in an MRL, e.g. "
"vcd:// or vcd:///dev/dvd:"),
- 10,
+ 10,
vcd_default_autoplay_cb, class);
-
-
- class->vcd_device =
- strdup (config->register_filename(config,
+
+
+ class->vcd_device =
+ strdup (config->register_filename(config,
"media.vcd.device",
"", XINE_CONFIG_STRING_IS_DEVICE_NAME,
_("CD-ROM drive used for VCD when none given"),
-_("What to use if no drive specified. If the setting is empty, xine will scan for CD drives."),
+_("What to use if no drive specified. If the setting is empty, xine will scan for CD drives."),
20,
- vcd_default_dev_changed_cb,
+ vcd_default_dev_changed_cb,
(void *) class));
my_vcd.player.slider_length =
- config->register_enum(config,
+ config->register_enum(config,
"media.vcd.length_reporting",
- VCDPLAYER_SLIDER_LENGTH_AUTO,
+ VCDPLAYER_SLIDER_LENGTH_AUTO,
(char **) length_reporting_modes,
_("VCD position slider range"),
_("range that the stream playback position slider represents playing a VCD."),
- 10,
+ 10,
vcd_slider_length_cb, NULL);
#if READAHEAD_FINISHED
- my_vcd.player.readahead =
+ my_vcd.player.readahead =
config->register_bool(config, "vcd.use_readahead",
(int) false,
_("VCD read-ahead caching?"),
@@ -1873,29 +1871,29 @@ _("range that the stream playback position slider represents playing a VCD."),
vcd_read_ahead_cb, NULL);
#endif
- my_vcd.player.autoadvance =
- config->register_bool(config,
+ my_vcd.player.autoadvance =
+ config->register_bool(config,
"media.vcd.autoadvance",
(int) true,
_("automatically advance VCD track/entry"),
_("If enabled, we should automatically advance to the next entry or track. Used only when playback control (PBC) is disabled."),
- 10,
- vcd_autoadvance_cb,
- NULL);
+ 10,
+ vcd_autoadvance_cb,
+ NULL);
- my_vcd.player.show_rejected =
- config->register_bool(config,
+ my_vcd.player.show_rejected =
+ config->register_bool(config,
"media.vcd.show_rejected",
(int) false,
_("show 'rejected' VCD LIDs"),
_("Some playback list IDs (LIDs) are marked not showable, "
"but you can see them in the MRL list if this is set. Rejected entries "
"are marked with an asterisk (*) appended to the MRL."),
- 10,
- vcd_show_rejected_cb,
- NULL);
+ 10,
+ vcd_show_rejected_cb,
+ NULL);
- my_vcd.v_config.title_format =
+ my_vcd.v_config.title_format =
strdup(config->register_string(config,
"media.vcd.title_format",
"%F - %I %N%L%S, disk %c of %C - %v %A",
@@ -1921,7 +1919,7 @@ _("VCD format used in the GUI Title. Similar to the Unix date "
vcd_title_format_changed_cb,
NULL));
- my_vcd.v_config.comment_format =
+ my_vcd.v_config.comment_format =
strdup(config->register_string(config,
"media.vcd.comment_format",
"%P - Track %T",
@@ -1934,8 +1932,8 @@ _("VCD format used in the GUI Title. Similar to the Unix date "
vcd_comment_format_changed_cb,
NULL));
- vcdplayer_debug =
- config->register_num(config,
+ vcdplayer_debug =
+ config->register_num(config,
"media.vcd.debug",
0,
_("VCD debug flag mask"),
@@ -1954,12 +1952,12 @@ _("For tracking down bugs in the VCD plugin. Mask values are:\n"
"2048: Debugging from VCDINFO\n"
),
20,
- vcd_debug_cb,
- class);
+ vcd_debug_cb,
+ class);
}
-
+
gl_default_vcd_log_handler = vcd_log_set_handler (uninit_log_handler);
- gl_default_cdio_log_handler =
+ gl_default_cdio_log_handler =
cdio_log_set_handler ((cdio_log_handler_t) uninit_log_handler);
my_vcd.input_plugin.open = vcd_plugin_open;
@@ -1979,7 +1977,7 @@ _("For tracking down bugs in the VCD plugin. Mask values are:\n"
my_vcd.class = class;
my_vcd.i_mouse_button = -1;
my_vcd.b_mouse_in = false;
-
+
my_vcd.player.psz_source = NULL;
my_vcd.player.b_opened = false;
@@ -1991,11 +1989,11 @@ _("For tracking down bugs in the VCD plugin. Mask values are:\n"
return class;
}
-/*
+/*
Exported plugin catalog entries.
All plugins listing only the current API number break when the API
- number is increased. This is by design.
+ number is increased. This is by design.
Sometimes in the rush to get out a buggy release, the API number is
increased without communication let alone a concern for whether it
@@ -2012,13 +2010,13 @@ _("For tracking down bugs in the VCD plugin. Mask values are:\n"
*/
const plugin_info_t xine_plugin_info[] EXPORTED = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, (char *) SHORT_PLUGIN_NAME,
XINE_VERSION_CODE, NULL, vcd_init },
{ PLUGIN_NONE, 0, (char *) "", 0, NULL, NULL }
};
-/*
+/*
* Local variables:
* c-file-style: "gnu"
* tab-width: 8
diff --git a/src/input/videodev2.h b/src/input/videodev2.h
index ce32ec9eb..7863e454b 100644
--- a/src/input/videodev2.h
+++ b/src/input/videodev2.h
@@ -113,14 +113,14 @@ enum v4l2_field {
transmitted first */
};
#define V4L2_FIELD_HAS_TOP(field) \
- ((field) == V4L2_FIELD_TOP ||\
+ ((field) == V4L2_FIELD_TOP ||\
(field) == V4L2_FIELD_INTERLACED ||\
(field) == V4L2_FIELD_INTERLACED_TB ||\
(field) == V4L2_FIELD_INTERLACED_BT ||\
(field) == V4L2_FIELD_SEQ_TB ||\
(field) == V4L2_FIELD_SEQ_BT)
#define V4L2_FIELD_HAS_BOTTOM(field) \
- ((field) == V4L2_FIELD_BOTTOM ||\
+ ((field) == V4L2_FIELD_BOTTOM ||\
(field) == V4L2_FIELD_INTERLACED ||\
(field) == V4L2_FIELD_INTERLACED_TB ||\
(field) == V4L2_FIELD_INTERLACED_BT ||\
@@ -254,12 +254,12 @@ struct v4l2_capability
*/
struct v4l2_pix_format
{
- __u32 width;
+ __u32 width;
__u32 height;
__u32 pixelformat;
- enum v4l2_field field;
- __u32 bytesperline; /* for padding, zero if unused */
- __u32 sizeimage;
+ enum v4l2_field field;
+ __u32 bytesperline; /* for padding, zero if unused */
+ __u32 sizeimage;
enum v4l2_colorspace colorspace;
__u32 priv; /* private data, depends on pixelformat */
};
@@ -542,7 +542,7 @@ struct v4l2_clip
struct v4l2_window
{
struct v4l2_rect w;
- enum v4l2_field field;
+ enum v4l2_field field;
__u32 chromakey;
struct v4l2_clip *clips;
__u32 clipcount;
@@ -660,7 +660,7 @@ typedef __u64 v4l2_std_id;
#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
V4L2_STD_NTSC_M_JP |\
V4L2_STD_NTSC_M_KR)
-#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
+#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
V4L2_STD_SECAM_K |\
V4L2_STD_SECAM_K1)
#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
@@ -784,7 +784,7 @@ struct v4l2_ext_controls
#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
-#define V4L2_CTRL_ID_MASK (0x0fffffff)
+#define V4L2_CTRL_ID_MASK (0x0fffffff)
#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
@@ -814,21 +814,21 @@ struct v4l2_querymenu
/* Control flags */
#define V4L2_CTRL_FLAG_DISABLED 0x0001
#define V4L2_CTRL_FLAG_GRABBED 0x0002
-#define V4L2_CTRL_FLAG_READ_ONLY 0x0004
-#define V4L2_CTRL_FLAG_UPDATE 0x0008
-#define V4L2_CTRL_FLAG_INACTIVE 0x0010
-#define V4L2_CTRL_FLAG_SLIDER 0x0020
+#define V4L2_CTRL_FLAG_READ_ONLY 0x0004
+#define V4L2_CTRL_FLAG_UPDATE 0x0008
+#define V4L2_CTRL_FLAG_INACTIVE 0x0010
+#define V4L2_CTRL_FLAG_SLIDER 0x0020
/* Query flag, to be ORed with the control ID */
#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
/* User-class control IDs defined by V4L2 */
#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
-#define V4L2_CID_USER_BASE V4L2_CID_BASE
+#define V4L2_CID_USER_BASE V4L2_CID_BASE
/* IDs reserved for driver specific controls */
#define V4L2_CID_PRIVATE_BASE 0x08000000
-#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1)
+#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1)
#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
@@ -856,11 +856,11 @@ struct v4l2_querymenu
#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */
/* MPEG-class control IDs defined by V4L2 */
-#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
-#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
+#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
+#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
/* MPEG streams */
-#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0)
+#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0)
enum v4l2_mpeg_stream_type {
V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */
V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */
@@ -869,32 +869,32 @@ enum v4l2_mpeg_stream_type {
V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */
V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */
};
-#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1)
-#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2)
-#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3)
-#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4)
-#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5)
-#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6)
-#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7)
+#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1)
+#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2)
+#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3)
+#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4)
+#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5)
+#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6)
+#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7)
enum v4l2_mpeg_stream_vbi_fmt {
V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */
V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */
};
/* MPEG audio */
-#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100)
+#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100)
enum v4l2_mpeg_audio_sampling_freq {
V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
};
-#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101)
+#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101)
enum v4l2_mpeg_audio_encoding {
V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
};
-#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
+#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
enum v4l2_mpeg_audio_l1_bitrate {
V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0,
V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1,
@@ -911,7 +911,7 @@ enum v4l2_mpeg_audio_l1_bitrate {
V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
};
-#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103)
+#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103)
enum v4l2_mpeg_audio_l2_bitrate {
V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0,
V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1,
@@ -928,7 +928,7 @@ enum v4l2_mpeg_audio_l2_bitrate {
V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
};
-#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104)
+#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104)
enum v4l2_mpeg_audio_l3_bitrate {
V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0,
V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1,
@@ -945,70 +945,70 @@ enum v4l2_mpeg_audio_l3_bitrate {
V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
};
-#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105)
+#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105)
enum v4l2_mpeg_audio_mode {
V4L2_MPEG_AUDIO_MODE_STEREO = 0,
V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
V4L2_MPEG_AUDIO_MODE_DUAL = 2,
V4L2_MPEG_AUDIO_MODE_MONO = 3,
};
-#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106)
+#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106)
enum v4l2_mpeg_audio_mode_extension {
V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0,
V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1,
V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
};
-#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107)
+#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107)
enum v4l2_mpeg_audio_emphasis {
V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0,
V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2,
};
-#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108)
+#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108)
enum v4l2_mpeg_audio_crc {
V4L2_MPEG_AUDIO_CRC_NONE = 0,
V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
};
-#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109)
+#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109)
/* MPEG video */
-#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
+#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
enum v4l2_mpeg_video_encoding {
V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1,
};
-#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201)
+#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201)
enum v4l2_mpeg_video_aspect {
V4L2_MPEG_VIDEO_ASPECT_1x1 = 0,
V4L2_MPEG_VIDEO_ASPECT_4x3 = 1,
V4L2_MPEG_VIDEO_ASPECT_16x9 = 2,
V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
};
-#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202)
-#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203)
-#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204)
-#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205)
-#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206)
+#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202)
+#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203)
+#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204)
+#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206)
enum v4l2_mpeg_video_bitrate_mode {
V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
};
-#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
-#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
+#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
-#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
-#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
+#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
+#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
/* MPEG-class control IDs specific to the CX2584x driver as defined by V4L2 */
-#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
+#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1,
};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2)
enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0,
V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
@@ -1016,18 +1016,18 @@ enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3,
V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3)
enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type {
V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0,
V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4)
enum v4l2_mpeg_cx2341x_video_temporal_filter_mode {
V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1,
};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6)
enum v4l2_mpeg_cx2341x_video_median_filter_type {
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0,
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1,
@@ -1035,11 +1035,11 @@ enum v4l2_mpeg_cx2341x_video_median_filter_type {
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4,
};
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
-#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
+#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11)
/*
* T U N I N G
@@ -1362,8 +1362,8 @@ struct v4l2_chip_ident {
#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression)
#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression)
-#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
-#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
+#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio)
#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
@@ -1381,20 +1381,20 @@ struct v4l2_chip_ident {
#define VIDIOC_TRY_ENCODER_CMD _IOWR ('V', 78, struct v4l2_encoder_cmd)
/* Experimental, only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
-#define VIDIOC_DBG_S_REGISTER _IOW ('V', 79, struct v4l2_register)
-#define VIDIOC_DBG_G_REGISTER _IOWR ('V', 80, struct v4l2_register)
+#define VIDIOC_DBG_S_REGISTER _IOW ('V', 79, struct v4l2_register)
+#define VIDIOC_DBG_G_REGISTER _IOWR ('V', 80, struct v4l2_register)
#define VIDIOC_G_CHIP_IDENT _IOWR ('V', 81, struct v4l2_chip_ident)
#endif
#ifdef __OLD_VIDIOC_
/* for compatibility, will go away some day */
-#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
-#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
-#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
-#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
-#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
-#define VIDIOC_CROPCAP_OLD _IOR ('V', 58, struct v4l2_cropcap)
+#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
+#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
+#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
+#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
+#define VIDIOC_CROPCAP_OLD _IOR ('V', 58, struct v4l2_cropcap)
#endif
#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */