diff options
Diffstat (limited to 'src/input')
-rw-r--r-- | src/input/input_mms.c | 61 | ||||
-rw-r--r-- | src/input/mms.c | 25 | ||||
-rw-r--r-- | src/input/mms.h | 4 | ||||
-rw-r--r-- | src/input/mmsh.c | 178 | ||||
-rw-r--r-- | src/input/mmsh.h | 4 |
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 |