2 * DVB subtitle decoding for ffmpeg
3 * Copyright (c) 2005 Ian Caulfield.
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.
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.
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
21 #include "bitstream.h"
24 //#define DEBUG_PACKET_CONTENTS
25 //#define DEBUG_SAVE_IMAGES
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
33 static unsigned char *cm
;
35 #ifdef DEBUG_SAVE_IMAGES
38 static void png_save(const char *filename
, uint8_t *bitmap
, int w
, int h
,
39 uint32_t *rgba_palette
)
43 char fname
[40], fname2
[40];
46 snprintf(fname
, 40, "%s.ppm", filename
);
48 f
= fopen(fname
, "w");
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
);
68 snprintf(fname2
, 40, "%s-a.pgm", filename
);
70 f
= fopen(fname2
, "w");
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
);
87 snprintf(command
, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2
, fname
, filename
);
90 snprintf(command
, 1024, "rm %s %s", fname
, fname2
);
95 static void png_save2(const char *filename
, uint32_t *bitmap
, int w
, int h
)
99 char fname
[40], fname2
[40];
102 snprintf(fname
, 40, "%s.ppm", filename
);
104 f
= fopen(fname
, "w");
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
);
124 snprintf(fname2
, 40, "%s-a.pgm", filename
);
126 f
= fopen(fname2
, "w");
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
);
143 snprintf(command
, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2
, fname
, filename
);
146 snprintf(command
, 1024, "rm %s %s", fname
, fname2
);
151 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
153 typedef struct DVBSubCLUT
{
158 uint32_t clut256
[256];
160 struct DVBSubCLUT
*next
;
163 static DVBSubCLUT default_clut
;
165 typedef struct DVBSubObjectDisplay
{
175 struct DVBSubObjectDisplay
*region_list_next
;
176 struct DVBSubObjectDisplay
*object_list_next
;
177 } DVBSubObjectDisplay
;
179 typedef struct DVBSubObject
{
184 DVBSubObjectDisplay
*display_list
;
186 struct DVBSubObject
*next
;
189 typedef struct DVBSubRegionDisplay
{
195 struct DVBSubRegionDisplay
*next
;
196 } DVBSubRegionDisplay
;
198 typedef struct DVBSubRegion
{
211 DVBSubObjectDisplay
*display_list
;
213 struct DVBSubRegion
*next
;
216 typedef struct DVBSubContext
{
221 DVBSubRegion
*region_list
;
222 DVBSubCLUT
*clut_list
;
223 DVBSubObject
*object_list
;
225 int display_list_size
;
226 DVBSubRegionDisplay
*display_list
;
230 static DVBSubObject
* get_object(DVBSubContext
*ctx
, int object_id
)
232 DVBSubObject
*ptr
= ctx
->object_list
;
234 while (ptr
!= NULL
&& ptr
->id
!= object_id
) {
241 static DVBSubCLUT
* get_clut(DVBSubContext
*ctx
, int clut_id
)
243 DVBSubCLUT
*ptr
= ctx
->clut_list
;
245 while (ptr
!= NULL
&& ptr
->id
!= clut_id
) {
252 static DVBSubRegion
* get_region(DVBSubContext
*ctx
, int region_id
)
254 DVBSubRegion
*ptr
= ctx
->region_list
;
256 while (ptr
!= NULL
&& ptr
->id
!= region_id
) {
263 static void delete_region_display_list(DVBSubContext
*ctx
, DVBSubRegion
*region
)
265 DVBSubObject
*object
, *obj2
, **obj2_ptr
;
266 DVBSubObjectDisplay
*display
, *obj_disp
, **obj_disp_ptr
;
268 while (region
->display_list
!= NULL
) {
269 display
= region
->display_list
;
271 object
= get_object(ctx
, display
->object_id
);
273 if (object
!= NULL
) {
274 obj_disp
= object
->display_list
;
275 obj_disp_ptr
= &object
->display_list
;
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
;
283 *obj_disp_ptr
= obj_disp
->object_list_next
;
285 if (object
->display_list
== NULL
) {
286 obj2
= ctx
->object_list
;
287 obj2_ptr
= &ctx
->object_list
;
289 while (obj2
!= NULL
&& obj2
!= object
) {
290 obj2_ptr
= &obj2
->next
;
294 *obj2_ptr
= obj2
->next
;
301 region
->display_list
= display
->region_list_next
;
308 static void delete_state(DVBSubContext
*ctx
)
310 DVBSubRegion
*region
;
313 while (ctx
->region_list
!= NULL
)
315 region
= ctx
->region_list
;
317 ctx
->region_list
= region
->next
;
319 delete_region_display_list(ctx
, region
);
320 if (region
->pbuf
!= NULL
)
321 av_free(region
->pbuf
);
326 while (ctx
->clut_list
!= NULL
)
328 clut
= ctx
->clut_list
;
330 ctx
->clut_list
= clut
->next
;
335 /* Should already be null */
336 if (ctx
->object_list
!= NULL
)
337 av_log(0, AV_LOG_ERROR
, "Memory deallocation error!\n");
340 static int dvbsub_init_decoder(AVCodecContext
*avctx
)
342 int i
, r
, g
, b
, a
= 0;
343 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
345 cm
= cropTbl
+ MAX_NEG_CROP
;
347 memset(avctx
->priv_data
, 0, sizeof(DVBSubContext
));
349 ctx
->composition_id
= avctx
->sub_id
& 0xffff;
350 ctx
->ancillary_id
= avctx
->sub_id
>> 16;
352 default_clut
.id
= -1;
353 default_clut
.next
= NULL
;
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);
360 default_clut
.clut16
[0] = RGBA( 0, 0, 0, 0);
361 for (i
= 1; i
< 16; i
++) {
363 r
= (i
& 1) ? 255 : 0;
364 g
= (i
& 2) ? 255 : 0;
365 b
= (i
& 4) ? 255 : 0;
367 r
= (i
& 1) ? 127 : 0;
368 g
= (i
& 2) ? 127 : 0;
369 b
= (i
& 4) ? 127 : 0;
371 default_clut
.clut16
[i
] = RGBA(r
, g
, b
, 255);
374 default_clut
.clut256
[0] = RGBA( 0, 0, 0, 0);
375 for (i
= 1; i
< 256; i
++) {
377 r
= (i
& 1) ? 255 : 0;
378 g
= (i
& 2) ? 255 : 0;
379 b
= (i
& 4) ? 255 : 0;
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);
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);
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);
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);
409 default_clut
.clut256
[i
] = RGBA(r
, g
, b
, a
);
415 static int dvbsub_close_decoder(AVCodecContext
*avctx
)
417 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
418 DVBSubRegionDisplay
*display
;
422 while (ctx
->display_list
!= NULL
)
424 display
= ctx
->display_list
;
425 ctx
->display_list
= display
->next
;
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
)
443 init_get_bits(&gb
, *srcbuf
, buf_size
<< 8);
445 while (get_bits_count(&gb
) < (buf_size
<< 8) && pixels_read
< dbuf_len
) {
446 bits
= get_bits(&gb
, 2);
449 if (non_mod
!= 1 || bits
!= 1) {
450 if (map_table
!= NULL
)
451 *destbuf
++ = map_table
[bits
];
457 bits
= get_bits(&gb
, 1);
459 run_length
= get_bits(&gb
, 3) + 3;
460 bits
= get_bits(&gb
, 2);
462 if (non_mod
== 1 && bits
== 1)
463 pixels_read
+= run_length
;
465 if (map_table
!= NULL
)
466 bits
= map_table
[bits
];
467 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
473 bits
= get_bits(&gb
, 1);
475 bits
= get_bits(&gb
, 2);
477 run_length
= get_bits(&gb
, 4) + 12;
478 bits
= get_bits(&gb
, 2);
480 if (non_mod
== 1 && bits
== 1)
481 pixels_read
+= run_length
;
483 if (map_table
!= NULL
)
484 bits
= map_table
[bits
];
485 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
490 } else if (bits
== 3) {
491 run_length
= get_bits(&gb
, 8) + 29;
492 bits
= get_bits(&gb
, 2);
494 if (non_mod
== 1 && bits
== 1)
495 pixels_read
+= run_length
;
497 if (map_table
!= NULL
)
498 bits
= map_table
[bits
];
499 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
504 } else if (bits
== 1) {
506 if (map_table
!= NULL
)
510 if (pixels_read
<= dbuf_len
) {
515 (*srcbuf
) += (get_bits_count(&gb
) + 7) >> 3;
519 if (map_table
!= NULL
)
530 if (get_bits(&gb
, 6) != 0)
531 av_log(0, AV_LOG_ERROR
, "DVBSub error: line overflow\n");
533 (*srcbuf
) += (get_bits_count(&gb
) + 7) >> 3;
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
)
548 init_get_bits(&gb
, *srcbuf
, buf_size
<< 8);
550 while (get_bits_count(&gb
) < (buf_size
<< 8) && pixels_read
< dbuf_len
) {
551 bits
= get_bits(&gb
, 4);
554 if (non_mod
!= 1 || bits
!= 1) {
555 if (map_table
!= NULL
)
556 *destbuf
++ = map_table
[bits
];
562 bits
= get_bits(&gb
, 1);
564 run_length
= get_bits(&gb
, 3);
566 if (run_length
== 0) {
567 (*srcbuf
) += (get_bits_count(&gb
) + 7) >> 3;
573 if (map_table
!= NULL
)
578 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
583 bits
= get_bits(&gb
, 1);
585 run_length
= get_bits(&gb
, 2) + 4;
586 bits
= get_bits(&gb
, 4);
588 if (non_mod
== 1 && bits
== 1)
589 pixels_read
+= run_length
;
591 if (map_table
!= NULL
)
592 bits
= map_table
[bits
];
593 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
599 bits
= get_bits(&gb
, 2);
601 run_length
= get_bits(&gb
, 4) + 9;
602 bits
= get_bits(&gb
, 4);
604 if (non_mod
== 1 && bits
== 1)
605 pixels_read
+= run_length
;
607 if (map_table
!= NULL
)
608 bits
= map_table
[bits
];
609 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
614 } else if (bits
== 3) {
615 run_length
= get_bits(&gb
, 8) + 25;
616 bits
= get_bits(&gb
, 4);
618 if (non_mod
== 1 && bits
== 1)
619 pixels_read
+= run_length
;
621 if (map_table
!= NULL
)
622 bits
= map_table
[bits
];
623 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
628 } else if (bits
== 1) {
630 if (map_table
!= NULL
)
634 if (pixels_read
<= dbuf_len
) {
639 if (map_table
!= NULL
)
651 if (get_bits(&gb
, 8) != 0)
652 av_log(0, AV_LOG_ERROR
, "DVBSub error: line overflow\n");
654 (*srcbuf
) += (get_bits_count(&gb
) + 7) >> 3;
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
)
663 uint8_t *sbuf_end
= (*srcbuf
) + buf_size
;
668 while (*srcbuf
< sbuf_end
&& pixels_read
< dbuf_len
) {
672 if (non_mod
!= 1 || bits
!= 1) {
673 if (map_table
!= NULL
)
674 *destbuf
++ = map_table
[bits
];
681 run_length
= bits
& 0x7f;
682 if ((bits
& 0x80) == 0) {
683 if (run_length
== 0) {
687 if (map_table
!= NULL
)
691 while (run_length
-- > 0 && pixels_read
< dbuf_len
) {
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
) {
710 if (*(*srcbuf
)++ != 0)
711 av_log(0, AV_LOG_ERROR
, "DVBSub error: line overflow\n");
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
)
721 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
723 DVBSubRegion
*region
= get_region(ctx
, display
->region_id
);
724 uint8_t *buf_end
= buf
+ buf_size
;
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};
736 av_log(avctx
, AV_LOG_INFO
, "DVB pixel block size %d, %s field:\n", buf_size
,
737 top_bottom
? "bottom" : "top");
740 #ifdef DEBUG_PACKET_CONTENTS
741 for (i
= 0; i
< buf_size
; i
++)
744 av_log(avctx
, AV_LOG_INFO
, "0x%08p: ", buf
+i
);
746 av_log(avctx
, AV_LOG_INFO
, "%02x ", buf
[i
]);
748 av_log(avctx
, AV_LOG_INFO
, "\n");
752 av_log(avctx
, AV_LOG_INFO
, "\n");
761 x_pos
= display
->x_pos
;
762 y_pos
= display
->y_pos
;
764 if ((y_pos
& 1) != top_bottom
)
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");
775 if (region
->depth
== 8)
777 else if (region
->depth
== 4)
782 x_pos
+= dvbsub_read_2bit_string(pbuf
+ (y_pos
* region
->width
) + x_pos
,
783 region
->width
- x_pos
, &buf
, buf_size
,
787 if (region
->depth
< 4) {
788 av_log(avctx
, AV_LOG_ERROR
, "4-bit pixel string in %d-bit region!\n", region
->depth
);
792 if (region
->depth
== 8)
797 x_pos
+= dvbsub_read_4bit_string(pbuf
+ (y_pos
* region
->width
) + x_pos
,
798 region
->width
- x_pos
, &buf
, buf_size
,
802 if (region
->depth
< 8) {
803 av_log(avctx
, AV_LOG_ERROR
, "8-bit pixel string in %d-bit region!\n", region
->depth
);
807 x_pos
+= dvbsub_read_8bit_string(pbuf
+ (y_pos
* region
->width
) + x_pos
,
808 region
->width
- x_pos
, &buf
, buf_size
,
813 map2to4
[0] = (*buf
) >> 4;
814 map2to4
[1] = (*buf
++) & 0xf;
815 map2to4
[2] = (*buf
) >> 4;
816 map2to4
[3] = (*buf
++) & 0xf;
819 for (i
= 0; i
< 4; i
++)
823 for (i
= 0; i
< 16; i
++)
828 x_pos
= display
->x_pos
;
832 av_log(avctx
, AV_LOG_INFO
, "Unknown/unsupported pixel block 0x%x\n", *(buf
-1));
838 static void dvbsub_parse_object_segment(AVCodecContext
*avctx
,
839 uint8_t *buf
, int buf_size
)
841 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
843 uint8_t *buf_end
= buf
+ buf_size
;
846 DVBSubObject
*object
;
847 DVBSubObjectDisplay
*display
;
848 int top_field_len
, bottom_field_len
;
850 int coding_method
, non_modifying_colour
;
852 object_id
= BE_16(buf
);
855 object
= get_object(ctx
, object_id
);
860 coding_method
= ((*buf
) >> 2) & 3;
861 non_modifying_colour
= ((*buf
++) >> 1) & 1;
863 if (coding_method
== 0) {
864 top_field_len
= BE_16(buf
);
866 bottom_field_len
= BE_16(buf
);
869 if (buf
+ top_field_len
+ bottom_field_len
> buf_end
) {
870 av_log(avctx
, AV_LOG_ERROR
, "Field data size too large\n");
874 for (display
= object
->display_list
; display
!= 0; display
= display
->object_list_next
) {
877 dvbsub_parse_pixel_data_block(avctx
, display
, block
, top_field_len
, 0,
878 non_modifying_colour
);
880 if (bottom_field_len
> 0)
881 block
= buf
+ top_field_len
;
883 bottom_field_len
= top_field_len
;
885 dvbsub_parse_pixel_data_block(avctx
, display
, block
, bottom_field_len
, 1,
886 non_modifying_colour
);
889 /* } else if (coding_method == 1) {*/
892 av_log(avctx
, AV_LOG_ERROR
, "Unknown object coding %d\n", coding_method
);
898 #define ONE_HALF (1 << (SCALEBITS - 1))
899 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
901 #define YUV_TO_RGB1_CCIR(cb1, cr1)\
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 + \
908 b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\
911 #define YUV_TO_RGB2_CCIR(r, g, b, y1)\
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];\
920 static void dvbsub_parse_clut_segment(AVCodecContext
*avctx
,
921 uint8_t *buf
, int buf_size
)
923 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
925 uint8_t *buf_end
= buf
+ buf_size
;
928 int entry_id
, depth
, full_range
;
929 int y
, cr
, cb
, alpha
;
930 int r
, g
, b
, r_add
, g_add
, b_add
;
932 #ifdef DEBUG_PACKET_CONTENTS
935 av_log(avctx
, AV_LOG_INFO
, "DVB clut packet:\n");
937 for (i
=0; i
< buf_size
; i
++)
939 av_log(avctx
, AV_LOG_INFO
, "%02x ", buf
[i
]);
941 av_log(avctx
, AV_LOG_INFO
, "\n");
945 av_log(avctx
, AV_LOG_INFO
, "\n");
952 clut
= get_clut(ctx
, clut_id
);
955 clut
= av_malloc(sizeof(DVBSubCLUT
));
957 memcpy(clut
, &default_clut
, sizeof(DVBSubCLUT
));
961 clut
->next
= ctx
->clut_list
;
962 ctx
->clut_list
= clut
;
965 while (buf
+ 4 < buf_end
)
969 depth
= (*buf
) & 0xe0;
972 av_log(avctx
, AV_LOG_ERROR
, "Invalid clut depth 0x%x!\n", *buf
);
976 full_range
= (*buf
++) & 1;
985 cr
= (((buf
[0] & 3) << 2) | ((buf
[1] >> 6) & 3)) << 4;
986 cb
= (buf
[1] << 2) & 0xf0;
987 alpha
= (buf
[1] << 6) & 0xc0;
995 YUV_TO_RGB1_CCIR(cb
, cr
);
996 YUV_TO_RGB2_CCIR(r
, g
, b
, y
);
999 av_log(avctx
, AV_LOG_INFO
, "clut %d := (%d,%d,%d,%d)\n", entry_id
, r
, g
, b
, alpha
);
1003 clut
->clut4
[entry_id
] = RGBA(r
,g
,b
,255 - alpha
);
1005 clut
->clut16
[entry_id
] = RGBA(r
,g
,b
,255 - alpha
);
1007 clut
->clut256
[entry_id
] = RGBA(r
,g
,b
,255 - alpha
);
1012 static void dvbsub_parse_region_segment(AVCodecContext
*avctx
,
1013 uint8_t *buf
, int buf_size
)
1015 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
1017 uint8_t *buf_end
= buf
+ buf_size
;
1018 int region_id
, object_id
;
1019 DVBSubRegion
*region
;
1020 DVBSubObject
*object
;
1021 DVBSubObjectDisplay
*display
;
1029 region
= get_region(ctx
, region_id
);
1033 region
= av_mallocz(sizeof(DVBSubRegion
));
1035 region
->id
= region_id
;
1037 region
->next
= ctx
->region_list
;
1038 ctx
->region_list
= region
;
1041 fill
= ((*buf
++) >> 3) & 1;
1043 region
->width
= BE_16(buf
);
1045 region
->height
= BE_16(buf
);
1048 if (region
->width
* region
->height
!= region
->buf_size
) {
1049 if (region
->pbuf
!= 0)
1050 av_free(region
->pbuf
);
1052 region
->buf_size
= region
->width
* region
->height
;
1054 region
->pbuf
= av_malloc(region
->buf_size
);
1059 region
->depth
= 1 << (((*buf
++) >> 2) & 7);
1060 region
->clut
= *buf
++;
1062 if (region
->depth
== 8)
1063 region
->bgcolour
= *buf
++;
1067 if (region
->depth
== 4)
1068 region
->bgcolour
= (((*buf
++) >> 4) & 15);
1070 region
->bgcolour
= (((*buf
++) >> 2) & 3);
1074 av_log(avctx
, AV_LOG_INFO
, "Region %d, (%dx%d)\n", region_id
, region
->width
, region
->height
);
1078 memset(region
->pbuf
, region
->bgcolour
, region
->buf_size
);
1080 av_log(avctx
, AV_LOG_INFO
, "Fill region (%d)\n", region
->bgcolour
);
1084 delete_region_display_list(ctx
, region
);
1086 while (buf
+ 5 < buf_end
) {
1087 object_id
= BE_16(buf
);
1090 object
= get_object(ctx
, object_id
);
1092 if (object
== NULL
) {
1093 object
= av_mallocz(sizeof(DVBSubObject
));
1095 object
->id
= object_id
;
1096 object
->next
= ctx
->object_list
;
1097 ctx
->object_list
= object
;
1100 object
->type
= (*buf
) >> 6;
1102 display
= av_mallocz(sizeof(DVBSubObjectDisplay
));
1104 display
->object_id
= object_id
;
1105 display
->region_id
= region_id
;
1107 display
->x_pos
= BE_16(buf
) & 0xfff;
1109 display
->y_pos
= BE_16(buf
) & 0xfff;
1112 if ((object
->type
== 1 || object
->type
== 2) && buf
+1 < buf_end
) {
1113 display
->fgcolour
= *buf
++;
1114 display
->bgcolour
= *buf
++;
1117 display
->region_list_next
= region
->display_list
;
1118 region
->display_list
= display
;
1120 display
->object_list_next
= object
->display_list
;
1121 object
->display_list
= display
;
1125 static void dvbsub_parse_page_segment(AVCodecContext
*avctx
,
1126 uint8_t *buf
, int buf_size
)
1128 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
1129 DVBSubRegionDisplay
*display
;
1130 DVBSubRegionDisplay
*tmp_display_list
, **tmp_ptr
;
1132 uint8_t *buf_end
= buf
+ buf_size
;
1139 ctx
->time_out
= *buf
++;
1140 page_state
= ((*buf
++) >> 2) & 3;
1143 av_log(avctx
, AV_LOG_INFO
, "Page time out %ds, state %d\n", ctx
->time_out
, page_state
);
1146 if (page_state
== 2)
1151 tmp_display_list
= ctx
->display_list
;
1152 ctx
->display_list
= NULL
;
1153 ctx
->display_list_size
= 0;
1155 while (buf
+ 5 < buf_end
) {
1159 display
= tmp_display_list
;
1160 tmp_ptr
= &tmp_display_list
;
1162 while (display
!= NULL
&& display
->region_id
!= region_id
) {
1163 tmp_ptr
= &display
->next
;
1164 display
= display
->next
;
1167 if (display
== NULL
)
1168 display
= av_mallocz(sizeof(DVBSubRegionDisplay
));
1170 display
->region_id
= region_id
;
1172 display
->x_pos
= BE_16(buf
);
1174 display
->y_pos
= BE_16(buf
);
1177 *tmp_ptr
= display
->next
;
1179 display
->next
= ctx
->display_list
;
1180 ctx
->display_list
= display
;
1181 ctx
->display_list_size
++;
1184 av_log(avctx
, AV_LOG_INFO
, "Region %d, (%d,%d)\n", region_id
, display
->x_pos
, display
->y_pos
);
1188 while (tmp_display_list
!= 0) {
1189 display
= tmp_display_list
;
1191 tmp_display_list
= display
->next
;
1199 #ifdef DEBUG_SAVE_IMAGES
1200 static void save_display_set(DVBSubContext
*ctx
)
1202 DVBSubRegion
*region
;
1203 DVBSubRegionDisplay
*display
;
1205 uint32_t *clut_table
;
1206 int x_pos
, y_pos
, width
, height
;
1207 int x
, y
, y_off
, x_off
;
1210 static int fileno_index
= 0;
1217 for (display
= ctx
->display_list
; display
!= NULL
; display
= display
->next
) {
1218 region
= get_region(ctx
, display
->region_id
);
1221 x_pos
= display
->x_pos
;
1222 y_pos
= display
->y_pos
;
1223 width
= region
->width
;
1224 height
= region
->height
;
1226 if (display
->x_pos
< x_pos
) {
1227 width
+= (x_pos
- display
->x_pos
);
1228 x_pos
= display
->x_pos
;
1231 if (display
->y_pos
< y_pos
) {
1232 height
+= (y_pos
- display
->y_pos
);
1233 y_pos
= display
->y_pos
;
1236 if (display
->x_pos
+ region
->width
> x_pos
+ width
) {
1237 width
= display
->x_pos
+ region
->width
- x_pos
;
1240 if (display
->y_pos
+ region
->height
> y_pos
+ height
) {
1241 height
= display
->y_pos
+ region
->height
- y_pos
;
1248 pbuf
= av_malloc(width
* height
* 4);
1250 for (display
= ctx
->display_list
; display
!= NULL
; display
= display
->next
) {
1251 region
= get_region(ctx
, display
->region_id
);
1253 x_off
= display
->x_pos
- x_pos
;
1254 y_off
= display
->y_pos
- y_pos
;
1256 clut
= get_clut(ctx
, region
->clut
);
1259 clut
= &default_clut
;
1261 switch (region
->depth
) {
1263 clut_table
= clut
->clut4
;
1266 clut_table
= clut
->clut256
;
1270 clut_table
= clut
->clut16
;
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
]];
1283 snprintf(filename
, 32, "dvbs.%d", fileno_index
);
1285 png_save2(filename
, pbuf
, width
, height
);
1294 static int dvbsub_display_end_segment(AVCodecContext
*avctx
, uint8_t *buf
,
1295 int buf_size
, AVSubtitle
*sub
)
1297 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
1299 DVBSubRegion
*region
;
1300 DVBSubRegionDisplay
*display
;
1301 AVSubtitleRect
*rect
;
1303 uint32_t *clut_table
;
1307 sub
->start_display_time
= 0;
1308 sub
->end_display_time
= ctx
->time_out
* 1000;
1311 sub
->num_rects
= ctx
->display_list_size
;
1313 if (sub
->num_rects
== 0)
1316 sub
->rects
= av_mallocz(sizeof(AVSubtitleRect
) * sub
->num_rects
);
1320 for (display
= ctx
->display_list
; display
!= NULL
; display
= display
->next
) {
1321 region
= get_region(ctx
, display
->region_id
);
1322 rect
= &sub
->rects
[i
];
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
;
1334 clut
= get_clut(ctx
, region
->clut
);
1337 clut
= &default_clut
;
1339 switch (region
->depth
) {
1341 clut_table
= clut
->clut4
;
1344 clut_table
= clut
->clut256
;
1348 clut_table
= clut
->clut16
;
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));
1355 rect
->bitmap
= av_malloc(region
->buf_size
);
1356 memcpy(rect
->bitmap
, region
->pbuf
, region
->buf_size
);
1363 #ifdef DEBUG_SAVE_IMAGES
1364 save_display_set(ctx
);
1370 static int dvbsub_decode(AVCodecContext
*avctx
,
1371 void *data
, int *data_size
,
1372 uint8_t *buf
, int buf_size
)
1374 DVBSubContext
*ctx
= (DVBSubContext
*) avctx
->priv_data
;
1375 AVSubtitle
*sub
= (AVSubtitle
*) data
;
1381 #ifdef DEBUG_PACKET_CONTENTS
1384 av_log(avctx
, AV_LOG_INFO
, "DVB sub packet:\n");
1386 for (i
=0; i
< buf_size
; i
++)
1388 av_log(avctx
, AV_LOG_INFO
, "%02x ", buf
[i
]);
1390 av_log(avctx
, AV_LOG_INFO
, "\n");
1394 av_log(avctx
, AV_LOG_INFO
, "\n");
1402 p_end
= buf
+ buf_size
;
1404 while (p
< p_end
&& *p
== 0x0f)
1407 segment_type
= *p
++;
1410 segment_length
= BE_16(p
);
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
);
1418 case DVBSUB_REGION_SEGMENT
:
1419 dvbsub_parse_region_segment(avctx
, p
, segment_length
);
1421 case DVBSUB_CLUT_SEGMENT
:
1422 dvbsub_parse_clut_segment(avctx
, p
, segment_length
);
1424 case DVBSUB_OBJECT_SEGMENT
:
1425 dvbsub_parse_object_segment(avctx
, p
, segment_length
);
1427 case DVBSUB_DISPLAY_SEGMENT
:
1428 *data_size
= dvbsub_display_end_segment(avctx
, p
, segment_length
, sub
);
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
);
1439 p
+= segment_length
;
1445 av_log(avctx
, AV_LOG_INFO
, "Junk at end of packet\n");
1454 AVCodec dvbsub_decoder
= {
1456 CODEC_TYPE_SUBTITLE
,
1457 CODEC_ID_DVB_SUBTITLE
,
1458 sizeof(DVBSubContext
),
1459 dvbsub_init_decoder
,
1461 dvbsub_close_decoder
,
1465 /* Parser (mostly) copied from dvdsub.c */
1467 #define PARSE_BUF_SIZE (65536)
1470 /* parser definition */
1471 typedef struct DVBSubParseContext
{
1472 uint8_t *packet_buf
;
1476 } DVBSubParseContext
;
1478 static int dvbsub_parse_init(AVCodecParserContext
*s
)
1480 DVBSubParseContext
*pc
= s
->priv_data
;
1481 pc
->packet_buf
= av_malloc(PARSE_BUF_SIZE
);
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
)
1491 DVBSubParseContext
*pc
= s
->priv_data
;
1493 int len
, buf_pos
= 0;
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
]);
1500 #ifdef DEBUG_PACKET_CONTENTS
1503 for (i
=0; i
< buf_size
; i
++)
1505 av_log(avctx
, AV_LOG_INFO
, "%02x ", buf
[i
]);
1507 av_log(avctx
, AV_LOG_INFO
, "\n");
1511 av_log(avctx
, AV_LOG_INFO
, "\n");
1518 s
->fetch_timestamp
= 1;
1520 if (s
->last_pts
!= s
->pts
&& s
->last_pts
!= AV_NOPTS_VALUE
) /* Start of a new packet */
1522 if (pc
->packet_index
!= pc
->packet_start
)
1525 av_log(avctx
, AV_LOG_INFO
, "Discarding %d bytes\n",
1526 pc
->packet_index
- pc
->packet_start
);
1530 pc
->packet_start
= 0;
1531 pc
->packet_index
= 0;
1533 if (buf_size
< 2 || buf
[0] != 0x20 || buf
[1] != 0x00) {
1535 av_log(avctx
, AV_LOG_INFO
, "Bad packet header\n");
1544 if (pc
->packet_start
!= 0)
1546 if (pc
->packet_index
!= pc
->packet_start
)
1548 memmove(pc
->packet_buf
, pc
->packet_buf
+ pc
->packet_start
,
1549 pc
->packet_index
- pc
->packet_start
);
1551 pc
->packet_index
-= pc
->packet_start
;
1552 pc
->packet_start
= 0;
1554 pc
->packet_start
= 0;
1555 pc
->packet_index
= 0;
1560 if (buf_size
- buf_pos
+ pc
->packet_index
> PARSE_BUF_SIZE
)
1563 /* if not currently in a packet, discard data */
1564 if (pc
->in_packet
== 0)
1567 memcpy(pc
->packet_buf
+ pc
->packet_index
, buf
+ buf_pos
, buf_size
- buf_pos
);
1568 pc
->packet_index
+= buf_size
- buf_pos
;
1571 p_end
= pc
->packet_buf
+ pc
->packet_index
;
1581 if (p
+ len
+ 6 <= p_end
)
1583 *poutbuf_size
+= len
+ 6;
1590 } else if (*p
== 0xff) {
1594 av_log(avctx
, AV_LOG_INFO
, "Junk at end of packet\n");
1597 pc
->packet_index
= p
- pc
->packet_buf
;
1601 av_log(avctx
, AV_LOG_ERROR
, "Junk in packet\n");
1603 pc
->packet_index
= p
- pc
->packet_buf
;
1609 if (*poutbuf_size
> 0)
1611 *poutbuf
= pc
->packet_buf
;
1612 pc
->packet_start
= *poutbuf_size
;
1615 if (s
->last_pts
== AV_NOPTS_VALUE
)
1616 s
->last_pts
= s
->pts
;
1621 static void dvbsub_parse_close(AVCodecParserContext
*s
)
1623 DVBSubParseContext
*pc
= s
->priv_data
;
1624 av_freep(&pc
->packet_buf
);
1627 AVCodecParser dvbsub_parser
= {
1628 { CODEC_ID_DVB_SUBTITLE
},
1629 sizeof(DVBSubParseContext
),