1 /*****************************************************************************
2 * dvbsub.c : DVB subtitles decoder thread
3 *****************************************************************************
4 * Copyright (C) 2003 ANEVIA
5 * Copyright (C) 2003-2004 VideoLAN
8 * Authors: Damien LUCAS <damien.lucas@anevia.com>
9 * Laurent Aimar <fenrir@via.ecp.fr>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
24 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
30 #include <vlc/decoder.h>
34 /*****************************************************************************
36 *****************************************************************************/
37 static int Open ( vlc_object_t *p_this );
38 static void Close( vlc_object_t *p_this );
41 set_description( _("DVB subtitles decoder") );
42 set_capability( "decoder", 50 );
43 set_callbacks( Open, Close );
46 /****************************************************************************
48 ****************************************************************************
49 * Those structures refer closely to the ETSI 300 743 Object model
50 ****************************************************************************/
52 /* Storage of a RLE entry */
53 typedef struct dvbsub_rle_s
61 struct dvbsub_rle_s* p_next;
64 /* A subpicture image is a list of codes
65 * We need to store the length of each line since nothing specify in
66 * the standard that all lines shoudl have the same length
67 * WARNING: We assume here that a spu is less than 576 lines high */
73 dvbsub_rle_t* p_codes;
77 /* The object definition gives the position of the object in a region */
78 typedef struct dvbsub_objectdef_s
87 struct dvbsub_objectdef_s* p_next;
91 /* The Region is an aera on the image
92 * with a list of the object definitions associated
94 typedef struct dvbsub_region_s
97 uint8_t i_version_number;
103 uint8_t i_level_comp;
109 dvbsub_objectdef_t* p_object;
113 /* The page defines the list of regions */
119 uint8_t i_version_number;
120 uint8_t i_regions_number;
121 dvbsub_region_t* regions;
125 /* An object is constituted of 2 images (for interleaving) */
126 typedef struct dvbsub_object_s
129 uint8_t i_version_number;
130 uint8_t i_coding_method;
131 vlc_bool_t b_non_modify_color;
132 dvbsub_image_t* topfield;
133 dvbsub_image_t* bottomfield;
134 struct dvbsub_object_s* p_next;
138 /* The entry in the palette CLUT */
152 uint8_t i_version_number;
153 dvbsub_color_t c_2b[0xff];
154 dvbsub_color_t c_4b[0xff];
155 dvbsub_color_t c_8b[0xff];
163 dvbsub_image_t* p_rle_top;
164 dvbsub_image_t* p_rle_bot;
174 dvbsub_clut_t* p_clut[0xff];
175 dvbsub_page_t* p_page;
176 dvbsub_object_t* p_objects;
177 subpicture_t* p_spu[16];
181 struct subpicture_sys_t
184 void * p_data; /* rle datas are stored */
185 vlc_object_t* p_input; /* Link to the input */
186 vlc_bool_t b_obsolete;
191 vout_thread_t *p_vout;
199 // List of different SEGMENT TYPES
200 // According to EN 300-743, table 2
201 #define DVBSUB_ST_PAGE_COMPOSITION 0x10
202 #define DVBSUB_ST_REGION_COMPOSITION 0x11
203 #define DVBSUB_ST_CLUT_DEFINITION 0x12
204 #define DVBSUB_ST_OBJECT_DATA 0x13
205 #define DVBSUB_ST_ENDOFDISPLAY 0x80
206 #define DVBSUB_ST_STUFFING 0xff
207 // List of different OBJECT TYPES
208 // According to EN 300-743, table 6
209 #define DVBSUB_OT_BASIC_BITMAP 0x00
210 #define DVBSUB_OT_BASIC_CHAR 0x01
211 #define DVBSUB_OT_COMPOSITE_STRING 0x02
213 // According to EN 300-743, table 9
214 #define DVBSUB_DT_2BP_CODE_STRING 0x10
215 #define DVBSUB_DT_4BP_CODE_STRING 0x11
216 #define DVBSUB_DT_8BP_CODE_STRING 0x12
217 #define DVBSUB_DT_24_TABLE_DATA 0x20
218 #define DVBSUB_DT_28_TABLE_DATA 0x21
219 #define DVBSUB_DT_48_TABLE_DATA 0x22
220 #define DVBSUB_DT_END_LINE 0xf0
222 /*****************************************************************************
224 *****************************************************************************/
225 static void Decode ( decoder_t *, block_t ** );
227 static vout_thread_t *FindVout( decoder_t * );
229 static int init( dvbsub_all_t *, int );
230 static void decode_segment( decoder_t *, dvbsub_all_t *, bs_t * );
231 static void render( dvbsub_all_t *, vout_thread_t * );
232 static void dvbsub( dvbsub_all_t * );
234 /*****************************************************************************
235 * Open: probe the decoder and return score
236 *****************************************************************************
237 * Tries to launch a decoder and return score so that the interface is able
239 *****************************************************************************/
240 static int Open( vlc_object_t *p_this )
242 decoder_t *p_dec = (decoder_t*) p_this;
243 decoder_sys_t *p_sys;
245 if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
250 p_dec->pf_decode_sub = Decode;
251 p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) );
253 p_sys->p_vout = NULL;
255 init( &p_sys->dvbsub, p_dec->fmt_in.subs.dvb.i_id );
257 es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'd','v','b','s' ) );
262 /*****************************************************************************
264 *****************************************************************************/
265 static void Close( vlc_object_t *p_this )
267 decoder_t *p_dec = (decoder_t*) p_this;
268 decoder_sys_t *p_sys = p_dec->p_sys;
270 if( p_sys->p_vout && p_sys->p_vout->p_subpicture != NULL )
272 subpicture_t * p_subpic;
274 for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
276 p_subpic = &p_sys->p_vout->p_subpicture[i_subpic];
277 if( p_subpic != NULL &&
278 ( p_subpic->i_status == RESERVED_SUBPICTURE ||
279 p_subpic->i_status == READY_SUBPICTURE ) )
281 vout_DestroySubPicture( p_sys->p_vout, p_subpic );
286 dvbsub( &p_sys->dvbsub );
291 /*****************************************************************************
293 *****************************************************************************/
294 static void Decode( decoder_t *p_dec, block_t **pp_block )
296 decoder_sys_t *p_sys = p_dec->p_sys;
299 if( pp_block == NULL || *pp_block == NULL )
306 p_sys->dvbsub.i_pts = p_block->i_pts;
307 if( p_sys->dvbsub.i_pts <= 0 )
309 msg_Warn( p_dec, "non dated subtitle" );
310 block_Release( p_block );
314 if( ( p_sys->p_vout = FindVout( p_dec ) ) )
316 int i_data_identifier;
317 int i_subtitle_stream_id;
318 int i_end_data_marker;
320 bs_init( &p_sys->bs, p_block->p_buffer, p_block->i_buffer );
322 i_data_identifier = bs_read( &p_sys->bs, 8 );
323 i_subtitle_stream_id = bs_read( &p_sys->bs, 8 );
327 if( bs_show( &p_sys->bs, 8 ) != 0x0f )
331 decode_segment( p_dec, &p_sys->dvbsub, &p_sys->bs );
333 i_end_data_marker = bs_read( &p_sys->bs, 8 );
335 /* Check if the page is to be displayed */
336 if( p_sys->dvbsub.p_page && p_sys->dvbsub.p_objects )
338 render( &p_sys->dvbsub, p_sys->p_vout );
341 vlc_object_release( p_sys->p_vout );
344 block_Release( p_block );
347 /* following functions are local */
348 /*****************************************************************************
349 * FindVout: Find a vout or wait for one to be created.
350 *****************************************************************************/
351 static vout_thread_t *FindVout( decoder_t *p_dec )
355 vout_thread_t *p_vout;
357 if( p_dec->b_die || p_dec->b_error )
361 p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
366 msleep( VOUT_OUTMEM_SLEEP );
370 static int init( dvbsub_all_t *p_dvbsub, int i_id )
374 memset( p_dvbsub, 0, sizeof( dvbsub_all_t ) );
377 p_dvbsub->i_id = i_id;
378 p_dvbsub->p_page = NULL;
379 p_dvbsub->p_objects = NULL;
380 for( i = 0; i < 255; i++ )
382 p_dvbsub->p_clut[i] = NULL;
384 for( i = 0; i < 16; i++ )
386 p_dvbsub->p_spu[i] = NULL;
391 static void free_all( dvbsub_all_t * );
393 static void dvbsub( dvbsub_all_t *p_dvbsub )
395 free_all( p_dvbsub );
398 static void decode_clut( dvbsub_all_t *p_dvbsub, bs_t *s );
399 static void decode_page_composition( dvbsub_all_t *p_dvbsub, bs_t *s);
400 static void decode_region_composition( dvbsub_all_t *p_dvbsub, bs_t *s );
401 static void stop_display( dvbsub_all_t* p_dvbsub );
402 static void decode_object( dvbsub_all_t *p_dvbsub, bs_t *s );
404 static void free_page( dvbsub_page_t* p_p );
406 static void decode_segment( decoder_t *p_dec, dvbsub_all_t *p_dvbspu, bs_t *s )
416 i_type = bs_read( s, 8 );
419 i_page_id = bs_read( s, 16 );
422 i_size = bs_show( s, 16 );
424 if( i_page_id != p_dvbspu->i_id )
426 bs_skip( s, 8 * ( 2 + i_size ) );
432 case DVBSUB_ST_CLUT_DEFINITION:
434 msg_Dbg( p_dec, "subtitle dvbsub_decode_clut" );
436 decode_clut( p_dvbspu, s );
438 case DVBSUB_ST_PAGE_COMPOSITION:
440 msg_Dbg( p_dec, "subtitle dvbsub_decode_page_composition" );
442 decode_page_composition( p_dvbspu, s );
444 case DVBSUB_ST_REGION_COMPOSITION:
446 msg_Dbg( p_dec, "subtitle dvbsub_decode_region_composition" );
448 decode_region_composition( p_dvbspu, s );
450 case DVBSUB_ST_OBJECT_DATA:
452 msg_Dbg( p_dec, "subtitle dvbsub_decode_object" );
454 decode_object( p_dvbspu, s );
456 case DVBSUB_ST_ENDOFDISPLAY:
458 msg_Dbg( p_dec, "subtitle dvbsub_stop_display" );
460 stop_display( p_dvbspu );
462 case DVBSUB_ST_STUFFING:
464 msg_Warn( p_dec, "unsupported segment type: (%04x)", i_type );
465 bs_skip( s, 8 * ( 2 + i_size ) );
470 static void stop_display( dvbsub_all_t *p_dvbsub )
474 for( i = 0; p_dvbsub->p_spu[i] != NULL; i++ )
476 p_dvbsub->p_spu[i]->i_stop = p_dvbsub->i_pts;
480 static void decode_clut( dvbsub_all_t *p_dvbsub, bs_t *s )
482 uint16_t i_segment_length;
483 uint16_t i_processed_length;
486 uint8_t i_version_number;
488 i_segment_length = bs_read( s, 16 );
489 i_clut_id = bs_read( s, 8 );
490 i_version_number = bs_read( s, 4 );
492 // Check that this id doesn't not already exist
493 // with the same version number
494 // And allocate memory if necessary
495 if( p_dvbsub->p_clut[i_clut_id] != NULL)
497 if( p_dvbsub->p_clut[i_clut_id]->i_version_number == i_version_number )
499 //TODO skip the right number of bits
504 memset( p_dvbsub->p_clut[i_clut_id], 0, sizeof(dvbsub_clut_t) );
509 p_dvbsub->p_clut[i_clut_id] = malloc( sizeof(dvbsub_clut_t) );
511 clut = p_dvbsub->p_clut[i_clut_id];
513 /* We don't have this version of the CLUT: Parse it */
514 clut->i_version_number = i_version_number;
515 bs_skip( s, 4 ); /* Reserved bits */
516 i_processed_length = 2;
517 while( i_processed_length < i_segment_length )
519 uint8_t y, cb, cr, t;
523 i_id = bs_read( s, 8 );
524 i_type = bs_read( s, 3 );
528 if( bs_read( s, 1 ) )
531 cr = bs_read( s, 8 );
532 cb = bs_read( s, 8 );
534 i_processed_length += 6;
539 cr = bs_read( s, 4 );
540 cb = bs_read( s, 4 );
542 i_processed_length += 4;
545 /* According to EN 300-743 section 7.2.3 note 1, type should
546 * not have more than 1 bit set to one
547 But, some strams don't respect this note. */
551 clut->c_2b[i_id].Y = y;
552 clut->c_2b[i_id].Cr = cr;
553 clut->c_2b[i_id].Cb = cb;
554 clut->c_2b[i_id].T = t;
558 clut->c_4b[i_id].Y = y;
559 clut->c_4b[i_id].Cr = cr;
560 clut->c_4b[i_id].Cb = cb;
561 clut->c_4b[i_id].T = t;
565 clut->c_8b[i_id].Y = y;
566 clut->c_8b[i_id].Cr = cr;
567 clut->c_8b[i_id].Cb = cb;
568 clut->c_8b[i_id].T = t;
573 static void decode_page_composition( dvbsub_all_t *p_dvbsub, bs_t *s )
575 unsigned int i_version_number;
576 unsigned int i_state;
577 unsigned int i_segment_length;
581 i_segment_length = bs_read( s, 16 );
583 /* A page is composed by one or more region: */
584 i_timeout = bs_read( s, 8 );
585 i_version_number = bs_read( s, 4 );
586 i_state = bs_read( s, 2 );
588 /* TODO We assume it is a new page (i_state) */
589 if( p_dvbsub->p_page ) free_page( p_dvbsub->p_page );
591 bs_skip( s, 2 ); /* Reserved */
593 /* Allocate a new page */
594 p_dvbsub->p_page = malloc( sizeof(dvbsub_page_t) );
595 p_dvbsub->p_page->i_timeout = i_timeout;
597 /* Number of regions: */
598 p_dvbsub->p_page->i_regions_number = (i_segment_length-2) / 6;
600 /* Special workaround for CAVENA encoders: a page with no regions is sent
601 * instead of a 0x80 packet (End Of Display) */
602 if( p_dvbsub->p_page->i_regions_number == 0 )
604 stop_display( p_dvbsub );
606 /* End of workaround */
608 p_dvbsub->p_page->regions =
609 malloc( p_dvbsub->p_page->i_regions_number * sizeof(dvbsub_region_t) );
610 for( i = 0; i < p_dvbsub->p_page->i_regions_number; i++ )
612 p_dvbsub->p_page->regions[i].i_id = bs_read( s, 8 );
613 bs_skip( s, 8 ); /* Reserved */
614 p_dvbsub->p_page->regions[i].i_x = bs_read( s, 16 );
615 p_dvbsub->p_page->regions[i].i_y = bs_read( s, 16 );
616 p_dvbsub->p_page->regions[i].p_object = NULL;
621 static void decode_region_composition( dvbsub_all_t *p_dvbsub, bs_t *s )
623 dvbsub_region_t* p_region = NULL;
624 unsigned int i_segment_length;
625 unsigned int i_processed_length;
626 unsigned int i_region_id;
629 i_segment_length = bs_read( s, 16 );
632 i_region_id = bs_read( s, 8 );
633 for( i = 0; i < p_dvbsub->p_page->i_regions_number; i++ )
635 if( p_dvbsub->p_page->regions[i].i_id == i_region_id )
637 p_region = &(p_dvbsub->p_page->regions[i]);
641 if( p_region == NULL )
644 * The region has never been declared before
646 fprintf( stderr, "Decoding of undeclared region N/A\n" );
650 /* Skip version number and fill flag */
651 if( bs_show( s, 4 ) == p_region->i_version_number )
653 fprintf( stderr, "Skipping already known region N/A\n" );
654 /* TODO Skip the right number of bits */
657 /* Region attributes */
658 p_region->i_version_number = bs_read( s, 4 );
659 p_region->b_fill = bs_read( s, 1 );
660 bs_skip( s, 3 ); /* Reserved */
661 p_region->i_width = bs_read( s, 16 );
662 p_region->i_height = bs_read( s, 16 );
663 p_region->i_level_comp = bs_read( s, 3 );
664 p_region->i_depth = bs_read( s, 3 );
665 bs_skip( s, 2 ); /* Reserved */
666 p_region->i_clut = bs_read( s, 8 );
667 p_region->i_8bp_code = bs_read( s, 8 );
668 p_region->i_4bp_code = bs_read( s, 4 );
669 p_region->i_2bp_code = bs_read( s, 2 );
670 bs_skip( s, 2 ); /* Reserved */
672 /* List of objects in the region: */
673 /* We already skipped 10 bytes */
675 i_processed_length = 10;
676 while( i_processed_length < i_segment_length )
678 /* We create a new object */
679 dvbsub_objectdef_t *p_obj = malloc( sizeof(dvbsub_objectdef_t) );
681 /* We parse object properties */
682 p_obj->p_next = NULL;
683 p_obj->i_id = bs_read( s, 16 );
684 p_obj->i_type = bs_read( s, 2 );
685 p_obj->i_provider = bs_read( s, 2 );
686 p_obj->i_xoffset = bs_read( s, 12 );
687 bs_skip( s, 4 ); /* Reserved */
688 p_obj->i_yoffset = bs_read( s, 12 );
690 i_processed_length += 6;
692 if( p_obj->i_type == DVBSUB_OT_BASIC_CHAR ||
693 p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING )
695 p_obj->i_fg_pc = bs_read( s, 8 );
696 p_obj->i_bg_pc = bs_read( s, 8 );
697 i_processed_length += 2;
701 if( p_region->p_object )
703 dvbsub_objectdef_t *p_o;
704 for( p_o = p_region->p_object; ; p_o = p_o->p_next )
706 if( p_o->p_next == NULL )
715 p_region->p_object = p_obj;
720 static dvbsub_image_t* dvbsub_parse_pdata( dvbsub_all_t *p_dvbsub, bs_t *s,
722 static uint16_t dvbsub_count0x11( bs_t *s, uint16_t* p,
723 dvbsub_image_t* p_image);
725 static void decode_object( dvbsub_all_t *p_dvbsub, bs_t *s )
727 dvbsub_object_t *p_obj;
728 uint16_t i_segment_length;
730 /* Memory Allocation */
731 p_obj = malloc( sizeof(dvbsub_object_t) );
732 p_obj->p_next = NULL;
734 i_segment_length = bs_read( s, 16 );
736 /* TODO Check we don't already have this object / this version */
737 p_obj->i_id = bs_read( s, 16 );
738 p_obj->i_version_number = bs_read( s, 4 );
739 p_obj->i_coding_method = bs_read( s, 2 );
740 p_obj->b_non_modify_color= bs_read( s, 1 );
741 bs_skip( s, 1 ); /* Reserved */
743 if( p_obj->i_coding_method == 0x00 )
745 uint16_t i_topfield_length;
746 uint16_t i_bottomfield_length;
748 i_topfield_length = bs_read( s, 16 );
749 i_bottomfield_length = bs_read( s, 16 );
752 dvbsub_parse_pdata( p_dvbsub, s, i_topfield_length );
754 dvbsub_parse_pdata( p_dvbsub, s, i_bottomfield_length );
758 bs_skip( s, (i_segment_length - 3 ) * 8 );
759 /*TODO: DVB subtitling as characters */
762 /* Add this object to the list of the page */
763 p_obj->p_next = p_dvbsub->p_objects;
764 p_dvbsub->p_objects = p_obj;
767 static dvbsub_image_t* dvbsub_parse_pdata( dvbsub_all_t *p_dvbsub, bs_t *s,
770 dvbsub_image_t* p_image;
771 uint16_t i_processed_length = 0;
772 uint16_t i_lines = 0;
773 uint16_t i_cols_last = 0;
775 p_image = malloc( sizeof(dvbsub_image_t) );
776 p_image->p_last = NULL;
778 memset( p_image->i_cols, 0, 576 * sizeof(uint16_t) );
780 /* Let's parse it a first time to determine the size of the buffer */
781 while( i_processed_length < length)
783 switch( bs_read( s, 8 ) )
786 fprintf(stderr, "0x10 N/A\n");
789 i_processed_length +=
790 1 + dvbsub_count0x11( s, &(p_image->i_cols[i_lines]),
794 fprintf(stderr, "0x12 N/A\n");
797 fprintf(stderr, "0x20 N/A\n");
800 fprintf(stderr, "0x21 N/A\n");
803 fprintf(stderr, "0x22 N/A\n");
806 i_processed_length++;
812 p_image->i_rows = i_lines;
813 p_image->i_cols[i_lines] = i_cols_last;
815 /* Check word-aligned bits */
816 if( bs_show( s, 8 ) == 0x00 )
824 static void add_rle_code( dvbsub_image_t *p, uint16_t num, uint8_t color )
826 if(p->p_last != NULL)
828 p->p_last->p_next = malloc( sizeof(dvbsub_rle_t) );
829 p->p_last = p->p_last->p_next;
833 p->p_codes = malloc( sizeof(dvbsub_rle_t) );
834 p->p_last = p->p_codes;
836 p->p_last->i_num = num;
837 p->p_last->i_color_code = color;
838 p->p_last->p_next = NULL;
841 static uint16_t dvbsub_count0x11( bs_t *s, uint16_t* p,
842 dvbsub_image_t* p_image )
844 uint16_t i_processed=0;
846 uint16_t i_count = 0;
851 if( (i_color = bs_read( s, 4 )) != 0x00 )
856 /* 1 pixel of color code '0000' */
857 add_rle_code( p_image, 1, i_color );
861 if( bs_read( s, 1 ) == 0x00 ) // Switch1
863 if( bs_show( s, 3 ) != 0x00 )
865 i_count = 2 + bs_read( s, 3 );
867 add_rle_code( p_image, i_count, 0x00 );
878 if( bs_read( s, 1 ) == 0x00) //Switch2
880 i_count = 4 + bs_read( s, 2 );
881 i_color = bs_read( s, 4 );
884 add_rle_code( p_image, i_count, i_color );
888 switch ( bs_read( s, 2 ) ) //Switch3
893 add_rle_code( p_image, 1, 0x00 );
898 add_rle_code( p_image, 2, 0x00 );
901 i_count = 9 + bs_read( s, 4 );
902 i_color = bs_read( s, 4 );
905 add_rle_code( p_image, i_count, i_color );
908 i_count= 25 + bs_read( s, 8 );
909 i_color = bs_read( s, 4 );
912 add_rle_code( p_image, i_count, i_color );
922 return ( i_processed + 7 ) / 8 ;
925 static void free_image (dvbsub_image_t* p_i)
928 dvbsub_rle_t* p2=NULL;
930 for( p1 = p_i->p_codes; p1 != NULL; p1=p2)
940 static void free_object (dvbsub_object_t* p_o)
945 static void free_objectdefs ( dvbsub_objectdef_t* p_o)
947 dvbsub_objectdef_t* p1;
948 dvbsub_objectdef_t* p2=NULL;
950 for( p1 = p_o; p1 != NULL; p1=p2)
958 static void free_regions (dvbsub_region_t* p_r, uint8_t nb)
962 for (i = 0; i<nb; i++) free_objectdefs ( p_r[i].p_object );
967 static void free_objects (dvbsub_object_t* p_o)
970 dvbsub_object_t* p2=NULL;
972 for( p1 = p_o; p1 != NULL; p1=p2)
975 free_image (p1->topfield);
976 free_image (p1->bottomfield);
981 static void free_clut ( dvbsub_clut_t* p_c )
986 static void free_page (dvbsub_page_t* p_p)
988 free_regions (p_p->regions, p_p->i_regions_number);
993 static void free_spu( subpicture_t *p_spu )
997 free_image(((dvbsub_render_t *)p_spu->p_sys->p_data)->p_rle_top);
998 free_image(((dvbsub_render_t *)p_spu->p_sys->p_data)->p_rle_bot);
999 free(p_spu->p_sys->p_data);
1000 free( p_spu->p_sys );
1001 p_spu->p_sys = NULL;
1005 static void free_all ( dvbsub_all_t* p_a )
1009 for(i=0; i<0xff; i++) if (p_a->p_clut[i]) free_clut ( p_a->p_clut[i] );
1010 for(i=0; i<16; i++) if (p_a->p_spu[i]) free_spu ( p_a->p_spu[i] );
1011 if(p_a->p_page) free_page( p_a->p_page );
1012 free_objects (p_a->p_objects);
1015 static void RenderYUY2( vout_thread_t *p_vout, picture_t *p_pic,
1016 const subpicture_t *p_spu )
1018 /* Common variables */
1024 dvbsub_render_t* p_r = ((dvbsub_render_t *)p_spu->p_sys->p_data);
1025 dvbsub_image_t* p_im = p_r->p_rle_top;
1028 p_desty = p_pic->Y_PIXELS;
1029 //let's render the 1st frame
1030 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1032 //if( p_c->y != 0 && p_c->t < 0x20)
1033 if( p_c->y != 0 && p_c->t < 0x20)
1037 //memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1038 // In YUY2 we have to set pixel per pixel
1039 for( i_cnt = 0; i_cnt < p_c->i_num; i_cnt+=2 )
1041 memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt, p_c->y, 1);
1042 //memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+1, p_c->cr, 1);
1043 //memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+2, p_c->y, 1);
1044 //memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+3, p_c->cb, 1);
1048 if(j >= p_im->i_cols[i])
1052 if( i>= p_im->i_rows) break;
1054 //idem for the second frame
1055 p_im = p_r->p_rle_bot; i=0; j=0;
1056 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1058 if( p_c->y != 0 && p_c->t < 0x20)
1062 //memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1063 // In YUY2 we have to set pixel per pixel
1064 for( i_cnt = 0; i_cnt < p_c->i_num; i_cnt+=2 )
1066 memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt, p_c->y, 1);
1067 //memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+1, p_c->cr, 1);
1068 //memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+2, p_c->y, 1);
1069 //memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+3, p_c->cb, 1);
1073 if(j >= p_im->i_cols[i])
1077 if( i>= p_im->i_rows) break;
1081 static void RenderI42x( vout_thread_t *p_vout, picture_t *p_pic,
1082 const subpicture_t *p_spu )
1084 /* Common variables */
1091 dvbsub_render_t* p_r = ((dvbsub_render_t *)p_spu->p_sys->p_data);
1092 dvbsub_image_t* p_im = p_r->p_rle_top;
1095 p_desty = p_pic->Y_PIXELS;
1096 p_destu = p_pic->U_PIXELS;
1097 p_destv = p_pic->V_PIXELS;
1098 //let's render the 1st frame
1099 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1105 //memset(p_dest+ y*p_pic->U_PITCH*2 + x, p_c->cr, p_c->i_num);
1106 //memset(p_desty+ (y)*p_pic->Y_PITCH + x, p_c->cr, p_c->i_num);
1107 //memset(p_dest+ y*p_pic->V_PITCH*2 + x, p_c->cb, p_c->i_num);
1108 //memset(p_destu+ (y)*p_pic->Y_PITCH + x, p_c->cb, p_c->i_num);
1109 memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1110 //memset(p_desty+ 2*y*p_pic->U_PITCH + x, p_c->cr, p_c->i_num);
1111 //memset(p_desty+ 2*y*p_pic->V_PITCH + x, p_c->cb, p_c->i_num);
1114 if(j >= p_im->i_cols[i])
1118 if( i>= p_im->i_rows) break;
1120 //idem for the second frame
1121 p_im = p_r->p_rle_bot; i=0; j=0;
1122 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1124 if( p_c->y != 0 && p_c->t < 0x20)
1128 //memset(p_desty+ y*p_pic->U_PITCH*2 + x, p_c->cr, p_c->i_num);
1129 //memset(p_desty+ y*p_pic->V_PITCH*2 + x, p_c->cb, p_c->i_num);
1130 memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1131 //memset(p_desty+ 2*y*p_pic->U_PITCH + x, p_c->cr, p_c->i_num);
1132 //memset(p_desty+ 2*y*p_pic->V_PITCH + x, p_c->cb, p_c->i_num);
1135 if(j >= p_im->i_cols[i])
1139 if( i>= p_im->i_rows) break;
1143 static void RenderDVBSUB( vout_thread_t *p_vout, picture_t *p_pic,
1144 const subpicture_t *p_spu )
1146 /* If we have changed the language on the fly */
1148 if( p_spu->p_sys == NULL || p_spu->p_sys->b_obsolete )
1153 switch( p_vout->output.i_chroma )
1155 /* I420 target, no scaling */
1156 case VLC_FOURCC('I','4','2','2'):
1157 case VLC_FOURCC('I','4','2','0'):
1158 case VLC_FOURCC('I','Y','U','V'):
1159 case VLC_FOURCC('Y','V','1','2'):
1160 /* As long as we just use Y info, I422 and YV12 are just equivalent
1161 * to I420. Remember to change it the day we'll take into account
1163 RenderI42x( p_vout, p_pic, p_spu );
1166 /* RV16 target, scaling */
1167 case VLC_FOURCC('R','V','1','6'):
1168 msg_Err(p_vout, "unimplemented chroma: RV16");
1169 /* RenderRV16( p_vout, p_pic, p_spu ); */
1172 /* RV32 target, scaling */
1173 case VLC_FOURCC('R','V','2','4'):
1174 case VLC_FOURCC('R','V','3','2'):
1175 msg_Err(p_vout, "unimplemented chroma: RV32");
1176 /* RenderRV32( p_vout, p_pic, p_spu ); */
1179 /* NVidia overlay, no scaling */
1180 case VLC_FOURCC('Y','U','Y','2'):
1181 RenderYUY2( p_vout, p_pic, p_spu );
1185 msg_Err( p_vout, "unknown chroma, can't render SPU" );
1190 static void dvbsub_Destroy( subpicture_t *p_spu )
1195 static void render( dvbsub_all_t *dvbsub, vout_thread_t *p_vout )
1197 dvbsub_region_t* p_region;
1198 dvbsub_objectdef_t* p_objectdef;
1199 dvbsub_object_t* p_o;
1200 dvbsub_object_t* p_object;
1201 dvbsub_object_t* p_object_old;
1202 dvbsub_render_t* p_render;
1206 /* loop on regions */
1207 for( i = 0; i < dvbsub->p_page->i_regions_number; i++ )
1209 p_region = &(dvbsub->p_page->regions[i]);
1211 /* loop on objects */
1212 for( p_objectdef = p_region->p_object; p_objectdef != NULL;
1213 p_objectdef = p_objectdef->p_next )
1215 /* Look for the right object */
1216 p_object = dvbsub->p_objects;
1217 while( !p_object && p_object->i_id != p_objectdef->i_id )
1219 p_object = p_object->p_next;
1224 msg_Err( p_vout, "internal decoder error");
1228 /* Allocate the render structure */
1229 p_render = malloc( sizeof(dvbsub_render_t) );
1230 p_render->i_x = p_region->i_x + p_objectdef->i_xoffset;
1231 p_render->i_y = p_region->i_y + p_objectdef->i_yoffset;
1232 p_render->p_rle_top = p_object->topfield;
1233 p_render->p_rle_bot = p_object->bottomfield;
1235 // if we did not recieved the CLUT yet
1236 if( !dvbsub->p_clut[p_region->i_clut] ) return;
1238 /* Compute the color datas according to the appropriate CLUT */
1239 for( p_c = p_render->p_rle_top->p_codes;
1240 p_c->p_next != NULL; p_c = p_c->p_next )
1242 //TODO We assume here we are working in 4bp
1243 p_c->y = dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Y;
1244 p_c->cr = dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cr;
1245 p_c->cb = dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cb;
1246 p_c->t = dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].T;
1248 for( p_c = p_render->p_rle_bot->p_codes; p_c->p_next != NULL;
1251 //TODO We assume here we are working in 4bp
1252 p_c->y = dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Y;
1253 p_c->cr = dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cr;
1254 p_c->cb = dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cb;
1255 p_c->t = dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].T;
1259 /* Allocate the subpicture internal data. */
1261 vout_CreateSubPicture( p_vout, SUBT1_CHAN, TEXT_CONTENT,
1262 MEMORY_SUBPICTURE );
1263 if( dvbsub->p_spu[j] == NULL )
1265 msg_Err(p_vout, "Unable to allocate memory, skipping");
1268 /* Set the pf_render callback */
1269 dvbsub->p_spu[j]->pf_render = RenderDVBSUB;
1270 dvbsub->p_spu[j]->p_sys = malloc( sizeof(subpicture_sys_t) );
1271 dvbsub->p_spu[j]->p_sys->p_data = p_render;
1272 dvbsub->p_spu[j]->p_sys->b_obsolete = 0;
1273 dvbsub->p_spu[j]->pf_destroy = dvbsub_Destroy;
1274 dvbsub->p_spu[j]->i_start = dvbsub->i_pts;
1275 dvbsub->p_spu[j]->i_stop = dvbsub->p_spu[j]->i_start +
1276 dvbsub->p_page->i_timeout * 1000000;
1277 dvbsub->p_spu[j]->b_ephemer = VLC_FALSE;
1279 // At this stage, we have all we need in p_render
1280 // We need to free the object
1281 //Remove this object from the list
1282 p_object_old = p_object;
1283 if( p_object == dvbsub->p_objects )
1285 dvbsub->p_objects = p_object->p_next;
1289 for( p_o = dvbsub->p_objects; p_o->p_next != p_object;
1290 p_o = p_o->p_next );
1291 p_o->p_next = p_object->p_next;
1293 free_object(p_object_old);
1295 vout_DisplaySubPicture( p_vout, dvbsub->p_spu[j] );