Mercurial > libavcodec.hg
comparison dvbsubdec.c @ 2796:95c35706acbb libavcodec
DVB subtitle decoder by (Ian Caulfield: imc25, cam ac uk)
author | michael |
---|---|
date | Sun, 17 Jul 2005 00:28:12 +0000 |
parents | |
children | 1f117208d20f |
comparison
equal
deleted
inserted
replaced
2795:de03cac6f7c2 | 2796:95c35706acbb |
---|---|
1 /* | |
2 * DVB subtitle decoding for ffmpeg | |
3 * Copyright (c) 2005 Ian Caulfield. | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 */ | |
19 #include "avcodec.h" | |
20 #include "dsputil.h" | |
21 #include "bitstream.h" | |
22 | |
23 //#define DEBUG | |
24 //#define DEBUG_PACKET_CONTENTS | |
25 //#define DEBUG_SAVE_IMAGES | |
26 | |
27 #define DVBSUB_PAGE_SEGMENT 0x10 | |
28 #define DVBSUB_REGION_SEGMENT 0x11 | |
29 #define DVBSUB_CLUT_SEGMENT 0x12 | |
30 #define DVBSUB_OBJECT_SEGMENT 0x13 | |
31 #define DVBSUB_DISPLAY_SEGMENT 0x80 | |
32 | |
33 static unsigned char *cm; | |
34 | |
35 #ifdef DEBUG_SAVE_IMAGES | |
36 #undef fprintf | |
37 #if 0 | |
38 static void png_save(const char *filename, uint8_t *bitmap, int w, int h, | |
39 uint32_t *rgba_palette) | |
40 { | |
41 int x, y, v; | |
42 FILE *f; | |
43 char fname[40], fname2[40]; | |
44 char command[1024]; | |
45 | |
46 snprintf(fname, 40, "%s.ppm", filename); | |
47 | |
48 f = fopen(fname, "w"); | |
49 if (!f) { | |
50 perror(fname); | |
51 exit(1); | |
52 } | |
53 fprintf(f, "P6\n" | |
54 "%d %d\n" | |
55 "%d\n", | |
56 w, h, 255); | |
57 for(y = 0; y < h; y++) { | |
58 for(x = 0; x < w; x++) { | |
59 v = rgba_palette[bitmap[y * w + x]]; | |
60 putc((v >> 16) & 0xff, f); | |
61 putc((v >> 8) & 0xff, f); | |
62 putc((v >> 0) & 0xff, f); | |
63 } | |
64 } | |
65 fclose(f); | |
66 | |
67 | |
68 snprintf(fname2, 40, "%s-a.pgm", filename); | |
69 | |
70 f = fopen(fname2, "w"); | |
71 if (!f) { | |
72 perror(fname2); | |
73 exit(1); | |
74 } | |
75 fprintf(f, "P5\n" | |
76 "%d %d\n" | |
77 "%d\n", | |
78 w, h, 255); | |
79 for(y = 0; y < h; y++) { | |
80 for(x = 0; x < w; x++) { | |
81 v = rgba_palette[bitmap[y * w + x]]; | |
82 putc((v >> 24) & 0xff, f); | |
83 } | |
84 } | |
85 fclose(f); | |
86 | |
87 snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); | |
88 system(command); | |
89 | |
90 snprintf(command, 1024, "rm %s %s", fname, fname2); | |
91 system(command); | |
92 } | |
93 #endif | |
94 | |
95 static void png_save2(const char *filename, uint32_t *bitmap, int w, int h) | |
96 { | |
97 int x, y, v; | |
98 FILE *f; | |
99 char fname[40], fname2[40]; | |
100 char command[1024]; | |
101 | |
102 snprintf(fname, 40, "%s.ppm", filename); | |
103 | |
104 f = fopen(fname, "w"); | |
105 if (!f) { | |
106 perror(fname); | |
107 exit(1); | |
108 } | |
109 fprintf(f, "P6\n" | |
110 "%d %d\n" | |
111 "%d\n", | |
112 w, h, 255); | |
113 for(y = 0; y < h; y++) { | |
114 for(x = 0; x < w; x++) { | |
115 v = bitmap[y * w + x]; | |
116 putc((v >> 16) & 0xff, f); | |
117 putc((v >> 8) & 0xff, f); | |
118 putc((v >> 0) & 0xff, f); | |
119 } | |
120 } | |
121 fclose(f); | |
122 | |
123 | |
124 snprintf(fname2, 40, "%s-a.pgm", filename); | |
125 | |
126 f = fopen(fname2, "w"); | |
127 if (!f) { | |
128 perror(fname2); | |
129 exit(1); | |
130 } | |
131 fprintf(f, "P5\n" | |
132 "%d %d\n" | |
133 "%d\n", | |
134 w, h, 255); | |
135 for(y = 0; y < h; y++) { | |
136 for(x = 0; x < w; x++) { | |
137 v = bitmap[y * w + x]; | |
138 putc((v >> 24) & 0xff, f); | |
139 } | |
140 } | |
141 fclose(f); | |
142 | |
143 snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); | |
144 system(command); | |
145 | |
146 snprintf(command, 1024, "rm %s %s", fname, fname2); | |
147 system(command); | |
148 } | |
149 #endif | |
150 | |
151 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) | |
152 | |
153 typedef struct DVBSubCLUT { | |
154 int id; | |
155 | |
156 uint32_t clut4[4]; | |
157 uint32_t clut16[16]; | |
158 uint32_t clut256[256]; | |
159 | |
160 struct DVBSubCLUT *next; | |
161 } DVBSubCLUT; | |
162 | |
163 static DVBSubCLUT default_clut; | |
164 | |
165 typedef struct DVBSubObjectDisplay { | |
166 int object_id; | |
167 int region_id; | |
168 | |
169 int x_pos; | |
170 int y_pos; | |
171 | |
172 int fgcolour; | |
173 int bgcolour; | |
174 | |
175 struct DVBSubObjectDisplay *region_list_next; | |
176 struct DVBSubObjectDisplay *object_list_next; | |
177 } DVBSubObjectDisplay; | |
178 | |
179 typedef struct DVBSubObject { | |
180 int id; | |
181 | |
182 int type; | |
183 | |
184 DVBSubObjectDisplay *display_list; | |
185 | |
186 struct DVBSubObject *next; | |
187 } DVBSubObject; | |
188 | |
189 typedef struct DVBSubRegionDisplay { | |
190 int region_id; | |
191 | |
192 int x_pos; | |
193 int y_pos; | |
194 | |
195 struct DVBSubRegionDisplay *next; | |
196 } DVBSubRegionDisplay; | |
197 | |
198 typedef struct DVBSubRegion { | |
199 int id; | |
200 | |
201 int width; | |
202 int height; | |
203 int depth; | |
204 | |
205 int clut; | |
206 int bgcolour; | |
207 | |
208 uint8_t *pbuf; | |
209 int buf_size; | |
210 | |
211 DVBSubObjectDisplay *display_list; | |
212 | |
213 struct DVBSubRegion *next; | |
214 } DVBSubRegion; | |
215 | |
216 typedef struct DVBSubContext { | |
217 int composition_id; | |
218 int ancillary_id; | |
219 | |
220 int time_out; | |
221 DVBSubRegion *region_list; | |
222 DVBSubCLUT *clut_list; | |
223 DVBSubObject *object_list; | |
224 | |
225 int display_list_size; | |
226 DVBSubRegionDisplay *display_list; | |
227 } DVBSubContext; | |
228 | |
229 | |
230 static DVBSubObject* get_object(DVBSubContext *ctx, int object_id) | |
231 { | |
232 DVBSubObject *ptr = ctx->object_list; | |
233 | |
234 while (ptr != NULL && ptr->id != object_id) { | |
235 ptr = ptr->next; | |
236 } | |
237 | |
238 return ptr; | |
239 } | |
240 | |
241 static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id) | |
242 { | |
243 DVBSubCLUT *ptr = ctx->clut_list; | |
244 | |
245 while (ptr != NULL && ptr->id != clut_id) { | |
246 ptr = ptr->next; | |
247 } | |
248 | |
249 return ptr; | |
250 } | |
251 | |
252 static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id) | |
253 { | |
254 DVBSubRegion *ptr = ctx->region_list; | |
255 | |
256 while (ptr != NULL && ptr->id != region_id) { | |
257 ptr = ptr->next; | |
258 } | |
259 | |
260 return ptr; | |
261 } | |
262 | |
263 static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region) | |
264 { | |
265 DVBSubObject *object, *obj2, **obj2_ptr; | |
266 DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr; | |
267 | |
268 while (region->display_list != NULL) { | |
269 display = region->display_list; | |
270 | |
271 object = get_object(ctx, display->object_id); | |
272 | |
273 if (object != NULL) { | |
274 obj_disp = object->display_list; | |
275 obj_disp_ptr = &object->display_list; | |
276 | |
277 while (obj_disp != NULL && obj_disp != display) { | |
278 obj_disp_ptr = &obj_disp->object_list_next; | |
279 obj_disp = obj_disp->object_list_next; | |
280 } | |
281 | |
282 if (obj_disp) { | |
283 *obj_disp_ptr = obj_disp->object_list_next; | |
284 | |
285 if (object->display_list == NULL) { | |
286 obj2 = ctx->object_list; | |
287 obj2_ptr = &ctx->object_list; | |
288 | |
289 while (obj2 != NULL && obj2 != object) { | |
290 obj2_ptr = &obj2->next; | |
291 obj2 = obj2->next; | |
292 } | |
293 | |
294 *obj2_ptr = obj2->next; | |
295 | |
296 av_free(obj2); | |
297 } | |
298 } | |
299 } | |
300 | |
301 region->display_list = display->region_list_next; | |
302 | |
303 av_free(display); | |
304 } | |
305 | |
306 } | |
307 | |
308 static void delete_state(DVBSubContext *ctx) | |
309 { | |
310 DVBSubRegion *region; | |
311 DVBSubCLUT *clut; | |
312 | |
313 while (ctx->region_list != NULL) | |
314 { | |
315 region = ctx->region_list; | |
316 | |
317 ctx->region_list = region->next; | |
318 | |
319 delete_region_display_list(ctx, region); | |
320 if (region->pbuf != NULL) | |
321 av_free(region->pbuf); | |
322 | |
323 av_free(region); | |
324 } | |
325 | |
326 while (ctx->clut_list != NULL) | |
327 { | |
328 clut = ctx->clut_list; | |
329 | |
330 ctx->clut_list = clut->next; | |
331 | |
332 av_free(clut); | |
333 } | |
334 | |
335 /* Should already be null */ | |
336 if (ctx->object_list != NULL) | |
337 av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); | |
338 } | |
339 | |
340 static int dvbsub_init_decoder(AVCodecContext *avctx) | |
341 { | |
342 int i, r, g, b, a = 0; | |
343 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
344 | |
345 cm = cropTbl + MAX_NEG_CROP; | |
346 | |
347 memset(avctx->priv_data, 0, sizeof(DVBSubContext)); | |
348 | |
349 ctx->composition_id = avctx->sub_id & 0xffff; | |
350 ctx->ancillary_id = avctx->sub_id >> 16; | |
351 | |
352 default_clut.id = -1; | |
353 default_clut.next = NULL; | |
354 | |
355 default_clut.clut4[0] = RGBA( 0, 0, 0, 0); | |
356 default_clut.clut4[1] = RGBA(255, 255, 255, 255); | |
357 default_clut.clut4[2] = RGBA( 0, 0, 0, 255); | |
358 default_clut.clut4[3] = RGBA(127, 127, 127, 255); | |
359 | |
360 default_clut.clut16[0] = RGBA( 0, 0, 0, 0); | |
361 for (i = 1; i < 16; i++) { | |
362 if (i < 8) { | |
363 r = (i & 1) ? 255 : 0; | |
364 g = (i & 2) ? 255 : 0; | |
365 b = (i & 4) ? 255 : 0; | |
366 } else { | |
367 r = (i & 1) ? 127 : 0; | |
368 g = (i & 2) ? 127 : 0; | |
369 b = (i & 4) ? 127 : 0; | |
370 } | |
371 default_clut.clut16[i] = RGBA(r, g, b, 255); | |
372 } | |
373 | |
374 default_clut.clut256[0] = RGBA( 0, 0, 0, 0); | |
375 for (i = 1; i < 256; i++) { | |
376 if (i < 8) { | |
377 r = (i & 1) ? 255 : 0; | |
378 g = (i & 2) ? 255 : 0; | |
379 b = (i & 4) ? 255 : 0; | |
380 a = 63; | |
381 } else { | |
382 switch (i & 0x88) { | |
383 case 0x00: | |
384 r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0); | |
385 g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0); | |
386 b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0); | |
387 a = 255; | |
388 break; | |
389 case 0x08: | |
390 r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0); | |
391 g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0); | |
392 b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0); | |
393 a = 127; | |
394 break; | |
395 case 0x80: | |
396 r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0); | |
397 g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0); | |
398 b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0); | |
399 a = 255; | |
400 break; | |
401 case 0x88: | |
402 r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0); | |
403 g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0); | |
404 b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0); | |
405 a = 255; | |
406 break; | |
407 } | |
408 } | |
409 default_clut.clut256[i] = RGBA(r, g, b, a); | |
410 } | |
411 | |
412 return 0; | |
413 } | |
414 | |
415 static int dvbsub_close_decoder(AVCodecContext *avctx) | |
416 { | |
417 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
418 DVBSubRegionDisplay *display; | |
419 | |
420 delete_state(ctx); | |
421 | |
422 while (ctx->display_list != NULL) | |
423 { | |
424 display = ctx->display_list; | |
425 ctx->display_list = display->next; | |
426 | |
427 av_free(display); | |
428 } | |
429 | |
430 return 0; | |
431 } | |
432 | |
433 static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, | |
434 uint8_t **srcbuf, int buf_size, | |
435 int non_mod, uint8_t *map_table) | |
436 { | |
437 GetBitContext gb; | |
438 | |
439 int bits; | |
440 int run_length; | |
441 int pixels_read = 0; | |
442 | |
443 init_get_bits(&gb, *srcbuf, buf_size << 8); | |
444 | |
445 while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) { | |
446 bits = get_bits(&gb, 2); | |
447 | |
448 if (bits != 0) { | |
449 if (non_mod != 1 || bits != 1) { | |
450 if (map_table != NULL) | |
451 *destbuf++ = map_table[bits]; | |
452 else | |
453 *destbuf++ = bits; | |
454 } | |
455 pixels_read++; | |
456 } else { | |
457 bits = get_bits(&gb, 1); | |
458 if (bits == 1) { | |
459 run_length = get_bits(&gb, 3) + 3; | |
460 bits = get_bits(&gb, 2); | |
461 | |
462 if (non_mod == 1 && bits == 1) | |
463 pixels_read += run_length; | |
464 else { | |
465 if (map_table != NULL) | |
466 bits = map_table[bits]; | |
467 while (run_length-- > 0 && pixels_read < dbuf_len) { | |
468 *destbuf++ = bits; | |
469 pixels_read++; | |
470 } | |
471 } | |
472 } else { | |
473 bits = get_bits(&gb, 1); | |
474 if (bits == 0) { | |
475 bits = get_bits(&gb, 2); | |
476 if (bits == 2) { | |
477 run_length = get_bits(&gb, 4) + 12; | |
478 bits = get_bits(&gb, 2); | |
479 | |
480 if (non_mod == 1 && bits == 1) | |
481 pixels_read += run_length; | |
482 else { | |
483 if (map_table != NULL) | |
484 bits = map_table[bits]; | |
485 while (run_length-- > 0 && pixels_read < dbuf_len) { | |
486 *destbuf++ = bits; | |
487 pixels_read++; | |
488 } | |
489 } | |
490 } else if (bits == 3) { | |
491 run_length = get_bits(&gb, 8) + 29; | |
492 bits = get_bits(&gb, 2); | |
493 | |
494 if (non_mod == 1 && bits == 1) | |
495 pixels_read += run_length; | |
496 else { | |
497 if (map_table != NULL) | |
498 bits = map_table[bits]; | |
499 while (run_length-- > 0 && pixels_read < dbuf_len) { | |
500 *destbuf++ = bits; | |
501 pixels_read++; | |
502 } | |
503 } | |
504 } else if (bits == 1) { | |
505 pixels_read += 2; | |
506 if (map_table != NULL) | |
507 bits = map_table[0]; | |
508 else | |
509 bits = 0; | |
510 if (pixels_read <= dbuf_len) { | |
511 *destbuf++ = bits; | |
512 *destbuf++ = bits; | |
513 } | |
514 } else { | |
515 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; | |
516 return pixels_read; | |
517 } | |
518 } else { | |
519 if (map_table != NULL) | |
520 bits = map_table[0]; | |
521 else | |
522 bits = 0; | |
523 *destbuf++ = bits; | |
524 pixels_read++; | |
525 } | |
526 } | |
527 } | |
528 } | |
529 | |
530 if (get_bits(&gb, 6) != 0) | |
531 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); | |
532 | |
533 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; | |
534 | |
535 return pixels_read; | |
536 } | |
537 | |
538 static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, | |
539 uint8_t **srcbuf, int buf_size, | |
540 int non_mod, uint8_t *map_table) | |
541 { | |
542 GetBitContext gb; | |
543 | |
544 int bits; | |
545 int run_length; | |
546 int pixels_read = 0; | |
547 | |
548 init_get_bits(&gb, *srcbuf, buf_size << 8); | |
549 | |
550 while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) { | |
551 bits = get_bits(&gb, 4); | |
552 | |
553 if (bits != 0) { | |
554 if (non_mod != 1 || bits != 1) { | |
555 if (map_table != NULL) | |
556 *destbuf++ = map_table[bits]; | |
557 else | |
558 *destbuf++ = bits; | |
559 } | |
560 pixels_read++; | |
561 } else { | |
562 bits = get_bits(&gb, 1); | |
563 if (bits == 0) { | |
564 run_length = get_bits(&gb, 3); | |
565 | |
566 if (run_length == 0) { | |
567 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; | |
568 return pixels_read; | |
569 } | |
570 | |
571 run_length += 2; | |
572 | |
573 if (map_table != NULL) | |
574 bits = map_table[0]; | |
575 else | |
576 bits = 0; | |
577 | |
578 while (run_length-- > 0 && pixels_read < dbuf_len) { | |
579 *destbuf++ = bits; | |
580 pixels_read++; | |
581 } | |
582 } else { | |
583 bits = get_bits(&gb, 1); | |
584 if (bits == 0) { | |
585 run_length = get_bits(&gb, 2) + 4; | |
586 bits = get_bits(&gb, 4); | |
587 | |
588 if (non_mod == 1 && bits == 1) | |
589 pixels_read += run_length; | |
590 else { | |
591 if (map_table != NULL) | |
592 bits = map_table[bits]; | |
593 while (run_length-- > 0 && pixels_read < dbuf_len) { | |
594 *destbuf++ = bits; | |
595 pixels_read++; | |
596 } | |
597 } | |
598 } else { | |
599 bits = get_bits(&gb, 2); | |
600 if (bits == 2) { | |
601 run_length = get_bits(&gb, 4) + 9; | |
602 bits = get_bits(&gb, 4); | |
603 | |
604 if (non_mod == 1 && bits == 1) | |
605 pixels_read += run_length; | |
606 else { | |
607 if (map_table != NULL) | |
608 bits = map_table[bits]; | |
609 while (run_length-- > 0 && pixels_read < dbuf_len) { | |
610 *destbuf++ = bits; | |
611 pixels_read++; | |
612 } | |
613 } | |
614 } else if (bits == 3) { | |
615 run_length = get_bits(&gb, 8) + 25; | |
616 bits = get_bits(&gb, 4); | |
617 | |
618 if (non_mod == 1 && bits == 1) | |
619 pixels_read += run_length; | |
620 else { | |
621 if (map_table != NULL) | |
622 bits = map_table[bits]; | |
623 while (run_length-- > 0 && pixels_read < dbuf_len) { | |
624 *destbuf++ = bits; | |
625 pixels_read++; | |
626 } | |
627 } | |
628 } else if (bits == 1) { | |
629 pixels_read += 2; | |
630 if (map_table != NULL) | |
631 bits = map_table[0]; | |
632 else | |
633 bits = 0; | |
634 if (pixels_read <= dbuf_len) { | |
635 *destbuf++ = bits; | |
636 *destbuf++ = bits; | |
637 } | |
638 } else { | |
639 if (map_table != NULL) | |
640 bits = map_table[0]; | |
641 else | |
642 bits = 0; | |
643 *destbuf++ = bits; | |
644 pixels_read ++; | |
645 } | |
646 } | |
647 } | |
648 } | |
649 } | |
650 | |
651 if (get_bits(&gb, 8) != 0) | |
652 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); | |
653 | |
654 (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; | |
655 | |
656 return pixels_read; | |
657 } | |
658 | |
659 static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, | |
660 uint8_t **srcbuf, int buf_size, | |
661 int non_mod, uint8_t *map_table) | |
662 { | |
663 uint8_t *sbuf_end = (*srcbuf) + buf_size; | |
664 int bits; | |
665 int run_length; | |
666 int pixels_read = 0; | |
667 | |
668 while (*srcbuf < sbuf_end && pixels_read < dbuf_len) { | |
669 bits = *(*srcbuf)++; | |
670 | |
671 if (bits != 0) { | |
672 if (non_mod != 1 || bits != 1) { | |
673 if (map_table != NULL) | |
674 *destbuf++ = map_table[bits]; | |
675 else | |
676 *destbuf++ = bits; | |
677 } | |
678 pixels_read++; | |
679 } else { | |
680 bits = *(*srcbuf)++; | |
681 run_length = bits & 0x7f; | |
682 if ((bits & 0x80) == 0) { | |
683 if (run_length == 0) { | |
684 return pixels_read; | |
685 } | |
686 | |
687 if (map_table != NULL) | |
688 bits = map_table[0]; | |
689 else | |
690 bits = 0; | |
691 while (run_length-- > 0 && pixels_read < dbuf_len) { | |
692 *destbuf++ = bits; | |
693 pixels_read++; | |
694 } | |
695 } else { | |
696 bits = *(*srcbuf)++; | |
697 | |
698 if (non_mod == 1 && bits == 1) | |
699 pixels_read += run_length; | |
700 if (map_table != NULL) | |
701 bits = map_table[bits]; | |
702 else while (run_length-- > 0 && pixels_read < dbuf_len) { | |
703 *destbuf++ = bits; | |
704 pixels_read++; | |
705 } | |
706 } | |
707 } | |
708 } | |
709 | |
710 if (*(*srcbuf)++ != 0) | |
711 av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); | |
712 | |
713 return pixels_read; | |
714 } | |
715 | |
716 | |
717 | |
718 static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display, | |
719 uint8_t *buf, int buf_size, int top_bottom, int non_mod) | |
720 { | |
721 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
722 | |
723 DVBSubRegion *region = get_region(ctx, display->region_id); | |
724 uint8_t *buf_end = buf + buf_size; | |
725 uint8_t *pbuf; | |
726 int x_pos, y_pos; | |
727 int i; | |
728 | |
729 uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf}; | |
730 uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff}; | |
731 uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, | |
732 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; | |
733 uint8_t *map_table; | |
734 | |
735 #ifdef DEBUG | |
736 av_log(avctx, AV_LOG_INFO, "DVB pixel block size %d, %s field:\n", buf_size, | |
737 top_bottom ? "bottom" : "top"); | |
738 #endif | |
739 | |
740 #ifdef DEBUG_PACKET_CONTENTS | |
741 for (i = 0; i < buf_size; i++) | |
742 { | |
743 if (i % 16 == 0) | |
744 av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i); | |
745 | |
746 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); | |
747 if (i % 16 == 15) | |
748 av_log(avctx, AV_LOG_INFO, "\n"); | |
749 } | |
750 | |
751 if (i % 16 != 0) | |
752 av_log(avctx, AV_LOG_INFO, "\n"); | |
753 | |
754 #endif | |
755 | |
756 if (region == 0) | |
757 return; | |
758 | |
759 pbuf = region->pbuf; | |
760 | |
761 x_pos = display->x_pos; | |
762 y_pos = display->y_pos; | |
763 | |
764 if ((y_pos & 1) != top_bottom) | |
765 y_pos++; | |
766 | |
767 while (buf < buf_end) { | |
768 if (x_pos > region->width || y_pos > region->height) { | |
769 av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n"); | |
770 return; | |
771 } | |
772 | |
773 switch (*buf++) { | |
774 case 0x10: | |
775 if (region->depth == 8) | |
776 map_table = map2to8; | |
777 else if (region->depth == 4) | |
778 map_table = map2to4; | |
779 else | |
780 map_table = NULL; | |
781 | |
782 x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos, | |
783 region->width - x_pos, &buf, buf_size, | |
784 non_mod, map_table); | |
785 break; | |
786 case 0x11: | |
787 if (region->depth < 4) { | |
788 av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth); | |
789 return; | |
790 } | |
791 | |
792 if (region->depth == 8) | |
793 map_table = map4to8; | |
794 else | |
795 map_table = NULL; | |
796 | |
797 x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos, | |
798 region->width - x_pos, &buf, buf_size, | |
799 non_mod, map_table); | |
800 break; | |
801 case 0x12: | |
802 if (region->depth < 8) { | |
803 av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth); | |
804 return; | |
805 } | |
806 | |
807 x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos, | |
808 region->width - x_pos, &buf, buf_size, | |
809 non_mod, NULL); | |
810 break; | |
811 | |
812 case 0x20: | |
813 map2to4[0] = (*buf) >> 4; | |
814 map2to4[1] = (*buf++) & 0xf; | |
815 map2to4[2] = (*buf) >> 4; | |
816 map2to4[3] = (*buf++) & 0xf; | |
817 break; | |
818 case 0x21: | |
819 for (i = 0; i < 4; i++) | |
820 map2to8[i] = *buf++; | |
821 break; | |
822 case 0x22: | |
823 for (i = 0; i < 16; i++) | |
824 map4to8[i] = *buf++; | |
825 break; | |
826 | |
827 case 0xf0: | |
828 x_pos = display->x_pos; | |
829 y_pos += 2; | |
830 break; | |
831 default: | |
832 av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1)); | |
833 } | |
834 } | |
835 | |
836 } | |
837 | |
838 static void dvbsub_parse_object_segment(AVCodecContext *avctx, | |
839 uint8_t *buf, int buf_size) | |
840 { | |
841 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
842 | |
843 uint8_t *buf_end = buf + buf_size; | |
844 uint8_t *block; | |
845 int object_id; | |
846 DVBSubObject *object; | |
847 DVBSubObjectDisplay *display; | |
848 int top_field_len, bottom_field_len; | |
849 | |
850 int coding_method, non_modifying_colour; | |
851 | |
852 object_id = BE_16(buf); | |
853 buf += 2; | |
854 | |
855 object = get_object(ctx, object_id); | |
856 | |
857 if (!object) | |
858 return; | |
859 | |
860 coding_method = ((*buf) >> 2) & 3; | |
861 non_modifying_colour = ((*buf++) >> 1) & 1; | |
862 | |
863 if (coding_method == 0) { | |
864 top_field_len = BE_16(buf); | |
865 buf += 2; | |
866 bottom_field_len = BE_16(buf); | |
867 buf += 2; | |
868 | |
869 if (buf + top_field_len + bottom_field_len > buf_end) { | |
870 av_log(avctx, AV_LOG_ERROR, "Field data size too large\n"); | |
871 return; | |
872 } | |
873 | |
874 for (display = object->display_list; display != 0; display = display->object_list_next) { | |
875 block = buf; | |
876 | |
877 dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0, | |
878 non_modifying_colour); | |
879 | |
880 if (bottom_field_len > 0) | |
881 block = buf + top_field_len; | |
882 else | |
883 bottom_field_len = top_field_len; | |
884 | |
885 dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1, | |
886 non_modifying_colour); | |
887 } | |
888 | |
889 /* } else if (coding_method == 1) {*/ | |
890 | |
891 } else { | |
892 av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method); | |
893 } | |
894 | |
895 } | |
896 | |
897 #define SCALEBITS 10 | |
898 #define ONE_HALF (1 << (SCALEBITS - 1)) | |
899 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) | |
900 | |
901 #define YUV_TO_RGB1_CCIR(cb1, cr1)\ | |
902 {\ | |
903 cb = (cb1) - 128;\ | |
904 cr = (cr1) - 128;\ | |
905 r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\ | |
906 g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \ | |
907 ONE_HALF;\ | |
908 b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\ | |
909 } | |
910 | |
911 #define YUV_TO_RGB2_CCIR(r, g, b, y1)\ | |
912 {\ | |
913 y = ((y1) - 16) * FIX(255.0/219.0);\ | |
914 r = cm[(y + r_add) >> SCALEBITS];\ | |
915 g = cm[(y + g_add) >> SCALEBITS];\ | |
916 b = cm[(y + b_add) >> SCALEBITS];\ | |
917 } | |
918 | |
919 | |
920 static void dvbsub_parse_clut_segment(AVCodecContext *avctx, | |
921 uint8_t *buf, int buf_size) | |
922 { | |
923 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
924 | |
925 uint8_t *buf_end = buf + buf_size; | |
926 int clut_id; | |
927 DVBSubCLUT *clut; | |
928 int entry_id, depth , full_range; | |
929 int y, cr, cb, alpha; | |
930 int r, g, b, r_add, g_add, b_add; | |
931 | |
932 #ifdef DEBUG_PACKET_CONTENTS | |
933 int i; | |
934 | |
935 av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n"); | |
936 | |
937 for (i=0; i < buf_size; i++) | |
938 { | |
939 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); | |
940 if (i % 16 == 15) | |
941 av_log(avctx, AV_LOG_INFO, "\n"); | |
942 } | |
943 | |
944 if (i % 16 != 0) | |
945 av_log(avctx, AV_LOG_INFO, "\n"); | |
946 | |
947 #endif | |
948 | |
949 clut_id = *buf++; | |
950 buf += 1; | |
951 | |
952 clut = get_clut(ctx, clut_id); | |
953 | |
954 if (clut == NULL) { | |
955 clut = av_malloc(sizeof(DVBSubCLUT)); | |
956 | |
957 memcpy(clut, &default_clut, sizeof(DVBSubCLUT)); | |
958 | |
959 clut->id = clut_id; | |
960 | |
961 clut->next = ctx->clut_list; | |
962 ctx->clut_list = clut; | |
963 } | |
964 | |
965 while (buf + 4 < buf_end) | |
966 { | |
967 entry_id = *buf++; | |
968 | |
969 depth = (*buf) & 0xe0; | |
970 | |
971 if (depth == 0) { | |
972 av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf); | |
973 return; | |
974 } | |
975 | |
976 full_range = (*buf++) & 1; | |
977 | |
978 if (full_range) { | |
979 y = *buf++; | |
980 cr = *buf++; | |
981 cb = *buf++; | |
982 alpha = *buf++; | |
983 } else { | |
984 y = buf[0] & 0xfc; | |
985 cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4; | |
986 cb = (buf[1] << 2) & 0xf0; | |
987 alpha = (buf[1] << 6) & 0xc0; | |
988 | |
989 buf += 2; | |
990 } | |
991 | |
992 if (y == 0) | |
993 alpha = 0xff; | |
994 | |
995 YUV_TO_RGB1_CCIR(cb, cr); | |
996 YUV_TO_RGB2_CCIR(r, g, b, y); | |
997 | |
998 #ifdef DEBUG | |
999 av_log(avctx, AV_LOG_INFO, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); | |
1000 #endif | |
1001 | |
1002 if (depth & 0x80) | |
1003 clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha); | |
1004 if (depth & 0x40) | |
1005 clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha); | |
1006 if (depth & 0x20) | |
1007 clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); | |
1008 } | |
1009 } | |
1010 | |
1011 | |
1012 static void dvbsub_parse_region_segment(AVCodecContext *avctx, | |
1013 uint8_t *buf, int buf_size) | |
1014 { | |
1015 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
1016 | |
1017 uint8_t *buf_end = buf + buf_size; | |
1018 int region_id, object_id; | |
1019 DVBSubRegion *region; | |
1020 DVBSubObject *object; | |
1021 DVBSubObjectDisplay *display; | |
1022 int fill; | |
1023 | |
1024 if (buf_size < 10) | |
1025 return; | |
1026 | |
1027 region_id = *buf++; | |
1028 | |
1029 region = get_region(ctx, region_id); | |
1030 | |
1031 if (region == NULL) | |
1032 { | |
1033 region = av_mallocz(sizeof(DVBSubRegion)); | |
1034 | |
1035 region->id = region_id; | |
1036 | |
1037 region->next = ctx->region_list; | |
1038 ctx->region_list = region; | |
1039 } | |
1040 | |
1041 fill = ((*buf++) >> 3) & 1; | |
1042 | |
1043 region->width = BE_16(buf); | |
1044 buf += 2; | |
1045 region->height = BE_16(buf); | |
1046 buf += 2; | |
1047 | |
1048 if (region->width * region->height != region->buf_size) { | |
1049 if (region->pbuf != 0) | |
1050 av_free(region->pbuf); | |
1051 | |
1052 region->buf_size = region->width * region->height; | |
1053 | |
1054 region->pbuf = av_malloc(region->buf_size); | |
1055 | |
1056 fill = 1; | |
1057 } | |
1058 | |
1059 region->depth = 1 << (((*buf++) >> 2) & 7); | |
1060 region->clut = *buf++; | |
1061 | |
1062 if (region->depth == 8) | |
1063 region->bgcolour = *buf++; | |
1064 else { | |
1065 buf += 1; | |
1066 | |
1067 if (region->depth == 4) | |
1068 region->bgcolour = (((*buf++) >> 4) & 15); | |
1069 else | |
1070 region->bgcolour = (((*buf++) >> 2) & 3); | |
1071 } | |
1072 | |
1073 #ifdef DEBUG | |
1074 av_log(avctx, AV_LOG_INFO, "Region %d, (%dx%d)\n", region_id, region->width, region->height); | |
1075 #endif | |
1076 | |
1077 if (fill) { | |
1078 memset(region->pbuf, region->bgcolour, region->buf_size); | |
1079 #ifdef DEBUG | |
1080 av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolour); | |
1081 #endif | |
1082 } | |
1083 | |
1084 delete_region_display_list(ctx, region); | |
1085 | |
1086 while (buf + 5 < buf_end) { | |
1087 object_id = BE_16(buf); | |
1088 buf += 2; | |
1089 | |
1090 object = get_object(ctx, object_id); | |
1091 | |
1092 if (object == NULL) { | |
1093 object = av_mallocz(sizeof(DVBSubObject)); | |
1094 | |
1095 object->id = object_id; | |
1096 object->next = ctx->object_list; | |
1097 ctx->object_list = object; | |
1098 } | |
1099 | |
1100 object->type = (*buf) >> 6; | |
1101 | |
1102 display = av_mallocz(sizeof(DVBSubObjectDisplay)); | |
1103 | |
1104 display->object_id = object_id; | |
1105 display->region_id = region_id; | |
1106 | |
1107 display->x_pos = BE_16(buf) & 0xfff; | |
1108 buf += 2; | |
1109 display->y_pos = BE_16(buf) & 0xfff; | |
1110 buf += 2; | |
1111 | |
1112 if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) { | |
1113 display->fgcolour = *buf++; | |
1114 display->bgcolour = *buf++; | |
1115 } | |
1116 | |
1117 display->region_list_next = region->display_list; | |
1118 region->display_list = display; | |
1119 | |
1120 display->object_list_next = object->display_list; | |
1121 object->display_list = display; | |
1122 } | |
1123 } | |
1124 | |
1125 static void dvbsub_parse_page_segment(AVCodecContext *avctx, | |
1126 uint8_t *buf, int buf_size) | |
1127 { | |
1128 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
1129 DVBSubRegionDisplay *display; | |
1130 DVBSubRegionDisplay *tmp_display_list, **tmp_ptr; | |
1131 | |
1132 uint8_t *buf_end = buf + buf_size; | |
1133 int region_id; | |
1134 int page_state; | |
1135 | |
1136 if (buf_size < 1) | |
1137 return; | |
1138 | |
1139 ctx->time_out = *buf++; | |
1140 page_state = ((*buf++) >> 2) & 3; | |
1141 | |
1142 #ifdef DEBUG | |
1143 av_log(avctx, AV_LOG_INFO, "Page time out %ds, state %d\n", ctx->time_out, page_state); | |
1144 #endif | |
1145 | |
1146 if (page_state == 2) | |
1147 { | |
1148 delete_state(ctx); | |
1149 } | |
1150 | |
1151 tmp_display_list = ctx->display_list; | |
1152 ctx->display_list = NULL; | |
1153 ctx->display_list_size = 0; | |
1154 | |
1155 while (buf + 5 < buf_end) { | |
1156 region_id = *buf++; | |
1157 buf += 1; | |
1158 | |
1159 display = tmp_display_list; | |
1160 tmp_ptr = &tmp_display_list; | |
1161 | |
1162 while (display != NULL && display->region_id != region_id) { | |
1163 tmp_ptr = &display->next; | |
1164 display = display->next; | |
1165 } | |
1166 | |
1167 if (display == NULL) | |
1168 display = av_mallocz(sizeof(DVBSubRegionDisplay)); | |
1169 | |
1170 display->region_id = region_id; | |
1171 | |
1172 display->x_pos = BE_16(buf); | |
1173 buf += 2; | |
1174 display->y_pos = BE_16(buf); | |
1175 buf += 2; | |
1176 | |
1177 *tmp_ptr = display->next; | |
1178 | |
1179 display->next = ctx->display_list; | |
1180 ctx->display_list = display; | |
1181 ctx->display_list_size++; | |
1182 | |
1183 #ifdef DEBUG | |
1184 av_log(avctx, AV_LOG_INFO, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos); | |
1185 #endif | |
1186 } | |
1187 | |
1188 while (tmp_display_list != 0) { | |
1189 display = tmp_display_list; | |
1190 | |
1191 tmp_display_list = display->next; | |
1192 | |
1193 av_free(display); | |
1194 } | |
1195 | |
1196 } | |
1197 | |
1198 | |
1199 #ifdef DEBUG_SAVE_IMAGES | |
1200 static void save_display_set(DVBSubContext *ctx) | |
1201 { | |
1202 DVBSubRegion *region; | |
1203 DVBSubRegionDisplay *display; | |
1204 DVBSubCLUT *clut; | |
1205 uint32_t *clut_table; | |
1206 int x_pos, y_pos, width, height; | |
1207 int x, y, y_off, x_off; | |
1208 uint32_t *pbuf; | |
1209 char filename[32]; | |
1210 static int fileno_index = 0; | |
1211 | |
1212 x_pos = -1; | |
1213 y_pos = -1; | |
1214 width = 0; | |
1215 height = 0; | |
1216 | |
1217 for (display = ctx->display_list; display != NULL; display = display->next) { | |
1218 region = get_region(ctx, display->region_id); | |
1219 | |
1220 if (x_pos == -1) { | |
1221 x_pos = display->x_pos; | |
1222 y_pos = display->y_pos; | |
1223 width = region->width; | |
1224 height = region->height; | |
1225 } else { | |
1226 if (display->x_pos < x_pos) { | |
1227 width += (x_pos - display->x_pos); | |
1228 x_pos = display->x_pos; | |
1229 } | |
1230 | |
1231 if (display->y_pos < y_pos) { | |
1232 height += (y_pos - display->y_pos); | |
1233 y_pos = display->y_pos; | |
1234 } | |
1235 | |
1236 if (display->x_pos + region->width > x_pos + width) { | |
1237 width = display->x_pos + region->width - x_pos; | |
1238 } | |
1239 | |
1240 if (display->y_pos + region->height > y_pos + height) { | |
1241 height = display->y_pos + region->height - y_pos; | |
1242 } | |
1243 } | |
1244 } | |
1245 | |
1246 if (x_pos >= 0) { | |
1247 | |
1248 pbuf = av_malloc(width * height * 4); | |
1249 | |
1250 for (display = ctx->display_list; display != NULL; display = display->next) { | |
1251 region = get_region(ctx, display->region_id); | |
1252 | |
1253 x_off = display->x_pos - x_pos; | |
1254 y_off = display->y_pos - y_pos; | |
1255 | |
1256 clut = get_clut(ctx, region->clut); | |
1257 | |
1258 if (clut == 0) | |
1259 clut = &default_clut; | |
1260 | |
1261 switch (region->depth) { | |
1262 case 2: | |
1263 clut_table = clut->clut4; | |
1264 break; | |
1265 case 8: | |
1266 clut_table = clut->clut256; | |
1267 break; | |
1268 case 4: | |
1269 default: | |
1270 clut_table = clut->clut16; | |
1271 break; | |
1272 } | |
1273 | |
1274 for (y = 0; y < region->height; y++) { | |
1275 for (x = 0; x < region->width; x++) { | |
1276 pbuf[((y + y_off) * width) + x_off + x] = | |
1277 clut_table[region->pbuf[y * region->width + x]]; | |
1278 } | |
1279 } | |
1280 | |
1281 } | |
1282 | |
1283 snprintf(filename, 32, "dvbs.%d", fileno_index); | |
1284 | |
1285 png_save2(filename, pbuf, width, height); | |
1286 | |
1287 av_free(pbuf); | |
1288 } | |
1289 | |
1290 fileno_index++; | |
1291 } | |
1292 #endif | |
1293 | |
1294 static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf, | |
1295 int buf_size, AVSubtitle *sub) | |
1296 { | |
1297 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
1298 | |
1299 DVBSubRegion *region; | |
1300 DVBSubRegionDisplay *display; | |
1301 AVSubtitleRect *rect; | |
1302 DVBSubCLUT *clut; | |
1303 uint32_t *clut_table; | |
1304 int i; | |
1305 | |
1306 sub->rects = NULL; | |
1307 sub->start_display_time = 0; | |
1308 sub->end_display_time = ctx->time_out * 1000; | |
1309 sub->format = 0; | |
1310 | |
1311 sub->num_rects = ctx->display_list_size; | |
1312 | |
1313 if (sub->num_rects == 0) | |
1314 return 0; | |
1315 | |
1316 sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects); | |
1317 | |
1318 i = 0; | |
1319 | |
1320 for (display = ctx->display_list; display != NULL; display = display->next) { | |
1321 region = get_region(ctx, display->region_id); | |
1322 rect = &sub->rects[i]; | |
1323 | |
1324 if (region == NULL) | |
1325 continue; | |
1326 | |
1327 rect->x = display->x_pos; | |
1328 rect->y = display->y_pos; | |
1329 rect->w = region->width; | |
1330 rect->h = region->height; | |
1331 rect->nb_colors = 16; | |
1332 rect->linesize = region->width; | |
1333 | |
1334 clut = get_clut(ctx, region->clut); | |
1335 | |
1336 if (clut == NULL) | |
1337 clut = &default_clut; | |
1338 | |
1339 switch (region->depth) { | |
1340 case 2: | |
1341 clut_table = clut->clut4; | |
1342 break; | |
1343 case 8: | |
1344 clut_table = clut->clut256; | |
1345 break; | |
1346 case 4: | |
1347 default: | |
1348 clut_table = clut->clut16; | |
1349 break; | |
1350 } | |
1351 | |
1352 rect->rgba_palette = av_malloc((1 << region->depth) * sizeof(uint32_t)); | |
1353 memcpy(rect->rgba_palette, clut_table, (1 << region->depth) * sizeof(uint32_t)); | |
1354 | |
1355 rect->bitmap = av_malloc(region->buf_size); | |
1356 memcpy(rect->bitmap, region->pbuf, region->buf_size); | |
1357 | |
1358 i++; | |
1359 } | |
1360 | |
1361 sub->num_rects = i; | |
1362 | |
1363 #ifdef DEBUG_SAVE_IMAGES | |
1364 save_display_set(ctx); | |
1365 #endif | |
1366 | |
1367 return 1; | |
1368 } | |
1369 | |
1370 static int dvbsub_decode(AVCodecContext *avctx, | |
1371 void *data, int *data_size, | |
1372 uint8_t *buf, int buf_size) | |
1373 { | |
1374 DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; | |
1375 AVSubtitle *sub = (AVSubtitle*) data; | |
1376 uint8_t *p, *p_end; | |
1377 int segment_type; | |
1378 int page_id; | |
1379 int segment_length; | |
1380 | |
1381 #ifdef DEBUG_PACKET_CONTENTS | |
1382 int i; | |
1383 | |
1384 av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n"); | |
1385 | |
1386 for (i=0; i < buf_size; i++) | |
1387 { | |
1388 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); | |
1389 if (i % 16 == 15) | |
1390 av_log(avctx, AV_LOG_INFO, "\n"); | |
1391 } | |
1392 | |
1393 if (i % 16 != 0) | |
1394 av_log(avctx, AV_LOG_INFO, "\n"); | |
1395 | |
1396 #endif | |
1397 | |
1398 if (buf_size <= 2) | |
1399 return -1; | |
1400 | |
1401 p = buf; | |
1402 p_end = buf + buf_size; | |
1403 | |
1404 while (p < p_end && *p == 0x0f) | |
1405 { | |
1406 p += 1; | |
1407 segment_type = *p++; | |
1408 page_id = BE_16(p); | |
1409 p += 2; | |
1410 segment_length = BE_16(p); | |
1411 p += 2; | |
1412 | |
1413 if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) { | |
1414 switch (segment_type) { | |
1415 case DVBSUB_PAGE_SEGMENT: | |
1416 dvbsub_parse_page_segment(avctx, p, segment_length); | |
1417 break; | |
1418 case DVBSUB_REGION_SEGMENT: | |
1419 dvbsub_parse_region_segment(avctx, p, segment_length); | |
1420 break; | |
1421 case DVBSUB_CLUT_SEGMENT: | |
1422 dvbsub_parse_clut_segment(avctx, p, segment_length); | |
1423 break; | |
1424 case DVBSUB_OBJECT_SEGMENT: | |
1425 dvbsub_parse_object_segment(avctx, p, segment_length); | |
1426 break; | |
1427 case DVBSUB_DISPLAY_SEGMENT: | |
1428 *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub); | |
1429 break; | |
1430 default: | |
1431 #ifdef DEBUG | |
1432 av_log(avctx, AV_LOG_INFO, "Subtitling segment type 0x%x, page id %d, length %d\n", | |
1433 segment_type, page_id, segment_length); | |
1434 #endif | |
1435 break; | |
1436 } | |
1437 } | |
1438 | |
1439 p += segment_length; | |
1440 } | |
1441 | |
1442 if (p != p_end) | |
1443 { | |
1444 #ifdef DEBUG | |
1445 av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); | |
1446 #endif | |
1447 return -1; | |
1448 } | |
1449 | |
1450 return 0; | |
1451 } | |
1452 | |
1453 | |
1454 AVCodec dvbsub_decoder = { | |
1455 "dvbsub", | |
1456 CODEC_TYPE_SUBTITLE, | |
1457 CODEC_ID_DVB_SUBTITLE, | |
1458 sizeof(DVBSubContext), | |
1459 dvbsub_init_decoder, | |
1460 NULL, | |
1461 dvbsub_close_decoder, | |
1462 dvbsub_decode, | |
1463 }; | |
1464 | |
1465 /* Parser (mostly) copied from dvdsub.c */ | |
1466 | |
1467 #define PARSE_BUF_SIZE (65536) | |
1468 | |
1469 | |
1470 /* parser definition */ | |
1471 typedef struct DVBSubParseContext { | |
1472 uint8_t *packet_buf; | |
1473 int packet_start; | |
1474 int packet_index; | |
1475 int in_packet; | |
1476 } DVBSubParseContext; | |
1477 | |
1478 static int dvbsub_parse_init(AVCodecParserContext *s) | |
1479 { | |
1480 DVBSubParseContext *pc = s->priv_data; | |
1481 pc->packet_buf = av_malloc(PARSE_BUF_SIZE); | |
1482 | |
1483 return 0; | |
1484 } | |
1485 | |
1486 static int dvbsub_parse(AVCodecParserContext *s, | |
1487 AVCodecContext *avctx, | |
1488 uint8_t **poutbuf, int *poutbuf_size, | |
1489 const uint8_t *buf, int buf_size) | |
1490 { | |
1491 DVBSubParseContext *pc = s->priv_data; | |
1492 uint8_t *p, *p_end; | |
1493 int len, buf_pos = 0; | |
1494 | |
1495 #ifdef DEBUG | |
1496 av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%Lx, lpts=%Lx, cpts=%Lx:\n", | |
1497 s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]); | |
1498 #endif | |
1499 | |
1500 #ifdef DEBUG_PACKET_CONTENTS | |
1501 int i; | |
1502 | |
1503 for (i=0; i < buf_size; i++) | |
1504 { | |
1505 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); | |
1506 if (i % 16 == 15) | |
1507 av_log(avctx, AV_LOG_INFO, "\n"); | |
1508 } | |
1509 | |
1510 if (i % 16 != 0) | |
1511 av_log(avctx, AV_LOG_INFO, "\n"); | |
1512 | |
1513 #endif | |
1514 | |
1515 *poutbuf = NULL; | |
1516 *poutbuf_size = 0; | |
1517 | |
1518 s->fetch_timestamp = 1; | |
1519 | |
1520 if (s->last_pts != s->pts && s->last_pts != AV_NOPTS_VALUE) /* Start of a new packet */ | |
1521 { | |
1522 if (pc->packet_index != pc->packet_start) | |
1523 { | |
1524 #ifdef DEBUG | |
1525 av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n", | |
1526 pc->packet_index - pc->packet_start); | |
1527 #endif | |
1528 } | |
1529 | |
1530 pc->packet_start = 0; | |
1531 pc->packet_index = 0; | |
1532 | |
1533 if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) { | |
1534 #ifdef DEBUG | |
1535 av_log(avctx, AV_LOG_INFO, "Bad packet header\n"); | |
1536 #endif | |
1537 return -1; | |
1538 } | |
1539 | |
1540 buf_pos = 2; | |
1541 | |
1542 pc->in_packet = 1; | |
1543 } else { | |
1544 if (pc->packet_start != 0) | |
1545 { | |
1546 if (pc->packet_index != pc->packet_start) | |
1547 { | |
1548 memmove(pc->packet_buf, pc->packet_buf + pc->packet_start, | |
1549 pc->packet_index - pc->packet_start); | |
1550 | |
1551 pc->packet_index -= pc->packet_start; | |
1552 pc->packet_start = 0; | |
1553 } else { | |
1554 pc->packet_start = 0; | |
1555 pc->packet_index = 0; | |
1556 } | |
1557 } | |
1558 } | |
1559 | |
1560 if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE) | |
1561 return -1; | |
1562 | |
1563 /* if not currently in a packet, discard data */ | |
1564 if (pc->in_packet == 0) | |
1565 return buf_size; | |
1566 | |
1567 memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos); | |
1568 pc->packet_index += buf_size - buf_pos; | |
1569 | |
1570 p = pc->packet_buf; | |
1571 p_end = pc->packet_buf + pc->packet_index; | |
1572 | |
1573 while (p < p_end) | |
1574 { | |
1575 if (*p == 0x0f) | |
1576 { | |
1577 if (p + 6 <= p_end) | |
1578 { | |
1579 len = BE_16(p + 4); | |
1580 | |
1581 if (p + len + 6 <= p_end) | |
1582 { | |
1583 *poutbuf_size += len + 6; | |
1584 | |
1585 p += len + 6; | |
1586 } else | |
1587 break; | |
1588 } else | |
1589 break; | |
1590 } else if (*p == 0xff) { | |
1591 if (p + 1 < p_end) | |
1592 { | |
1593 #ifdef DEBUG | |
1594 av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); | |
1595 #endif | |
1596 } | |
1597 pc->packet_index = p - pc->packet_buf; | |
1598 pc->in_packet = 0; | |
1599 break; | |
1600 } else { | |
1601 av_log(avctx, AV_LOG_ERROR, "Junk in packet\n"); | |
1602 | |
1603 pc->packet_index = p - pc->packet_buf; | |
1604 pc->in_packet = 0; | |
1605 break; | |
1606 } | |
1607 } | |
1608 | |
1609 if (*poutbuf_size > 0) | |
1610 { | |
1611 *poutbuf = pc->packet_buf; | |
1612 pc->packet_start = *poutbuf_size; | |
1613 } | |
1614 | |
1615 if (s->last_pts == AV_NOPTS_VALUE) | |
1616 s->last_pts = s->pts; | |
1617 | |
1618 return buf_size; | |
1619 } | |
1620 | |
1621 static void dvbsub_parse_close(AVCodecParserContext *s) | |
1622 { | |
1623 DVBSubParseContext *pc = s->priv_data; | |
1624 av_freep(&pc->packet_buf); | |
1625 } | |
1626 | |
1627 AVCodecParser dvbsub_parser = { | |
1628 { CODEC_ID_DVB_SUBTITLE }, | |
1629 sizeof(DVBSubParseContext), | |
1630 dvbsub_parse_init, | |
1631 dvbsub_parse, | |
1632 dvbsub_parse_close, | |
1633 }; |