summaryrefslogtreecommitdiff
path: root/src/input
diff options
context:
space:
mode:
Diffstat (limited to 'src/input')
-rw-r--r--src/input/input_mms.c61
-rw-r--r--src/input/mms.c25
-rw-r--r--src/input/mms.h4
-rw-r--r--src/input/mmsh.c178
-rw-r--r--src/input/mmsh.h4
5 files changed, 172 insertions, 100 deletions
diff --git a/src/input/input_mms.c b/src/input/input_mms.c
index 8c4718ac3..d353895b6 100644
--- a/src/input/input_mms.c
+++ b/src/input/input_mms.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: input_mms.c,v 1.46 2004/02/17 13:40:57 valtri Exp $
+ * $Id: input_mms.c,v 1.47 2004/04/06 00:25:29 tmattern Exp $
*
* mms input plugin based on work from major mms
*/
@@ -82,8 +82,6 @@ typedef struct {
char *mrl;
- off_t curpos;
-
nbc_t *nbc;
char scratch[1025];
@@ -110,8 +108,6 @@ static off_t mms_plugin_read (input_plugin_t *this_gen,
lprintf ("mms_plugin_read: %lld bytes ...\n", len);
- nbc_check_buffers (this->nbc);
-
switch (this->protocol) {
case PROTOCOL_MMST:
n = mms_read (this->mms, buf, len);
@@ -120,8 +116,6 @@ static off_t mms_plugin_read (input_plugin_t *this_gen,
n = mmsh_read (this->mmsh, buf, len);
break;
}
-
- this->curpos += n;
return n;
}
@@ -151,37 +145,45 @@ 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;
- off_t dest = this->curpos;
+ off_t dest = 0;
+ off_t curpos = 0;
lprintf ("mms_plugin_seek: %lld offset, %d origin...\n", offset, origin);
+
+ switch (this->protocol) {
+ case PROTOCOL_MMST:
+ curpos = mms_get_current_pos (this->mms);
+ break;
+ case PROTOCOL_MMSH:
+ curpos = mmsh_get_current_pos (this->mmsh);
+ break;
+ }
+
switch (origin) {
case SEEK_SET:
dest = offset;
break;
case SEEK_CUR:
- dest = this->curpos + offset;
+ dest = curpos + offset;
break;
- case SEEK_END:
- printf ("input_mms: SEEK_END not implemented!\n");
- return this->curpos;
default:
printf ("input_mms: unknown origin in seek!\n");
- return this->curpos;
+ return curpos;
}
- if (this->curpos > dest) {
+ if (curpos > dest) {
printf ("input_mms: cannot seek back!\n");
- return this->curpos;
+ return curpos;
}
-
- while (this->curpos<dest) {
+
+ while (curpos < dest) {
int n = 0;
int diff;
- diff = dest - this->curpos;
+ diff = dest - curpos;
- if (diff>1024)
+ if (diff > 1024)
diff = 1024;
switch (this->protocol) {
@@ -193,14 +195,14 @@ static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
break;
}
- this->curpos += n;
+ curpos += n;
if (n < diff)
- return this->curpos;
+ return curpos;
}
- return this->curpos;
+ return curpos;
}
static off_t mms_plugin_get_length (input_plugin_t *this_gen) {
@@ -235,12 +237,21 @@ 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;
+
/*
printf ("current pos is %lld\n", this->curpos);
*/
+ switch (this->protocol) {
+ case PROTOCOL_MMST:
+ curpos = mms_get_current_pos(this->mms);
+ break;
+ case PROTOCOL_MMSH:
+ curpos = mmsh_get_current_pos(this->mmsh);
+ break;
+ }
- return this->curpos;
+ return curpos;
}
static void mms_plugin_dispose (input_plugin_t *this_gen) {
@@ -351,7 +362,6 @@ static int mms_plugin_open (input_plugin_t *this_gen) {
this->mms = mms;
this->mmsh = mmsh;
- this->curpos = 0;
return 1;
}
@@ -385,7 +395,6 @@ static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stre
this->mmsh = NULL;
this->protocol = protocol;
this->mrl = mrl;
- this->curpos = 0;
this->nbc = nbc_init (this->stream);
if (xine_config_lookup_entry (stream->xine, "input.mms_network_bandwidth",
diff --git a/src/input/mms.c b/src/input/mms.c
index a101e1324..e5e4ce027 100644
--- a/src/input/mms.c
+++ b/src/input/mms.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: mms.c,v 1.43 2004/04/04 12:19:06 tmattern Exp $
+ * $Id: mms.c,v 1.44 2004/04/06 00:25:29 tmattern Exp $
*
* MMS over TCP protocol
* based on work from major mms
@@ -25,7 +25,7 @@
*
* TODO:
* general cleanup, error messages
- * allways check packet size
+ * always check packet size
* enable seeking !
*/
@@ -126,6 +126,7 @@ struct mms_s {
int has_audio;
int has_video;
int live_flag;
+ off_t current_pos;
};
@@ -487,6 +488,7 @@ static void interp_header (mms_t *this) {
/*
* parse header
*/
+
i = 30;
while (i < this->asf_header_len) {
@@ -804,6 +806,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
this->has_audio = 0;
this->has_video = 0;
this->bandwidth = bandwidth;
+ this->current_pos = 0;
report_progress (stream, 0);
@@ -963,6 +966,7 @@ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) {
#endif
lprintf("mms_connect: passed\n" );
+
return this;
fail:
@@ -1007,10 +1011,16 @@ static int get_media_packet (mms_t *this) {
if (pre_header[4] == 0x04) {
- uint32_t packet_len;
+ uint32_t packet_len, sequence;
- packet_len = (pre_header[7] << 8 | pre_header[6]) - 8;
+ packet_len = LE_16(&pre_header[6]) - 8;
+ sequence = LE_32(&pre_header[0]);
+ lprintf ("sequence=%d\n", sequence);
+
+ /* simulate a seek */
+ this->current_pos = this->asf_header_len + sequence * this->packet_length;
+
lprintf ("asf media packet detected, len=%d\n", packet_len);
if (packet_len > (BUF_SIZE)) {
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
@@ -1109,6 +1119,7 @@ static int get_media_packet (mms_t *this) {
"failed to send command 0x07\n");
return 0;
}
+ this->current_pos = 0;
} else if (command != 0x05) {
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
@@ -1157,6 +1168,7 @@ int mms_read (mms_t *this, char *data, int len) {
this->asf_header_read += n;
total += n;
+ this->current_pos += n;
} else {
int n, bytes_left ;
@@ -1181,6 +1193,7 @@ int mms_read (mms_t *this, char *data, int len) {
this->buf_read += n;
total += n;
+ this->current_pos += n;
}
}
return total;
@@ -1210,3 +1223,7 @@ void mms_close (mms_t *this) {
uint32_t mms_get_length (mms_t *this) {
return this->file_length;
}
+
+off_t mms_get_current_pos (mms_t *this) {
+ return this->current_pos;
+}
diff --git a/src/input/mms.h b/src/input/mms.h
index b18a90f45..3c1b4af81 100644
--- a/src/input/mms.h
+++ b/src/input/mms.h
@@ -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: mms.h,v 1.10 2003/12/09 00:02:30 f1rmb Exp $
+ * $Id: mms.h,v 1.11 2004/04/06 00:25:29 tmattern Exp $
*
* libmms public header
*/
@@ -39,5 +39,7 @@ void mms_close (mms_t *this);
int mms_peek_header (mms_t *this, char *data, int maxsize);
+off_t mms_get_current_pos (mms_t *this);
+
#endif
diff --git a/src/input/mmsh.c b/src/input/mmsh.c
index 425b957f8..67c2dc7fa 100644
--- a/src/input/mmsh.c
+++ b/src/input/mmsh.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: mmsh.c,v 1.27 2004/01/23 00:01:15 valtri Exp $
+ * $Id: mmsh.c,v 1.28 2004/04/06 00:25:29 tmattern Exp $
*
* MMS over HTTP protocol
* written by Thibaut Mattern
@@ -53,7 +53,6 @@
/*
#define LOG
*/
-
#include "xine_internal.h"
#include "xineutils.h"
@@ -113,8 +112,6 @@ static const char* mmsh_LiveRequest =
"Pragma: stream-switch-entry=%s\r\n"
"Connection: Close\r\n\r\n";
-
-#if 0
/* Unused requests */
static const char* mmsh_PostRequest =
"POST %s HTTP/1.0\r\n"
@@ -122,7 +119,8 @@ static const char* mmsh_PostRequest =
USERAGENT
"Host: %s\r\n"
"Pragma: client-id=%u\r\n"
-/* "Pragma: log-line=no-cache,rate=1.000000,stream-time=%u,stream-offset=%u:%u,request-context=2,max-duration=%u\r\n" */
+/* "Pragma: log-line=no-cache,rate=1.000000,stream-time=%u,stream-offset=%u:%u,request-context=2,max-duration=%u\r\n"
+ */
"Pragma: Content-Length: 0\r\n"
CLIENTGUID
"\r\n";
@@ -135,7 +133,6 @@ static const char* mmsh_RangeRequest =
"Range: bytes=%Lu-\r\n"
CLIENTGUID
"Connection: Close\r\n\r\n";
-#endif
@@ -169,7 +166,6 @@ struct mmsh_s {
uint16_t chunk_type;
uint16_t chunk_length;
uint16_t chunk_seq_number;
- int chunk_eos;
uint8_t buf[CHUNK_SIZE];
int buf_size;
@@ -190,6 +186,9 @@ struct mmsh_s {
int has_audio;
int has_video;
+
+ off_t current_pos;
+ int user_bandwitdh;
};
static int get_guid (unsigned char *buffer, int offset) {
@@ -345,22 +344,25 @@ static int get_chunk_header (mmsh_t *this) {
this->chunk_type = LE_16 (chunk_header);
this->chunk_length = LE_16 (chunk_header + 2) - 8;
this->chunk_seq_number = LE_32 (chunk_header + 4);
-
+
+
/* display debug infos */
#ifdef LOG
switch (this->chunk_type) {
case CHUNK_TYPE_DATA:
printf ("libmmsh: chunk type: CHUNK_TYPE_DATA\n");
+ printf ("libmmsh: chunk length: %d\n", this->chunk_length);
+ printf ("libmmsh: chunk seq: %d\n", this->chunk_seq_number);
break;
case CHUNK_TYPE_END:
printf ("libmmsh: chunk type: CHUNK_TYPE_END\n");
+ printf ("libmmsh: continue: %d\n", this->chunk_seq_number);
break;
case CHUNK_TYPE_ASF_HEADER:
printf ("libmmsh: chunk type: CHUNK_TYPE_ASF_HEADER\n");
+ printf ("libmmsh: chunk length: %d\n", this->chunk_length);
break;
}
- printf ("libmmsh: chunk length: %d\n", this->chunk_length);
- printf ("libmmsh: chunk seq_number: %d\n", this->chunk_seq_number);
#endif
return 1;
@@ -372,7 +374,8 @@ static int get_header (mmsh_t *this) {
lprintf("get_header\n");
this->asf_header_len = 0;
-
+ this->asf_header_read = 0;
+
/* read chunk */
while (1) {
if (get_chunk_header(this)) {
@@ -411,7 +414,7 @@ static void interp_header (mmsh_t *this) {
int i;
- lprintf ("interp_header\n");
+ lprintf ("interp_header, header_len=%d\n", this->asf_header_len);
this->packet_length = 0;
@@ -585,8 +588,8 @@ static int mmsh_tcp_connect(mmsh_t *this) {
return 0;
}
-mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) {
- mmsh_t *this;
+
+static int mmsh_connect_int(mmsh_t *this, int bandwidth) {
int i;
int video_stream = -1;
int audio_stream = -1;
@@ -597,49 +600,11 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) {
int bandwitdh_left;
char stream_selection[10 * ASF_MAX_NUM_STREAMS]; /* 10 chars per stream */
int offset;
-
- if (!url)
- return NULL;
-
- report_progress (stream, 0);
-
- this = (mmsh_t*) xine_xmalloc (sizeof (mmsh_t));
-
- this->stream = stream;
- this->url = strdup(url);
- this->s = -1;
- this->asf_header_len = 0;
- this->asf_header_read = 0;
- this->num_stream_ids = 0;
- this->packet_length = 0;
- this->buf_size = 0;
- this->buf_read = 0;
- this->has_audio = 0;
- this->has_video = 0;
- this->chunk_eos = 0;
-
- report_progress (stream, 0);
-
- if (!_x_parse_url (this->url, &this->proto, &this->host, &this->port,
- &this->user, &this->password, &this->uri)) {
- 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);
-
/*
* let the negotiations begin...
*/
-
+ this->num_stream_ids = 0;
+
/* first request */
lprintf("first http request\n");
@@ -657,7 +622,7 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) {
interp_header(this);
close(this->s);
- report_progress (stream, 20);
+ report_progress (this->stream, 20);
/* choose the best quality for the audio stream */
@@ -769,7 +734,8 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) {
if (!get_answer (this))
goto fail;
- get_header(this);
+ if (!get_header(this))
+ goto fail;
interp_header(this);
for (i = 0; i < this->num_stream_ids; i++) {
@@ -784,9 +750,59 @@ mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) {
this->asf_header[this->bitrates_pos[this->stream_ids[i]] + 3] = 0;
}
}
+ return 1;
+
+fail:
+ return 0;
+}
- report_progress (stream, 100);
+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->stream = stream;
+ this->url = strdup(url);
+ this->s = -1;
+ this->asf_header_len = 0;
+ this->asf_header_read = 0;
+ this->num_stream_ids = 0;
+ this->packet_length = 0;
+ this->buf_size = 0;
+ this->buf_read = 0;
+ this->has_audio = 0;
+ this->has_video = 0;
+ this->current_pos = 0;
+ this->user_bandwitdh = bandwidth;
+
+ report_progress (stream, 0);
+
+ if (!_x_parse_url (this->url, &this->proto, &this->host, &this->port,
+ &this->user, &this->password, &this->uri)) {
+ 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_bandwitdh))
+ goto fail;
+ report_progress (stream, 100);
+
lprintf("mmsh_connect: passed\n" );
return this;
@@ -820,11 +836,31 @@ static int get_media_packet (mmsh_t *this) {
lprintf("get_media_packet: this->packet_length: %d\n", this->packet_length);
- if (!this->chunk_eos && get_chunk_header(this)) {
+ if (get_chunk_header(this)) {
switch (this->chunk_type) {
case CHUNK_TYPE_END:
- this->chunk_eos = 1;
+ /* this->chunk_seq_number:
+ * 0: stop
+ * 1: a new stream follows
+ */
+ if (this->chunk_seq_number == 0) {
+ return 0;
+ } else {
+ close(this->s);
+
+ if (mmsh_tcp_connect(this))
+ return 0;
+
+ if (!mmsh_connect_int(this, this->user_bandwitdh))
+ return 0;
+
+ this->current_pos = 0;
+ this->buf_size = 0;
+ return 1;
+ }
+ break;
case CHUNK_TYPE_DATA:
+ this->current_pos = this->asf_header_len + this->chunk_seq_number * this->packet_length;
break;
default:
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
@@ -884,6 +920,7 @@ int mmsh_read (mmsh_t *this, char *data, int len) {
this->asf_header_read += n;
total += n;
+ this->current_pos += n;
} else {
int n, bytes_left ;
@@ -891,24 +928,25 @@ int mmsh_read (mmsh_t *this, char *data, int len) {
bytes_left = this->buf_size - this->buf_read;
if (bytes_left == 0) {
- this->buf_read = 0;
- if (!get_media_packet (this)) {
+ this->buf_read = 0;
+ if (!get_media_packet (this)) {
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
- "libmmsh: get_media_packet failed\n");
- return total;
- }
- bytes_left = this->buf_size;
+ "libmmsh: get_media_packet failed\n");
+ return total;
+ }
+ bytes_left = this->buf_size;
}
- if ((len-total) < bytes_left)
- n = len-total;
+ if ((len - total) < bytes_left)
+ n = len - total;
else
- n = bytes_left;
+ n = bytes_left;
xine_fast_memcpy (&data[total], &this->buf[this->buf_read], n);
this->buf_read += n;
total += n;
+ this->current_pos += n;
}
}
return total;
@@ -941,3 +979,7 @@ void mmsh_close (mmsh_t *this) {
uint32_t mmsh_get_length (mmsh_t *this) {
return this->file_length;
}
+
+off_t mmsh_get_current_pos (mmsh_t *this) {
+ return this->current_pos;
+}
diff --git a/src/input/mmsh.h b/src/input/mmsh.h
index 756629ee1..4ae838526 100644
--- a/src/input/mmsh.h
+++ b/src/input/mmsh.h
@@ -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: mmsh.h,v 1.3 2003/12/09 00:02:30 f1rmb Exp $
+ * $Id: mmsh.h,v 1.4 2004/04/06 00:25:29 tmattern Exp $
*
* libmmsh public header
*/
@@ -39,4 +39,6 @@ void mmsh_close (mmsh_t *this);
int mmsh_peek_header (mmsh_t *this, char *data, int maxsize);
+off_t mmsh_get_current_pos (mmsh_t *this);
+
#endif