Mercurial > mplayer.hg
annotate vobsub.c @ 6110:7bea806b9c5f
Improvment for spu subtitles.
Removed the integreted spudec in vobsub.
Various cleanup/bugfix in vobsub (no more auto palette when a true one is
here)
HW spu rendering moved in spudec because we first need to reassable the
packet before sending them to the hw.
Spudec is now created only if nedded.
author | albeu |
---|---|
date | Fri, 17 May 2002 23:47:27 +0000 |
parents | 412ff784c971 |
children | 141a082e6da6 |
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 { | |
728 int line_reserve = 0; | |
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 } |