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.5 2003/11/24 00:39:01 fenrir Exp $
8 * Authors: Damien LUCAS <damien.lucas@anevia.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
29 #include <vlc/decoder.h>
33 /*****************************************************************************
35 *****************************************************************************/
36 static int Open ( vlc_object_t *p_this );
37 static void Close( vlc_object_t *p_this );
40 add_category_hint( N_("subtitles"), NULL, VLC_TRUE );
41 set_description( _("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;
188 dvbsub_clut_t* p_clut[0xff];
189 dvbsub_page_t* p_page;
190 dvbsub_object_t* p_objects;
191 subpicture_t* p_spu[16];
194 struct subpicture_sys_t
197 void * p_data; /* rle datas are stored */
198 vlc_object_t* p_input; /* Link to the input */
199 vlc_bool_t b_obsolete;
204 vout_thread_t *p_vout;
211 // List of different SEGMENT TYPES
212 // According to EN 300-743, table 2
213 #define DVBSUB_ST_PAGE_COMPOSITION 0x10
214 #define DVBSUB_ST_REGION_COMPOSITION 0x11
215 #define DVBSUB_ST_CLUT_DEFINITION 0x12
216 #define DVBSUB_ST_OBJECT_DATA 0x13
217 #define DVBSUB_ST_ENDOFDISPLAY 0x80
218 #define DVBSUB_ST_STUFFING 0xff
219 // List of different OBJECT TYPES
220 // According to EN 300-743, table 6
221 #define DVBSUB_OT_BASIC_BITMAP 0x00
222 #define DVBSUB_OT_BASIC_CHAR 0x01
223 #define DVBSUB_OT_COMPOSITE_STRING 0x02
225 // According to EN 300-743, table 9
226 #define DVBSUB_DT_2BP_CODE_STRING 0x10
227 #define DVBSUB_DT_4BP_CODE_STRING 0x11
228 #define DVBSUB_DT_8BP_CODE_STRING 0x12
229 #define DVBSUB_DT_24_TABLE_DATA 0x20
230 #define DVBSUB_DT_28_TABLE_DATA 0x21
231 #define DVBSUB_DT_48_TABLE_DATA 0x22
232 #define DVBSUB_DT_END_LINE 0xf0
234 /*****************************************************************************
236 *****************************************************************************/
237 static void Decode ( decoder_t *, block_t ** );
239 static vout_thread_t *FindVout( decoder_t * );
241 static void RenderI42x( vout_thread_t *, picture_t *, const subpicture_t *,
243 static void RenderYUY2( vout_thread_t *, picture_t *, const subpicture_t *,
245 static void dvbsub_clut_add_entry ( dvbsub_clut_t* clut, uint8_t type,
246 uint8_t id, uint8_t y, uint8_t cr,
247 uint8_t cb, uint8_t t);
248 static void dvbsub_add_objectdef_to_region ( dvbsub_objectdef_t* p_obj,
249 dvbsub_region_t* p_region );
250 static dvbsub_image_t* dvbsub_parse_pdata ( dvbsub_thread_t* ,uint16_t );
251 static uint16_t dvbsub_count0x11(dvbsub_thread_t* p_spudec,
253 dvbsub_image_t* p_image);
254 static void dvbsub_decode_segment ( dvbsub_thread_t *, dvbsub_all_t* );
255 static void dvbsub_decode_page_composition ( dvbsub_thread_t *, dvbsub_all_t* );
256 static void dvbsub_decode_region_composition ( dvbsub_thread_t*, dvbsub_all_t*);
257 static void dvbsub_decode_object ( dvbsub_thread_t*, dvbsub_all_t* );
258 static vlc_bool_t dvbsub_check_page ( dvbsub_all_t* );
259 static void dvbsub_render ( dvbsub_thread_t *p_spudec,dvbsub_all_t* );
260 static int dvbsub_parse ( dvbsub_thread_t *p_spudec, dvbsub_all_t* dvbsub );
261 static void dvbsub_decode_clut ( dvbsub_thread_t*, dvbsub_all_t*);
262 static void dvbsub_stop_display ( dvbsub_thread_t* p_dec, dvbsub_all_t* dvbsub);
264 static void free_image (dvbsub_image_t* p_i);
265 static void free_object (dvbsub_object_t* p_o);
266 static void free_regions (dvbsub_region_t* p_r, uint8_t nb);
267 static void free_objects (dvbsub_object_t* p_o);
268 static void free_clut ( dvbsub_clut_t* p_c);
269 static void free_page (dvbsub_page_t* p_p);
270 static void free_all ( dvbsub_all_t* p_a );
273 /*****************************************************************************
274 * Open: probe the decoder and return score
275 *****************************************************************************
276 * Tries to launch a decoder and return score so that the interface is able
278 *****************************************************************************/
279 static int Open( vlc_object_t *p_this )
281 decoder_t *p_dec = (decoder_t*) p_this;
282 decoder_sys_t *p_sys;
284 if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
289 p_dec->pf_decode_subs = Decode;
290 p_sys = p_dec->p_sys = malloc( sizeof( decoder_sys_t ) );
292 p_sys->p_vout = NULL;
295 es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'd','v','b','s' ) );
300 /*****************************************************************************
302 *****************************************************************************/
303 static void Close( vlc_object_t *p_this )
305 decoder_t *p_dec = (decoder_t*) p_this;
306 decoder_sys_t *p_sys = p_dec->p_sys;
308 if( p_sys->p_vout && p_sys->p_vout->p_subpicture != NULL )
310 subpicture_t * p_subpic;
312 for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
314 p_subpic = &p_sys->p_vout->p_subpicture[i_subpic];
315 if( p_subpic != NULL &&
316 ( ( p_subpic->i_status == RESERVED_SUBPICTURE )
317 || ( p_subpic->i_status == READY_SUBPICTURE ) ) )
319 vout_DestroySubPicture( p_sys->p_vout, p_subpic );
327 /*****************************************************************************
328 * RunDecoder: this function is called just after the thread is created
329 *****************************************************************************/
330 static int RunDecoder( decoder_fifo_t * p_fifo )
332 dvbsub_thread_t * p_dvbsubdec;
333 // vout_thread_t * p_vout_backup = NULL;
336 /* Allocate the memory needed to store the thread's structure */
337 p_dvbsubdec = (dvbsub_thread_t *)trox_malloc( sizeof(dvbsub_thread_t) );
338 if ( p_dvbsubdec == NULL )
340 msg_Err( p_fifo, "out of memory" );
341 DecoderError( p_fifo );
345 * Initialize the thread properties
347 p_dvbsubdec->p_vout = NULL;
348 p_dvbsubdec->p_fifo = p_fifo;
350 * Initialize thread and free configuration
352 p_dvbsubdec->p_fifo->b_error = InitThread( p_dvbsubdec );
354 dvbsub.p_objects=NULL;
355 for(k=0; k<0xff; k++) dvbsub.p_clut[k] = NULL;
356 for(k=0; k<16; k++) dvbsub.p_spu[k] = NULL;
359 * Main loop - it is not executed if an error occured during
362 while( (!p_dvbsubdec->p_fifo->b_die) && (!p_dvbsubdec->p_fifo->b_error) )
364 dvbsub_parse( p_dvbsubdec, &dvbsub );
365 p_dvbsubdec->p_vout = FindVout( p_dvbsubdec );
366 if( p_dvbsubdec->p_vout )
368 // Check if the page is to be displayed
369 if(dvbsub_check_page(&dvbsub))
371 dvbsub_render(p_dvbsubdec, &dvbsub);
373 vlc_object_release( p_dvbsubdec->p_vout );
376 // Free all structures
377 //dvbsub.p_objects=NULL;
378 //for(k=0; k<16; k++)
379 // if(dvbsub.p_spu[k] != NULL)
380 // dvbsub.p_spu[k]->p_sys->b_obsolete = 1;
385 if( p_dvbsubdec->p_fifo->b_error )
387 DecoderError( p_dvbsubdec->p_fifo );
389 EndThread( p_dvbsubdec, &dvbsub );
393 EndThread( p_dvbsubdec, &dvbsub );
398 /* following functions are local */
399 /*****************************************************************************
400 * FindVout: Find a vout or wait for one to be created.
401 *****************************************************************************/
402 static vout_thread_t *FindVout( decoder_t *p_dec )
406 vout_thread_t *p_vout;
408 if( p_dec->b_die || p_dec->b_error )
412 p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
417 msleep( VOUT_OUTMEM_SLEEP );
421 /*****************************************************************************
422 * EndThread: thread destruction
423 *****************************************************************************
424 * This function is called when the thread ends after a sucessful
426 *****************************************************************************/
427 static void EndThread( dvbsub_thread_t *p_dvbsubdec, dvbsub_all_t* p_dvbsub )
429 if( p_dvbsubdec->p_vout != NULL
430 && p_dvbsubdec->p_vout->p_subpicture != NULL )
432 subpicture_t * p_subpic;
434 for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
436 p_subpic = &p_dvbsubdec->p_vout->p_subpicture[i_subpic];
437 if( p_subpic != NULL &&
438 ( ( p_subpic->i_status == RESERVED_SUBPICTURE )
439 || ( p_subpic->i_status == READY_SUBPICTURE ) ) )
441 vout_DestroySubPicture( p_dvbsubdec->p_vout, p_subpic );
445 CloseBitstream( &p_dvbsubdec->bit_stream );
446 trox_free( p_dvbsubdec );
451 static int dvbsub_parse ( dvbsub_thread_t *p_spudec,
452 dvbsub_all_t* dvbsub )
454 unsigned int data_identifier;
455 unsigned int subtitle_stream_id;
456 unsigned int nextbits;
457 uint32_t end_data_marker;
458 /* Re-align the buffer on an 8-bit boundary */
459 RealignBits( &p_spudec->bit_stream );
460 data_identifier = GetBits( &p_spudec->bit_stream, 8 );
461 subtitle_stream_id = GetBits( &p_spudec->bit_stream, 8 );
462 nextbits = ShowBits( &p_spudec->bit_stream, 8 );
463 while(nextbits == 0x0f )
465 dvbsub_decode_segment( p_spudec, dvbsub );
466 nextbits = ShowBits( &p_spudec->bit_stream, 8 );
468 end_data_marker = GetBits( &p_spudec->bit_stream, 8 );
474 static void dvbsub_decode_segment ( dvbsub_thread_t * p_spudec,
475 dvbsub_all_t * dvbsub )
477 unsigned int sync_byte;
478 unsigned int segment_type;
480 uint16_t segment_length;
482 sync_byte = GetBits( &p_spudec->bit_stream, 8 );
483 segment_type = GetBits( &p_spudec->bit_stream, 8 );
484 page_id = GetBits( &p_spudec->bit_stream, 16 );
485 segment_length = ShowBits( &p_spudec->bit_stream, 16 );
486 if( page_id != ((dvb_spuinfo_t*)p_spudec->p_fifo->p_spuinfo)->i_id )
488 //TODO should use GetChunk
489 for(k=0; k<segment_length+2; k++) GetBits( &p_spudec->bit_stream, 8 );
492 switch( segment_type )
494 case DVBSUB_ST_CLUT_DEFINITION:
495 dvbsub_decode_clut ( p_spudec, dvbsub );
497 case DVBSUB_ST_PAGE_COMPOSITION:
498 dvbsub_decode_page_composition ( p_spudec, dvbsub );
500 case DVBSUB_ST_REGION_COMPOSITION:
501 dvbsub_decode_region_composition ( p_spudec, dvbsub );
503 case DVBSUB_ST_OBJECT_DATA:
504 dvbsub_decode_object ( p_spudec, dvbsub );
506 case DVBSUB_ST_ENDOFDISPLAY:
507 dvbsub_stop_display ( p_spudec, dvbsub);
509 case DVBSUB_ST_STUFFING:
511 fprintf(stderr, "*** DVBSUB - Unsupported segment type ! (%04x)\n",
513 GetBits( &p_spudec->bit_stream, 16 );
514 for(k=0; k<segment_length; k++)
515 GetBits( &p_spudec->bit_stream, 8 );
522 static void dvbsub_decode_page_composition (dvbsub_thread_t *p_spudec,
523 dvbsub_all_t *dvbsub)
525 unsigned int i_version_number;
526 unsigned int i_state;
527 unsigned int i_segment_length;
530 i_segment_length = GetBits( &p_spudec->bit_stream, 16 );
531 //A page is composed by one or more region:
532 i_timeout = GetBits( &p_spudec->bit_stream, 8 );
533 i_version_number = GetBits( &p_spudec->bit_stream, 4 );
534 i_state = GetBits( &p_spudec->bit_stream, 2 );
535 // TODO We assume it is a new page (i_state)
536 if (dvbsub->p_page) free_page(dvbsub->p_page);
538 GetBits( &p_spudec->bit_stream, 2 ); /* Reserved */
539 //Allocate a new page
540 dvbsub->p_page = trox_malloc (sizeof(dvbsub_page_t));
541 dvbsub->p_page->i_timeout = i_timeout;
542 // Number of regions:
543 dvbsub->p_page->i_regions_number = (i_segment_length-2) / 6;
545 /* Special workaround for CAVENA encoders
546 * a page with no regions is sent instead of a 0x80 packet (End Of Display) */
547 if( dvbsub->p_page->i_regions_number == 0 )
549 dvbsub_stop_display(p_spudec, dvbsub );
551 /* /Special workaround */
553 dvbsub->p_page->regions =
554 trox_malloc(dvbsub->p_page->i_regions_number*sizeof(dvbsub_region_t));
555 for(k=0; k<dvbsub->p_page->i_regions_number ; k++)
557 dvbsub->p_page->regions[k].i_id = GetBits( &p_spudec->bit_stream, 8 );
558 GetBits( &p_spudec->bit_stream, 8 ); /* Reserved */
559 dvbsub->p_page->regions[k].i_x = GetBits( &p_spudec->bit_stream, 16 );
560 dvbsub->p_page->regions[k].i_y = GetBits( &p_spudec->bit_stream, 16 );
561 dvbsub->p_page->regions[k].p_object = NULL;
566 static void dvbsub_decode_region_composition (dvbsub_thread_t *p_spudec,
567 dvbsub_all_t *dvbsub)
569 unsigned int i_segment_length;
570 unsigned int i_processed_length;
571 unsigned int i_region_id;
572 dvbsub_region_t* p_region;
575 i_segment_length = GetBits( &p_spudec->bit_stream, 16 );
577 i_region_id = GetBits( &p_spudec->bit_stream, 8 );
578 for(k=0; k<dvbsub->p_page->i_regions_number; k++)
580 if ( dvbsub->p_page->regions[k].i_id == i_region_id )
581 p_region = &(dvbsub->p_page->regions[k]);
586 // The region has never been declared before
588 fprintf (stderr, "Decoding of undeclared region N/A...\n");
591 // Skip version number and fill flag
592 if (ShowBits( &p_spudec->bit_stream, 4 ) == p_region->i_version_number)
594 fprintf(stderr, "Skipping already known region N/A ...\n");
595 // TODO Skip the right number of bits
598 p_region->i_version_number = GetBits( &p_spudec->bit_stream, 4 );
599 p_region->b_fill = GetBits( &p_spudec->bit_stream, 1 );
600 GetBits( &p_spudec->bit_stream, 3 ); /* Reserved */
601 p_region->i_width = GetBits( &p_spudec->bit_stream, 16 );
602 p_region->i_height = GetBits( &p_spudec->bit_stream, 16 );
603 p_region->i_level_comp = GetBits( &p_spudec->bit_stream, 3 );
604 p_region->i_depth = GetBits( &p_spudec->bit_stream, 3 );
605 GetBits( &p_spudec->bit_stream, 2 ); /* Reserved */
606 p_region->i_clut = GetBits( &p_spudec->bit_stream, 8 );
607 p_region->i_8bp_code = GetBits( &p_spudec->bit_stream, 8 );
608 p_region->i_4bp_code = GetBits( &p_spudec->bit_stream, 4 );
609 p_region->i_2bp_code = GetBits( &p_spudec->bit_stream, 2 );
610 GetBits( &p_spudec->bit_stream, 2 ); /* Reserved */
611 // List of objects in the region:
612 // We already skipped 10 bytes
613 i_processed_length = 10;
614 while ( i_processed_length < i_segment_length )
616 // We create a new object
617 dvbsub_objectdef_t* p_obj;
618 p_obj = trox_malloc(sizeof(dvbsub_objectdef_t));
619 // We parse object properties
620 p_obj->i_id = GetBits( &p_spudec->bit_stream, 16 );
621 p_obj->i_type = GetBits( &p_spudec->bit_stream, 2 );
622 p_obj->i_provider = GetBits( &p_spudec->bit_stream, 2 );
623 p_obj->i_xoffset = GetBits( &p_spudec->bit_stream, 12 );
624 GetBits( &p_spudec->bit_stream, 4 ); /* Reserved */
625 p_obj->i_yoffset = GetBits( &p_spudec->bit_stream, 12 );
626 i_processed_length += 6;
627 if ( p_obj->i_type == DVBSUB_OT_BASIC_CHAR
628 || p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING )
630 p_obj->i_fg_pc = GetBits( &p_spudec->bit_stream, 8 );
631 p_obj->i_bg_pc = GetBits( &p_spudec->bit_stream, 8 );
632 i_processed_length += 2;
634 p_obj->p_next = NULL;
635 dvbsub_add_objectdef_to_region(p_obj, p_region);
640 static void dvbsub_decode_object (dvbsub_thread_t* p_spudec,
641 dvbsub_all_t* dvbsub)
643 dvbsub_object_t* p_obj;
644 dvbsub_object_t* p_o;
645 uint16_t i_segment_length;
646 uint16_t i_topfield_length;
647 uint16_t i_bottomfield_length;
649 p_obj = trox_malloc ( sizeof ( dvbsub_object_t ) );
651 i_segment_length = GetBits( &p_spudec->bit_stream, 16 );
652 p_obj->i_id = GetBits( &p_spudec->bit_stream, 16 );
653 p_obj->i_version_number = GetBits( &p_spudec->bit_stream, 4 );
654 // TODO Check we don't already have this object / this version
655 p_obj->i_coding_method = GetBits( &p_spudec->bit_stream, 2 );
656 p_obj->b_non_modify_color = GetBits( &p_spudec->bit_stream, 1 );
657 GetBits( &p_spudec->bit_stream, 1 ); /* Reserved */
658 if(p_obj->i_coding_method == 0x00)
660 i_topfield_length = GetBits( &p_spudec->bit_stream, 16 );
661 i_bottomfield_length = GetBits( &p_spudec->bit_stream, 16 );
662 p_obj->topfield = dvbsub_parse_pdata (p_spudec, i_topfield_length);
664 dvbsub_parse_pdata (p_spudec, i_bottomfield_length);
668 GetBits(&p_spudec->bit_stream, (i_segment_length -3) *8);
670 // DVB subtitling as characters
672 // Add this object to the list of the page
673 p_o = dvbsub->p_objects;
674 dvbsub->p_objects = p_obj;
679 static void dvbsub_stop_display ( dvbsub_thread_t* p_dec,
680 dvbsub_all_t* dvbsub)
684 for(j = 0; dvbsub->p_spu[j] != NULL; j++)
685 dvbsub->p_spu[j]->i_stop = p_dec->bit_stream.p_pes->i_pts;
689 static void dvbsub_decode_clut ( dvbsub_thread_t* p_dec,
690 dvbsub_all_t* dvbsub)
692 uint16_t i_segment_length;
693 uint16_t i_processed_length;
695 uint8_t i_entry_type;
698 uint8_t i_version_number;
703 i_segment_length = GetBits( &p_dec->bit_stream, 16 );
704 i_clut_id = GetBits( &p_dec->bit_stream, 8 );
705 i_version_number = GetBits( &p_dec->bit_stream, 4 );
706 // Check that this id doesn't not already exist
707 // with the same version number
708 // And allocate memory if necessary
709 if( dvbsub->p_clut[i_clut_id] != NULL)
711 if ( dvbsub->p_clut[i_clut_id]->i_version_number == i_version_number )
713 //TODO skip the right number of bits
718 memset(dvbsub->p_clut[i_clut_id], 0, sizeof(dvbsub_clut_t));
723 dvbsub->p_clut[i_clut_id] = trox_malloc(sizeof(dvbsub_clut_t));
725 clut = dvbsub->p_clut[i_clut_id];
726 /* We don't have this version of the CLUT:
728 clut->i_version_number = i_version_number;
729 GetBits( &p_dec->bit_stream, 4 ); /* Reserved bits */
730 i_processed_length=2;
731 while(i_processed_length<i_segment_length)
733 i_entry_id = GetBits( &p_dec->bit_stream, 8 );
734 i_entry_type = GetBits( &p_dec->bit_stream, 3 );
735 GetBits( &p_dec->bit_stream, 4 );
736 if ( GetBits( &p_dec->bit_stream, 1 )==0x01 )
738 y = GetBits( &p_dec->bit_stream, 8 );
739 cr = GetBits( &p_dec->bit_stream, 8 );
740 cb = GetBits( &p_dec->bit_stream, 8 );
741 t = GetBits( &p_dec->bit_stream, 8 );
742 i_processed_length += 6;
746 y = GetBits( &p_dec->bit_stream, 6 );
747 cr = GetBits( &p_dec->bit_stream, 4 );
748 cb = GetBits( &p_dec->bit_stream, 4 );
749 t = GetBits( &p_dec->bit_stream, 2 );
750 i_processed_length += 4;
752 dvbsub_clut_add_entry(clut, i_entry_type, i_entry_id, y, cr, cb, t);
757 static void dvbsub_clut_add_entry ( dvbsub_clut_t* clut, uint8_t type,
758 uint8_t id, uint8_t y, uint8_t cr,
759 uint8_t cb, uint8_t t)
761 /* According to EN 300-743 section 7.2.3 note 1, type should
762 * not have more than 1 bit set to one
763 But, some strams don't respect this note. */
766 clut->c_2b[id].Y = y;
767 clut->c_2b[id].Cr = cr;
768 clut->c_2b[id].Cb = cb;
769 clut->c_2b[id].T = t;
773 clut->c_4b[id].Y = y;
774 clut->c_4b[id].Cr = cr;
775 clut->c_4b[id].Cb = cb;
776 clut->c_4b[id].T = t;
780 clut->c_8b[id].Y = y;
781 clut->c_8b[id].Cr = cr;
782 clut->c_8b[id].Cb = cb;
783 clut->c_8b[id].T = t;
789 static void dvbsub_add_objectdef_to_region ( dvbsub_objectdef_t* p_obj,
790 dvbsub_region_t* p_region )
792 dvbsub_objectdef_t* p_o = p_region->p_object;
793 // Seek to the last non null element
796 for(; p_o->p_next!=NULL; p_o=p_o->p_next);
798 p_o->p_next->p_next = NULL;
802 p_region->p_object = p_obj;
803 p_region->p_object->p_next = NULL;
809 static dvbsub_image_t* dvbsub_parse_pdata ( dvbsub_thread_t* p_spudec,
812 dvbsub_image_t* p_image;
813 uint16_t i_processed_length=0;
815 uint16_t i_cols_last=0;
816 p_image = trox_malloc ( sizeof ( dvbsub_image_t) );
817 p_image->p_last=NULL;
818 memset(p_image->i_cols, 0, 576*sizeof(uint16_t));
819 /* Let's parse it a first time to determine the size of the buffer */
820 while (i_processed_length < length)
822 switch(GetBits( &p_spudec->bit_stream, 8 ))
825 fprintf(stderr, "0x10 N/A\n");
828 i_processed_length += 1 + dvbsub_count0x11(p_spudec,
829 &(p_image->i_cols[i_lines]),
833 fprintf(stderr, "0x12 N/A\n");
836 fprintf(stderr, "0x20 N/A\n");
839 fprintf(stderr, "0x21 N/A\n");
842 fprintf(stderr, "0x22 N/A\n");
845 i_processed_length++;
850 p_image->i_rows = i_lines;
851 p_image->i_cols[i_lines] = i_cols_last;
852 // Check word-aligned bits
853 if(ShowBits( &p_spudec->bit_stream, 8 )==0x00)
854 GetBits( &p_spudec->bit_stream, 8 );
860 static void add_rle_code (dvbsub_image_t* p, uint16_t num, uint8_t color)
862 if(p->p_last != NULL)
864 p->p_last->p_next = trox_malloc (sizeof (dvbsub_rle_t));
865 p->p_last = p->p_last->p_next;
869 p->p_codes = trox_malloc (sizeof (dvbsub_rle_t));
870 p->p_last = p->p_codes;
872 p->p_last->i_num = num;
873 p->p_last->i_color_code = color;
874 p->p_last->p_next = NULL;
879 static uint16_t dvbsub_count0x11(dvbsub_thread_t* p_spudec, uint16_t* p, dvbsub_image_t* p_image)
881 uint16_t i_processed=0;
883 uint16_t i_count = 0;
887 if ( (i_color = GetBits( &p_spudec->bit_stream, 4 )) != 0x00 )
891 // 1 pixel of color code '0000'
892 add_rle_code (p_image, 1, i_color );
896 if(GetBits( &p_spudec->bit_stream, 1 ) == 0x00) // Switch1
898 if( ShowBits( &p_spudec->bit_stream, 3 ) != 0x00 )
900 i_count = 2 + GetBits( &p_spudec->bit_stream, 3 );
902 add_rle_code (p_image, i_count, 0x00);
906 GetBits( &p_spudec->bit_stream, 3);
913 if(GetBits( &p_spudec->bit_stream, 1 ) == 0x00) //Switch2
915 i_count = 4 + GetBits( &p_spudec->bit_stream, 2 );
916 i_color = GetBits( &p_spudec->bit_stream, 4 );
919 add_rle_code(p_image, i_count, i_color);
923 switch ( GetBits( &p_spudec->bit_stream, 2 ) ) //Switch3
928 add_rle_code(p_image, 1, 0x00);
933 add_rle_code(p_image, 2, 0x00);
936 i_count = 9 + GetBits( &p_spudec->bit_stream, 4 );
937 i_color = GetBits( &p_spudec->bit_stream, 4 );
940 add_rle_code ( p_image, i_count, i_color );
943 i_count= 25 + GetBits( &p_spudec->bit_stream, 8 );
944 i_color = GetBits( &p_spudec->bit_stream, 4 );
947 add_rle_code ( p_image, i_count, i_color );
954 RealignBits ( &p_spudec->bit_stream );
955 return (i_processed+7)/8 ;
958 static vlc_bool_t dvbsub_check_page(dvbsub_all_t* dvbsub)
960 if(dvbsub->p_page != NULL)
962 if(dvbsub->p_objects != NULL)
968 static void free_image (dvbsub_image_t* p_i)
971 dvbsub_rle_t* p2=NULL;
973 for( p1 = p_i->p_codes; p1 != NULL; p1=p2)
983 static void free_object (dvbsub_object_t* p_o)
988 static void free_objectdefs ( dvbsub_objectdef_t* p_o)
990 dvbsub_objectdef_t* p1;
991 dvbsub_objectdef_t* p2=NULL;
993 for( p1 = p_o; p1 != NULL; p1=p2)
1001 static void free_regions (dvbsub_region_t* p_r, uint8_t nb)
1005 for (i = 0; i<nb; i++) free_objectdefs ( p_r[i].p_object );
1010 static void free_objects (dvbsub_object_t* p_o)
1012 dvbsub_object_t* p1;
1013 dvbsub_object_t* p2=NULL;
1015 for( p1 = p_o; p1 != NULL; p1=p2)
1018 free_image (p1->topfield);
1019 free_image (p1->bottomfield);
1024 static void free_clut ( dvbsub_clut_t* p_c) { trox_free(p_c); }
1026 static void free_page (dvbsub_page_t* p_p)
1028 free_regions (p_p->regions, p_p->i_regions_number);
1033 static void free_spu( subpicture_t *p_spu )
1037 free_image(((dvbsub_render_t *)p_spu->p_sys->p_data)->p_rle_top);
1038 free_image(((dvbsub_render_t *)p_spu->p_sys->p_data)->p_rle_bot);
1039 trox_free(p_spu->p_sys->p_data);
1040 trox_free( p_spu->p_sys );
1041 p_spu->p_sys = NULL;
1045 static void free_all ( dvbsub_all_t* p_a )
1049 for(i=0; i<0xff; i++) if (p_a->p_clut[i]) free_clut ( p_a->p_clut[i] );
1050 for(i=0; i<16; i++) if (p_a->p_spu[i]) free_spu ( p_a->p_spu[i] );
1051 if(p_a->p_page) free_page( p_a->p_page );
1052 free_objects (p_a->p_objects);
1056 static void dvbsub_RenderDVBSUB ( vout_thread_t *p_vout, picture_t *p_pic,
1057 const subpicture_t *p_spu, vlc_bool_t b_crop )
1059 // If we have changed the language on the fly,
1060 if(!p_spu->p_sys) return;
1062 if(p_spu->p_sys->b_obsolete) return;
1064 switch (p_vout->output.i_chroma)
1066 /* I420 target, no scaling */
1067 case VLC_FOURCC('I','4','2','2'):
1068 case VLC_FOURCC('I','4','2','0'):
1069 case VLC_FOURCC('I','Y','U','V'):
1070 case VLC_FOURCC('Y','V','1','2'):
1071 // As long as we just use Y info, I422 and YV12 are just equivalent
1072 // to I420. Remember to change it the day we'll take into account
1074 RenderI42x( p_vout, p_pic, p_spu, VLC_FALSE );
1076 /* RV16 target, scaling */
1077 case VLC_FOURCC('R','V','1','6'):
1078 fprintf(stderr, "Not implemented chroma ! RV16)\n");
1079 //RenderRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
1081 /* RV32 target, scaling */
1082 case VLC_FOURCC('R','V','2','4'):
1083 case VLC_FOURCC('R','V','3','2'):
1084 fprintf(stderr, "Not implemented chroma ! RV32 \n");
1085 //RenderRV32( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
1087 /* NVidia overlay, no scaling */
1088 case VLC_FOURCC('Y','U','Y','2'):
1089 RenderYUY2( p_vout, p_pic, p_spu, VLC_FALSE );
1092 msg_Err( p_vout, "unknown chroma, can't render SPU" );
1098 static void RenderYUY2 ( vout_thread_t *p_vout, picture_t *p_pic,
1099 const subpicture_t *p_spu, vlc_bool_t b_crop )
1101 /* Common variables */
1107 dvbsub_render_t* p_r = ((dvbsub_render_t *)p_spu->p_sys->p_data);
1108 dvbsub_image_t* p_im = p_r->p_rle_top;
1111 p_desty = p_pic->Y_PIXELS;
1112 //let's render the 1st frame
1113 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1115 // if( p_c->y != 0 && p_c->t < 0x20)
1116 if( p_c->y != 0 && p_c->t < 0x20)
1120 //memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1121 // In YUY2 we have to set pixel per pixel
1122 for( i_cnt = 0; i_cnt < p_c->i_num; i_cnt+=2 )
1124 memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt, p_c->y, 1);
1125 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+1, p_c->cr, 1);
1126 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+2, p_c->y, 1);
1127 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+3, p_c->cb, 1);
1131 if(j >= p_im->i_cols[i])
1135 if( i>= p_im->i_rows) break;
1137 //idem for the second frame
1138 p_im = p_r->p_rle_bot; i=0; j=0;
1139 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1141 if( p_c->y != 0 && p_c->t < 0x20)
1145 //memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1146 // In YUY2 we have to set pixel per pixel
1147 for( i_cnt = 0; i_cnt < p_c->i_num; i_cnt+=2 )
1149 memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt, p_c->y, 1);
1150 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+1, p_c->cr, 1);
1151 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+2, p_c->y, 1);
1152 // memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+3, p_c->cb, 1);
1156 if(j >= p_im->i_cols[i])
1160 if( i>= p_im->i_rows) break;
1165 static void RenderI42x ( vout_thread_t *p_vout, picture_t *p_pic,
1166 const subpicture_t *p_spu, vlc_bool_t b_crop )
1168 /* Common variables */
1175 dvbsub_render_t* p_r = ((dvbsub_render_t *)p_spu->p_sys->p_data);
1176 dvbsub_image_t* p_im = p_r->p_rle_top;
1179 p_desty = p_pic->Y_PIXELS;
1180 p_destu = p_pic->U_PIXELS;
1181 p_destv = p_pic->V_PIXELS;
1182 //let's render the 1st frame
1183 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1189 //memset(p_dest+ y*p_pic->U_PITCH*2 + x, p_c->cr, p_c->i_num);
1190 // memset(p_desty+ (y)*p_pic->Y_PITCH + x, p_c->cr, p_c->i_num);
1191 //memset(p_dest+ y*p_pic->V_PITCH*2 + x, p_c->cb, p_c->i_num);
1192 //memset(p_destu+ (y)*p_pic->Y_PITCH + x, p_c->cb, p_c->i_num);
1193 memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1194 // memset(p_desty+ 2*y*p_pic->U_PITCH + x, p_c->cr, p_c->i_num);
1195 // memset(p_desty+ 2*y*p_pic->V_PITCH + x, p_c->cb, p_c->i_num);
1198 if(j >= p_im->i_cols[i])
1202 if( i>= p_im->i_rows) break;
1204 //idem for the second frame
1205 p_im = p_r->p_rle_bot; i=0; j=0;
1206 for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1208 if( p_c->y != 0 && p_c->t < 0x20)
1212 // memset(p_desty+ y*p_pic->U_PITCH*2 + x, p_c->cr, p_c->i_num);
1213 // memset(p_desty+ y*p_pic->V_PITCH*2 + x, p_c->cb, p_c->i_num);
1214 memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1215 // memset(p_desty+ 2*y*p_pic->U_PITCH + x, p_c->cr, p_c->i_num);
1216 // memset(p_desty+ 2*y*p_pic->V_PITCH + x, p_c->cb, p_c->i_num);
1219 if(j >= p_im->i_cols[i])
1223 if( i>= p_im->i_rows) break;
1227 static void dvbsub_Destroy( subpicture_t *p_spu )
1232 static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
1234 dvbsub_region_t* p_region;
1235 dvbsub_objectdef_t* p_objectdef;
1236 dvbsub_object_t* p_o;
1237 dvbsub_object_t* p_object;
1238 dvbsub_object_t* p_object_old;
1239 dvbsub_render_t* p_render;
1243 /* loop on regions */
1244 for(i=0; i< dvbsub->p_page->i_regions_number; i++)
1246 p_region = &(dvbsub->p_page->regions[i]);
1247 /* loop on objects */
1248 for(p_objectdef = p_region->p_object;
1249 p_objectdef != NULL;
1250 p_objectdef = p_objectdef->p_next)
1252 /* Look for the right object */
1253 p_object = dvbsub->p_objects;
1254 while((p_object!=NULL) && (p_object->i_id != p_objectdef->i_id))
1256 p_object = p_object->p_next;
1260 fprintf(stderr, "Internal DvbSub decoder error\n");
1263 /* Allocate the render structure */
1264 p_render = trox_malloc(sizeof(dvbsub_render_t));
1265 p_render->i_x = p_region->i_x + p_objectdef->i_xoffset;
1266 p_render->i_y = p_region->i_y + p_objectdef->i_yoffset;
1267 p_render->p_rle_top = p_object->topfield;
1268 p_render->p_rle_bot = p_object->bottomfield;
1270 // if we did not recieved the CLUT yet
1271 if ( !dvbsub->p_clut[p_region->i_clut] ) return;
1273 /* Compute the color datas according to the appropriate CLUT */
1274 for(p_c=p_render->p_rle_top->p_codes;p_c->p_next!=NULL; p_c=p_c->p_next)
1276 //TODO We assume here we are working in 4bp
1277 p_c->y=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Y;
1278 p_c->cr=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cr;
1279 p_c->cb=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cb;
1280 p_c->t=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].T;
1282 for(p_c=p_render->p_rle_bot->p_codes;p_c->p_next!=NULL; p_c=p_c->p_next)
1284 //TODO We assume here we are working in 4bp
1285 p_c->y=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Y;
1286 p_c->cr=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cr;
1287 p_c->cb=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cb;
1288 p_c->t=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].T;
1292 /* Allocate the subpicture internal data. */
1293 dvbsub->p_spu[j] = vout_CreateSubPicture( p_dec->p_vout,
1294 MEMORY_SUBPICTURE );
1295 if( dvbsub->p_spu[j] == NULL )
1297 fprintf(stderr, "Unable to allocate memory ... skipping\n");
1300 /* Set the pf_render callback */
1301 dvbsub->p_spu[j]->pf_render = dvbsub_RenderDVBSUB;
1302 dvbsub->p_spu[j]->p_sys = trox_malloc( sizeof( subpicture_sys_t ));
1303 dvbsub->p_spu[j]->p_sys->p_data = p_render;
1304 dvbsub->p_spu[j]->p_sys->b_obsolete=0;
1305 dvbsub->p_spu[j]->pf_destroy = dvbsub_Destroy;
1306 dvbsub->p_spu[j]->i_start = p_dec->bit_stream.p_pes->i_pts;
1307 dvbsub->p_spu[j]->i_stop = dvbsub->p_spu[j]->i_start + dvbsub->p_page->i_timeout*1000000;
1308 dvbsub->p_spu[j]->b_ephemer = VLC_FALSE;
1310 // At this stage, we have all we need in p_render
1311 // We need to free the object
1312 //Remove this object from the list
1313 p_object_old = p_object;
1314 if(p_object == dvbsub->p_objects)
1315 dvbsub->p_objects = p_object->p_next;
1318 for(p_o = dvbsub->p_objects; p_o->p_next != p_object; p_o=p_o->p_next);
1319 p_o->p_next = p_object->p_next;
1321 free_object(p_object_old);
1323 vout_DisplaySubPicture (p_dec->p_vout, dvbsub->p_spu[j] );