Mercurial > mplayer.hg
annotate stream/pnm.c @ 35005:b1a1dcae9760
Replace MESA YCBCR support by the Apple variant.
This adds hardware support for yuy2 and uyvy color formats when running
on OSX.
In addition add some hacks to make it fast (at least on PPC Mac Mini running
OSX 10.5), ca. 20% faster than -vo corevideo.
The MESA YCBCR variant never worked properly and has become even more broken
and thus been disabled in most maintained drivers and thus is really
a dead-end.
author | reimar |
---|---|
date | Sat, 18 Aug 2012 15:54:34 +0000 |
parents | a93891202051 |
children | 7505733df2b4 |
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" |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
33346
diff
changeset
|
47 #include "mp_msg.h" |
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 | |
25696 | 419 int c=sizeof(pnm_header); |
8570 | 420 char fixme[]={0,1}; |
421 | |
25696 | 422 memcpy(p->buffer,pnm_header,sizeof(pnm_header)); |
8570 | 423 c+=pnm_write_chunk(PNA_CLIENT_CHALLANGE,strlen(pnm_challenge), |
424 pnm_challenge,&p->buffer[c]); | |
25696 | 425 c+=pnm_write_chunk(PNA_CLIENT_CAPS,sizeof(pnm_client_caps), |
8570 | 426 pnm_client_caps,&p->buffer[c]); |
427 c+=pnm_write_chunk(0x0a,0,NULL,&p->buffer[c]); | |
428 c+=pnm_write_chunk(0x0c,0,NULL,&p->buffer[c]); | |
429 c+=pnm_write_chunk(0x0d,0,NULL,&p->buffer[c]); | |
430 c+=pnm_write_chunk(0x16,2,fixme,&p->buffer[c]); | |
431 c+=pnm_write_chunk(PNA_TIMESTAMP,strlen(pnm_timestamp), | |
432 pnm_timestamp,&p->buffer[c]); | |
433 c+=pnm_write_chunk(PNA_BANDWIDTH,4, | |
434 (const char *)&pnm_default_bandwidth,&p->buffer[c]); | |
435 c+=pnm_write_chunk(0x08,0,NULL,&p->buffer[c]); | |
436 c+=pnm_write_chunk(0x0e,0,NULL,&p->buffer[c]); | |
437 c+=pnm_write_chunk(0x0f,0,NULL,&p->buffer[c]); | |
438 c+=pnm_write_chunk(0x11,0,NULL,&p->buffer[c]); | |
439 c+=pnm_write_chunk(0x10,0,NULL,&p->buffer[c]); | |
440 c+=pnm_write_chunk(0x15,0,NULL,&p->buffer[c]); | |
441 c+=pnm_write_chunk(0x12,0,NULL,&p->buffer[c]); | |
442 c+=pnm_write_chunk(PNA_GUID,strlen(pnm_guid), | |
443 pnm_guid,&p->buffer[c]); | |
25696 | 444 c+=pnm_write_chunk(PNA_TWENTYFOUR,sizeof(pnm_twentyfour), |
8570 | 445 pnm_twentyfour,&p->buffer[c]); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
446 |
8570 | 447 /* data after chunks */ |
25696 | 448 memcpy(&p->buffer[c],after_chunks,sizeof(after_chunks)); |
449 c+=sizeof(after_chunks); | |
8570 | 450 |
451 /* client id string */ | |
452 p->buffer[c]=PNA_CLIENT_STRING; | |
25698 | 453 AV_WB16(&p->buffer[c+1], strlen(client_string)-1); /* don't know why do we have -1 here */ |
8570 | 454 memcpy(&p->buffer[c+3],client_string,strlen(client_string)+1); |
455 c=c+3+strlen(client_string)+1; | |
456 | |
457 /* file path */ | |
458 p->buffer[c]=0; | |
459 p->buffer[c+1]=PNA_PATH_REQUEST; | |
25698 | 460 AV_WB16(&p->buffer[c+2], strlen(p->path)); |
8570 | 461 memcpy(&p->buffer[c+4],p->path,strlen(p->path)); |
462 c=c+4+strlen(p->path); | |
463 | |
464 /* some trailing bytes */ | |
465 p->buffer[c]='y'; | |
466 p->buffer[c+1]='B'; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
467 |
8570 | 468 rm_write(p->s,p->buffer,c+2); |
469 } | |
470 | |
471 /* | |
472 * pnm_send_response sends a response of a challenge | |
473 */ | |
474 | |
475 static void pnm_send_response(pnm_t *p, const char *response) { | |
476 | |
477 int size=strlen(response); | |
478 | |
479 p->buffer[0]=0x23; | |
480 p->buffer[1]=0; | |
481 p->buffer[2]=(unsigned char) size; | |
482 | |
483 memcpy(&p->buffer[3], response, size); | |
484 | |
485 rm_write (p->s, p->buffer, size+3); | |
486 | |
487 } | |
488 | |
489 /* | |
490 * get headers and challenge and fix headers | |
491 * write headers to p->header | |
492 * write challenge to p->buffer | |
493 * | |
494 * return 0 on error. != 0 on success | |
495 */ | |
496 | |
497 static int pnm_get_headers(pnm_t *p, int *need_response) { | |
498 | |
499 uint32_t chunk_type; | |
500 uint8_t *ptr=p->header; | |
501 uint8_t *prop_hdr=NULL; | |
502 int chunk_size,size=0; | |
503 int nr; | |
504 /* rmff_header_t *h; */ | |
505 | |
506 *need_response=0; | |
507 | |
508 while(1) { | |
509 if (HEADER_SIZE-size<=0) | |
510 { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
511 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: header buffer overflow. exiting\n"); |
8570 | 512 return 0; |
513 } | |
514 chunk_size=pnm_get_chunk(p,HEADER_SIZE-size,&chunk_type,ptr,&nr); | |
515 if (chunk_size < 0) return 0; | |
516 if (chunk_type == 0) break; | |
517 if (chunk_type == PNA_TAG) | |
518 { | |
25696 | 519 memcpy(ptr, rm_header, sizeof(rm_header)); |
520 chunk_size=sizeof(rm_header); | |
8570 | 521 *need_response=nr; |
522 } | |
523 if (chunk_type == DATA_TAG) | |
524 chunk_size=0; | |
525 if (chunk_type == RMF_TAG) | |
526 chunk_size=0; | |
527 if (chunk_type == PROP_TAG) | |
528 prop_hdr=ptr; | |
529 size+=chunk_size; | |
530 ptr+=chunk_size; | |
531 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
532 |
8852 | 533 if (!prop_hdr) { |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
534 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: error while parsing headers.\n"); |
8852 | 535 return 0; |
536 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
537 |
8570 | 538 /* set data offset */ |
25701 | 539 AV_WB32(&prop_hdr[42], size - 1); |
8570 | 540 |
541 /* read challenge */ | |
542 memcpy (p->buffer, ptr, PREAMBLE_SIZE); | |
543 rm_read (p->s, &p->buffer[PREAMBLE_SIZE], 64); | |
544 | |
545 /* now write a data header */ | |
25696 | 546 memcpy(ptr, pnm_data_header, sizeof(pnm_data_header)); |
547 size+=sizeof(pnm_data_header); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
548 /* |
8570 | 549 h=rmff_scan_header(p->header); |
550 rmff_fix_header(h); | |
551 p->header_len=rmff_get_header_size(h); | |
552 rmff_dump_header(h, p->header, HEADER_SIZE); | |
553 */ | |
554 p->header_len=size; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
555 |
8570 | 556 return 1; |
557 } | |
558 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
559 /* |
8570 | 560 * determine correct stream number by looking at indices |
561 */ | |
562 | |
563 static int pnm_calc_stream(pnm_t *p) { | |
564 | |
565 char str0=0,str1=0; | |
566 | |
567 /* looking at the first index to | |
568 * find possible stream types | |
569 */ | |
570 if (p->seq_current[0]==p->seq_num[0]) str0=1; | |
571 if (p->seq_current[0]==p->seq_num[2]) str1=1; | |
572 | |
573 switch (str0+str1) { | |
574 case 1: /* one is possible, good. */ | |
575 if (str0) | |
576 { | |
577 p->seq_num[0]++; | |
578 p->seq_num[1]=p->seq_current[1]+1; | |
579 return 0; | |
580 } else | |
581 { | |
582 p->seq_num[2]++; | |
583 p->seq_num[3]=p->seq_current[1]+1; | |
584 return 1; | |
585 } | |
586 break; | |
587 case 0: | |
588 case 2: /* both types or none possible, not so good */ | |
589 /* try to figure out by second index */ | |
25700 | 590 if ( p->seq_current[1] == p->seq_num[1] |
591 && p->seq_current[1] != p->seq_num[3]) | |
8570 | 592 { |
593 /* ok, only stream0 matches */ | |
594 p->seq_num[0]=p->seq_current[0]+1; | |
595 p->seq_num[1]++; | |
596 return 0; | |
597 } | |
25700 | 598 if ( p->seq_current[1] == p->seq_num[3] |
599 && p->seq_current[1] != p->seq_num[1]) | |
8570 | 600 { |
601 /* ok, only stream1 matches */ | |
602 p->seq_num[2]=p->seq_current[0]+1; | |
603 p->seq_num[3]++; | |
604 return 1; | |
605 } | |
606 /* wow, both streams match, or not. */ | |
607 /* now we try to decide by timestamps */ | |
608 if (p->ts_current < p->ts_last[1]) | |
609 return 0; | |
610 if (p->ts_current < p->ts_last[0]) | |
611 return 1; | |
612 /* does not help, we guess type 0 */ | |
613 #ifdef LOG | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
614 mp_msg(MSGT_OPEN, MSGL_INFO, "guessing stream# 0\n"); |
8570 | 615 #endif |
616 p->seq_num[0]=p->seq_current[0]+1; | |
617 p->seq_num[1]=p->seq_current[1]+1; | |
618 return 0; | |
619 break; | |
620 } | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
621 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: wow, something very nasty happened in pnm_calc_stream\n"); |
8570 | 622 return 2; |
623 } | |
624 | |
625 /* | |
626 * gets a stream chunk and writes it to a recieve buffer | |
627 */ | |
628 | |
629 static int pnm_get_stream_chunk(pnm_t *p) { | |
630 | |
631 int n; | |
632 char keepalive='!'; | |
633 unsigned int fof1, fof2, stream; | |
634 | |
635 /* send a keepalive */ | |
636 /* realplayer seems to do that every 43th package */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
637 if (p->packet%43 == 42) |
8570 | 638 rm_write(p->s,&keepalive,1); |
639 | |
640 /* data chunks begin with: 'Z' <o> <o> <i1> 'Z' <i2> | |
641 * where <o> is the offset to next stream chunk, | |
642 * <i1> is a 16 bit index | |
643 * <i2> is a 8 bit index which counts from 0x10 to somewhere | |
644 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
645 |
8570 | 646 n = rm_read (p->s, p->buffer, 8); |
15077
a893e0bfa9d6
"Fix" for pnm EOF detection (stop on read errors)
rtognimp
parents:
15076
diff
changeset
|
647 if (n<0) return -1; |
8570 | 648 if (n<8) return 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
649 |
8570 | 650 /* skip 8 bytes if 0x62 is read */ |
651 if (p->buffer[0] == 0x62) | |
652 { | |
653 n = rm_read (p->s, p->buffer, 8); | |
654 if (n<8) return 0; | |
655 #ifdef LOG | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
656 mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: had to seek 8 bytes on 0x62\n"); |
8570 | 657 #endif |
658 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
659 |
8570 | 660 /* a server message */ |
661 if (p->buffer[0] == 'X') | |
662 { | |
25697 | 663 int size=AV_RB16(&p->buffer[1]); |
8570 | 664 |
665 rm_read (p->s, &p->buffer[8], size-5); | |
666 p->buffer[size+3]=0; | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
667 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
|
668 return -1; |
8570 | 669 } |
670 if (p->buffer[0] == 'F') | |
671 { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
672 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
|
673 return -1; |
8570 | 674 } |
675 | |
676 /* skip bytewise to next chunk. | |
11000 | 677 * seems, that we don't need that, if we send enough |
8570 | 678 * keepalives |
679 */ | |
680 n=0; | |
681 while (p->buffer[0] != 0x5a) { | |
682 int i; | |
25700 | 683 for (i=1; i<8; i++) |
8570 | 684 p->buffer[i-1]=p->buffer[i]; |
685 rm_read (p->s, &p->buffer[7], 1); | |
686 n++; | |
687 } | |
688 | |
689 #ifdef LOG | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
690 if (n) mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: had to seek %i bytes to next chunk\n", n); |
8570 | 691 #endif |
692 | |
693 /* check for 'Z's */ | |
25700 | 694 if (p->buffer[0] != 0x5a || p->buffer[7] != 0x5a) |
8570 | 695 { |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
696 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: bad boundaries\n"); |
8570 | 697 hexdump(p->buffer, 8); |
698 return 0; | |
699 } | |
700 | |
701 /* check offsets */ | |
25697 | 702 fof1=AV_RB16(&p->buffer[1]); |
703 fof2=AV_RB16(&p->buffer[3]); | |
8570 | 704 if (fof1 != fof2) |
705 { | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
706 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: frame offsets are different: 0x%04x 0x%04x\n",fof1,fof2); |
8570 | 707 return 0; |
708 } | |
709 | |
710 /* get first index */ | |
25697 | 711 p->seq_current[0]=AV_RB16(&p->buffer[5]); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
712 |
8570 | 713 /* now read the rest of stream chunk */ |
714 n = rm_read (p->s, &p->recv[5], fof1-5); | |
25700 | 715 if (n<fof1-5) return 0; |
8570 | 716 |
717 /* get second index */ | |
718 p->seq_current[1]=p->recv[5]; | |
719 | |
720 /* get timestamp */ | |
25697 | 721 p->ts_current=AV_RB32(&p->recv[6]); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
722 |
8570 | 723 /* get stream number */ |
724 stream=pnm_calc_stream(p); | |
725 | |
726 /* saving timestamp */ | |
727 p->ts_last[stream]=p->ts_current; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
728 |
8570 | 729 /* constructing a data packet header */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
730 |
8570 | 731 p->recv[0]=0; /* object version */ |
732 p->recv[1]=0; | |
733 | |
25698 | 734 AV_WB16(&p->recv[2], fof2); /* length */ |
8570 | 735 |
736 p->recv[4]=0; /* stream number */ | |
737 p->recv[5]=stream; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
738 |
25699 | 739 p->recv[10] &= 0xfe; /* streambox seems to do that... */ |
8570 | 740 |
741 p->packet++; | |
742 | |
743 p->recv_size=fof1; | |
744 | |
745 return fof1; | |
746 } | |
747 | |
748 // 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
|
749 static pnm_t *pnm_connect(int fd, char *path) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
750 |
8570 | 751 pnm_t *p=malloc(sizeof(pnm_t)); |
8852 | 752 int need_response=0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
753 |
8570 | 754 p->path=strdup(path); |
755 p->s=fd; | |
756 | |
757 pnm_send_request(p,pnm_available_bandwidths[10]); | |
758 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
|
759 mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: failed to set up stream\n"); |
8570 | 760 free(p->path); |
761 free(p); | |
762 return NULL; | |
763 } | |
764 if (need_response) | |
765 pnm_send_response(p, pnm_response); | |
766 p->ts_last[0]=0; | |
767 p->ts_last[1]=0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
768 |
8570 | 769 /* copy header to recv */ |
770 | |
771 memcpy(p->recv, p->header, p->header_len); | |
772 p->recv_size = p->header_len; | |
773 p->recv_read = 0; | |
774 | |
775 return p; | |
776 } | |
777 | |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
778 static int pnm_read (pnm_t *this, char *data, int len) { |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
779 |
8570 | 780 int to_copy=len; |
781 char *dest=data; | |
782 char *source=this->recv + this->recv_read; | |
783 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
|
784 int retval; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
785 |
8570 | 786 if (len < 0) return 0; |
787 while (to_copy > fill) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
788 |
8570 | 789 memcpy(dest, source, fill); |
790 to_copy -= fill; | |
791 dest += fill; | |
792 this->recv_read=0; | |
793 | |
15076
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
794 if ((retval = pnm_get_stream_chunk (this)) <= 0) { |
8570 | 795 #ifdef LOG |
15626
941b1a71351f
printf converted to mp_msg; made static many unnecessarily global symbols
nicodvb
parents:
15614
diff
changeset
|
796 mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: %d of %d bytes provided\n", len-to_copy, len); |
8570 | 797 #endif |
15076
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
798 if (retval < 0) |
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
799 return retval; |
1a02a23202c2
Stop streaming if we got a server error or message on pnm streaming.
rtognimp
parents:
14164
diff
changeset
|
800 else |
8570 | 801 return len-to_copy; |
802 } | |
803 source = this->recv; | |
804 fill = this->recv_size - this->recv_read; | |
805 } | |
806 | |
807 memcpy(dest, source, to_copy); | |
808 this->recv_read += to_copy; | |
809 | |
810 #ifdef LOG | |
15585 | 811 mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: %d bytes provided\n", len); |
8570 | 812 #endif |
813 | |
814 return len; | |
815 } | |
816 | |
15585 | 817 static int pnm_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) { |
818 return pnm_read(stream_ctrl->data, buffer, size); | |
819 } | |
820 | |
821 static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { | |
822 int fd; | |
823 pnm_t *pnm; | |
824 URL_t *url; | |
825 | |
826 mp_msg(MSGT_OPEN, MSGL_INFO, "STREAM_PNM, URL: %s\n", stream->url); | |
827 stream->streaming_ctrl = streaming_ctrl_new(); | |
25700 | 828 if(stream->streaming_ctrl==NULL) |
15585 | 829 return STREAM_ERROR; |
25700 | 830 |
15585 | 831 stream->streaming_ctrl->bandwidth = network_bandwidth; |
832 url = url_new(stream->url); | |
833 stream->streaming_ctrl->url = check4proxies(url); | |
834 //url_free(url); | |
835 | |
836 fd = connect2Server( stream->streaming_ctrl->url->hostname, | |
837 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
|
838 |
15585 | 839 if(fd<0) |
840 goto fail; | |
841 | |
842 pnm = pnm_connect(fd,stream->streaming_ctrl->url->file); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28402
diff
changeset
|
843 if(!pnm) |
15585 | 844 goto fail; |
845 stream->type = STREAMTYPE_STREAM; | |
846 stream->fd=fd; | |
847 stream->streaming_ctrl->data=pnm; | |
848 stream->streaming_ctrl->streaming_read = pnm_streaming_read; | |
849 //stream->streaming_ctrl->streaming_seek = nop_streaming_seek; | |
850 stream->streaming_ctrl->prebuffer_size = 8*1024; // 8 KBytes | |
851 stream->streaming_ctrl->buffering = 1; | |
852 stream->streaming_ctrl->status = streaming_playing_e; | |
853 *file_format = DEMUXER_TYPE_REAL; | |
854 fixup_network_stream_cache(stream); | |
855 return STREAM_OK; | |
856 | |
857 fail: | |
858 streaming_ctrl_free(stream->streaming_ctrl); | |
859 stream->streaming_ctrl = NULL; | |
24257 | 860 return STREAM_UNSUPPORTED; |
15585 | 861 } |
862 | |
863 | |
25211 | 864 const stream_info_t stream_info_pnm = { |
15585 | 865 "RealNetworks pnm", |
866 "pnm", | |
867 "Arpi, xine team", | |
868 "ported from xine", | |
869 open_s, | |
870 {"pnm", NULL}, //pnm as fallback | |
871 NULL, | |
872 0 // Urls are an option string | |
873 }; |