Mercurial > mplayer.hg
annotate stream/pnm.c @ 32040:fb341240a2a8
Move stream_dump_type extern declaration to mplayer.h, where it belongs.
author | diego |
---|---|
date | Thu, 09 Sep 2010 17:10:18 +0000 |
parents | 64ba1daa147a |
children | 780f64c1ac7e |
rev | line source |
---|---|
8570 | 1 /* |
2 * Copyright (C) 2000-2002 the xine project | |
3 * | |
4 * This file is part of xine, a free video player. | |
5 * | |
6 * xine is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * xine is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
19614 | 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
8570 | 19 * |
20 * $Id$ | |
21 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
22 * pnm protocol implementation |
8570 | 23 * based upon code from joschka |
24 */ | |
25 | |
15614
a4a46131ee71
Change header order to avoid compile error because of STREAM_SEEK
reimar
parents:
15585
diff
changeset
|
26 #include "config.h" |
a4a46131ee71
Change header order to avoid compile error because of STREAM_SEEK
reimar
parents:
15585
diff
changeset
|
27 |
8570 | 28 #include <unistd.h> |
29 #include <stdio.h> | |
30 #include <assert.h> | |
31 #include <string.h> | |
32 #include <sys/stat.h> | |
33 #include <fcntl.h> | |
34 #include <errno.h> | |
35 #include <stdlib.h> | |
36 #include <sys/time.h> | |
8584 | 37 #include <inttypes.h> |
28402 | 38 #if !HAVE_WINSOCK2_H |
27472
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
39 #include <sys/socket.h> |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
40 //#include <netinet/in.h> |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
41 //#include <netdb.h> |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
42 #else |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
43 #include <winsock2.h> |
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
44 #endif |
10281 | 45 |
25697 | 46 #include "libavutil/intreadwrite.h" |
27472
c0b233cd30ca
Revert moving closesocket definition and network headers to network.h.
diego
parents:
27464
diff
changeset
|
47 |
15614
a4a46131ee71
Change header order to avoid compile error because of STREAM_SEEK
reimar
parents:
15585
diff
changeset
|
48 #include "stream.h" |
19312
ab8d6b6deb63
proper inclusion of demuxer.h (including libmpdemux in Makefile only was to make previous split easier)
ben
parents:
19271
diff
changeset
|
49 #include "libmpdemux/demuxer.h" |
15614
a4a46131ee71
Change header order to avoid compile error because of STREAM_SEEK
reimar
parents:
15585
diff
changeset
|
50 #include "help_mp.h" |
17092 | 51 #include "osdep/timer.h" |
27473
ae5da477539e
Move '#define closesocket close' preprocessor directive to a common place
diego
parents:
27472
diff
changeset
|
52 #include "network.h" |
8570 | 53 #include "pnm.h" |
19335
2a9d669e5ff6
isolated tcp socket code from network.c to a dedicated file
ben
parents:
19312
diff
changeset
|
54 #include "tcp.h" |
8570 | 55 //#include "libreal/rmff.h" |
56 | |
57 #define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \ | |
58 (((long)(unsigned char)(ch3) ) | \ | |
59 ( (long)(unsigned char)(ch2) << 8 ) | \ | |
60 ( (long)(unsigned char)(ch1) << 16 ) | \ | |
61 ( (long)(unsigned char)(ch0) << 24 ) ) | |
62 | |
63 | |
64 #define RMF_TAG FOURCC_TAG('.', 'R', 'M', 'F') | |
65 #define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P') | |
66 #define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R') | |
67 #define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T') | |
68 #define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A') | |
69 #define INDX_TAG FOURCC_TAG('I', 'N', 'D', 'X') | |
70 #define PNA_TAG FOURCC_TAG('P', 'N', 'A', 0 ) | |
71 | |
72 /* | |
73 #define LOG | |
74 */ | |
75 | |
8880 | 76 #define BUF_SIZE 4096 |
77 #define HEADER_SIZE 4096 | |
8570 | 78 |
79 struct pnm_s { | |
80 | |
81 int s; | |
82 | |
83 // char *host; | |
84 // int port; | |
85 char *path; | |
86 // char *url; | |
87 | |
88 char buffer[BUF_SIZE]; /* scratch buffer */ | |
89 | |
90 /* receive buffer */ | |
91 uint8_t recv[BUF_SIZE]; | |
92 int recv_size; | |
93 int recv_read; | |
94 | |
95 uint8_t header[HEADER_SIZE]; | |
96 int header_len; | |
97 int header_read; | |
98 unsigned int seq_num[4]; /* two streams with two indices */ | |
99 unsigned int seq_current[2]; /* seqs of last stream chunk read */ | |
100 uint32_t ts_current; /* timestamp of current chunk */ | |
101 uint32_t ts_last[2]; /* timestamps of last chunks */ | |
102 unsigned int packet; /* number of last recieved packet */ | |
103 }; | |
104 | |
105 /* sizes */ | |
106 #define PREAMBLE_SIZE 8 | |
107 #define CHECKSUM_SIZE 3 | |
108 | |
109 | |
110 /* header of rm files */ | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
111 static const unsigned char rm_header[]={ |
8570 | 112 0x2e, 0x52, 0x4d, 0x46, /* object_id ".RMF" */ |
113 0x00, 0x00, 0x00, 0x12, /* header_size 0x12 */ | |
114 0x00, 0x00, /* object_version 0x00 */ | |
115 0x00, 0x00, 0x00, 0x00, /* file_version 0x00 */ | |
116 0x00, 0x00, 0x00, 0x06 /* num_headers 0x06 */ | |
117 }; | |
118 | |
119 /* data chunk header */ | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
120 static const unsigned char pnm_data_header[]={ |
8570 | 121 'D','A','T','A', |
122 0,0,0,0, /* data chunk size */ | |
123 0,0, /* object version */ | |
124 0,0,0,0, /* num packets */ | |
125 0,0,0,0}; /* next data header */ | |
126 | |
127 /* pnm request chunk ids */ | |
128 | |
129 #define PNA_CLIENT_CAPS 0x03 | |
130 #define PNA_CLIENT_CHALLANGE 0x04 | |
131 #define PNA_BANDWIDTH 0x05 | |
132 #define PNA_GUID 0x13 | |
133 #define PNA_TIMESTAMP 0x17 | |
134 #define PNA_TWENTYFOUR 0x18 | |
135 | |
136 #define PNA_CLIENT_STRING 0x63 | |
137 #define PNA_PATH_REQUEST 0x52 | |
138 | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
139 static const unsigned char pnm_challenge[] = "0990f6b4508b51e801bd6da011ad7b56"; |
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
140 static const unsigned char pnm_timestamp[] = "[15/06/1999:22:22:49 00:00]"; |
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
141 static const unsigned char pnm_guid[] = "3eac2411-83d5-11d2-f3ea-d7c3a51aa8b0"; |
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
142 static const unsigned char pnm_response[] = "97715a899cbe41cee00dd434851535bf"; |
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
143 static const unsigned char client_string[] = "WinNT_9.0_6.0.6.45_plus32_MP60_en-US_686l"; |
8570 | 144 |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
145 static const unsigned char pnm_header[] = { |
8570 | 146 'P','N','A', |
147 0x00, 0x0a, | |
148 0x00, 0x14, | |
149 0x00, 0x02, | |
150 0x00, 0x01 }; | |
151 | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
152 static const unsigned char pnm_client_caps[] = { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
153 0x07, 0x8a, 'p','n','r','v', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
154 0, 0x90, 'p','n','r','v', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
155 0, 0x64, 'd','n','e','t', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
156 0, 0x46, 'p','n','r','v', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
157 0, 0x32, 'd','n','e','t', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
158 0, 0x2b, 'p','n','r','v', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
159 0, 0x28, 'd','n','e','t', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
160 0, 0x24, 'p','n','r','v', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
161 0, 0x19, 'd','n','e','t', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
162 0, 0x18, 'p','n','r','v', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
163 0, 0x14, 's','i','p','r', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
164 0, 0x14, 'd','n','e','t', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
165 0, 0x24, '2','8','_','8', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
166 0, 0x12, 'p','n','r','v', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
167 0, 0x0f, 'd','n','e','t', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
168 0, 0x0a, 's','i','p','r', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
169 0, 0x0a, 'd','n','e','t', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
170 0, 0x08, 's','i','p','r', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
171 0, 0x06, 's','i','p','r', |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
172 0, 0x12, 'l','p','c','J', |
8570 | 173 0, 0x07, '0','5','_','6' }; |
174 | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
175 static const uint32_t pnm_default_bandwidth=10485800; |
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
176 static const uint32_t pnm_available_bandwidths[]={14400,19200,28800,33600,34430,57600, |
8570 | 177 115200,262200,393216,524300,1544000,10485800}; |
178 | |
25695 | 179 static const unsigned char pnm_twentyfour[]={ |
8570 | 180 0xd5, 0x42, 0xa3, 0x1b, 0xef, 0x1f, 0x70, 0x24, |
181 0x85, 0x29, 0xb3, 0x8d, 0xba, 0x11, 0xf3, 0xd6 }; | |
182 | |
183 /* now other data follows. marked with 0x0000 at the beginning */ | |
25695 | 184 static const unsigned char after_chunks[]={ |
8570 | 185 0x00, 0x00, /* mark */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
186 |
8570 | 187 0x50, 0x84, /* seems to be fixated */ |
188 0x1f, 0x3a /* varies on each request (checksum ?)*/ | |
189 }; | |
190 | |
191 static void hexdump (char *buf, int length); | |
192 | |
193 static int rm_write(int s, const char *buf, int len) { | |
194 int total, timeout; | |
195 | |
196 total = 0; timeout = 30; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
197 while (total < len){ |
8570 | 198 int n; |
199 | |
10206
35e306346e59
Using recv/send instead read/write for proper MinGW support (it's a 4.2BSD standard). Patch by FloDt <flodt8@yahoo.de>
alex
parents:
8880
diff
changeset
|
200 n = send (s, &buf[total], len - total, 0); |
8570 | 201 |
202 if (n > 0) | |
203 total += n; | |
204 else if (n < 0) { | |
28402 | 205 #if !HAVE_WINSOCK2_H |
25700 | 206 if (timeout>0 && (errno == EAGAIN || errno == EINPROGRESS)) { |
10281 | 207 #else |
25700 | 208 if (timeout>0 && (errno == EAGAIN || WSAGetLastError() == WSAEINPROGRESS)) { |
10281 | 209 #endif |
16372
b313a38c69cb
replace sleep with usec_sleep, required for recent mingw versions, patch by Robert Swain <robert.swain at gmail.com>
faust3
parents:
15626
diff
changeset
|
210 usec_sleep (1000000); timeout--; |
8570 | 211 } else |
212 return -1; | |
213 } | |
214 } | |
215 | |
216 return total; | |
217 } | |
218 | |
219 static ssize_t rm_read(int fd, void *buf, size_t count) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
220 |
8570 | 221 ssize_t ret, total; |
222 | |
223 total = 0; | |
224 | |
225 while (total < count) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
226 |
8570 | 227 fd_set rset; |
228 struct timeval timeout; | |
229 | |
230 FD_ZERO (&rset); | |
231 FD_SET (fd, &rset); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
232 |
8570 | 233 timeout.tv_sec = 3; |
234 timeout.tv_usec = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
235 |
8570 | 236 if (select (fd+1, &rset, NULL, NULL, &timeout) <= 0) { |
237 return -1; | |
238 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
239 |
10206
35e306346e59
Using recv/send instead read/write for proper MinGW support (it's a 4.2BSD standard). Patch by FloDt <flodt8@yahoo.de>
alex
parents:
8880
diff
changeset
|
240 ret=recv (fd, ((uint8_t*)buf)+total, count-total, 0); |
8570 | 241 |
242 if (ret<=0) { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
243 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: read error.\n"); |
8570 | 244 return ret; |
245 } else | |
246 total += ret; | |
247 } | |
248 | |
249 return total; | |
250 } | |
251 | |
252 /* | |
253 * debugging utilities | |
254 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
255 |
8570 | 256 static void hexdump (char *buf, int length) { |
257 | |
258 int i; | |
259 | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
260 mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: ascii>"); |
8570 | 261 for (i = 0; i < length; i++) { |
262 unsigned char c = buf[i]; | |
263 | |
25700 | 264 if (c >= 32 && c <= 128) |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
265 mp_msg(MSGT_OPEN, MSGL_INFO, "%c", c); |
8570 | 266 else |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
267 mp_msg(MSGT_OPEN, MSGL_INFO, "."); |
8570 | 268 } |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
269 mp_msg(MSGT_OPEN, MSGL_INFO, "\n"); |
8570 | 270 |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
271 mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: hexdump> "); |
8570 | 272 for (i = 0; i < length; i++) { |
273 unsigned char c = buf[i]; | |
274 | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
275 mp_msg(MSGT_OPEN, MSGL_INFO, "%02x", c); |
8570 | 276 |
277 if ((i % 16) == 15) | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
278 mp_msg(MSGT_OPEN, MSGL_INFO, "\npnm: "); |
8570 | 279 |
280 if ((i % 2) == 1) | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
281 mp_msg(MSGT_OPEN, MSGL_INFO, " "); |
8570 | 282 |
283 } | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
284 mp_msg(MSGT_OPEN, MSGL_INFO, "\n"); |
8570 | 285 } |
286 | |
287 /* | |
288 * pnm_get_chunk gets a chunk from stream | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
289 * and returns number of bytes read |
8570 | 290 */ |
291 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
292 static int pnm_get_chunk(pnm_t *p, |
8570 | 293 unsigned int max, |
294 unsigned int *chunk_type, | |
295 char *data, int *need_response) { | |
296 | |
297 unsigned int chunk_size; | |
14164 | 298 unsigned int n; |
8570 | 299 char *ptr; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
300 |
14164 | 301 if (max < PREAMBLE_SIZE) |
302 return -1; | |
303 | |
8570 | 304 /* get first PREAMBLE_SIZE bytes and ignore checksum */ |
305 rm_read (p->s, data, CHECKSUM_SIZE); | |
306 if (data[0] == 0x72) | |
307 rm_read (p->s, data, PREAMBLE_SIZE); | |
308 else | |
309 rm_read (p->s, data+CHECKSUM_SIZE, PREAMBLE_SIZE-CHECKSUM_SIZE); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
310 |
14164 | 311 max -= PREAMBLE_SIZE; |
312 | |
25697 | 313 *chunk_type = AV_RB32(data); |
314 chunk_size = AV_RB32(data+4); | |
8570 | 315 |
316 switch (*chunk_type) { | |
317 case PNA_TAG: | |
318 *need_response=0; | |
319 ptr=data+PREAMBLE_SIZE; | |
14164 | 320 if (max < 1) |
321 return -1; | |
8570 | 322 rm_read (p->s, ptr++, 1); |
14164 | 323 max -= 1; |
8570 | 324 |
325 while(1) { | |
326 /* expecting following chunk format: 0x4f <chunk size> <data...> */ | |
327 | |
14164 | 328 if (max < 2) |
329 return -1; | |
8570 | 330 rm_read (p->s, ptr, 2); |
14164 | 331 max -= 2; |
8570 | 332 if (*ptr == 'X') /* checking for server message */ |
333 { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
334 mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: got a message from server:\n"); |
14164 | 335 if (max < 1) |
336 return -1; | |
8570 | 337 rm_read (p->s, ptr+2, 1); |
14164 | 338 max = -1; |
25697 | 339 n=AV_RB16(ptr+1); |
14164 | 340 if (max < n) |
341 return -1; | |
8570 | 342 rm_read (p->s, ptr+3, n); |
14164 | 343 max -= n; |
8570 | 344 ptr[3+n]=0; |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
345 mp_msg(MSGT_OPEN, MSGL_WARN, "%s\n",ptr+3); |
8570 | 346 return -1; |
347 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
348 |
8570 | 349 if (*ptr == 'F') /* checking for server error */ |
350 { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
351 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: server error.\n"); |
8570 | 352 return -1; |
353 } | |
354 if (*ptr == 'i') | |
355 { | |
356 ptr+=2; | |
357 *need_response=1; | |
358 continue; | |
359 } | |
360 if (*ptr != 0x4f) break; | |
361 n=ptr[1]; | |
14164 | 362 if (max < n) |
363 return -1; | |
8570 | 364 rm_read (p->s, ptr+2, n); |
14164 | 365 max -= n; |
8570 | 366 ptr+=(n+2); |
367 } | |
368 /* the checksum of the next chunk is ignored here */ | |
14164 | 369 if (max < 1) |
370 return -1; | |
8570 | 371 rm_read (p->s, ptr+2, 1); |
372 ptr+=3; | |
373 chunk_size=ptr-data; | |
374 break; | |
375 case RMF_TAG: | |
376 case DATA_TAG: | |
377 case PROP_TAG: | |
378 case MDPR_TAG: | |
379 case CONT_TAG: | |
14164 | 380 if (chunk_size > max || chunk_size < PREAMBLE_SIZE) { |
31834
64ba1daa147a
various spelling fixes, found by the Debian QA tool 'lintian'
siretart
parents:
31427
diff
changeset
|
381 mp_msg(MSGT_OPEN, MSGL_ERR, "error: max chunk size exceeded (max was 0x%04x)\n", max); |
14164 | 382 #ifdef LOG |
8570 | 383 n=rm_read (p->s, &data[PREAMBLE_SIZE], 0x100 - PREAMBLE_SIZE); |
384 hexdump(data,n+PREAMBLE_SIZE); | |
14164 | 385 #endif |
8570 | 386 return -1; |
387 } | |
388 rm_read (p->s, &data[PREAMBLE_SIZE], chunk_size-PREAMBLE_SIZE); | |
389 break; | |
390 default: | |
391 *chunk_type = 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
392 chunk_size = PREAMBLE_SIZE; |
8570 | 393 break; |
394 } | |
395 | |
396 return chunk_size; | |
397 } | |
398 | |
399 /* | |
400 * writes a chunk to a buffer, returns number of bytes written | |
401 */ | |
402 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
403 static int pnm_write_chunk(uint16_t chunk_id, uint16_t length, |
8570 | 404 const char *chunk, char *data) { |
405 | |
25701 | 406 AV_WB16(&data[0], chunk_id); |
407 AV_WB16(&data[2], length); | |
8570 | 408 memcpy(&data[4],chunk,length); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
409 |
8570 | 410 return length+4; |
411 } | |
412 | |
413 /* | |
414 * constructs a request and sends it | |
415 */ | |
416 | |
417 static void pnm_send_request(pnm_t *p, uint32_t bandwidth) { | |
418 | |
419 uint16_t i16; | |
25696 | 420 int c=sizeof(pnm_header); |
8570 | 421 char fixme[]={0,1}; |
422 | |
25696 | 423 memcpy(p->buffer,pnm_header,sizeof(pnm_header)); |
8570 | 424 c+=pnm_write_chunk(PNA_CLIENT_CHALLANGE,strlen(pnm_challenge), |
425 pnm_challenge,&p->buffer[c]); | |
25696 | 426 c+=pnm_write_chunk(PNA_CLIENT_CAPS,sizeof(pnm_client_caps), |
8570 | 427 pnm_client_caps,&p->buffer[c]); |
428 c+=pnm_write_chunk(0x0a,0,NULL,&p->buffer[c]); | |
429 c+=pnm_write_chunk(0x0c,0,NULL,&p->buffer[c]); | |
430 c+=pnm_write_chunk(0x0d,0,NULL,&p->buffer[c]); | |
431 c+=pnm_write_chunk(0x16,2,fixme,&p->buffer[c]); | |
432 c+=pnm_write_chunk(PNA_TIMESTAMP,strlen(pnm_timestamp), | |
433 pnm_timestamp,&p->buffer[c]); | |
434 c+=pnm_write_chunk(PNA_BANDWIDTH,4, | |
435 (const char *)&pnm_default_bandwidth,&p->buffer[c]); | |
436 c+=pnm_write_chunk(0x08,0,NULL,&p->buffer[c]); | |
437 c+=pnm_write_chunk(0x0e,0,NULL,&p->buffer[c]); | |
438 c+=pnm_write_chunk(0x0f,0,NULL,&p->buffer[c]); | |
439 c+=pnm_write_chunk(0x11,0,NULL,&p->buffer[c]); | |
440 c+=pnm_write_chunk(0x10,0,NULL,&p->buffer[c]); | |
441 c+=pnm_write_chunk(0x15,0,NULL,&p->buffer[c]); | |
442 c+=pnm_write_chunk(0x12,0,NULL,&p->buffer[c]); | |
443 c+=pnm_write_chunk(PNA_GUID,strlen(pnm_guid), | |
444 pnm_guid,&p->buffer[c]); | |
25696 | 445 c+=pnm_write_chunk(PNA_TWENTYFOUR,sizeof(pnm_twentyfour), |
8570 | 446 pnm_twentyfour,&p->buffer[c]); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
447 |
8570 | 448 /* data after chunks */ |
25696 | 449 memcpy(&p->buffer[c],after_chunks,sizeof(after_chunks)); |
450 c+=sizeof(after_chunks); | |
8570 | 451 |
452 /* client id string */ | |
453 p->buffer[c]=PNA_CLIENT_STRING; | |
25698 | 454 AV_WB16(&p->buffer[c+1], strlen(client_string)-1); /* don't know why do we have -1 here */ |
8570 | 455 memcpy(&p->buffer[c+1],&i16,2); |
456 memcpy(&p->buffer[c+3],client_string,strlen(client_string)+1); | |
457 c=c+3+strlen(client_string)+1; | |
458 | |
459 /* file path */ | |
460 p->buffer[c]=0; | |
461 p->buffer[c+1]=PNA_PATH_REQUEST; | |
25698 | 462 AV_WB16(&p->buffer[c+2], strlen(p->path)); |
8570 | 463 memcpy(&p->buffer[c+4],p->path,strlen(p->path)); |
464 c=c+4+strlen(p->path); | |
465 | |
466 /* some trailing bytes */ | |
467 p->buffer[c]='y'; | |
468 p->buffer[c+1]='B'; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
469 |
8570 | 470 rm_write(p->s,p->buffer,c+2); |
471 } | |
472 | |
473 /* | |
474 * pnm_send_response sends a response of a challenge | |
475 */ | |
476 | |
477 static void pnm_send_response(pnm_t *p, const char *response) { | |
478 | |
479 int size=strlen(response); | |
480 | |
481 p->buffer[0]=0x23; | |
482 p->buffer[1]=0; | |
483 p->buffer[2]=(unsigned char) size; | |
484 | |
485 memcpy(&p->buffer[3], response, size); | |
486 | |
487 rm_write (p->s, p->buffer, size+3); | |
488 | |
489 } | |
490 | |
491 /* | |
492 * get headers and challenge and fix headers | |
493 * write headers to p->header | |
494 * write challenge to p->buffer | |
495 * | |
496 * return 0 on error. != 0 on success | |
497 */ | |
498 | |
499 static int pnm_get_headers(pnm_t *p, int *need_response) { | |
500 | |
501 uint32_t chunk_type; | |
502 uint8_t *ptr=p->header; | |
503 uint8_t *prop_hdr=NULL; | |
504 int chunk_size,size=0; | |
505 int nr; | |
506 /* rmff_header_t *h; */ | |
507 | |
508 *need_response=0; | |
509 | |
510 while(1) { | |
511 if (HEADER_SIZE-size<=0) | |
512 { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
513 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: header buffer overflow. exiting\n"); |
8570 | 514 return 0; |
515 } | |
516 chunk_size=pnm_get_chunk(p,HEADER_SIZE-size,&chunk_type,ptr,&nr); | |
517 if (chunk_size < 0) return 0; | |
518 if (chunk_type == 0) break; | |
519 if (chunk_type == PNA_TAG) | |
520 { | |
25696 | 521 memcpy(ptr, rm_header, sizeof(rm_header)); |
522 chunk_size=sizeof(rm_header); | |
8570 | 523 *need_response=nr; |
524 } | |
525 if (chunk_type == DATA_TAG) | |
526 chunk_size=0; | |
527 if (chunk_type == RMF_TAG) | |
528 chunk_size=0; | |
529 if (chunk_type == PROP_TAG) | |
530 prop_hdr=ptr; | |
531 size+=chunk_size; | |
532 ptr+=chunk_size; | |
533 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
534 |
8852 | 535 if (!prop_hdr) { |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
536 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: error while parsing headers.\n"); |
8852 | 537 return 0; |
538 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
539 |
8570 | 540 /* set data offset */ |
25701 | 541 AV_WB32(&prop_hdr[42], size - 1); |
8570 | 542 |
543 /* read challenge */ | |
544 memcpy (p->buffer, ptr, PREAMBLE_SIZE); | |
545 rm_read (p->s, &p->buffer[PREAMBLE_SIZE], 64); | |
546 | |
547 /* now write a data header */ | |
25696 | 548 memcpy(ptr, pnm_data_header, sizeof(pnm_data_header)); |
549 size+=sizeof(pnm_data_header); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
550 /* |
8570 | 551 h=rmff_scan_header(p->header); |
552 rmff_fix_header(h); | |
553 p->header_len=rmff_get_header_size(h); | |
554 rmff_dump_header(h, p->header, HEADER_SIZE); | |
555 */ | |
556 p->header_len=size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
557 |
8570 | 558 return 1; |
559 } | |
560 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
561 /* |
8570 | 562 * determine correct stream number by looking at indices |
563 */ | |
564 | |
565 static int pnm_calc_stream(pnm_t *p) { | |
566 | |
567 char str0=0,str1=0; | |
568 | |
569 /* looking at the first index to | |
570 * find possible stream types | |
571 */ | |
572 if (p->seq_current[0]==p->seq_num[0]) str0=1; | |
573 if (p->seq_current[0]==p->seq_num[2]) str1=1; | |
574 | |
575 switch (str0+str1) { | |
576 case 1: /* one is possible, good. */ | |
577 if (str0) | |
578 { | |
579 p->seq_num[0]++; | |
580 p->seq_num[1]=p->seq_current[1]+1; | |
581 return 0; | |
582 } else | |
583 { | |
584 p->seq_num[2]++; | |
585 p->seq_num[3]=p->seq_current[1]+1; | |
586 return 1; | |
587 } | |
588 break; | |
589 case 0: | |
590 case 2: /* both types or none possible, not so good */ | |
591 /* try to figure out by second index */ | |
25700 | 592 if ( p->seq_current[1] == p->seq_num[1] |
593 && p->seq_current[1] != p->seq_num[3]) | |
8570 | 594 { |
595 /* ok, only stream0 matches */ | |
596 p->seq_num[0]=p->seq_current[0]+1; | |
597 p->seq_num[1]++; | |
598 return 0; | |
599 } | |
25700 | 600 if ( p->seq_current[1] == p->seq_num[3] |
601 && p->seq_current[1] != p->seq_num[1]) | |
8570 | 602 { |
603 /* ok, only stream1 matches */ | |
604 p->seq_num[2]=p->seq_current[0]+1; | |
605 p->seq_num[3]++; | |
606 return 1; | |
607 } | |
608 /* wow, both streams match, or not. */ | |
609 /* now we try to decide by timestamps */ | |
610 if (p->ts_current < p->ts_last[1]) | |
611 return 0; | |
612 if (p->ts_current < p->ts_last[0]) | |
613 return 1; | |
614 /* does not help, we guess type 0 */ | |
615 #ifdef LOG | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
616 mp_msg(MSGT_OPEN, MSGL_INFO, "guessing stream# 0\n"); |
8570 | 617 #endif |
618 p->seq_num[0]=p->seq_current[0]+1; | |
619 p->seq_num[1]=p->seq_current[1]+1; | |
620 return 0; | |
621 break; | |
622 } | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
623 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: wow, something very nasty happened in pnm_calc_stream\n"); |
8570 | 624 return 2; |
625 } | |
626 | |
627 /* | |
628 * gets a stream chunk and writes it to a recieve buffer | |
629 */ | |
630 | |
631 static int pnm_get_stream_chunk(pnm_t *p) { | |
632 | |
633 int n; | |
634 char keepalive='!'; | |
635 unsigned int fof1, fof2, stream; | |
636 | |
637 /* send a keepalive */ | |
638 /* realplayer seems to do that every 43th package */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
639 if (p->packet%43 == 42) |
8570 | 640 rm_write(p->s,&keepalive,1); |
641 | |
642 /* data chunks begin with: 'Z' <o> <o> <i1> 'Z' <i2> | |
643 * where <o> is the offset to next stream chunk, | |
644 * <i1> is a 16 bit index | |
645 * <i2> is a 8 bit index which counts from 0x10 to somewhere | |
646 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
647 |
8570 | 648 n = rm_read (p->s, p->buffer, 8); |
15077
a893e0bfa9d6
"Fix" for pnm EOF detection (stop on read errors)
rtognimp
parents:
15076
diff
changeset
|
649 if (n<0) return -1; |
8570 | 650 if (n<8) return 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
651 |
8570 | 652 /* skip 8 bytes if 0x62 is read */ |
653 if (p->buffer[0] == 0x62) | |
654 { | |
655 n = rm_read (p->s, p->buffer, 8); | |
656 if (n<8) return 0; | |
657 #ifdef LOG | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
658 mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: had to seek 8 bytes on 0x62\n"); |
8570 | 659 #endif |
660 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
661 |
8570 | 662 /* a server message */ |
663 if (p->buffer[0] == 'X') | |
664 { | |
25697 | 665 int size=AV_RB16(&p->buffer[1]); |
8570 | 666 |
667 rm_read (p->s, &p->buffer[8], size-5); | |
668 p->buffer[size+3]=0; | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
669 mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: got message from server while reading stream:\n%s\n", &p->buffer[3]); |
15076
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
670 return -1; |
8570 | 671 } |
672 if (p->buffer[0] == 'F') | |
673 { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
674 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: server error.\n"); |
15076
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
675 return -1; |
8570 | 676 } |
677 | |
678 /* skip bytewise to next chunk. | |
11000 | 679 * seems, that we don't need that, if we send enough |
8570 | 680 * keepalives |
681 */ | |
682 n=0; | |
683 while (p->buffer[0] != 0x5a) { | |
684 int i; | |
25700 | 685 for (i=1; i<8; i++) |
8570 | 686 p->buffer[i-1]=p->buffer[i]; |
687 rm_read (p->s, &p->buffer[7], 1); | |
688 n++; | |
689 } | |
690 | |
691 #ifdef LOG | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
692 if (n) mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: had to seek %i bytes to next chunk\n", n); |
8570 | 693 #endif |
694 | |
695 /* check for 'Z's */ | |
25700 | 696 if (p->buffer[0] != 0x5a || p->buffer[7] != 0x5a) |
8570 | 697 { |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
698 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: bad boundaries\n"); |
8570 | 699 hexdump(p->buffer, 8); |
700 return 0; | |
701 } | |
702 | |
703 /* check offsets */ | |
25697 | 704 fof1=AV_RB16(&p->buffer[1]); |
705 fof2=AV_RB16(&p->buffer[3]); | |
8570 | 706 if (fof1 != fof2) |
707 { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
708 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: frame offsets are different: 0x%04x 0x%04x\n",fof1,fof2); |
8570 | 709 return 0; |
710 } | |
711 | |
712 /* get first index */ | |
25697 | 713 p->seq_current[0]=AV_RB16(&p->buffer[5]); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
714 |
8570 | 715 /* now read the rest of stream chunk */ |
716 n = rm_read (p->s, &p->recv[5], fof1-5); | |
25700 | 717 if (n<fof1-5) return 0; |
8570 | 718 |
719 /* get second index */ | |
720 p->seq_current[1]=p->recv[5]; | |
721 | |
722 /* get timestamp */ | |
25697 | 723 p->ts_current=AV_RB32(&p->recv[6]); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
724 |
8570 | 725 /* get stream number */ |
726 stream=pnm_calc_stream(p); | |
727 | |
728 /* saving timestamp */ | |
729 p->ts_last[stream]=p->ts_current; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
730 |
8570 | 731 /* constructing a data packet header */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
732 |
8570 | 733 p->recv[0]=0; /* object version */ |
734 p->recv[1]=0; | |
735 | |
25698 | 736 AV_WB16(&p->recv[2], fof2); /* length */ |
8570 | 737 |
738 p->recv[4]=0; /* stream number */ | |
739 p->recv[5]=stream; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
740 |
25699 | 741 p->recv[10] &= 0xfe; /* streambox seems to do that... */ |
8570 | 742 |
743 p->packet++; | |
744 | |
745 p->recv_size=fof1; | |
746 | |
747 return fof1; | |
748 } | |
749 | |
750 // pnm_t *pnm_connect(const char *mrl) { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
751 static pnm_t *pnm_connect(int fd, char *path) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
752 |
8570 | 753 pnm_t *p=malloc(sizeof(pnm_t)); |
8852 | 754 int need_response=0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
755 |
8570 | 756 p->path=strdup(path); |
757 p->s=fd; | |
758 | |
759 pnm_send_request(p,pnm_available_bandwidths[10]); | |
760 if (!pnm_get_headers(p, &need_response)) { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
761 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: failed to set up stream\n"); |
8570 | 762 free(p->path); |
763 free(p); | |
764 return NULL; | |
765 } | |
766 if (need_response) | |
767 pnm_send_response(p, pnm_response); | |
768 p->ts_last[0]=0; | |
769 p->ts_last[1]=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
770 |
8570 | 771 /* copy header to recv */ |
772 | |
773 memcpy(p->recv, p->header, p->header_len); | |
774 p->recv_size = p->header_len; | |
775 p->recv_read = 0; | |
776 | |
777 return p; | |
778 } | |
779 | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
780 static int pnm_read (pnm_t *this, char *data, int len) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
781 |
8570 | 782 int to_copy=len; |
783 char *dest=data; | |
784 char *source=this->recv + this->recv_read; | |
785 int fill=this->recv_size - this->recv_read; | |
15076
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
786 int retval; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
787 |
8570 | 788 if (len < 0) return 0; |
789 while (to_copy > fill) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
790 |
8570 | 791 memcpy(dest, source, fill); |
792 to_copy -= fill; | |
793 dest += fill; | |
794 this->recv_read=0; | |
795 | |
15076
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
796 if ((retval = pnm_get_stream_chunk (this)) <= 0) { |
8570 | 797 #ifdef LOG |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
798 mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: %d of %d bytes provided\n", len-to_copy, len); |
8570 | 799 #endif |
15076
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
800 if (retval < 0) |
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
801 return retval; |
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
802 else |
8570 | 803 return len-to_copy; |
804 } | |
805 source = this->recv; | |
806 fill = this->recv_size - this->recv_read; | |
807 } | |
808 | |
809 memcpy(dest, source, to_copy); | |
810 this->recv_read += to_copy; | |
811 | |
812 #ifdef LOG | |
15585 | 813 mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: %d bytes provided\n", len); |
8570 | 814 #endif |
815 | |
816 return len; | |
817 } | |
818 | |
15585 | 819 static int pnm_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) { |
820 return pnm_read(stream_ctrl->data, buffer, size); | |
821 } | |
822 | |
823 static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { | |
824 int fd; | |
825 pnm_t *pnm; | |
826 URL_t *url; | |
827 | |
828 mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_PNM, URL: %s\n", stream->url); | |
829 stream->streaming_ctrl = streaming_ctrl_new(); | |
25700 | 830 if(stream->streaming_ctrl==NULL) |
15585 | 831 return STREAM_ERROR; |
25700 | 832 |
15585 | 833 stream->streaming_ctrl->bandwidth = network_bandwidth; |
834 url = url_new(stream->url); | |
835 stream->streaming_ctrl->url = check4proxies(url); | |
836 //url_free(url); | |
837 | |
838 fd = connect2Server( stream->streaming_ctrl->url->hostname, | |
839 stream->streaming_ctrl->url->port ? stream->streaming_ctrl->url->port : 7070,1 ); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
840 |
15585 | 841 if(fd<0) |
842 goto fail; | |
843 | |
844 pnm = pnm_connect(fd,stream->streaming_ctrl->url->file); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
845 if(!pnm) |
15585 | 846 goto fail; |
847 stream->type = STREAMTYPE_STREAM; | |
848 stream->fd=fd; | |
849 stream->streaming_ctrl->data=pnm; | |
850 stream->streaming_ctrl->streaming_read = pnm_streaming_read; | |
851 //stream->streaming_ctrl->streaming_seek = nop_streaming_seek; | |
852 stream->streaming_ctrl->prebuffer_size = 8*1024; // 8 KBytes | |
853 stream->streaming_ctrl->buffering = 1; | |
854 stream->streaming_ctrl->status = streaming_playing_e; | |
855 *file_format = DEMUXER_TYPE_REAL; | |
856 fixup_network_stream_cache(stream); | |
857 return STREAM_OK; | |
858 | |
859 fail: | |
860 streaming_ctrl_free(stream->streaming_ctrl); | |
861 stream->streaming_ctrl = NULL; | |
24257 | 862 return STREAM_UNSUPPORTED; |
15585 | 863 } |
864 | |
865 | |
25211 | 866 const stream_info_t stream_info_pnm = { |
15585 | 867 "RealNetworks pnm", |
868 "pnm", | |
869 "Arpi, xine team", | |
870 "ported from xine", | |
871 open_s, | |
872 {"pnm", NULL}, //pnm as fallback | |
873 NULL, | |
874 0 // Urls are an option string | |
875 }; |