summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Holst <holstsn@users.sourceforge.net>2002-12-12 22:08:09 +0000
committerStefan Holst <holstsn@users.sourceforge.net>2002-12-12 22:08:09 +0000
commit41760a052b481e67ba31af505352860be86b94bf (patch)
tree1cd421c33a9c976d0e932c286c0ae4cd59a27b63
parent0edd77bcd29eaadd898ba789ac6b594c13cd6eb4 (diff)
downloadxine-lib-41760a052b481e67ba31af505352860be86b94bf.tar.gz
xine-lib-41760a052b481e67ba31af505352860be86b94bf.tar.bz2
* Initial version of an rtsp input plugin. It is far from being perfect,
only a few streams work for now. * A couple of fixes in pnm input plugin. * Fixed stream info in demux_real. CVS patchset: 3495 CVS date: 2002/12/12 22:08:09
-rw-r--r--configure.ac2
-rw-r--r--src/demuxers/demux_real.c9
-rw-r--r--src/input/Makefile.am11
-rw-r--r--src/input/input_pnm.c24
-rw-r--r--src/input/input_rtsp.c297
-rw-r--r--src/input/pnm.c219
-rw-r--r--src/input/pnm.h5
7 files changed, 417 insertions, 150 deletions
diff --git a/configure.ac b/configure.ac
index f55d6e1ae..cf91c925c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1159,6 +1159,8 @@ src/dxr3/Makefile
src/input/Makefile
src/input/libdvdnav/Makefile
src/input/libdvdread/Makefile
+src/input/librtsp/Makefile
+src/input/libreal/Makefile
src/liba52/Makefile
src/libdts/Makefile
src/libfaad/Makefile
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index ec565c575..b5e7d2d5e 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -21,7 +21,7 @@
* For more information regarding the Real file format, visit:
* http://www.pcisys.net/~melanson/codecs/
*
- * $Id: demux_real.c,v 1.22 2002/12/12 17:51:03 holstsn Exp $
+ * $Id: demux_real.c,v 1.23 2002/12/12 22:08:11 holstsn Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -92,7 +92,6 @@ typedef struct {
int status;
unsigned int duration;
int packet_count;
- int bitrate;
int video_stream_num;
uint32_t video_buf_type;
@@ -328,9 +327,6 @@ static void real_parse_headers (demux_real_t *this) {
mdpr = pnm_parse_mdpr (chunk_buffer);
- this->bitrate = mdpr->avg_bit_rate;
- this->stream->stream_info[XINE_STREAM_INFO_BITRATE] = mdpr->avg_bit_rate;
-
#ifdef LOG
printf ("demux_real: parsing type specific data...\n");
#endif
@@ -359,6 +355,8 @@ static void real_parse_headers (demux_real_t *this) {
printf ("demux_real: audio detected %.3s\n",
mdpr->type_specific_data+off+4);
#endif
+ this->stream->stream_info[XINE_STREAM_INFO_AUDIO_BITRATE] = mdpr->avg_bit_rate;
+
version = BE_16 (mdpr->type_specific_data+off);
@@ -453,6 +451,7 @@ static void real_parse_headers (demux_real_t *this) {
#ifdef LOG
printf ("demux_real: video detected\n");
#endif
+ this->stream->stream_info[XINE_STREAM_INFO_VIDEO_BITRATE] = mdpr->avg_bit_rate;
/* FIXME: insert video codec detection code here */
break; /* video */
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
index a5d301066..d662ba379 100644
--- a/src/input/Makefile.am
+++ b/src/input/Makefile.am
@@ -3,9 +3,9 @@
##
if HAVE_DVDNAV
-SUBDIRS = libdvdread
+SUBDIRS = libreal librtsp libdvdread
else
-SUBDIRS = libdvdread libdvdnav
+SUBDIRS = libreal librtsp libdvdread libdvdnav
endif
LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
@@ -48,7 +48,8 @@ lib_LTLIBRARIES = \
$(in_vcd) \
xineplug_inp_mms.la \
xineplug_inp_stdin_fifo.la \
- xineplug_inp_pnm.la
+ xineplug_inp_pnm.la \
+ xineplug_inp_rtsp.la
#lib_LTLIBRARIES = \
# $(in_cda) \
@@ -102,6 +103,10 @@ xineplug_inp_pnm_la_SOURCES = input_pnm.c net_buf_ctrl.c pnm.c
xineplug_inp_pnm_la_LIBADD = $(XINE_LIB)
xineplug_inp_pnm_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
+xineplug_inp_rtsp_la_SOURCES = input_rtsp.c net_buf_ctrl.c
+xineplug_inp_rtsp_la_LIBADD = $(XINE_LIB) libreal/libreal.la librtsp/librtsp.la
+xineplug_inp_rtsp_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
+
include_HEADERS = input_plugin.h
noinst_HEADERS = net_buf_ctrl.h mms.h pnm.h
diff --git a/src/input/input_pnm.c b/src/input/input_pnm.c
index e30d0e721..35f4ea2d1 100644
--- a/src/input/input_pnm.c
+++ b/src/input/input_pnm.c
@@ -43,9 +43,11 @@
#include "pnm.h"
#include "net_buf_ctrl.h"
-
+/*
#define LOG
+*/
+#define BUFSIZE 1025
extern int errno;
@@ -71,7 +73,7 @@ typedef struct {
nbc_t *nbc;
- char scratch[1025];
+ char scratch[BUFSIZE];
} pnm_input_plugin_t;
@@ -121,11 +123,23 @@ static buf_element_t *pnm_plugin_read_block (input_plugin_t *this_gen,
}
static off_t pnm_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
- /*
pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen;
- */
- return -1;
+ printf ("input_pnm: seek %lld bytes, origin %d\n",
+ offset, origin);
+
+ /* only realtive forward-seeking is implemented */
+
+ if ((origin == SEEK_CUR) && (offset >= 0)) {
+
+ for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
+ this->curpos += pnm_plugin_read (this_gen, this->scratch, BUFSIZE);
+ }
+
+ this->curpos += pnm_plugin_read (this_gen, this->scratch, offset);
+ }
+
+ return this->curpos;
}
static off_t pnm_plugin_get_length (input_plugin_t *this_gen) {
diff --git a/src/input/input_rtsp.c b/src/input/input_rtsp.c
new file mode 100644
index 000000000..ad483bde8
--- /dev/null
+++ b/src/input/input_rtsp.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * rtsp input plugin
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <assert.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "bswap.h"
+
+#include "xine_internal.h"
+#include "xineutils.h"
+#include "input_plugin.h"
+
+#include "librtsp/rtsp_session.h"
+#include "net_buf_ctrl.h"
+
+/*
+#define LOG
+*/
+
+#define BUFSIZE 1025
+
+extern int errno;
+
+#if !defined(NDELAY) && defined(O_NDELAY)
+#define FNDELAY O_NDELAY
+#endif
+
+typedef struct {
+
+ input_class_t input_class;
+
+ xine_t *xine;
+} rtsp_input_class_t;
+
+typedef struct {
+ input_plugin_t input_plugin;
+
+ rtsp_session_t *rtsp;
+
+ char *mrl;
+
+ off_t curpos;
+
+ nbc_t *nbc;
+
+ char scratch[BUFSIZE];
+
+} rtsp_input_plugin_t;
+
+
+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;
+
+#ifdef LOG
+ printf ("rtsp_plugin_read: %lld bytes ...\n",
+ len);
+#endif
+
+ nbc_check_buffers (this->nbc);
+
+ n = rtsp_session_read (this->rtsp, buf, len);
+ this->curpos += n;
+
+ return n;
+}
+
+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);
+ int total_bytes;
+
+#ifdef LOG
+ printf ("rtsp_plugin_read_block: %lld bytes...\n",
+ todo);
+#endif
+
+ buf->content = buf->mem;
+ buf->type = BUF_DEMUX_BLOCK;
+
+ total_bytes = rtsp_plugin_read (this_gen, buf->content, todo);
+
+ if (total_bytes != todo) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
+ buf->size = total_bytes;
+
+ return buf;
+}
+
+static off_t rtsp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
+
+ rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
+
+ printf ("input_rtsp: seek %lld bytes, origin %d\n",
+ offset, origin);
+
+ /* only realtive forward-seeking is implemented */
+
+ if ((origin == SEEK_CUR) && (offset >= 0)) {
+
+ for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
+ this->curpos += rtsp_plugin_read (this_gen, this->scratch, BUFSIZE);
+ }
+
+ this->curpos += rtsp_plugin_read (this_gen, this->scratch, 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;
+ off_t length;
+ */
+
+ return -1;
+}
+
+static uint32_t rtsp_plugin_get_capabilities (input_plugin_t *this_gen) {
+ return INPUT_CAP_NOCAP;
+}
+
+static uint32_t rtsp_plugin_get_blocksize (input_plugin_t *this_gen) {
+ return 0;
+}
+
+static off_t rtsp_plugin_get_current_pos (input_plugin_t *this_gen){
+ rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
+
+ /*
+ printf ("current pos is %lld\n", this->curpos);
+ */
+
+ return this->curpos;
+}
+
+static void rtsp_plugin_dispose (input_plugin_t *this_gen) {
+ rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
+
+ if (this->rtsp) {
+ rtsp_session_end (this->rtsp);
+ this->rtsp = NULL;
+ }
+
+ if (this->nbc) {
+ nbc_close (this->nbc);
+ this->nbc = NULL;
+ }
+
+ if(this->mrl)
+ free(this->mrl);
+
+ free (this);
+}
+
+static char* rtsp_plugin_get_mrl (input_plugin_t *this_gen) {
+ rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen;
+
+ return this->mrl;
+}
+
+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; */
+
+ return INPUT_OPTIONAL_UNSUPPORTED;
+}
+
+static input_plugin_t *open_plugin (input_class_t *cls_gen, xine_stream_t *stream,
+ const char *data) {
+
+ /* rtsp_input_class_t *cls = (rtsp_input_class_t *) cls_gen; */
+ rtsp_input_plugin_t *this;
+ rtsp_session_t *rtsp;
+ char *mrl = strdup(data);
+
+#ifdef LOG
+ printf ("input_rtsp: trying to open '%s'\n", mrl);
+#endif
+
+ if (strncasecmp (mrl, "rtsp://", 6)) {
+ free (mrl);
+ return NULL;
+ }
+
+ rtsp = rtsp_session_start(mrl);
+
+ if (!rtsp) {
+ free (mrl);
+ return NULL;
+ }
+
+ this = (rtsp_input_plugin_t *) xine_xmalloc (sizeof (rtsp_input_plugin_t));
+
+ this->rtsp = rtsp;
+ this->mrl = mrl;
+ this->nbc = nbc_init (stream);
+
+ this->input_plugin.get_capabilities = rtsp_plugin_get_capabilities;
+ this->input_plugin.read = rtsp_plugin_read;
+ this->input_plugin.read_block = rtsp_plugin_read_block;
+ this->input_plugin.seek = rtsp_plugin_seek;
+ this->input_plugin.get_current_pos = rtsp_plugin_get_current_pos;
+ this->input_plugin.get_length = rtsp_plugin_get_length;
+ this->input_plugin.get_blocksize = rtsp_plugin_get_blocksize;
+ this->input_plugin.get_mrl = rtsp_plugin_get_mrl;
+ 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;
+}
+
+/*
+ * rtsp input plugin class stuff
+ */
+
+static char *rtsp_class_get_description (input_class_t *this_gen) {
+ return _("rtsp streaming input plugin");
+}
+
+static char *rtsp_class_get_identifier (input_class_t *this_gen) {
+ return "rtsp";
+}
+
+static void rtsp_class_dispose (input_class_t *this_gen) {
+ rtsp_input_class_t *this = (rtsp_input_class_t *) this_gen;
+
+ free (this);
+}
+
+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->xine = xine;
+
+ this->input_class.open_plugin = open_plugin;
+ this->input_class.get_identifier = rtsp_class_get_identifier;
+ this->input_class.get_description = rtsp_class_get_description;
+ this->input_class.get_dir = NULL;
+ this->input_class.get_autoplay_list = NULL;
+ this->input_class.dispose = rtsp_class_dispose;
+ this->input_class.eject_media = NULL;
+
+ return this;
+}
+
+/*
+ * exported plugin catalog entry
+ */
+
+plugin_info_t xine_plugin_info[] = {
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_INPUT, 10, "rtsp", XINE_VERSION_CODE, NULL, init_class },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+};
+
diff --git a/src/input/pnm.c b/src/input/pnm.c
index 8341e23e6..419f32ccc 100644
--- a/src/input/pnm.c
+++ b/src/input/pnm.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: pnm.c,v 1.1 2002/11/23 00:04:32 guenter Exp $
+ * $Id: pnm.c,v 1.2 2002/12/12 22:08:14 holstsn Exp $
*
* pnm protocol implementation by joschka
*/
@@ -29,7 +29,6 @@
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
@@ -37,8 +36,11 @@
#include <time.h>
#include "pnm.h"
+#include "libreal/rmff.h"
+/*
#define LOG
+*/
#define BUF_SIZE 1024
#define HEADER_SIZE 1024
@@ -64,6 +66,8 @@ struct pnm_s {
int header_read;
unsigned int seq_num[4]; /* two streams with two indices */
unsigned int seq_current[2]; /* seqs of last stream chunk read */
+ uint32_t ts_current; /* timestamp of current chunk */
+ uint32_t ts_last[2]; /* timestamps of last chunks */
unsigned int packet; /* number of last recieved packet */
};
@@ -71,12 +75,6 @@ struct pnm_s {
* utility macros
*/
-#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
- ( (long)(unsigned char)(ch3) | \
- ( (long)(unsigned char)(ch2) << 8 ) | \
- ( (long)(unsigned char)(ch1) << 16 ) | \
- ( (long)(unsigned char)(ch0) << 24 ) )
-
#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
(((uint8_t*)(x))[1] << 16) | \
@@ -86,24 +84,6 @@ struct pnm_s {
/* D means direct (no pointer) */
#define BE_16D(x) ((x & 0xff00) >> 8)|((x & 0x00ff) << 8)
-/*
- * constants
- */
-
-#define RMF_TAG FOURCC_TAG('.', 'R', 'M', 'F')
-#define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P')
-#define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R')
-#define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T')
-#define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A')
-#define INDX_TAG FOURCC_TAG('I', 'N', 'D', 'X')
-#define PNA_TAG FOURCC_TAG('P', 'N', 'A', 0 )
-
-/* prop flags */
-#define PN_SAVE_ENABLED 0x01
-#define PN_PERFECT_PLAY_ENABLED 0x02
-#define PN_LIVE_BROADCAST 0x04
-
-
/* sizes */
#define PREAMBLE_SIZE 8
#define CHECKSUM_SIZE 3
@@ -182,24 +162,6 @@ const uint32_t pnm_default_bandwidth=10485800;
const uint32_t pnm_available_bandwidths[]={14400,19200,28800,33600,34430,57600,
115200,262200,393216,524300,1544000,10485800};
-/* some unknown chunks */
-#define PNM_AFTER_CLIENT_CAPS_SIZE 18
-const unsigned char pnm_after_client_caps[]={
- 0x00, 0x0a, 0x00, 0x00,
- 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x0d, 0x00, 0x00,
- 0x00, 0x16, 0x00, 0x02, 0x00, 0x01 };
-
-#define PNM_AFTER_BANDWIDTH_SIZE 28
-const unsigned char pnm_after_bandwidth[]={
- 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x0e, 0x00, 0x00,
- 0x00, 0x0f, 0x00, 0x00,
- 0x00, 0x11, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x15, 0x00, 0x00,
- 0x00, 0x12, 0x00, 0x00 };
-
#define PNM_TWENTYFOUR_SIZE 16
unsigned char pnm_twentyfour[]={
0xd5, 0x42, 0xa3, 0x1b, 0xef, 0x1f, 0x70, 0x24,
@@ -302,7 +264,7 @@ static ssize_t rm_read(int fd, void *buf, size_t count) {
FD_ZERO (&rset);
FD_SET (fd, &rset);
- timeout.tv_sec = 30;
+ timeout.tv_sec = 3;
timeout.tv_usec = 0;
if (select (fd+1, &rset, NULL, NULL, &timeout) <= 0) {
@@ -357,23 +319,6 @@ static void hexdump (char *buf, int length) {
}
/*
- * basic stream reading
- */
-
-static char *pnm_get_string(unsigned char *data) {
-
- char *string;
- int length;
-
- length=BE_16(data);
- string=malloc(sizeof(char)*(length+1));
- memcpy(string,&data[2],length);
- string[length]=0;
-
- return string;
-}
-
-/*
* pnm_get_chunk gets a chunk from stream
* and returns number of bytes read
*/
@@ -411,6 +356,12 @@ static unsigned int pnm_get_chunk(pnm_t *p,
printf("%s\n",&data[PREAMBLE_SIZE+0x04]);
exit(0);
}
+ if (data[PREAMBLE_SIZE+0x01] == 'F')
+ {
+ printf("pnm: server error.\n");
+ exit(0);
+ }
+
/* expecting following chunk format: 0x4f <chunk size> <data...> */
rm_read (p->s, ptr, 2);
while (*ptr == 0x4f) {
@@ -467,7 +418,6 @@ static int pnm_write_chunk(uint16_t chunk_id, uint16_t length,
static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {
uint16_t i16;
- uint32_t bw;
int c=PNM_HEADER_SIZE;
char fixme[]={0,1};
@@ -502,7 +452,7 @@ static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {
/* client id string */
p->buffer[c]=PNA_CLIENT_STRING;
- i16=BE_16D(strlen(client_string)-1); /* dont know why do we have -1 here */
+ i16=BE_16D((strlen(client_string)-1)); /* dont know why do we have -1 here */
memcpy(&p->buffer[c+1],&i16,2);
memcpy(&p->buffer[c+3],client_string,strlen(client_string)+1);
c=c+3+strlen(client_string)+1;
@@ -551,7 +501,8 @@ static void pnm_get_headers(pnm_t *p) {
uint8_t *ptr=p->header;
uint8_t *prop_hdr=NULL;
int chunk_size,size=0;
-
+/* rmff_header_t *h; */
+
while(1) {
if (HEADER_SIZE-size<=0)
{
@@ -572,13 +523,16 @@ static void pnm_get_headers(pnm_t *p) {
}
/* set pre-buffer to a low number */
- prop_hdr[36]=0x01;
- prop_hdr[37]=0xd6;
+ /* prop_hdr[36]=0x01;
+ prop_hdr[37]=0xd6; */
+ /* set data offset */
+ size--;
prop_hdr[42]=(size>>24)%0xff;
prop_hdr[43]=(size>>16)%0xff;
prop_hdr[44]=(size>>8)%0xff;
prop_hdr[45]=(size)%0xff;
+ size++;
/* read challenge */
memcpy (p->buffer, ptr, PREAMBLE_SIZE);
@@ -587,7 +541,12 @@ static void pnm_get_headers(pnm_t *p) {
/* 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;
}
@@ -620,7 +579,7 @@ static int pnm_calc_stream(pnm_t *p) {
}
break;
case 0:
- case 2: /* both types or none possible, not so good */
+ case 2: /* both types or none possible, not so good */
/* try to figure out by second index */
if ( (p->seq_current[1] == p->seq_num[1])
&&(p->seq_current[1] != p->seq_num[3]))
@@ -638,8 +597,14 @@ static int pnm_calc_stream(pnm_t *p) {
p->seq_num[3]++;
return 1;
}
- /* wow, both streams match, or not. */
- /* in this case, we guess type 0 */
+ /* wow, both streams match, or not. */
+ /* now we try to decide by timestamps */
+ if (p->ts_current < p->ts_last[1])
+ return 0;
+ if (p->ts_current < p->ts_last[0])
+ return 1;
+ /* does not help, we guess type 0 */
+ printf("guessing stream# 0\n");
p->seq_num[0]=p->seq_current[0]+1;
p->seq_num[1]=p->seq_current[1]+1;
return 0;
@@ -680,6 +645,9 @@ static int pnm_get_stream_chunk(pnm_t *p) {
{
n = rm_read (p->s, p->buffer, 8);
if (n<8) return 0;
+#ifdef LOG
+ printf("pnm: had to seek 8 bytes on 0x62\n");
+#endif
}
/* a server message */
@@ -692,6 +660,11 @@ static int pnm_get_stream_chunk(pnm_t *p) {
printf("pnm: got message from server:\n%s\n", &p->buffer[3]);
exit(0);
}
+ if (p->buffer[0] == 'F')
+ {
+ printf("pnm: server error.\n");
+ exit(0);
+ }
/* skip bytewise to next chunk.
* seems, that we dont need that, if we send enough
@@ -706,8 +679,9 @@ static int pnm_get_stream_chunk(pnm_t *p) {
rm_read (p->s, &p->buffer[7], 1);
n++;
}
+
if (n) printf("pnm: had to seek %i bytes to next chunk\n", n);
-
+
/* check for 'Z's */
if ((p->buffer[0] != 0x5a)||(p->buffer[7] != 0x5a))
{
@@ -735,8 +709,14 @@ static int pnm_get_stream_chunk(pnm_t *p) {
/* get second index */
p->seq_current[1]=p->recv[5];
+ /* get timestamp */
+ p->ts_current=BE_32(&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 */
@@ -843,80 +823,51 @@ pnm_t *pnm_connect(const char *mrl) {
pnm_send_request(p,pnm_available_bandwidths[10]);
pnm_get_headers(p);
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);
+ p->recv_size = p->header_len;
+ p->recv_read = 0;
return p;
}
int pnm_read (pnm_t *this, char *data, int len) {
- int total;
-
- total = 0;
-
- while (total < len) {
+
+ int to_copy=len;
+ char *dest=data;
+ char *source=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;
+ this->recv_read=0;
+ if (!pnm_get_stream_chunk (this)) {
#ifdef LOG
- printf ("libpnm: read, got %d / %d bytes\n", total, len);
+ printf ("libpnm: %d of %d bytes provided\n", len-to_copy, len);
#endif
-
- if (this->header_read < this->header_len) {
- int n, bytes_left ;
-
- printf ("libpnm: reading from header (%d<%d)\n",
- this->header_read, this->header_len);
-
- bytes_left = this->header_len - this->header_read ;
-
- if ((len-total) < bytes_left)
- n = len-total;
- else
- n = bytes_left;
-
- memcpy (&data[total], &this->header[this->header_read], n);
-
- printf ("libpnm: copied %d bytes\n", n);
-
- this->header_read += n;
- total += n;
- } else {
-
- int n, bytes_left ;
-
- printf ("libpnm: reading from chunk (%d>=%d)\n",
- this->header_read, this->header_len);
-
- bytes_left = this->recv_size - this->recv_read;
-
- while (!bytes_left) {
-
- this->recv_read = 0;
-
- if (!pnm_get_stream_chunk (this)) {
- printf ("libpnm: pnm_get_stream_chunk failed\n");
- return total;
- }
- bytes_left = this->recv_size - this->recv_read;
- }
-
-
- if ((len-total)<bytes_left)
- n = len-total;
- else
- n = bytes_left;
-
- memcpy (&data[total], &this->recv[this->recv_read], n);
-
- printf ("libpnm: copied %d bytes\n", n);
-
- this->recv_read += n;
- total += n;
+ return len-to_copy;
}
+ source = this->recv;
+ fill = this->recv_size - this->recv_read;
}
- printf ("libpnm: total=%d\n", total);
+ memcpy(dest, source, to_copy);
+ this->recv_read += to_copy;
- hexdump (data, total);
+#ifdef LOG
+ printf ("libpnm: %d bytes provided\n", len);
+#endif
- return total;
+ return len;
}
int pnm_peek_header (pnm_t *this, char *data) {
@@ -934,5 +885,3 @@ void pnm_close(pnm_t *p) {
free(p);
}
-
-
diff --git a/src/input/pnm.h b/src/input/pnm.h
index 8d07986ab..a2fb68539 100644
--- a/src/input/pnm.h
+++ b/src/input/pnm.h
@@ -17,16 +17,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: pnm.h,v 1.1 2002/11/23 00:04:32 guenter Exp $
+ * $Id: pnm.h,v 1.2 2002/12/12 22:08:15 holstsn Exp $
*
* pnm util functions header by joschka
- *
*/
#ifndef HAVE_PNM_H
#define HAVE_PNM_H
+#ifndef __CYGWIN__
#include <inttypes.h>
+#endif
/*#include "xine_internal.h" */
typedef struct pnm_s pnm_t;