1 /*****************************************************************************
2 * dvbsub.c : DVB subtitles decoder thread
3 *****************************************************************************
4 * Copyright (C) 2003 ANEVIA
5 * Copyright (C) 2003 VideoLAN
6 * $Id: dvbsub.c,v 1.9 2004/01/25 20:40:59 gbazin Exp $
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 );
47 // Wow, that's ugly but very usefull for a memory leak track
50 static long long unsigned int trox_malloc_nb = 0;
51 static long long unsigned int trox_free_nb = 0;
53 static void* trox_malloc (size_t size)
54 { ++trox_malloc_nb; return malloc (size); }
56 static void trox_free (void* ptr)
57 { ++trox_free_nb; free(ptr); return; }
59 static void trox_call ()
61 fprintf(stderr, "dvbbsub -- Memory usage: %llu mallocs %llu frees (%llu)\n",
64 trox_malloc_nb - trox_free_nb);
68 # define trox_malloc malloc
69 # define trox_free free
72 /****************************************************************************
74 ****************************************************************************
75 * Those structures refer closely to the ETSI 300 743 Object model
76 ****************************************************************************/
78 /* Storage of a RLE entry */
79 typedef struct dvbsub_rle_s
87 struct dvbsub_rle_s* p_next;
90 /* A subpicture image is a list of codes
91 * We need to store the length of each line since nothing specify in
92 * the standard that all lines shoudl have the same length
93 * WARNING: We assume here that a spu is less than 576 lines high */
99 dvbsub_rle_t* p_codes;
102 /* The object definition gives the position of the object in a region */
103 typedef struct dvbsub_objectdef_s
112 struct dvbsub_objectdef_s* p_next;
113 } dvbsub_objectdef_t;
115 /* The Region is an aera on the image
116 * with a list of the object definitions associated
118 typedef struct dvbsub_region_s
121 uint8_t i_version_number;
127 uint8_t i_level_comp;
133 dvbsub_objectdef_t* p_object;
136 /* The page defines the list of regions */
142 uint8_t i_version_number;
143 uint8_t i_regions_number;
144 dvbsub_region_t* regions;
147 /* An object is constituted of 2 images (for interleaving) */
148 typedef struct dvbsub_object_s
151 uint8_t i_version_number;
152 uint8_t i_coding_method;
153 vlc_bool_t b_non_modify_color;
154 dvbsub_image_t* topfield;
155 dvbsub_image_t* bottomfield;
156 struct dvbsub_object_s* p_next;
159 /* The entry in the palette CLUT */
172 uint8_t i_version_number;
173 dvbsub_color_t c_2b[0xff];
174 dvbsub_color_t c_4b[0xff];
175 dvbsub_color_t c_8b[0xff];
182 dvbsub_image_t* p_rle_top;
183 dvbsub_image_t* p_rle_bot;
192 dvbsub_clut_t* p_clut[0xff];
193 dvbsub_page_t* p_page;
194 dvbsub_object_t* p_objects;
195 subpicture_t* p_spu[16];
198 struct subpicture_sys_t
201 void * p_data; /* rle datas are stored */
202 vlc_object_t* p_input; /* Link to the input */
203 vlc_bool_t b_obsolete;
208 vout_thread_t *p_vout;
216 // List of different SEGMENT TYPES
217 // According to EN 300-743, table 2
218 #define DVBSUB_ST_PAGE_COMPOSITION 0x10
219 #define DVBSUB_ST_REGION_COMPOSITION 0x11
220 #define DVBSUB_ST_CLUT_DEFINITION 0x12
221 #define DVBSUB_ST_OBJECT_DATA 0x13
222 #define DVBSUB_ST_ENDOFDISPLAY 0x80
223 #define DVBSUB_ST_STUFFING 0xff
224 // List of different OBJECT TYPES
225 // According to EN 300-743, table 6
226 #define DVBSUB_OT_BASIC_BITMAP 0x00
227 #define DVBSUB_OT_BASIC_CHAR 0x01
228 #define DVBSUB_OT_COMPOSITE_STRING 0x02
230 // According to EN 300-743, table 9
231 #define DVBSUB_DT_2BP_CODE_STRING 0x10
232 #define DVBSUB_DT_4BP_CODE_STRING 0x11
233 #define DVBSUB_DT_8BP_CODE_STRING 0x12
234 #define DVBSUB_DT_24_TABLE_DATA 0x20
235 #define DVBSUB_DT_28_TABLE_DATA 0x21
236 #define DVBSUB_DT_48_TABLE_DATA 0x22
237 #define DVBSUB_DT_END_LINE 0xf0
239 /*****************************************************************************
241 *****************************************************************************/
242 static void Decode ( decoder_t *, block_t ** );
244 static vout_thread_t *FindVout( decoder_t * );
246 static int dvbsub_init( dvbsub_all_t *, int );
247 static void dvbsub_decode_segment( dvbsub_all_t *p_dvbsub, bs_t *s );
248 static void dvbsub_render( dvbsub_all_t *, vout_thread_t * );
249 static void dvbsub_clean( dvbsub_all_t * );
252 /*****************************************************************************
253 * Open: probe the decoder and return score
254 *****************************************************************************
255 * Tries to launch a decoder and return score so that the interface is able
257 *****************************************************************************/
258 static int Open( vlc_object_t *p_this )
260 decoder_t *p_dec = (decoder_t*) p_this;
261 decoder_sys_t *p_sys;
263 if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
268 p_dec->pf_decode_sub = Decode;
269 p_sys = p_dec->p_sys = malloc( sizeof( decoder_sys_t ) );
271 p_sys->p_vout = NULL;
273 dvbsub_init( &p_sys->dvbsub, p_dec->fmt_in.subs.dvb.i_id );
275 es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'd','v','b','s' ) );
280 /*****************************************************************************
282 *****************************************************************************/
283 static void Close( vlc_object_t *p_this )
285 decoder_t *p_dec = (decoder_t*) p_this;
286 decoder_sys_t *p_sys = p_dec->p_sys;
288 if( p_sys->p_vout && p_sys->p_vout->p_subpicture != NULL )
290 subpicture_t * p_subpic;
292 for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
294 p_subpic = &p_sys->p_vout->p_subpicture[i_subpic];
295 if( p_subpic != NULL &&
296 ( ( p_subpic->i_status == RESERVED_SUBPICTURE ) ||
297 ( p_subpic->i_status == READY_SUBPICTURE ) ) )
299 vout_DestroySubPicture( p_sys->p_vout, p_subpic );
304 dvbsub_clean( &p_sys->dvbsub );
309 /*****************************************************************************
311 *****************************************************************************/
312 static void Decode( decoder_t *p_dec, block_t **pp_block )
314 decoder_sys_t *p_sys = p_dec->p_sys;
317 if( pp_block == NULL || *pp_block == NULL )
324 p_sys->dvbsub.i_pts = p_block->i_pts;
325 if( p_sys->dvbsub.i_pts <= 0 )
327 msg_Warn( p_dec, "non dated subtitle" );
328 block_Release( p_block );
332 if( ( p_sys->p_vout = FindVout( p_dec ) ) )
334 int i_data_identifier;
335 int i_subtitle_stream_id;
336 int i_end_data_marker;
338 bs_init( &p_sys->bs, p_block->p_buffer, p_block->i_buffer );
340 i_data_identifier = bs_read( &p_sys->bs, 8 );
341 i_subtitle_stream_id = bs_read( &p_sys->bs, 8 );
345 if( bs_show( &p_sys->bs, 8 ) != 0x0f )
349 dvbsub_decode_segment( &p_sys->dvbsub, &p_sys->bs );
351 i_end_data_marker = bs_read( &p_sys->bs, 8 );
353 /* Check if the page is to be displayed */
354 if( p_sys->dvbsub.p_page && p_sys->dvbsub.p_objects )
356 dvbsub_render( &p_sys->dvbsub, p_sys->p_vout );
359 vlc_object_release( p_sys->p_vout );
362 block_Release( p_block );
365 /* following functions are local */
366 /*****************************************************************************
367 * FindVout: Find a vout or wait for one to be created.
368 *****************************************************************************/
369 static vout_thread_t *FindVout( decoder_t *p_dec )
373 vout_thread_t *p_vout;
375 if( p_dec->b_die || p_dec->b_error )
379 p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
384 msleep( VOUT_OUTMEM_SLEEP );
389 static int dvbsub_init( dvbsub_all_t *p_dvbsub, int i_id )
393 memset( p_dvbsub, 0, sizeof( dvbsub_all_t ) );
396 p_dvbsub->i_id = i_id;
397 p_dvbsub->p_page = NULL;
398 p_dvbsub->p_objects = NULL;
399 for( i = 0; i < 255; i++ )
401 p_dvbsub->p_clut[i] = NULL;
403 for( i = 0; i < 16; i++ )
405 p_dvbsub->p_spu[i] = NULL;
410 static void free_all( dvbsub_all_t * );
412 static void dvbsub_clean( dvbsub_all_t *p_dvbsub )
414 free_all( p_dvbsub );
419 static void dvbsub_decode_clut( dvbsub_all_t *p_dvbsub, bs_t *s );
420 static void dvbsub_decode_page_composition( dvbsub_all_t *p_dvbsub, bs_t *s);
421 static void dvbsub_decode_region_composition( dvbsub_all_t *p_dvbsub, bs_t *s );
422 static void dvbsub_stop_display( dvbsub_all_t* p_dvbsub );
423 static void dvbsub_decode_object( dvbsub_all_t *p_dvbsub, bs_t *s );
425 static void free_page (dvbsub_page_t* p_p);
427 static void dvbsub_decode_segment( dvbsub_all_t *p_dvbspu, bs_t *s )
437 i_type = bs_read( s, 8 );
440 i_page_id = bs_read( s, 16 );
443 i_size = bs_show( s, 16 );
445 if( i_page_id != p_dvbspu->i_id )
447 bs_skip( s, 8 * ( 2 + i_size ) );
453 case DVBSUB_ST_CLUT_DEFINITION:
454 dvbsub_decode_clut( p_dvbspu, s );
456 case DVBSUB_ST_PAGE_COMPOSITION:
457 dvbsub_decode_page_composition( p_dvbspu, s );
459 case DVBSUB_ST_REGION_COMPOSITION:
460 dvbsub_decode_region_composition( p_dvbspu, s );
462 case DVBSUB_ST_OBJECT_DATA:
463 dvbsub_decode_object( p_dvbspu, s );
465 case DVBSUB_ST_ENDOFDISPLAY:
466 dvbsub_stop_display( p_dvbspu );
468 case DVBSUB_ST_STUFFING:
470 fprintf( stderr, "DVBSUB - Unsupported segment type : (%04x)",
472 bs_skip( s, 8 * ( 2 + i_size ) );
477 static void dvbsub_stop_display( dvbsub_all_t *p_dvbsub )
481 for( i = 0; p_dvbsub->p_spu[i] != NULL; i++ )
483 p_dvbsub->p_spu[i]->i_stop = p_dvbsub->i_pts;
487 static void dvbsub_decode_clut( dvbsub_all_t *p_dvbsub, bs_t *s )
489 uint16_t i_segment_length;
490 uint16_t i_processed_length;
493 uint8_t i_version_number;
495 i_segment_length = bs_read( s, 16 );
496 i_clut_id = bs_read( s, 8 );
497 i_version_number = bs_read( s, 4 );
499 // Check that this id doesn't not already exist
500 // with the same version number
501 // And allocate memory if necessary
502 if( p_dvbsub->p_clut[i_clut_id] != NULL)
504 if( p_dvbsub->p_clut[i_clut_id]->i_version_number == i_version_number )
506 //TODO skip the right number of bits
511 memset( p_dvbsub->p_clut[i_clut_id], 0, sizeof(dvbsub_clut_t) );
516 p_dvbsub->p_clut[i_clut_id] = trox_malloc( sizeof(dvbsub_clut_t) );
518 clut = p_dvbsub->p_clut[i_clut_id];
520 /* We don't have this version of the CLUT:
522 clut->i_version_number = i_version_number;
523 bs_skip( s, 4 ); /* Reserved bits */
524 i_processed_length = 2;
525 while( i_processed_length < i_segment_length )
527 uint8_t y, cb, cr, t;
531 i_id = bs_read( s, 8 );
532 i_type = bs_read( s, 3 );
536 if( bs_read( s, 1 ) )
539 cr = bs_read( s, 8 );
540 cb = bs_read( s, 8 );
542 i_processed_length += 6;
547 cr = bs_read( s, 4 );
548 cb = bs_read( s, 4 );
550 i_processed_length += 4;
553 /* According to EN 300-743 section 7.2.3 note 1, type should
554 * not have more than 1 bit set to one
555 But, some strams don't respect this note. */
559 clut->c_2b[i_id].Y = y;
560 clut->c_2b[i_id].Cr = cr;
561 clut->c_2b[i_id].Cb = cb;
562 clut->c_2b[i_id].T = t;
566 clut->c_4b[i_id].Y = y;
567 clut->c_4b[i_id].Cr = cr;
568 clut->c_4b[i_id].Cb = cb;
569 clut->c_4b[i_id].T = t;
573 clut->c_8b[i_id].Y = y;
574 clut->c_8b[i_id].Cr = cr;
575 clut->c_8b[i_id].Cb = cb;
576 clut->c_8b[i_id].T = t;
581 static void dvbsub_decode_page_composition( dvbsub_all_t *p_dvbsub, bs_t *s )
583 unsigned int i_version_number;
584 unsigned int i_state;
585 unsigned int i_segment_length;
589 i_segment_length = bs_read( s, 16 );
591 /* A page is composed by one or more region: */
592 i_timeout = bs_read( s, 8 );
593 i_version_number = bs_read( s, 4 );
594 i_state = bs_read( s, 2 );
596 /* TODO We assume it is a new page (i_state) */
597 if( p_dvbsub->p_page ) free_page( p_dvbsub->p_page );
599 bs_skip( s, 2 ); /* Reserved */
601 /* Allocate a new page */
602 p_dvbsub->p_page = trox_malloc( sizeof(dvbsub_page_t) );
603 p_dvbsub->p_page->i_timeout = i_timeout;
605 /* Number of regions: */
606 p_dvbsub->p_page->i_regions_number = (i_segment_length-2) / 6;
608 /* Special workaround for CAVENA encoders
609 * a page with no regions is sent instead of a 0x80 packet (End Of Display) */
610 if( p_dvbsub->p_page->i_regions_number == 0 )
612 dvbsub_stop_display( p_dvbsub );
614 /* /Special workaround */
616 p_dvbsub->p_page->regions =
617 trox_malloc(p_dvbsub->p_page->i_regions_number*sizeof(dvbsub_region_t));
618 for( i = 0; i < p_dvbsub->p_page->i_regions_number; i++ )
620 p_dvbsub->p_page->regions[i].i_id = bs_read( s, 8 );
621 bs_skip( s, 8 ); /* Reserved */
622 p_dvbsub->p_page->regions[i].i_x = bs_read( s, 16 );
623 p_dvbsub->p_page->regions[i].i_y = bs_read( s, 16 );
624 p_dvbsub->p_page->regions[i].p_object = NULL;
629 static void dvbsub_decode_region_composition( dvbsub_all_t *p_dvbsub, bs_t *s )
631 dvbsub_region_t* p_region = NULL;
632 unsigned int i_segment_length;
633 unsigned int i_processed_length;
634 unsigned int i_region_id;
637 i_segment_length = bs_read( s, 16 );
640 i_region_id = bs_read( s, 8 );
641 for( i = 0; i < p_dvbsub->p_page->i_regions_number; i++ )
643 if( p_dvbsub->p_page->regions[i].i_id == i_region_id )
645 p_region = &(p_dvbsub->p_page->regions[i]);
649 if( p_region == NULL )
652 * The region has never been declared before
654 fprintf( stderr, "Decoding of undeclared region N/A\n" );
658 /* Skip version number and fill flag */
659 if( bs_show( s, 4 ) == p_region->i_version_number )
661 fprintf( stderr, "Skipping already known region N/A\n" );
662 /* TODO Skip the right number of bits */
665 /* Region attributes */
666 p_region->i_version_number = bs_read( s, 4 );
667 p_region->b_fill = bs_read( s, 1 );
668 bs_skip( s, 3 ); /* Reserved */
669 p_region->i_width = bs_read( s, 16 );
670 p_region->i_height = bs_read( s, 16 );
671 p_region->i_level_comp = bs_read( s, 3 );
672 p_region->i_depth = bs_read( s, 3 );
673 bs_skip( s, 2 ); /* Reserved */
674 p_region->i_clut = bs_read( s, 8 );
675 p_region->i_8bp_code = bs_read( s, 8 );
676 p_region->i_4bp_code = bs_read( s, 4 );
677 p_region->i_2bp_code = bs_read( s, 2 );
678 bs_skip( s, 2 ); /* Reserved */
680 /* List of objects in the region: */
681 /* We already skipped 10 bytes */
683 i_processed_length = 10;
684 while( i_processed_length < i_segment_length )
686 /* We create a new object */
687 dvbsub_objectdef_t *p_obj = trox_malloc(sizeof(dvbsub_objectdef_t));
689 /* We parse object properties */
690 p_obj->p_next = NULL;
691 p_obj->i_id = bs_read( s, 16 );
692 p_obj->i_type = bs_read( s, 2 );
693 p_obj->i_provider = bs_read( s, 2 );
694 p_obj->i_xoffset = bs_read( s, 12 );
695 bs_skip( s, 4 ); /* Reserved */
696 p_obj->i_yoffset = bs_read( s, 12 );
698 i_processed_length += 6;
700 if( p_obj->i_type == DVBSUB_OT_BASIC_CHAR ||
701 p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING )
703 p_obj->i_fg_pc = bs_read( s, 8 );
704 p_obj->i_bg_pc = bs_read( s, 8 );
705 i_processed_length += 2;
709 if( p_region->p_object )
711 dvbsub_objectdef_t *p_o;
712 for( p_o = p_region->p_object; ; p_o = p_o->p_next )
714 if( p_o->p_next == NULL )
723 p_region->p_object = p_obj;
728 static dvbsub_image_t* dvbsub_parse_pdata( dvbsub_all_t *p_dvbsub, bs_t *s, uint16_t length );
729 static uint16_t dvbsub_count0x11( bs_t *s, uint16_t* p, dvbsub_image_t* p_image);
731 static void dvbsub_decode_object( dvbsub_all_t *p_dvbsub, bs_t *s )
733 dvbsub_object_t *p_obj;
734 uint16_t i_segment_length;
736 /* Memory Allocation */
737 p_obj = trox_malloc ( sizeof ( dvbsub_object_t ) );
738 p_obj->p_next = NULL;
740 i_segment_length = bs_read( s, 16 );
742 /* TODO Check we don't already have this object / this version */
743 p_obj->i_id = bs_read( s, 16 );
744 p_obj->i_version_number = bs_read( s, 4 );
745 p_obj->i_coding_method = bs_read( s, 2 );
746 p_obj->b_non_modify_color= bs_read( s, 1 );
747 bs_skip( s, 1 ); /* Reserved */
749 if( p_obj->i_coding_method == 0x00 )
751 uint16_t i_topfield_length;
752 uint16_t i_bottomfield_length;
754 i_topfield_length = bs_read( s, 16 );
755 i_bottomfield_length= bs_read( s, 16 );
757 p_obj->topfield = dvbsub_parse_pdata( p_dvbsub, s, i_topfield_length );
758 p_obj->bottomfield = dvbsub_parse_pdata( p_dvbsub, s, i_bottomfield_length );
762 bs_skip( s, (i_segment_length - 3 ) * 8 );
764 * DVB subtitling as characters */
767 /* Add this object to the list of the page */
768 p_obj->p_next = p_dvbsub->p_objects;
769 p_dvbsub->p_objects = p_obj;
772 static dvbsub_image_t* dvbsub_parse_pdata( dvbsub_all_t *p_dvbsub, bs_t *s, uint16_t length )
774 dvbsub_image_t* p_image;
775 uint16_t i_processed_length=0;
777 uint16_t i_cols_last=0;
779 p_image = trox_malloc ( sizeof ( dvbsub_image_t) );
780 p_image->p_last=NULL;
782 memset(p_image->i_cols, 0, 576*sizeof(uint16_t));
784 /* Let's parse it a first time to determine the size of the buffer */
785 while( i_processed_length < length)
787 switch( bs_read( s, 8 ) )
790 fprintf(stderr, "0x10 N/A\n");
793 i_processed_length +=
794 1 + dvbsub_count0x11( s, &(p_image->i_cols[i_lines]),
798 fprintf(stderr, "0x12 N/A\n");
801 fprintf(stderr, "0x20 N/A\n");
804 fprintf(stderr, "0x21 N/A\n");
807 fprintf(stderr, "0x22 N/A\n");
810 i_processed_length++;
816 p_image->i_rows = i_lines;
817 p_image->i_cols[i_lines] = i_cols_last;
819 /* Check word-aligned bits */
820 if( bs_show( s, 8 ) == 0x00 )
830 static void add_rle_code( dvbsub_image_t *p, uint16_t num, uint8_t color )
832 if(p->p_last != NULL)
834 p->p_last->p_next = trox_malloc (sizeof (dvbsub_rle_t));
835 p->p_last = p->p_last->p_next;
839 p->p_codes = trox_malloc (sizeof (dvbsub_rle_t));
840 p->p_last = p->p_codes;
842 p->p_last->i_num = num;
843 p->p_last->i_color_code = color;
844 p->p_last->p_next = NULL;
848 static uint16_t dvbsub_count0x11( bs_t *s, uint16_t* p, dvbsub_image_t* p_image )
850 uint16_t i_processed=0;
852 uint16_t i_count = 0;
857 if( (i_color = bs_read( s, 4 )) != 0x00 )
862 /* 1 pixel of color code '0000' */
863 add_rle_code( p_image, 1, i_color );
867 if( bs_read( s, 1 ) == 0x00 ) // Switch1
869 if( bs_show( s, 3 ) != 0x00 )
871 i_count = 2 + bs_read( s, 3 );
873 add_rle_code( p_image, i_count, 0x00 );
884 if( bs_read( s, 1 ) == 0x00) //Switch2
886 i_count = 4 + bs_read( s, 2 );
887 i_color = bs_read( s, 4 );
890 add_rle_code( p_image, i_count, i_color );
894 switch ( bs_read( s, 2 ) ) //Switch3
899 add_rle_code( p_image, 1, 0x00 );
904 add_rle_code( p_image, 2, 0x00 );
907 i_count = 9 + bs_read( s, 4 );
908 i_color = bs_read( s, 4 );
911 add_rle_code( p_image, i_count, i_color );
914 i_count= 25 + bs_read( s, 8 );
915 i_color = bs_read( s, 4 );
918 add_rle_code( p_image, i_count, i_color );
928 return ( i_processed + 7 ) / 8 ;
931 static void free_image (dvbsub_image_t* p_i)
934 dvbsub_rle_t* p2=NULL;
936 for( p1 = p_i->p_codes; p1 != NULL; p1=p2)
946 static void free_object (dvbsub_object_t* p_o)
951 static void free_objectdefs ( dvbsub_objectdef_t* p_o)
953 dvbsub_objectdef_t* p1;
954 dvbsub_objectdef_t* p2=NULL;
956 for( p1 = p_o; p1 != NULL; p1=p2)
964 static void free_regions (dvbsub_region_t* p_r, uint8_t nb)
968 for (i = 0; i<nb; i++) free_objectdefs ( p_r[i].p_object );
973 static void free_objects (dvbsub_object_t* p_o)
976 dvbsub_object_t* p2=NULL;
978 for( p1 = p_o; p1 != NULL; p1=p2)
981 free_image (p1->topfield);
982 free_image (p1->bottomfield);
987 static void free_clut ( dvbsub_clut_t* p_c )
992 static void free_page (dvbsub_page_t* p_p)
994 free_regions (p_p->regions, p_p->i_regions_number);
999 static void free_spu( subpicture_t *p_spu )
1003 free_image(((dvbsub_render_t *)p_spu->p_sys->p_data)->p_rle_top);
1004 free_image(((dvbsub_render_t *)p_spu->p_sys->p_data)->p_rle_bot);
1005 trox_free(p_spu->p_sys->p_data);
1006 trox_free( p_spu->p_sys );
1007 p_spu->p_sys = NULL;
1011 static void free_all ( dvbsub_all_t* p_a )
1015 for(i=0; i<0xff; i++) if (p_a->p_clut[i]) free_clut ( p_a->p_clut[i] );
1016 for(i=0; i<16; i++) if (p_a->p_spu[i]) free_spu ( p_a->p_spu[i] );
1017 if(p_a->p_page) free_page( p_a->p_page );
1018 free_objects (p_a->p_objects);
1021 static void RenderYUY2( vout_thread_t *p_vout, picture_t *p_pic,
1022 const subpicture_t *p_spu )
1024 /* Common variables */
1030 dvbsub_render_t* p_r = ((dvbsub_render_t *)p_spu->p_sys->p_data);
1031 dvbsub_image_t* p_im = p_r->p_rle_top;
1034 p_desty = p_pic->Y_PIXELS;
1035 //let's render the 1st frame
1036 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1038 // if( p_c->y != 0 && p_c->t < 0x20)
1039 if( p_c->y != 0 && p_c->t < 0x20)
1043 //memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1044 // In YUY2 we have to set pixel per pixel
1045 for( i_cnt = 0; i_cnt < p_c->i_num; i_cnt+=2 )
1047 memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt, p_c->y, 1);
1048 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+1, p_c->cr, 1);
1049 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+2, p_c->y, 1);
1050 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+3, p_c->cb, 1);
1054 if(j >= p_im->i_cols[i])
1058 if( i>= p_im->i_rows) break;
1060 //idem for the second frame
1061 p_im = p_r->p_rle_bot; i=0; j=0;
1062 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1064 if( p_c->y != 0 && p_c->t < 0x20)
1068 //memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1069 // In YUY2 we have to set pixel per pixel
1070 for( i_cnt = 0; i_cnt < p_c->i_num; i_cnt+=2 )
1072 memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt, p_c->y, 1);
1073 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+1, p_c->cr, 1);
1074 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+2, p_c->y, 1);
1075 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+3, p_c->cb, 1);
1079 if(j >= p_im->i_cols[i])
1083 if( i>= p_im->i_rows) break;
1088 static void RenderI42x( vout_thread_t *p_vout, picture_t *p_pic,
1089 const subpicture_t *p_spu )
1091 /* Common variables */
1098 dvbsub_render_t* p_r = ((dvbsub_render_t *)p_spu->p_sys->p_data);
1099 dvbsub_image_t* p_im = p_r->p_rle_top;
1102 p_desty = p_pic->Y_PIXELS;
1103 p_destu = p_pic->U_PIXELS;
1104 p_destv = p_pic->V_PIXELS;
1105 //let's render the 1st frame
1106 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1112 //memset(p_dest+ y*p_pic->U_PITCH*2 + x, p_c->cr, p_c->i_num);
1113 // memset(p_desty+ (y)*p_pic->Y_PITCH + x, p_c->cr, p_c->i_num);
1114 //memset(p_dest+ y*p_pic->V_PITCH*2 + x, p_c->cb, p_c->i_num);
1115 //memset(p_destu+ (y)*p_pic->Y_PITCH + x, p_c->cb, p_c->i_num);
1116 memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1117 // memset(p_desty+ 2*y*p_pic->U_PITCH + x, p_c->cr, p_c->i_num);
1118 // memset(p_desty+ 2*y*p_pic->V_PITCH + x, p_c->cb, p_c->i_num);
1121 if(j >= p_im->i_cols[i])
1125 if( i>= p_im->i_rows) break;
1127 //idem for the second frame
1128 p_im = p_r->p_rle_bot; i=0; j=0;
1129 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1131 if( p_c->y != 0 && p_c->t < 0x20)
1135 // memset(p_desty+ y*p_pic->U_PITCH*2 + x, p_c->cr, p_c->i_num);
1136 // memset(p_desty+ y*p_pic->V_PITCH*2 + x, p_c->cb, p_c->i_num);
1137 memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1138 // memset(p_desty+ 2*y*p_pic->U_PITCH + x, p_c->cr, p_c->i_num);
1139 // memset(p_desty+ 2*y*p_pic->V_PITCH + x, p_c->cb, p_c->i_num);
1142 if(j >= p_im->i_cols[i])
1146 if( i>= p_im->i_rows) break;
1150 static void dvbsub_RenderDVBSUB( vout_thread_t *p_vout, picture_t *p_pic,
1151 const subpicture_t *p_spu )
1153 /* If we have changed the language on the fly */
1155 if( p_spu->p_sys == NULL || p_spu->p_sys->b_obsolete )
1160 switch( p_vout->output.i_chroma )
1162 /* I420 target, no scaling */
1163 case VLC_FOURCC('I','4','2','2'):
1164 case VLC_FOURCC('I','4','2','0'):
1165 case VLC_FOURCC('I','Y','U','V'):
1166 case VLC_FOURCC('Y','V','1','2'):
1167 /* As long as we just use Y info, I422 and YV12 are just equivalent
1168 * to I420. Remember to change it the day we'll take into account
1170 RenderI42x( p_vout, p_pic, p_spu );
1173 /* RV16 target, scaling */
1174 case VLC_FOURCC('R','V','1','6'):
1175 msg_Err(p_vout, _("unimplemented chroma: RV16"));
1176 /* RenderRV16( p_vout, p_pic, p_spu ); */
1179 /* RV32 target, scaling */
1180 case VLC_FOURCC('R','V','2','4'):
1181 case VLC_FOURCC('R','V','3','2'):
1182 msg_Err(p_vout, _("unimplemented chroma: RV32"));
1183 /* RenderRV32( p_vout, p_pic, p_spu ); */
1186 /* NVidia overlay, no scaling */
1187 case VLC_FOURCC('Y','U','Y','2'):
1188 RenderYUY2( p_vout, p_pic, p_spu );
1192 msg_Err( p_vout, "unknown chroma, can't render SPU" );
1197 static void dvbsub_Destroy( subpicture_t *p_spu )
1202 static void dvbsub_render( dvbsub_all_t *dvbsub, vout_thread_t *p_vout )
1204 dvbsub_region_t* p_region;
1205 dvbsub_objectdef_t* p_objectdef;
1206 dvbsub_object_t* p_o;
1207 dvbsub_object_t* p_object;
1208 dvbsub_object_t* p_object_old;
1209 dvbsub_render_t* p_render;
1214 /* loop on regions */
1215 for( i = 0; i < dvbsub->p_page->i_regions_number; i++ )
1217 p_region = &(dvbsub->p_page->regions[i]);
1219 /* loop on objects */
1220 for(p_objectdef = p_region->p_object; p_objectdef != NULL; p_objectdef = p_objectdef->p_next )
1222 /* Look for the right object */
1223 p_object = dvbsub->p_objects;
1224 while((p_object!=NULL) && (p_object->i_id != p_objectdef->i_id))
1226 p_object = p_object->p_next;
1231 msg_Err(p_vout, _("internal DvbSub decoder error"));
1235 /* Allocate the render structure */
1236 p_render = trox_malloc(sizeof(dvbsub_render_t));
1237 p_render->i_x = p_region->i_x + p_objectdef->i_xoffset;
1238 p_render->i_y = p_region->i_y + p_objectdef->i_yoffset;
1239 p_render->p_rle_top = p_object->topfield;
1240 p_render->p_rle_bot = p_object->bottomfield;
1242 // if we did not recieved the CLUT yet
1243 if ( !dvbsub->p_clut[p_region->i_clut] ) return;
1245 /* Compute the color datas according to the appropriate CLUT */
1246 for(p_c=p_render->p_rle_top->p_codes;p_c->p_next!=NULL; p_c=p_c->p_next)
1248 //TODO We assume here we are working in 4bp
1249 p_c->y=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Y;
1250 p_c->cr=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cr;
1251 p_c->cb=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cb;
1252 p_c->t=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].T;
1254 for(p_c=p_render->p_rle_bot->p_codes;p_c->p_next!=NULL; p_c=p_c->p_next)
1256 //TODO We assume here we are working in 4bp
1257 p_c->y=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Y;
1258 p_c->cr=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cr;
1259 p_c->cb=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cb;
1260 p_c->t=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].T;
1264 /* Allocate the subpicture internal data. */
1265 dvbsub->p_spu[j] = vout_CreateSubPicture( p_vout, MEMORY_SUBPICTURE );
1266 if( dvbsub->p_spu[j] == NULL )
1268 msg_Err(p_vout, "Unable to allocate memory, skipping");
1271 /* Set the pf_render callback */
1272 dvbsub->p_spu[j]->pf_render = dvbsub_RenderDVBSUB;
1273 dvbsub->p_spu[j]->p_sys = trox_malloc( sizeof( subpicture_sys_t ));
1274 dvbsub->p_spu[j]->p_sys->p_data = p_render;
1275 dvbsub->p_spu[j]->p_sys->b_obsolete=0;
1276 dvbsub->p_spu[j]->pf_destroy = dvbsub_Destroy;
1277 dvbsub->p_spu[j]->i_start = dvbsub->i_pts;
1278 dvbsub->p_spu[j]->i_stop = dvbsub->p_spu[j]->i_start + dvbsub->p_page->i_timeout*1000000;
1279 dvbsub->p_spu[j]->b_ephemer = VLC_FALSE;
1281 // At this stage, we have all we need in p_render
1282 // We need to free the object
1283 //Remove this object from the list
1284 p_object_old = p_object;
1285 if(p_object == dvbsub->p_objects)
1286 dvbsub->p_objects = p_object->p_next;
1289 for(p_o = dvbsub->p_objects; p_o->p_next != p_object; p_o=p_o->p_next);
1290 p_o->p_next = p_object->p_next;
1292 free_object(p_object_old);
1294 vout_DisplaySubPicture( p_vout, dvbsub->p_spu[j] );