summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2002-03-19 02:12:49 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2002-03-19 02:12:49 +0000
commit45e8d9079bac057741810a62bb41215e575ce56c (patch)
tree8c848a4dfdb8283f53ec91637145364ab6c77222
parent31bb532cd84320a72f10e72cc6ca9c062ecfc948 (diff)
downloadxine-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.c20
-rw-r--r--src/input/asxparser.c284
-rw-r--r--src/input/input_mms.c59
-rw-r--r--src/input/mms.c89
-rw-r--r--src/input/mms.h2
-rw-r--r--src/xine-engine/audio_out.c4
-rw-r--r--src/xine-engine/audio_out.h4
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 */