2 * DVB subtitle decoding for ffmpeg
3 * Copyright (c) 2005 Ian Caulfield.
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "bitstream.h"
24 #include "colorspace.h"
27 //#define DEBUG_PACKET_CONTENTS
28 //#define DEBUG_SAVE_IMAGES
30 #define DVBSUB_PAGE_SEGMENT 0x10
31 #define DVBSUB_REGION_SEGMENT 0x11
32 #define DVBSUB_CLUT_SEGMENT 0x12
33 #define DVBSUB_OBJECT_SEGMENT 0x13
34 #define DVBSUB_DISPLAY_SEGMENT 0x80
36 #define cm (ff_cropTbl + MAX_NEG_CROP)
38 #ifdef DEBUG_SAVE_IMAGES
41 static void png_save(const char *filename
, uint8_t *bitmap
, int w
, int h
,
42 uint32_t *rgba_palette
)
46 char fname
[40], fname2
[40];
49 snprintf(fname
, 40, "%s.ppm", filename
);
51 f
= fopen(fname
, "w");
60 for(y
= 0; y
< h
; y
++) {
61 for(x
= 0; x
< w
; x
++) {
62 v
= rgba_palette
[bitmap
[y
* w
+ x
]];
63 putc((v
>> 16) & 0xff, f
);
64 putc((v
>> 8) & 0xff, f
);
65 putc((v
>> 0) & 0xff, f
);
71 snprintf(fname2
, 40, "%s-a.pgm", filename
);
73 f
= fopen(fname2
, "w");
82 for(y
= 0; y
< h
; y
++) {
83 for(x
= 0; x
< w
; x
++) {
84 v
= rgba_palette
[bitmap
[y
* w
+ x
]];
85 putc((v
>> 24) & 0xff, f
);
90 snprintf(command
, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2
, fname
, filename
);
93 snprintf(command
, 1024, "rm %s %s", fname
, fname2
);
98 static void png_save2(const char *filename
, uint32_t *bitmap
, int w
, int h
)
102 char fname
[40], fname2
[40];
105 snprintf(fname
, sizeof(fname
), "%s.ppm", filename
);
107 f
= fopen(fname
, "w");
116 for(y
= 0; y
< h
; y
++) {
117 for(x
= 0; x
< w
; x
++) {
118 v
= bitmap
[y
* w
+ x
];
119 putc((v
>> 16) & 0xff, f
);
120 putc((v
>> 8) & 0xff, f
);
121 putc((v
>> 0) & 0xff, f
);
127 snprintf(fname2
, sizeof(fname2
), "%s-a.pgm", filename
);
129 f
= fopen(fname2
, "w");
138 for(y
= 0; y
< h
; y
++) {
139 for(x
= 0; x
< w
; x
++) {
140 v
= bitmap
[y
* w
+ x
];
141 putc((v
>> 24) & 0xff, f
);
146 snprintf(command
, sizeof(command
), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2
, fname
, filename
);
149 snprintf(command
, sizeof(command
), "rm %s %s", fname
, fname2
);
154 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
156 typedef struct DVBSubCLUT
{
161 uint32_t clut256
[256];
163 struct DVBSubCLUT
*next
;
166 static DVBSubCLUT default_clut
;
168 typedef struct DVBSubObjectDisplay
{
178 struct DVBSubObjectDisplay
*region_list_next
;
179 struct DVBSubObjectDisplay
*object_list_next
;
180 } DVBSubObjectDisplay
;
182 typedef struct DVBSubObject
{
187 DVBSubObjectDisplay
*display_list
;
189 struct DVBSubObject
*next
;
192 typedef struct DVBSubRegionDisplay
{
198 struct DVBSubRegionDisplay
*next
;
199 } DVBSubRegionDisplay
;
201 typedef struct DVBSubRegion
{
214 DVBSubObjectDisplay
*display_list
;
216 struct DVBSubRegion
*next
;
219 typedef struct DVBSubContext
{
224 DVBSubRegion
*region_list
;
225 DVBSubCLUT
*clut_list
;
226 DVBSubObject
*object_list
;
228 int display_list_size
;
229 DVBSubRegionDisplay
*display_list
;
233 static DVBSubObject
* get_object(DVBSubContext
*ctx
, int object_id
)
235 DVBSubObject
*ptr
= ctx
->object_list
;
237 while (ptr
&& ptr
->id
!= object_id
) {
244 static DVBSubCLUT
* get_clut(DVBSubContext
*ctx
, int clut_id
)
246 DVBSubCLUT
*ptr
= ctx
->clut_list
;
248 while (ptr
&& ptr
->id
!= clut_id
) {
255 static DVBSubRegion
* get_region(DVBSubContext
*ctx
, int region_id
)
257 DVBSubRegion
*ptr
= ctx
->region_list
;
259 while (ptr
&& ptr
->id
!= region_id
) {
266 static void delete_region_display_list(DVBSubContext
*ctx
, DVBSubRegion
*region
)
268 DVBSubObject
*object
, *obj2
, **obj2_ptr
;
269 DVBSubObjectDisplay
*display
, *obj_disp
, **obj_disp_ptr
;
271 while (region
->display_list
) {
272 display
= region
->display_list
;
274 object
= get_object(ctx
, display
->object_id
);
277 obj_disp
= object
->display_list
;
278 obj_disp_ptr
= &object
->display_list
;
280 while (obj_disp
&& obj_disp
!= display
) {
281 obj_disp_ptr
= &obj_disp
->object_list_next
;
282 obj_disp
= obj_disp
->object_list_next
;
286 *obj_disp_ptr
= obj_disp
->object_list_next
;
288 if (!object
->display_list
) {
289 obj2
= ctx
->object_list
;
290 obj2_ptr
= &ctx
->object_list
;
292 while (obj2
&& obj2
!= object
) {
293 obj2_ptr
= &obj2
->next
;
297 *obj2_ptr
= obj2
->next
;
304 region
->display_list
= display
->region_list_next
;
311 static void delete_state(DVBSubContext
*ctx
)
313 DVBSubRegion
*region
;
316 while (ctx
->region_list
) {
317 region
= ctx
->region_list
;
319 ctx
->region_list
= region
->next
;
321 delete_region_display_list(ctx
, region
);
323 av_free(region
->pbuf
);
328 while (ctx
->clut_list
) {
329 clut
= ctx
->clut_list
;
331 ctx
->clut_list
= clut
->next
;
336 /* Should already be null */
337 if (ctx
->object_list
)
338 av_log(0, AV_LOG_ERROR
, "Memory deallocation error!\n");
341 static int dvbsub_init_decoder(AVCodecContext
*avctx
)
343 int i
, r
, g
, b
, a
= 0;
344 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
346 memset(avctx
->priv_data
, 0, sizeof(DVBSubContext
));
348 ctx
->composition_id
= avctx
->sub_id
& 0xffff;
349 ctx
->ancillary_id
= avctx
->sub_id
>> 16;
351 default_clut
.id
= -1;
352 default_clut
.next
= NULL
;
354 default_clut
.clut4
[0] = RGBA( 0, 0, 0, 0);
355 default_clut
.clut4
[1] = RGBA(255, 255, 255, 255);
356 default_clut
.clut4
[2] = RGBA( 0, 0, 0, 255);
357 default_clut
.clut4
[3] = RGBA(127, 127, 127, 255);
359 default_clut
.clut16
[0] = RGBA( 0, 0, 0, 0);
360 for (i
= 1; i
< 16; i
++) {
362 r
= (i
& 1) ? 255 : 0;
363 g
= (i
& 2) ? 255 : 0;
364 b
= (i
& 4) ? 255 : 0;
366 r
= (i
& 1) ? 127 : 0;
367 g
= (i
& 2) ? 127 : 0;
368 b
= (i
& 4) ? 127 : 0;
370 default_clut
.clut16
[i
] = RGBA(r
, g
, b
, 255);
373 default_clut
.clut256
[0] = RGBA( 0, 0, 0, 0);
374 for (i
= 1; i
< 256; i
++) {
376 r
= (i
& 1) ? 255 : 0;
377 g
= (i
& 2) ? 255 : 0;
378 b
= (i
& 4) ? 255 : 0;
383 r
= ((i
& 1) ? 85 : 0) + ((i
& 0x10) ? 170 : 0);
384 g
= ((i
& 2) ? 85 : 0) + ((i
& 0x20) ? 170 : 0);
385 b
= ((i
& 4) ? 85 : 0) + ((i
& 0x40) ? 170 : 0);
389 r
= ((i
& 1) ? 85 : 0) + ((i
& 0x10) ? 170 : 0);
390 g
= ((i
& 2) ? 85 : 0) + ((i
& 0x20) ? 170 : 0);
391 b
= ((i
& 4) ? 85 : 0) + ((i
& 0x40) ? 170 : 0);
395 r
= 127 + ((i
& 1) ? 43 : 0) + ((i
& 0x10) ? 85 : 0);
396 g
= 127 + ((i
& 2) ? 43 : 0) + ((i
& 0x20) ? 85 : 0);
397 b
= 127 + ((i
& 4) ? 43 : 0) + ((i
& 0x40) ? 85 : 0);
401 r
= ((i
& 1) ? 43 : 0) + ((i
& 0x10) ? 85 : 0);
402 g
= ((i
& 2) ? 43 : 0) + ((i
& 0x20) ? 85 : 0);
403 b
= ((i
& 4) ? 43 : 0) + ((i
& 0x40) ? 85 : 0);
408 default_clut
.clut256
[i
] = RGBA(r
, g
, b
, a
);
414 static int dvbsub_close_decoder(AVCodecContext
*avctx
)
416 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
417 DVBSubRegionDisplay
*display
;
421 while (ctx
->display_list
) {
422 display
= ctx
->display_list
;
423 ctx
->display_list
= display
->next
;
431 static int dvbsub_read_2bit_string(uint8_t *destbuf
, int dbuf_len
,
432 uint8_t **srcbuf
, int buf_size
,
433 int non_mod
, uint8_t *map_table
)
441 init_get_bits(&gb
, *srcbuf
, buf_size
<< 8);
443 while (get_bits_count(&gb
) < (buf_size
<< 8) && pixels_read
< dbuf_len
) {
444 bits
= get_bits(&gb
, 2);
447 if (non_mod
!= 1 || bits
!= 1) {
449 *destbuf
++ = map_table
[bits
];
455 bits
= get_bits1(&gb
);
457 run_length
= get_bits(&gb
, 3) + 3;
458 bits
= get_bits(&gb
, 2);
460 if (non_mod
== 1 && bits
== 1)
461 pixels_read
+= run_length
;
464 bits
= map_table
[bits
];
465 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
471 bits
= get_bits1(&gb
);
473 bits
= get_bits(&gb
, 2);
475 run_length
= get_bits(&gb
, 4) + 12;
476 bits
= get_bits(&gb
, 2);
478 if (non_mod
== 1 && bits
== 1)
479 pixels_read
+= run_length
;
482 bits
= map_table
[bits
];
483 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
488 } else if (bits
== 3) {
489 run_length
= get_bits(&gb
, 8) + 29;
490 bits
= get_bits(&gb
, 2);
492 if (non_mod
== 1 && bits
== 1)
493 pixels_read
+= run_length
;
496 bits
= map_table
[bits
];
497 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
502 } else if (bits
== 1) {
508 if (pixels_read
<= dbuf_len
) {
513 (*srcbuf
) += (get_bits_count(&gb
) + 7) >> 3;
528 if (get_bits(&gb
, 6))
529 av_log(0, AV_LOG_ERROR
, "DVBSub error: line overflow\n");
531 (*srcbuf
) += (get_bits_count(&gb
) + 7) >> 3;
536 static int dvbsub_read_4bit_string(uint8_t *destbuf
, int dbuf_len
,
537 uint8_t **srcbuf
, int buf_size
,
538 int non_mod
, uint8_t *map_table
)
546 init_get_bits(&gb
, *srcbuf
, buf_size
<< 8);
548 while (get_bits_count(&gb
) < (buf_size
<< 8) && pixels_read
< dbuf_len
) {
549 bits
= get_bits(&gb
, 4);
552 if (non_mod
!= 1 || bits
!= 1) {
554 *destbuf
++ = map_table
[bits
];
560 bits
= get_bits1(&gb
);
562 run_length
= get_bits(&gb
, 3);
564 if (run_length
== 0) {
565 (*srcbuf
) += (get_bits_count(&gb
) + 7) >> 3;
576 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
581 bits
= get_bits1(&gb
);
583 run_length
= get_bits(&gb
, 2) + 4;
584 bits
= get_bits(&gb
, 4);
586 if (non_mod
== 1 && bits
== 1)
587 pixels_read
+= run_length
;
590 bits
= map_table
[bits
];
591 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
597 bits
= get_bits(&gb
, 2);
599 run_length
= get_bits(&gb
, 4) + 9;
600 bits
= get_bits(&gb
, 4);
602 if (non_mod
== 1 && bits
== 1)
603 pixels_read
+= run_length
;
606 bits
= map_table
[bits
];
607 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
612 } else if (bits
== 3) {
613 run_length
= get_bits(&gb
, 8) + 25;
614 bits
= get_bits(&gb
, 4);
616 if (non_mod
== 1 && bits
== 1)
617 pixels_read
+= run_length
;
620 bits
= map_table
[bits
];
621 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
626 } else if (bits
== 1) {
632 if (pixels_read
<= dbuf_len
) {
649 if (get_bits(&gb
, 8))
650 av_log(0, AV_LOG_ERROR
, "DVBSub error: line overflow\n");
652 (*srcbuf
) += (get_bits_count(&gb
) + 7) >> 3;
657 static int dvbsub_read_8bit_string(uint8_t *destbuf
, int dbuf_len
,
658 uint8_t **srcbuf
, int buf_size
,
659 int non_mod
, uint8_t *map_table
)
661 uint8_t *sbuf_end
= (*srcbuf
) + buf_size
;
666 while (*srcbuf
< sbuf_end
&& pixels_read
< dbuf_len
) {
670 if (non_mod
!= 1 || bits
!= 1) {
672 *destbuf
++ = map_table
[bits
];
679 run_length
= bits
& 0x7f;
680 if ((bits
& 0x80) == 0) {
681 if (run_length
== 0) {
689 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
696 if (non_mod
== 1 && bits
== 1)
697 pixels_read
+= run_length
;
699 bits
= map_table
[bits
];
700 else while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
709 av_log(0, AV_LOG_ERROR
, "DVBSub error: line overflow\n");
716 static void dvbsub_parse_pixel_data_block(AVCodecContext
*avctx
, DVBSubObjectDisplay
*display
,
717 uint8_t *buf
, int buf_size
, int top_bottom
, int non_mod
)
719 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
721 DVBSubRegion
*region
= get_region(ctx
, display
->region_id
);
722 uint8_t *buf_end
= buf
+ buf_size
;
727 uint8_t map2to4
[] = { 0x0, 0x7, 0x8, 0xf};
728 uint8_t map2to8
[] = {0x00, 0x77, 0x88, 0xff};
729 uint8_t map4to8
[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
730 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
734 av_log(avctx
, AV_LOG_INFO
, "DVB pixel block size %d, %s field:\n", buf_size
,
735 top_bottom
? "bottom" : "top");
738 #ifdef DEBUG_PACKET_CONTENTS
739 for (i
= 0; i
< buf_size
; i
++) {
741 av_log(avctx
, AV_LOG_INFO
, "0x%08p: ", buf
+i
);
743 av_log(avctx
, AV_LOG_INFO
, "%02x ", buf
[i
]);
745 av_log(avctx
, AV_LOG_INFO
, "\n");
749 av_log(avctx
, AV_LOG_INFO
, "\n");
758 x_pos
= display
->x_pos
;
759 y_pos
= display
->y_pos
;
761 if ((y_pos
& 1) != top_bottom
)
764 while (buf
< buf_end
) {
765 if (x_pos
> region
->width
|| y_pos
> region
->height
) {
766 av_log(avctx
, AV_LOG_ERROR
, "Invalid object location!\n");
772 if (region
->depth
== 8)
774 else if (region
->depth
== 4)
779 x_pos
+= dvbsub_read_2bit_string(pbuf
+ (y_pos
* region
->width
) + x_pos
,
780 region
->width
- x_pos
, &buf
, buf_size
,
784 if (region
->depth
< 4) {
785 av_log(avctx
, AV_LOG_ERROR
, "4-bit pixel string in %d-bit region!\n", region
->depth
);
789 if (region
->depth
== 8)
794 x_pos
+= dvbsub_read_4bit_string(pbuf
+ (y_pos
* region
->width
) + x_pos
,
795 region
->width
- x_pos
, &buf
, buf_size
,
799 if (region
->depth
< 8) {
800 av_log(avctx
, AV_LOG_ERROR
, "8-bit pixel string in %d-bit region!\n", region
->depth
);
804 x_pos
+= dvbsub_read_8bit_string(pbuf
+ (y_pos
* region
->width
) + x_pos
,
805 region
->width
- x_pos
, &buf
, buf_size
,
810 map2to4
[0] = (*buf
) >> 4;
811 map2to4
[1] = (*buf
++) & 0xf;
812 map2to4
[2] = (*buf
) >> 4;
813 map2to4
[3] = (*buf
++) & 0xf;
816 for (i
= 0; i
< 4; i
++)
820 for (i
= 0; i
< 16; i
++)
825 x_pos
= display
->x_pos
;
829 av_log(avctx
, AV_LOG_INFO
, "Unknown/unsupported pixel block 0x%x\n", *(buf
-1));
835 static void dvbsub_parse_object_segment(AVCodecContext
*avctx
,
836 uint8_t *buf
, int buf_size
)
838 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
840 uint8_t *buf_end
= buf
+ buf_size
;
843 DVBSubObject
*object
;
844 DVBSubObjectDisplay
*display
;
845 int top_field_len
, bottom_field_len
;
847 int coding_method
, non_modifying_color
;
849 object_id
= AV_RB16(buf
);
852 object
= get_object(ctx
, object_id
);
857 coding_method
= ((*buf
) >> 2) & 3;
858 non_modifying_color
= ((*buf
++) >> 1) & 1;
860 if (coding_method
== 0) {
861 top_field_len
= AV_RB16(buf
);
863 bottom_field_len
= AV_RB16(buf
);
866 if (buf
+ top_field_len
+ bottom_field_len
> buf_end
) {
867 av_log(avctx
, AV_LOG_ERROR
, "Field data size too large\n");
871 for (display
= object
->display_list
; display
; display
= display
->object_list_next
) {
874 dvbsub_parse_pixel_data_block(avctx
, display
, block
, top_field_len
, 0,
875 non_modifying_color
);
877 if (bottom_field_len
> 0)
878 block
= buf
+ top_field_len
;
880 bottom_field_len
= top_field_len
;
882 dvbsub_parse_pixel_data_block(avctx
, display
, block
, bottom_field_len
, 1,
883 non_modifying_color
);
886 /* } else if (coding_method == 1) {*/
889 av_log(avctx
, AV_LOG_ERROR
, "Unknown object coding %d\n", coding_method
);
894 static void dvbsub_parse_clut_segment(AVCodecContext
*avctx
,
895 uint8_t *buf
, int buf_size
)
897 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
899 uint8_t *buf_end
= buf
+ buf_size
;
902 int entry_id
, depth
, full_range
;
903 int y
, cr
, cb
, alpha
;
904 int r
, g
, b
, r_add
, g_add
, b_add
;
906 #ifdef DEBUG_PACKET_CONTENTS
909 av_log(avctx
, AV_LOG_INFO
, "DVB clut packet:\n");
911 for (i
=0; i
< buf_size
; i
++) {
912 av_log(avctx
, AV_LOG_INFO
, "%02x ", buf
[i
]);
914 av_log(avctx
, AV_LOG_INFO
, "\n");
918 av_log(avctx
, AV_LOG_INFO
, "\n");
925 clut
= get_clut(ctx
, clut_id
);
928 clut
= av_malloc(sizeof(DVBSubCLUT
));
930 memcpy(clut
, &default_clut
, sizeof(DVBSubCLUT
));
934 clut
->next
= ctx
->clut_list
;
935 ctx
->clut_list
= clut
;
938 while (buf
+ 4 < buf_end
) {
941 depth
= (*buf
) & 0xe0;
944 av_log(avctx
, AV_LOG_ERROR
, "Invalid clut depth 0x%x!\n", *buf
);
948 full_range
= (*buf
++) & 1;
957 cr
= (((buf
[0] & 3) << 2) | ((buf
[1] >> 6) & 3)) << 4;
958 cb
= (buf
[1] << 2) & 0xf0;
959 alpha
= (buf
[1] << 6) & 0xc0;
967 YUV_TO_RGB1_CCIR(cb
, cr
);
968 YUV_TO_RGB2_CCIR(r
, g
, b
, y
);
971 av_log(avctx
, AV_LOG_INFO
, "clut %d := (%d,%d,%d,%d)\n", entry_id
, r
, g
, b
, alpha
);
975 clut
->clut4
[entry_id
] = RGBA(r
,g
,b
,255 - alpha
);
977 clut
->clut16
[entry_id
] = RGBA(r
,g
,b
,255 - alpha
);
979 clut
->clut256
[entry_id
] = RGBA(r
,g
,b
,255 - alpha
);
984 static void dvbsub_parse_region_segment(AVCodecContext
*avctx
,
985 uint8_t *buf
, int buf_size
)
987 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
989 uint8_t *buf_end
= buf
+ buf_size
;
990 int region_id
, object_id
;
991 DVBSubRegion
*region
;
992 DVBSubObject
*object
;
993 DVBSubObjectDisplay
*display
;
1001 region
= get_region(ctx
, region_id
);
1004 region
= av_mallocz(sizeof(DVBSubRegion
));
1006 region
->id
= region_id
;
1008 region
->next
= ctx
->region_list
;
1009 ctx
->region_list
= region
;
1012 fill
= ((*buf
++) >> 3) & 1;
1014 region
->width
= AV_RB16(buf
);
1016 region
->height
= AV_RB16(buf
);
1019 if (region
->width
* region
->height
!= region
->buf_size
) {
1021 av_free(region
->pbuf
);
1023 region
->buf_size
= region
->width
* region
->height
;
1025 region
->pbuf
= av_malloc(region
->buf_size
);
1030 region
->depth
= 1 << (((*buf
++) >> 2) & 7);
1031 if(region
->depth
<2 || region
->depth
>8){
1032 av_log(avctx
, AV_LOG_ERROR
, "region depth %d is invalid\n", region
->depth
);
1035 region
->clut
= *buf
++;
1037 if (region
->depth
== 8)
1038 region
->bgcolor
= *buf
++;
1042 if (region
->depth
== 4)
1043 region
->bgcolor
= (((*buf
++) >> 4) & 15);
1045 region
->bgcolor
= (((*buf
++) >> 2) & 3);
1049 av_log(avctx
, AV_LOG_INFO
, "Region %d, (%dx%d)\n", region_id
, region
->width
, region
->height
);
1053 memset(region
->pbuf
, region
->bgcolor
, region
->buf_size
);
1055 av_log(avctx
, AV_LOG_INFO
, "Fill region (%d)\n", region
->bgcolor
);
1059 delete_region_display_list(ctx
, region
);
1061 while (buf
+ 5 < buf_end
) {
1062 object_id
= AV_RB16(buf
);
1065 object
= get_object(ctx
, object_id
);
1068 object
= av_mallocz(sizeof(DVBSubObject
));
1070 object
->id
= object_id
;
1071 object
->next
= ctx
->object_list
;
1072 ctx
->object_list
= object
;
1075 object
->type
= (*buf
) >> 6;
1077 display
= av_mallocz(sizeof(DVBSubObjectDisplay
));
1079 display
->object_id
= object_id
;
1080 display
->region_id
= region_id
;
1082 display
->x_pos
= AV_RB16(buf
) & 0xfff;
1084 display
->y_pos
= AV_RB16(buf
) & 0xfff;
1087 if ((object
->type
== 1 || object
->type
== 2) && buf
+1 < buf_end
) {
1088 display
->fgcolor
= *buf
++;
1089 display
->bgcolor
= *buf
++;
1092 display
->region_list_next
= region
->display_list
;
1093 region
->display_list
= display
;
1095 display
->object_list_next
= object
->display_list
;
1096 object
->display_list
= display
;
1100 static void dvbsub_parse_page_segment(AVCodecContext
*avctx
,
1101 uint8_t *buf
, int buf_size
)
1103 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
1104 DVBSubRegionDisplay
*display
;
1105 DVBSubRegionDisplay
*tmp_display_list
, **tmp_ptr
;
1107 uint8_t *buf_end
= buf
+ buf_size
;
1114 ctx
->time_out
= *buf
++;
1115 page_state
= ((*buf
++) >> 2) & 3;
1118 av_log(avctx
, AV_LOG_INFO
, "Page time out %ds, state %d\n", ctx
->time_out
, page_state
);
1121 if (page_state
== 2) {
1125 tmp_display_list
= ctx
->display_list
;
1126 ctx
->display_list
= NULL
;
1127 ctx
->display_list_size
= 0;
1129 while (buf
+ 5 < buf_end
) {
1133 display
= tmp_display_list
;
1134 tmp_ptr
= &tmp_display_list
;
1136 while (display
&& display
->region_id
!= region_id
) {
1137 tmp_ptr
= &display
->next
;
1138 display
= display
->next
;
1142 display
= av_mallocz(sizeof(DVBSubRegionDisplay
));
1144 display
->region_id
= region_id
;
1146 display
->x_pos
= AV_RB16(buf
);
1148 display
->y_pos
= AV_RB16(buf
);
1151 *tmp_ptr
= display
->next
;
1153 display
->next
= ctx
->display_list
;
1154 ctx
->display_list
= display
;
1155 ctx
->display_list_size
++;
1158 av_log(avctx
, AV_LOG_INFO
, "Region %d, (%d,%d)\n", region_id
, display
->x_pos
, display
->y_pos
);
1162 while (tmp_display_list
) {
1163 display
= tmp_display_list
;
1165 tmp_display_list
= display
->next
;
1173 #ifdef DEBUG_SAVE_IMAGES
1174 static void save_display_set(DVBSubContext
*ctx
)
1176 DVBSubRegion
*region
;
1177 DVBSubRegionDisplay
*display
;
1179 uint32_t *clut_table
;
1180 int x_pos
, y_pos
, width
, height
;
1181 int x
, y
, y_off
, x_off
;
1184 static int fileno_index
= 0;
1191 for (display
= ctx
->display_list
; display
; display
= display
->next
) {
1192 region
= get_region(ctx
, display
->region_id
);
1195 x_pos
= display
->x_pos
;
1196 y_pos
= display
->y_pos
;
1197 width
= region
->width
;
1198 height
= region
->height
;
1200 if (display
->x_pos
< x_pos
) {
1201 width
+= (x_pos
- display
->x_pos
);
1202 x_pos
= display
->x_pos
;
1205 if (display
->y_pos
< y_pos
) {
1206 height
+= (y_pos
- display
->y_pos
);
1207 y_pos
= display
->y_pos
;
1210 if (display
->x_pos
+ region
->width
> x_pos
+ width
) {
1211 width
= display
->x_pos
+ region
->width
- x_pos
;
1214 if (display
->y_pos
+ region
->height
> y_pos
+ height
) {
1215 height
= display
->y_pos
+ region
->height
- y_pos
;
1222 pbuf
= av_malloc(width
* height
* 4);
1224 for (display
= ctx
->display_list
; display
; display
= display
->next
) {
1225 region
= get_region(ctx
, display
->region_id
);
1227 x_off
= display
->x_pos
- x_pos
;
1228 y_off
= display
->y_pos
- y_pos
;
1230 clut
= get_clut(ctx
, region
->clut
);
1233 clut
= &default_clut
;
1235 switch (region
->depth
) {
1237 clut_table
= clut
->clut4
;
1240 clut_table
= clut
->clut256
;
1244 clut_table
= clut
->clut16
;
1248 for (y
= 0; y
< region
->height
; y
++) {
1249 for (x
= 0; x
< region
->width
; x
++) {
1250 pbuf
[((y
+ y_off
) * width
) + x_off
+ x
] =
1251 clut_table
[region
->pbuf
[y
* region
->width
+ x
]];
1257 snprintf(filename
, sizeof(filename
), "dvbs.%d", fileno_index
);
1259 png_save2(filename
, pbuf
, width
, height
);
1268 static int dvbsub_display_end_segment(AVCodecContext
*avctx
, uint8_t *buf
,
1269 int buf_size
, AVSubtitle
*sub
)
1271 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
1273 DVBSubRegion
*region
;
1274 DVBSubRegionDisplay
*display
;
1275 AVSubtitleRect
*rect
;
1277 uint32_t *clut_table
;
1281 sub
->start_display_time
= 0;
1282 sub
->end_display_time
= ctx
->time_out
* 1000;
1285 sub
->num_rects
= ctx
->display_list_size
;
1287 if (sub
->num_rects
> 0)
1288 sub
->rects
= av_mallocz(sizeof(AVSubtitleRect
) * sub
->num_rects
);
1292 for (display
= ctx
->display_list
; display
; display
= display
->next
) {
1293 region
= get_region(ctx
, display
->region_id
);
1294 rect
= &sub
->rects
[i
];
1299 rect
->x
= display
->x_pos
;
1300 rect
->y
= display
->y_pos
;
1301 rect
->w
= region
->width
;
1302 rect
->h
= region
->height
;
1303 rect
->nb_colors
= 16;
1304 rect
->linesize
= region
->width
;
1306 clut
= get_clut(ctx
, region
->clut
);
1309 clut
= &default_clut
;
1311 switch (region
->depth
) {
1313 clut_table
= clut
->clut4
;
1316 clut_table
= clut
->clut256
;
1320 clut_table
= clut
->clut16
;
1324 rect
->rgba_palette
= av_malloc((1 << region
->depth
) * sizeof(uint32_t));
1325 memcpy(rect
->rgba_palette
, clut_table
, (1 << region
->depth
) * sizeof(uint32_t));
1327 rect
->bitmap
= av_malloc(region
->buf_size
);
1328 memcpy(rect
->bitmap
, region
->pbuf
, region
->buf_size
);
1335 #ifdef DEBUG_SAVE_IMAGES
1336 save_display_set(ctx
);
1342 static int dvbsub_decode(AVCodecContext
*avctx
,
1343 void *data
, int *data_size
,
1344 uint8_t *buf
, int buf_size
)
1346 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
1347 AVSubtitle
*sub
= (AVSubtitle
*) data
;
1353 #ifdef DEBUG_PACKET_CONTENTS
1356 av_log(avctx
, AV_LOG_INFO
, "DVB sub packet:\n");
1358 for (i
=0; i
< buf_size
; i
++) {
1359 av_log(avctx
, AV_LOG_INFO
, "%02x ", buf
[i
]);
1361 av_log(avctx
, AV_LOG_INFO
, "\n");
1365 av_log(avctx
, AV_LOG_INFO
, "\n");
1373 p_end
= buf
+ buf_size
;
1375 while (p
< p_end
&& *p
== 0x0f) {
1377 segment_type
= *p
++;
1378 page_id
= AV_RB16(p
);
1380 segment_length
= AV_RB16(p
);
1383 if (page_id
== ctx
->composition_id
|| page_id
== ctx
->ancillary_id
) {
1384 switch (segment_type
) {
1385 case DVBSUB_PAGE_SEGMENT
:
1386 dvbsub_parse_page_segment(avctx
, p
, segment_length
);
1388 case DVBSUB_REGION_SEGMENT
:
1389 dvbsub_parse_region_segment(avctx
, p
, segment_length
);
1391 case DVBSUB_CLUT_SEGMENT
:
1392 dvbsub_parse_clut_segment(avctx
, p
, segment_length
);
1394 case DVBSUB_OBJECT_SEGMENT
:
1395 dvbsub_parse_object_segment(avctx
, p
, segment_length
);
1397 case DVBSUB_DISPLAY_SEGMENT
:
1398 *data_size
= dvbsub_display_end_segment(avctx
, p
, segment_length
, sub
);
1402 av_log(avctx
, AV_LOG_INFO
, "Subtitling segment type 0x%x, page id %d, length %d\n",
1403 segment_type
, page_id
, segment_length
);
1409 p
+= segment_length
;
1414 av_log(avctx
, AV_LOG_INFO
, "Junk at end of packet\n");
1423 AVCodec dvbsub_decoder
= {
1425 CODEC_TYPE_SUBTITLE
,
1426 CODEC_ID_DVB_SUBTITLE
,
1427 sizeof(DVBSubContext
),
1428 dvbsub_init_decoder
,
1430 dvbsub_close_decoder
,