diff options
Diffstat (limited to 'lib/win32/libmms_win32/src')
22 files changed, 0 insertions, 6001 deletions
diff --git a/lib/win32/libmms_win32/src/.cvsignore b/lib/win32/libmms_win32/src/.cvsignore deleted file mode 100644 index 9db9f89608..0000000000 --- a/lib/win32/libmms_win32/src/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -.cvsignore -.deps -.libs -Makefile -Makefile.in -libmms.la -mms.lo -testconnect -testdownload -testswap diff --git a/lib/win32/libmms_win32/src/Makefile.am b/lib/win32/libmms_win32/src/Makefile.am deleted file mode 100644 index 61de364647..0000000000 --- a/lib/win32/libmms_win32/src/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ -# noinst_PROGRAMS = testconnect testdownload testswap - -lib_LTLIBRARIES = libmms.la - -libmms_la_SOURCES = \ - mmsio.h \ - mms.c \ - mms.h \ - mms_config.h \ - mmsh.c \ - mmsh.h \ - mmsx.c \ - mmsx.h \ - bswap.h \ - uri.c \ - uri.h \ - asfheader.h \ - mmsh.h - -# noinst_HEADERS = - -libmms_la_LDFLAGS = -version-info 0:2:0 -no-undefined -export-dynamic -libmms_la_LIBADD = $(GLIB_LIBS) - -libmmsincdir = $(includedir)/libmms - -libmmsinc_HEADERS = \ - mms.h \ - mms_config.h \ - bswap.h \ - mmsio.h \ - mmsx.h \ - mmsh.h - -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - $(MMS_PKG_CFLAGS) \ - $(GLIB_CFLAGS) - -DEPS = $(top_builddir)/src/libmms.la -LDADD = $(top_builddir)/src/libmms.la - -# libmms_test_SOURCES = testconnect.c testdownload.c testswap.c -# libmms_test_LDADD = $(LDADD) diff --git a/lib/win32/libmms_win32/src/README.AUX b/lib/win32/libmms_win32/src/README.AUX deleted file mode 100644 index e4a430c01d..0000000000 --- a/lib/win32/libmms_win32/src/README.AUX +++ /dev/null @@ -1,15 +0,0 @@ -Auxiliary files ---------------- - -Files listed here are auxiliary in sense they are _NOT_ part of libmms -source. Sometimes they are not meant to ever be, and are included -temporarily as reference for declarations not ported from Xine yet, -and sometimes their status isn't clear enough yet for them to be -considered libmms part. They don't fall under libmms' license, and -have their own distribution terms. - -* Files provided for porting reasons: - - input_mms.c - -* Files not included officially yet: - - asfheader.h
\ No newline at end of file diff --git a/lib/win32/libmms_win32/src/asfheader.h b/lib/win32/libmms_win32/src/asfheader.h deleted file mode 100644 index 09d94edfea..0000000000 --- a/lib/win32/libmms_win32/src/asfheader.h +++ /dev/null @@ -1,261 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: asfheader.h,v 1.2 2005/12/12 09:24:19 theuraeus Exp $ - * - * demultiplexer for asf streams - * - * based on ffmpeg's - * ASF compatible encoder and decoder. - * Copyright (c) 2000, 2001 Gerard Lantau. - * - * GUID list from avifile - * some other ideas from MPlayer - */ - -#ifndef ASFHEADER_H -#define ASFHEADER_H - -/* - * define asf GUIDs (list from avifile) - */ -#define GUID_ERROR 0 - - /* base ASF objects */ -#define GUID_ASF_HEADER 1 -#define GUID_ASF_DATA 2 -#define GUID_ASF_SIMPLE_INDEX 3 -#define GUID_INDEX 4 -#define GUID_MEDIA_OBJECT_INDEX 5 -#define GUID_TIMECODE_INDEX 6 - - /* header ASF objects */ -#define GUID_ASF_FILE_PROPERTIES 7 -#define GUID_ASF_STREAM_PROPERTIES 8 -#define GUID_ASF_HEADER_EXTENSION 9 -#define GUID_ASF_CODEC_LIST 10 -#define GUID_ASF_SCRIPT_COMMAND 11 -#define GUID_ASF_MARKER 12 -#define GUID_ASF_BITRATE_MUTUAL_EXCLUSION 13 -#define GUID_ASF_ERROR_CORRECTION 14 -#define GUID_ASF_CONTENT_DESCRIPTION 15 -#define GUID_ASF_EXTENDED_CONTENT_DESCRIPTION 16 -#define GUID_ASF_STREAM_BITRATE_PROPERTIES 17 -#define GUID_ASF_EXTENDED_CONTENT_ENCRYPTION 18 -#define GUID_ASF_PADDING 19 - - /* stream properties object stream type */ -#define GUID_ASF_AUDIO_MEDIA 20 -#define GUID_ASF_VIDEO_MEDIA 21 -#define GUID_ASF_COMMAND_MEDIA 22 -#define GUID_ASF_JFIF_MEDIA 23 -#define GUID_ASF_DEGRADABLE_JPEG_MEDIA 24 -#define GUID_ASF_FILE_TRANSFER_MEDIA 25 -#define GUID_ASF_BINARY_MEDIA 26 - - /* stream properties object error correction type */ -#define GUID_ASF_NO_ERROR_CORRECTION 27 -#define GUID_ASF_AUDIO_SPREAD 28 - - /* mutual exclusion object exlusion type */ -#define GUID_ASF_MUTEX_BITRATE 29 -#define GUID_ASF_MUTEX_UKNOWN 30 - - /* header extension */ -#define GUID_ASF_RESERVED_1 31 - - /* script command */ -#define GUID_ASF_RESERVED_SCRIPT_COMMNAND 32 - - /* marker object */ -#define GUID_ASF_RESERVED_MARKER 33 - - /* various */ -/* -#define GUID_ASF_HEAD2 27 -*/ -#define GUID_ASF_AUDIO_CONCEAL_NONE 34 -#define GUID_ASF_CODEC_COMMENT1_HEADER 35 -#define GUID_ASF_2_0_HEADER 36 - -#define GUID_END 37 - - -/* asf stream types */ -#define ASF_STREAM_TYPE_UNKNOWN 0 -#define ASF_STREAM_TYPE_AUDIO 1 -#define ASF_STREAM_TYPE_VIDEO 2 -#define ASF_STREAM_TYPE_CONTROL 3 -#define ASF_STREAM_TYPE_JFIF 4 -#define ASF_STREAM_TYPE_DEGRADABLE_JPEG 5 -#define ASF_STREAM_TYPE_FILE_TRANSFER 6 -#define ASF_STREAM_TYPE_BINARY 7 - -#define ASF_MAX_NUM_STREAMS 23 - -#ifndef GUID_DEFINED -#define GUID_DEFINED - -typedef struct _GUID { /* size is 16 */ - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -} GUID; - -#endif /* !GUID_DEFINED */ - -static const struct -{ - const char* name; - const GUID guid; -} guids[] = -{ - { "error", - { 0x0,} }, - - - /* base ASF objects */ - { "header", - { 0x75b22630, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }} }, - - { "data", - { 0x75b22636, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }} }, - - { "simple index", - { 0x33000890, 0xe5b1, 0x11cf, { 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb }} }, - - { "index", - { 0xd6e229d3, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, - - { "media object index", - { 0xfeb103f8, 0x12ad, 0x4c64, { 0x84, 0x0f, 0x2a, 0x1d, 0x2f, 0x7a, 0xd4, 0x8c }} }, - - { "timecode index", - { 0x3cb73fd0, 0x0c4a, 0x4803, { 0x95, 0x3d, 0xed, 0xf7, 0xb6, 0x22, 0x8f, 0x0c }} }, - - /* header ASF objects */ - { "file properties", - { 0x8cabdca1, 0xa947, 0x11cf, { 0x8e, 0xe4, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, - - { "stream header", - { 0xb7dc0791, 0xa9b7, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, - - { "header extension", - { 0x5fbf03b5, 0xa92e, 0x11cf, { 0x8e, 0xe3, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, - - { "codec list", - { 0x86d15240, 0x311d, 0x11d0, { 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, - - { "script command", - { 0x1efb1a30, 0x0b62, 0x11d0, { 0xa3, 0x9b, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, - - { "marker", - { 0xf487cd01, 0xa951, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, - - { "bitrate mutual exclusion", - { 0xd6e229dc, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, - - { "error correction", - { 0x75b22635, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }} }, - - { "content description", - { 0x75b22633, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }} }, - - { "extended content description", - { 0xd2d0a440, 0xe307, 0x11d2, { 0x97, 0xf0, 0x00, 0xa0, 0xc9, 0x5e, 0xa8, 0x50 }} }, - - { "stream bitrate properties", /* (http://get.to/sdp) */ - { 0x7bf875ce, 0x468d, 0x11d1, { 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2 }} }, - - { "extended content encryption", - { 0x298ae614, 0x2622, 0x4c17, { 0xb9, 0x35, 0xda, 0xe0, 0x7e, 0xe9, 0x28, 0x9c }} }, - - { "padding", - { 0x1806d474, 0xcadf, 0x4509, { 0xa4, 0xba, 0x9a, 0xab, 0xcb, 0x96, 0xaa, 0xe8 }} }, - - - /* stream properties object stream type */ - { "audio media", - { 0xf8699e40, 0x5b4d, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, - - { "video media", - { 0xbc19efc0, 0x5b4d, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, - - { "command media", - { 0x59dacfc0, 0x59e6, 0x11d0, { 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, - - { "JFIF media (JPEG)", - { 0xb61be100, 0x5b4e, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, - - { "Degradable JPEG media", - { 0x35907de0, 0xe415, 0x11cf, { 0xa9, 0x17, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, - - { "File Transfer media", - { 0x91bd222c, 0xf21c, 0x497a, { 0x8b, 0x6d, 0x5a, 0xa8, 0x6b, 0xfc, 0x01, 0x85 }} }, - - { "Binary media", - { 0x3afb65e2, 0x47ef, 0x40f2, { 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43 }} }, - - /* stream properties object error correction */ - { "no error correction", - { 0x20fb5700, 0x5b55, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }} }, - - { "audio spread", - { 0xbfc3cd50, 0x618f, 0x11cf, { 0x8b, 0xb2, 0x00, 0xaa, 0x00, 0xb4, 0xe2, 0x20 }} }, - - - /* mutual exclusion object exlusion type */ - { "mutex bitrate", - { 0xd6e22a01, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, - - { "mutex unknown", - { 0xd6e22a02, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, - - - /* header extension */ - { "reserved_1", - { 0xabd3d211, 0xa9ba, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, - - - /* script command */ - { "reserved script command", - { 0x4B1ACBE3, 0x100B, 0x11D0, { 0xA3, 0x9B, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 }} }, - - /* marker object */ - { "reserved marker", - { 0x4CFEDB20, 0x75F6, 0x11CF, { 0x9C, 0x0F, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB }} }, - - /* various */ - /* Already defined (reserved_1) - { "head2", - { 0xabd3d211, 0xa9ba, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }} }, - */ - { "audio conceal none", - { 0x49f1a440, 0x4ece, 0x11d0, { 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, - - { "codec comment1 header", - { 0x86d15241, 0x311d, 0x11d0, { 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }} }, - - { "asf 2.0 header", - { 0xd6e229d1, 0x35da, 0x11d1, { 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe }} }, - -}; - -#endif diff --git a/lib/win32/libmms_win32/src/bswap.h b/lib/win32/libmms_win32/src/bswap.h deleted file mode 100644 index 5fde765406..0000000000 --- a/lib/win32/libmms_win32/src/bswap.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef BSWAP_H_INCLUDED -#define BSWAP_H_INCLUDED - -/* - * Copyright (C) 2004 Maciej Katafiasz <mathrick@users.sourceforge.net> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -/* Go cheap now, will rip out glib later. *Sigh* */ -#include <glib.h> - -/* NOTE: - * Now, to clear up confusion: LE_XX means "from LE to native, XX bits wide" - * I know it's not very clear naming (tell me about it, I - * misinterpreted in first version and caused bad nasty bug, *sigh*), - * but that's inherited code, will clean up as things go - * Oh, and one more thing -- they take *pointers*, not actual ints - */ - -#define LE_16(val) (GINT16_FROM_LE (*((guint16*)(val)))) -#define BE_16(val) (GINT16_FROM_BE (*((guint16*)(val)))) -#define LE_32(val) (GINT32_FROM_LE (*((guint32*)(val)))) -#define BE_32(val) (GINT32_FROM_BE (*((guint32*)(val)))) - -#define LE_64(val) (GINT64_FROM_LE (*((guint64*)(val)))) -#define BE_64(val) (GINT64_FROM_BE (*((guint64*)(val)))) - -#endif /* BSWAP_H_INCLUDED */ diff --git a/lib/win32/libmms_win32/src/input_mms.c b/lib/win32/libmms_win32/src/input_mms.c deleted file mode 100644 index fdfbbad8a2..0000000000 --- a/lib/win32/libmms_win32/src/input_mms.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: input_mms.c,v 1.1 2004/02/15 19:57:21 mathrick Exp $ - * - * mms input plugin based on work from major mms - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <unistd.h> -#include <stdio.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> - -#define LOG_MODULE "input_mms" -#define LOG_VERBOSE -/* -#define LOG -*/ - -#include "bswap.h" -#include "xine_internal.h" -#include "xineutils.h" -#include "input_plugin.h" - -#include "mms.h" -#include "mmsh.h" -#include "net_buf_ctrl.h" - -#define PROTOCOL_UNDEFINED 0 -#define PROTOCOL_MMST 1 -#define PROTOCOL_MMSH 2 - -#if !defined(NDELAY) && defined(O_NDELAY) -#define FNDELAY O_NDELAY -#endif - -/* network bandwidth */ -const uint32_t mms_bandwidths[]={14400,19200,28800,33600,34430,57600, - 115200,262200,393216,524300,1544000,10485800}; - -const char * mms_bandwidth_strs[]={"14.4 Kbps (Modem)", "19.2 Kbps (Modem)", - "28.8 Kbps (Modem)", "33.6 Kbps (Modem)", - "34.4 Kbps (Modem)", "57.6 Kbps (Modem)", - "115.2 Kbps (ISDN)", "262.2 Kbps (Cable/DSL)", - "393.2 Kbps (Cable/DSL)","524.3 Kbps (Cable/DSL)", - "1.5 Mbps (T1)", "10.5 Mbps (LAN)", NULL}; - -typedef struct { - input_plugin_t input_plugin; - - xine_stream_t *stream; - mms_t *mms; - mmsh_t *mmsh; - - char *mrl; - - off_t curpos; - - 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; - - xine_t *xine; -} mms_input_class_t; - -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; - - 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); - break; - case PROTOCOL_MMSH: - n = mmsh_read (this->mmsh, buf, len); - break; - } - - this->curpos += n; - - return n; -} - -static buf_element_t *mms_plugin_read_block (input_plugin_t *this_gen, - fifo_buffer_t *fifo, off_t todo) { - /*mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; */ - buf_element_t *buf = fifo->buffer_pool_alloc (fifo); - int total_bytes; - - lprintf ("mms_plugin_read_block: %lld bytes...\n", todo); - - buf->content = buf->mem; - buf->type = BUF_DEMUX_BLOCK; - - total_bytes = mms_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 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; - - lprintf ("mms_plugin_seek: %lld offset, %d origin...\n", offset, origin); - - switch (origin) { - case SEEK_SET: - dest = offset; - break; - case SEEK_CUR: - dest = this->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; - } - - if (this->curpos > dest) { - printf ("input_mms: cannot seek back!\n"); - return this->curpos; - } - - while (this->curpos<dest) { - int n = 0; - int diff; - - diff = dest - this->curpos; - - if (diff>1024) - diff = 1024; - - switch (this->protocol) { - case PROTOCOL_MMST: - n = mms_read (this->mms, this->scratch, diff); - break; - case PROTOCOL_MMSH: - n = mmsh_read (this->mmsh, this->scratch, diff); - break; - } - - this->curpos += n; - - if (n < diff) - return this->curpos; - - } - - return this->curpos; -} - -static off_t mms_plugin_get_length (input_plugin_t *this_gen) { - mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; - off_t length = 0; - - if (!this->mms) - return 0; - - switch (this->protocol) { - case PROTOCOL_MMST: - length = mms_get_length (this->mms); - break; - case PROTOCOL_MMSH: - length = mmsh_get_length (this->mmsh); - break; - } - - lprintf ("length is %lld\n", length); - - return length; - -} - -static uint32_t mms_plugin_get_capabilities (input_plugin_t *this_gen) { - return INPUT_CAP_PREVIEW; -} - -static uint32_t mms_plugin_get_blocksize (input_plugin_t *this_gen) { - return 0; -} - -static off_t mms_plugin_get_current_pos (input_plugin_t *this_gen){ - mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; - - /* - printf ("current pos is %lld\n", this->curpos); - */ - - return this->curpos; -} - -static void mms_plugin_dispose (input_plugin_t *this_gen) { - mms_input_plugin_t *this = (mms_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; - - if (this->nbc) { - nbc_close (this->nbc); - this->nbc = NULL; - } - - if(this->mrl) - free(this->mrl); - - free (this); -} - -static char* mms_plugin_get_mrl (input_plugin_t *this_gen) { - mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; - - return this->mrl; -} - -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; - - switch (data_type) { - - case INPUT_OPTIONAL_DATA_PREVIEW: - switch (this->protocol) { - case PROTOCOL_MMST: - return mms_peek_header (this->mms, data, MAX_PREVIEW_SIZE); - break; - case PROTOCOL_MMSH: - return mmsh_peek_header (this->mmsh, data, MAX_PREVIEW_SIZE); - break; - } - break; - - default: - return INPUT_OPTIONAL_UNSUPPORTED; - break; - - } - - return INPUT_OPTIONAL_UNSUPPORTED; -} - -static void bandwidth_changed_cb (void *this_gen, xine_cfg_entry_t *entry) { - mms_input_class_t *class = (mms_input_class_t*) this_gen; - - lprintf ("bandwidth_changed_cb %d\n", entry->num_value); - - if(!class) - return; - - if(class->ip && ((entry->num_value >= 0) && (entry->num_value <= 11))) { - mms_input_plugin_t *this = class->ip; - - this->bandwidth = mms_bandwidths[entry->num_value]; - } -} - -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); - if (mms) { - this->protocol = PROTOCOL_MMST; - } else { - mmsh = mmsh_connect (this->stream, this->mrl, this->bandwidth); - this->protocol = PROTOCOL_MMSH; - } - break; - case PROTOCOL_MMST: - mms = mms_connect (this->stream, this->mrl, this->bandwidth); - break; - case PROTOCOL_MMSH: - mmsh = mmsh_connect (this->stream, this->mrl, this->bandwidth); - break; - } - - if (!mms && !mmsh) { - return 0; - } - - this->mms = mms; - this->mmsh = mmsh; - this->curpos = 0; - - return 1; -} - -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; - mms_input_plugin_t *this; - char *mrl = strdup(data); - xine_cfg_entry_t bandwidth_entry; - int protocol; - - lprintf ("trying to open '%s'\n", mrl); - - if (!strncasecmp (mrl, "mms://", 6)) { - protocol = PROTOCOL_UNDEFINED; - } else if (!strncasecmp (mrl, "mmst://", 7)) { - protocol = PROTOCOL_MMST; - } else if (!strncasecmp (mrl, "mmsh://", 7)) { - protocol = PROTOCOL_MMSH; - } else { - free (mrl); - return NULL; - } - - this = (mms_input_plugin_t *) xine_xmalloc (sizeof (mms_input_plugin_t)); - cls->ip = this; - this->stream = stream; - this->mms = NULL; - 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", - &bandwidth_entry)) { - bandwidth_changed_cb(cls, &bandwidth_entry); - } - - this->input_plugin.open = mms_plugin_open; - this->input_plugin.get_capabilities = mms_plugin_get_capabilities; - this->input_plugin.read = mms_plugin_read; - this->input_plugin.read_block = mms_plugin_read_block; - this->input_plugin.seek = mms_plugin_seek; - this->input_plugin.get_current_pos = mms_plugin_get_current_pos; - this->input_plugin.get_length = mms_plugin_get_length; - this->input_plugin.get_blocksize = mms_plugin_get_blocksize; - this->input_plugin.get_mrl = mms_plugin_get_mrl; - this->input_plugin.dispose = mms_plugin_dispose; - this->input_plugin.get_optional_data = mms_plugin_get_optional_data; - this->input_plugin.input_class = cls_gen; - - - return &this->input_plugin; -} - -/* - * mms input plugin class stuff - */ - -static char *mms_class_get_description (input_class_t *this_gen) { - return _("mms streaming input plugin"); -} - -static char *mms_class_get_identifier (input_class_t *this_gen) { - return "mms"; -} - -static void mms_class_dispose (input_class_t *this_gen) { - mms_input_class_t *this = (mms_input_class_t *) this_gen; - - free (this); -} - -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->xine = xine; - this->ip = NULL; - - this->input_class.get_instance = mms_class_get_instance; - this->input_class.get_identifier = mms_class_get_identifier; - this->input_class.get_description = mms_class_get_description; - this->input_class.get_dir = NULL; - this->input_class.get_autoplay_list = NULL; - this->input_class.dispose = mms_class_dispose; - this->input_class.eject_media = NULL; - - xine->config->register_enum(xine->config, "input.mms_network_bandwidth", 10, - (char **)mms_bandwidth_strs, - "Network bandwidth", - NULL, 0, bandwidth_changed_cb, (void*) this); - - return this; -} - -/* - * exported plugin catalog entry - */ - -plugin_info_t xine_plugin_info[] = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT, 14, "mms", XINE_VERSION_CODE, NULL, init_class }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; diff --git a/lib/win32/libmms_win32/src/mms.c b/lib/win32/libmms_win32/src/mms.c deleted file mode 100644 index 4c574d4a27..0000000000 --- a/lib/win32/libmms_win32/src/mms.c +++ /dev/null @@ -1,1981 +0,0 @@ -/* - * Copyright (C) 2002-2004 the xine project - * - * This file is part of LibMMS, an MMS protocol handling library. - * - * 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 ree 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 - * - * $Id: mms.c,v 1.31 2007/12/11 20:35:01 jwrdegoede Exp $ - * - * MMS over TCP protocol - * based on work from major mms - * utility functions to handle communication with an mms server - * - * TODO: - * error messages - * enable seeking ! - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glib.h> /* for G_OS_WIN32 */ - -#ifdef G_OS_WIN32 -#ifdef _MSC_VER -#include <Winsock2.h> -#endif -#include <ws2tcpip.h> -#else -#include <unistd.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#endif - -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <time.h> - -#if defined(HAVE_ICONV) && defined(HAVE_LANGINFO_CODESET) -#define USE_ICONV -#include <iconv.h> -#include <locale.h> -#include <langinfo.h> -#endif - -/********** logging **********/ -#define LOG_MODULE "mms" -#define LOG_VERBOSE -#ifdef DEBUG -# define lprintf g_print -#else -# define lprintf(x) -#endif - -#define __MMS_C__ - -#include "bswap.h" -#include "mms.h" -#include "asfheader.h" -#include "uri.h" -#include "utils.h" - - -/* - * mms specific types - */ - -#define MMST_PORT 1755 - -#define BUF_SIZE 102400 - -#define CMD_HEADER_LEN 40 -#define CMD_PREFIX_LEN 8 -#define CMD_BODY_LEN 1024 * 16 /* FIXME: make this dynamic */ - -#define ASF_HEADER_LEN (8192 * 2) - - -#define MMS_PACKET_ERR 0 -#define MMS_PACKET_COMMAND 1 -#define MMS_PACKET_ASF_HEADER 2 -#define MMS_PACKET_ASF_PACKET 3 - -#define ASF_HEADER_PACKET_ID_TYPE 2 -#define ASF_MEDIA_PACKET_ID_TYPE 4 - - -typedef struct mms_buffer_s mms_buffer_t; -struct mms_buffer_s { - uint8_t *buffer; - int pos; -}; - -typedef struct mms_packet_header_s mms_packet_header_t; -struct mms_packet_header_s { - uint32_t packet_len; - uint8_t flags; - uint8_t packet_id_type; - uint32_t packet_seq; -}; - -typedef struct mms_stream_s mms_stream_t; -struct mms_stream_s { - int stream_id; - int stream_type; - uint32_t bitrate; - uint32_t bitrate_pos; -}; - -struct mms_s { - - /* FIXME: de-xine-ification */ - void *custom_data; - - int s; - - /* url parsing */ - char *url; - char *proto; - char *host; - int port; - char *user; - char *password; - char *uri; - - /* command to send */ - 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 */ - - char str[1024]; /* scratch buffer to built strings */ - - /* receive buffer */ - uint8_t buf[BUF_SIZE]; - int buf_size; - int buf_read; - off_t buf_packet_seq_offset; /* packet sequence offset residing in - buf */ - - uint8_t asf_header[ASF_HEADER_LEN]; - uint32_t asf_header_len; - uint32_t asf_header_read; - int seq_num; - int num_stream_ids; - mms_stream_t streams[ASF_MAX_NUM_STREAMS]; - uint8_t packet_id_type; - off_t start_packet_seq; /* for live streams != 0, need to keep it around */ - int need_discont; /* whether we need to set start_packet_seq */ - uint32_t asf_packet_len; - uint64_t file_len; - uint64_t time_len; /* playback time in 100 nanosecs (10^-7) */ - uint64_t preroll; - uint64_t asf_num_packets; - char guid[37]; - int bandwidth; - - int has_audio; - int has_video; - int live_flag; - int seekable; - off_t current_pos; - int eos; -}; - -/* required for MSVC 6.0 */ -static gdouble -guint64_to_gdouble (guint64 value) -{ - if (value & G_GINT64_CONSTANT (0x8000000000000000)) - return (gdouble) ((gint64) value) + (gdouble) 18446744073709551616.; - else - return (gdouble) ((gint64) value); -} - -static int fallback_io_select(void *data, int socket, int state, int timeout_msec) -{ - int ret; - fd_set set; - struct timeval tv = { timeout_msec / 1000, (timeout_msec % 1000) * 1000}; - FD_ZERO(&set); - FD_SET(socket, &set); - ret = select(1, (state == MMS_IO_READ_READY) ? &set : NULL, - (state == MMS_IO_WRITE_READY) ? &set : NULL, NULL, &tv); - -#ifdef G_OS_WIN32 - if (ret > 0) - return MMS_IO_STATUS_READY; - else if (ret == 0) - return MMS_IO_STATUS_TIMEOUT; - else -#endif - return ret; -} - -static off_t fallback_io_read(void *data, int socket, char *buf, off_t num) -{ - off_t len = 0, ret; -/* lprintf("%d\n", fallback_io_select(data, socket, MMS_IO_READ_READY, 1000)); */ - errno = 0; - while (len < num) - { - ret = (off_t)recv(socket, buf + len, num - len, 0); - if(ret == 0) - break; /* EOF */ - if(ret < 0) - switch(errno) - { - case EAGAIN: - lprintf("len == %lld\n", (gint64) len); - break; - default: - lprintf("len == %lld\n", (gint64) len); - perror(NULL); - /* if already read something, return it, we will fail next time */ - return len ? len : ret; - } - len += ret; - } - lprintf("ret len == %lld\nnum == %lld\n", (gint64) len, (gint64) num); - return len; -} - -static off_t fallback_io_write(void *data, int socket, char *buf, off_t num) -{ - return (off_t)send(socket, buf, num, 0); -} - -static int fallback_io_tcp_connect(void *data, const char *host, int port) -{ - - struct hostent *h; - int i, s; - - h = gethostbyname(host); - if (h == NULL) { -/* fprintf(stderr, "unable to resolve host: %s\n", host); */ - return -1; - } - - s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (s == -1) { -/* fprintf(stderr, "failed to create socket: %s", strerror(errno)); */ - return -1; - } - -#ifndef G_OS_WIN32 - if (fcntl (s, F_SETFL, fcntl (s, F_GETFL) & ~O_NONBLOCK) == -1) { -/* _x_message(stream, XINE_MSG_CONNECTION_REFUSED, "can't put socket in non-blocking mode", strerror(errno), NULL); */ - return -1; - } -#endif - - for (i = 0; h->h_addr_list[i]; i++) { - struct in_addr ia; - struct sockaddr_in sin; - - memcpy (&ia, h->h_addr_list[i], 4); - sin.sin_family = AF_INET; - sin.sin_addr = ia; - sin.sin_port = htons(port); - -#ifdef G_OS_WIN32 - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) ==-1) { -#else - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) ==-1 && errno != EINPROGRESS) { -#endif - - /* FIXME: de-xine-ification */ -/* _x_message(stream, XINE_MSG_CONNECTION_REFUSED, strerror(errno), NULL); */ - close(s); - continue; - } - - return s; - } - return -1; -} - - -static mms_io_t fallback_io = - { - &fallback_io_select, - NULL, - &fallback_io_read, - NULL, - &fallback_io_write, - NULL, - &fallback_io_tcp_connect, - NULL, - }; - -static mms_io_t default_io = { - &fallback_io_select, - NULL, - &fallback_io_read, - NULL, - &fallback_io_write, - NULL, - &fallback_io_tcp_connect, - NULL, - }; - - -#define io_read(io, socket, buf, num) \ - ((io) ? (io)->read(io->read_data, socket, buf, num) \ - : default_io.read(NULL , socket, buf, num)) -#define io_write(io, socket, buf, num) \ - ((io) ? (io)->write(io->write_data, socket, buf, num) \ - : default_io.write(NULL , socket, buf, num)) -#define io_select(io, fd, state, timeout_msec) \ - ((io) ? (io)->select(io->select_data, fd, state, timeout_msec) \ - : default_io.select(NULL , fd, state, timeout_msec)) -#define io_connect(io, host, port) \ - ((io) ? (io)->connect(io->connect_data, host, port) \ - : default_io.connect(NULL , host, port)) - -const mms_io_t* mms_get_default_io_impl() -{ - return &default_io; -} - -void mms_set_default_io_impl(const mms_io_t *io) -{ - if(io->select) - { - default_io.select = io->select; - default_io.select_data = io->select_data; - } else - { - default_io.select = fallback_io.select; - default_io.select_data = fallback_io.select_data; - } - if(io->read) - { - default_io.read = io->read; - default_io.read_data = io->read_data; - } else - { - default_io.read = fallback_io.read; - default_io.read_data = fallback_io.read_data; - } - if(io->write) - { - default_io.write = io->write; - default_io.write_data = io->write_data; - } else - { - default_io.write = fallback_io.write; - default_io.write_data = fallback_io.write_data; - } - if(io->connect) - { - default_io.connect = io->connect; - default_io.connect_data = io->connect_data; - } else - { - default_io.connect = fallback_io.connect; - default_io.connect_data = fallback_io.connect_data; - } -} - -static void mms_buffer_init (mms_buffer_t *mms_buffer, uint8_t *buffer) { - mms_buffer->buffer = buffer; - mms_buffer->pos = 0; -} - -static void mms_buffer_put_8 (mms_buffer_t *mms_buffer, uint8_t value) { - - mms_buffer->buffer[mms_buffer->pos] = value & 0xff; - - mms_buffer->pos += 1; -} - -#if 0 -static void mms_buffer_put_16 (mms_buffer_t *mms_buffer, uint16_t value) { - - mms_buffer->buffer[mms_buffer->pos] = value & 0xff; - mms_buffer->buffer[mms_buffer->pos + 1] = (value >> 8) & 0xff; - - mms_buffer->pos += 2; -} -#endif - -static void mms_buffer_put_32 (mms_buffer_t *mms_buffer, uint32_t value) { - - mms_buffer->buffer[mms_buffer->pos] = value & 0xff; - mms_buffer->buffer[mms_buffer->pos + 1] = (value >> 8) & 0xff; - mms_buffer->buffer[mms_buffer->pos + 2] = (value >> 16) & 0xff; - mms_buffer->buffer[mms_buffer->pos + 3] = (value >> 24) & 0xff; - - mms_buffer->pos += 4; -} - -static int get_guid (unsigned char *buffer, int offset) { - int i; - GUID g; - - g.Data1 = LE_32(buffer + offset); - g.Data2 = LE_16(buffer + offset + 4); - g.Data3 = LE_16(buffer + offset + 6); - for(i = 0; i < 8; i++) { - g.Data4[i] = buffer[offset + 8 + i]; - } - - for (i = 1; i < GUID_END; i++) { - if (!memcmp(&g, &guids[i].guid, sizeof(GUID))) { - lprintf("GUID: %s\n", guids[i].name); - return i; - } - } - - lprintf("unknown GUID: 0x%x, 0x%x, 0x%x, " - "{ 0x%hx, 0x%hx, 0x%hx, 0x%hx, 0x%hx, 0x%hx, 0x%hx, 0x%hx }\n", - g.Data1, g.Data2, g.Data3, - g.Data4[0], g.Data4[1], g.Data4[2], g.Data4[3], - g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]); - - return GUID_ERROR; -} - - -static void print_command (char *data, int len) { - -#ifdef DEBUG - int i; - int dir = LE_32 (data + 36) >> 16; - int comm = LE_32 (data + 36) & 0xFFFF; - - lprintf ("----------------------------------------------\n"); - if (dir == 3) { - lprintf ("send command 0x%02x, %d bytes\n", comm, len); - } else { - lprintf ("receive command 0x%02x, %d bytes\n", comm, len); - } - lprintf (" start sequence %08x\n", LE_32 (data + 0)); - lprintf (" command id %08x\n", LE_32 (data + 4)); - lprintf (" length %8x \n", LE_32 (data + 8)); - lprintf (" protocol %08x\n", LE_32 (data + 12)); - lprintf (" len8 %8x \n", LE_32 (data + 16)); - lprintf (" sequence # %08x\n", LE_32 (data + 20)); - lprintf (" len8 (II) %8x \n", LE_32 (data + 32)); - lprintf (" dir | comm %08x\n", LE_32 (data + 36)); - if (len >= 4) - lprintf (" prefix1 %08x\n", LE_32 (data + 40)); - if (len >= 8) - lprintf (" prefix2 %08x\n", LE_32 (data + 44)); - - 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)) - lprintf ("%c", c); - else - lprintf (" %02x ", c); - - } - if (len > CMD_HEADER_LEN) - lprintf ("\n"); - lprintf ("----------------------------------------------\n"); -#endif -} - - - -static int send_command (mms_io_t *io, mms_t *this, int command, - uint32_t prefix1, uint32_t prefix2, - int length) { - int len8; - off_t n; - mms_buffer_t command_buffer; - - len8 = (length + 7) / 8; - - this->scmd_len = 0; - - mms_buffer_init(&command_buffer, this->scmd); - mms_buffer_put_32 (&command_buffer, 0x00000001); /* start sequence */ - mms_buffer_put_32 (&command_buffer, 0xB00BFACE); /* #-)) */ - mms_buffer_put_32 (&command_buffer, len8 * 8 + 32); - mms_buffer_put_32 (&command_buffer, 0x20534d4d); /* protocol type "MMS " */ - mms_buffer_put_32 (&command_buffer, len8 + 4); - mms_buffer_put_32 (&command_buffer, this->seq_num); - this->seq_num++; - mms_buffer_put_32 (&command_buffer, 0x0); /* timestamp */ - mms_buffer_put_32 (&command_buffer, 0x0); - 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); - - if (length & 7) - memset(this->scmd + length + CMD_HEADER_LEN + CMD_PREFIX_LEN, 0, 8 - (length & 7)); - - n = io_write(io, this->s, this->scmd, len8 * 8 + CMD_HEADER_LEN + CMD_PREFIX_LEN); - if (n != (len8 * 8 + CMD_HEADER_LEN + CMD_PREFIX_LEN)) { - return 0; - } - - print_command (this->scmd, length); - - return 1; -} - -#ifdef USE_ICONV -static iconv_t string_utf16_open() { - return iconv_open("UTF-16LE", nl_langinfo(CODESET)); -} - -static void string_utf16_close(iconv_t url_conv) { - if (url_conv != (iconv_t)-1) { - iconv_close(url_conv); - } -} - -static void string_utf16(iconv_t url_conv, char *dest, char *src, int len) { - memset(dest, 0, 2 * len); - - if (url_conv == (iconv_t)-1) { - int i; - - for (i = 0; i < len; i++) { - dest[i * 2] = src[i]; - dest[i * 2 + 1] = 0; - } - dest[i * 2] = 0; - dest[i * 2 + 1] = 0; - } - else { - size_t len1, len2; - char *ip, *op; - - len1 = len; len2 = 1000; - ip = src; op = dest; - iconv(url_conv, &ip, &len1, &op, &len2); - } -} - -#else -static void string_utf16(int unused, char *dest, char *src, int len) { - int i; - - memset (dest, 0, 2 * len); - - for (i = 0; i < len; i++) { - dest[i * 2] = src[i]; - dest[i * 2 + 1] = 0; - } - - dest[i * 2] = 0; - dest[i * 2 + 1] = 0; -} -#endif - - -/* - * return packet type - */ -static int get_packet_header (mms_io_t *io, mms_t *this, mms_packet_header_t *header) { - size_t len; - int packet_type; - - header->packet_len = 0; - header->packet_seq = 0; - header->flags = 0; - header->packet_id_type = 0; - len = io_read(io, this->s, this->buf, 8); - this->buf_packet_seq_offset = -1; - if (len != 8) - goto error; - - if (LE_32(this->buf + 4) == 0xb00bface) { - /* command packet */ - header->flags = this->buf[3]; - len = io_read(io, this->s, this->buf + 8, 4); - if (len != 4) - goto error; - - header->packet_len = LE_32(this->buf + 8) + 4; - if (header->packet_len > BUF_SIZE - 12) { - header->packet_len = 0; - goto error; - } - lprintf("mms command\n"); - packet_type = MMS_PACKET_COMMAND; - } else { - header->packet_seq = LE_32(this->buf); - header->packet_id_type = this->buf[4]; - header->flags = this->buf[5]; - header->packet_len = (LE_16(this->buf + 6) - 8) & 0xffff; - if (header->packet_id_type == ASF_HEADER_PACKET_ID_TYPE) { - lprintf("asf header\n"); - packet_type = MMS_PACKET_ASF_HEADER; - } else { - lprintf("asf packet\n"); - packet_type = MMS_PACKET_ASF_PACKET; - } - } - - return packet_type; - -error: - lprintf("read error, len=%d\n", len); - perror("Could not read packet header"); - return MMS_PACKET_ERR; -} - - -static int get_packet_command (mms_io_t *io, 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); - - len = io_read(io, this->s, this->buf + 12, packet_len) ; - //this->buf_packet_seq_offset = -1; // already set in get_packet_header - if (len != packet_len) { - return 0; - } - - print_command (this->buf, len); - - /* check protocol type ("MMS ") */ - if (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], - LE_32(this->buf + 12)); - return 0; - } - - command = LE_32 (this->buf + 36) & 0xFFFF; - lprintf("command = 0x%2x\n", command); - - return command; -} - -static int get_answer (mms_io_t *io, mms_t *this) { - int command = 0; - mms_packet_header_t header; - - switch (get_packet_header (io, this, &header)) { - case MMS_PACKET_ERR: - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: failed to read mms packet header\n"); - break; - case MMS_PACKET_COMMAND: - command = get_packet_command (io, this, header.packet_len); - - if (command == 0x1b) { - - if (!send_command (io, this, 0x1b, 0, 0, 0)) { - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: failed to send command\n"); - return 0; - } - /* FIXME: limit recursion */ - command = get_answer (io, this); - } - break; - case MMS_PACKET_ASF_HEADER: - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: unexpected asf header packet\n"); - break; - case MMS_PACKET_ASF_PACKET: - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " -"libmms: unexpected asf packet\n"); - break; - } - - return command; -} - - -static int get_asf_header (mms_io_t *io, mms_t *this) { - - off_t len; - int stop = 0; - - this->asf_header_read = 0; - this->asf_header_len = 0; - - while (!stop) { - mms_packet_header_t header; - int command; - - switch (get_packet_header (io, this, &header)) { - case MMS_PACKET_ERR: - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: failed to read mms packet header\n"); - return 0; - break; - case MMS_PACKET_COMMAND: - command = get_packet_command (io, this, header.packet_len); - - if (command == 0x1b) { - - if (!send_command (io, this, 0x1b, 0, 0, 0)) { - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: failed to send command\n"); - return 0; - } - command = get_answer (io, this); - } else { - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: unexpected command packet\n"); - } - break; - case MMS_PACKET_ASF_HEADER: - case MMS_PACKET_ASF_PACKET: - if (header.packet_len + this->asf_header_len > ASF_HEADER_LEN) { - lprintf( "***LOG:*** -- " - "libmms: asf packet too large: %d\n", - header.packet_len + this->asf_header_len); - return 0; - } - len = io_read(io, this->s, - this->asf_header + this->asf_header_len, header.packet_len); - if (len != header.packet_len) { - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: get_asf_header failed\n"); - return 0; - } - this->asf_header_len += header.packet_len; - lprintf("header flags: %d\n", header.flags); - if ((header.flags == 0X08) || (header.flags == 0X0C)) - stop = 1; - break; - } - } - lprintf ("get header packet succ\n"); - return 1; -} - -static void interp_asf_header (mms_t *this) { - - int i; - - this->asf_packet_len = 0; - this->num_stream_ids = 0; - this->asf_num_packets = 0; - /* - * parse header - */ - - i = 30; - while (i < this->asf_header_len) { - - int guid; - uint64_t length; - - guid = get_guid(this->asf_header, i); - i += 16; - - length = LE_64(this->asf_header + i); - i += 8; - - switch (guid) { - - case GUID_ASF_FILE_PROPERTIES: - - this->asf_packet_len = LE_32(this->asf_header + i + 92 - 24); - if (this->asf_packet_len > BUF_SIZE) { - this->asf_packet_len = 0; - lprintf( "***LOG:*** -- " - "libmms: asf packet len too large\n"); - break; - } - this->file_len = LE_64(this->asf_header + i + 40 - 24); - this->time_len = LE_64(this->asf_header + i + 64 - 24); - //this->time_len = LE_64(this->asf_header + i + 72 - 24); - this->preroll = LE_64(this->asf_header + i + 80 - 24); - lprintf ("file object, packet length = %d (%d)\n", - this->asf_packet_len, LE_32(this->asf_header + i + 96 - 24)); - break; - - case GUID_ASF_STREAM_PROPERTIES: - { - uint16_t flags; - uint16_t stream_id; - int type; - int encrypted; - - guid = get_guid(this->asf_header, i); - switch (guid) { - case GUID_ASF_AUDIO_MEDIA: - type = ASF_STREAM_TYPE_AUDIO; - this->has_audio = 1; - break; - - case GUID_ASF_VIDEO_MEDIA: - case GUID_ASF_JFIF_MEDIA: - case GUID_ASF_DEGRADABLE_JPEG_MEDIA: - type = ASF_STREAM_TYPE_VIDEO; - this->has_video = 1; - break; - - case GUID_ASF_COMMAND_MEDIA: - type = ASF_STREAM_TYPE_CONTROL; - break; - - default: - type = ASF_STREAM_TYPE_UNKNOWN; - } - - flags = LE_16(this->asf_header + i + 48); - stream_id = flags & 0x7F; - encrypted = flags >> 15; - - lprintf ("stream object, stream id: %d, type: %d, encrypted: %d\n", - stream_id, type, encrypted); - - if (this->num_stream_ids < ASF_MAX_NUM_STREAMS) { - this->streams[this->num_stream_ids].stream_type = type; - this->streams[this->num_stream_ids].stream_id = stream_id; - this->num_stream_ids++; - } else { - lprintf ("too many streams, skipping\n"); - } - } - break; - - case GUID_ASF_STREAM_BITRATE_PROPERTIES: - { - uint16_t streams = LE_16(this->asf_header + i); - uint16_t stream_id; - int j; - - lprintf ("stream bitrate properties\n"); - lprintf ("streams %d\n", streams); - - for(j = 0; j < streams; j++) { - int stream_index; - stream_id = LE_16(this->asf_header + i + 2 + j * 6); - lprintf ("stream id %d\n", stream_id); - for(stream_index = 0; stream_index < this->num_stream_ids; stream_index++) { - if (this->streams[stream_index].stream_id == stream_id) - break; - } - if (stream_index < this->num_stream_ids) { - this->streams[stream_index].bitrate = LE_32(this->asf_header + i + 4 + j * 6); - this->streams[stream_index].bitrate_pos = i + 4 + j * 6; - lprintf ("stream id %d, bitrate %d\n", stream_id, - this->streams[stream_index].bitrate); - } - } - } - break; - - case GUID_ASF_DATA: - this->asf_num_packets = LE_64(this->asf_header + i + 40 - 24); - break; - - default: - lprintf ("unknown object\n"); - break; - } - - lprintf ("length : %lld\n", length); - - if (length > 24) { - i += length - 24; - } - } -} - -const static char *const mmst_proto_s[] = { "mms", "mmst", NULL }; - -static int mmst_valid_proto (char *proto) { - int i = 0; - - lprintf("mmst_valid_proto\n"); - - if (!proto) - return 0; - - while(mmst_proto_s[i]) { - if (!g_strcasecmp(proto, mmst_proto_s[i])) { - return 1; - } - i++; - } - return 0; -} - -/* FIXME: de-xine-ification */ - -/* static void report_progress (void *data, int p) { - - xine_event_t event; - xine_progress_data_t prg; - - 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); -} */ - - -/* - * returns 1 on error - */ -static int mms_tcp_connect(mms_io_t *io, mms_t *this) { - int progress, res; - - if (!this->port) this->port = MMST_PORT; - - /* - * try to connect - */ - lprintf("try to connect to %s on port %d \n", this->host, this->port); - this->s = io_connect(io, this->host, this->port); - if (this->s == -1) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "failed to connect '%s'\n", this->host); - return 1; - } - - /* connection timeout 15s */ - progress = 0; - do { - /*FIXME: de-xine-ification */ -/* report_progress(this->stream, progress); */ - res = io_select(io, this->s, MMS_IO_WRITE_READY, 500); - progress += 1; - } while ((res == MMS_IO_STATUS_TIMEOUT) && (progress < 30)); - if (res != MMS_IO_STATUS_READY) { - return 1; - } - lprintf ("connected\n"); - return 0; -} - -static void mms_gen_guid(char guid[]) { - static char digit[16] = "0123456789ABCDEF"; - int i = 0; - - srand(time(NULL)); - for (i = 0; i < 36; i++) { - guid[i] = digit[(int) ((16.0*rand())/(RAND_MAX+1.0))]; - } - guid[8] = '-'; guid[13] = '-'; guid[18] = '-'; guid[23] = '-'; - guid[36] = '\0'; -} - -/* - * return 0 on error - */ -int static mms_choose_best_streams(mms_io_t *io, mms_t *this) { - int i; - int video_stream = 0; - int audio_stream = 0; - int max_arate = 0; - int min_vrate = 0; - int min_bw_left = 0; - int bandwitdh_left; - int res; - - /* command 0x33 */ - /* choose the best quality for the audio stream */ - /* i've never seen more than one audio stream */ - lprintf("num_stream_ids=%d\n", this->num_stream_ids); - for (i = 0; i < this->num_stream_ids; i++) { - switch (this->streams[i].stream_type) { - case ASF_STREAM_TYPE_AUDIO: - if (this->streams[i].bitrate > max_arate) { - audio_stream = this->streams[i].stream_id; - max_arate = this->streams[i].bitrate; - } - break; - default: - break; - } - } - - /* choose a video stream adapted to the user bandwidth */ - bandwitdh_left = this->bandwidth - max_arate; - if (bandwitdh_left < 0) { - bandwitdh_left = 0; - } - lprintf("bandwitdh %d, left %d\n", this->bandwidth, bandwitdh_left); - - min_bw_left = bandwitdh_left; - for (i = 0; i < this->num_stream_ids; i++) { - switch (this->streams[i].stream_type) { - case ASF_STREAM_TYPE_VIDEO: - if (((bandwitdh_left - this->streams[i].bitrate) < min_bw_left) && - (bandwitdh_left >= this->streams[i].bitrate)) { - video_stream = this->streams[i].stream_id; - min_bw_left = bandwitdh_left - this->streams[i].bitrate; - } - break; - default: - break; - } - } - - /* choose the lower bitrate of */ - if (!video_stream && this->has_video) { - for (i = 0; i < this->num_stream_ids; i++) { - switch (this->streams[i].stream_type) { - case ASF_STREAM_TYPE_VIDEO: - if ((this->streams[i].bitrate < min_vrate) || - (!min_vrate)) { - video_stream = this->streams[i].stream_id; - min_vrate = this->streams[i].bitrate; - } - break; - default: - break; - } - } - } - - lprintf("selected streams: audio %d, video %d\n", audio_stream, video_stream); - lprintf("disabling other streams\n"); - memset (this->scmd_body, 0, 40); - for (i = 1; i < this->num_stream_ids; i++) { - this->scmd_body [ (i - 1) * 6 + 2 ] = 0xFF; - this->scmd_body [ (i - 1) * 6 + 3 ] = 0xFF; - this->scmd_body [ (i - 1) * 6 + 4 ] = this->streams[i].stream_id ; - this->scmd_body [ (i - 1) * 6 + 5 ] = this->streams[i].stream_id >> 8; - if ((this->streams[i].stream_id == audio_stream) || - (this->streams[i].stream_id == video_stream)) { - this->scmd_body [ (i - 1) * 6 + 6 ] = 0x00; - this->scmd_body [ (i - 1) * 6 + 7 ] = 0x00; - } else { - lprintf("disabling stream %d\n", this->streams[i].stream_id); - this->scmd_body [ (i - 1) * 6 + 6 ] = 0x02; - this->scmd_body [ (i - 1) * 6 + 7 ] = 0x00; - - /* forces the asf demuxer to not choose this stream */ - if (this->streams[i].bitrate_pos) { - if (this->streams[i].bitrate_pos+3 <= ASF_HEADER_LEN) { - this->asf_header[this->streams[i].bitrate_pos ] = 0; - this->asf_header[this->streams[i].bitrate_pos + 1] = 0; - this->asf_header[this->streams[i].bitrate_pos + 2] = 0; - this->asf_header[this->streams[i].bitrate_pos + 3] = 0; - } else { - lprintf("***LOG:*** -- " - "libmms: attempt to write beyond asf header limit"); - } - } - } - } - - if (!send_command (io, this, 0x33, this->num_stream_ids, - 0xFFFF | this->streams[0].stream_id << 16, - this->num_stream_ids * 6 + 2)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: mms_choose_best_streams failed\n"); - return 0; - } - - if ((res = get_answer (io, this)) != 0x21) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: unexpected response: %02x (0x21)\n", res); - } - - return 1; -} - -/* - * TODO: error messages - * network timing request - */ -/* FIXME: got somewhat broken during xine_stream_t->(void*) conversion */ -mms_t *mms_connect (mms_io_t *io, void *data, const char *url, int bandwidth) { -#ifdef USE_ICONV - iconv_t url_conv; -#else - int url_conv = 0; -#endif - mms_t *this; - int res; - GURI *uri; - - if (!url) - return NULL; - - mms_sock_init(); - - /* FIXME: needs proper error-signalling work */ - this = (mms_t*) malloc (sizeof (mms_t)); - - this->custom_data = data; - this->url = strdup (url); - this->s = -1; - this->seq_num = 0; - this->scmd_body = this->scmd + CMD_HEADER_LEN + CMD_PREFIX_LEN; - this->asf_header_len = 0; - this->asf_header_read = 0; - this->num_stream_ids = 0; - this->asf_packet_len = 0; - this->start_packet_seq= 0; - this->need_discont = 1; - this->buf_size = 0; - this->buf_read = 0; - this->buf_packet_seq_offset = -1; - this->has_audio = 0; - this->has_video = 0; - this->bandwidth = bandwidth; - this->current_pos = 0; - this->eos = 0; - - /* FIXME de-xine-ification */ -/* report_progress (stream, 0); */ - - uri = gnet_uri_new(this->url); - if(!uri) { - lprintf ("invalid url\n"); - goto fail; - } - this->proto = uri->scheme; - this->user = uri->user; - this->host = uri->hostname; - this->port = uri->port; - this->password = uri->passwd; - this->uri = gnet_mms_helper(uri); - - if(!this->uri) - goto fail; - - if (!mmst_valid_proto(this->proto)) { - lprintf ("unsupported protocol\n"); - goto fail; - } - - if (mms_tcp_connect(io, this)) { - goto fail; - } - /* FIXME de-xine-ification */ -/* report_progress (stream, 30); */ - -#ifdef USE_ICONV - url_conv = string_utf16_open(); -#endif - /* - * let the negotiations begin... - */ - - /* command 0x1 */ - lprintf("send command 0x01\n"); - mms_gen_guid(this->guid); - sprintf (this->str, "\x1c\x03NSPlayer/7.0.0.1956; {%s}; Host: %s", - this->guid, this->host); - string_utf16 (url_conv, this->scmd_body, this->str, strlen(this->str) + 2); - - if (!send_command (io, this, 1, 0, 0x0004000b, strlen(this->str) * 2 + 8)) { - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: failed to send command 0x01\n"); - goto fail; - } - - if ((res = get_answer (io, this)) != 0x01) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: unexpected response: %02x (0x01)\n", res); - lprintf("answer: %d\n", res); - goto fail; - } - - /* FIXME de-xine-ification */ -/* report_progress (stream, 40); */ - - /* TODO: insert network timing request here */ - /* command 0x2 */ - lprintf("send command 0x02\n"); - string_utf16 (url_conv, &this->scmd_body[8], "\002\000\\\\192.168.0.129\\TCP\\1037\0000", 28); - memset (this->scmd_body, 0, 8); - if (!send_command (io, this, 2, 0, 0, 28 * 2 + 8)) { - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: failed to send command 0x02\n"); - - goto fail; - } - - switch (res = get_answer (io, this)) { - case 0x02: - /* protocol accepted */ - break; - case 0x03: - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: protocol failed\n"); - goto fail; - break; - default: - lprintf("unexpected response: %02x (0x02 or 0x03)\n", res); - goto fail; - } - - /* FIXME de-xine-ification */ -/* report_progress (stream, 50); */ - - /* command 0x5 */ - { - mms_buffer_t command_buffer; - - 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); /* ?? */ - - /* FIXME: refuse to work with urls that are longer that buffer can hold - 64 is a precation */ - - if (strlen(this->uri) >= CMD_BODY_LEN - 64) - goto fail; - - string_utf16 (url_conv, this->scmd_body + command_buffer.pos, this->uri, strlen(this->uri)); - if (!send_command (io, this, 5, 1, 0xffffffff, strlen(this->uri) * 2 + 12)) - goto fail; - } - - switch (res = get_answer (io, this)) { - case 0x06: - { - int xx, yy; - /* no authentication required */ - - /* Warning: sdp is not right here */ - xx = this->buf[62]; - yy = this->buf[63]; - this->live_flag = ((xx == 0) && ((yy & 0xf) == 2)); - this->seekable = !this->live_flag; - lprintf("live: live_flag=%d, xx=%d, yy=%d\n", this->live_flag, xx, yy); - } - break; - case 0x1A: - /* authentication request, not yet supported */ - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: authentication request, not yet supported\n"); - goto fail; - break; - default: - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: unexpected response: %02x (0x06 or 0x1A)\n", res); - goto fail; - } - - /* FIXME de-xine-ification */ -/* report_progress (stream, 60); */ - - /* command 0x15 */ - lprintf("send command 0x15\n"); - { - mms_buffer_t command_buffer; - mms_buffer_init(&command_buffer, this->scmd_body); - mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0x00800000); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0x40AC2000); /* ?? */ - mms_buffer_put_32 (&command_buffer, ASF_HEADER_PACKET_ID_TYPE); /* Header Packet ID type */ - mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ - if (!send_command (io, this, 0x15, 1, 0, command_buffer.pos)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: failed to send command 0x15\n"); - goto fail; - } - } - - if ((res = get_answer (io, this)) != 0x11) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: unexpected response: %02x (0x11)\n", res); - goto fail; - } - - this->num_stream_ids = 0; - - if (!get_asf_header (io, this)) - goto fail; - - interp_asf_header (this); - if (!this->asf_packet_len || !this->num_stream_ids) - goto fail; - - /* FIXME de-xine-ification */ -/* report_progress (stream, 70); */ - - if (!mms_choose_best_streams(io, this)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: mms_choose_best_streams failed"); - goto fail; - } - - /* FIXME de-xine-ification */ -/* report_progress (stream, 80); */ - - /* command 0x07 */ - this->packet_id_type = ASF_MEDIA_PACKET_ID_TYPE; - { - 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, 0xFFFFFFFF); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */ - mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */ - mms_buffer_put_8 (&command_buffer, 0xFF); - mms_buffer_put_8 (&command_buffer, 0xFF); - mms_buffer_put_8 (&command_buffer, 0x00); /* stream time limit flag */ - mms_buffer_put_32 (&command_buffer, this->packet_id_type); /* asf media packet id type */ - if (!send_command (io, this, 0x07, 1, 0x0001FFFF, command_buffer.pos)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: failed to send command 0x07\n"); - goto fail; - } - } - -/* report_progress (stream, 100); */ - -#ifdef USE_ICONV - string_utf16_close(url_conv); -#endif - - lprintf("mms_connect: passed\n" ); - - return this; - -fail: - if (this->s != -1) - close (this->s); - if (this->url) - free(this->url); - if (this->proto) - free(this->proto); - if (this->host) - free(this->host); - if (this->user) - free(this->user); - if (this->password) - free(this->password); - if (this->uri) - free(this->uri); - - free (this); - return NULL; -} - -static int get_media_packet (mms_io_t *io, mms_t *this) { - mms_packet_header_t header; - off_t len; - - switch (get_packet_header (io, this, &header)) { - case MMS_PACKET_ERR: - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: failed to read mms packet header\n"); - return 0; - break; - - case MMS_PACKET_COMMAND: - { - int command; - command = get_packet_command (io, this, header.packet_len); - - switch (command) { - case 0x1e: - { - uint32_t error_code; - - /* Warning: sdp is incomplete. Do not stop if error_code==1 */ - error_code = LE_32(this->buf + CMD_HEADER_LEN); - lprintf ("End of the current stream. Continue=%d\n", error_code); - - if (error_code == 0) { - this->eos = 1; - return 0; - } - - } - break; - - case 0x20: - { - lprintf ("new stream.\n"); - /* asf header */ - if (!get_asf_header (io, this)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "failed to read new ASF header\n"); - return 0; - } - - interp_asf_header (this); - if (!this->asf_packet_len || !this->num_stream_ids) - return 0; - - if (!mms_choose_best_streams(io, this)) - return 0; - - /* send command 0x07 */ - /* TODO: ugly */ - /* command 0x07 */ - { - 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, 0xFFFFFFFF); /* ?? */ - mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */ - mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */ - mms_buffer_put_8 (&command_buffer, 0xFF); - mms_buffer_put_8 (&command_buffer, 0xFF); - mms_buffer_put_8 (&command_buffer, 0x00); /* stream time limit flag */ - mms_buffer_put_32 (&command_buffer, ASF_MEDIA_PACKET_ID_TYPE); /* asf media packet id type */ - if (!send_command (io, this, 0x07, 1, 0x0001FFFF, command_buffer.pos)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: failed to send command 0x07\n"); - return 0; - } - } - this->current_pos = 0; - - /* I don't know if this ever happens with none live (and thus - seekable streams), but I do know that if it happens all bets - with regards to seeking are off */ - this->seekable = 0; - } - break; - - case 0x1b: - { - if (!send_command (io, this, 0x1b, 0, 0, 0)) { - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: failed to send command\n"); - return 0; - } - } - break; - - case 0x05: - break; - - default: - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "unexpected mms command %02x\n", command); - } - this->buf_size = 0; - } - break; - - case MMS_PACKET_ASF_HEADER: - /* FIXME: de-xine-ification */ - lprintf( "***LOG:*** -- " - "libmms: unexpected asf header packet\n"); - this->buf_size = 0; - break; - - case MMS_PACKET_ASF_PACKET: - { - /* media packet */ - - /* FIXME: probably needs some more sophisticated logic, but - until we do seeking, this should work */ - if(this->need_discont && - header.packet_id_type == ASF_MEDIA_PACKET_ID_TYPE) - { - this->need_discont = 0; - this->start_packet_seq = header.packet_seq; - } - - lprintf ("asf media packet detected, packet_len=%d, packet_seq=%d\n", - header.packet_len, header.packet_seq); - if (header.packet_len > this->asf_packet_len) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: invalid asf packet len: %d bytes\n", header.packet_len); - return 0; - } - - /* simulate a seek */ - 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); - if (len != header.packet_len) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: read failed\n"); - return 0; - } - - /* explicit padding with 0 */ - lprintf("padding: %d bytes\n", this->asf_packet_len - header.packet_len); - { - char *base = (char *)(this->buf); - char *start = base + header.packet_len; - char *end = start + this->asf_packet_len - header.packet_len; - if ((start > base) && (start < (base+BUF_SIZE-1)) && - (start < end) && (end < (base+BUF_SIZE-1))) { - memset(this->buf + header.packet_len, 0, this->asf_packet_len - header.packet_len); - } - if (header.packet_id_type == this->packet_id_type) { - if (this->asf_packet_len > BUF_SIZE) { - this->buf_size = BUF_SIZE; - } else { - this->buf_size = this->asf_packet_len; - } - this->buf_packet_seq_offset = - header.packet_seq - this->start_packet_seq; - } else { - this->buf_size = 0; - // Don't set this packet sequence for reuse in seek(), since the - // subsequence packet may be discontinued. - //this->buf_packet_seq_offset = header.packet_seq; - // already set to -1 in get_packet_header - //this->buf_packet_seq_offset = -1; - } - } - } - break; - } - - lprintf ("get media packet succ\n"); - - return 1; -} - - -int mms_peek_header (mms_t *this, char *data, int maxsize) { - - int len; - - len = (this->asf_header_len < maxsize) ? this->asf_header_len : maxsize; - - memcpy(data, this->asf_header, len); - return len; -} - -int mms_read (mms_io_t *io, mms_t *this, char *data, int len) { - int total; - - total = 0; - while (total < len && !this->eos) { - - if (this->asf_header_read < this->asf_header_len) { - int n, bytes_left; - - bytes_left = this->asf_header_len - this->asf_header_read ; - - if ((len - total) < bytes_left) - n = len-total; - else - n = bytes_left; - - memcpy (&data[total], &this->asf_header[this->asf_header_read], n); - - this->asf_header_read += n; - total += n; - this->current_pos += n; - } else { - - int n, bytes_left; - - bytes_left = this->buf_size - this->buf_read; - if (bytes_left == 0) { - this->buf_size = this->buf_read = 0; - if (!get_media_packet (io, this)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: get_media_packet failed\n"); - return total; - } - bytes_left = this->buf_size; - } - - if ((len - total) < bytes_left) - n = len - total; - else - n = bytes_left; - - memcpy (&data[total], &this->buf[this->buf_read], n); - - this->buf_read += n; - total += n; - this->current_pos += n; - } - } - return total; -} - -// To be inline function? -static int mms_request_data_packet (mms_io_t *io, mms_t *this, - double time_sec, unsigned long first_packet, unsigned long time_msec_limit) { - /* command 0x07 */ - { - 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); - memcpy(this->scmd_body, &time_sec, 8); - mms_buffer_init(&command_buffer, this->scmd_body+8); - mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */ - //mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */ - mms_buffer_put_32 (&command_buffer, first_packet); /* first packet sequence */ - //mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */ - //mms_buffer_put_8 (&command_buffer, 0xFF); - //mms_buffer_put_8 (&command_buffer, 0xFF); - //mms_buffer_put_8 (&command_buffer, 0x00); /* stream time limit flag */ - mms_buffer_put_32 (&command_buffer, time_msec_limit & 0x00FFFFFF);/* max stream time limit (3 bytes) */ - mms_buffer_put_32 (&command_buffer, this->packet_id_type); /* asf media packet id type */ - if (!send_command (io, this, 0x07, 1, 0x0001FFFF, 8+command_buffer.pos)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: failed to send command 0x07\n"); - return 0; - } - } - /* TODO: adjust current_pos, considering asf_header_read */ - return 1; -} - -int mms_request_time_seek (mms_io_t *io, mms_t *this, double time_sec) { - if (++this->packet_id_type <= ASF_MEDIA_PACKET_ID_TYPE) - this->packet_id_type = ASF_MEDIA_PACKET_ID_TYPE+1; - //return mms_request_data_packet (io, this, time_sec, 0xFFFFFFFF, 0x00FFFFFF); - // also adjust time by preroll - return mms_request_data_packet (io, this, - time_sec+guint64_to_gdouble(this->preroll)/1000, - 0xFFFFFFFF, 0x00FFFFFF); -} - -// set current_pos to the first byte of the requested packet by peeking at -// the first packet. -// To be inline function? -static int peek_and_set_pos (mms_io_t *io, mms_t *this) { - uint8_t saved_buf[BUF_SIZE]; - int saved_buf_size; - off_t saved_buf_packet_seq_offset; - // save buf and buf_size that may be changed in get_media_packet() - memcpy(saved_buf, this->buf, this->buf_size); - saved_buf_size = this->buf_size; - saved_buf_packet_seq_offset = this->buf_packet_seq_offset; - //this->buf_size = this->buf_read = 0; // reset buf, only if success peeking - this->buf_size = 0; - while (!this->eos) { - // get_media_packet() will set current_pos if data packet is read. - if (!get_media_packet (io, this)) { - /* FIXME: de-xine-ification */ - lprintf ( "***LOG:*** -- " - "libmms: get_media_packet failed\n"); - // restore buf and buf_size that may be changed in get_media_packet() - memcpy(this->buf, saved_buf, saved_buf_size); - this->buf_size = saved_buf_size; - this->buf_packet_seq_offset = saved_buf_packet_seq_offset; - return 0; - } - if (this->buf_size > 0) break; - } - // flush header and reset buf_read, only if success peeking - this->asf_header_read = this->asf_header_len; - this->buf_read = 0; - return 1; - //return this->current_pos; -} - -// send time seek request, and update current_pos corresponding to the next -// requested packet -// Note that, the current_pos will always does not less than asf_header_len -int mms_time_seek (mms_io_t *io, mms_t *this, double time_sec) { - if (!this->seekable) - return 0; - - if (!mms_request_time_seek (io, this, time_sec)) return 0; - return peek_and_set_pos (io, this); -} - -// http://sdp.ppona.com/zipfiles/MMSprotocol_pdf.zip said that, this -// packet_seq value make no difference in version 9 servers. -// But from my experiment with -// mms://202.142.200.130/tltk/56k/tltkD2006-08-08ID-7209.wmv and -// mms://202.142.200.130/tltk/56k/tltkD2006-09-01ID-7467.wmv (the url may valid -// in only 2-3 months) whose server is version 9, it does response and return -// the requested packet. -int mms_request_packet_seek (mms_io_t *io, mms_t *this, - unsigned long packet_seq) { - if (++this->packet_id_type <= ASF_MEDIA_PACKET_ID_TYPE) - this->packet_id_type = ASF_MEDIA_PACKET_ID_TYPE+1; - return mms_request_data_packet (io, this, 0, packet_seq, 0x00FFFFFF); -} - -// send packet seek request, and update current_pos corresponding to the next -// requested packet -// Note that, the current_pos will always does not less than asf_header_len -// Not export this function. Let user use mms_seek() instead? -static int mms_packet_seek (mms_io_t *io, mms_t *this, - unsigned long packet_seq) { - if (!mms_request_packet_seek (io, this, packet_seq)) return 0; - return peek_and_set_pos (io, this); -} - -/* -TODO: To use this table to calculate buf_packet_seq_offset rather than store -and retrieve it from this->buf_packet_seq_offset? -current_packet_seq == (current_pos - asf_header_len) / asf_packet_len -current_packet_seq == -1 if current_pos < asf_header_len -buf_packet_seq_offset indicating which packet sequence are residing in the buf. -Possible status after read(), "last" means last value or unchange. -current_packet_seq | buf_read | buf_size | buf_packet_seq_offset --------------------+----------------+-----------+--------------- -<= 0 | 0 (last) | 0 (last) | none -<= 0 | 0 (last) | 0 (last) | eos at #0 -<= 0 | 0 (last) | 0 (last) | eos at > #0 -<= 0 | 0 (last) | > 0 (last)| #0 -<= 0 | buf_size (last)| > 0 (last)| > #0 -> 0 | 0 | 0 | eos at current_packet_seq -> 0 | 0(never happen)| > 0 | (never happen) -> 0 | buf_size | > 0 | current_packet_seq-1 -*/ -// TODO: How to handle seek() in multi stream source? -// The stream that follows 0x20 ("new stream") command. -off_t mms_seek (mms_io_t *io, mms_t *this, off_t offset, int origin) { - off_t dest; - off_t dest_packet_seq; - //off_t buf_packet_seq_offset; - - if (!this->seekable) - return this->current_pos; - - switch (origin) { - case SEEK_SET: - dest = offset; - break; - case SEEK_CUR: - dest = this->current_pos + offset; - break; - case SEEK_END: - //if (this->asf_num_packets == 0) { - // //printf ("input_mms: unknown end position in seek!\n"); - // return this->current_pos; - //} - dest = mms_get_length (this) + offset; - default: - printf ("input_mms: unknown origin in seek!\n"); - return this->current_pos; - } - - dest_packet_seq = dest - this->asf_header_len; - //if (dest_packet_seq > 0) dest_packet_seq /= this->asf_packet_len; - dest_packet_seq = dest_packet_seq >= 0 ? - dest_packet_seq / this->asf_packet_len : -1; -#if 0 - // buf_packet_seq_offset will identify which packet sequence are residing in - // the buf. -#if 1 /* To show both of the alternate styles :D */ - buf_packet_seq_offset = this->current_pos - this->asf_header_len; - //if (buf_packet_seq_offset > 0) buf_packet_seq_offset /= this->asf_packet_len; - buf_packet_seq_offset = buf_packet_seq_offset >= 0 ? - buf_packet_seq_offset / this->asf_packet_len : -1; - // Note: buf_read == buf_size == 0 may means that it is eos, - // eos means that the packet has been peek'ed. - if (this->buf_read >= this->buf_size && this->buf_size > 0 && - buf_packet_seq_offset >= 0 || - // assuming packet not peek'ed in the following condition - /*this->buf_read >= this->buf_size && */this->buf_size == 0 && - buf_packet_seq_offset == 0) - // The buf is all read but the packet has not been peek'ed. - --buf_packet_seq_offset; -#else - buf_packet_seq_offset = this->current_pos - this->asf_header_len - 1; - //if (buf_packet_seq_offset > 0) buf_packet_seq_offset /= this->asf_packet_len; - buf_packet_seq_offset = buf_packet_seq_offset >= 0 ? - buf_packet_seq_offset / this->asf_packet_len : -1; - // Note: buf_read == buf_size == 0 may means that it is eos, - // eos means that the packet has been peek'ed. - if (this->buf_read == 0/* && buf_packet_seq_offset >= 0*/) - // Since the packet has just been peek'ed. - ++buf_packet_seq_offset; -#endif -#endif - - if (dest_packet_seq < 0) { - if (this->buf_packet_seq_offset > 0) { - if (!mms_request_packet_seek (io, this, 0xFFFFFFFF)) - return this->current_pos; -#if 1 - // clear buf - this->buf_read = this->buf_size = 0; - this->buf_packet_seq_offset = -1; - } else { -#else - // clear buf - this->buf_read = this->buf_size; - // Set this packet sequence not to be reused, since the subsequence - // packet may be discontinued. - this->buf_packet_seq_offset = -1; - // don't reset buf_read if buf_packet_seq_offset < 0, since the previous - // buf may not be cleared. - } else if (this->buf_packet_seq_offset == 0) { -#endif - // reset buf_read - this->buf_read = 0; - } - this->asf_header_read = dest; - return this->current_pos = dest; - } - // dest_packet_seq >= 0 - if (this->asf_num_packets && dest == this->asf_header_len + - this->asf_num_packets*this->asf_packet_len) { - // Requesting the packet beyond the last packet, can cause the server to - // not return any packet or any eos command. This can cause - // mms_packet_seek() to hang. - // This is to allow seeking at end of stream, and avoid hanging. - --dest_packet_seq; - } - if (dest_packet_seq != this->buf_packet_seq_offset) { - if (this->asf_num_packets && dest_packet_seq >= this->asf_num_packets) { - // Do not seek beyond the last packet. - return this->current_pos; - } - if (!mms_packet_seek (io, this, this->start_packet_seq + dest_packet_seq)) - return this->current_pos; - // Check if current_pos is correct. - // This can happen if the server ignore packet seek command. - // If so, just return unchanged current_pos, rather than trying to - // mms_read() to reach the destination pos. - // It should let the caller to decide to choose the alternate method, such - // as, mms_time_seek() and/or mms_read() until the destination pos is - // reached. - if (dest_packet_seq != this->buf_packet_seq_offset) - return this->current_pos; - // This has already been set in mms_packet_seek(). - //if (current_packet_seq < 0) - // this->asf_header_read = this->asf_header_len; - //this->asf_header_read = this->asf_header_len; - } - // eos is reached ? - //if (this->buf_size <= 0) return this->current_pos; - //this->buf_read = (dest - this->asf_header_len) % this->asf_packet_len; - this->buf_read = dest - - (this->asf_header_len + dest_packet_seq*this->asf_packet_len); - // will never happen ? - //if (this->buf_size <= this->buf_read) return this->current_pos; - return this->current_pos = dest; -} - - -void mms_close (mms_t *this) { - - if (this->s != -1) - close (this->s); - if (this->url) - free(this->url); - if (this->proto) - free(this->proto); - if (this->host) - free(this->host); - if (this->user) - free(this->user); - if (this->password) - free(this->password); - if (this->uri) - free(this->uri); - - free (this); -} - -double mms_get_time_length (mms_t *this) { - return guint64_to_gdouble(this->time_len) / 1e7; -} - -uint64_t mms_get_raw_time_length (mms_t *this) { - return this->time_len; -} - -uint32_t mms_get_length (mms_t *this) { - /* we could / should return this->file_len here, but usually this->file_len - is longer then the calculation below, as usually an asf file contains an - asf index object after the data stream. However since we do not have a - (known) way to get to this index object through mms, we return a - calculated size of what we can get to when we know. */ - if (this->asf_num_packets) - return this->asf_header_len + this->asf_num_packets*this->asf_packet_len; - else - return this->file_len; -} - -off_t mms_get_current_pos (mms_t *this) { - return this->current_pos; -} - -uint32_t mms_get_asf_header_len (mms_t *this) { - return this->asf_header_len; -} - -uint64_t mms_get_asf_packet_len (mms_t *this) { - return this->asf_packet_len; -} - -int mms_get_seekable (mms_t *this) { - return this->seekable; -} - -/* If init_state is N where > 0, mms_init has been called N times; - * if == 0, library is not initialized; if < 0, library initialization - * has failed. */ -static int init_state = 0; - -int mms_sock_init(void) -{ -#ifdef G_OS_WIN32 - WORD wVersionRequested; - WSADATA wsaData; - int err; -#endif - - if (init_state > 0) { - init_state++; - return 0; - } - else if (init_state < 0) { - return -1; - } - -#ifdef G_OS_WIN32 - wVersionRequested = MAKEWORD(2, 2); - - err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - return init_state = -1; - } -#endif - init_state = 1; - - return 0; -} - diff --git a/lib/win32/libmms_win32/src/mms.h b/lib/win32/libmms_win32/src/mms.h deleted file mode 100644 index c6cc6ed40f..0000000000 --- a/lib/win32/libmms_win32/src/mms.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: mms.h,v 1.15 2007/12/11 20:24:48 jwrdegoede Exp $ - * - * libmms public header - */ - -/* TODO/dexineification: - * + functions needed: - * - _x_io_*() - * - xine_malloc() [?] - * - xine_fast_memcpy() [?] - */ - -#ifndef HAVE_MMS_H -#define HAVE_MMS_H - -#include <inttypes.h> -#include <stdio.h> -#include <sys/types.h> - -/* #include "xine_internal.h" */ - -#include "bswap.h" -#include "mmsio.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct mms_s mms_t; - -int mms_sock_init (void); -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_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, - unsigned long packet_seq); -/* - * mms_seek() will try to seek using mms_request_packet_seek(), if the server - * ignore the packet seek command, it will return unchanged current_pos, rather - * than trying to mms_read() until the destination pos is reached. This is to - * let the caller, by itself, to decide to choose the alternate method, such - * as, mms_time_seek() and/or mms_read() until the destination pos is reached. - * One can do binary search using time offset (mms_time_seek()) as a search - * index, to approach the desired byte offset. It is to systematically guess - * the time offset to reach for the byte offset. - */ -mms_off_t mms_seek (mms_io_t *io, mms_t *instance, mms_off_t offset, int origin); -/* return total playback time in seconds */ -double mms_get_time_length (mms_t *instance); -/* return raw total playback time in 100 nanosecs (10^-7) */ -uint64_t mms_get_raw_time_length (mms_t *instance); -uint32_t mms_get_length (mms_t *instance); -void mms_close (mms_t *instance); - -int mms_peek_header (mms_t *instance, char *data, int maxsize); - -mms_off_t mms_get_current_pos (mms_t *instance); - -uint32_t mms_get_asf_header_len (mms_t *instance); - -uint64_t mms_get_asf_packet_len (mms_t *instance); - -int mms_get_seekable (mms_t *instance); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif - diff --git a/lib/win32/libmms_win32/src/mms_config.h b/lib/win32/libmms_win32/src/mms_config.h deleted file mode 100644 index 4e1045b819..0000000000 --- a/lib/win32/libmms_win32/src/mms_config.h +++ /dev/null @@ -1,4 +0,0 @@ -/* libmms public autoconf settings header file */ - -/* Define to 1 if libmms is compiled with 64 bit file offsets */ -#undef LIBMMS_HAVE_64BIT_OFF_T diff --git a/lib/win32/libmms_win32/src/mms_config.h.in b/lib/win32/libmms_win32/src/mms_config.h.in deleted file mode 100644 index 4e1045b819..0000000000 --- a/lib/win32/libmms_win32/src/mms_config.h.in +++ /dev/null @@ -1,4 +0,0 @@ -/* libmms public autoconf settings header file */ - -/* Define to 1 if libmms is compiled with 64 bit file offsets */ -#undef LIBMMS_HAVE_64BIT_OFF_T diff --git a/lib/win32/libmms_win32/src/mmsh.c b/lib/win32/libmms_win32/src/mmsh.c deleted file mode 100644 index 48690a2501..0000000000 --- a/lib/win32/libmms_win32/src/mmsh.c +++ /dev/null @@ -1,1558 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: mmsh.c,v 1.16 2007/12/11 20:50:43 jwrdegoede Exp $ - * - * MMS over HTTP protocol - * written by Thibaut Mattern - * based on mms.c and specs from avifile - * (http://avifile.sourceforge.net/asf-1.0.htm) - * - * TODO: - * error messages - * http support cleanup, find a way to share code with input_http.c (http.h|c) - * http proxy support - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glib.h> - -#ifdef G_OS_WIN32 -#ifdef _MSC_VER -#include <Winsock2.h> -#endif -#include <ws2tcpip.h> -#else -#include <unistd.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <time.h> -#include <assert.h> - -#define LOG_MODULE "mmsh" -#define LOG_VERBOSE -#ifdef DEBUG -# define lprintf g_print -#else -# define lprintf(x) -#endif - -/* cheat a bit and call ourselves mms.c to keep the code in mmsio.h clean */ -#define __MMS_C__ - -#include "bswap.h" -#include "mmsh.h" -#include "asfheader.h" -#include "uri.h" -#include "utils.h" - -/* #define USERAGENT "User-Agent: NSPlayer/7.1.0.3055\r\n" */ -#define USERAGENT "User-Agent: NSPlayer/4.1.0.3856\r\n" -#define CLIENTGUID "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}\r\n" - - -#define MMSH_PORT 80 -#define MMSH_UNKNOWN 0 -#define MMSH_SEEKABLE 1 -#define MMSH_LIVE 2 - -#define CHUNK_HEADER_LENGTH 4 -#define EXT_HEADER_LENGTH 8 -#define CHUNK_TYPE_RESET 0x4324 -#define CHUNK_TYPE_DATA 0x4424 -#define CHUNK_TYPE_END 0x4524 -#define CHUNK_TYPE_ASF_HEADER 0x4824 -#define CHUNK_SIZE 65536 /* max chunk size */ -#define ASF_HEADER_SIZE (8192 * 2) /* max header size */ - -#define SCRATCH_SIZE 1024 - -static const char* mmsh_FirstRequest = - "GET %s HTTP/1.0\r\n" - "Accept: */*\r\n" - USERAGENT - "Host: %s:%d\r\n" - "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=0:0,request-context=%u,max-duration=0\r\n" - CLIENTGUID - "Connection: Close\r\n\r\n"; - -static const char* mmsh_SeekableRequest = - "GET %s HTTP/1.0\r\n" - "Accept: */*\r\n" - USERAGENT - "Host: %s:%d\r\n" - "Pragma: no-cache,rate=1.000000,stream-time=%u,stream-offset=%u:%u,request-context=%u,max-duration=%u\r\n" - CLIENTGUID - "Pragma: xPlayStrm=1\r\n" - "Pragma: stream-switch-count=%d\r\n" - "Pragma: stream-switch-entry=%s\r\n" /* ffff:1:0 ffff:2:0 */ - "Connection: Close\r\n\r\n"; - -static const char* mmsh_LiveRequest = - "GET %s HTTP/1.0\r\n" - "Accept: */*\r\n" - USERAGENT - "Host: %s:%d\r\n" - "Pragma: no-cache,rate=1.000000,request-context=%u\r\n" - "Pragma: xPlayStrm=1\r\n" - CLIENTGUID - "Pragma: stream-switch-count=%d\r\n" - "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" - "Accept: */*\r\n" - 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: Content-Length: 0\r\n" - CLIENTGUID - "\r\n"; - -static const char* mmsh_RangeRequest = - "GET %s HTTP/1.0\r\n" - "Accept: */*\r\n" - USERAGENT - "Host: %s:%d\r\n" - "Range: bytes=%Lu-\r\n" - CLIENTGUID - "Connection: Close\r\n\r\n"; -#endif - - - -/* - * mmsh specific types - */ - - -struct mmsh_s { - - /* FIXME: de-xine-ification */ - void *custom_data; - - int s; - - /* url parsing */ - char *url; - char *proxy_url; - char *proto; - char *connect_host; - int connect_port; - char *http_host; - int http_port; - int http_request_number; - char *proxy_user; - char *proxy_password; - char *host_user; - char *host_password; - char *uri; - - char str[SCRATCH_SIZE]; /* scratch buffer to built strings */ - - int stream_type; /* seekable or broadcast */ - - /* receive buffer */ - - /* chunk */ - uint16_t chunk_type; - uint16_t chunk_length; - uint32_t chunk_seq_number; - uint8_t buf[CHUNK_SIZE]; - - int buf_size; - int buf_read; - - uint8_t asf_header[ASF_HEADER_SIZE]; - uint32_t asf_header_len; - uint32_t asf_header_read; - int num_stream_ids; - int stream_ids[ASF_MAX_NUM_STREAMS]; - int stream_types[ASF_MAX_NUM_STREAMS]; - uint32_t packet_length; - int64_t file_length; - uint64_t time_len; /* playback time in 100 nanosecs (10^-7) */ - uint64_t preroll; - uint64_t asf_num_packets; - char guid[37]; - uint32_t bitrates[ASF_MAX_NUM_STREAMS]; - uint32_t bitrates_pos[ASF_MAX_NUM_STREAMS]; - - int has_audio; - int has_video; - int seekable; - - off_t current_pos; - int user_bandwidth; -}; - -static int fallback_io_select(void *data, int socket, int state, int timeout_msec) -{ - int ret; - fd_set set; - struct timeval tv = { timeout_msec / 1000, (timeout_msec % 1000) * 1000}; - FD_ZERO(&set); - FD_SET(socket, &set); - ret = select(1, (state == MMS_IO_READ_READY) ? &set : NULL, - (state == MMS_IO_WRITE_READY) ? &set : NULL, NULL, &tv); - -#ifdef G_OS_WIN32 - if (ret > 0) - return MMS_IO_STATUS_READY; - else if (ret == 0) - return MMS_IO_STATUS_TIMEOUT; - else -#endif - return ret; -} - -static off_t fallback_io_read(void *data, int socket, char *buf, off_t num) -{ - off_t len = 0, ret; -/* lprintf("%d\n", fallback_io_select(data, socket, MMS_IO_READ_READY, 1000)); */ - errno = 0; - while (len < num) - { - ret = (off_t)recv(socket, buf + len, num - len, 0); - if(ret == 0) - break; /* EOF */ - if(ret < 0) - switch(errno) - { - case EAGAIN: - lprintf("len == %lld\n", (gint64) len); - break; - default: - lprintf("len == %lld\n", (gint64) len); - perror(NULL); - /* if already read something, return it, we will fail next time */ - return len ? len : ret; - } - len += ret; - } - lprintf("ret len == %lld\nnum == %lld\n", (gint64) len, (gint64) num); - lprintf("read\n"); - return len; -} - -static off_t fallback_io_write(void *data, int socket, char *buf, off_t num) -{ - return (off_t)send(socket, buf, num, 0); -} - -static int fallback_io_tcp_connect(void *data, const char *host, int port) -{ - - struct hostent *h; - int i, s; - - h = gethostbyname(host); - if (h == NULL) { -/* fprintf(stderr, "unable to resolve host: %s\n", host); */ - return -1; - } - - s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (s == -1) { -/* fprintf(stderr, "failed to create socket: %s", strerror(errno)); */ - return -1; - } - -#ifndef G_OS_WIN32 - if (fcntl (s, F_SETFL, fcntl (s, F_GETFL) & ~O_NONBLOCK) == -1) { -/* _x_message(stream, XINE_MSG_CONNECTION_REFUSED, "can't put socket in non-blocking mode", strerror(errno), NULL); */ - return -1; - } -#endif - - for (i = 0; h->h_addr_list[i]; i++) { - struct in_addr ia; - struct sockaddr_in sin; - - memcpy (&ia, h->h_addr_list[i], 4); - sin.sin_family = AF_INET; - sin.sin_addr = ia; - sin.sin_port = htons(port); - -#ifdef G_OS_WIN32 - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) ==-1) { -#else - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) ==-1 && errno != EINPROGRESS) { -#endif - - /* FIXME: de-xine-ification */ -/* _x_message(stream, XINE_MSG_CONNECTION_REFUSED, strerror(errno), NULL); */ - close(s); - continue; - } - - return s; - } - return -1; -} - - -static mms_io_t fallback_io = - { - &fallback_io_select, - NULL, - &fallback_io_read, - NULL, - &fallback_io_write, - NULL, - &fallback_io_tcp_connect, - NULL, - }; - -static mms_io_t default_io = { - &fallback_io_select, - NULL, - &fallback_io_read, - NULL, - &fallback_io_write, - NULL, - &fallback_io_tcp_connect, - NULL, - }; - - -#define io_read(io, socket, buf, num) \ - ((io) ? (io)->read(io->read_data, socket, buf, num) \ - : default_io.read(NULL , socket, buf, num)) -#define io_write(io, socket, buf, num) \ - ((io) ? (io)->write(io->write_data, socket, buf, num) \ - : default_io.write(NULL , socket, buf, num)) -#define io_select(io, fd, state, timeout_msec) \ - ((io) ? (io)->select(io->select_data, fd, state, timeout_msec) \ - : default_io.select(NULL , fd, state, timeout_msec)) -#define io_connect(io, host, port) \ - ((io) ? (io)->connect(io->connect_data, host, port) \ - : default_io.connect(NULL , host, port)) - - -static int get_guid (unsigned char *buffer, int offset) { - int i; - GUID g; - - g.Data1 = LE_32(buffer + offset); - g.Data2 = LE_16(buffer + offset + 4); - g.Data3 = LE_16(buffer + offset + 6); - for(i = 0; i < 8; i++) { - g.Data4[i] = buffer[offset + 8 + i]; - } - - for (i = 1; i < GUID_END; i++) { - if (!memcmp(&g, &guids[i].guid, sizeof(GUID))) { - lprintf ("GUID: %s\n", guids[i].name); - - return i; - } - } - - lprintf ("libmmsh: unknown GUID: 0x%x, 0x%x, 0x%x, " - "{ 0x%hx, 0x%hx, 0x%hx, 0x%hx, 0x%hx, 0x%hx, 0x%hx, 0x%hx }\n", - g.Data1, g.Data2, g.Data3, - g.Data4[0], g.Data4[1], g.Data4[2], g.Data4[3], - g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]); - return GUID_ERROR; -} - -static int send_command (mms_io_t *io, mmsh_t *this, char *cmd) { - int length; - - lprintf ("send_command:\n%s\n", cmd); - - length = strlen(cmd); - if (io_write(io, this->s, cmd, length) != length) { - lprintf ("mmsh: send error.\n"); - return 0; - } - return 1; -} - -static int get_answer (mms_io_t *io, mmsh_t *this) { - - int done, len, linenum; - char *features; - - lprintf ("get_answer\n"); - - done = 0; len = 0; linenum = 0; - this->stream_type = MMSH_UNKNOWN; - - while (!done) { - - if (io_read(io, this->s, &(this->buf[len]), 1) != 1) { - lprintf ("mmsh: alart: end of stream\n"); - return 0; - } - - if (this->buf[len] == '\012') { - - 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) { - int httpver, httpsub, httpcode; - char httpstatus[51]; - - if (sscanf(this->buf, "HTTP/%d.%d %d %50[^\015\012]", &httpver, &httpsub, - &httpcode, httpstatus) != 4) { - lprintf ("mmsh: bad response format\n"); - return 0; - } - - if (httpcode >= 300 && httpcode < 400) { - lprintf ("mmsh: 3xx redirection not implemented: >%d %s<\n", httpcode, httpstatus); - return 0; - } - - if (httpcode < 200 || httpcode >= 300) { - lprintf ("mmsh: http status not 2xx: >%d %s<\n", httpcode, httpstatus); - return 0; - } - } else { - - if (!g_strncasecmp(this->buf, "Location: ", 10)) { - lprintf ("mmsh: Location redirection not implemented.\n"); - return 0; - } - - if (!g_strncasecmp(this->buf, "Pragma:", 7)) { - features = strstr(this->buf + 7, "features="); - if (features) { - if (strstr(features, "seekable")) { - lprintf("seekable stream\n"); - this->stream_type = MMSH_SEEKABLE; - this->seekable = 1; - } else { - if (strstr(features, "broadcast")) { - lprintf("live stream\n"); - this->stream_type = MMSH_LIVE; - this->seekable = 0; - } - } - } - } - } - - if (len == -1) { - done = 1; - } else { - len = 0; - } - } else { - len ++; - } - } - if (this->stream_type == MMSH_UNKNOWN) { - lprintf ("mmsh: unknown stream type\n"); - this->stream_type = MMSH_SEEKABLE; /* FIXME ? */ - this->seekable = 1; - } - return 1; -} - -static int get_chunk_header (mms_io_t *io, mmsh_t *this) { - uint8_t chunk_header[CHUNK_HEADER_LENGTH]; - uint8_t ext_header[EXT_HEADER_LENGTH]; - int read_len; - int ext_header_len; - - lprintf ("get_chunk_header\n"); - - /* read chunk header */ - read_len = io_read(io, this->s, chunk_header, CHUNK_HEADER_LENGTH); - if (read_len != CHUNK_HEADER_LENGTH) { - lprintf ("chunk header read failed, %d != %d\n", read_len, CHUNK_HEADER_LENGTH); - return 0; - } - this->chunk_type = LE_16 (&chunk_header[0]); - this->chunk_length = LE_16 (&chunk_header[2]); - - switch (this->chunk_type) { - case CHUNK_TYPE_DATA: - ext_header_len = 8; - break; - case CHUNK_TYPE_END: - ext_header_len = 4; - break; - case CHUNK_TYPE_ASF_HEADER: - ext_header_len = 8; - break; - case CHUNK_TYPE_RESET: - ext_header_len = 4; - break; - default: - ext_header_len = 0; - } - /* read extended header */ - if (ext_header_len > 0) { - read_len = io_read (io, this->s, ext_header, ext_header_len); - if (read_len != ext_header_len) { - lprintf ("extended header read failed. %d != %d\n", read_len, ext_header_len); - return 0; - } - } - - if (this->chunk_type == CHUNK_TYPE_DATA || this->chunk_type == CHUNK_TYPE_END) - this->chunk_seq_number = LE_32 (&ext_header[0]); - - /* display debug infos */ -#ifdef DEBUG - switch (this->chunk_type) { - case CHUNK_TYPE_DATA: - lprintf ("chunk type: CHUNK_TYPE_DATA\n"); - lprintf ("chunk length: %d\n", this->chunk_length); - lprintf ("chunk seq: %d\n", this->chunk_seq_number); - lprintf ("unknown: %d\n", ext_header[4]); - lprintf ("mmsh seq: %d\n", ext_header[5]); - lprintf ("len2: %d\n", LE_16(&ext_header[6])); - break; - case CHUNK_TYPE_END: - lprintf ("chunk type: CHUNK_TYPE_END\n"); - lprintf ("continue: %d\n", this->chunk_seq_number); - break; - case CHUNK_TYPE_ASF_HEADER: - lprintf ("chunk type: CHUNK_TYPE_ASF_HEADER\n"); - lprintf ("chunk length: %d\n", this->chunk_length); - lprintf ("unknown: %2X %2X %2X %2X %2X %2X\n", - ext_header[0], ext_header[1], ext_header[2], ext_header[3], - ext_header[4], ext_header[5]); - lprintf ("len2: %d\n", LE_16(&ext_header[6])); - break; - case CHUNK_TYPE_RESET: - lprintf ("chunk type: CHUNK_TYPE_RESET\n"); - lprintf ("chunk seq: %d\n", this->chunk_seq_number); - lprintf ("unknown: %2X %2X %2X %2X\n", - ext_header[0], ext_header[1], ext_header[2], ext_header[3]); - break; - default: - lprintf ("unknown chunk: %4X\n", this->chunk_type); - } -#endif - - this->chunk_length -= ext_header_len; - return 1; -} - -static int get_header (mms_io_t *io, mmsh_t *this) { - int len = 0; - - lprintf("get_header\n"); - - this->asf_header_len = 0; - this->asf_header_read = 0; - - /* read chunk */ - while (1) { - if (get_chunk_header(io, this)) { - if (this->chunk_type == CHUNK_TYPE_ASF_HEADER) { - if ((this->asf_header_len + this->chunk_length) > ASF_HEADER_SIZE) { - lprintf ("mmsh: the asf header exceed %d bytes\n", ASF_HEADER_SIZE); - return 0; - } else { - len = io_read(io, this->s, this->asf_header + this->asf_header_len, - this->chunk_length); - this->asf_header_len += len; - if (len != this->chunk_length) { - return 0; - } - } - } else { - break; - } - } else { - lprintf("get_chunk_header failed\n"); - return 0; - } - } - - if (this->chunk_type == CHUNK_TYPE_DATA) { - /* read the first data chunk */ - len = io_read (io, this->s, this->buf, this->chunk_length); - - if (len != this->chunk_length) { - return 0; - } else { - /* check and 0 pad the first data chunk */ - if (this->chunk_length > this->packet_length) { - lprintf ("mmsh: chunk_length(%d) > packet_length(%d)\n", - this->chunk_length, this->packet_length); - return 0; - } - - /* explicit padding with 0 */ - if (this->chunk_length < this->packet_length) - memset(this->buf + this->chunk_length, 0, - this->packet_length - this->chunk_length); - - this->buf_size = this->packet_length; - - return 1; - } - } else { - /* unexpected packet type */ - return 0; - } -} - -static void interp_header (mms_io_t *io, mmsh_t *this) { - - int i; - - lprintf ("interp_header, header_len=%d\n", this->asf_header_len); - - this->packet_length = 0; - this->num_stream_ids = 0; - this->asf_num_packets = 0; - - /* - * parse asf header - */ - - i = 30; - while ((i + 24) < this->asf_header_len) { - - int guid; - uint64_t length; - - guid = get_guid(this->asf_header, i); - i += 16; - - length = LE_64(this->asf_header + i); - i += 8; - - if ((i + length) >= this->asf_header_len) return; - - switch (guid) { - - case GUID_ASF_FILE_PROPERTIES: - - this->packet_length = LE_32(this->asf_header + i + 92 - 24); - if (this->packet_length > CHUNK_SIZE) { - this->packet_length = 0; - break; - } - this->file_length = LE_64(this->asf_header + i + 40 - 24); - this->time_len = LE_64(this->asf_header + i + 64 - 24); - //this->time_len = LE_64(this->asf_header + i + 72 - 24); - this->preroll = LE_64(this->asf_header + i + 80 - 24); - lprintf ("file object, packet length = %d (%d)\n", - this->packet_length, LE_32(this->asf_header + i + 96 - 24)); - break; - - case GUID_ASF_STREAM_PROPERTIES: - { - uint16_t flags; - uint16_t stream_id; - int type; - int encrypted; - - guid = get_guid(this->asf_header, i); - switch (guid) { - case GUID_ASF_AUDIO_MEDIA: - type = ASF_STREAM_TYPE_AUDIO; - this->has_audio = 1; - break; - - case GUID_ASF_VIDEO_MEDIA: - case GUID_ASF_JFIF_MEDIA: - case GUID_ASF_DEGRADABLE_JPEG_MEDIA: - type = ASF_STREAM_TYPE_VIDEO; - this->has_video = 1; - break; - - case GUID_ASF_COMMAND_MEDIA: - type = ASF_STREAM_TYPE_CONTROL; - break; - - default: - type = ASF_STREAM_TYPE_UNKNOWN; - } - - flags = LE_16(this->asf_header + i + 48); - stream_id = flags & 0x7F; - encrypted = flags >> 15; - - lprintf ("stream object, stream id: %d, type: %d, encrypted: %d\n", - stream_id, type, encrypted); - - this->stream_types[stream_id] = type; - this->stream_ids[this->num_stream_ids] = stream_id; - this->num_stream_ids++; - - } - break; - - case GUID_ASF_STREAM_BITRATE_PROPERTIES: - { - uint16_t streams = LE_16(this->asf_header + i); - uint16_t stream_id; - int j; - - lprintf ("stream bitrate properties\n"); - lprintf ("streams %d\n", streams); - - for(j = 0; j < streams; j++) { - stream_id = LE_16(this->asf_header + i + 2 + j * 6); - - lprintf ("stream id %d\n", stream_id); - - this->bitrates[stream_id] = LE_32(this->asf_header + i + 4 + j * 6); - this->bitrates_pos[stream_id] = i + 4 + j * 6; - lprintf ("mmsh: stream id %d, bitrate %d\n", stream_id, this->bitrates[stream_id]); - } - } - break; - - case GUID_ASF_DATA: - this->asf_num_packets = LE_64(this->asf_header + i + 40 - 24); - lprintf("mmsh: num_packets: %d\n", (int)this->asf_num_packets); - break; - - default: - lprintf ("unknown object\n"); - break; - } - - lprintf ("length : %lld\n", length); - - if (length > 24) { - i += length - 24; - } - } -} - -const static char *const mmsh_proto_s[] = { "mms", "mmsh", NULL }; - -static int mmsh_valid_proto (char *proto) { - int i = 0; - - lprintf("mmsh_valid_proto\n"); - - if (!proto) - return 0; - - while(mmsh_proto_s[i]) { - if (!g_strcasecmp(proto, mmsh_proto_s[i])) { - return 1; - } - i++; - } - return 0; -} - -/* - * returns 1 on error - */ -static int mmsh_tcp_connect(mms_io_t *io, mmsh_t *this) { - int progress, res; - - if (!this->connect_port) this->connect_port = MMSH_PORT; - - /* - * try to connect - */ - lprintf("try to connect to %s on port %d \n", this->connect_host, this->connect_port); - - this->s = io_connect (io, this->connect_host, this->connect_port); - - if (this->s == -1) { - lprintf ("mmsh: failed to connect '%s'\n", this->connect_host); - return 1; - } - - /* connection timeout 15s */ - progress = 0; - do { -// report_progress(this->stream, progress); - res = io_select (io, this->s, MMS_IO_WRITE_READY, 500); - progress += 1; - } while ((res == MMS_IO_STATUS_TIMEOUT) && (progress < 30)); - if (res != MMS_IO_STATUS_READY) { - close (this->s); - this->s = -1; - return 1; - } - lprintf ("connected\n"); - - return 0; -} - -static int mmsh_connect_int (mms_io_t *io, mmsh_t *this, off_t seek, uint32_t time_seek) { - int i; - int video_stream = -1; - int audio_stream = -1; - int max_arate = -1; - int min_vrate = -1; - int min_bw_left = 0; - int stream_id; - int bandwitdh_left; - char stream_selection[10 * ASF_MAX_NUM_STREAMS]; /* 10 chars per stream */ - int offset; - - /* Close exisiting connection (if any) and connect */ - if (this->s != -1) - close(this->s); - - if (mmsh_tcp_connect(io, this)) { - return 0; - } -// report_progress (stream, 30); - - /* - * let the negotiations begin... - */ - this->num_stream_ids = 0; - - /* first request */ - lprintf("first http request\n"); - - g_snprintf (this->str, SCRATCH_SIZE, mmsh_FirstRequest, this->uri, - this->http_host, this->http_port, this->http_request_number++); - - if (!send_command (io, this, this->str)) - goto fail; - - if (!get_answer (io, this)) - goto fail; - - - get_header(io, this); - interp_header(io, this); - if (!this->packet_length || !this->num_stream_ids) - goto fail; - - close(this->s); -// report_progress (stream, 20); - - - /* choose the best quality for the audio stream */ - /* i've never seen more than one audio stream */ - for (i = 0; i < this->num_stream_ids; i++) { - stream_id = this->stream_ids[i]; - switch (this->stream_types[stream_id]) { - case ASF_STREAM_TYPE_AUDIO: - if ((audio_stream == -1) || (this->bitrates[stream_id] > max_arate)) { - audio_stream = stream_id; - max_arate = this->bitrates[stream_id]; - } - break; - default: - break; - } - } - - /* choose a video stream adapted to the user bandwidth */ - bandwitdh_left = this->user_bandwidth - max_arate; - if (bandwitdh_left < 0) { - bandwitdh_left = 0; - } - lprintf("bandwitdh %d, left %d\n", this->user_bandwidth, bandwitdh_left); - - min_bw_left = bandwitdh_left; - for (i = 0; i < this->num_stream_ids; i++) { - stream_id = this->stream_ids[i]; - switch (this->stream_types[stream_id]) { - case ASF_STREAM_TYPE_VIDEO: - if (((bandwitdh_left - this->bitrates[stream_id]) < min_bw_left) && - (bandwitdh_left >= this->bitrates[stream_id])) { - video_stream = stream_id; - min_bw_left = bandwitdh_left - this->bitrates[stream_id]; - } - break; - default: - break; - } - } - - /* choose the stream with the lower bitrate */ - if ((video_stream == -1) && this->has_video) { - for (i = 0; i < this->num_stream_ids; i++) { - stream_id = this->stream_ids[i]; - switch (this->stream_types[stream_id]) { - case ASF_STREAM_TYPE_VIDEO: - if ((video_stream == -1) || - (this->bitrates[stream_id] < min_vrate) || - (!min_vrate)) { - video_stream = stream_id; - min_vrate = this->bitrates[stream_id]; - } - break; - default: - break; - } - } - } - - lprintf("audio stream %d, video stream %d\n", audio_stream, video_stream); - - /* second request */ - lprintf("second http request\n"); - - if (mmsh_tcp_connect(io, this)) { - return 0; - } - - /* stream selection string */ - /* The same selection is done with mmst */ - /* 0 means selected */ - /* 2 means disabled */ - offset = 0; - for (i = 0; i < this->num_stream_ids; i++) { - int size; - if ((this->stream_ids[i] == audio_stream) || - (this->stream_ids[i] == video_stream)) { - size = g_snprintf(stream_selection + offset, sizeof(stream_selection) - offset, - "ffff:%d:0 ", this->stream_ids[i]); - } else { - lprintf ("disabling stream %d\n", this->stream_ids[i]); - size = g_snprintf(stream_selection + offset, sizeof(stream_selection) - offset, - "ffff:%d:2 ", this->stream_ids[i]); - } - if (size < 0) goto fail; - offset += size; - } - - switch (this->stream_type) { - case MMSH_SEEKABLE: - g_snprintf (this->str, SCRATCH_SIZE, mmsh_SeekableRequest, this->uri, - this->http_host, this->http_port, time_seek, - (unsigned int)(seek >> 32), - (unsigned int)seek, this->http_request_number++, 0, - this->num_stream_ids, stream_selection); - break; - case MMSH_LIVE: - g_snprintf (this->str, SCRATCH_SIZE, mmsh_LiveRequest, this->uri, - this->http_host, this->http_port, this->http_request_number++, - this->num_stream_ids, stream_selection); - break; - } - - if (!send_command (io, this, this->str)) - goto fail; - - lprintf("before read \n"); - - if (!get_answer (io, this)) - goto fail; - - if (!get_header(io, this)) - goto fail; - - interp_header(io, this); - if (!this->packet_length || !this->num_stream_ids) - goto fail; - - for (i = 0; i < this->num_stream_ids; i++) { - if ((this->stream_ids[i] != audio_stream) && - (this->stream_ids[i] != video_stream)) { - lprintf("disabling stream %d\n", this->stream_ids[i]); - - /* forces the asf demuxer to not choose this stream */ - if (this->bitrates_pos[this->stream_ids[i]]) { - this->asf_header[this->bitrates_pos[this->stream_ids[i]]] = 0; - this->asf_header[this->bitrates_pos[this->stream_ids[i]] + 1] = 0; - this->asf_header[this->bitrates_pos[this->stream_ids[i]] + 2] = 0; - this->asf_header[this->bitrates_pos[this->stream_ids[i]] + 3] = 0; - } - } - } - return 1; -fail: - close(this->s); - this->s = -1; - return 0; -} - -mmsh_t *mmsh_connect (mms_io_t *io, void *data, const char *url, int bandwidth) { - mmsh_t *this; - GURI *uri = NULL; - GURI *proxy_uri = NULL; - char *proxy_env; - if (!url) - return NULL; - - mms_sock_init(); - -// report_progress (stream, 0); - /* - * initializatoin is essential here. the fail: label depends - * on the various char * in our this structure to be - * NULL if they haven't been assigned yet. - */ - this = (mmsh_t*) malloc (sizeof (mmsh_t)); - this->url=NULL; - this->proxy_url = NULL; - this->proto = NULL; - this->connect_host = NULL; - this->http_host = NULL; - this->proxy_user = NULL; - this->proxy_password = NULL; - this->host_user = NULL; - this->host_password = NULL; - this->uri = NULL; - - this->custom_data = data; - this->url = strdup(url); - if ((proxy_env = getenv("http_proxy")) != NULL) - this->proxy_url = strdup(proxy_env); - else - this->proxy_url = NULL; - 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_bandwidth = bandwidth; - this->http_request_number = 1; - -// report_progress (stream, 0); - - if (this->proxy_url) { - proxy_uri = gnet_uri_new(this->proxy_url); - if (!proxy_uri) { - lprintf("invalid proxy url\n"); - goto fail; - } - if (! proxy_uri->port ) { - proxy_uri->port = 3128; //default squid port - } - } - uri = gnet_uri_new(this->url); - if (!uri) { - lprintf ("invalid url\n"); - goto fail; - } - if (! uri->port ) { - //checked in tcp_connect, but it's better to initialize it here - uri->port = MMSH_PORT; - } - if (this->proxy_url) { - char * uri_string; - this->proto = (uri->scheme) ? strdup(uri->scheme) : NULL; - this->connect_host = (proxy_uri->hostname) ? strdup(proxy_uri->hostname) : NULL; - this->connect_port = proxy_uri->port; - this->http_host = (uri->scheme) ? strdup(uri->hostname) : NULL; - this->http_port = uri->port; - this->proxy_user = (proxy_uri->user) ? strdup(proxy_uri->user) : NULL; - this->proxy_password = (proxy_uri->passwd) ? strdup(proxy_uri->passwd) : NULL; - this->host_user = (uri->user) ? strdup(uri->user) : NULL; - this->host_password = (uri->passwd) ? strdup(uri->passwd) : NULL; - gnet_uri_set_scheme(uri,"http"); - this->uri = gnet_mms_helper(uri); - g_free(uri_string); - } else { - this->proto = (uri->scheme) ? strdup(uri->scheme) : NULL; - this->connect_host = (uri->hostname) ? strdup(uri->hostname) : NULL; - this->connect_port = uri->port; - this->http_host = (uri->hostname) ? strdup(uri->hostname) : NULL; - this->http_port = uri->port; - this->proxy_user = NULL; - this->proxy_password = NULL; - this->host_user =(uri->user) ? strdup(uri->user) : NULL; - this->host_password = (uri->passwd) ? strdup(uri->passwd) : NULL; - this->uri = gnet_mms_helper(uri); - } - - if(!this->uri) - goto fail; - - if (proxy_uri) { - gnet_uri_delete(proxy_uri); - proxy_uri = NULL; - } - if (uri) { - gnet_uri_delete(uri); - uri = NULL; - } - if (!mmsh_valid_proto(this->proto)) { - lprintf ("unsupported protocol\n"); - goto fail; - } - - if (!mmsh_connect_int(io, this, 0, 0)) - goto fail; - -// report_progress (stream, 100); - - lprintf("mmsh_connect: passed\n" ); - - return this; - -fail: - lprintf("mmsh_connect: failed\n" ); - if (proxy_uri) - gnet_uri_delete(proxy_uri); - if (uri) - gnet_uri_delete(uri); - if (this->s != -1) - close(this->s); - if (this->url) - free(this->url); - if (this->proxy_url) - free(this->proxy_url); - if (this->proto) - free(this->proto); - if (this->connect_host) - free(this->connect_host); - if (this->http_host) - free(this->http_host); - if (this->proxy_user) - free(this->proxy_user); - if (this->proxy_password) - free(this->proxy_password); - if (this->host_user) - free(this->host_user); - if (this->host_password) - free(this->host_password); - if (this->uri) - free(this->uri); - - free(this); - - lprintf("mmsh_connect: failed return\n" ); - return NULL; -} - - -/* - * returned value: - * 0: error - * 1: data packet read - * 2: new header and data packet read - */ -static int get_media_packet (mms_io_t *io, mmsh_t *this) { - int len = 0; - - lprintf("get_media_packet: this->packet_length: %d\n", this->packet_length); - - if (get_chunk_header(io, this)) { - switch (this->chunk_type) { - case CHUNK_TYPE_END: - /* this->chunk_seq_number: - * 0: stop - * 1: a new stream follows - */ - if (this->chunk_seq_number == 0) - return 0; - - this->http_request_number = 1; - if (!mmsh_connect_int (io, this, 0, 0)) - return 0; - - /* What todo with: current_pos ?? - Also our chunk_seq_numbers will probably restart from 0! - If this happens with a seekable stream (does it ever?) - and we get a seek request after this were fscked! */ - this->seekable = 0; - - /* mmsh_connect_int reads the first data packet */ - /* 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; - } - if (!get_header (io, this)) - return 0; - interp_header(io, this); - - /* What todo with: current_pos ?? - Also our chunk_seq_numbers might restart from 0! - If this happens with a seekable stream (does it ever?) - and we get a seek request after this were fscked! */ - this->seekable = 0; - - /* get_header reads the first data packet */ - /* this->buf_size is set by get_header */ - return 2; - - default: - lprintf ("mmsh: unexpected chunk type\n"); - return 0; - } - - len = io_read (io, this->s, this->buf, this->chunk_length); - - if (len == this->chunk_length) { - /* explicit padding with 0 */ - if (this->chunk_length > this->packet_length) { - lprintf ("mmsh: chunk_length(%d) > packet_length(%d)\n", - this->chunk_length, this->packet_length); - return 0; - } - - { - char *base = (char *)(this->buf); - char *start = base + this->chunk_length; - char *end = start + this->packet_length - this->chunk_length; - if ((start > base) && (start < (base+CHUNK_SIZE-1)) && - (start < end) && (end < (base+CHUNK_SIZE-1))) { - memset(start, 0, - this->packet_length - this->chunk_length); - } - if (this->packet_length > CHUNK_SIZE) { - this->buf_size = CHUNK_SIZE; - } else { - this->buf_size = this->packet_length; - } - } - return 1; - } else { - lprintf ("mmsh: read error, %d != %d\n", len, this->chunk_length); - return 0; - } - } else { - return 0; - } -} - -int mmsh_peek_header (mmsh_t *this, char *data, int maxsize) { - int len; - - lprintf("mmsh_peek_header\n"); - - len = (this->asf_header_len < maxsize) ? this->asf_header_len : maxsize; - - memcpy(data, this->asf_header, len); - return len; -} - -int mmsh_read (mms_io_t *io, mmsh_t *this, char *data, int len) { - int total; - - total = 0; - - lprintf ("mmsh_read: len: %d\n", len); - - /* Check if the stream didn't get closed because of previous errors */ - if (this->s == -1) - return total; - - while (total < len) { - - if (this->asf_header_read < this->asf_header_len) { - int n, bytes_left ; - - bytes_left = this->asf_header_len - this->asf_header_read ; - - if ((len-total) < bytes_left) - n = len-total; - else - n = bytes_left; - - memcpy (&data[total], &this->asf_header[this->asf_header_read], n); - - this->asf_header_read += n; - total += n; - this->current_pos += n; - } else { - - int n, bytes_left ; - - bytes_left = this->buf_size - this->buf_read; - - if (bytes_left == 0) { - int packet_type; - - this->buf_size=this ->buf_read = 0; - packet_type = get_media_packet (io, this); - - if (packet_type == 0) { - lprintf ("mmsh: get_media_packet failed\n"); - return total; - } else if (packet_type == 2) { - continue; - } - bytes_left = this->buf_size; - } - - if ((len-total) < bytes_left) - n = len-total; - else - n = bytes_left; - - memcpy (&data[total], &this->buf[this->buf_read], n); - - this->buf_read += n; - total += n; - this->current_pos += n; - } - } - return total; -} - -off_t mmsh_seek (mms_io_t *io, mmsh_t *this, off_t offset, int origin) { - off_t dest; - off_t dest_packet_seq; - uint32_t orig_asf_header_len = this->asf_header_len; - uint32_t orig_asf_packet_len = this->packet_length; - - if (!this->seekable) - return this->current_pos; - - switch (origin) { - case SEEK_SET: - dest = offset; - break; - case SEEK_CUR: - dest = this->current_pos + offset; - break; - case SEEK_END: - dest = mmsh_get_length (this) + offset; - default: - return this->current_pos; - } - - dest_packet_seq = dest - this->asf_header_len; - dest_packet_seq = dest_packet_seq >= 0 ? - dest_packet_seq / this->packet_length : -1; - - if (dest_packet_seq < 0) { - if (this->chunk_seq_number > 0) { - lprintf("mmsh: seek within header, already read beyond first packet, resetting connection\n"); - if (!mmsh_connect_int(io, this, 0, 0)) { - /* Oops no more connection let our caller know things are fscked up */ - return this->current_pos = -1; - } - /* Some what simple / naive check to check for changed headers - if the header was changed we are once more fscked up */ - if (this->asf_header_len != orig_asf_header_len || - this->packet_length != orig_asf_packet_len) { - lprintf("mmsh: AIIEEE asf header or packet length changed on re-open for seek\n"); - /* Its a different stream, so its useless! */ - close (this->s); - this->s = -1; - return this->current_pos = -1; - } - } else - lprintf("mmsh: seek within header, resetting buf_read\n"); - - // reset buf_read - this->buf_read = 0; - this->asf_header_read = dest; - return this->current_pos = dest; - } - - // dest_packet_seq >= 0 - if (this->asf_num_packets && dest == this->asf_header_len + - this->asf_num_packets*this->packet_length) { - // Requesting the packet beyond the last packet, can cause the server to - // not return any packet or any eos command. This can cause - // mms_packet_seek() to hang. - // This is to allow seeking at end of stream, and avoid hanging. - --dest_packet_seq; - lprintf("mmsh: seek to eos!\n"); - } - - if (dest_packet_seq != this->chunk_seq_number) { - - if (this->asf_num_packets && dest_packet_seq >= this->asf_num_packets) { - // Do not seek beyond the last packet. - return this->current_pos; - } - - lprintf("mmsh: seek to %d, packet: %d\n", (int)dest, (int)dest_packet_seq); - if (!mmsh_connect_int(io, this, (dest_packet_seq+1) * this->packet_length, 0)) { - /* Oops no more connection let our caller know things are fscked up */ - return this->current_pos = -1; - } - /* Some what simple / naive check to check for changed headers - if the header was changed we are once more fscked up */ - if (this->asf_header_len != orig_asf_header_len || - this->packet_length != orig_asf_packet_len) { - lprintf("mmsh: AIIEEE asf header or packet length changed on re-open for seek\n"); - /* Its a different stream, so its useless! */ - close (this->s); - this->s = -1; - return this->current_pos = -1; - } - } - else - lprintf("mmsh: seek within current packet, dest: %d, current pos: %d\n", - (int)dest, (int)this->current_pos); - - /* make sure asf_header is seen as fully read by mmsh_read() this is needed - in case our caller tries to seek over part of the header, or when we've - done an actual packet seek as get_header() resets asf_header_read then. */ - this->asf_header_read = this->asf_header_len; - - /* check we got what we want */ - if (dest_packet_seq == this->chunk_seq_number) { - this->buf_read = dest - - (this->asf_header_len + dest_packet_seq*this->packet_length); - this->current_pos = dest; - } else { - lprintf("Seek failed, wanted packet: %d, got packet: %d\n", - (int)dest_packet_seq, (int)this->chunk_seq_number); - this->buf_read = 0; - this->current_pos = this->asf_header_len + this->chunk_seq_number * - this->packet_length; - } - - lprintf("current_pos after seek to %d: %d (buf_read %d)\n", - (int)dest, (int)this->current_pos, (int)this->buf_read); - - return this->current_pos; -} - -int mmsh_time_seek (mms_io_t *io, mmsh_t *this, double time_sec) { - uint32_t orig_asf_header_len = this->asf_header_len; - uint32_t orig_asf_packet_len = this->packet_length; - - if (!this->seekable) - return 0; - - lprintf("mmsh: time seek to %f secs\n", time_sec); - if (!mmsh_connect_int(io, this, 0, time_sec * 1000 + guint64_to_gdouble(this->preroll))) { - /* Oops no more connection let our caller know things are fscked up */ - this->current_pos = -1; - return 0; - } - /* Some what simple / naive check to check for changed headers - if the header was changed we are once more fscked up */ - if (this->asf_header_len != orig_asf_header_len || - this->packet_length != orig_asf_packet_len) { - lprintf("mmsh: AIIEEE asf header or packet length changed on re-open for seek\n"); - /* Its a different stream, so its useless! */ - close (this->s); - this->s = -1; - this->current_pos = -1; - return 0; - } - - this->asf_header_read = this->asf_header_len; - this->buf_read = 0; - this->current_pos = this->asf_header_len + this->chunk_seq_number * - this->packet_length; - - lprintf("mmsh, current_pos after time_seek:%d\n", (int)this->current_pos); - - return 1; -} - -void mmsh_close (mmsh_t *this) { - - lprintf("mmsh_close\n"); - - if (this->s != -1) - close(this->s); - if (this->url) - free(this->url); - if (this->proxy_url) - free(this->proxy_url); - if (this->proto) - free(this->proto); - if (this->connect_host) - free(this->connect_host); - if (this->http_host) - free(this->http_host); - if (this->proxy_user) - free(this->proxy_user); - if (this->proxy_password) - free(this->proxy_password); - if (this->host_user) - free(this->host_user); - if (this->host_password) - free(this->host_password); - if (this->uri) - free(this->uri); - if (this) - free (this); -} - - -uint32_t mmsh_get_length (mmsh_t *this) { - /* we could / should return this->file_len here, but usually this->file_len - is longer then the calculation below, as usually an asf file contains an - asf index object after the data stream. However since we do not have a - (known) way to get to this index object through mms, we return a - calculated size of what we can get to when we know. */ - if (this->asf_num_packets) - return this->asf_header_len + this->asf_num_packets*this->packet_length; - else - return this->file_length; -} - -double mmsh_get_time_length (mmsh_t *this) { - return guint64_to_gdouble(this->time_len) / 1e7; -} - -uint64_t mmsh_get_raw_time_length (mmsh_t *this) { - return this->time_len; -} - -off_t mmsh_get_current_pos (mmsh_t *this) { - return this->current_pos; -} - -uint32_t mmsh_get_asf_header_len (mmsh_t *this) { - return this->asf_header_len; -} - -uint32_t mmsh_get_asf_packet_len (mmsh_t *this) { - return this->packet_length; -} - -int mmsh_get_seekable (mmsh_t *this) { - return this->seekable; -} diff --git a/lib/win32/libmms_win32/src/mmsh.h b/lib/win32/libmms_win32/src/mmsh.h deleted file mode 100644 index 6a33f0cbfc..0000000000 --- a/lib/win32/libmms_win32/src/mmsh.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - * - * $Id: mmsh.h,v 1.8 2007/12/11 20:24:48 jwrdegoede Exp $ - * - * libmmsh public header - */ - -#ifndef HAVE_MMSH_H -#define HAVE_MMSH_H - -#include <inttypes.h> -#include <stdio.h> -#include <sys/types.h> -#include "mmsio.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -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_time_seek (mms_io_t *io, mmsh_t *instance, double time_sec); -mms_off_t mmsh_seek (mms_io_t *io, mmsh_t *this, mms_off_t offset, int origin); -uint32_t mmsh_get_length (mmsh_t *instance); -double mmsh_get_time_length (mmsh_t *this); -uint64_t mmsh_get_raw_time_length (mmsh_t *this); -mms_off_t mmsh_get_current_pos (mmsh_t *instance); -void mmsh_close (mmsh_t *instance); - -int mmsh_peek_header (mmsh_t *instance, char *data, int maxsize); - -uint32_t mmsh_get_asf_header_len (mmsh_t *this); - -uint32_t mmsh_get_asf_packet_len (mmsh_t *this); - -int mmsh_get_seekable (mmsh_t *this); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/lib/win32/libmms_win32/src/mmsio.h b/lib/win32/libmms_win32/src/mmsio.h deleted file mode 100644 index 750d537c50..0000000000 --- a/lib/win32/libmms_win32/src/mmsio.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef __MMS_IO_H__ -#define __MMS_IO_H__ - -#include "mms_config.h" - -/* On 64 bit file offset capable systems, libmms' configure script adds - -D_FILE_OFFSET_BITS=64 to the CFLAGS. This causes off_t to be 64 bit, - When an app which includes this header file gets compiled without - -D_FILE_OFFSET_BITS=64, it should still expect / pass 64 bit ints for - off_t, this acomplishes this: */ -#if defined LIBMMS_HAVE_64BIT_OFF_T && !defined __MMS_C__ -#define mms_off_t int64_t -#else -#define mms_off_t off_t -#endif - -#ifdef __cplusplus -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); - -/* select states */ -#define MMS_IO_READ_READY 1 -#define MMS_IO_WRITE_READY 2 - -enum - { - MMS_IO_STATUS_READY, /* IO can be safely performed */ - MMS_IO_STATUS_ERROR, /* There was IO error */ - MMS_IO_STATUS_ABORTED, /* IO command was (somehow) - aborted. This is not error, but invalidates IO for further operations*/ - MMS_IO_STATUS_TIMEOUT /* Timeout was exceeded */ - }; - -/* - * Waits for a file descriptor/socket to change status. - * - * users can use this handler to provide their own implementations, - * for example abortable ones - * - * params : - * data whatever parameter may be needed by implementation - * fd file/socket descriptor - * state MMS_IO_READ_READY, MMS_IO_WRITE_READY - * timeout_sec timeout in seconds - * - * - * return value : - * MMS_IO_READY the file descriptor is ready for cmd - * MMS_IO_ERROR an i/o error occured - * MMS_IO_ABORTED command aborted - * MMS_IO_TIMEOUT the file descriptor is not ready after timeout_msec milliseconds - * every other return value is interpreted same as MMS_IO_ABORTED - */ -typedef int (*mms_io_select_func)(void *data, int fd, int state, int timeout_msec); - -/* - * open a tcp connection - * - * params : - * stream needed for reporting errors but may be NULL - * host address of target - * port port on target - * - * returns a socket descriptor or -1 if an error occured - */ -typedef int (*mms_io_tcp_connect_func)(void *data, const char *host, int port); - -typedef struct -{ - mms_io_select_func select; - void *select_data; - mms_io_read_func read; - void *read_data; - mms_io_write_func write; - void *write_data; - mms_io_tcp_connect_func connect; - void *connect_data; -} mms_io_t; - -/* set default IO implementation, it will be used in absence of specific IO - parameter. Structure is referenced, not copied, must remain valid for entire - usage period. Passing NULL reverts to default, POSIX based implementation */ -void mms_set_default_io_impl(const mms_io_t *io); -const mms_io_t* mms_get_default_io_impl(); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __MMS_IO_H__ */ diff --git a/lib/win32/libmms_win32/src/mmsx.c b/lib/win32/libmms_win32/src/mmsx.c deleted file mode 100644 index 0618387462..0000000000 --- a/lib/win32/libmms_win32/src/mmsx.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2007 Hans de Goede <j.w.r.degoede@hhs.nl> - * - * This file is part of libmms a free mms protocol library - * - * libmms is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * libmss 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 Library 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 - */ - -/* - * mmsx is a small wrapper around the mms and mmsh protocol implementations - * in libmms. The mmsx functions provide transparent access to both protocols - * so that programs who wish to support both can do so with a single code path - * if desired. - */ - -#include <stdlib.h> -#include "mmsx.h" -#include "mms.h" -#include "mmsh.h" - -struct mmsx_s { - mms_t *connection; - mmsh_t *connection_h; -}; - -mmsx_t *mmsx_connect(mms_io_t *io, void *data, const char *url, int bandwidth) -{ - mmsx_t *mmsx = calloc(1, sizeof(mmsx_t)); - - if (!mmsx) - return mmsx; - - mmsx->connection_h = mmsh_connect(io, data, url, bandwidth); - if (mmsx->connection_h) - return mmsx; - - mmsx->connection = mms_connect(io, data, url, bandwidth); - if (mmsx->connection) - return mmsx; - - free(mmsx); - return NULL; -} - -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); - else - return mmsh_read(io, mmsx->connection_h, data, len); -} - -int mmsx_time_seek (mms_io_t *io, mmsx_t *mmsx, double time_sec) -{ - if(mmsx->connection) - return mms_time_seek(io, mmsx->connection, time_sec); - else - return mmsh_time_seek(io, mmsx->connection_h, time_sec); -} - -mms_off_t mmsx_seek (mms_io_t *io, mmsx_t *mmsx, mms_off_t offset, int origin) -{ - if(mmsx->connection) - return mms_seek(io, mmsx->connection, offset, origin); - else - return mmsh_seek(io, mmsx->connection_h, offset, origin); -} - -double mmsx_get_time_length (mmsx_t *mmsx) -{ - if(mmsx->connection) - return mms_get_time_length(mmsx->connection); - else - return mmsh_get_time_length(mmsx->connection_h); -} - -uint64_t mmsx_get_raw_time_length (mmsx_t *mmsx) -{ - if(mmsx->connection) - return mms_get_raw_time_length(mmsx->connection); - else - return mmsh_get_raw_time_length(mmsx->connection_h); -} - -uint32_t mmsx_get_length (mmsx_t *mmsx) -{ - if(mmsx->connection) - return mms_get_length(mmsx->connection); - else - return mmsh_get_length(mmsx->connection_h); -} - -void mmsx_close (mmsx_t *mmsx) -{ - if(mmsx->connection) - mms_close(mmsx->connection); - else - mmsh_close(mmsx->connection_h); - - free(mmsx); -} - -int mmsx_peek_header (mmsx_t *mmsx, char *data, int maxsize) -{ - if(mmsx->connection) - return mms_peek_header(mmsx->connection, data, maxsize); - else - return mmsh_peek_header(mmsx->connection_h, data, maxsize); -} - -mms_off_t mmsx_get_current_pos (mmsx_t *mmsx) -{ - if(mmsx->connection) - return mms_get_current_pos(mmsx->connection); - else - return mmsh_get_current_pos(mmsx->connection_h); -} - -uint32_t mmsx_get_asf_header_len(mmsx_t *mmsx) -{ - if(mmsx->connection) - return mms_get_asf_header_len(mmsx->connection); - else - return mmsh_get_asf_header_len(mmsx->connection_h); -} - -uint64_t mmsx_get_asf_packet_len (mmsx_t *mmsx) -{ - if(mmsx->connection) - return mms_get_asf_packet_len(mmsx->connection); - else - return mmsh_get_asf_packet_len(mmsx->connection_h); -} - -int mmsx_get_seekable (mmsx_t *mmsx) -{ - if(mmsx->connection) - return mms_get_seekable(mmsx->connection); - else - return mmsh_get_seekable(mmsx->connection_h); -} diff --git a/lib/win32/libmms_win32/src/mmsx.h b/lib/win32/libmms_win32/src/mmsx.h deleted file mode 100644 index df4adfce4c..0000000000 --- a/lib/win32/libmms_win32/src/mmsx.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2007 Hans de Goede <j.w.r.degoede@hhs.nl> - * - * This file is part of libmms a free mms protocol library - * - * libmms is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * libmss 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 Library 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 - * - * libmms public header - */ - -/* - * mmsx is a small wrapper around the mms and mmsh protocol implementations - * in libmms. The mmsx functions provide transparent access to both protocols - * so that programs who wish to support both can do so with a single code path - * if desired. - */ - -#ifndef HAVE_MMSX_H -#define HAVE_MMSX_H - -#include <inttypes.h> -#include "mmsio.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef struct mmsx_s mmsx_t; - -mmsx_t* mmsx_connect (mms_io_t *io, void *data, const char *url, int bandwidth); - -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); -mms_off_t mmsx_seek (mms_io_t *io, mmsx_t *instance, mms_off_t offset, int origin); -/* return total playback time in seconds */ -double mmsx_get_time_length (mmsx_t *instance); -/* return raw total playback time in 100 nanosecs (10^-7) */ -uint64_t mmsx_get_raw_time_length (mmsx_t *instance); -uint32_t mmsx_get_length (mmsx_t *instance); -void mmsx_close (mmsx_t *instance); - -int mmsx_peek_header (mmsx_t *instance, char *data, int maxsize); - -mms_off_t mmsx_get_current_pos (mmsx_t *instance); - -uint32_t mmsx_get_asf_header_len (mmsx_t *instance); - -uint64_t mmsx_get_asf_packet_len (mmsx_t *instance); - -int mmsx_get_seekable (mmsx_t *instance); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif - diff --git a/lib/win32/libmms_win32/src/testconnect.c b/lib/win32/libmms_win32/src/testconnect.c deleted file mode 100644 index 9ed2f1a6fb..0000000000 --- a/lib/win32/libmms_win32/src/testconnect.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "mms.h" - -const char *url = "mms://od-msn.msn.com/3/mbr/apprentice_bts.wmv"; - -int main(int argc, char *argv[]) -{ - if(mms_connect(NULL, NULL, url, 1)) - printf("Connect OK\n"); - - return 0; -} diff --git a/lib/win32/libmms_win32/src/testdownload.c b/lib/win32/libmms_win32/src/testdownload.c deleted file mode 100644 index 21d2d566ec..0000000000 --- a/lib/win32/libmms_win32/src/testdownload.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <stdio.h> -#include "mms.h" - -const char *url = "mms://od-msn.msn.com/3/mbr/apprentice_bts.wmv"; - -int main(int argc, char *argv[]) -{ - mms_t *this = NULL; - char buf[1024]; - int i, res; - FILE* f; - - if((this = mms_connect(NULL, NULL, url, 1))) - printf("Connect OK\n"); - f = fopen("/tmp/mmsdownload.test", "w"); - for(i = 0; i < 10000; i++) - { - res = mms_read(NULL, this, buf, 1024); - if(!res) - break; - fwrite(buf, 1, res, f); - } - if(i > 0) - printf("OK, read %d times\n", i); - else - printf("Failed to read from stream\n"); - - -} diff --git a/lib/win32/libmms_win32/src/testswap.c b/lib/win32/libmms_win32/src/testswap.c deleted file mode 100644 index 22b201b922..0000000000 --- a/lib/win32/libmms_win32/src/testswap.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Test byteswapping functions for correct operation */ -/* FIXME: put some more extensive tests here */ - - -#include <sys/types.h> -#include "bswap.h" - - -int main(int argc, char *argv[]) -{ - unsigned char test_value32[5] = "\xFE\xDC\xBA\x10"; - u_int32_t le_uint32 = ((((u_int32_t)(test_value32[3])) << 24) | - (((u_int32_t)(test_value32[2])) << 16) | - (((u_int32_t)(test_value32[1])) << 8) | - (((u_int32_t)(test_value32[0])) << 0)); - - u_int32_t le_uint16 = ((((u_int32_t)(test_value32[1])) << 8) | - (((u_int32_t)(test_value32[0])) << 0)); - - u_int32_t be_uint32 = ((((u_int32_t)(test_value32[0])) << 24) | - (((u_int32_t)(test_value32[1])) << 16) | - (((u_int32_t)(test_value32[2])) << 8) | - (((u_int32_t)(test_value32[3])) << 0)); - - u_int32_t be_uint16 = ((((u_int32_t)(test_value32[0])) << 8) | - (((u_int32_t)(test_value32[1])) << 0)); - - printf("test_value32: %2hhx%2hhx%2hhx%2hhx\n", test_value32[0], - test_value32[1], test_value32[2], test_value32[3]); - printf("test_value32 as u_int32_t: %04x\n", *(u_int32_t*)test_value32); - printf("le_uint32: %04x\n", le_uint32); - printf ("LE_32(le_uint32): %08x\n", LE_32(&le_uint32)); - - printf("test_value16 as u_int16_t: %04x\n", *(u_int16_t*)test_value32); - printf("le_uint16: %04x\n", le_uint16); - printf ("LE_16(le_uint16): %04hx\n", LE_16(&le_uint16)); - - printf("be_uint32: %04x\n", be_uint32); - printf ("BE_32(be_uint32): %08x\n", BE_32(&be_uint32)); - - printf("test_value16 as u_int16_t: %04x\n", *(u_int16_t*)test_value32); - printf("be_uint16: %04x\n", be_uint16); - printf ("BE_16(be_uint16): %04hx\n", BE_16(&be_uint16)); - -} diff --git a/lib/win32/libmms_win32/src/uri.c b/lib/win32/libmms_win32/src/uri.c deleted file mode 100644 index 36710a5252..0000000000 --- a/lib/win32/libmms_win32/src/uri.c +++ /dev/null @@ -1,904 +0,0 @@ -/* GNet - Networking library - * Copyright (C) 2000-2003 David Helder, David Bolcsfoldi, Eric Williams - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* FIXME: #include "gnet-private.h" */ -#include <glib.h> -#include <string.h> -#include <stdlib.h> -#include <ctype.h> - -#include "uri.h" -#include <string.h> - -static void field_unescape (char *str); -static char* field_escape (char* str, unsigned char mask); - -#define USERINFO_ESCAPE_MASK 0x01 -#define PATH_ESCAPE_MASK 0x02 -#define QUERY_ESCAPE_MASK 0x04 -#define FRAGMENT_ESCAPE_MASK 0x08 - -/* #define FALSE 0 */ -/* #define TRUE (!FALSE) */ - -static unsigned char neednt_escape_table[] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x0c, - 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x00, 0x0f, 0x00, 0x00, 0x0f, - 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - - -/* -Perl code to generate above table: - -#!/usr/bin/perl - -$ok = "abcdefghijklmnopqrstuvwxyz" . - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" . - "0123456789" . - "-_.!~*'()"; -$userinfo_ok = ';:&=+\$,'; -$path_ok = ':\@&=+\$,;/'; -$query_ok = ';/?:\@&=+\$,'; -$fragment_ok = ';/?:\@&=+\$,'; - -for ($i = 0; $i < 32; $i++) -{ - print " "; - for ($j = 0; $j < 8; $j++) - { - $num = 0; - $letter = chr(($i * 8) + $j); - - $num |= 0b0001 if (index($userinfo_ok, $letter) != -1); - $num |= 0b0010 if (index($path_ok, $letter) != -1); - $num |= 0b0100 if (index($query_ok, $letter) != -1); - $num |= 0b1000 if (index($fragment_ok, $letter) != -1); - $num |= 0b1111 if (index($ok, $letter) != -1); - - printf "0x%02x, ", $num; - } - print "\n"; -} -*/ - - -/* our own ISSPACE. ANSI isspace is local dependent */ -#define ISSPACE(C) (((C) >= 9 && (C) <= 13) || (C) == ' ') - - -static int split_user_passwd(const char* in, char** user, char** passwd) -{ - char *tmp = strdup(in); - - if(!tmp) - return 0; - *passwd = strchr(tmp, ':'); - if(!(*passwd)) - { - free(tmp); - return 0; - } - *((*passwd)++) = '\0'; // don't you love C? :) - - *user = strdup(tmp); - if(!*user) - return 0; - *passwd = strdup(*passwd); - if(!*passwd) - return 0; - - free(tmp); - return 1; -} - -/** - * gnet_uri_new - * @uri: URI string - * - * Creates a #GURI from a string. Empty fields are set to NULL. The - * parser does not validate the URI -- it will accept some malformed - * URI. URIs are usually in the form - * scheme://userinfo@hostname:port/path?query#fragment - * - * URIs created from user input are typically unescaped. URIs - * created from machine input (e.g. received over the internet) are - * typically escaped. - * - * Returns: a new #GURI, or NULL if there was a failure. - * - **/ -GURI* -gnet_uri_new (const char* uri) -{ - GURI* guri = NULL; - const char* p; - const char* temp; - - g_return_val_if_fail (uri, NULL); - - /* Skip initial whitespace */ - p = uri; - while (*p && ISSPACE((int)*p)) - ++p; - if (!*p) /* Error if it's just a string of space */ - return NULL; - - guri = g_new0 (GURI, 1); - - /* Scheme */ - temp = p; - while (*p && *p != ':' && *p != '/' && *p != '?' && *p != '#') - ++p; - if (*p == ':') - { - guri->scheme = g_strndup (temp, p - temp); - ++p; - } - else /* This char is NUL, /, ?, or # */ - p = temp; - - /* Authority */ - if (*p == '/' && p[1] == '/') - { - char *userinfo; - p += 2; - - /* Userinfo */ - temp = p; - while (*p && *p != '@' && *p != '/' ) /* Look for @ or / */ - ++p; - if (*p == '@') /* Found userinfo */ - { - userinfo = g_strndup (temp, p - temp); - if(!split_user_passwd(userinfo, &guri->user, &guri->passwd)) - { - free(userinfo); - goto error; - } - free(userinfo); - ++p; - } - else - p = temp; - - /* Hostname */ - - /* Check for IPv6 canonical hostname in brackets */ - if (*p == '[') - { - p++; /* Skip [ */ - temp = p; - while (*p && *p != ']') ++p; - if ((p - temp) == 0) - goto error; - guri->hostname = g_strndup (temp, p - temp); - if (*p) - p++; /* Skip ] (if there) */ - } - else - { - temp = p; - while (*p && *p != '/' && *p != '?' && *p != '#' && *p != ':') ++p; - if ((p - temp) == 0) - goto error; - guri->hostname = g_strndup (temp, p - temp); - } - - /* Port */ - if (*p == ':') - { - for (++p; isdigit((int)*p); ++p) - guri->port = guri->port * 10 + (*p - '0'); - } - - } - - /* Path (we are liberal and won't check if it starts with /) */ - temp = p; - while (*p && *p != '?' && *p != '#') - ++p; - if (p != temp) - guri->path = g_strndup(temp, p - temp); - - /* Query */ - if (*p == '?') - { - temp = p + 1; - while (*p && *p != '#') - ++p; - guri->query = g_strndup (temp, p - temp); - } - - /* Fragment */ - if (*p == '#') - { - ++p; - guri->fragment = g_strdup (p); - } - - return guri; - - error: - gnet_uri_delete (guri); - return NULL; -} - - -/** - * gnet_uri_new_fields - * @scheme: scheme - * @hostname: host name - * @port: port - * @path: path - * - * Creates a #GURI from the fields. This function uses the most - * common fields. Use gnet_uri_new_fields_all() to specify all - * fields. - * - * Returns: a new #GURI. - * - **/ -GURI* -gnet_uri_new_fields (const char* scheme, const char* hostname, - const gint port, const char* path) -{ - GURI* uri = NULL; - - uri = g_new0 (GURI, 1); - if (scheme) uri->scheme = g_strdup (scheme); - if (hostname) uri->hostname = g_strdup (hostname); - uri->port = port; - if (path) uri->path = g_strdup (path); - - return uri; -} - - -/** - * gnet_uri_new_fields_all - * @scheme: scheme - * @userinfo: user info - * @hostname: host name - * @port: port - * @path: path - * @query: query - * @fragment: fragment - * - * Creates a #GURI from all fields. - * - * Returns: a new #GURI. - * - **/ -GURI* -gnet_uri_new_fields_all (const char* scheme, const char* user, - const char* passwd, const char* hostname, - const gint port, const char* path, - const char* query, const char* fragment) -{ - GURI* uri = NULL; - - uri = g_new0 (GURI, 1); - if (scheme) uri->scheme = g_strdup (scheme); - if (user) uri->user = g_strdup (user); - if (passwd) uri->passwd = g_strdup (passwd); - if (hostname) uri->hostname = g_strdup (hostname); - uri->port = port; - if (path) uri->path = g_strdup (path); - if (query) uri->query = g_strdup (query); - if (fragment) uri->fragment = g_strdup (fragment); - - return uri; -} - - -/** - * gnet_uri_clone: - * @uri: a #GURI - * - * Copies a #GURI. - * - * Returns: a copy of @uri. - * - **/ -GURI* -gnet_uri_clone (const GURI* uri) -{ - GURI* uri2; - - g_return_val_if_fail (uri, NULL); - - uri2 = g_new0 (GURI, 1); - uri2->scheme = g_strdup (uri->scheme); - uri2->user = g_strdup (uri->user); - uri2->passwd = g_strdup (uri->passwd); - uri2->hostname = g_strdup (uri->hostname); - uri2->port = uri->port; - uri2->path = g_strdup (uri->path); - uri2->query = g_strdup (uri->query); - uri2->fragment = g_strdup (uri->fragment); - - return uri2; -} - - -/** - * gnet_uri_delete: - * @uri: a #GURI - * - * Deletes a #GURI. - * - **/ -void -gnet_uri_delete (GURI* uri) -{ - if (uri) - { - g_free (uri->scheme); - g_free (uri->user); - g_free (uri->passwd); - g_free (uri->hostname); - g_free (uri->path); - g_free (uri->query); - g_free (uri->fragment); - g_free (uri); - } -} - - - - -#define SAFESTRCMP(A,B) (((A)&&(B))?(strcmp((A),(B))):((A)||(B))) - -/** - * gnet_uri_equal - * @p1: a #GURI - * @p2: another #GURI - * - * Compares two #GURI's for equality. - * - * Returns: TRUE if they are equal; FALSE otherwise. - * - **/ -int -gnet_uri_equal (gconstpointer p1, gconstpointer p2) -{ - const GURI* uri1 = (const GURI*) p1; - const GURI* uri2 = (const GURI*) p2; - - g_return_val_if_fail (uri1, FALSE); - g_return_val_if_fail (uri2, FALSE); - - if (uri1->port == uri2->port && - !SAFESTRCMP(uri1->scheme, uri2->scheme) && - !SAFESTRCMP(uri1->user, uri2->user) && - !SAFESTRCMP(uri1->passwd, uri2->passwd) && - !SAFESTRCMP(uri1->hostname, uri2->hostname) && - !SAFESTRCMP(uri1->path, uri2->path) && - !SAFESTRCMP(uri1->query, uri2->query) && - !SAFESTRCMP(uri1->fragment, uri2->fragment)) - return TRUE; - - return FALSE; -} - - -/** - * gnet_uri_hash - * @p: a #GURI - * - * Creates a hash code for @p for use with GHashTable. - * - * Returns: hash code for @p. - * - **/ -guint -gnet_uri_hash (gconstpointer p) -{ - const GURI* uri = (const GURI*) p; - guint h = 0; - - g_return_val_if_fail (uri, 0); - - if (uri->scheme) h = g_str_hash (uri->scheme); - if (uri->user) h ^= g_str_hash (uri->user); - if (uri->passwd) h ^= g_str_hash (uri->passwd); - if (uri->hostname) h ^= g_str_hash (uri->hostname); - h ^= uri->port; - if (uri->path) h ^= g_str_hash (uri->path); - if (uri->query) h ^= g_str_hash (uri->query); - if (uri->fragment) h ^= g_str_hash (uri->fragment); - - return h; -} - - -/** - * gnet_uri_escape - * @uri: a #GURI - * - * Escapes the fields in a #GURI. Network protocols use escaped - * URIs. People use unescaped URIs. - * - **/ -void -gnet_uri_escape (GURI* uri) -{ - g_return_if_fail (uri); - - uri->user = field_escape (uri->user, USERINFO_ESCAPE_MASK); - uri->passwd = field_escape (uri->passwd, USERINFO_ESCAPE_MASK); - uri->path = field_escape (uri->path, PATH_ESCAPE_MASK); - uri->query = field_escape (uri->query, QUERY_ESCAPE_MASK); - uri->fragment = field_escape (uri->fragment, FRAGMENT_ESCAPE_MASK); -} - - -/** - * gnet_uri_unescape - * @uri: a #GURI - * - * Unescapes the fields in the URI. Network protocols use escaped - * URIs. People use unescaped URIs. - * - **/ -void -gnet_uri_unescape (GURI* uri) -{ - g_return_if_fail (uri); - - if (uri->user) - field_unescape (uri->user); - if (uri->passwd) - field_unescape (uri->passwd); - if (uri->path) - field_unescape (uri->path); - if (uri->query) - field_unescape (uri->query); - if (uri->fragment) - field_unescape (uri->fragment); -} - - -static char* -field_escape (char* str, unsigned char mask) -{ - gint len; - gint i; - int must_escape = FALSE; - char* dst; - gint j; - - if (str == NULL) - return NULL; - - /* Roughly calculate buffer size */ - len = 0; - for (i = 0; str[i]; i++) - { - if (neednt_escape_table[(guint) str[i]] & mask) - len++; - else - { - len += 3; - must_escape = TRUE; - } - } - - /* Don't escape if unnecessary */ - if (must_escape == FALSE) - return str; - - /* Allocate buffer */ - dst = (char*) g_malloc(len + 1); - - /* Copy */ - for (i = j = 0; str[i]; i++, j++) - { - /* Unescaped character */ - if (neednt_escape_table[(guint) str[i]] & mask) - { - dst[j] = str[i]; - } - - /* Escaped character */ - else - { - dst[j] = '%'; - - if (((str[i] & 0xf0) >> 4) < 10) - dst[j+1] = ((str[i] & 0xf0) >> 4) + '0'; - else - dst[j+1] = ((str[i] & 0xf0) >> 4) + 'a' - 10; - - if ((str[i] & 0x0f) < 10) - dst[j+2] = (str[i] & 0x0f) + '0'; - else - dst[j+2] = (str[i] & 0x0f) + 'a' - 10; - - j += 2; /* and j is incremented in loop too */ - } - } - dst[j] = '\0'; - - g_free (str); - return dst; -} - - - -static void -field_unescape (char* s) -{ - char* src; - char* dst; - - for (src = dst = s; *src; ++src, ++dst) - { - if (src[0] == '%' && src[1] != '\0' && src[2] != '\0') - { - gint high, low; - - if ('a' <= src[1] && src[1] <= 'f') - high = src[1] - 'a' + 10; - else if ('A' <= src[1] && src[1] <= 'F') - high = src[1] - 'A' + 10; - else if ('0' <= src[1] && src[1] <= '9') - high = src[1] - '0'; - else /* malformed */ - goto regular_copy; - - if ('a' <= src[2] && src[2] <= 'f') - low = src[2] - 'a' + 10; - else if ('A' <= src[2] && src[2] <= 'F') - low = src[2] - 'A' + 10; - else if ('0' <= src[2] && src[2] <= '9') - low = src[2] - '0'; - else /* malformed */ - goto regular_copy; - - *dst = (char)((high << 4) + low); - src += 2; - } - else - { - regular_copy: - *dst = *src; - } - } - - *dst = '\0'; -} - - - -/** - * gnet_uri_get_string - * @uri: a #GURI - * - * Gets a string representation of a #GURI. This function does not - * escape or unescape the fields first. Call gnet_uri_escape() or - * gnet_uri_unescape first if necessary. - * - * Returns: a string. - * - **/ -char* -gnet_uri_get_string (const GURI* uri) -{ - char* rv = NULL; - GString* buffer = NULL; - - g_return_val_if_fail (uri, NULL); - - buffer = g_string_sized_new (16); - - if (uri->scheme) - g_string_sprintfa (buffer, "%s:", uri->scheme); - - if (uri->user || uri->passwd || uri->hostname || uri->port) - g_string_append (buffer, "//"); - - if (uri->user) - { - buffer = g_string_append (buffer, uri->user); - buffer = g_string_append_c (buffer, '@'); - } - if (uri->passwd) - { - buffer = g_string_append (buffer, uri->passwd); - buffer = g_string_append_c (buffer, '@'); - } - - /* Add brackets around the hostname if it's IPv6 */ - if (uri->hostname) - { - if (strchr(uri->hostname, ':') == NULL) - buffer = g_string_append (buffer, uri->hostname); - else - g_string_sprintfa (buffer, "[%s]", uri->hostname); - } - - if (uri->port) - g_string_sprintfa (buffer, ":%d", uri->port); - - if (uri->path) - { - if (*uri->path == '/' || - !(uri->user || uri->passwd || uri->hostname || uri->port)) - g_string_append (buffer, uri->path); - else - g_string_sprintfa (buffer, "/%s", uri->path); - } - - if (uri->query) - g_string_sprintfa (buffer, "?%s", uri->query); - - if (uri->fragment) - g_string_sprintfa (buffer, "#%s", uri->fragment); - - /* Free only GString not data contained, return the data instead */ - rv = buffer->str; - g_string_free (buffer, FALSE); - return rv; -} - - -/** - * gnet_uri_set_scheme - * @uri: a #GURI - * @scheme: scheme - * - * Sets a #GURI's scheme. - * - **/ -void -gnet_uri_set_scheme (GURI* uri, const char* scheme) -{ - g_return_if_fail (uri); - - if (uri->scheme) - { - g_free (uri->scheme); - uri->scheme = NULL; - } - - if (scheme) - uri->scheme = g_strdup (scheme); -} - - -/** - * gnet_uri_set_userinfo - * @uri: a #GURI - * @userinfo: user info - * - * Sets a #GURI's user info. - * - **/ -void -gnet_uri_set_userinfo (GURI* uri, const char* user, const char* passwd) -{ - g_return_if_fail (uri); - - if (uri->user) - { - g_free (uri->user); - uri->user = NULL; - } - if (uri->passwd) - { - g_free (uri->passwd); - uri->passwd = NULL; - } - - if (user) - uri->user = g_strdup (user); - if (passwd) - uri->passwd = g_strdup (passwd); -} - - -/** - * gnet_uri_set_hostname - * @uri: a #GURI - * @hostname: host name - * - * Sets a #GURI's host name. - * - **/ -void -gnet_uri_set_hostname (GURI* uri, const char* hostname) -{ - g_return_if_fail (uri); - - if (uri->hostname) - { - g_free (uri->hostname); - uri->hostname = NULL; - } - - if (hostname) - uri->hostname = g_strdup (hostname); -} - - -/** - * gnet_uri_set_port - * @uri: a #GURI - * @port: port - * - * Set a #GURI's port. - * - **/ -void -gnet_uri_set_port (GURI* uri, gint port) -{ - uri->port = port; -} - - -/** - * gnet_uri_set_path - * @uri: a #GURI - * @path: path - * - * Set a #GURI's path. - * - **/ -void -gnet_uri_set_path (GURI* uri, const char* path) -{ - g_return_if_fail (uri); - - if (uri->path) - { - g_free (uri->path); - uri->path = NULL; - } - - if (path) - uri->path = g_strdup (path); -} - - - -/** - * gnet_uri_set_query - * @uri: a #GURI - * @query: query - * - * Set a #GURI's query. - * - **/ -void -gnet_uri_set_query (GURI* uri, const char* query) -{ - g_return_if_fail (uri); - - if (uri->query) - { - g_free (uri->query); - uri->query = NULL; - } - - if (query) - uri->query = g_strdup (query); -} - - -/** - * gnet_uri_set_fragment - * @uri: a #GURI - * @fragment: fragment - * - * Set a #GURI's fragment. - * - **/ -void -gnet_uri_set_fragment (GURI* uri, const char* fragment) -{ - g_return_if_fail (uri); - - if (uri->fragment) - { - g_free (uri->fragment); - uri->fragment = NULL; - } - - if (fragment) - uri->fragment = g_strdup (fragment); -} - - -/** - * gnet_mms_helper - * @uri: a #GURI - * - * returns char* representation of an uri that is sutable for - * using in mms protocol. - * '/path?query' - * - **/ - -char* gnet_mms_helper(const GURI* uri) -{ - size_t len = 0; - char *ret, *tmp = NULL; - - - /* Strip leading slashes and calculate the length of the path - * which might not be present in the URI */ - if (uri->path) { - tmp = uri->path; - while (*tmp == '/') - ++tmp; - len += strlen(tmp); - } - /* Append length of the query part */ - if (uri->query) - len += strlen(uri->query) + 1; /* + '?' */ - - if (!(ret = (char *) malloc(len + 2))) - return NULL; - - strcpy(ret, "/"); - - /* Copy the optional path */ - if (tmp) - strcat(ret, tmp); - - /* Copy the optional query */ - if (uri->query) { - strcat(ret, "?"); - strcat(ret, uri->query); - } - - return ret; -} diff --git a/lib/win32/libmms_win32/src/uri.h b/lib/win32/libmms_win32/src/uri.h deleted file mode 100644 index c7a93edfe9..0000000000 --- a/lib/win32/libmms_win32/src/uri.h +++ /dev/null @@ -1,94 +0,0 @@ -/* GNet - Networking library - * Copyright (C) 2000-2001 David Helder, David Bolcsfoldi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#ifndef _GNET_URI_H -#define _GNET_URI_H - -#include <glib.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/** - * GURI: - * @scheme: Scheme (or protocol) - * @userinfo: User info - * @hostname: Host name - * @port: Port number - * @path: Path - * @query: Query - * @fragment: Fragment - * - * The #GURI structure represents a URI. All fields in this - * structure are publicly readable. - * - **/ -typedef struct _GURI GURI; - -struct _GURI -{ - char* scheme; - char* user; - char* passwd; - char* hostname; - gint port; - char* path; - char* query; - char* fragment; -}; - - - -GURI* gnet_uri_new (const char* uri); -GURI* gnet_uri_new_fields (const char* scheme, const char* hostname, - const gint port, const char* path); -GURI* -gnet_uri_new_fields_all (const char* scheme, const char* user, - const char* passwd, const char* hostname, - const gint port, const char* path, - const char* query, const char* fragment); -GURI* gnet_uri_clone (const GURI* uri); -void gnet_uri_delete (GURI* uri); - -gboolean gnet_uri_equal (gconstpointer p1, gconstpointer p2); -guint gnet_uri_hash (gconstpointer p); - -void gnet_uri_escape (GURI* uri); -void gnet_uri_unescape (GURI* uri); - -char* gnet_uri_get_string (const GURI* uri); - -void gnet_uri_set_scheme (GURI* uri, const char* scheme); -void gnet_uri_set_userinfo (GURI* uri, const char* user, const char* passwd); -void gnet_uri_set_hostname (GURI* uri, const char* hostname); -void gnet_uri_set_port (GURI* uri, gint port); -void gnet_uri_set_path (GURI* uri, const char* path); -void gnet_uri_set_query (GURI* uri, const char* query); -void gnet_uri_set_fragment (GURI* uri, const char* fragment); - -char* gnet_mms_helper(const GURI* uri); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _GNET_URI_H */ diff --git a/lib/win32/libmms_win32/src/utils.c b/lib/win32/libmms_win32/src/utils.c deleted file mode 100644 index 985dd58916..0000000000 --- a/lib/win32/libmms_win32/src/utils.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2008 the xine project - * - * This file is part of LibMMS, an MMS protocol handling library. - * - * 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 ree 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 - * - * $Id: mms.c,v 1.31 2007/12/11 20:35:01 jwrdegoede Exp $ - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glib.h> -#include "utils.h" - -gdouble util_guint64_to_gdouble (guint64 value) -{ - if (value & G_GINT64_CONSTANT (0x8000000000000000)) - return (gdouble) ((gint64) value) + (gdouble) 18446744073709551616.; - else - return (gdouble) ((gint64) value); -} - diff --git a/lib/win32/libmms_win32/src/utils.h b/lib/win32/libmms_win32/src/utils.h deleted file mode 100644 index 1823f76f75..0000000000 --- a/lib/win32/libmms_win32/src/utils.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2008 the xine project - * - * This file is part of LibMMS, an MMS protocol handling library. - * - * 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 ree 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 - * - * $Id: mms.c,v 1.31 2007/12/11 20:35:01 jwrdegoede Exp $ - */ - -#ifndef __UTILS_H__ -#define __UTILS_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -gdouble util_guint64_to_gdouble (guint64 value); - -#ifdef WIN32 -#define guint64_to_gdouble(value) util_guint64_to_gdouble(value) -#else -#define guint64_to_gdouble(value) ((gdouble) (value)) -#endif - -G_END_DECLS - -#endif /* __UTILS_H__ */ |