diff options
author | Guenter Bartsch <guenter@users.sourceforge.net> | 2002-03-19 02:12:49 +0000 |
---|---|---|
committer | Guenter Bartsch <guenter@users.sourceforge.net> | 2002-03-19 02:12:49 +0000 |
commit | 45e8d9079bac057741810a62bb41215e575ce56c (patch) | |
tree | 8c848a4dfdb8283f53ec91637145364ab6c77222 | |
parent | 31bb532cd84320a72f10e72cc6ca9c062ecfc948 (diff) | |
download | xine-lib-45e8d9079bac057741810a62bb41215e575ce56c.tar.gz xine-lib-45e8d9079bac057741810a62bb41215e575ce56c.tar.bz2 |
improved buffering for audio-only streams
(wanna try? gnome-xine mms://live5-ms.unbn.unit.net/radio_project )
forced asx-parser back to a (hopefully) working state
fixed warning about wrong audio_instance type
CVS patchset: 1591
CVS date: 2002/03/19 02:12:49
-rw-r--r-- | src/demuxers/demux_asf.c | 20 | ||||
-rw-r--r-- | src/input/asxparser.c | 284 | ||||
-rw-r--r-- | src/input/input_mms.c | 59 | ||||
-rw-r--r-- | src/input/mms.c | 89 | ||||
-rw-r--r-- | src/input/mms.h | 2 | ||||
-rw-r--r-- | src/xine-engine/audio_out.c | 4 | ||||
-rw-r--r-- | src/xine-engine/audio_out.h | 4 |
7 files changed, 220 insertions, 242 deletions
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c index e50b36f70..1b32d418a 100644 --- a/src/demuxers/demux_asf.c +++ b/src/demuxers/demux_asf.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: demux_asf.c,v 1.30 2002/03/18 22:45:53 guenter Exp $ + * $Id: demux_asf.c,v 1.31 2002/03/19 02:12:49 guenter Exp $ * * demultiplexer for asf streams * @@ -1275,12 +1275,26 @@ static int demux_asf_open(demux_plugin_t *this_gen, input_plugin_t *input, int stage) { demux_asf_t *this = (demux_asf_t *) this_gen; + uint8_t buf[8192]; + int len; switch(stage) { - case STAGE_BY_CONTENT: + + /* + * try to get a preview of the data + */ + len = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW); + if (len == INPUT_OPTIONAL_UNSUPPORTED) + return DEMUX_CANNOT_HANDLE; + + if (!memcmp(buf, &asf_header, sizeof(GUID))) { + printf ("demux_asf: file starts with an asf header\n"); + this->input = input; + return DEMUX_CAN_HANDLE; + } + return DEMUX_CANNOT_HANDLE; - break; case STAGE_BY_EXTENSION: { char *ending; diff --git a/src/input/asxparser.c b/src/input/asxparser.c index b23a3529a..b094b5f49 100644 --- a/src/input/asxparser.c +++ b/src/input/asxparser.c @@ -3,227 +3,157 @@ #include <sys/types.h> #include <fcntl.h> #include <string.h> -#include "mms.h" +#include <mms.h> #include <unistd.h> #include <ctype.h> +void asx_find_entries(char* buff, char** fname, + int *IsNotFinished); +char *strupr(char *string); -extern char *mms_url_s[]; -extern char *mms_url_e[]; +void first_request(char *buff, char *host, char *file, int *len) { -void asx_find_entries(char* buff,char *url, char** fname, - int *IsNotFinished ) -{ - int res; - int delta; - int delta1=0; - char *ptr; - char* ptre=NULL; - char* ptre1=NULL; - - - - delta=mms_start_where(buff); - if(delta < 0) - return ; - - ptr=buff+delta; - if(!strncasecmp(ptr,"HREF",4)){ - char* lastsl; - lastsl=(char*)strchr(ptr,'/'); - if(lastsl) - ptr=lastsl; - lastsl=(char*)strrchr(url,'/'); - if(lastsl) - delta1=lastsl-url; - } - ptre1=(char*)strstr(ptr, "#"); - if (!ptre1) - ptre1=(char*)strstr(ptr, "?"); - if (!ptre) - ptre=(char*)strstr(ptr, "\"/>"); - if (!ptre) - ptre=(char*)strstr(ptr, "\" "); - if (!ptre) - ptre=(char*)strstr(ptr, "\"\t"); - if (!ptre) - ptre=(char*)strstr(ptr, "\"\n"); - if (!ptre) - ptre=(char*)strstr(ptr, "\t"); - if (!ptre) - ptre=(char*)strstr(ptr, "\r"); - if (!ptre) - ptre=(char*)strstr(ptr, "\n"); - if (!ptre) - ptre=(char*)strstr(ptr, " "); - - if( ((ptre > ptre1) && ptre1) || (!ptre && ptre1) ) - ptre=ptre1; - - if(!ptre){ - char *ptr1; - - ptr1=(char*)strrchr(ptr,'.'); - - if(!ptr1) - goto cont; - - - if (!mms_url_is(ptr1+1, mms_url_e)) { - - } - else - ptre=ptr1+4; - - - - } - cont: - printf("TEST 1 \n"); - if (!ptre) - return ; - - printf("TEST 2 \n"); - res=(int)(ptre-ptr); - if(res<=0) - return ; - if ( !delta1 ){ - (*fname)=(char*)realloc((*fname),res+2); - memcpy(*fname,ptr,res); - (*fname)[res]=0; - } - else{ - (*fname)=(char*)realloc((*fname),res+2+delta1+1); - memcpy(*fname,url,delta1+1); - memcpy(*fname+delta1,ptr,res+2); - (*fname)[res+delta1+1]=0; - } - - printf("asxparser path is %s \n", *fname); - return ; -} -void first_request(char* buff,char* host, char* file,int *len) -{ char *ptr; bzero(buff,*len); ptr=buff; ptr+=sprintf(ptr,"GET %s HTTP/1.0\r\n",file); ptr+=sprintf(ptr,"Accept: */*\r\n"); - ptr+=sprintf(ptr,"User-Agent: NSPlayer/7.0.0.1956\r\n"); + ptr+=sprintf(ptr,"User-Agent: xine/0.9.8\r\n"); ptr+=sprintf(ptr,"Host: %s\r\n", host); ptr+=sprintf(ptr,"Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=0:0,request-context=1,max-duration=0\r\n"); ptr+=sprintf(ptr,"Pragma: xClientGUID=%s\r\n", "{33715801-BAB3-9D85-24E9-03B90328270A}"); - - ptr+=sprintf(ptr,"Connection: Keep-Alive\r\n\r\n"); - + ptr+=sprintf(ptr,"Connection: Close\r\n\r\n"); *len =(int)ptr-(int)buff; } +int asx_parse (char* mrl, char** rname) { -int asx_parse (char* fname, char** rname) -{ - char* ptr=NULL; - char buff[1024]; - int res; - int IsNotFinished=0; - char *url, *host=NULL, *hostend=NULL; - char buff1[1024]; - int s ,l; - char notyetconnected=1; - - if(!fname) - return 1; - - ptr=(char*)strrchr(fname,'.'); + char* ptr=NULL; + char buff[1024]; + int res; + int is_not_finished=0; + char *url, *host, *hostend; + char *path, *file; + int hostlen, s ,l; - if(!ptr) - return 1; - - - if( mms_start_where(fname) < 0 ){ - FILE *fp; - /* probably it is asx file on the disk*/ - fp=fopen(fname,"r"); - if(!fp) - return 1; - fread(buff,sizeof(buff),1,fp); - fclose(fp); - printf ("asxparser: buff =%s \n",buff ); - goto proc; - } + if (strncasecmp (mrl, "mmshttp://", 10)) { + return 0; + } - strncpy(buff1,fname,sizeof(buff1)); - /* extract hostname/test/connect */ - conn: + ptr=strstr(mrl,"//"); + if(!ptr) + return 0; + + l=ptr-mrl+2; + url = strdup (mrl); - url=mms_connect_common(&s,80,buff1,&host,&hostend,NULL,NULL); - if(!url) - return 1; + /* extract hostname */ + hostend = strchr(&url[l],'/'); + if (!hostend) { + printf ("asxparser: invalid url >%s<, failed to find hostend \n", url); + free(url); + return 0; + } + hostlen = hostend - url - l; + host = malloc (hostlen+1); + strncpy (host, &url[l], hostlen); + host[hostlen]=0; + + /* extract path and file */ + + path = url+hostlen+l+1; + file = strrchr (url, '/'); + + /* + * try to connect + */ + + printf("asxparser host=%s \n",host); + printf("asxparser file=%s \n",hostend); + s = host_connect (host, 80); + if (s == -1) { + printf ("asxparser: failed to connect\n"); + free (host); + free (url); + return 0; + } printf("asxparser: connect passed \n"); - notyetconnected=0; l=sizeof(buff); - first_request(buff, host,hostend, &l); + first_request(buff, host, hostend, &l); write(s,buff,l); res=read(s,buff, sizeof(buff)); - printf("asxparser: answer1=::%s:: \n %d byte received \n",buff,res); - - - if(mms_start_where(buff) < 0){ - l=sizeof(buff); - /* second_request(buff, host,hostend, &l); + printf("asxparser: answer1=%s %d byte received \n",buff,res); + if(!strstr(buff,"mms://")) { + l=sizeof(buff); + first_request(buff, host, hostend, &l); write(s,buff,l); -*/ - res=read(s,buff, sizeof(buff)); - printf("asxparser: answer2=%s %d byte received\n",buff,res); -} - - + res=read(s,buff, sizeof(buff)); + printf("asxparser: answer2=%s %d byte received\n",buff,res); + } close(s); + free(url); free(host); + if(res<1) + return 0; + + printf ("asxparser: finding entries...\n"); + + asx_find_entries(buff,rname,&is_not_finished); - if(res<1){ - char *ext; + return 1; - ext=strrchr(buff1,'.'); +} + +void asx_find_entries (char* buff, char** fname, + int *is_not_finished ) { + int res; + char *ptr; + char *uptr; + char* ptre; - if(mms_url_is(buff1,mms_url_s) - && ext && mms_url_is(ext+1, mms_url_e)){ - printf("asxparser: using url received from browser \n"); - return 0; - } - printf("asxparser: no success fname=%s ext=%s \n",fname,ext); - return 1; + /*no <ASX VERSION >*/ + uptr=strdup(buff); + uptr=strupr(uptr); + + if (!strstr(uptr,"ASX VERSION")){ + free(uptr); + return ; } + free(uptr); + + ptr=(char*)strstr(buff, "mms://"); + if(!ptr) + return ; + ptre=(char*)strstr(ptr, "\""); + if (!ptre) + return ; + + res=(int)(ptre-ptr); + if(res<=0) + return ; + (*fname)=(char*)malloc(res+2); + memcpy(*fname,ptr,res); + (*fname)[res]=0; - proc: - asx_find_entries(buff,fname,rname,&IsNotFinished); - if(notyetconnected && *rname){ - strncpy(buff1,*rname,sizeof(buff1)); - goto conn; - } - printf("asx_parser passed \n"); - return 0; - + printf("asxparser path is %s \n", *fname); + return ; } - -char *strupr(char *string) -{ +char *strupr(char *string) { char *s; - if (string) - { - for (s = string; *s; ++s) - *s = toupper(*s); - } + if (string){ + for (s = string; *s; ++s) + *s = toupper(*s); + } return string; } diff --git a/src/input/input_mms.c b/src/input/input_mms.c index 04c477f8f..7f56b65d3 100644 --- a/src/input/input_mms.c +++ b/src/input/input_mms.c @@ -78,16 +78,11 @@ static int mms_plugin_open (input_plugin_t *this_gen, char *mrl) { char* nmrl=NULL; char* uptr; - int error_id; + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; - error_id=asx_parse(mrl,&nmrl); - - if(error_id) - return 0; - - if(!nmrl) - nmrl=mrl; + if (!asx_parse (mrl,&nmrl)) + nmrl = mrl; printf("mms_plugin_open: using mrl <%s> \n", nmrl); @@ -95,13 +90,19 @@ static int mms_plugin_open (input_plugin_t *this_gen, char *mrl) { if (!mms_url_is(nmrl,mms_url_s)){ return 0; - } + } this->mrl = strdup(nmrl); /* FIXME: small memory leak */ + this->xine->osd_renderer->filled_rect (this->xine->osd, 0, 0, 299, 99, 0); + this->xine->osd_renderer->render_text (this->xine->osd, 5, 30, "mms: contacting...", OSD_TEXT1); + this->xine->osd_renderer->show (this->xine->osd, 0); + this->mms = mms_connect (nmrl); + this->xine->osd_renderer->hide (this->xine->osd, 0); + if (!this->mms){ return 0; @@ -112,13 +113,13 @@ static int mms_plugin_open (input_plugin_t *this_gen, char *mrl) { /* register our scr plugin */ - this->scr->scr.start (&this->scr->scr, this->xine->metronom->get_current_time (this->xine->metronom)); - this->xine->metronom->register_scr (this->xine->metronom, &this->scr->scr); + this->scr->scr.start (&this->scr->scr, this->xine->metronom->get_current_time (this->xine->metronom)); + this->xine->metronom->register_scr (this->xine->metronom, &this->scr->scr); return 1; } -#define LOW_WATER_MARK 50 -#define HIGH_WATER_MARK 100 +#define LOW_WATER_MARK 25 +#define HIGH_WATER_MARK 50 static off_t mms_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { @@ -132,20 +133,38 @@ static off_t mms_plugin_read (input_plugin_t *this_gen, #endif fifo_fill = this->xine->video_fifo->size(this->xine->video_fifo); + if (this->xine->audio_fifo) { + fifo_fill += 8*this->xine->audio_fifo->size(this->xine->audio_fifo); + } + if (this->buffering) { + xine_log (this->xine, XINE_LOG_MSG, + "input_mms: buffering (%d/%d)...\n", fifo_fill, HIGH_WATER_MARK); + } if (fifo_fill<LOW_WATER_MARK) { + if (!this->buffering) { + this->xine->osd_renderer->filled_rect (this->xine->osd, 0, 0, 299, 99, 0); + this->xine->osd_renderer->render_text (this->xine->osd, 5, 30, "mms: buffering...", OSD_TEXT1); + this->xine->osd_renderer->show (this->xine->osd, 0); + + /* give video_out time to display osd before pause */ + sleep (1); + } + this->xine->metronom->set_speed (this->xine->metronom, SPEED_PAUSE); + this->xine->audio_out->audio_paused = 2; this->buffering = 1; this->scr->adjustable = 0; - printf ("input_mms: buffering (%d/%d)...\n", fifo_fill, LOW_WATER_MARK); } else if ( (fifo_fill>HIGH_WATER_MARK) && (this->buffering)) { this->xine->metronom->set_speed (this->xine->metronom, SPEED_NORMAL); + this->xine->audio_out->audio_paused = 0; this->buffering = 0; this->scr->adjustable = 1; - printf ("input_mms: buffering...done\n"); + + this->xine->osd_renderer->hide (this->xine->osd, 0); } n = mms_read (this->mms, buf, len); @@ -307,6 +326,16 @@ static char* mms_plugin_get_mrl (input_plugin_t *this_gen) { 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: + + return mms_peek_header (this->mms, data); + + break; + } + return INPUT_OPTIONAL_UNSUPPORTED; } diff --git a/src/input/mms.c b/src/input/mms.c index 419f5412d..ab5d38a32 100644 --- a/src/input/mms.c +++ b/src/input/mms.c @@ -511,57 +511,54 @@ static void interp_header (mms_t *this) { } -int mms_url_is(char* url, char** mms_url) - { - int i=0; - char* uptr; +int mms_url_is(char* url, char** mms_url) { + int i=0; + char* uptr; - printf("mms_url_is l=%d \n",strlen(mms_url[0])); - if(!url ) - return 0; - uptr=strdup(url); - uptr=strupr(uptr); - while(mms_url[i]){ - if(!strncasecmp(uptr,mms_url[i],strlen(mms_url[i]) )){ - free(uptr); - return strlen(mms_url[i]); - } - i++; - } - free(uptr); + printf("mms_url_is l=%d \n",strlen(mms_url[0])); + if(!url ) return 0; - } -int mms_start_where(char* url) - { - int i=0; - int delta; - char *p; - char* uptr; - - if(!url ) - return -1; - uptr=strdup(url); - uptr=strupr(uptr); - while(mms_url_s[i]){ - if((p=strstr(uptr,mms_url_s[i]))){ - delta=p-uptr; - free(uptr); - return delta; - } - i++; + uptr=strdup(url); + uptr=strupr(uptr); + while(mms_url[i]){ + if(!strncasecmp(uptr,mms_url[i],strlen(mms_url[i]) )){ + free(uptr); + return strlen(mms_url[i]); } - free(uptr); + i++; + } + free(uptr); + return 0; +} + +int mms_start_where(char* url) { + int i=0; + int delta; + char *p; + char* uptr; + + if (!url) return -1; - } -char* mms_connect_common(int *s ,int port,char *url, char **host , char** hostend, - char **path,char **file) -{ + uptr=strdup(url); + uptr=strupr(uptr); + while(mms_url_s[i]){ + if((p=strstr(uptr,mms_url_s[i]))){ + delta=p-uptr; + free(uptr); + return delta; + } + i++; + } + free(uptr); + return -1; +} + +char* mms_connect_common(int *s, int port, char *url, char **host, char** hostend, + char **path, char **file) { int hostlen; int proto_len; char *forport; - - if(!(proto_len=mms_url_is(url,mms_url_s))){ @@ -834,6 +831,12 @@ static int get_media_packet (mms_t *this) { return 1; } +int mms_peek_header (mms_t *this, char *data) { + + memcpy (data, this->asf_header, this->asf_header_len); + return this->asf_header_len; +} + int mms_read (mms_t *this, char *data, int len) { int total; diff --git a/src/input/mms.h b/src/input/mms.h index b1a8879bb..31f5ab0f7 100644 --- a/src/input/mms.h +++ b/src/input/mms.h @@ -39,5 +39,7 @@ int mms_read (mms_t *this, char *data, int len); uint32_t mms_get_length (mms_t *this); void mms_close (mms_t *this); +int mms_peek_header (mms_t *this, char *data); + #endif diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index a30d99ab2..27dc57dfb 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -17,7 +17,7 @@ * along with self program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_out.c,v 1.47 2002/03/18 22:45:53 guenter Exp $ + * $Id: audio_out.c,v 1.48 2002/03/19 02:12:49 guenter Exp $ * * 22-8-2001 James imported some useful AC3 sections from the previous alsa driver. * (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> @@ -260,7 +260,7 @@ static void *ao_loop (void *this_gen) { #ifdef LOG printf ("audio_out: current delay is %d, current time is %lld\n", - delay, cur_time); + delay, cur_time); #endif /* External A52 decoder delay correction */ diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h index 471c21a2e..03600edcf 100644 --- a/src/xine-engine/audio_out.h +++ b/src/xine-engine/audio_out.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: audio_out.h,v 1.26 2002/03/11 19:58:01 jkeil Exp $ + * $Id: audio_out.h,v 1.27 2002/03/19 02:12:50 guenter Exp $ */ #ifndef HAVE_AUDIO_OUT_H #define HAVE_AUDIO_OUT_H @@ -191,7 +191,7 @@ struct ao_instance_s { * * See AO_CTRL_* below. */ - int (*control) (ao_driver_t *this, int cmd, /* arg */ ...); + int (*control) (ao_instance_t *this, int cmd, /* arg */ ...); /* private stuff */ |