From 708c8ba9f7aefe9f795c9c4eb30ab128f09c8b3d Mon Sep 17 00:00:00 2001 From: waker Date: Wed, 3 Oct 2012 17:47:27 +0200 Subject: mms: improved stream aborting --- plugins/mms/libmms/mms.c | 18 ++++++++++-------- plugins/mms/libmms/mms.h | 2 +- plugins/mms/libmms/mmsh.c | 20 +++++++++++--------- plugins/mms/libmms/mmsh.h | 2 +- plugins/mms/libmms/mmsio.h | 2 +- plugins/mms/libmms/mmsx.c | 9 ++++++--- plugins/mms/libmms/mmsx.h | 2 +- plugins/mms/mmsplug.c | 9 ++++++++- 8 files changed, 39 insertions(+), 25 deletions(-) diff --git a/plugins/mms/libmms/mms.c b/plugins/mms/libmms/mms.c index 766a5761..ad63e6f8 100644 --- a/plugins/mms/libmms/mms.c +++ b/plugins/mms/libmms/mms.c @@ -142,6 +142,8 @@ struct mms_s { int seekable; off_t current_pos; int eos; + + int *need_abort; }; static int fallback_io_select(void *data, int socket, int state, int timeout_msec) @@ -154,7 +156,7 @@ static int fallback_io_select(void *data, int socket, int state, int timeout_mse (state == MMS_IO_WRITE_READY) ? &set : NULL, NULL, &tv); } -static off_t fallback_io_read(void *data, int socket, char *buf, off_t num) +static off_t fallback_io_read(void *data, int socket, char *buf, off_t num, int *need_abort) { off_t len = 0, ret; /* lprintf("%d\n", fallback_io_select(data, socket, MMS_IO_READ_READY, 1000)); */ @@ -502,7 +504,7 @@ static int get_packet_header (mms_io_t *io, mms_t *this, mms_packet_header_t *he header->packet_seq = 0; header->flags = 0; header->packet_id_type = 0; - len = io_read(io, this->s, this->buf, 8); + len = io_read(io, this->s, this->buf, 8, this->need_abort); this->buf_packet_seq_offset = -1; if (len != 8) goto error; @@ -510,7 +512,7 @@ static int get_packet_header (mms_io_t *io, mms_t *this, mms_packet_header_t *he if (LE_32(this->buf + 4) == 0xb00bface) { /* command packet */ header->flags = this->buf[3]; - len = io_read(io, this->s, this->buf + 8, 4); + len = io_read(io, this->s, this->buf + 8, 4, this->need_abort); if (len != 4) goto error; @@ -547,7 +549,7 @@ static int get_packet_command (mms_io_t *io, mms_t *this, uint32_t packet_len) { int command = 0; size_t len; - len = io_read(io, this->s, this->buf + 12, packet_len) ; + len = io_read(io, this->s, this->buf + 12, packet_len, this->need_abort) ; //this->buf_packet_seq_offset = -1; // already set in get_packet_header if (len != packet_len) { lprintf("mms: error reading command packet\n"); @@ -641,7 +643,7 @@ static int get_asf_header (mms_io_t *io, mms_t *this) { return 0; } len = io_read(io, this->s, - this->asf_header + this->asf_header_len, header.packet_len); + this->asf_header + this->asf_header_len, header.packet_len, this->need_abort); if (len != header.packet_len) { lprintf("mms: error reading asf header\n"); return 0; @@ -1437,7 +1439,7 @@ static int get_media_packet (mms_io_t *io, mms_t *this) { this->current_pos = (off_t)this->asf_header_len + ((off_t)header.packet_seq - this->start_packet_seq) * (off_t)this->asf_packet_len; - len = io_read(io, this->s, this->buf, header.packet_len); + len = io_read(io, this->s, this->buf, header.packet_len, this->need_abort); if (len != header.packet_len) { lprintf("mms: error reading asf packet\n"); return 0; @@ -1475,11 +1477,11 @@ int mms_peek_header (mms_t *this, char *data, int maxsize) { return len; } -int mms_read (mms_io_t *io, mms_t *this, char *data, int len) { +int mms_read (mms_io_t *io, mms_t *this, char *data, int len, int *need_abort) { int total; total = 0; - while (total < len && !this->eos) { + while (total < len && !this->eos && (!need_abort || !(*need_abort))) { if (this->asf_header_read < this->asf_header_len) { int n, bytes_left; diff --git a/plugins/mms/libmms/mms.h b/plugins/mms/libmms/mms.h index bce71d54..be329eef 100644 --- a/plugins/mms/libmms/mms.h +++ b/plugins/mms/libmms/mms.h @@ -39,7 +39,7 @@ typedef struct mms_s mms_t; mms_t* mms_connect (mms_io_t *io, void *data, const char *url, int bandwidth); -int mms_read (mms_io_t *io, mms_t *instance, char *data, int len); +int mms_read (mms_io_t *io, mms_t *instance, char *data, int len, int *need_abort); int mms_request_time_seek (mms_io_t *io, mms_t *instance, double time_sec); int mms_time_seek (mms_io_t *io, mms_t *instance, double time_sec); int mms_request_packet_seek (mms_io_t *io, mms_t *instance, diff --git a/plugins/mms/libmms/mmsh.c b/plugins/mms/libmms/mmsh.c index 9a7b119b..a0552f6c 100644 --- a/plugins/mms/libmms/mmsh.c +++ b/plugins/mms/libmms/mmsh.c @@ -202,6 +202,8 @@ struct mmsh_s { off_t current_pos; int user_bandwidth; + + int *need_abort; }; static int fallback_io_select(void *data, int socket, int state, int timeout_msec) @@ -214,7 +216,7 @@ static int fallback_io_select(void *data, int socket, int state, int timeout_mse (state == MMS_IO_WRITE_READY) ? &set : NULL, NULL, &tv); } -static off_t fallback_io_read(void *data, int socket, char *buf, off_t num) +static off_t fallback_io_read(void *data, int socket, char *buf, off_t num, int *need_abort) { off_t len = 0, ret; /* lprintf("%d\n", fallback_io_select(data, socket, MMS_IO_READ_READY, 1000)); */ @@ -367,7 +369,7 @@ static int get_answer (mms_io_t *io, mmsh_t *this) { while (!done) { - if (io_read(io, this->s, &(this->buf[len]), 1) != 1) { + if (io_read(io, this->s, &(this->buf[len]), 1, this->need_abort) != 1) { lprintf ("mmsh: alart: end of stream\n"); return 0; } @@ -454,7 +456,7 @@ static int get_chunk_header (mms_io_t *io, mmsh_t *this) { int ext_header_len; /* read chunk header */ - read_len = io_read(io, this->s, chunk_header, CHUNK_HEADER_LENGTH); + read_len = io_read(io, this->s, chunk_header, CHUNK_HEADER_LENGTH, this->need_abort); if (read_len != CHUNK_HEADER_LENGTH) { if (read_len == 0) return EOS; @@ -482,7 +484,7 @@ static int get_chunk_header (mms_io_t *io, mmsh_t *this) { } /* read extended header */ if (ext_header_len > 0) { - read_len = io_read (io, this->s, ext_header, ext_header_len); + read_len = io_read (io, this->s, ext_header, ext_header_len, this->need_abort); if (read_len != ext_header_len) { lprintf("mmsh: extended header read failed. %d != %d\n", read_len, ext_header_len); return ERROR; @@ -546,7 +548,7 @@ static int get_header (mms_io_t *io, mmsh_t *this) { return ERROR; } else { len = io_read(io, this->s, this->asf_header + this->asf_header_len, - this->chunk_length); + this->chunk_length, this->need_abort); if (len > 0) this->asf_header_len += len; if (len != this->chunk_length) { @@ -567,7 +569,7 @@ static int get_header (mms_io_t *io, mmsh_t *this) { if (this->chunk_type == CHUNK_TYPE_DATA) { /* read the first data chunk */ - len = io_read (io, this->s, this->buf, this->chunk_length); + len = io_read (io, this->s, this->buf, this->chunk_length, this->need_abort); if (len != this->chunk_length) { lprintf ("mmsh: asf data chunk read failed, %d != %d\n", len, @@ -1216,7 +1218,7 @@ static int get_media_packet (mms_io_t *io, mmsh_t *this) { return ERROR; } - len = io_read (io, this->s, this->buf, this->chunk_length); + len = io_read (io, this->s, this->buf, this->chunk_length, this->need_abort); if (len == this->chunk_length) { /* explicit padding with 0 */ @@ -1253,7 +1255,7 @@ int mmsh_peek_header (mmsh_t *this, char *data, int maxsize) { return len; } -int mmsh_read (mms_io_t *io, mmsh_t *this, char *data, int len) { +int mmsh_read (mms_io_t *io, mmsh_t *this, char *data, int len, int *need_abort) { int total; total = 0; @@ -1262,7 +1264,7 @@ int mmsh_read (mms_io_t *io, mmsh_t *this, char *data, int len) { if (this->s == -1) return total; - while (total < len) { + while (total < len && (!need_abort || !(*need_abort))) { if (this->asf_header_read < this->asf_header_len) { int n, bytes_left ; diff --git a/plugins/mms/libmms/mmsh.h b/plugins/mms/libmms/mmsh.h index b222eeaa..744eefc0 100644 --- a/plugins/mms/libmms/mmsh.h +++ b/plugins/mms/libmms/mmsh.h @@ -39,7 +39,7 @@ typedef struct mmsh_s mmsh_t; char* mmsh_connect_common(int *s ,int *port, char *url, char **host, char **path, char **file); mmsh_t* mmsh_connect (mms_io_t *io, void *data, const char *url_, int bandwidth); -int mmsh_read (mms_io_t *io, mmsh_t *instance, char *data, int len); +int mmsh_read (mms_io_t *io, mmsh_t *instance, char *data, int len, int *need_abort); int mmsh_time_seek (mms_io_t *io, mmsh_t *instance, double time_sec); mms_off_t mmsh_seek (mms_io_t *io, mmsh_t *instance, mms_off_t offset, int origin); uint32_t mmsh_get_length (mmsh_t *instance); diff --git a/plugins/mms/libmms/mmsio.h b/plugins/mms/libmms/mmsio.h index 8e4304d9..a1cb93bb 100644 --- a/plugins/mms/libmms/mmsio.h +++ b/plugins/mms/libmms/mmsio.h @@ -19,7 +19,7 @@ extern "C" { #endif /* __cplusplus */ typedef mms_off_t (*mms_io_write_func)(void *data, int socket, char *buf, mms_off_t num); -typedef mms_off_t (*mms_io_read_func)(void *data, int socket, char *buf, mms_off_t num); +typedef mms_off_t (*mms_io_read_func)(void *data, int socket, char *buf, mms_off_t num, int *need_abort); /* select states */ #define MMS_IO_READ_READY 1 diff --git a/plugins/mms/libmms/mmsx.c b/plugins/mms/libmms/mmsx.c index fc95de86..e2c3fd9b 100644 --- a/plugins/mms/libmms/mmsx.c +++ b/plugins/mms/libmms/mmsx.c @@ -33,9 +33,10 @@ struct mmsx_s { mms_t *connection; mmsh_t *connection_h; + int *need_abort; }; -mmsx_t *mmsx_connect(mms_io_t *io, void *data, const char *url, int bandwidth) +mmsx_t *mmsx_connect(mms_io_t *io, void *data, const char *url, int bandwidth, int *need_abort) { mmsx_t *mmsx = calloc(1, sizeof(mmsx_t)); char *try_mms_first = getenv("LIBMMS_TRY_MMS_FIRST"); @@ -43,6 +44,8 @@ mmsx_t *mmsx_connect(mms_io_t *io, void *data, const char *url, int bandwidth) if (!mmsx) return mmsx; + mmsx->need_abort = need_abort; + /* Normally we try mmsh first, as mms: is a rollover protocol identifier according to microsoft and recent mediaplayer versions will try mmsh before mms for mms:// uris. Note that in case of a mmst:// or a @@ -72,9 +75,9 @@ mmsx_t *mmsx_connect(mms_io_t *io, void *data, const char *url, int bandwidth) int mmsx_read (mms_io_t *io, mmsx_t *mmsx, char *data, int len) { if(mmsx->connection) - return mms_read(io, mmsx->connection, data, len); + return mms_read(io, mmsx->connection, data, len, mmsx->need_abort); else - return mmsh_read(io, mmsx->connection_h, data, len); + return mmsh_read(io, mmsx->connection_h, data, len, mmsx->need_abort); } int mmsx_time_seek (mms_io_t *io, mmsx_t *mmsx, double time_sec) diff --git a/plugins/mms/libmms/mmsx.h b/plugins/mms/libmms/mmsx.h index df4adfce..d2acc877 100644 --- a/plugins/mms/libmms/mmsx.h +++ b/plugins/mms/libmms/mmsx.h @@ -39,7 +39,7 @@ extern "C" { typedef struct mmsx_s mmsx_t; -mmsx_t* mmsx_connect (mms_io_t *io, void *data, const char *url, int bandwidth); +mmsx_t* mmsx_connect (mms_io_t *io, void *data, const char *url, int bandwidth, int *need_abort); int mmsx_read (mms_io_t *io, mmsx_t *instance, char *data, int len); int mmsx_time_seek (mms_io_t *io, mmsx_t *instance, double time_sec); diff --git a/plugins/mms/mmsplug.c b/plugins/mms/mmsplug.c index 94d0ed3c..3d2e3faf 100644 --- a/plugins/mms/mmsplug.c +++ b/plugins/mms/mmsplug.c @@ -28,6 +28,7 @@ typedef struct { DB_vfs_t *vfs; mmsx_t *stream; const mms_io_t *io; + int need_abort; } MMS_FILE; static DB_vfs_t plugin; @@ -49,7 +50,7 @@ static DB_FILE * mms_open (const char *fname) { MMS_FILE *fp = malloc (sizeof (MMS_FILE)); fp->io = mms_get_default_io_impl(); - fp->stream = mmsx_connect ((mms_io_t *)fp->io, fp, fname, 1544000); + fp->stream = mmsx_connect ((mms_io_t *)fp->io, fp, fname, 1544000, &fp->need_abort); if (!fp->stream) { free (fp); return NULL; @@ -118,6 +119,11 @@ mms_is_streaming (void) { return 1; } +static void +mms_abort (DB_FILE *fp) { + ((MMS_FILE *)fp)->need_abort = 1; +} + static DB_vfs_t plugin = { .plugin.api_vmajor = 1, .plugin.api_vminor = 0, @@ -156,6 +162,7 @@ static DB_vfs_t plugin = { .get_content_type = mms_get_content_type, .get_schemes = mms_get_schemes, .is_streaming = mms_is_streaming, + .abort = mms_abort, }; DB_plugin_t * -- cgit v1.2.3