Mercurial > mplayer.hg
annotate vobsub.c @ 6200:e604be87613d
codecs.conf versioning - patch by Joey Parrish <joey@yunamusic.com>
author | arpi |
---|---|
date | Sun, 26 May 2002 22:39:38 +0000 |
parents | 141a082e6da6 |
children | f8551f89dd48 |
rev | line source |
---|---|
4080 | 1 /* |
2 * Some code freely inspired from VobSub <URL:http://vobsub.edensrising.com>, | |
3 * with kind permission from Gabest <gabest@freemail.hu> | |
4 */ | |
5 /* #define HAVE_GETLINE */ | |
6 #include <ctype.h> | |
7 #include <errno.h> | |
8 #include <stdio.h> | |
9 #include <stdlib.h> | |
10 #include <string.h> | |
11 #include <fcntl.h> | |
12 #include <unistd.h> | |
13 #include <sys/stat.h> | |
14 #include <sys/types.h> | |
15 | |
16 #include "config.h" | |
17 | |
18 #include "stream.h" | |
19 #include "vobsub.h" | |
6110 | 20 #include "libvo/video_out.h" |
4080 | 21 #include "spudec.h" |
22 #include "mp_msg.h" | |
23 | |
24 extern int vobsub_id; | |
25 | |
26 extern int verbose; | |
27 | |
28 #ifdef HAVE_GETLINE | |
29 extern ssize_t getline(char **, size_t *, FILE *); | |
30 #else | |
31 /* FIXME This should go into a general purpose library or even a | |
32 separate file. */ | |
33 static ssize_t | |
34 getline (char **lineptr, size_t *n, FILE *stream) | |
35 { | |
36 size_t res = 0; | |
37 int c; | |
38 if (*lineptr == NULL) { | |
39 *lineptr = malloc(4096); | |
40 if (*lineptr) | |
41 *n = 4096; | |
42 } | |
43 else if (*n == 0) { | |
44 char *tmp = realloc(*lineptr, 4096); | |
45 if (tmp) { | |
46 *lineptr = tmp; | |
47 *n = 4096; | |
48 } | |
49 } | |
50 if (*lineptr == NULL || *n == 0) | |
51 return -1; | |
52 | |
53 for (c = fgetc(stream); c != EOF; c = fgetc(stream)) { | |
54 if (res + 1 >= *n) { | |
55 char *tmp = realloc(*lineptr, *n * 2); | |
56 if (tmp == NULL) | |
57 return -1; | |
58 *lineptr = tmp; | |
59 *n *= 2; | |
60 } | |
61 (*lineptr)[res++] = c; | |
62 if (c == '\n') { | |
63 (*lineptr)[res] = 0; | |
64 return res; | |
65 } | |
66 } | |
67 if (res == 0) | |
68 return -1; | |
69 (*lineptr)[res] = 0; | |
70 return res; | |
71 } | |
72 #endif | |
73 | |
74 /********************************************************************** | |
75 * MPEG parsing | |
76 **********************************************************************/ | |
77 | |
78 typedef struct { | |
79 stream_t *stream; | |
80 unsigned int pts; | |
81 int aid; | |
82 unsigned char *packet; | |
83 unsigned int packet_reserve; | |
84 unsigned int packet_size; | |
85 } mpeg_t; | |
86 | |
87 static mpeg_t * | |
88 mpeg_open(const char *filename) | |
89 { | |
90 mpeg_t *res = malloc(sizeof(mpeg_t)); | |
91 int err = res == NULL; | |
92 if (!err) { | |
93 int fd; | |
94 res->pts = 0; | |
95 res->aid = -1; | |
96 res->packet = NULL; | |
97 res->packet_size = 0; | |
98 res->packet_reserve = 0; | |
99 fd = open(filename, O_RDONLY); | |
100 err = fd < 0; | |
101 if (!err) { | |
102 res->stream = new_stream(fd, STREAMTYPE_FILE); | |
103 err = res->stream == NULL; | |
104 if (err) | |
105 close(fd); | |
106 } | |
107 if (err) | |
108 free(res); | |
109 } | |
110 return err ? NULL : res; | |
111 } | |
112 | |
113 static void | |
114 mpeg_free(mpeg_t *mpeg) | |
115 { | |
116 int fd; | |
117 if (mpeg->packet) | |
118 free(mpeg->packet); | |
119 fd = mpeg->stream->fd; | |
120 free_stream(mpeg->stream); | |
121 close(fd); | |
122 free(mpeg); | |
123 } | |
124 | |
125 static int | |
126 mpeg_eof(mpeg_t *mpeg) | |
127 { | |
128 return stream_eof(mpeg->stream); | |
129 } | |
130 | |
131 static off_t | |
132 mpeg_tell(mpeg_t *mpeg) | |
133 { | |
134 return stream_tell(mpeg->stream); | |
135 } | |
136 | |
137 static int | |
138 mpeg_run(mpeg_t *mpeg) | |
139 { | |
140 unsigned int len, idx, version; | |
141 int c; | |
142 /* Goto start of a packet, it starts with 0x000001?? */ | |
143 const unsigned char wanted[] = { 0, 0, 1 }; | |
144 unsigned char buf[5]; | |
145 | |
146 mpeg->aid = -1; | |
147 mpeg->packet_size = 0; | |
148 if (stream_read(mpeg->stream, buf, 4) != 4) | |
149 return -1; | |
150 while (memcmp(buf, wanted, sizeof(wanted)) != 0) { | |
151 c = stream_read_char(mpeg->stream); | |
152 if (c < 0) | |
153 return -1; | |
154 memmove(buf, buf + 1, 3); | |
155 buf[3] = c; | |
156 } | |
157 switch (buf[3]) { | |
158 case 0xb9: /* System End Code */ | |
159 break; | |
160 case 0xba: /* Packet start code */ | |
161 c = stream_read_char(mpeg->stream); | |
162 if (c < 0) | |
163 return -1; | |
164 if ((c & 0xc0) == 0x40) | |
165 version = 4; | |
166 else if ((c & 0xf0) == 0x20) | |
167 version = 2; | |
168 else { | |
6110 | 169 mp_msg(MSGT_VOBSUB,MSGL_ERR, "Unsupported MPEG version: 0x%02x", c); |
4080 | 170 return -1; |
171 } | |
172 if (version == 4) { | |
173 if (!stream_skip(mpeg->stream, 9)) | |
174 return -1; | |
175 } | |
176 else if (version == 2) { | |
177 if (!stream_skip(mpeg->stream, 7)) | |
178 return -1; | |
179 } | |
180 else | |
181 abort(); | |
182 break; | |
183 case 0xbd: /* packet */ | |
184 if (stream_read(mpeg->stream, buf, 2) != 2) | |
185 return -1; | |
186 len = buf[0] << 8 | buf[1]; | |
187 idx = mpeg_tell(mpeg); | |
188 c = stream_read_char(mpeg->stream); | |
189 if (c < 0) | |
190 return -1; | |
191 if ((c & 0xC0) == 0x40) { /* skip STD scale & size */ | |
192 if (stream_read_char(mpeg->stream) < 0) | |
193 return -1; | |
194 c = stream_read_char(mpeg->stream); | |
195 if (c < 0) | |
196 return -1; | |
197 } | |
198 if ((c & 0xf0) == 0x20) { /* System-1 stream timestamp */ | |
199 /* Do we need this? */ | |
200 abort(); | |
201 } | |
202 else if ((c & 0xf0) == 0x30) { | |
203 /* Do we need this? */ | |
204 abort(); | |
205 } | |
206 else if ((c & 0xc0) == 0x80) { /* System-2 (.VOB) stream */ | |
207 unsigned int pts_flags, hdrlen, dataidx; | |
208 c = stream_read_char(mpeg->stream); | |
209 if (c < 0) | |
210 return -1; | |
211 pts_flags = c; | |
212 c = stream_read_char(mpeg->stream); | |
213 if (c < 0) | |
214 return -1; | |
215 hdrlen = c; | |
216 dataidx = mpeg_tell(mpeg) + hdrlen; | |
217 if (dataidx > idx + len) { | |
6110 | 218 mp_msg(MSGT_VOBSUB,MSGL_ERR, "Invalid header length: %d (total length: %d, idx: %d, dataidx: %d)\n", |
4080 | 219 hdrlen, len, idx, dataidx); |
220 return -1; | |
221 } | |
222 if ((pts_flags & 0xc0) == 0x80) { | |
223 if (stream_read(mpeg->stream, buf, 5) != 5) | |
224 return -1; | |
225 if (!(((buf[0] & 0xf0) == 0x20) && (buf[0] & 1) && (buf[2] & 1) && (buf[4] & 1))) { | |
6110 | 226 mp_msg(MSGT_VOBSUB,MSGL_ERR, "vobsub PTS error: 0x%02x %02x%02x %02x%02x \n", |
4080 | 227 buf[0], buf[1], buf[2], buf[3], buf[4]); |
228 mpeg->pts = 0; | |
229 } | |
230 else | |
231 mpeg->pts = ((buf[0] & 0x0e) << 29 | buf[1] << 22 | (buf[2] & 0xfe) << 14 | |
232 | buf[3] << 7 | (buf[4] >> 1)) / 900; | |
233 } | |
234 else /* if ((pts_flags & 0xc0) == 0xc0) */ { | |
235 /* what's this? */ | |
236 /* abort(); */ | |
237 } | |
238 stream_seek(mpeg->stream, dataidx); | |
239 mpeg->aid = stream_read_char(mpeg->stream); | |
240 if (mpeg->aid < 0) { | |
6110 | 241 mp_msg(MSGT_VOBSUB,MSGL_ERR, "Bogus aid %d\n", mpeg->aid); |
4080 | 242 return -1; |
243 } | |
244 mpeg->packet_size = len - ((unsigned int) mpeg_tell(mpeg) - idx); | |
245 if (mpeg->packet_reserve < mpeg->packet_size) { | |
246 if (mpeg->packet) | |
247 free(mpeg->packet); | |
248 mpeg->packet = malloc(mpeg->packet_size); | |
249 if (mpeg->packet) | |
250 mpeg->packet_reserve = mpeg->packet_size; | |
251 } | |
252 if (mpeg->packet == NULL) { | |
6110 | 253 mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure"); |
4080 | 254 mpeg->packet_reserve = 0; |
255 mpeg->packet_size = 0; | |
256 return -1; | |
257 } | |
6110 | 258 if ((unsigned int)stream_read(mpeg->stream, mpeg->packet, mpeg->packet_size) != mpeg->packet_size) { |
259 mp_msg(MSGT_VOBSUB,MSGL_ERR,"stream_read failure"); | |
4080 | 260 mpeg->packet_size = 0; |
261 return -1; | |
262 } | |
263 idx = len; | |
264 } | |
265 break; | |
266 case 0xbe: /* Padding */ | |
267 if (stream_read(mpeg->stream, buf, 2) != 2) | |
268 return -1; | |
269 len = buf[0] << 8 | buf[1]; | |
270 if (len > 0 && !stream_skip(mpeg->stream, len)) | |
271 return -1; | |
272 break; | |
273 default: | |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
274 if (0xc0 <= buf[3] && buf[3] < 0xf0) { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
275 /* MPEG audio or video */ |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
276 if (stream_read(mpeg->stream, buf, 2) != 2) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
277 return -1; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
278 len = buf[0] << 8 | buf[1]; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
279 if (len > 0 && !stream_skip(mpeg->stream, len)) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
280 return -1; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
281 |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
282 } |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
283 else { |
6110 | 284 mp_msg(MSGT_VOBSUB,MSGL_ERR,"unknown header 0x%02X%02X%02X%02X\n", |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
285 buf[0], buf[1], buf[2], buf[3]); |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
286 return -1; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
287 } |
4080 | 288 } |
289 return 0; | |
290 } | |
291 | |
292 /********************************************************************** | |
293 * Packet queue | |
294 **********************************************************************/ | |
295 | |
296 typedef struct { | |
297 unsigned int pts100; | |
298 off_t filepos; | |
299 unsigned int size; | |
300 unsigned char *data; | |
301 } packet_t; | |
302 | |
303 typedef struct { | |
304 char *id; | |
305 packet_t *packets; | |
306 unsigned int packets_reserve; | |
307 unsigned int packets_size; | |
308 unsigned int current_index; | |
309 } packet_queue_t; | |
310 | |
311 static void | |
312 packet_construct(packet_t *pkt) | |
313 { | |
314 pkt->pts100 = 0; | |
315 pkt->filepos = 0; | |
316 pkt->size = 0; | |
317 pkt->data = NULL; | |
318 } | |
319 | |
320 static void | |
321 packet_destroy(packet_t *pkt) | |
322 { | |
323 if (pkt->data) | |
324 free(pkt->data); | |
325 } | |
326 | |
327 static void | |
328 packet_queue_construct(packet_queue_t *queue) | |
329 { | |
330 queue->id = NULL; | |
331 queue->packets = NULL; | |
332 queue->packets_reserve = 0; | |
333 queue->packets_size = 0; | |
334 queue->current_index = 0; | |
335 } | |
336 | |
337 static void | |
338 packet_queue_destroy(packet_queue_t *queue) | |
339 { | |
340 if (queue->packets) { | |
341 while (queue->packets_size--) | |
342 packet_destroy(queue->packets + queue->packets_size); | |
343 free(queue->packets); | |
344 } | |
345 return; | |
346 } | |
347 | |
348 /* Make sure there is enough room for needed_size packets in the | |
349 packet queue. */ | |
350 static int | |
351 packet_queue_ensure(packet_queue_t *queue, unsigned int needed_size) | |
352 { | |
353 if (queue->packets_reserve < needed_size) { | |
354 if (queue->packets) { | |
355 packet_t *tmp = realloc(queue->packets, 2 * queue->packets_reserve * sizeof(packet_t)); | |
356 if (tmp == NULL) { | |
6110 | 357 mp_msg(MSGT_VOBSUB,MSGL_FATAL,"realloc failure"); |
4080 | 358 return -1; |
359 } | |
360 queue->packets = tmp; | |
361 queue->packets_reserve *= 2; | |
362 } | |
363 else { | |
364 queue->packets = malloc(sizeof(packet_t)); | |
365 if (queue->packets == NULL) { | |
6110 | 366 mp_msg(MSGT_VOBSUB,MSGL_FATAL,"malloc failure"); |
4080 | 367 return -1; |
368 } | |
369 queue->packets_reserve = 1; | |
370 } | |
371 } | |
372 return 0; | |
373 } | |
374 | |
375 /* add one more packet */ | |
376 static int | |
377 packet_queue_grow(packet_queue_t *queue) | |
378 { | |
379 if (packet_queue_ensure(queue, queue->packets_size + 1) < 0) | |
380 return -1; | |
381 packet_construct(queue->packets + queue->packets_size); | |
382 ++queue->packets_size; | |
383 return 0; | |
384 } | |
385 | |
386 /* insert a new packet, duplicating pts from the current one */ | |
387 static int | |
388 packet_queue_insert(packet_queue_t *queue) | |
389 { | |
390 packet_t *pkts; | |
391 if (packet_queue_ensure(queue, queue->packets_size + 1) < 0) | |
392 return -1; | |
393 /* XXX packet_size does not reflect the real thing here, it will be updated a bit later */ | |
394 memmove(queue->packets + queue->current_index + 2, | |
395 queue->packets + queue->current_index + 1, | |
4085 | 396 sizeof(packet_t) * (queue->packets_size - queue->current_index - 1)); |
4080 | 397 pkts = queue->packets + queue->current_index; |
398 ++queue->packets_size; | |
399 ++queue->current_index; | |
400 packet_construct(pkts + 1); | |
401 pkts[1].pts100 = pkts[0].pts100; | |
402 pkts[1].filepos = pkts[0].filepos; | |
403 return 0; | |
404 } | |
405 | |
406 /********************************************************************** | |
407 * Vosub | |
408 **********************************************************************/ | |
409 | |
410 typedef struct { | |
411 unsigned int palette[16]; | |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
412 unsigned int cuspal[4]; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
413 int delay; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
414 unsigned int custom; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
415 unsigned int have_palette; |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
416 unsigned int orig_frame_width, orig_frame_height; |
5563 | 417 unsigned int origin_x, origin_y; |
4080 | 418 /* index */ |
419 packet_queue_t *spu_streams; | |
420 unsigned int spu_streams_size; | |
421 unsigned int spu_streams_current; | |
422 } vobsub_t; | |
423 | |
4085 | 424 /* Make sure that the spu stream idx exists. */ |
4080 | 425 static int |
4085 | 426 vobsub_ensure_spu_stream(vobsub_t *vob, unsigned int index) |
4080 | 427 { |
428 if (index >= vob->spu_streams_size) { | |
429 /* This is a new stream */ | |
430 if (vob->spu_streams) { | |
431 packet_queue_t *tmp = realloc(vob->spu_streams, (index + 1) * sizeof(packet_queue_t)); | |
432 if (tmp == NULL) { | |
6110 | 433 mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: realloc failure"); |
4080 | 434 return -1; |
435 } | |
436 vob->spu_streams = tmp; | |
437 } | |
438 else { | |
439 vob->spu_streams = malloc((index + 1) * sizeof(packet_queue_t)); | |
440 if (vob->spu_streams == NULL) { | |
6110 | 441 mp_msg(MSGT_VOBSUB,MSGL_ERR,"vobsub_ensure_spu_stream: malloc failure"); |
4080 | 442 return -1; |
443 } | |
444 } | |
445 while (vob->spu_streams_size <= index) { | |
446 packet_queue_construct(vob->spu_streams + vob->spu_streams_size); | |
447 ++vob->spu_streams_size; | |
448 } | |
449 } | |
4085 | 450 return 0; |
451 } | |
452 | |
453 static int | |
454 vobsub_add_id(vobsub_t *vob, const char *id, size_t idlen, const unsigned int index) | |
455 { | |
456 if (vobsub_ensure_spu_stream(vob, index) < 0) | |
457 return -1; | |
4080 | 458 if (id && idlen) { |
459 if (vob->spu_streams[index].id) | |
460 free(vob->spu_streams[index].id); | |
461 vob->spu_streams[index].id = malloc(idlen + 1); | |
462 if (vob->spu_streams[index].id == NULL) { | |
6110 | 463 mp_msg(MSGT_VOBSUB,MSGL_FATAL,"vobsub_add_id: malloc failure"); |
4080 | 464 return -1; |
465 } | |
466 vob->spu_streams[index].id[idlen] = 0; | |
467 memcpy(vob->spu_streams[index].id, id, idlen); | |
468 } | |
469 vob->spu_streams_current = index; | |
470 if (verbose) | |
6110 | 471 mp_msg(MSGT_VOBSUB,MSGL_V,"[vobsub] subtitle (vobsubid): %d language %s\n", |
4080 | 472 index, vob->spu_streams[index].id); |
473 return 0; | |
474 } | |
475 | |
476 static int | |
477 vobsub_add_timestamp(vobsub_t *vob, off_t filepos, unsigned int ms) | |
478 { | |
479 packet_queue_t *queue; | |
480 packet_t *pkt; | |
481 if (vob->spu_streams == 0) { | |
6110 | 482 mp_msg(MSGT_VOBSUB,MSGL_WARN,"[vobsub] warning, binning some index entries. Check your index file\n"); |
4080 | 483 return -1; |
484 } | |
485 queue = vob->spu_streams + vob->spu_streams_current; | |
486 if (packet_queue_grow(queue) >= 0) { | |
487 pkt = queue->packets + (queue->packets_size - 1); | |
488 pkt->filepos = filepos; | |
5563 | 489 pkt->pts100 = ms * 90; |
4080 | 490 return 0; |
491 } | |
492 return -1; | |
493 } | |
494 | |
495 static int | |
496 vobsub_parse_id(vobsub_t *vob, const char *line) | |
497 { | |
498 // id: xx, index: n | |
499 size_t idlen; | |
500 const char *p, *q; | |
501 p = line; | |
502 while (isspace(*p)) | |
503 ++p; | |
504 q = p; | |
505 while (isalpha(*q)) | |
506 ++q; | |
507 idlen = q - p; | |
508 if (idlen == 0) | |
509 return -1; | |
510 ++q; | |
511 while (isspace(*q)) | |
512 ++q; | |
513 if (strncmp("index:", q, 6)) | |
514 return -1; | |
515 q += 6; | |
516 while (isspace(*q)) | |
517 ++q; | |
518 if (!isdigit(*q)) | |
519 return -1; | |
520 return vobsub_add_id(vob, p, idlen, atoi(q)); | |
521 } | |
522 | |
523 static int | |
524 vobsub_parse_timestamp(vobsub_t *vob, const char *line) | |
525 { | |
526 // timestamp: HH:MM:SS.mmm, filepos: 0nnnnnnnnn | |
527 const char *p; | |
528 int h, m, s, ms; | |
529 off_t filepos; | |
530 while (isspace(*line)) | |
531 ++line; | |
532 p = line; | |
533 while (isdigit(*p)) | |
534 ++p; | |
535 if (p - line != 2) | |
536 return -1; | |
537 h = atoi(line); | |
538 if (*p != ':') | |
539 return -1; | |
540 line = ++p; | |
541 while (isdigit(*p)) | |
542 ++p; | |
543 if (p - line != 2) | |
544 return -1; | |
545 m = atoi(line); | |
546 if (*p != ':') | |
547 return -1; | |
548 line = ++p; | |
549 while (isdigit(*p)) | |
550 ++p; | |
551 if (p - line != 2) | |
552 return -1; | |
553 s = atoi(line); | |
554 if (*p != ':') | |
555 return -1; | |
556 line = ++p; | |
557 while (isdigit(*p)) | |
558 ++p; | |
559 if (p - line != 3) | |
560 return -1; | |
561 ms = atoi(line); | |
562 if (*p != ',') | |
563 return -1; | |
564 line = p + 1; | |
565 while (isspace(*line)) | |
566 ++line; | |
567 if (strncmp("filepos:", line, 8)) | |
568 return -1; | |
569 line += 8; | |
570 while (isspace(*line)) | |
571 ++line; | |
572 if (! isxdigit(*line)) | |
573 return -1; | |
574 filepos = strtol(line, NULL, 16); | |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
575 return vobsub_add_timestamp(vob, filepos, vob->delay + ms + 1000 * (s + 60 * (m + 60 * h))); |
4080 | 576 } |
577 | |
578 static int | |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
579 vobsub_parse_size(vobsub_t *vob, const char *line) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
580 { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
581 // size: WWWxHHH |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
582 char *p; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
583 while (isspace(*line)) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
584 ++line; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
585 if (!isdigit(*line)) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
586 return -1; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
587 vob->orig_frame_width = strtoul(line, &p, 10); |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
588 if (*p != 'x') |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
589 return -1; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
590 ++p; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
591 vob->orig_frame_height = strtoul(p, NULL, 10); |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
592 return 0; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
593 } |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
594 |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
595 static int |
5563 | 596 vobsub_parse_origin(vobsub_t *vob, const char *line) |
597 { | |
598 // org: X,Y | |
599 char *p; | |
600 while (isspace(*line)) | |
601 ++line; | |
602 if (!isdigit(*line)) | |
603 return -1; | |
604 vob->origin_x = strtoul(line, &p, 10); | |
605 if (*p != ',') | |
606 return -1; | |
607 ++p; | |
608 vob->origin_y = strtoul(p, NULL, 10); | |
609 return 0; | |
610 } | |
611 | |
612 static int | |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
613 vobsub_parse_palette(vobsub_t *vob, const char *line) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
614 { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
615 // palette: XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX, XXXXXX |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
616 unsigned int n; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
617 n = 0; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
618 while (1) { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
619 const char *p; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
620 while (isspace(*line)) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
621 ++line; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
622 p = line; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
623 while (isxdigit(*p)) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
624 ++p; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
625 if (p - line != 6) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
626 return -1; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
627 vob->palette[n++] = strtoul(line, NULL, 16); |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
628 if (n == 16) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
629 break; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
630 if (*p == ',') |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
631 ++p; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
632 line = p; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
633 } |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
634 vob->have_palette = 1; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
635 return 0; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
636 } |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
637 |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
638 static int |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
639 vobsub_parse_custom(vobsub_t *vob, const char *line) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
640 { |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
641 //custom colors: OFF/ON(0/1) |
5839 | 642 if ((strncmp("ON", line + 15, 2) == 0)||strncmp("1", line + 15, 1) == 0) |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
643 vob->custom=1; |
5839 | 644 else if ((strncmp("OFF", line + 15, 3) == 0)||strncmp("0", line + 15, 1) == 0) |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
645 vob->custom=0; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
646 else |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
647 return -1; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
648 return 0; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
649 } |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
650 |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
651 static int |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
652 vobsub_parse_cuspal(vobsub_t *vob, const char *line) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
653 { |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
654 //colors: XXXXXX, XXXXXX, XXXXXX, XXXXXX |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
655 unsigned int n; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
656 n = 0; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
657 line += 40; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
658 while(1){ |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
659 const char *p; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
660 while (isspace(*line)) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
661 ++line; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
662 p=line; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
663 while (isxdigit(*p)) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
664 ++p; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
665 if (p - line !=6) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
666 return -1; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
667 vob->cuspal[n++] = strtoul(line, NULL,16); |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
668 if (n==4) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
669 break; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
670 if(*p == ',') |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
671 ++p; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
672 line = p; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
673 } |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
674 return 0; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
675 } |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
676 |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
677 /* don't know how to use tridx */ |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
678 static int |
6110 | 679 vobsub_parse_tridx(const char *line) |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
680 { |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
681 //tridx: XXXX |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
682 int tridx; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
683 tridx = strtoul((line + 26), NULL, 16); |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
684 tridx = ((tridx&0x1000)>>12) | ((tridx&0x100)>>7) | ((tridx&0x10)>>2) | ((tridx&1)<<3); |
6110 | 685 return tridx; |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
686 } |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
687 |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
688 static int |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
689 vobsub_parse_delay(vobsub_t *vob, const char *line) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
690 { |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
691 int h, m, s, ms; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
692 int forward = 1; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
693 if (*(line + 7) == '+'){ |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
694 forward = 1; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
695 line++; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
696 } |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
697 else if (*(line + 7) == '-'){ |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
698 forward = -1; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
699 line++; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
700 } |
6110 | 701 mp_msg(MSGT_SPUDEC,MSGL_V, "forward=%d", forward); |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
702 h = atoi(line + 7); |
6110 | 703 mp_msg(MSGT_VOBSUB,MSGL_V, "h=%d," ,h); |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
704 m = atoi(line + 10); |
6110 | 705 mp_msg(MSGT_VOBSUB,MSGL_V, "m=%d,", m); |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
706 s = atoi(line + 13); |
6110 | 707 mp_msg(MSGT_VOBSUB,MSGL_V, "s=%d,", s); |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
708 ms = atoi(line + 16); |
6110 | 709 mp_msg(MSGT_VOBSUB,MSGL_V, "ms=%d", ms); |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
710 vob->delay = ms + 1000 * (s + 60 * (m + 60 * h)) * forward; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
711 return 0; |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
712 } |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
713 |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
714 static int |
6110 | 715 vobsub_set_lang(const char *line) |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
716 { |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
717 if (vobsub_id == -1) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
718 vobsub_id = atoi(line + 8); |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
719 return 0; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
720 } |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
721 |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
722 static int |
4080 | 723 vobsub_parse_one_line(vobsub_t *vob, FILE *fd) |
724 { | |
725 ssize_t line_size; | |
726 int res = -1; | |
727 do { | |
6163
141a082e6da6
applied 64bit patch from Ulrich Hecht <uli at suse dot de>
alex
parents:
6110
diff
changeset
|
728 size_t line_reserve = 0; |
4080 | 729 char *line = NULL; |
730 line_size = getline(&line, &line_reserve, fd); | |
731 if (line_size < 0) { | |
732 if (line) | |
733 free(line); | |
734 break; | |
735 } | |
736 if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#') | |
737 continue; | |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
738 else if (strncmp("langidx:", line, 8) == 0) |
6110 | 739 res = vobsub_set_lang(line); |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
740 else if (strncmp("delay:", line, 6) == 0) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
741 res = vobsub_parse_delay(vob, line); |
4080 | 742 else if (strncmp("id:", line, 3) == 0) |
743 res = vobsub_parse_id(vob, line + 3); | |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
744 else if (strncmp("palette:", line, 8) == 0) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
745 res = vobsub_parse_palette(vob, line + 8); |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
746 else if (strncmp("size:", line, 5) == 0) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
747 res = vobsub_parse_size(vob, line + 5); |
5563 | 748 else if (strncmp("org:", line, 4) == 0) |
749 res = vobsub_parse_origin(vob, line + 4); | |
4080 | 750 else if (strncmp("timestamp:", line, 10) == 0) |
751 res = vobsub_parse_timestamp(vob, line + 10); | |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
752 else if (strncmp("custom colors:", line, 14) == 0) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
753 //custom colors: ON/OFF, tridx: XXXX, colors: XXXXXX, XXXXXX, XXXXXX,XXXXXX |
6110 | 754 res = vobsub_parse_cuspal(vob, line) + vobsub_parse_tridx(line) + vobsub_parse_custom(vob, line); |
4080 | 755 else { |
756 if (verbose) | |
6110 | 757 mp_msg(MSGT_VOBSUB,MSGL_V, "vobsub: ignoring %s", line); |
4080 | 758 continue; |
759 } | |
760 if (res < 0) | |
6110 | 761 mp_msg(MSGT_VOBSUB,MSGL_ERR, "ERROR in %s", line); |
4080 | 762 break; |
763 } while (1); | |
764 return res; | |
765 } | |
766 | |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
767 int |
6110 | 768 vobsub_parse_ifo(void* this, const char *const name, unsigned int *palette, unsigned int *width, unsigned int *height, int force) |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
769 { |
6110 | 770 vobsub_t *vob = (vobsub_t*)this; |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
771 int res = -1; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
772 FILE *fd = fopen(name, "rb"); |
5869
412ff784c971
Avoid bogus file not found message if vobsub isn'T forced (autodetect).
atmos4
parents:
5839
diff
changeset
|
773 if (fd == NULL) { |
412ff784c971
Avoid bogus file not found message if vobsub isn'T forced (autodetect).
atmos4
parents:
5839
diff
changeset
|
774 if (force) |
6110 | 775 mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't open IFO file"); |
5869
412ff784c971
Avoid bogus file not found message if vobsub isn'T forced (autodetect).
atmos4
parents:
5839
diff
changeset
|
776 } else { |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
777 // parse IFO header |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
778 unsigned char block[0x800]; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
779 const char *const ifo_magic = "DVDVIDEO-VTS"; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
780 if (fread(block, sizeof(block), 1, fd) != 1) { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
781 if (force) |
6110 | 782 mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't read IFO header"); |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
783 } else if (memcmp(block, ifo_magic, strlen(ifo_magic) + 1)) |
6110 | 784 mp_msg(MSGT_VOBSUB,MSGL_ERR, "Bad magic in IFO header\n"); |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
785 else { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
786 unsigned long pgci_sector = block[0xcc] << 24 | block[0xcd] << 16 |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
787 | block[0xce] << 8 | block[0xcf]; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
788 int standard = (block[0x200] & 0x30) >> 4; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
789 int resolution = (block[0x201] & 0x0c) >> 2; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
790 *height = standard ? 576 : 480; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
791 *width = 0; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
792 switch (resolution) { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
793 case 0x0: |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
794 *width = 720; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
795 break; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
796 case 0x1: |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
797 *width = 704; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
798 break; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
799 case 0x2: |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
800 *width = 352; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
801 break; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
802 case 0x3: |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
803 *width = 352; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
804 *height /= 2; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
805 break; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
806 default: |
6110 | 807 mp_msg(MSGT_VOBSUB,MSGL_WARN,"Vobsub: Unknown resolution %d \n", resolution); |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
808 } |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
809 if (fseek(fd, pgci_sector * sizeof(block), SEEK_SET) |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
810 || fread(block, sizeof(block), 1, fd) != 1) |
6110 | 811 mp_msg(MSGT_VOBSUB,MSGL_ERR, "Can't read IFO PGCI"); |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
812 else { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
813 unsigned long idx; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
814 unsigned long pgc_offset = block[0xc] << 24 | block[0xd] << 16 |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
815 | block[0xe] << 8 | block[0xf]; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
816 for (idx = 0; idx < 16; ++idx) { |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
817 unsigned char *p = block + pgc_offset + 0xa4 + 4 * idx; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
818 palette[idx] = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
819 } |
6110 | 820 if(vob) |
821 vob->have_palette = 1; | |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
822 res = 0; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
823 } |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
824 } |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
825 fclose(fd); |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
826 } |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
827 return res; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
828 } |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
829 |
4080 | 830 void * |
6110 | 831 vobsub_open(const char *const name,const char *const ifo,const int force,void** spu) |
4080 | 832 { |
833 vobsub_t *vob = malloc(sizeof(vobsub_t)); | |
6110 | 834 if(spu) |
835 *spu = NULL; | |
4080 | 836 if (vob) { |
837 char *buf; | |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
838 vob->orig_frame_width = 0; |
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
839 vob->orig_frame_height = 0; |
4080 | 840 vob->spu_streams = NULL; |
841 vob->spu_streams_size = 0; | |
842 vob->spu_streams_current = 0; | |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
843 vob->delay = 0; |
4080 | 844 buf = malloc((strlen(name) + 5) * sizeof(char)); |
845 if (buf) { | |
846 FILE *fd; | |
847 mpeg_t *mpg; | |
5388
3af2729c5c87
* New command line switch for mplayer & mencoder:
kmkaplan
parents:
4787
diff
changeset
|
848 /* read in the info file */ |
6110 | 849 if(!ifo) { |
850 strcpy(buf, name); | |
851 strcat(buf, ".ifo"); | |
852 vobsub_parse_ifo(vob,buf, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force); | |
853 } else | |
854 vobsub_parse_ifo(vob,ifo, vob->palette, &vob->orig_frame_width, &vob->orig_frame_height, force); | |
4080 | 855 /* read in the index */ |
856 strcpy(buf, name); | |
857 strcat(buf, ".idx"); | |
858 fd = fopen(buf, "rb"); | |
4787 | 859 if (fd == NULL) { |
860 if(force) | |
6110 | 861 mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: Can't open IDX file"); |
862 else { | |
863 free(buf); | |
864 free(vob); | |
865 return NULL; | |
866 } | |
4787 | 867 } else { |
4080 | 868 while (vobsub_parse_one_line(vob, fd) >= 0) |
869 /* NOOP */ ; | |
870 fclose(fd); | |
871 } | |
5833
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
872 /* if no palette in .idx then use custom colors */ |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
873 if ((vob->custom == 0)&&(vob->have_palette!=1)) |
91d766389a5d
VobSub updates, custom palette support and other stuff, can't write the name of the chinese(?) patch supplier.
atmos4
parents:
5563
diff
changeset
|
874 vob->custom = 1; |
6110 | 875 if (spu && vob->orig_frame_width && vob->orig_frame_height) |
876 *spu = spudec_new_scaled_vobsub(vob->palette, vob->cuspal, vob->custom, vob->orig_frame_width, vob->orig_frame_height); | |
4080 | 877 |
878 /* read the indexed mpeg_stream */ | |
879 strcpy(buf, name); | |
880 strcat(buf, ".sub"); | |
881 mpg = mpeg_open(buf); | |
4787 | 882 if (mpg == NULL) { |
6110 | 883 if(force) |
884 mp_msg(MSGT_VOBSUB,MSGL_ERR,"VobSub: Can't open SUB file"); | |
885 else { | |
886 | |
887 free(buf); | |
888 free(vob); | |
889 return NULL; | |
890 } | |
4787 | 891 } else { |
4080 | 892 long last_pts_diff = 0; |
893 while (!mpeg_eof(mpg)) { | |
894 off_t pos = mpeg_tell(mpg); | |
895 if (mpeg_run(mpg) < 0) { | |
896 if (!mpeg_eof(mpg)) | |
6110 | 897 mp_msg(MSGT_VOBSUB,MSGL_ERR,"mpeg_run error"); |
4080 | 898 break; |
899 } | |
900 if (mpg->packet_size) { | |
901 if ((mpg->aid & 0xe0) == 0x20) { | |
902 unsigned int sid = mpg->aid & 0x1f; | |
4085 | 903 if (vobsub_ensure_spu_stream(vob, sid) >= 0) { |
4080 | 904 packet_queue_t *queue = vob->spu_streams + sid; |
905 /* get the packet to fill */ | |
4085 | 906 if (queue->packets_size == 0 && packet_queue_grow(queue) < 0) |
907 abort(); | |
4080 | 908 while (queue->current_index + 1 < queue->packets_size |
909 && queue->packets[queue->current_index + 1].filepos <= pos) | |
910 ++queue->current_index; | |
911 if (queue->current_index < queue->packets_size) { | |
912 packet_t *pkt; | |
913 if (queue->packets[queue->current_index].data) { | |
914 /* insert a new packet and fix the PTS ! */ | |
915 packet_queue_insert(queue); | |
916 queue->packets[queue->current_index].pts100 = | |
917 mpg->pts + last_pts_diff; | |
918 } | |
919 pkt = queue->packets + queue->current_index; | |
920 last_pts_diff = pkt->pts100 - mpg->pts; | |
921 /* FIXME: should not use mpg_sub internal informations, make a copy */ | |
922 pkt->data = mpg->packet; | |
923 pkt->size = mpg->packet_size; | |
924 mpg->packet = NULL; | |
925 mpg->packet_reserve = 0; | |
926 mpg->packet_size = 0; | |
927 } | |
928 } | |
929 else | |
6110 | 930 mp_msg(MSGT_VOBSUB,MSGL_WARN, "don't know what to do with subtitle #%u\n", sid); |
4080 | 931 } |
932 } | |
933 } | |
934 vob->spu_streams_current = vob->spu_streams_size; | |
935 while (vob->spu_streams_current-- > 0) | |
936 vob->spu_streams[vob->spu_streams_current].current_index = 0; | |
937 mpeg_free(mpg); | |
938 } | |
939 free(buf); | |
940 } | |
941 } | |
942 return vob; | |
943 } | |
944 | |
945 void | |
946 vobsub_close(void *this) | |
947 { | |
948 vobsub_t *vob = (vobsub_t *)this; | |
949 if (vob->spu_streams) { | |
950 while (vob->spu_streams_size--) | |
951 packet_queue_destroy(vob->spu_streams + vob->spu_streams_size); | |
952 free(vob->spu_streams); | |
953 } | |
954 free(vob); | |
955 } | |
956 | |
6110 | 957 int |
958 vobsub_get_packet(void *vobhandle, float pts,void** data, int* timestamp) { | |
959 vobsub_t *vob = (vobsub_t *)vobhandle; | |
960 unsigned int pts100 = 90000 * pts; | |
961 if (vob->spu_streams && 0 <= vobsub_id && (unsigned) vobsub_id < vob->spu_streams_size) { | |
962 packet_queue_t *queue = vob->spu_streams + vobsub_id; | |
963 while (queue->current_index < queue->packets_size) { | |
964 packet_t *pkt = queue->packets + queue->current_index; | |
965 if (pkt->pts100 <= pts100) { | |
966 ++queue->current_index; | |
967 *data = pkt->data; | |
968 *timestamp = pkt->pts100; | |
969 return pkt->size; | |
970 } else break; | |
4080 | 971 } |
6110 | 972 } |
973 return -1; | |
4080 | 974 } |
975 | |
976 void | |
977 vobsub_reset(void *vobhandle) | |
978 { | |
979 vobsub_t *vob = (vobsub_t *)vobhandle; | |
980 if (vob->spu_streams) { | |
981 unsigned int n = vob->spu_streams_size; | |
982 while (n-- > 0) | |
983 vob->spu_streams[n].current_index = 0; | |
984 } | |
985 } |