]> git.sesse.net Git - vlc/blob - modules/codec/dvbsub.c
* ALL: final improvements to the decoders/packetizers api.
[vlc] / modules / codec / dvbsub.c
1 /*****************************************************************************
2  * dvbsub.c : DVB subtitles decoder thread
3  *****************************************************************************
4  * Copyright (C) 2003 ANEVIA
5  * $Id: dvbsub.c,v 1.3 2003/11/16 21:07:30 gbazin Exp $
6  *
7  * Authors: Damien LUCAS <damien.lucas@anevia.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include <stdlib.h>                                      /* malloc(), free() */
27 #include <string.h>                                    /* memcpy(), memset() */
28 #include <vlc/vlc.h>
29 #include <vlc/vout.h>
30 #include <vlc/decoder.h>
31 #include "codecs.h"
32
33
34 // Wow, that's ugly but very usefull for a memory leak track
35 // so I just keep it
36 #if 0
37 static long long unsigned int trox_malloc_nb = 0;
38 static long long unsigned int trox_free_nb = 0;
39
40 static void* trox_malloc (size_t size)
41 { ++trox_malloc_nb; return malloc (size); }
42
43 static void trox_free (void* ptr)
44 { ++trox_free_nb; free(ptr); return; }
45
46 static void trox_call ()
47 {
48   fprintf(stderr, "dvbbsub -- Memory usage:  %llu mallocs %llu frees (%llu)\n",
49                   trox_malloc_nb,
50                   trox_free_nb,
51                   trox_malloc_nb - trox_free_nb);
52   return;
53 }
54 #else
55 # define trox_malloc malloc
56 # define trox_free free
57 # define trox_call()
58 #endif
59 /****************************************************************************
60  * Local structures
61  ****************************************************************************
62  * Those structures refer closely to the ETSI 300 743 Object model
63  ****************************************************************************/
64
65 /* Storage of a RLE entry */
66 typedef struct dvbsub_rle_s
67 {
68     uint16_t                 i_num;
69     uint8_t                 i_color_code;
70     uint8_t                 y;
71     uint8_t                 cr;
72     uint8_t                 cb;
73     uint8_t                 t;
74     struct dvbsub_rle_s*    p_next;
75 } dvbsub_rle_t;
76
77 /* A subpicture image is a list of codes
78  * We need to store the length of each line since nothing specify in
79  * the standard that all lines shoudl have the same length
80  * WARNING: We assume here that a spu is less than 576 lines high */
81 typedef struct
82 {
83     uint16_t                        i_rows;
84     uint16_t                        i_cols[576];
85     dvbsub_rle_t*                   p_last;
86     dvbsub_rle_t*                   p_codes;
87 } dvbsub_image_t;
88
89 /* The object definition gives the position of the object in a region */
90 typedef struct dvbsub_objectdef_s
91 {
92     uint16_t                    i_id;
93     uint8_t                     i_type;
94     uint8_t                     i_provider;
95     uint16_t                    i_xoffset;
96     uint16_t                    i_yoffset;
97     uint8_t                     i_fg_pc;
98     uint8_t                     i_bg_pc;
99     struct dvbsub_objectdef_s*  p_next;
100 } dvbsub_objectdef_t;
101
102 /* The Region is an aera on the image
103  * with a list of the object definitions associated
104  * and a CLUT */
105 typedef struct dvbsub_region_s
106 {
107     uint8_t                 i_id;
108     uint8_t                 i_version_number;
109     vlc_bool_t              b_fill;
110     uint16_t                i_x;
111     uint16_t                i_y;
112     uint16_t                i_width;
113     uint16_t                i_height;
114     uint8_t                 i_level_comp;
115     uint8_t                 i_depth;
116     uint8_t                 i_clut;
117     uint8_t                 i_8bp_code;
118     uint8_t                 i_4bp_code;
119     uint8_t                 i_2bp_code;
120     dvbsub_objectdef_t*    p_object;
121 } dvbsub_region_t;
122
123 /* The page defines the list of regions */
124 typedef struct
125 {
126     uint16_t              i_id;
127     uint8_t               i_timeout;
128     uint8_t               i_state;
129     uint8_t               i_version_number;
130     uint8_t               i_regions_number;
131     dvbsub_region_t*      regions;
132 } dvbsub_page_t;
133
134 /* An object is constituted of 2 images (for interleaving) */
135 typedef struct dvbsub_object_s
136 {
137     uint16_t                i_id;
138     uint8_t                 i_version_number;
139     uint8_t                 i_coding_method;
140     vlc_bool_t              b_non_modify_color;
141     dvbsub_image_t*         topfield;
142     dvbsub_image_t*         bottomfield;
143     struct dvbsub_object_s* p_next;
144 } dvbsub_object_t;
145
146 /* The entry in the palette CLUT */
147 typedef struct
148 {
149     uint8_t                 Y;
150     uint8_t                 Cr;
151     uint8_t                 Cb;
152     uint8_t                 T;
153 } dvbsub_color_t;
154
155 /* */
156 typedef struct
157 {
158     uint8_t                 i_id;
159     uint8_t                 i_version_number;
160     dvbsub_color_t          c_2b[0xff];
161     dvbsub_color_t          c_4b[0xff];
162     dvbsub_color_t          c_8b[0xff];
163 } dvbsub_clut_t;
164
165 typedef struct
166 {
167     uint8_t                 i_x;
168     uint16_t                i_y;
169     dvbsub_image_t*         p_rle_top;
170     dvbsub_image_t*         p_rle_bot;
171 } dvbsub_render_t;
172
173 typedef struct
174 {
175     dvbsub_clut_t*          p_clut[0xff];
176     dvbsub_page_t*          p_page;
177     dvbsub_object_t*        p_objects;
178     subpicture_t*           p_spu[16];
179 } dvbsub_all_t;
180 typedef struct
181 {
182     /* Thread properties and locks */
183     vlc_thread_t        thread_id;                /* Id for thread functions */
184     /* Input properties */
185     decoder_fifo_t*     p_fifo;                /* Stores the PES stream data */
186     bit_stream_t        bit_stream;             /* PES data at the bit level */
187     /* Output properties */
188     vout_thread_t*      p_vout;          /* Needed to create the subpictures */
189 } dvbsub_thread_t;
190 struct subpicture_sys_t
191 {
192     mtime_t         i_pts;
193     void *          p_data;                          /* rle datas are stored */
194     vlc_object_t*   p_input;                            /* Link to the input */
195     vlc_bool_t      b_obsolete;
196 };
197 // List of different SEGMENT TYPES
198 // According to EN 300-743, table 2
199 #define DVBSUB_ST_PAGE_COMPOSITION      0x10
200 #define DVBSUB_ST_REGION_COMPOSITION    0x11
201 #define DVBSUB_ST_CLUT_DEFINITION       0x12
202 #define DVBSUB_ST_OBJECT_DATA           0x13
203 #define DVBSUB_ST_ENDOFDISPLAY          0x80
204 #define DVBSUB_ST_STUFFING              0xff
205 // List of different OBJECT TYPES
206 // According to EN 300-743, table 6
207 #define DVBSUB_OT_BASIC_BITMAP          0x00
208 #define DVBSUB_OT_BASIC_CHAR            0x01
209 #define DVBSUB_OT_COMPOSITE_STRING      0x02
210 // Pixel DATA TYPES
211 // According to EN 300-743, table 9
212 #define DVBSUB_DT_2BP_CODE_STRING       0x10
213 #define DVBSUB_DT_4BP_CODE_STRING       0x11
214 #define DVBSUB_DT_8BP_CODE_STRING       0x12
215 #define DVBSUB_DT_24_TABLE_DATA         0x20
216 #define DVBSUB_DT_28_TABLE_DATA         0x21
217 #define DVBSUB_DT_48_TABLE_DATA         0x22
218 #define DVBSUB_DT_END_LINE              0xf0
219
220 /*****************************************************************************
221  * Local prototypes
222  *****************************************************************************/
223 static int  OpenDecoder   ( vlc_object_t * );
224 static int  RunDecoder    ( decoder_fifo_t * );
225 static int  InitThread    ( dvbsub_thread_t * );
226 static void EndThread     ( dvbsub_thread_t *i, dvbsub_all_t*);
227 static vout_thread_t *FindVout( dvbsub_thread_t * );
228 static void RenderI42x( vout_thread_t *, picture_t *, const subpicture_t *,
229                         vlc_bool_t );
230 static void RenderYUY2( vout_thread_t *, picture_t *, const subpicture_t *,
231                         vlc_bool_t );
232 static void dvbsub_clut_add_entry ( dvbsub_clut_t* clut, uint8_t type,
233                                     uint8_t id, uint8_t y, uint8_t cr,
234                                     uint8_t cb, uint8_t t);
235 static void dvbsub_add_objectdef_to_region ( dvbsub_objectdef_t* p_obj,
236                                    dvbsub_region_t* p_region );
237 static dvbsub_image_t* dvbsub_parse_pdata ( dvbsub_thread_t* ,uint16_t );
238 static uint16_t dvbsub_count0x11(dvbsub_thread_t* p_spudec,
239                                  uint16_t* p,
240                                  dvbsub_image_t* p_image);
241 static void dvbsub_decode_segment ( dvbsub_thread_t *, dvbsub_all_t* );
242 static void dvbsub_decode_page_composition ( dvbsub_thread_t *, dvbsub_all_t* );
243 static void dvbsub_decode_region_composition ( dvbsub_thread_t*, dvbsub_all_t*);
244 static void dvbsub_decode_object ( dvbsub_thread_t*, dvbsub_all_t* );
245 static vlc_bool_t dvbsub_check_page ( dvbsub_all_t* );
246 static void dvbsub_render ( dvbsub_thread_t *p_spudec,dvbsub_all_t* );
247 static int dvbsub_parse ( dvbsub_thread_t *p_spudec, dvbsub_all_t* dvbsub );
248 static void dvbsub_decode_clut ( dvbsub_thread_t*, dvbsub_all_t*);
249 static void dvbsub_stop_display ( dvbsub_thread_t* p_dec, dvbsub_all_t* dvbsub);
250
251 static void free_image (dvbsub_image_t* p_i);
252 static void free_object (dvbsub_object_t* p_o);
253 static void free_regions (dvbsub_region_t* p_r, uint8_t nb);
254 static void free_objects (dvbsub_object_t* p_o);
255 static void free_clut ( dvbsub_clut_t* p_c);
256 static void free_page (dvbsub_page_t* p_p);
257 static void free_all ( dvbsub_all_t* p_a );
258
259
260 /*****************************************************************************
261  * Module descriptor.
262  *****************************************************************************/
263 vlc_module_begin();
264     add_category_hint( N_("subtitles"), NULL, VLC_TRUE );
265     set_description( _("subtitles decoder") );
266     set_capability( "decoder", 50 );
267     set_callbacks( OpenDecoder, NULL );
268 vlc_module_end();
269 /*****************************************************************************
270  * OpenDecoder: probe the decoder and return score
271  *****************************************************************************
272  * Tries to launch a decoder and return score so that the interface is able
273  * to chose.
274  *****************************************************************************/
275 static int OpenDecoder( vlc_object_t *p_this )
276 {
277     decoder_t *p_dec = (decoder_t*) p_this;
278     if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
279     {
280         return VLC_EGENERIC;
281     }
282     p_dec->pf_run = RunDecoder;
283     return VLC_SUCCESS;
284 }
285 /*****************************************************************************
286  * RunDecoder: this function is called just after the thread is created
287  *****************************************************************************/
288 static int RunDecoder( decoder_fifo_t * p_fifo )
289 {
290     dvbsub_thread_t *    p_dvbsubdec;
291 //    vout_thread_t *         p_vout_backup = NULL;
292     dvbsub_all_t            dvbsub;
293     unsigned int            k;
294     /* Allocate the memory needed to store the thread's structure */
295     p_dvbsubdec = (dvbsub_thread_t *)trox_malloc( sizeof(dvbsub_thread_t) );
296     if ( p_dvbsubdec == NULL )
297     {
298         msg_Err( p_fifo, "out of memory" );
299         DecoderError( p_fifo );
300         return( -1 );
301     }
302     /*
303      * Initialize the thread properties
304      */
305     p_dvbsubdec->p_vout = NULL;
306     p_dvbsubdec->p_fifo = p_fifo;
307     /*
308      * Initialize thread and free configuration
309      */
310     p_dvbsubdec->p_fifo->b_error = InitThread( p_dvbsubdec );
311     dvbsub.p_page=NULL;
312     dvbsub.p_objects=NULL;
313     for(k=0; k<0xff; k++) dvbsub.p_clut[k] = NULL;
314     for(k=0; k<16; k++) dvbsub.p_spu[k] = NULL;
315
316     /*
317      * Main loop - it is not executed if an error occured during
318      * initialization
319      */
320     while( (!p_dvbsubdec->p_fifo->b_die) && (!p_dvbsubdec->p_fifo->b_error) )
321     {
322         dvbsub_parse( p_dvbsubdec, &dvbsub );
323         p_dvbsubdec->p_vout = FindVout( p_dvbsubdec );
324         if( p_dvbsubdec->p_vout )
325         {
326             // Check if the page is to be displayed
327             if(dvbsub_check_page(&dvbsub))
328             {
329                 dvbsub_render(p_dvbsubdec, &dvbsub);
330             }
331             vlc_object_release( p_dvbsubdec->p_vout );
332         }
333     }
334     // Free all structures
335     //dvbsub.p_objects=NULL;
336     //for(k=0; k<16; k++)
337     //    if(dvbsub.p_spu[k] != NULL)
338     //        dvbsub.p_spu[k]->p_sys->b_obsolete = 1;
339
340     /*
341      * Error loop
342      */
343     if( p_dvbsubdec->p_fifo->b_error )
344     {
345         DecoderError( p_dvbsubdec->p_fifo );
346         /* End of thread */
347         EndThread( p_dvbsubdec, &dvbsub );
348         return -1;
349     }
350     /* End of thread */
351     EndThread( p_dvbsubdec, &dvbsub );
352     free_all(&dvbsub);
353     return 0;
354 }
355 /* following functions are local */
356 /*****************************************************************************
357  * InitThread: initialize dvbsub decoder thread
358  *****************************************************************************
359  * This function is called from RunThread and performs the second step of the
360  * initialization. It returns 0 on success. Note that the thread's flag are not
361  * modified inside this function.
362  *****************************************************************************/
363 static int InitThread( dvbsub_thread_t *p_dvbsubdec )
364 {
365     int i_ret;
366     /* Call InitBitstream anyway so p_spudec->bit_stream is in a known
367      * state before calling CloseBitstream */
368     i_ret = InitBitstream( &p_dvbsubdec->bit_stream, p_dvbsubdec->p_fifo,
369                            NULL, NULL );
370     /* Check for a video output */
371     p_dvbsubdec->p_vout = FindVout( p_dvbsubdec );
372     if( !p_dvbsubdec->p_vout )
373     {
374         return -1;
375     }
376     /* It was just a check */
377     vlc_object_release( p_dvbsubdec->p_vout );
378     p_dvbsubdec->p_vout = NULL;
379     return i_ret;
380 }
381 /*****************************************************************************
382  * FindVout: Find a vout or wait for one to be created.
383  *****************************************************************************/
384 static vout_thread_t *FindVout( dvbsub_thread_t *p_spudec )
385 {
386     vout_thread_t *p_vout = NULL;
387     /* Find an available video output */
388     do
389     {
390         if( p_spudec->p_fifo->b_die || p_spudec->p_fifo->b_error )
391         {
392             break;
393         }
394         p_vout = vlc_object_find( p_spudec->p_fifo, VLC_OBJECT_VOUT,
395                                   FIND_ANYWHERE );
396         if( p_vout )
397         {
398             break;
399         }
400         msleep( VOUT_OUTMEM_SLEEP );
401     }
402     while( 1 );
403     return p_vout;
404 }
405 /*****************************************************************************
406  * EndThread: thread destruction
407  *****************************************************************************
408  * This function is called when the thread ends after a sucessful
409  * initialization.
410  *****************************************************************************/
411 static void EndThread( dvbsub_thread_t *p_dvbsubdec, dvbsub_all_t* p_dvbsub )
412 {
413     if( p_dvbsubdec->p_vout != NULL
414          && p_dvbsubdec->p_vout->p_subpicture != NULL )
415     {
416         subpicture_t *  p_subpic;
417         int i_subpic;
418         for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )
419         {
420             p_subpic = &p_dvbsubdec->p_vout->p_subpicture[i_subpic];
421             if( p_subpic != NULL &&
422               ( ( p_subpic->i_status == RESERVED_SUBPICTURE )
423              || ( p_subpic->i_status == READY_SUBPICTURE ) ) )
424             {
425                 vout_DestroySubPicture( p_dvbsubdec->p_vout, p_subpic );
426             }
427         }
428     }
429     CloseBitstream( &p_dvbsubdec->bit_stream );
430     trox_free( p_dvbsubdec );
431     trox_call();
432 }
433
434
435 static int dvbsub_parse ( dvbsub_thread_t *p_spudec,
436                           dvbsub_all_t* dvbsub )
437 {
438     unsigned int data_identifier;
439     unsigned int subtitle_stream_id;
440     unsigned int nextbits;
441     uint32_t end_data_marker;
442     /* Re-align the buffer on an 8-bit boundary */
443     RealignBits( &p_spudec->bit_stream );
444     data_identifier = GetBits( &p_spudec->bit_stream, 8 );
445     subtitle_stream_id = GetBits( &p_spudec->bit_stream, 8 );
446     nextbits = ShowBits( &p_spudec->bit_stream, 8 );
447     while(nextbits == 0x0f )
448     {
449         dvbsub_decode_segment(  p_spudec, dvbsub );
450         nextbits = ShowBits( &p_spudec->bit_stream, 8 );
451     }
452     end_data_marker = GetBits( &p_spudec->bit_stream, 8 );
453     return 0;
454 }
455
456
457
458 static void dvbsub_decode_segment ( dvbsub_thread_t * p_spudec,
459                                     dvbsub_all_t * dvbsub )
460 {
461     unsigned int sync_byte;
462     unsigned int segment_type;
463     uint16_t page_id;
464     uint16_t segment_length;
465     int k;
466     sync_byte = GetBits( &p_spudec->bit_stream, 8 );
467     segment_type = GetBits( &p_spudec->bit_stream, 8 );
468     page_id = GetBits( &p_spudec->bit_stream, 16 );
469     segment_length = ShowBits( &p_spudec->bit_stream, 16 );
470     if( page_id != ((dvb_spuinfo_t*)p_spudec->p_fifo->p_spuinfo)->i_id )
471     {
472         //TODO should use GetChunk
473         for(k=0; k<segment_length+2; k++) GetBits( &p_spudec->bit_stream, 8 );
474         return;
475     }
476     switch( segment_type )
477     {
478         case DVBSUB_ST_CLUT_DEFINITION:
479             dvbsub_decode_clut ( p_spudec, dvbsub );
480             break;
481          case DVBSUB_ST_PAGE_COMPOSITION:
482             dvbsub_decode_page_composition ( p_spudec, dvbsub );
483             break;
484         case DVBSUB_ST_REGION_COMPOSITION:
485             dvbsub_decode_region_composition ( p_spudec, dvbsub );
486             break;
487         case DVBSUB_ST_OBJECT_DATA:
488             dvbsub_decode_object (  p_spudec, dvbsub );
489             break;
490         case DVBSUB_ST_ENDOFDISPLAY:
491             dvbsub_stop_display ( p_spudec, dvbsub);
492             break;
493         case DVBSUB_ST_STUFFING:
494         default:
495             fprintf(stderr, "*** DVBSUB - Unsupported segment type ! (%04x)\n",
496                                                                 segment_type );
497             GetBits( &p_spudec->bit_stream, 16 );
498             for(k=0; k<segment_length; k++)
499                   GetBits( &p_spudec->bit_stream, 8 );
500             break;
501     }
502     return;
503 }
504
505
506 static void dvbsub_decode_page_composition (dvbsub_thread_t *p_spudec,
507                                             dvbsub_all_t *dvbsub)
508 {
509     unsigned int i_version_number;
510     unsigned int i_state;
511     unsigned int i_segment_length;
512     uint8_t i_timeout;
513     unsigned int k;
514     i_segment_length = GetBits( &p_spudec->bit_stream, 16 );
515     //A page is composed by one or more region:
516     i_timeout =  GetBits( &p_spudec->bit_stream, 8 );
517     i_version_number =  GetBits( &p_spudec->bit_stream, 4 );
518     i_state =  GetBits( &p_spudec->bit_stream, 2 );
519     // TODO We assume it is a new page (i_state)
520     if (dvbsub->p_page) free_page(dvbsub->p_page);
521
522     GetBits( &p_spudec->bit_stream, 2 ); /* Reserved */
523     //Allocate a new page
524     dvbsub->p_page = trox_malloc (sizeof(dvbsub_page_t));
525     dvbsub->p_page->i_timeout = i_timeout;
526     // Number of regions:
527     dvbsub->p_page->i_regions_number = (i_segment_length-2) / 6;
528
529 /* Special workaround for CAVENA encoders
530  * a page with no regions is sent instead of a 0x80 packet (End Of Display) */
531     if( dvbsub->p_page->i_regions_number == 0 )
532     {
533         dvbsub_stop_display(p_spudec, dvbsub );
534     }
535 /* /Special workaround */
536
537     dvbsub->p_page->regions =
538                trox_malloc(dvbsub->p_page->i_regions_number*sizeof(dvbsub_region_t));
539     for(k=0; k<dvbsub->p_page->i_regions_number ; k++)
540     {
541         dvbsub->p_page->regions[k].i_id = GetBits( &p_spudec->bit_stream, 8 );
542         GetBits( &p_spudec->bit_stream, 8 ); /* Reserved */
543         dvbsub->p_page->regions[k].i_x = GetBits( &p_spudec->bit_stream, 16 );
544         dvbsub->p_page->regions[k].i_y = GetBits( &p_spudec->bit_stream, 16 );
545         dvbsub->p_page->regions[k].p_object = NULL;
546     }
547 }
548
549
550 static void dvbsub_decode_region_composition (dvbsub_thread_t *p_spudec,
551                                        dvbsub_all_t *dvbsub)
552 {
553     unsigned int i_segment_length;
554     unsigned int i_processed_length;
555     unsigned int i_region_id;
556     dvbsub_region_t* p_region;
557     unsigned int k;
558     p_region = NULL;
559     i_segment_length = GetBits( &p_spudec->bit_stream, 16 );
560     // Get region id:
561     i_region_id = GetBits( &p_spudec->bit_stream, 8 );
562     for(k=0; k<dvbsub->p_page->i_regions_number; k++)
563     {
564         if ( dvbsub->p_page->regions[k].i_id ==  i_region_id )
565           p_region = &(dvbsub->p_page->regions[k]);
566     }
567     if(p_region == NULL)
568     {
569         // TODO
570         // The region has never been declared before
571         // Internal error
572         fprintf (stderr, "Decoding of undeclared region N/A...\n");
573         return;
574     }
575     // Skip version number and fill flag
576     if (ShowBits( &p_spudec->bit_stream, 4 ) == p_region->i_version_number)
577     {
578         fprintf(stderr, "Skipping already known region N/A ...\n");
579         // TODO Skip the right number of bits
580     }
581     // Region attributes
582     p_region->i_version_number = GetBits( &p_spudec->bit_stream, 4 );
583     p_region->b_fill = GetBits( &p_spudec->bit_stream, 1 );
584     GetBits( &p_spudec->bit_stream, 3 ); /* Reserved */
585     p_region->i_width = GetBits( &p_spudec->bit_stream, 16 );
586     p_region->i_height =  GetBits( &p_spudec->bit_stream, 16 );
587     p_region->i_level_comp =  GetBits( &p_spudec->bit_stream, 3 );
588     p_region->i_depth =  GetBits( &p_spudec->bit_stream, 3 );
589     GetBits( &p_spudec->bit_stream, 2 ); /* Reserved */
590     p_region->i_clut =  GetBits( &p_spudec->bit_stream, 8 );
591     p_region->i_8bp_code = GetBits( &p_spudec->bit_stream, 8 );
592     p_region->i_4bp_code = GetBits( &p_spudec->bit_stream, 4 );
593     p_region->i_2bp_code = GetBits( &p_spudec->bit_stream, 2 );
594     GetBits( &p_spudec->bit_stream, 2 ); /* Reserved */
595     // List of objects in the region:
596     // We already skipped 10 bytes
597     i_processed_length = 10;
598     while ( i_processed_length < i_segment_length )
599     {
600         // We create a new object
601         dvbsub_objectdef_t*     p_obj;
602         p_obj = trox_malloc(sizeof(dvbsub_objectdef_t));
603         // We parse object properties
604         p_obj->i_id = GetBits( &p_spudec->bit_stream, 16 );
605         p_obj->i_type = GetBits( &p_spudec->bit_stream, 2 );
606         p_obj->i_provider = GetBits( &p_spudec->bit_stream, 2 );
607         p_obj->i_xoffset = GetBits( &p_spudec->bit_stream, 12 );
608         GetBits( &p_spudec->bit_stream, 4 ); /* Reserved */
609         p_obj->i_yoffset = GetBits( &p_spudec->bit_stream, 12 );
610         i_processed_length += 6;
611         if ( p_obj->i_type == DVBSUB_OT_BASIC_CHAR 
612                || p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING )
613         {
614             p_obj->i_fg_pc =  GetBits( &p_spudec->bit_stream, 8 );
615             p_obj->i_bg_pc =  GetBits( &p_spudec->bit_stream, 8 );
616             i_processed_length += 2;
617         }
618         p_obj->p_next = NULL;
619         dvbsub_add_objectdef_to_region(p_obj, p_region);
620     }
621 }
622
623
624 static void dvbsub_decode_object (dvbsub_thread_t* p_spudec,
625                                   dvbsub_all_t* dvbsub)
626 {
627     dvbsub_object_t*   p_obj;
628     dvbsub_object_t*   p_o;
629     uint16_t    i_segment_length;
630     uint16_t    i_topfield_length;
631     uint16_t    i_bottomfield_length;
632     // Memory Allocation
633     p_obj = trox_malloc ( sizeof ( dvbsub_object_t ) );
634     p_obj->p_next=NULL;
635     i_segment_length =  GetBits( &p_spudec->bit_stream, 16 );
636     p_obj->i_id =  GetBits( &p_spudec->bit_stream, 16 );
637     p_obj->i_version_number = GetBits( &p_spudec->bit_stream, 4 );
638     // TODO Check we don't already have this object / this version
639     p_obj->i_coding_method = GetBits( &p_spudec->bit_stream, 2 );
640     p_obj->b_non_modify_color = GetBits( &p_spudec->bit_stream, 1 );
641     GetBits( &p_spudec->bit_stream, 1 ); /* Reserved */
642     if(p_obj->i_coding_method == 0x00)
643     {
644         i_topfield_length = GetBits( &p_spudec->bit_stream, 16 );
645         i_bottomfield_length = GetBits( &p_spudec->bit_stream, 16 );
646         p_obj->topfield = dvbsub_parse_pdata (p_spudec, i_topfield_length);
647         p_obj->bottomfield =
648                             dvbsub_parse_pdata (p_spudec, i_bottomfield_length);
649     }
650     else
651     {
652         GetBits(&p_spudec->bit_stream, (i_segment_length -3) *8);
653         //TODO
654         // DVB subtitling as characters
655     }
656     // Add this object to the list of the page
657     p_o = dvbsub->p_objects;
658     dvbsub->p_objects = p_obj;
659     p_obj->p_next = p_o;
660     return;
661 }
662
663 static void dvbsub_stop_display ( dvbsub_thread_t* p_dec,
664                                   dvbsub_all_t* dvbsub)
665 {
666     unsigned int j;
667
668     for(j = 0; dvbsub->p_spu[j] != NULL; j++)
669         dvbsub->p_spu[j]->i_stop = p_dec->bit_stream.p_pes->i_pts;
670     return;
671 }
672
673 static void dvbsub_decode_clut ( dvbsub_thread_t* p_dec,
674                                  dvbsub_all_t* dvbsub)
675 {
676     uint16_t         i_segment_length;
677     uint16_t         i_processed_length;
678     uint8_t          i_entry_id;
679     uint8_t          i_entry_type;
680     dvbsub_clut_t*   clut;
681     uint8_t          i_clut_id;
682     uint8_t          i_version_number;
683     uint8_t          y;
684     uint8_t          cr;
685     uint8_t          cb;
686     uint8_t          t;
687     i_segment_length =  GetBits( &p_dec->bit_stream, 16 );
688     i_clut_id = GetBits( &p_dec->bit_stream, 8 );
689     i_version_number = GetBits( &p_dec->bit_stream, 4 );
690     // Check that this id doesn't not already exist
691     // with the same version number
692     // And allocate memory if necessary
693     if( dvbsub->p_clut[i_clut_id] != NULL)
694     {
695         if ( dvbsub->p_clut[i_clut_id]->i_version_number == i_version_number )
696         {
697             //TODO skip the right number of bits
698             return;
699         }
700         else
701         {
702             memset(dvbsub->p_clut[i_clut_id], 0, sizeof(dvbsub_clut_t));
703         }
704     }
705     else
706     {
707         dvbsub->p_clut[i_clut_id] = trox_malloc(sizeof(dvbsub_clut_t));
708     }
709     clut = dvbsub->p_clut[i_clut_id];
710     /* We don't have this version of the CLUT:
711      * Parse it                                 */
712     clut->i_version_number = i_version_number;
713     GetBits( &p_dec->bit_stream, 4 ); /* Reserved bits */
714     i_processed_length=2;
715     while(i_processed_length<i_segment_length)
716     {
717         i_entry_id = GetBits( &p_dec->bit_stream, 8 );
718         i_entry_type = GetBits( &p_dec->bit_stream, 3 );
719         GetBits( &p_dec->bit_stream, 4 );
720         if ( GetBits( &p_dec->bit_stream, 1 )==0x01 )
721         {
722                 y  = GetBits( &p_dec->bit_stream, 8 );
723                 cr = GetBits( &p_dec->bit_stream, 8 );
724                 cb = GetBits( &p_dec->bit_stream, 8 );
725                 t  = GetBits( &p_dec->bit_stream, 8 );
726                 i_processed_length += 6;
727         }
728         else
729         {
730                 y  = GetBits( &p_dec->bit_stream, 6 );
731                 cr = GetBits( &p_dec->bit_stream, 4 );
732                 cb = GetBits( &p_dec->bit_stream, 4 );
733                 t  = GetBits( &p_dec->bit_stream, 2 );
734                 i_processed_length += 4;
735         }
736         dvbsub_clut_add_entry(clut, i_entry_type, i_entry_id, y, cr, cb, t);
737     }
738 }
739
740
741 static void dvbsub_clut_add_entry ( dvbsub_clut_t* clut, uint8_t type,
742                                     uint8_t id, uint8_t y, uint8_t cr,
743                                     uint8_t cb, uint8_t t)
744 {
745     /* According to EN 300-743 section 7.2.3 note 1, type should
746      * not have more than 1 bit set to one
747        But, some strams don't respect this note. */
748     if( type & 0x04)
749     {
750         clut->c_2b[id].Y = y;
751         clut->c_2b[id].Cr = cr;
752         clut->c_2b[id].Cb = cb;
753         clut->c_2b[id].T = t;
754     }
755     if( type & 0x02)
756     {
757         clut->c_4b[id].Y = y;
758         clut->c_4b[id].Cr = cr;
759         clut->c_4b[id].Cb = cb;
760         clut->c_4b[id].T = t;
761     }
762     if( type & 0x01)
763     {
764         clut->c_8b[id].Y = y;
765         clut->c_8b[id].Cr = cr;
766         clut->c_8b[id].Cb = cb;
767         clut->c_8b[id].T = t;
768     }
769     return;
770 }
771
772
773 static void dvbsub_add_objectdef_to_region ( dvbsub_objectdef_t* p_obj,
774                                    dvbsub_region_t* p_region )
775 {
776     dvbsub_objectdef_t* p_o = p_region->p_object;
777     // Seek to the last non null element
778     if(p_o!=NULL)
779     {
780         for(; p_o->p_next!=NULL; p_o=p_o->p_next);
781         p_o->p_next = p_obj;
782         p_o->p_next->p_next = NULL;
783     }
784     else
785     {
786         p_region->p_object = p_obj;
787         p_region->p_object->p_next = NULL;
788     }
789     return;
790 }
791
792
793 static dvbsub_image_t* dvbsub_parse_pdata ( dvbsub_thread_t* p_spudec,
794                                                    uint16_t length )
795 {
796     dvbsub_image_t* p_image;
797     uint16_t i_processed_length=0;
798     uint16_t i_lines=0;
799     uint16_t i_cols_last=0;
800     p_image = trox_malloc ( sizeof ( dvbsub_image_t) );
801     p_image->p_last=NULL;
802     memset(p_image->i_cols, 0, 576*sizeof(uint16_t));
803     /* Let's parse it a first time to determine the size of the buffer */
804     while (i_processed_length < length)
805     {
806         switch(GetBits( &p_spudec->bit_stream, 8 ))
807         {
808             case 0x10:
809                 fprintf(stderr, "0x10 N/A\n");
810                 break;
811             case 0x11:
812                 i_processed_length += 1 + dvbsub_count0x11(p_spudec,
813                                                 &(p_image->i_cols[i_lines]),
814                                                 p_image);
815                 break;
816             case 0x12:
817                 fprintf(stderr, "0x12 N/A\n");
818                 break;
819             case 0x20:
820                 fprintf(stderr, "0x20 N/A\n");
821                 break;
822             case 0x21:
823                 fprintf(stderr, "0x21 N/A\n");
824                 break;
825             case 0x22:
826                 fprintf(stderr, "0x22 N/A\n");
827                 break;
828             case 0xf0:
829                 i_processed_length++;
830                 i_lines++;
831                 break;
832         }
833     }
834     p_image->i_rows =  i_lines;
835     p_image->i_cols[i_lines] = i_cols_last;
836     // Check word-aligned bits
837     if(ShowBits( &p_spudec->bit_stream, 8 )==0x00)
838         GetBits( &p_spudec->bit_stream, 8 );
839     return p_image;
840 }
841
842
843
844 static void add_rle_code (dvbsub_image_t* p, uint16_t num, uint8_t color)
845 {
846     if(p->p_last != NULL)
847     {
848         p->p_last->p_next = trox_malloc (sizeof (dvbsub_rle_t));
849         p->p_last = p->p_last->p_next;
850    }
851     else
852     {
853         p->p_codes =  trox_malloc (sizeof (dvbsub_rle_t));
854         p->p_last = p->p_codes;
855     }
856     p->p_last->i_num = num;
857     p->p_last->i_color_code = color;
858     p->p_last->p_next = NULL;
859     return;
860 }
861
862
863 static uint16_t dvbsub_count0x11(dvbsub_thread_t* p_spudec, uint16_t* p, dvbsub_image_t* p_image)
864 {
865     uint16_t i_processed=0;
866     vlc_bool_t b_stop=0;
867     uint16_t i_count = 0;
868     uint8_t i_color =0;
869     while (!b_stop)
870     {
871         if ( (i_color = GetBits( &p_spudec->bit_stream, 4 )) != 0x00 )
872         {
873             (*p)++;
874             i_processed+=4;
875             // 1 pixel of color code '0000'
876             add_rle_code (p_image, 1, i_color );
877         }
878         else
879         {
880             if(GetBits( &p_spudec->bit_stream, 1 ) == 0x00)           // Switch1
881             {
882                 if( ShowBits( &p_spudec->bit_stream, 3 ) != 0x00 )
883                 {
884                     i_count = 2 + GetBits( &p_spudec->bit_stream, 3 );
885                     (*p) += i_count ;
886                     add_rle_code (p_image, i_count, 0x00);
887                 }
888                 else
889                 {
890                     GetBits( &p_spudec->bit_stream, 3);
891                     b_stop=1;
892                 }
893                 i_processed += 8;
894             }
895             else
896             {
897                 if(GetBits( &p_spudec->bit_stream, 1 ) == 0x00)        //Switch2
898                 {
899                     i_count =  4 + GetBits( &p_spudec->bit_stream, 2 );
900                     i_color = GetBits(  &p_spudec->bit_stream, 4 );
901                     (*p) += i_count;
902                     i_processed += 12;
903                     add_rle_code(p_image, i_count, i_color);
904                 }
905                 else
906                 {
907                     switch ( GetBits( &p_spudec->bit_stream, 2 ) )     //Switch3
908                     {
909                         case 0x0:
910                             (*p)++;
911                             i_processed += 8;
912                             add_rle_code(p_image, 1, 0x00);
913                             break;
914                         case 0x1:
915                             (*p)+=2;
916                             i_processed += 8;
917                             add_rle_code(p_image, 2, 0x00);
918                             break;
919                         case 0x2:
920                              i_count = 9 + GetBits( &p_spudec->bit_stream, 4 );
921                              i_color = GetBits( &p_spudec->bit_stream, 4 );
922                              (*p)+= i_count;
923                              i_processed += 16;
924                              add_rle_code ( p_image, i_count, i_color );
925                              break;
926                         case 0x3:
927                              i_count= 25 + GetBits( &p_spudec->bit_stream, 8 );
928                              i_color = GetBits( &p_spudec->bit_stream, 4 );
929                              (*p)+= i_count;
930                              i_processed += 20;
931                              add_rle_code ( p_image, i_count, i_color );
932                              break;
933                     }
934                 }
935             }
936         }
937     }
938     RealignBits (  &p_spudec->bit_stream );
939     return (i_processed+7)/8 ;
940 }
941
942 static vlc_bool_t dvbsub_check_page(dvbsub_all_t* dvbsub)
943 {
944     if(dvbsub->p_page != NULL)
945     {
946         if(dvbsub->p_objects != NULL)
947             return VLC_TRUE;
948     }
949     return VLC_FALSE;
950 }
951
952 static void free_image (dvbsub_image_t* p_i)
953 {
954     dvbsub_rle_t* p1;
955     dvbsub_rle_t* p2=NULL;
956
957     for( p1 = p_i->p_codes; p1 != NULL; p1=p2)
958     {
959         p2=p1->p_next;
960         trox_free(p1);
961         p1=NULL;
962     }
963
964     trox_free(p_i);
965 }
966
967 static void free_object (dvbsub_object_t* p_o)
968 {
969     trox_free(p_o);
970 }
971
972 static void free_objectdefs ( dvbsub_objectdef_t* p_o)
973 {
974     dvbsub_objectdef_t* p1;
975     dvbsub_objectdef_t* p2=NULL;
976
977     for( p1 = p_o; p1 != NULL; p1=p2)
978     {
979         p2=p1->p_next;
980         trox_free(p1);
981         p1=NULL;
982     }
983 }
984
985 static void free_regions (dvbsub_region_t* p_r, uint8_t nb)
986 {
987     unsigned int i;
988
989     for (i = 0; i<nb; i++) free_objectdefs ( p_r[i].p_object );
990     trox_free (p_r);
991     p_r = NULL;
992 }
993
994 static void free_objects (dvbsub_object_t* p_o)
995 {
996     dvbsub_object_t* p1;
997     dvbsub_object_t* p2=NULL;
998
999     for( p1 = p_o; p1 != NULL; p1=p2)
1000     {
1001         p2=p1->p_next;
1002         free_image (p1->topfield);
1003         free_image (p1->bottomfield);
1004         free_object(p1);
1005     }
1006 }
1007
1008 static void free_clut ( dvbsub_clut_t* p_c) { trox_free(p_c); }
1009
1010 static void free_page (dvbsub_page_t* p_p)
1011 {
1012     free_regions (p_p->regions, p_p->i_regions_number);
1013     trox_free(p_p);
1014     p_p = NULL;
1015 }
1016
1017 static void free_spu( subpicture_t *p_spu )
1018 {
1019     if ( p_spu->p_sys )
1020     {
1021         free_image(((dvbsub_render_t *)p_spu->p_sys->p_data)->p_rle_top);
1022         free_image(((dvbsub_render_t *)p_spu->p_sys->p_data)->p_rle_bot);
1023         trox_free(p_spu->p_sys->p_data);
1024         trox_free( p_spu->p_sys );
1025         p_spu->p_sys = NULL;
1026     }
1027 }
1028
1029 static void free_all ( dvbsub_all_t* p_a )
1030 {
1031     unsigned int i;
1032
1033     for(i=0; i<0xff; i++) if (p_a->p_clut[i]) free_clut ( p_a->p_clut[i] );
1034     for(i=0; i<16; i++) if (p_a->p_spu[i]) free_spu ( p_a->p_spu[i] );
1035     if(p_a->p_page) free_page( p_a->p_page );
1036     free_objects (p_a->p_objects);
1037
1038 }
1039
1040 static void dvbsub_RenderDVBSUB ( vout_thread_t *p_vout, picture_t *p_pic,
1041                                 const subpicture_t *p_spu, vlc_bool_t b_crop )
1042 {
1043     // If we have changed the language on the fly,
1044     if(!p_spu->p_sys) return;
1045
1046     if(p_spu->p_sys->b_obsolete) return;
1047
1048     switch (p_vout->output.i_chroma)
1049     {
1050         /* I420 target, no scaling */
1051         case VLC_FOURCC('I','4','2','2'):
1052         case VLC_FOURCC('I','4','2','0'):
1053         case VLC_FOURCC('I','Y','U','V'):
1054         case VLC_FOURCC('Y','V','1','2'):
1055             // As long as we just use Y info, I422 and YV12 are just equivalent
1056             // to I420. Remember to change it the day we'll take into account
1057             // U and V info.
1058             RenderI42x( p_vout, p_pic, p_spu, VLC_FALSE );
1059             break;
1060         /* RV16 target, scaling */
1061         case VLC_FOURCC('R','V','1','6'):
1062             fprintf(stderr, "Not implemented chroma ! RV16)\n");
1063             //RenderRV16( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
1064             break;
1065         /* RV32 target, scaling */
1066         case VLC_FOURCC('R','V','2','4'):
1067         case VLC_FOURCC('R','V','3','2'):
1068             fprintf(stderr, "Not implemented chroma ! RV32 \n");
1069             //RenderRV32( p_vout, p_pic, p_spu, p_spu->p_sys->b_crop );
1070             break;
1071         /* NVidia overlay, no scaling */
1072         case VLC_FOURCC('Y','U','Y','2'):
1073             RenderYUY2( p_vout, p_pic, p_spu, VLC_FALSE );
1074             break;
1075         default:
1076             msg_Err( p_vout, "unknown chroma, can't render SPU" );
1077             break;
1078     }
1079 }
1080
1081
1082 static void RenderYUY2 ( vout_thread_t *p_vout, picture_t *p_pic,
1083                         const subpicture_t *p_spu, vlc_bool_t b_crop )
1084 {
1085     /* Common variables */
1086     uint8_t  *p_desty;
1087     uint16_t i,j;
1088     uint16_t i_cnt;
1089     uint16_t x, y;
1090     dvbsub_rle_t* p_c;
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;
1093     i=0;
1094     j=0;
1095     p_desty = p_pic->Y_PIXELS;
1096     //let's render the 1st frame
1097     for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1098     {
1099 //        if( p_c->y != 0  && p_c->t < 0x20)
1100         if( p_c->y != 0  && p_c->t < 0x20)
1101         {
1102             x = j+ p_r->i_x;
1103             y = 2*i+p_r->i_y;
1104             //memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1105             // In YUY2 we have to set pixel per pixel
1106             for( i_cnt = 0; i_cnt < p_c->i_num; i_cnt+=2 )
1107             {
1108                 memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt, p_c->y, 1);
1109            //     memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+1, p_c->cr, 1);
1110           //      memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+2, p_c->y, 1);
1111            //     memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+3, p_c->cb, 1);
1112             }
1113         }
1114         j += p_c->i_num;
1115         if(j >= p_im->i_cols[i])
1116         {
1117             i++; j=0;
1118         }
1119         if( i>= p_im->i_rows) break;
1120     }
1121     //idem for the second frame
1122     p_im = p_r->p_rle_bot; i=0; j=0;
1123     for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1124     {
1125         if( p_c->y != 0 && p_c->t < 0x20)
1126         {
1127             x = j+ p_r->i_x;
1128             y = 2*i+1+p_r->i_y;
1129             //memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1130             // In YUY2 we have to set pixel per pixel
1131             for( i_cnt = 0; i_cnt < p_c->i_num; i_cnt+=2 )
1132             {
1133                 memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt, p_c->y, 1);
1134            //     memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+1, p_c->cr, 1);
1135            //     memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+2, p_c->y, 1);
1136            //     memset(p_desty+ y*p_pic->Y_PITCH + 2*x + i_cnt+3, p_c->cb, 1);
1137            }
1138         }
1139         j += p_c->i_num;
1140         if(j >= p_im->i_cols[i])
1141         {
1142             i++; j=0;
1143         }
1144         if( i>= p_im->i_rows) break;
1145     }
1146 }
1147
1148
1149 static void RenderI42x ( vout_thread_t *p_vout, picture_t *p_pic,
1150                         const subpicture_t *p_spu, vlc_bool_t b_crop )
1151 {
1152     /* Common variables */
1153     uint8_t  *p_desty;
1154     uint8_t  *p_destu;
1155     uint8_t  *p_destv;
1156     uint16_t i,j;
1157     uint16_t x, y;
1158     dvbsub_rle_t* p_c;
1159     dvbsub_render_t* p_r = ((dvbsub_render_t *)p_spu->p_sys->p_data);
1160     dvbsub_image_t* p_im = p_r->p_rle_top;
1161     i=0;
1162     j=0;
1163     p_desty = p_pic->Y_PIXELS;
1164     p_destu = p_pic->U_PIXELS;
1165     p_destv = p_pic->V_PIXELS;
1166     //let's render the 1st frame
1167     for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1168     {
1169         if( p_c->y != 0 )
1170         {
1171             x = j+ p_r->i_x;
1172             y = 2*i+p_r->i_y;
1173             //memset(p_dest+ y*p_pic->U_PITCH*2 + x, p_c->cr, p_c->i_num);
1174 //            memset(p_desty+ (y)*p_pic->Y_PITCH + x, p_c->cr, p_c->i_num);
1175             //memset(p_dest+ y*p_pic->V_PITCH*2 + x, p_c->cb, p_c->i_num);
1176             //memset(p_destu+ (y)*p_pic->Y_PITCH + x, p_c->cb, p_c->i_num);
1177             memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1178   //          memset(p_desty+ 2*y*p_pic->U_PITCH + x, p_c->cr, p_c->i_num);
1179   //          memset(p_desty+ 2*y*p_pic->V_PITCH + x, p_c->cb, p_c->i_num);
1180         }
1181         j += p_c->i_num;
1182         if(j >= p_im->i_cols[i])
1183         {
1184             i++; j=0;
1185         }
1186         if( i>= p_im->i_rows) break;
1187     }
1188     //idem for the second frame
1189     p_im = p_r->p_rle_bot; i=0; j=0;
1190     for(p_c = p_im->p_codes; p_c->p_next != NULL; p_c=p_c->p_next)
1191     {
1192         if( p_c->y != 0 && p_c->t < 0x20)
1193         {
1194             x = j+ p_r->i_x;
1195             y = 2*i+1+p_r->i_y;
1196 //            memset(p_desty+ y*p_pic->U_PITCH*2 + x, p_c->cr, p_c->i_num);
1197 //            memset(p_desty+ y*p_pic->V_PITCH*2 + x, p_c->cb, p_c->i_num);
1198             memset(p_desty+ y*p_pic->Y_PITCH + x, p_c->y, p_c->i_num);
1199 //            memset(p_desty+ 2*y*p_pic->U_PITCH + x, p_c->cr, p_c->i_num);
1200 //            memset(p_desty+ 2*y*p_pic->V_PITCH + x, p_c->cb, p_c->i_num);
1201         }
1202         j += p_c->i_num;
1203         if(j >= p_im->i_cols[i])
1204         {
1205             i++; j=0;
1206         }
1207         if( i>= p_im->i_rows) break;
1208     }
1209 }
1210
1211 static void dvbsub_Destroy( subpicture_t *p_spu )
1212 {
1213     free_spu( p_spu );
1214 }
1215
1216 static void dvbsub_render( dvbsub_thread_t *p_dec, dvbsub_all_t* dvbsub)
1217 {
1218     dvbsub_region_t*     p_region;
1219     dvbsub_objectdef_t*  p_objectdef;
1220     dvbsub_object_t*     p_o;
1221     dvbsub_object_t*     p_object;
1222     dvbsub_object_t*     p_object_old;
1223     dvbsub_render_t*     p_render;
1224     dvbsub_rle_t*        p_c;
1225     uint8_t i,j;
1226     j=0;
1227     /* loop on regions */
1228     for(i=0; i< dvbsub->p_page->i_regions_number; i++)
1229     {
1230         p_region = &(dvbsub->p_page->regions[i]);
1231     /* loop on objects */
1232     for(p_objectdef = p_region->p_object;
1233           p_objectdef != NULL;
1234             p_objectdef = p_objectdef->p_next)
1235     {
1236         /* Look for the right object */
1237         p_object = dvbsub->p_objects;
1238         while((p_object!=NULL) && (p_object->i_id != p_objectdef->i_id))
1239         {
1240             p_object = p_object->p_next;
1241         }
1242         if(p_object==NULL)
1243         {
1244             fprintf(stderr, "Internal DvbSub decoder error\n");
1245             return;
1246         }
1247         /* Allocate the render structure */
1248         p_render = trox_malloc(sizeof(dvbsub_render_t));
1249         p_render->i_x = p_region->i_x + p_objectdef->i_xoffset;
1250         p_render->i_y = p_region->i_y + p_objectdef->i_yoffset;
1251         p_render->p_rle_top = p_object->topfield;
1252         p_render->p_rle_bot = p_object->bottomfield;
1253
1254         // if we did not recieved the CLUT yet
1255         if ( !dvbsub->p_clut[p_region->i_clut] ) return;
1256
1257         /* Compute the color datas according to the appropriate CLUT */
1258         for(p_c=p_render->p_rle_top->p_codes;p_c->p_next!=NULL; p_c=p_c->p_next)
1259         {
1260             //TODO We assume here we are working in 4bp
1261             p_c->y=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Y;
1262             p_c->cr=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cr;
1263             p_c->cb=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cb;
1264             p_c->t=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].T;
1265         }
1266         for(p_c=p_render->p_rle_bot->p_codes;p_c->p_next!=NULL; p_c=p_c->p_next)
1267         {
1268             //TODO We assume here we are working in 4bp
1269             p_c->y=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Y;
1270             p_c->cr=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cr;
1271             p_c->cb=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].Cb;
1272             p_c->t=dvbsub->p_clut[p_region->i_clut]->c_4b[p_c->i_color_code].T;
1273         }
1274
1275
1276         /* Allocate the subpicture internal data. */
1277         dvbsub->p_spu[j] = vout_CreateSubPicture( p_dec->p_vout,
1278                                                       MEMORY_SUBPICTURE );
1279         if( dvbsub->p_spu[j] == NULL )
1280         {
1281             fprintf(stderr, "Unable to allocate memory ... skipping\n");
1282             return;
1283         }
1284         /* Set the pf_render callback */
1285         dvbsub->p_spu[j]->pf_render = dvbsub_RenderDVBSUB;
1286         dvbsub->p_spu[j]->p_sys =  trox_malloc( sizeof( subpicture_sys_t ));
1287         dvbsub->p_spu[j]->p_sys->p_data = p_render;
1288         dvbsub->p_spu[j]->p_sys->b_obsolete=0;
1289         dvbsub->p_spu[j]->pf_destroy = dvbsub_Destroy;
1290         dvbsub->p_spu[j]->i_start = p_dec->bit_stream.p_pes->i_pts;
1291         dvbsub->p_spu[j]->i_stop =  dvbsub->p_spu[j]->i_start + dvbsub->p_page->i_timeout*1000000;
1292         dvbsub->p_spu[j]->b_ephemer = VLC_FALSE;
1293
1294         // At this stage, we have all we need in p_render
1295         // We need to free the object
1296         //Remove this object from the list
1297         p_object_old = p_object;
1298         if(p_object == dvbsub->p_objects)
1299           dvbsub->p_objects = p_object->p_next;
1300         else
1301         {
1302          for(p_o = dvbsub->p_objects; p_o->p_next != p_object; p_o=p_o->p_next);
1303          p_o->p_next = p_object->p_next;
1304         }
1305         free_object(p_object_old);
1306
1307         vout_DisplaySubPicture (p_dec->p_vout, dvbsub->p_spu[j] );
1308         j++;
1309     }
1310     }
1311 }