diff options
author | Stefan Holst <holstsn@users.sourceforge.net> | 2002-12-26 14:57:33 +0000 |
---|---|---|
committer | Stefan Holst <holstsn@users.sourceforge.net> | 2002-12-26 14:57:33 +0000 |
commit | 808cb01e516d7e9b9916bb59f56912b8e138cdcb (patch) | |
tree | 187a768067ea75ce1dd3065e10cf54ff72de12ec | |
parent | 50995cd8f35202c609bc83f7f2709fe412fa7c60 (diff) | |
download | xine-lib-808cb01e516d7e9b9916bb59f56912b8e138cdcb.tar.gz xine-lib-808cb01e516d7e9b9916bb59f56912b8e138cdcb.tar.bz2 |
pnm stream setup improvements
CVS patchset: 3683
CVS date: 2002/12/26 14:57:33
-rw-r--r-- | src/input/pnm.c | 100 |
1 files changed, 61 insertions, 39 deletions
diff --git a/src/input/pnm.c b/src/input/pnm.c index 0a4339f85..da91d67ad 100644 --- a/src/input/pnm.c +++ b/src/input/pnm.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: pnm.c,v 1.6 2002/12/22 00:35:04 komadori Exp $ + * $Id: pnm.c,v 1.7 2002/12/26 14:57:33 holstsn Exp $ * * pnm protocol implementation * based upon code from joschka @@ -326,11 +326,11 @@ static void hexdump (char *buf, int length) { * pnm_get_chunk gets a chunk from stream * and returns number of bytes read */ - + static unsigned int pnm_get_chunk(pnm_t *p, unsigned int max, unsigned int *chunk_type, - char *data) { + char *data, int *need_response) { unsigned int chunk_size; int n; @@ -341,45 +341,55 @@ static unsigned int pnm_get_chunk(pnm_t *p, if (data[0] == 0x72) rm_read (p->s, data, PREAMBLE_SIZE); else - rm_read (p->s, &data[CHECKSUM_SIZE], PREAMBLE_SIZE-CHECKSUM_SIZE); + rm_read (p->s, data+CHECKSUM_SIZE, PREAMBLE_SIZE-CHECKSUM_SIZE); - *chunk_type = BE_32(&data[0]); - chunk_size = BE_32(&data[4]); + *chunk_type = BE_32(data); + chunk_size = BE_32(data+4); switch (*chunk_type) { case PNA_TAG: - ptr=&data[PREAMBLE_SIZE]; - rm_read (p->s, ptr, 0x0c - PREAMBLE_SIZE); - ptr+=0x0b-PREAMBLE_SIZE; - if (data[PREAMBLE_SIZE+0x01] == 'X') /* checking for server message */ - { - printf("input_pnm: got a message from server:\n"); /* print message and exit */ - n=BE_16(&data[PREAMBLE_SIZE+0x02]); - rm_read (p->s, &data[PREAMBLE_SIZE+0x04], n); - data[PREAMBLE_SIZE+0x04+n]=0; - printf("%s\n",&data[PREAMBLE_SIZE+0x04]); - return -1; - } - if (data[PREAMBLE_SIZE+0x01] == 'F') - { - printf("input_pnm: server error.\n"); - return -1; - } - - /* expecting following chunk format: 0x4f <chunk size> <data...> */ - rm_read (p->s, ptr+1, 1); - while (*ptr == 0x4f) { - ptr++; - n=(*ptr); - ptr++; - rm_read (p->s, ptr, n+2); - ptr+=n; + *need_response=0; + ptr=data+PREAMBLE_SIZE; + rm_read (p->s, ptr++, 1); + + while(1) { + /* expecting following chunk format: 0x4f <chunk size> <data...> */ + + rm_read (p->s, ptr, 2); + if (*ptr == 'X') /* checking for server message */ + { + printf("input_pnm: got a message from server:\n"); + rm_read (p->s, ptr+2, 1); + n=BE_16(ptr+1); + rm_read (p->s, ptr+3, n); + ptr[3+n]=0; + printf("%s\n",ptr+3); + return -1; + } + + if (*ptr == 'F') /* checking for server error */ + { + printf("input_pnm: server error.\n"); + return -1; + } + if (*ptr == 'i') + { + ptr+=2; + *need_response=1; + continue; + } + if (*ptr != 0x4f) break; + n=ptr[1]; + rm_read (p->s, ptr+2, n); + ptr+=(n+2); } /* the checksum of the next chunk is ignored here */ - rm_read (p->s, ptr+1, 1); - ptr++; + rm_read (p->s, ptr+2, 1); + ptr+=3; chunk_size=ptr-data; break; + case RMF_TAG: + case DATA_TAG: case PROP_TAG: case MDPR_TAG: case CONT_TAG: @@ -396,6 +406,7 @@ static unsigned int pnm_get_chunk(pnm_t *p, chunk_size = PREAMBLE_SIZE; break; } + return chunk_size; } @@ -491,6 +502,7 @@ static void pnm_send_response(pnm_t *p, const char *response) { memcpy(&p->buffer[3], response, size); rm_write (p->s, p->buffer, size+3); + } /* @@ -501,28 +513,36 @@ static void pnm_send_response(pnm_t *p, const char *response) { * return 0 on error. != 0 on success */ -static int pnm_get_headers(pnm_t *p) { +static int pnm_get_headers(pnm_t *p, int *need_response) { uint32_t chunk_type; uint8_t *ptr=p->header; uint8_t *prop_hdr=NULL; int chunk_size,size=0; + int nr; /* rmff_header_t *h; */ + *need_response=0; + while(1) { if (HEADER_SIZE-size<=0) { printf("input_pnm: header buffer overflow. exiting\n"); return 0; } - chunk_size=pnm_get_chunk(p,HEADER_SIZE-size,&chunk_type,ptr); + chunk_size=pnm_get_chunk(p,HEADER_SIZE-size,&chunk_type,ptr,&nr); if (chunk_size < 0) return 0; if (chunk_type == 0) break; if (chunk_type == PNA_TAG) { memcpy(ptr, rm_header, RM_HEADER_SIZE); chunk_size=RM_HEADER_SIZE; + *need_response=nr; } + if (chunk_type == DATA_TAG) + chunk_size=0; + if (chunk_type == RMF_TAG) + chunk_size=0; if (chunk_type == PROP_TAG) prop_hdr=ptr; size+=chunk_size; @@ -637,7 +657,7 @@ static int pnm_get_stream_chunk(pnm_t *p) { /* send a keepalive */ /* realplayer seems to do that every 43th package */ - if (!(p->packet%43)) + if ((p->packet%43) == 42) { rm_write(p->s,&keepalive,1); } @@ -760,6 +780,7 @@ pnm_t *pnm_connect(const char *mrl) { int pathbegin, hostend; pnm_t *p=malloc(sizeof(pnm_t)); int fd; + int need_response; if (strncmp(mrl,"pnm://",6)) { @@ -811,7 +832,7 @@ pnm_t *pnm_connect(const char *mrl) { p->s=fd; pnm_send_request(p,pnm_available_bandwidths[10]); - if (!pnm_get_headers(p)) { + if (!pnm_get_headers(p, &need_response)) { printf ("input_pnm: failed to set up stream\n"); free(p->path); free(p->host); @@ -819,7 +840,8 @@ pnm_t *pnm_connect(const char *mrl) { free(p); return NULL; } - pnm_send_response(p, pnm_response); + if (need_response) + pnm_send_response(p, pnm_response); p->ts_last[0]=0; p->ts_last[1]=0; |