summaryrefslogtreecommitdiff
path: root/src/input/pnm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/pnm.c')
-rw-r--r--src/input/pnm.c219
1 files changed, 84 insertions, 135 deletions
diff --git a/src/input/pnm.c b/src/input/pnm.c
index 8341e23e6..419f32ccc 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.1 2002/11/23 00:04:32 guenter Exp $
+ * $Id: pnm.c,v 1.2 2002/12/12 22:08:14 holstsn Exp $
*
* pnm protocol implementation by joschka
*/
@@ -29,7 +29,6 @@
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
@@ -37,8 +36,11 @@
#include <time.h>
#include "pnm.h"
+#include "libreal/rmff.h"
+/*
#define LOG
+*/
#define BUF_SIZE 1024
#define HEADER_SIZE 1024
@@ -64,6 +66,8 @@ struct pnm_s {
int header_read;
unsigned int seq_num[4]; /* two streams with two indices */
unsigned int seq_current[2]; /* seqs of last stream chunk read */
+ uint32_t ts_current; /* timestamp of current chunk */
+ uint32_t ts_last[2]; /* timestamps of last chunks */
unsigned int packet; /* number of last recieved packet */
};
@@ -71,12 +75,6 @@ struct pnm_s {
* utility macros
*/
-#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \
- ( (long)(unsigned char)(ch3) | \
- ( (long)(unsigned char)(ch2) << 8 ) | \
- ( (long)(unsigned char)(ch1) << 16 ) | \
- ( (long)(unsigned char)(ch0) << 24 ) )
-
#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
(((uint8_t*)(x))[1] << 16) | \
@@ -86,24 +84,6 @@ struct pnm_s {
/* D means direct (no pointer) */
#define BE_16D(x) ((x & 0xff00) >> 8)|((x & 0x00ff) << 8)
-/*
- * constants
- */
-
-#define RMF_TAG FOURCC_TAG('.', 'R', 'M', 'F')
-#define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P')
-#define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R')
-#define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T')
-#define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A')
-#define INDX_TAG FOURCC_TAG('I', 'N', 'D', 'X')
-#define PNA_TAG FOURCC_TAG('P', 'N', 'A', 0 )
-
-/* prop flags */
-#define PN_SAVE_ENABLED 0x01
-#define PN_PERFECT_PLAY_ENABLED 0x02
-#define PN_LIVE_BROADCAST 0x04
-
-
/* sizes */
#define PREAMBLE_SIZE 8
#define CHECKSUM_SIZE 3
@@ -182,24 +162,6 @@ const uint32_t pnm_default_bandwidth=10485800;
const uint32_t pnm_available_bandwidths[]={14400,19200,28800,33600,34430,57600,
115200,262200,393216,524300,1544000,10485800};
-/* some unknown chunks */
-#define PNM_AFTER_CLIENT_CAPS_SIZE 18
-const unsigned char pnm_after_client_caps[]={
- 0x00, 0x0a, 0x00, 0x00,
- 0x00, 0x0c, 0x00, 0x00,
- 0x00, 0x0d, 0x00, 0x00,
- 0x00, 0x16, 0x00, 0x02, 0x00, 0x01 };
-
-#define PNM_AFTER_BANDWIDTH_SIZE 28
-const unsigned char pnm_after_bandwidth[]={
- 0x00, 0x08, 0x00, 0x00,
- 0x00, 0x0e, 0x00, 0x00,
- 0x00, 0x0f, 0x00, 0x00,
- 0x00, 0x11, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x15, 0x00, 0x00,
- 0x00, 0x12, 0x00, 0x00 };
-
#define PNM_TWENTYFOUR_SIZE 16
unsigned char pnm_twentyfour[]={
0xd5, 0x42, 0xa3, 0x1b, 0xef, 0x1f, 0x70, 0x24,
@@ -302,7 +264,7 @@ static ssize_t rm_read(int fd, void *buf, size_t count) {
FD_ZERO (&rset);
FD_SET (fd, &rset);
- timeout.tv_sec = 30;
+ timeout.tv_sec = 3;
timeout.tv_usec = 0;
if (select (fd+1, &rset, NULL, NULL, &timeout) <= 0) {
@@ -357,23 +319,6 @@ static void hexdump (char *buf, int length) {
}
/*
- * basic stream reading
- */
-
-static char *pnm_get_string(unsigned char *data) {
-
- char *string;
- int length;
-
- length=BE_16(data);
- string=malloc(sizeof(char)*(length+1));
- memcpy(string,&data[2],length);
- string[length]=0;
-
- return string;
-}
-
-/*
* pnm_get_chunk gets a chunk from stream
* and returns number of bytes read
*/
@@ -411,6 +356,12 @@ static unsigned int pnm_get_chunk(pnm_t *p,
printf("%s\n",&data[PREAMBLE_SIZE+0x04]);
exit(0);
}
+ if (data[PREAMBLE_SIZE+0x01] == 'F')
+ {
+ printf("pnm: server error.\n");
+ exit(0);
+ }
+
/* expecting following chunk format: 0x4f <chunk size> <data...> */
rm_read (p->s, ptr, 2);
while (*ptr == 0x4f) {
@@ -467,7 +418,6 @@ static int pnm_write_chunk(uint16_t chunk_id, uint16_t length,
static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {
uint16_t i16;
- uint32_t bw;
int c=PNM_HEADER_SIZE;
char fixme[]={0,1};
@@ -502,7 +452,7 @@ static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {
/* client id string */
p->buffer[c]=PNA_CLIENT_STRING;
- i16=BE_16D(strlen(client_string)-1); /* dont know why do we have -1 here */
+ i16=BE_16D((strlen(client_string)-1)); /* dont know why do we have -1 here */
memcpy(&p->buffer[c+1],&i16,2);
memcpy(&p->buffer[c+3],client_string,strlen(client_string)+1);
c=c+3+strlen(client_string)+1;
@@ -551,7 +501,8 @@ static void pnm_get_headers(pnm_t *p) {
uint8_t *ptr=p->header;
uint8_t *prop_hdr=NULL;
int chunk_size,size=0;
-
+/* rmff_header_t *h; */
+
while(1) {
if (HEADER_SIZE-size<=0)
{
@@ -572,13 +523,16 @@ static void pnm_get_headers(pnm_t *p) {
}
/* set pre-buffer to a low number */
- prop_hdr[36]=0x01;
- prop_hdr[37]=0xd6;
+ /* prop_hdr[36]=0x01;
+ prop_hdr[37]=0xd6; */
+ /* set data offset */
+ size--;
prop_hdr[42]=(size>>24)%0xff;
prop_hdr[43]=(size>>16)%0xff;
prop_hdr[44]=(size>>8)%0xff;
prop_hdr[45]=(size)%0xff;
+ size++;
/* read challenge */
memcpy (p->buffer, ptr, PREAMBLE_SIZE);
@@ -587,7 +541,12 @@ static void pnm_get_headers(pnm_t *p) {
/* now write a data header */
memcpy(ptr, pnm_data_header, PNM_DATA_HEADER_SIZE);
size+=PNM_DATA_HEADER_SIZE;
-
+/*
+ h=rmff_scan_header(p->header);
+ rmff_fix_header(h);
+ p->header_len=rmff_get_header_size(h);
+ rmff_dump_header(h, p->header, HEADER_SIZE);
+*/
p->header_len=size;
}
@@ -620,7 +579,7 @@ static int pnm_calc_stream(pnm_t *p) {
}
break;
case 0:
- case 2: /* both types or none possible, not so good */
+ case 2: /* both types or none possible, not so good */
/* try to figure out by second index */
if ( (p->seq_current[1] == p->seq_num[1])
&&(p->seq_current[1] != p->seq_num[3]))
@@ -638,8 +597,14 @@ static int pnm_calc_stream(pnm_t *p) {
p->seq_num[3]++;
return 1;
}
- /* wow, both streams match, or not. */
- /* in this case, we guess type 0 */
+ /* wow, both streams match, or not. */
+ /* now we try to decide by timestamps */
+ if (p->ts_current < p->ts_last[1])
+ return 0;
+ if (p->ts_current < p->ts_last[0])
+ return 1;
+ /* does not help, we guess type 0 */
+ printf("guessing stream# 0\n");
p->seq_num[0]=p->seq_current[0]+1;
p->seq_num[1]=p->seq_current[1]+1;
return 0;
@@ -680,6 +645,9 @@ static int pnm_get_stream_chunk(pnm_t *p) {
{
n = rm_read (p->s, p->buffer, 8);
if (n<8) return 0;
+#ifdef LOG
+ printf("pnm: had to seek 8 bytes on 0x62\n");
+#endif
}
/* a server message */
@@ -692,6 +660,11 @@ static int pnm_get_stream_chunk(pnm_t *p) {
printf("pnm: got message from server:\n%s\n", &p->buffer[3]);
exit(0);
}
+ if (p->buffer[0] == 'F')
+ {
+ printf("pnm: server error.\n");
+ exit(0);
+ }
/* skip bytewise to next chunk.
* seems, that we dont need that, if we send enough
@@ -706,8 +679,9 @@ static int pnm_get_stream_chunk(pnm_t *p) {
rm_read (p->s, &p->buffer[7], 1);
n++;
}
+
if (n) printf("pnm: had to seek %i bytes to next chunk\n", n);
-
+
/* check for 'Z's */
if ((p->buffer[0] != 0x5a)||(p->buffer[7] != 0x5a))
{
@@ -735,8 +709,14 @@ static int pnm_get_stream_chunk(pnm_t *p) {
/* get second index */
p->seq_current[1]=p->recv[5];
+ /* get timestamp */
+ p->ts_current=BE_32(&p->recv[6]);
+
/* get stream number */
stream=pnm_calc_stream(p);
+
+ /* saving timestamp */
+ p->ts_last[stream]=p->ts_current;
/* constructing a data packet header */
@@ -843,80 +823,51 @@ pnm_t *pnm_connect(const char *mrl) {
pnm_send_request(p,pnm_available_bandwidths[10]);
pnm_get_headers(p);
pnm_send_response(p, pnm_response);
+ p->ts_last[0]=0;
+ p->ts_last[1]=0;
+
+ /* copy header to recv */
+
+ memcpy(p->recv, p->header, p->header_len);
+ p->recv_size = p->header_len;
+ p->recv_read = 0;
return p;
}
int pnm_read (pnm_t *this, char *data, int len) {
- int total;
-
- total = 0;
-
- while (total < len) {
+
+ int to_copy=len;
+ char *dest=data;
+ char *source=this->recv + this->recv_read;
+ int fill=this->recv_size - this->recv_read;
+
+ if (len < 0) return 0;
+ while (to_copy > fill) {
+
+ memcpy(dest, source, fill);
+ to_copy -= fill;
+ dest += fill;
+ this->recv_read=0;
+ if (!pnm_get_stream_chunk (this)) {
#ifdef LOG
- printf ("libpnm: read, got %d / %d bytes\n", total, len);
+ printf ("libpnm: %d of %d bytes provided\n", len-to_copy, len);
#endif
-
- if (this->header_read < this->header_len) {
- int n, bytes_left ;
-
- printf ("libpnm: reading from header (%d<%d)\n",
- this->header_read, this->header_len);
-
- bytes_left = this->header_len - this->header_read ;
-
- if ((len-total) < bytes_left)
- n = len-total;
- else
- n = bytes_left;
-
- memcpy (&data[total], &this->header[this->header_read], n);
-
- printf ("libpnm: copied %d bytes\n", n);
-
- this->header_read += n;
- total += n;
- } else {
-
- int n, bytes_left ;
-
- printf ("libpnm: reading from chunk (%d>=%d)\n",
- this->header_read, this->header_len);
-
- bytes_left = this->recv_size - this->recv_read;
-
- while (!bytes_left) {
-
- this->recv_read = 0;
-
- if (!pnm_get_stream_chunk (this)) {
- printf ("libpnm: pnm_get_stream_chunk failed\n");
- return total;
- }
- bytes_left = this->recv_size - this->recv_read;
- }
-
-
- if ((len-total)<bytes_left)
- n = len-total;
- else
- n = bytes_left;
-
- memcpy (&data[total], &this->recv[this->recv_read], n);
-
- printf ("libpnm: copied %d bytes\n", n);
-
- this->recv_read += n;
- total += n;
+ return len-to_copy;
}
+ source = this->recv;
+ fill = this->recv_size - this->recv_read;
}
- printf ("libpnm: total=%d\n", total);
+ memcpy(dest, source, to_copy);
+ this->recv_read += to_copy;
- hexdump (data, total);
+#ifdef LOG
+ printf ("libpnm: %d bytes provided\n", len);
+#endif
- return total;
+ return len;
}
int pnm_peek_header (pnm_t *this, char *data) {
@@ -934,5 +885,3 @@ void pnm_close(pnm_t *p) {
free(p);
}
-
-