]> git.sesse.net Git - vlc/blob - modules/codec/dvbsub.c
* modules/codec/dvbsub.c: add_suppressed -> add_suppressed_integer
[vlc] / modules / codec / dvbsub.c
1 /*****************************************************************************
2  * dvbsub.c : DVB subtitles decoder
3  *            DVB subtitles encoder (developed for Anevia, www.anevia.com)
4  *****************************************************************************
5  * Copyright (C) 2003 ANEVIA
6  * Copyright (C) 2003-2005 the VideoLAN team
7  * $Id$
8  *
9  * Authors: Gildas Bazin <gbazin@videolan.org>
10  *          Damien LUCAS <damien.lucas@anevia.com>
11  *          Laurent Aimar <fenrir@via.ecp.fr>
12  *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27  *****************************************************************************/
28 /*****************************************************************************
29  * Preamble
30  *
31  * FIXME:
32  * DVB subtitles coded as strings of characters are not handled correctly.
33  * The character codes in the string should actually be indexes refering to a
34  * character table identified in the subtitle descriptor.
35  *****************************************************************************/
36 #include <vlc/vlc.h>
37 #include <vlc/vout.h>
38 #include <vlc/decoder.h>
39 #include <vlc/sout.h>
40
41 #include "vlc_bits.h"
42
43 /* #define DEBUG_DVBSUB 1 */
44
45 #define POSX_TEXT N_("Decoding X coordinate")
46 #define POSX_LONGTEXT N_("X coordinate of the rendered subtitle")
47
48 #define POSY_TEXT N_("Decoding Y coordinate")
49 #define POSY_LONGTEXT N_("Y coordinate of the rendered subtitle") 
50
51 #define POS_TEXT N_("Subpicture position")
52 #define POS_LONGTEXT N_( \
53   "You can enforce the subpicture position on the video " \
54   "(0=center, 1=left, 2=right, 4=top, 8=bottom, you can " \
55   "also use combinations of these values, e.g. 6=top-right).")
56
57 #define ENC_POSX_TEXT N_("Encoding X coordinate")
58 #define ENC_POSX_LONGTEXT N_("X coordinate of the encoded subtitle" )
59 #define ENC_POSY_TEXT N_("Encoding Y coordinate")
60 #define ENC_POSY_LONGTEXT N_("Y coordinate of the encoded subtitle" )
61
62 static int pi_pos_values[] = { 0, 1, 2, 4, 8, 5, 6, 9, 10 };
63 static char *ppsz_pos_descriptions[] =
64 { N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
65   N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
66
67 /*****************************************************************************
68  * Module descriptor.
69  *****************************************************************************/
70 static int  Open ( vlc_object_t * );
71 static void Close( vlc_object_t * );
72 static subpicture_t *Decode( decoder_t *, block_t ** );
73
74 static int OpenEncoder  ( vlc_object_t * );
75 static void CloseEncoder( vlc_object_t * );
76 static block_t *Encode  ( encoder_t *, subpicture_t * );
77
78 vlc_module_begin();
79 #   define DVBSUB_CFG_PREFIX "dvbsub-"
80     set_description( _("DVB subtitles decoder") );
81     set_capability( "decoder", 50 );
82     set_category( CAT_INPUT );
83     set_subcategory( SUBCAT_INPUT_SCODEC );
84     set_callbacks( Open, Close );
85
86     add_integer( DVBSUB_CFG_PREFIX "position", 8, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );
87         change_integer_list( pi_pos_values, ppsz_pos_descriptions, 0 );
88     add_integer( DVBSUB_CFG_PREFIX "x", -1, NULL, POSX_TEXT, POSX_LONGTEXT, VLC_FALSE );
89     add_integer( DVBSUB_CFG_PREFIX "y", -1, NULL, POSY_TEXT, POSY_LONGTEXT, VLC_FALSE );
90
91 #   define ENC_CFG_PREFIX "sout-dvbsub-"
92     add_submodule();
93     set_description( _("DVB subtitles encoder") );
94     set_capability( "encoder", 100 );
95     set_callbacks( OpenEncoder, CloseEncoder );
96
97     add_integer( ENC_CFG_PREFIX "x", -1, NULL, ENC_POSX_TEXT, ENC_POSX_LONGTEXT, VLC_FALSE );
98     add_integer( ENC_CFG_PREFIX "y", -1, NULL, ENC_POSY_TEXT, ENC_POSY_LONGTEXT, VLC_FALSE );
99     add_suppressed_integer( ENC_CFG_PREFIX "timeout" ); /* Suppressed since 0.8.5 */
100 vlc_module_end();
101
102 static const char *ppsz_enc_options[] = { "x", "y", NULL };
103
104 /****************************************************************************
105  * Local structures
106  ****************************************************************************
107  * Those structures refer closely to the ETSI 300 743 Object model
108  ****************************************************************************/
109
110 /* The object definition gives the position of the object in a region */
111 typedef struct dvbsub_objectdef_s
112 {
113     int i_id;
114     int i_type;
115     int i_x;
116     int i_y;
117     int i_fg_pc;
118     int i_bg_pc;
119     char *psz_text; /* for string of characters objects */
120
121 } dvbsub_objectdef_t;
122
123 /* The entry in the palette CLUT */
124 typedef struct
125 {
126     uint8_t                 Y;
127     uint8_t                 Cr;
128     uint8_t                 Cb;
129     uint8_t                 T;
130
131 } dvbsub_color_t;
132
133 /* */
134 typedef struct dvbsub_clut_s
135 {
136     uint8_t                 i_id;
137     uint8_t                 i_version;
138     dvbsub_color_t          c_2b[4];
139     dvbsub_color_t          c_4b[16];
140     dvbsub_color_t          c_8b[256];
141
142     struct dvbsub_clut_s    *p_next;
143
144 } dvbsub_clut_t;
145
146 /* The Region is an aera on the image
147  * with a list of the object definitions associated and a CLUT */
148 typedef struct dvbsub_region_s
149 {
150     int i_id;
151     int i_version;
152     int i_x;
153     int i_y;
154     int i_width;
155     int i_height;
156     int i_level_comp;
157     int i_depth;
158     int i_clut;
159
160     uint8_t *p_pixbuf;
161
162     int                    i_object_defs;
163     dvbsub_objectdef_t     *p_object_defs;
164
165     struct dvbsub_region_s *p_next;
166
167 } dvbsub_region_t;
168
169 /* The object definition gives the position of the object in a region */
170 typedef struct dvbsub_regiondef_s
171 {
172     int i_id;
173     int i_x;
174     int i_y;
175
176 } dvbsub_regiondef_t;
177
178 /* The page defines the list of regions */
179 typedef struct
180 {
181     int i_id;
182     int i_timeout; /* in seconds */
183     int i_state;
184     int i_version;
185
186     int                i_region_defs;
187     dvbsub_regiondef_t *p_region_defs;
188
189 } dvbsub_page_t;
190
191 struct decoder_sys_t
192 {
193     bs_t            bs;
194
195     /* Decoder internal data */
196     int             i_id;
197     int             i_ancillary_id;
198     mtime_t         i_pts;
199
200     vlc_bool_t      b_absolute;
201     int             i_spu_position;
202     int             i_spu_x;
203     int             i_spu_y;
204
205     vlc_bool_t      b_page;
206     dvbsub_page_t   *p_page;
207     dvbsub_region_t *p_regions;
208     dvbsub_clut_t   *p_cluts;
209     dvbsub_clut_t   default_clut;
210 };
211
212
213 /* List of different SEGMENT TYPES */
214 /* According to EN 300-743, table 2 */
215 #define DVBSUB_ST_PAGE_COMPOSITION      0x10
216 #define DVBSUB_ST_REGION_COMPOSITION    0x11
217 #define DVBSUB_ST_CLUT_DEFINITION       0x12
218 #define DVBSUB_ST_OBJECT_DATA           0x13
219 #define DVBSUB_ST_ENDOFDISPLAY          0x80
220 #define DVBSUB_ST_STUFFING              0xff
221 /* List of different OBJECT TYPES */
222 /* According to EN 300-743, table 6 */
223 #define DVBSUB_OT_BASIC_BITMAP          0x00
224 #define DVBSUB_OT_BASIC_CHAR            0x01
225 #define DVBSUB_OT_COMPOSITE_STRING      0x02
226 /* Pixel DATA TYPES */
227 /* According to EN 300-743, table 9 */ 
228 #define DVBSUB_DT_2BP_CODE_STRING       0x10
229 #define DVBSUB_DT_4BP_CODE_STRING       0x11
230 #define DVBSUB_DT_8BP_CODE_STRING       0x12
231 #define DVBSUB_DT_24_TABLE_DATA         0x20
232 #define DVBSUB_DT_28_TABLE_DATA         0x21
233 #define DVBSUB_DT_48_TABLE_DATA         0x22
234 #define DVBSUB_DT_END_LINE              0xf0
235 /* List of different Page Composition Segment state */
236 /* According to EN 300-743, 7.2.1 table 3 */
237 #define DVBSUB_PCS_STATE_ACQUISITION    0x01
238 #define DVBSUB_PCS_STATE_CHANGE         0x02
239
240 /*****************************************************************************
241  * Local prototypes
242  *****************************************************************************/
243 static void decode_segment( decoder_t *, bs_t * );
244 static void decode_page_composition( decoder_t *, bs_t * );
245 static void decode_region_composition( decoder_t *, bs_t * );
246 static void decode_object( decoder_t *, bs_t * );
247 static void decode_clut( decoder_t *, bs_t * );
248 static void free_all( decoder_t * );
249
250 static void default_clut_init( decoder_t * );
251
252 static subpicture_t *render( decoder_t * );
253
254 /*****************************************************************************
255  * Open: probe the decoder and return score
256  *****************************************************************************
257  * Tries to launch a decoder and return score so that the interface is able
258  * to chose.
259  *****************************************************************************/
260 static int Open( vlc_object_t *p_this )
261 {
262     decoder_t     *p_dec = (decoder_t *) p_this;
263     decoder_sys_t *p_sys;
264     vlc_value_t    val;
265     int i_posx, i_posy;
266
267     if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
268     {
269         return VLC_EGENERIC;
270     }
271
272     p_dec->pf_decode_sub = Decode;
273     p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) );
274     memset( p_sys, 0, sizeof(decoder_sys_t) );
275
276     p_sys->i_pts          = (mtime_t) 0;    
277     p_sys->i_id           = p_dec->fmt_in.subs.dvb.i_id & 0xFFFF;
278     p_sys->i_ancillary_id = p_dec->fmt_in.subs.dvb.i_id >> 16;
279
280     p_sys->p_regions      = NULL;
281     p_sys->p_cluts        = NULL;
282     p_sys->p_page         = NULL;
283
284     var_Create( p_this, DVBSUB_CFG_PREFIX "position",
285                 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
286     var_Get( p_this, DVBSUB_CFG_PREFIX "position", &val );
287     p_sys->i_spu_position = val.i_int;
288     var_Create( p_this, DVBSUB_CFG_PREFIX "x",
289                 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
290     var_Get( p_this, DVBSUB_CFG_PREFIX "x", &val );
291     i_posx = val.i_int;
292     var_Create( p_this, DVBSUB_CFG_PREFIX "y",
293                 VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
294     var_Get( p_this, DVBSUB_CFG_PREFIX "y", &val );
295     i_posy = val.i_int;
296
297     /* Check if subpicture position was overridden */
298     p_sys->b_absolute = VLC_TRUE;
299     p_sys->i_spu_x = p_sys->i_spu_y = 0;
300
301     if( i_posx >= 0 && i_posy >= 0 )
302     {
303         p_sys->b_absolute = VLC_FALSE;
304         p_sys->i_spu_x = i_posx;
305         p_sys->i_spu_y = i_posy;
306     }
307
308     es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'd','v','b','s' ) );
309
310     default_clut_init( p_dec );
311
312     return VLC_SUCCESS;
313 }
314
315 /*****************************************************************************
316  * Close:
317  *****************************************************************************/
318 static void Close( vlc_object_t *p_this )
319 {
320     decoder_t     *p_dec = (decoder_t*) p_this;
321     decoder_sys_t *p_sys = p_dec->p_sys;
322
323     var_Destroy( p_this, DVBSUB_CFG_PREFIX "x" );
324     var_Destroy( p_this, DVBSUB_CFG_PREFIX "y" );
325     var_Destroy( p_this, DVBSUB_CFG_PREFIX "position" );    
326
327     free_all( p_dec );
328     free( p_sys );
329 }
330
331 /*****************************************************************************
332  * Decode:
333  *****************************************************************************/
334 static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
335 {
336     decoder_sys_t *p_sys = p_dec->p_sys;
337     block_t       *p_block;
338     subpicture_t  *p_spu = NULL;
339
340     if( pp_block == NULL || *pp_block == NULL ) return NULL;
341     p_block = *pp_block;
342     *pp_block = NULL;
343
344     p_sys->i_pts = p_block->i_pts;
345     if( p_sys->i_pts <= 0 )
346     {
347 #ifdef DEBUG_DVBSUB
348         /* Some DVB channels send stuffing segments in non-dated packets so
349          * don't complain too loudly. */
350         msg_Warn( p_dec, "non dated subtitle" );
351 #endif
352         block_Release( p_block );
353         return NULL;
354     }
355
356     bs_init( &p_sys->bs, p_block->p_buffer, p_block->i_buffer );
357
358     if( bs_read( &p_sys->bs, 8 ) != 0x20 ) /* Data identifier */
359     {
360         msg_Dbg( p_dec, "invalid data identifier" );
361         block_Release( p_block );
362         return NULL;
363     }
364
365     if( bs_read( &p_sys->bs, 8 ) ) /* Subtitle stream id */
366     {
367         msg_Dbg( p_dec, "invalid subtitle stream id" );
368         block_Release( p_block );
369         return NULL;
370     }
371
372 #ifdef DEBUG_DVBSUB
373     msg_Dbg( p_dec, "subtitle packet received: "I64Fd, p_sys->i_pts );
374 #endif
375
376     p_sys->b_page = VLC_FALSE;
377     while( bs_show( &p_sys->bs, 8 ) == 0x0f ) /* Sync byte */
378     {
379         decode_segment( p_dec, &p_sys->bs );
380     }
381
382     if( bs_read( &p_sys->bs, 8 ) != 0xff ) /* End marker */
383     {
384         msg_Warn( p_dec, "end marker not found (corrupted subtitle ?)" );
385         block_Release( p_block );
386         return NULL;
387     }
388
389     /* Check if the page is to be displayed */
390     if( p_sys->p_page && p_sys->b_page ) p_spu = render( p_dec );
391
392     block_Release( p_block );
393
394     return p_spu;
395 }
396
397 /* following functions are local */
398
399 /*****************************************************************************
400  * default_clut_init: default clut as defined in EN 300-743 section 10
401  *****************************************************************************/
402 static void default_clut_init( decoder_t *p_dec )
403 {
404     decoder_sys_t *p_sys = p_dec->p_sys;
405     uint8_t i;
406
407 #define RGB_TO_Y(r, g, b) ((int16_t) 77 * r + 150 * g + 29 * b) / 256;
408 #define RGB_TO_U(r, g, b) ((int16_t) -44 * r - 87 * g + 131 * b) / 256;
409 #define RGB_TO_V(r, g, b) ((int16_t) 131 * r - 110 * g - 21 * b) / 256;
410
411     /* 4 entries CLUT */
412     for( i = 0; i < 4; i++ )
413     {
414         uint8_t R = 0, G = 0, B = 0, T = 0;
415
416         if( !(i & 0x2) && !(i & 0x1) ) T = 0xFF;
417         else if( !(i & 0x2) && (i & 0x1) ) R = G = B = 0xFF;
418         else if( (i & 0x2) && !(i & 0x1) ) R = G = B = 0;
419         else R = G = B = 0x7F;
420
421         p_sys->default_clut.c_2b[i].Y = RGB_TO_Y(R,G,B);
422         p_sys->default_clut.c_2b[i].Cr = RGB_TO_U(R,G,B);
423         p_sys->default_clut.c_2b[i].Cb = RGB_TO_V(R,G,B);
424         p_sys->default_clut.c_2b[i].T = T;
425     }
426
427     /* 16 entries CLUT */
428     for( i = 0; i < 16; i++ )
429     {
430         uint8_t R = 0, G = 0, B = 0, T = 0;
431
432         if( !(i & 0x8) )
433         {
434             if( !(i & 0x4) && !(i & 0x2) && !(i & 0x1) )
435             {
436                 T = 0xFF;
437             }
438             else
439             {
440                 R = (i & 0x1) ? 0xFF : 0;
441                 G = (i & 0x2) ? 0xFF : 0;
442                 B = (i & 0x4) ? 0xFF : 0;
443             }
444         }
445         else
446         {
447             R = (i & 0x1) ? 0x7F : 0;
448             G = (i & 0x2) ? 0x7F : 0;
449             B = (i & 0x4) ? 0x7F : 0;
450         }
451
452         p_sys->default_clut.c_4b[i].Y = RGB_TO_Y(R,G,B);
453         p_sys->default_clut.c_4b[i].Cr = RGB_TO_U(R,G,B);
454         p_sys->default_clut.c_4b[i].Cb = RGB_TO_V(R,G,B);
455         p_sys->default_clut.c_4b[i].T = T;
456     }
457
458     /* 256 entries CLUT */
459     memset( p_sys->default_clut.c_8b, 0xFF, 256 * sizeof(dvbsub_color_t) );
460 }
461
462 static void decode_segment( decoder_t *p_dec, bs_t *s )
463 {
464     decoder_sys_t *p_sys = p_dec->p_sys;
465     int i_type;
466     int i_page_id;
467     int i_size;
468
469     /* sync_byte (already checked) */
470     bs_skip( s, 8 );
471
472     /* segment type */
473     i_type = bs_read( s, 8 );
474
475     /* page id */
476     i_page_id = bs_read( s, 16 );
477
478     /* segment size */
479     i_size = bs_show( s, 16 );
480
481     if( i_page_id != p_sys->i_id && i_page_id != p_sys->i_ancillary_id )
482     {
483 #ifdef DEBUG_DVBSUB
484         msg_Dbg( p_dec, "subtitle skipped (page id: %i, %i)",
485                  i_page_id, p_sys->i_id );
486 #endif
487         bs_skip( s,  8 * ( 2 + i_size ) );
488         return;
489     }
490
491     if( p_sys->i_ancillary_id != p_sys->i_id &&
492         i_type == DVBSUB_ST_PAGE_COMPOSITION &&
493         i_page_id == p_sys->i_ancillary_id )
494     {
495 #ifdef DEBUG_DVBSUB
496         msg_Dbg( p_dec, "skipped invalid ancillary subtitle packet" );
497 #endif
498         bs_skip( s,  8 * ( 2 + i_size ) );
499         return;
500     }
501
502 #ifdef DEBUG_DVBSUB
503     if( i_page_id == p_sys->i_id )
504         msg_Dbg( p_dec, "segment (id: %i)", i_page_id );
505     else
506         msg_Dbg( p_dec, "ancillary segment (id: %i)", i_page_id );
507 #endif
508
509     switch( i_type )
510     {
511     case DVBSUB_ST_PAGE_COMPOSITION:
512 #ifdef DEBUG_DVBSUB
513         msg_Dbg( p_dec, "decode_page_composition" );
514 #endif
515         decode_page_composition( p_dec, s );
516         break;
517
518     case DVBSUB_ST_REGION_COMPOSITION:
519 #ifdef DEBUG_DVBSUB
520         msg_Dbg( p_dec, "decode_region_composition" );
521 #endif
522         decode_region_composition( p_dec, s );
523         break;
524
525     case DVBSUB_ST_CLUT_DEFINITION:
526 #ifdef DEBUG_DVBSUB
527         msg_Dbg( p_dec, "decode_clut" );
528 #endif
529         decode_clut( p_dec, s );
530         break;
531
532     case DVBSUB_ST_OBJECT_DATA:
533 #ifdef DEBUG_DVBSUB
534         msg_Dbg( p_dec, "decode_object" );
535 #endif
536         decode_object( p_dec, s );
537         break;
538
539     case DVBSUB_ST_ENDOFDISPLAY:
540 #ifdef DEBUG_DVBSUB
541         msg_Dbg( p_dec, "end of display" );
542 #endif
543         bs_skip( s,  8 * ( 2 + i_size ) );
544         break;
545
546     case DVBSUB_ST_STUFFING:
547 #ifdef DEBUG_DVBSUB
548         msg_Dbg( p_dec, "skip stuffing" );
549 #endif
550         bs_skip( s,  8 * ( 2 + i_size ) );
551         break;
552
553     default:
554         msg_Warn( p_dec, "unsupported segment type: (%04x)", i_type );
555         bs_skip( s,  8 * ( 2 + i_size ) );
556         break;
557     }
558 }
559
560 static void decode_clut( decoder_t *p_dec, bs_t *s )
561 {
562     decoder_sys_t *p_sys = p_dec->p_sys;
563     uint16_t      i_segment_length;
564     uint16_t      i_processed_length;
565     dvbsub_clut_t *p_clut, *p_next;
566     int           i_id, i_version;
567
568     i_segment_length = bs_read( s, 16 );
569     i_id             = bs_read( s, 8 );
570     i_version        = bs_read( s, 4 );
571
572     /* Check if we already have this clut */
573     for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )
574     {
575         if( p_clut->i_id == i_id ) break;
576     }
577
578     /* Check version number */
579     if( p_clut && p_clut->i_version == i_version )
580     {
581         /* Nothing to do */
582         bs_skip( s, 8 * i_segment_length - 12 );
583         return;
584     }
585
586     if( !p_clut )
587     {
588 #ifdef DEBUG_DVBSUB
589         msg_Dbg( p_dec, "new clut: %i", i_id );
590 #endif
591         p_clut = malloc( sizeof(dvbsub_clut_t) );
592         p_clut->p_next = p_sys->p_cluts;
593         p_sys->p_cluts = p_clut;
594     }
595
596     /* Initialize to default clut */
597     p_next = p_clut->p_next;
598     *p_clut = p_sys->default_clut;
599     p_clut->p_next = p_next;
600
601     /* We don't have this version of the CLUT: Parse it */
602     p_clut->i_version = i_version;
603     p_clut->i_id = i_id;
604     bs_skip( s, 4 ); /* Reserved bits */
605     i_processed_length = 2;
606     while( i_processed_length < i_segment_length )
607     {
608         uint8_t y, cb, cr, t;
609         uint8_t i_id;
610         uint8_t i_type;
611
612         i_id = bs_read( s, 8 );
613         i_type = bs_read( s, 3 );
614
615         bs_skip( s, 4 );
616
617         if( bs_read( s, 1 ) )
618         {
619             y  = bs_read( s, 8 );
620             cr = bs_read( s, 8 );
621             cb = bs_read( s, 8 );
622             t  = bs_read( s, 8 );
623             i_processed_length += 6;
624         }
625         else
626         {
627             y  = bs_read( s, 6 ) << 2;
628             cr = bs_read( s, 4 ) << 4;
629             cb = bs_read( s, 4 ) << 4;
630             t  = bs_read( s, 2 ) << 6;
631             i_processed_length += 4;
632         }
633
634         /* We are not entirely compliant here as full transparency is indicated
635          * with a luma value of zero, not a transparency value of 0xff
636          * (full transparency would actually be 0xff + 1). */
637         if( y == 0 )
638         {
639             cr = cb = 0;
640             t  = 0xff;
641         }
642
643         /* According to EN 300-743 section 7.2.3 note 1, type should
644          * not have more than 1 bit set to one, but some streams don't
645          * respect this note. */
646         if( i_type & 0x04 && i_id < 4 )
647         {
648             p_clut->c_2b[i_id].Y = y;
649             p_clut->c_2b[i_id].Cr = cr;
650             p_clut->c_2b[i_id].Cb = cb;
651             p_clut->c_2b[i_id].T = t;
652         }
653         if( i_type & 0x02 && i_id < 16 )
654         {
655             p_clut->c_4b[i_id].Y = y;
656             p_clut->c_4b[i_id].Cr = cr;
657             p_clut->c_4b[i_id].Cb = cb;
658             p_clut->c_4b[i_id].T = t;
659         }
660         if( i_type & 0x01 )
661         {
662             p_clut->c_8b[i_id].Y = y;
663             p_clut->c_8b[i_id].Cr = cr;
664             p_clut->c_8b[i_id].Cb = cb;
665             p_clut->c_8b[i_id].T = t;
666         }
667     }
668 }
669
670 static void decode_page_composition( decoder_t *p_dec, bs_t *s )
671 {
672     decoder_sys_t *p_sys = p_dec->p_sys;
673     int i_version, i_state, i_segment_length, i_timeout, i;
674
675     /* A page is composed by 0 or more region */
676     i_segment_length = bs_read( s, 16 );
677     i_timeout = bs_read( s, 8 );
678     i_version = bs_read( s, 4 );
679     i_state = bs_read( s, 2 );
680     bs_skip( s, 2 ); /* Reserved */
681
682     if( i_state == DVBSUB_PCS_STATE_CHANGE )
683     {
684         /* End of an epoch, reset decoder buffer */
685 #ifdef DEBUG_DVBSUB
686         msg_Dbg( p_dec, "page composition mode change" );
687 #endif
688         free_all( p_dec );
689     }
690     else if( !p_sys->p_page && i_state != DVBSUB_PCS_STATE_ACQUISITION &&
691              i_state != DVBSUB_PCS_STATE_CHANGE )
692     {
693         /* Not a full PCS, we need to wait for one */
694         msg_Dbg( p_dec, "didn't receive an acquisition page yet" );
695
696 #if 0
697         /* Try to start decoding even without an acquisition page */
698         bs_skip( s,  8 * (i_segment_length - 2) );
699         return;
700 #endif
701     }
702
703 #ifdef DEBUG_DVBSUB
704     if( i_state == DVBSUB_PCS_STATE_ACQUISITION )
705         msg_Dbg( p_dec, "acquisition page composition" );
706 #endif
707
708     /* Check version number */
709     if( p_sys->p_page && p_sys->p_page->i_version == i_version )
710     {
711         bs_skip( s,  8 * (i_segment_length - 2) );
712         return;
713     }
714     else if( p_sys->p_page )
715     {
716         if( p_sys->p_page->i_region_defs )
717             free( p_sys->p_page->p_region_defs );
718         p_sys->p_page->i_region_defs = 0;
719     }
720
721     if( !p_sys->p_page )
722     {
723 #ifdef DEBUG_DVBSUB
724         msg_Dbg( p_dec, "new page" );
725 #endif
726         /* Allocate a new page */
727         p_sys->p_page = malloc( sizeof(dvbsub_page_t) );
728     }
729
730     p_sys->p_page->i_version = i_version;
731     p_sys->p_page->i_timeout = i_timeout;
732     p_sys->b_page = VLC_TRUE;
733
734     /* Number of regions */
735     p_sys->p_page->i_region_defs = (i_segment_length - 2) / 6;
736
737     if( p_sys->p_page->i_region_defs == 0 ) return;
738
739     p_sys->p_page->p_region_defs =
740         malloc( p_sys->p_page->i_region_defs * sizeof(dvbsub_region_t) );
741     for( i = 0; i < p_sys->p_page->i_region_defs; i++ )
742     {
743         p_sys->p_page->p_region_defs[i].i_id = bs_read( s, 8 );
744         bs_skip( s, 8 ); /* Reserved */
745         p_sys->p_page->p_region_defs[i].i_x = bs_read( s, 16 );
746         p_sys->p_page->p_region_defs[i].i_y = bs_read( s, 16 );
747
748 #ifdef DEBUG_DVBSUB
749         msg_Dbg( p_dec, "page_composition, region %i (%i,%i)",
750                  i, p_sys->p_page->p_region_defs[i].i_x,
751                  p_sys->p_page->p_region_defs[i].i_y );
752 #endif
753     }
754 }
755
756 static void decode_region_composition( decoder_t *p_dec, bs_t *s )
757 {
758     decoder_sys_t *p_sys = p_dec->p_sys;
759     dvbsub_region_t *p_region, **pp_region = &p_sys->p_regions;
760     int i_segment_length, i_processed_length, i_id, i_version;
761     int i_width, i_height, i_level_comp, i_depth, i_clut;
762     int i_8_bg, i_4_bg, i_2_bg;
763     vlc_bool_t b_fill;
764
765     i_segment_length = bs_read( s, 16 );
766     i_id = bs_read( s, 8 );
767     i_version = bs_read( s, 4 );
768
769     /* Check if we already have this region */
770     for( p_region = p_sys->p_regions; p_region != NULL;
771          p_region = p_region->p_next )
772     {
773         pp_region = &p_region->p_next;
774         if( p_region->i_id == i_id ) break;
775     }
776
777     /* Check version number */
778     if( p_region && p_region->i_version == i_version )
779     {
780         bs_skip( s, 8 * (i_segment_length - 1) - 4 );
781         return;
782     }
783
784     if( !p_region )
785     {
786 #ifdef DEBUG_DVBSUB
787         msg_Dbg( p_dec, "new region: %i", i_id );
788 #endif
789         p_region = *pp_region = malloc( sizeof(dvbsub_region_t) );
790         memset( p_region, 0, sizeof(dvbsub_region_t) );
791         p_region->p_object_defs = NULL;
792         p_region->p_pixbuf = NULL;
793         p_region->p_next = NULL;
794     }
795
796     /* Region attributes */
797     p_region->i_id = i_id;
798     p_region->i_version = i_version;
799     b_fill = bs_read( s, 1 );
800     bs_skip( s, 3 ); /* Reserved */
801
802     i_width = bs_read( s, 16 );
803     i_height = bs_read( s, 16 );
804 #ifdef DEBUG_DVBSUB
805     msg_Dbg( p_dec, " width=%d height=%d", i_width, i_height );
806 #endif
807     i_level_comp = bs_read( s, 3 );
808     i_depth = bs_read( s, 3 );
809     bs_skip( s, 2 ); /* Reserved */
810     i_clut = bs_read( s, 8 );
811
812     i_8_bg = bs_read( s, 8 );
813     i_4_bg = bs_read( s, 4 );
814     i_2_bg = bs_read( s, 2 );
815     bs_skip( s, 2 ); /* Reserved */
816
817     /* Free old object defs */
818     while( p_region->i_object_defs )
819     {
820         int i = p_region->i_object_defs - 1;
821         if( p_region->p_object_defs[i].psz_text )
822             free( p_region->p_object_defs[i].psz_text );
823         if( !i ) free( p_region->p_object_defs );
824
825         p_region->i_object_defs--;
826     }
827     p_region->p_object_defs = NULL;
828
829     /* Extra sanity checks */
830     if( p_region->i_width != i_width || p_region->i_height != i_height )
831     {
832         if( p_region->p_pixbuf )
833         {
834             msg_Dbg( p_dec, "region size changed (%dx%d->%dx%d)",
835                      p_region->i_width, p_region->i_height, i_width, i_height );
836             free( p_region->p_pixbuf );
837         }
838
839         p_region->p_pixbuf = malloc( i_height * i_width );
840         p_region->i_depth = 0;
841         b_fill = VLC_TRUE;
842     }
843     if( p_region->i_depth && (p_region->i_depth != i_depth ||
844         p_region->i_level_comp != i_level_comp || p_region->i_clut != i_clut) )
845     {
846         msg_Dbg( p_dec, "region parameters changed (not allowed)" );
847     }
848
849     /* Erase background of region */
850     if( b_fill )
851     {
852         int i_background = (p_region->i_depth == 1) ? i_2_bg :
853             (p_region->i_depth == 2) ? i_4_bg : i_8_bg;
854         memset( p_region->p_pixbuf, i_background, i_width * i_height );
855     }
856
857     p_region->i_width = i_width;
858     p_region->i_height = i_height;
859     p_region->i_level_comp = i_level_comp;
860     p_region->i_depth = i_depth;
861     p_region->i_clut = i_clut;
862
863     /* List of objects in the region */
864     i_processed_length = 10;
865     while( i_processed_length < i_segment_length )
866     {
867         dvbsub_objectdef_t *p_obj;
868
869         /* We create a new object */
870         p_region->i_object_defs++;
871         p_region->p_object_defs =
872             realloc( p_region->p_object_defs,
873                      sizeof(dvbsub_objectdef_t) * p_region->i_object_defs );
874
875         /* We parse object properties */
876         p_obj = &p_region->p_object_defs[p_region->i_object_defs - 1];
877         p_obj->i_id         = bs_read( s, 16 );
878         p_obj->i_type       = bs_read( s, 2 );
879         bs_skip( s, 2 ); /* Provider */
880         p_obj->i_x          = bs_read( s, 12 );
881         bs_skip( s, 4 ); /* Reserved */
882         p_obj->i_y          = bs_read( s, 12 );
883         p_obj->psz_text     = 0;
884
885         i_processed_length += 6;
886
887         if( p_obj->i_type == DVBSUB_OT_BASIC_CHAR ||
888             p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING )
889         {
890             p_obj->i_fg_pc =  bs_read( s, 8 );
891             p_obj->i_bg_pc =  bs_read( s, 8 );
892             i_processed_length += 2;
893         }
894     }
895 }
896
897 static void dvbsub_render_pdata( decoder_t *, dvbsub_region_t *, int, int,
898                                  uint8_t *, int );
899 static void dvbsub_pdata2bpp( bs_t *, uint8_t *, int, int * );
900 static void dvbsub_pdata4bpp( bs_t *, uint8_t *, int, int * );
901 static void dvbsub_pdata8bpp( bs_t *, uint8_t *, int, int * );
902
903 static void decode_object( decoder_t *p_dec, bs_t *s )
904 {
905     decoder_sys_t *p_sys = p_dec->p_sys;
906     dvbsub_region_t *p_region;
907     int i_segment_length, i_coding_method, i_version, i_id, i;
908     vlc_bool_t b_non_modify_color;
909
910     /* ETSI 300-743 paragraph 7.2.4
911      * sync_byte, segment_type and page_id have already been processed.
912      */
913     i_segment_length = bs_read( s, 16 );
914     i_id             = bs_read( s, 16 );
915     i_version        = bs_read( s, 4 );
916     i_coding_method  = bs_read( s, 2 );
917
918     if( i_coding_method > 1 )
919     {
920         msg_Dbg( p_dec, "unknown DVB subtitling coding %d is not handled!", i_coding_method );
921         bs_skip( s, 8 * (i_segment_length - 2) - 6 );
922         return;
923     }
924
925     /* Check if the object needs to be rendered in at least one
926      * of the regions */
927     for( p_region = p_sys->p_regions; p_region != NULL;
928          p_region = p_region->p_next )
929     {
930         for( i = 0; i < p_region->i_object_defs; i++ )
931             if( p_region->p_object_defs[i].i_id == i_id ) break;
932
933         if( i != p_region->i_object_defs ) break;
934     }
935     if( !p_region )
936     {
937         bs_skip( s, 8 * (i_segment_length - 2) - 6 );
938         return;
939     }
940
941 #ifdef DEBUG_DVBSUB
942     msg_Dbg( p_dec, "new object: %i", i_id );
943 #endif
944
945     b_non_modify_color = bs_read( s, 1 );
946     bs_skip( s, 1 ); /* Reserved */
947
948     if( i_coding_method == 0x00 )
949     {
950         int i_topfield, i_bottomfield;
951         uint8_t *p_topfield, *p_bottomfield;
952
953         i_topfield    = bs_read( s, 16 );
954         i_bottomfield = bs_read( s, 16 );
955         p_topfield    = s->p_start + bs_pos( s ) / 8;
956         p_bottomfield = p_topfield + i_topfield;
957
958         bs_skip( s, 8 * (i_segment_length - 7) );
959
960         /* Sanity check */
961         if( i_segment_length < i_topfield + i_bottomfield + 7 ||
962             p_topfield + i_topfield + i_bottomfield > s->p_end )
963         {
964             msg_Dbg( p_dec, "corrupted object data" );
965             return;
966         }
967
968         for( p_region = p_sys->p_regions; p_region != NULL;
969              p_region = p_region->p_next )
970         {
971             for( i = 0; i < p_region->i_object_defs; i++ )
972             {
973                 if( p_region->p_object_defs[i].i_id != i_id ) continue;
974
975                 dvbsub_render_pdata( p_dec, p_region,
976                                      p_region->p_object_defs[i].i_x,
977                                      p_region->p_object_defs[i].i_y,
978                                      p_topfield, i_topfield );
979
980                 if( i_bottomfield )
981                 {
982                     dvbsub_render_pdata( p_dec, p_region,
983                                          p_region->p_object_defs[i].i_x,
984                                          p_region->p_object_defs[i].i_y + 1,
985                                          p_bottomfield, i_bottomfield );
986                 }
987                 else
988                 {
989                     /* Duplicate the top field */
990                     dvbsub_render_pdata( p_dec, p_region,
991                                          p_region->p_object_defs[i].i_x,
992                                          p_region->p_object_defs[i].i_y + 1,
993                                          p_topfield, i_topfield );
994                 }
995             }
996         }
997     }
998     else
999     {
1000         /* DVB subtitling as characters */
1001         int i_number_of_codes = bs_read( s, 8 );
1002         uint8_t* p_start = s->p_start + bs_pos( s ) / 8;
1003
1004         /* Sanity check */
1005         if( i_segment_length <  i_number_of_codes*2 + 4 ||
1006             p_start + i_number_of_codes*2 > s->p_end )
1007         {
1008             msg_Dbg( p_dec, "corrupted object data" );
1009             return;
1010         }
1011
1012         for( p_region = p_sys->p_regions; p_region != NULL;
1013              p_region = p_region->p_next )
1014         {
1015             for( i = 0; i < p_region->i_object_defs; i++ )
1016             {
1017                 int j;
1018
1019                 if( p_region->p_object_defs[i].i_id != i_id ) continue;
1020
1021                 p_region->p_object_defs[i].psz_text =
1022                     realloc( p_region->p_object_defs[i].psz_text,
1023                              i_number_of_codes + 1 );
1024
1025                 for( j = 0; j < i_number_of_codes; j++ )
1026                 {
1027                     p_region->p_object_defs[i].psz_text[j] = bs_read( s, 16 );
1028                 }
1029                 p_region->p_object_defs[i].psz_text[j] = 0;
1030             }
1031         }
1032     }
1033
1034 #ifdef DEBUG_DVBSUB
1035     msg_Dbg( p_dec, "end object: %i", i_id );
1036 #endif
1037 }
1038
1039 static void dvbsub_render_pdata( decoder_t *p_dec, dvbsub_region_t *p_region,
1040                                  int i_x, int i_y,
1041                                  uint8_t *p_field, int i_field )
1042 {
1043     uint8_t *p_pixbuf;
1044     int i_offset = 0;
1045     bs_t bs;
1046
1047     /* Sanity check */
1048     if( !p_region->p_pixbuf )
1049     {
1050         msg_Err( p_dec, "region %i has no pixel buffer!", p_region->i_id );
1051         return;
1052     }
1053     if( i_y < 0 || i_x < 0 || i_y >= p_region->i_height ||
1054         i_x >= p_region->i_width )
1055     {
1056         msg_Dbg( p_dec, "invalid offset (%i,%i)", i_x, i_y );
1057         return;
1058     }
1059
1060     p_pixbuf = p_region->p_pixbuf + i_y * p_region->i_width;
1061     bs_init( &bs, p_field, i_field );
1062
1063     while( !bs_eof( &bs ) )
1064     {
1065         /* Sanity check */
1066         if( i_y >= p_region->i_height ) return;
1067
1068         switch( bs_read( &bs, 8 ) )
1069         {
1070         case 0x10:
1071             dvbsub_pdata2bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1072                               &i_offset );
1073             break;
1074
1075         case 0x11:
1076             dvbsub_pdata4bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1077                               &i_offset );
1078             break;
1079
1080         case 0x12:
1081             dvbsub_pdata8bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
1082                               &i_offset );
1083             break;
1084
1085         case 0x20:
1086         case 0x21:
1087         case 0x22:
1088             /* We don't use map tables */
1089             break;
1090
1091         case 0xf0: /* End of line code */
1092             p_pixbuf += 2*p_region->i_width;
1093             i_offset = 0; i_y += 2;
1094             break;
1095         }
1096     }
1097 }
1098
1099 static void dvbsub_pdata2bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1100 {
1101     vlc_bool_t b_stop = 0;
1102
1103     while( !b_stop && !bs_eof( s ) )
1104     {
1105         int i_count = 0, i_color = 0;
1106
1107         if( (i_color = bs_read( s, 2 )) != 0x00 )
1108         {
1109             i_count = 1;
1110         }
1111         else
1112         {
1113             if( bs_read( s, 1 ) == 0x01 )         // Switch1
1114             {
1115                 i_count = 3 + bs_read( s, 3 );
1116                 i_color = bs_read( s, 2 );
1117             }
1118             else
1119             {
1120                 if( bs_read( s, 1 ) == 0x00 )     //Switch2
1121                 {
1122                     switch( bs_read( s, 2 ) )     //Switch3
1123                     {
1124                     case 0x00:
1125                         b_stop = 1;
1126                         break;
1127                     case 0x01:
1128                         i_count = 2;
1129                         break;
1130                     case 0x02:
1131                         i_count =  12 + bs_read( s, 4 );
1132                         i_color = bs_read( s, 2 );
1133                         break;
1134                     case 0x03:
1135                         i_count =  29 + bs_read( s, 8 );
1136                         i_color = bs_read( s, 2 );
1137                         break;
1138                     default:
1139                         break;
1140                     }
1141                 }
1142                 else
1143                 {
1144                     /* 1 pixel color 0 */
1145                     i_count = 1;
1146                 }
1147             }
1148         }
1149
1150         if( !i_count ) continue;
1151
1152         /* Sanity check */
1153         if( i_count + *pi_off > i_width ) break;
1154
1155         if( i_count == 1 ) p[*pi_off] = i_color;
1156         else memset( p + *pi_off, i_color, i_count );
1157
1158         (*pi_off) += i_count;
1159     }
1160
1161     bs_align( s );
1162 }
1163
1164 static void dvbsub_pdata4bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1165 {
1166     vlc_bool_t b_stop = 0;
1167
1168     while( !b_stop && !bs_eof( s ) )
1169     {
1170         int i_count = 0, i_color = 0;
1171
1172         if( (i_color = bs_read( s, 4 )) != 0x00 )
1173         {
1174             /* Add 1 pixel */
1175             i_count = 1;
1176         }
1177         else
1178         {
1179             if( bs_read( s, 1 ) == 0x00 )           // Switch1
1180             {
1181                 if( bs_show( s, 3 ) != 0x00 )
1182                 {
1183                     i_count = 2 + bs_read( s, 3 );
1184                 }
1185                 else
1186                 {
1187                     bs_skip( s, 3 );
1188                     b_stop = 1;
1189                 }
1190             }
1191             else
1192             {
1193                 if( bs_read( s, 1 ) == 0x00)        //Switch2
1194                 {
1195                     i_count =  4 + bs_read( s, 2 );
1196                     i_color = bs_read( s, 4 );
1197                 }
1198                 else
1199                 {
1200                     switch ( bs_read( s, 2 ) )     //Switch3
1201                     {
1202                     case 0x0:
1203                         i_count = 1;
1204                         break;
1205                     case 0x1:
1206                         i_count = 2;
1207                         break;
1208                     case 0x2:
1209                         i_count = 9 + bs_read( s, 4 );
1210                         i_color = bs_read( s, 4 );
1211                         break;
1212                     case 0x3:
1213                         i_count= 25 + bs_read( s, 8 );
1214                         i_color = bs_read( s, 4 );
1215                         break;
1216                     }
1217                 }
1218             }
1219         }
1220
1221         if( !i_count ) continue;
1222
1223         /* Sanity check */
1224         if( i_count + *pi_off > i_width ) break;
1225
1226         if( i_count == 1 ) p[*pi_off] = i_color;
1227         else memset( p + *pi_off, i_color, i_count );
1228
1229         (*pi_off) += i_count;
1230     }
1231
1232     bs_align( s );
1233 }
1234
1235 static void dvbsub_pdata8bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1236 {
1237     vlc_bool_t b_stop = 0;
1238
1239     while( !b_stop && !bs_eof( s ) )
1240     {
1241         int i_count = 0, i_color = 0;
1242
1243         if( (i_color = bs_read( s, 8 )) != 0x00 )
1244         {
1245             /* Add 1 pixel */
1246             i_count = 1;
1247         }
1248         else
1249         {
1250             if( bs_read( s, 1 ) == 0x00 )           // Switch1
1251             {
1252                 if( bs_show( s, 7 ) != 0x00 )
1253                 {
1254                     i_count = bs_read( s, 7 );
1255                 }
1256                 else
1257                 {
1258                     bs_skip( s, 7 );
1259                     b_stop = 1;
1260                 }
1261             }
1262             else
1263             {
1264                 i_count = bs_read( s, 7 );
1265                 i_color = bs_read( s, 8 );
1266             }
1267         }
1268
1269         if( !i_count ) continue;
1270
1271         /* Sanity check */
1272         if( i_count + *pi_off > i_width ) break;
1273
1274         if( i_count == 1 ) p[*pi_off] = i_color;
1275         else memset( p + *pi_off, i_color, i_count );
1276
1277         (*pi_off) += i_count;
1278     }
1279
1280     bs_align( s );
1281 }
1282
1283 static void free_all( decoder_t *p_dec )
1284 {
1285     decoder_sys_t *p_sys = p_dec->p_sys;
1286     dvbsub_region_t *p_reg, *p_reg_next;
1287     dvbsub_clut_t *p_clut, *p_clut_next;
1288
1289     for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut_next )
1290     {
1291         p_clut_next = p_clut->p_next;
1292         free( p_clut );
1293     }
1294     p_sys->p_cluts = NULL;
1295
1296     for( p_reg = p_sys->p_regions; p_reg != NULL; p_reg = p_reg_next )
1297     {
1298         int i;
1299
1300         p_reg_next = p_reg->p_next;
1301         for( i = 0; i < p_reg->i_object_defs; i++ )
1302             if( p_reg->p_object_defs[i].psz_text )
1303                 free( p_reg->p_object_defs[i].psz_text );
1304         if( p_reg->i_object_defs ) free( p_reg->p_object_defs );
1305         if( p_reg->p_pixbuf ) free( p_reg->p_pixbuf );
1306         free( p_reg );
1307     }
1308     p_sys->p_regions = NULL;
1309
1310     if( p_sys->p_page )
1311     {
1312         if( p_sys->p_page->i_region_defs )
1313             free( p_sys->p_page->p_region_defs );
1314         free( p_sys->p_page );
1315     }
1316     p_sys->p_page = NULL;
1317 }
1318
1319 static subpicture_t *render( decoder_t *p_dec )
1320 {
1321     decoder_sys_t *p_sys = p_dec->p_sys;
1322     subpicture_t *p_spu;
1323     subpicture_region_t **pp_spu_region;
1324     int i, j, i_timeout = 0;
1325
1326     /* Allocate the subpicture internal data. */
1327     p_spu = p_dec->pf_spu_buffer_new( p_dec );
1328     if( !p_spu ) return NULL;
1329
1330     pp_spu_region = &p_spu->p_region;
1331
1332     /* Loop on region definitions */
1333 #ifdef DEBUG_DVBSUB
1334     if( p_sys->p_page )
1335         msg_Dbg( p_dec, "rendering %i regions", p_sys->p_page->i_region_defs );
1336 #endif
1337
1338     for( i = 0; p_sys->p_page && i < p_sys->p_page->i_region_defs; i++ )
1339     {
1340         dvbsub_region_t     *p_region;
1341         dvbsub_regiondef_t  *p_regiondef;
1342         dvbsub_clut_t       *p_clut;
1343         dvbsub_color_t      *p_color;
1344         subpicture_region_t *p_spu_region;
1345         uint8_t *p_src, *p_dst;
1346         video_format_t fmt;
1347         int i_pitch;
1348
1349         i_timeout = p_sys->p_page->i_timeout;
1350
1351         p_regiondef = &p_sys->p_page->p_region_defs[i];
1352
1353 #ifdef DEBUG_DVBSUB
1354         msg_Dbg( p_dec, "rendering region %i (%i,%i)", i,
1355                  p_regiondef->i_x, p_regiondef->i_y );
1356 #endif
1357
1358         /* Find associated region */
1359         for( p_region = p_sys->p_regions; p_region != NULL;
1360              p_region = p_region->p_next )
1361         {
1362             if( p_regiondef->i_id == p_region->i_id ) break;
1363         }
1364
1365         if( !p_region )
1366         {
1367             msg_Dbg( p_dec, "region %i not found", p_regiondef->i_id );
1368             continue;
1369         }
1370
1371         /* Find associated CLUT */
1372         for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )
1373         {
1374             if( p_region->i_clut == p_clut->i_id ) break;
1375         }
1376         if( !p_clut )
1377         {
1378             msg_Dbg( p_dec, "clut %i not found", p_region->i_clut );
1379             continue;
1380         }
1381
1382         /* Create new SPU region */
1383         memset( &fmt, 0, sizeof(video_format_t) );
1384         fmt.i_chroma = VLC_FOURCC('Y','U','V','P');
1385         fmt.i_aspect = 0; /* 0 means use aspect ratio of background video */
1386         fmt.i_width = fmt.i_visible_width = p_region->i_width;
1387         fmt.i_height = fmt.i_visible_height = p_region->i_height;
1388         fmt.i_x_offset = fmt.i_y_offset = 0;
1389         p_spu_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
1390         if( !p_spu_region )
1391         {
1392             msg_Err( p_dec, "cannot allocate SPU region" );
1393             continue;
1394         }
1395         p_spu_region->i_x = p_regiondef->i_x;
1396         p_spu_region->i_y = p_regiondef->i_y;
1397         *pp_spu_region = p_spu_region;
1398         pp_spu_region = &p_spu_region->p_next;
1399
1400         /* Build palette */
1401         fmt.p_palette->i_entries = p_region->i_depth == 1 ? 4 :
1402             p_region->i_depth == 2 ? 16 : 256;
1403         p_color = (p_region->i_depth == 1) ? p_clut->c_2b :
1404             (p_region->i_depth == 2) ? p_clut->c_4b : p_clut->c_8b;
1405         for( j = 0; j < fmt.p_palette->i_entries; j++ )
1406         {
1407             fmt.p_palette->palette[j][0] = p_color[j].Y;
1408             fmt.p_palette->palette[j][1] = p_color[j].Cr;
1409             fmt.p_palette->palette[j][2] = p_color[j].Cb;
1410             fmt.p_palette->palette[j][3] = 0xff - p_color[j].T;
1411         }
1412
1413         p_src = p_region->p_pixbuf;
1414         p_dst = p_spu_region->picture.Y_PIXELS;
1415         i_pitch = p_spu_region->picture.Y_PITCH;
1416
1417         /* Copy pixel buffer */
1418         for( j = 0; j < p_region->i_height; j++ )
1419         {
1420             memcpy( p_dst, p_src, p_region->i_width );
1421             p_src += p_region->i_width;
1422             p_dst += i_pitch;
1423         }
1424
1425         /* Check subtitles encoded as strings of characters
1426          * (since there are not rendered in the pixbuffer) */
1427         for( j = 0; j < p_region->i_object_defs; j++ )
1428         {
1429             dvbsub_objectdef_t *p_object_def = &p_region->p_object_defs[j];
1430
1431             if( p_object_def->i_type != 1 || !p_object_def->psz_text )
1432                 continue;
1433
1434             /* Create new SPU region */
1435             memset( &fmt, 0, sizeof(video_format_t) );
1436             fmt.i_chroma = VLC_FOURCC('T','E','X','T');
1437             fmt.i_aspect = VOUT_ASPECT_FACTOR;
1438             fmt.i_width = fmt.i_visible_width = p_region->i_width;
1439             fmt.i_height = fmt.i_visible_height = p_region->i_height;
1440             fmt.i_x_offset = fmt.i_y_offset = 0;
1441             p_spu_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
1442             if( !p_region )
1443             {
1444                 msg_Err( p_dec, "cannot allocate SPU region" );
1445                 continue;
1446             }
1447
1448             p_spu_region->psz_text = strdup( p_object_def->psz_text );
1449             p_spu_region->i_x = p_regiondef->i_x + p_object_def->i_x;
1450             p_spu_region->i_y = p_regiondef->i_y + p_object_def->i_y;
1451             *pp_spu_region = p_spu_region;
1452             pp_spu_region = &p_spu_region->p_next;
1453         }
1454     }
1455
1456     /* Set the pf_render callback */
1457     p_spu->i_start = p_sys->i_pts;
1458     p_spu->i_stop = p_spu->i_start + (mtime_t) (i_timeout * 1000000);
1459     p_spu->b_ephemer = VLC_TRUE;
1460     p_spu->b_fade = VLC_TRUE;
1461
1462     /* Correct positioning of SPU */
1463     p_spu->b_absolute = p_sys->b_absolute;
1464     p_spu->i_flags = p_sys->i_spu_position;
1465     p_spu->i_x = p_sys->i_spu_x;
1466     p_spu->i_y = p_sys->i_spu_y;
1467
1468     return p_spu;
1469 }
1470
1471 /*****************************************************************************
1472  * encoder_sys_t : encoder descriptor
1473  *****************************************************************************/
1474 typedef struct encoder_region_t
1475 {
1476     int i_width;
1477     int i_height;
1478
1479 } encoder_region_t;
1480
1481 struct encoder_sys_t
1482 {
1483     unsigned int i_page_ver;
1484     unsigned int i_region_ver;
1485     unsigned int i_clut_ver;
1486
1487     int i_regions;
1488     encoder_region_t *p_regions;
1489
1490     mtime_t i_pts;
1491
1492     /* subpicture positioning */
1493     int i_offset_x;
1494     int i_offset_y;
1495 };
1496
1497 static void encode_page_composition( encoder_t *, bs_t *, subpicture_t * );
1498 static void encode_clut( encoder_t *, bs_t *, subpicture_t * );
1499 static void encode_region_composition( encoder_t *, bs_t *, subpicture_t * );
1500 static void encode_object( encoder_t *, bs_t *, subpicture_t * );
1501
1502 /*****************************************************************************
1503  * OpenEncoder: probe the encoder and return score
1504  *****************************************************************************/
1505 static int OpenEncoder( vlc_object_t *p_this )
1506 {
1507     encoder_t *p_enc = (encoder_t *)p_this;
1508     encoder_sys_t *p_sys;
1509     vlc_value_t val;
1510
1511     if( p_enc->fmt_out.i_codec != VLC_FOURCC('d','v','b','s') &&
1512         !p_enc->b_force )
1513     {
1514         return VLC_EGENERIC;
1515     }
1516
1517     /* Allocate the memory needed to store the decoder's structure */
1518     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
1519     {
1520         msg_Err( p_enc, "out of memory" );
1521         return VLC_ENOMEM;
1522     }
1523     p_enc->p_sys = p_sys;
1524
1525     p_enc->pf_encode_sub = Encode;
1526     p_enc->fmt_out.i_codec = VLC_FOURCC('d','v','b','s');
1527     p_enc->fmt_out.subs.dvb.i_id  = 1 << 16 | 1;
1528
1529     sout_CfgParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
1530
1531     p_sys->i_page_ver = 0;
1532     p_sys->i_region_ver = 0;
1533     p_sys->i_clut_ver = 0;
1534     p_sys->i_regions = 0;
1535     p_sys->p_regions = 0;
1536
1537     var_Create( p_this, ENC_CFG_PREFIX "x", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
1538     var_Get( p_this, ENC_CFG_PREFIX "x", &val );
1539     p_sys->i_offset_x = val.i_int;
1540     var_Create( p_this, ENC_CFG_PREFIX "y", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
1541     var_Get( p_this, ENC_CFG_PREFIX "y", &val );
1542     p_sys->i_offset_y = val.i_int;
1543
1544     return VLC_SUCCESS;
1545 }
1546
1547 /* FIXME: this routine is a hack to convert VLC_FOURCC('Y','U','V','A') 
1548  *        into VLC_FOURCC('Y','U','V','P')
1549  */
1550 static subpicture_t *YuvaYuvp( encoder_t *p_enc, subpicture_t *p_subpic )
1551 {
1552     subpicture_region_t *p_region = NULL;
1553
1554     if( !p_subpic ) return NULL;
1555
1556     for( p_region = p_subpic->p_region; p_region; p_region = p_region->p_next )
1557     {
1558         video_format_t *p_fmt = &p_region->fmt;
1559         int i = 0, j = 0, n = 0, p = 0;
1560         int i_max_entries = 256;
1561
1562 #ifdef RANDOM_DITHERING
1563         int i_seed = 0xdeadbeef; /* random seed */
1564 #else
1565         int *pi_delta;
1566 #endif
1567         int i_pixels = p_region->picture.p[0].i_visible_lines
1568                         * p_region->picture.p[0].i_pitch;
1569         int i_iterator = p_region->picture.p[0].i_visible_lines * 3 / 4
1570                             * p_region->picture.p[0].i_pitch
1571                         + p_region->picture.p[0].i_pitch * 1 / 3;
1572         int i_tolerance = 0;
1573
1574 #if DEBUG_DVBSUB
1575         msg_Dbg( p_enc, "YuvaYuvp: i_pixels=%d, i_iterator=%d", i_pixels, i_iterator );
1576 #endif
1577         p_fmt->i_chroma = VLC_FOURCC('Y','U','V','P');
1578         p_fmt->p_palette = (video_palette_t *) malloc( sizeof( video_palette_t ) );
1579         if( !p_fmt->p_palette ) break;
1580         p_fmt->p_palette->i_entries = 0;
1581
1582         /* Find best iterator using Euclide’s algorithm */
1583         for( ; i_iterator > 1 ; i_iterator-- )
1584         {
1585             int a = i_pixels;
1586             int b = i_iterator;
1587             int c;
1588
1589             while( b )
1590             {
1591                 c = a % b;
1592                 a = b;
1593                 b = c;
1594             }
1595
1596             if( a == 1 )
1597             {
1598                 break;
1599             }
1600         }
1601
1602         /* Count colors, build best palette */
1603         for( i_tolerance = 0; i_tolerance < 128; i_tolerance++ )
1604         {
1605             vlc_bool_t b_success = VLC_TRUE;
1606             p_fmt->p_palette->i_entries = 0;
1607
1608             for( i = 0; i < i_pixels ; )
1609             {
1610                 uint8_t y, u, v, a;
1611                 y = p_region->picture.p[0].p_pixels[i];
1612                 u = p_region->picture.p[1].p_pixels[i];
1613                 v = p_region->picture.p[2].p_pixels[i];
1614                 a = p_region->picture.p[3].p_pixels[i];
1615                 for( j = 0; j < p_fmt->p_palette->i_entries; j++ )
1616                 {
1617                     if( abs((int)p_fmt->p_palette->palette[j][0] - (int)y) <= i_tolerance &&
1618                         abs((int)p_fmt->p_palette->palette[j][1] - (int)u) <= i_tolerance &&
1619                         abs((int)p_fmt->p_palette->palette[j][2] - (int)v) <= i_tolerance &&
1620                         abs((int)p_fmt->p_palette->palette[j][3] - (int)a) <= i_tolerance / 2 )
1621                     {
1622                         break;
1623                     }
1624                 }
1625                 if( j == p_fmt->p_palette->i_entries )
1626                 {
1627                     p_fmt->p_palette->palette[j][0] = y;
1628                     p_fmt->p_palette->palette[j][1] = u;
1629                     p_fmt->p_palette->palette[j][2] = v;
1630                     p_fmt->p_palette->palette[j][3] = a;
1631                     p_fmt->p_palette->i_entries++;
1632                 }
1633                 if( p_fmt->p_palette->i_entries >= i_max_entries )
1634                 {
1635                     b_success = VLC_FALSE;
1636                     break;
1637                 }
1638                 i += i_iterator;
1639                 if( i > i_pixels )
1640                 {
1641                     i -= i_pixels;
1642                 }
1643             }
1644
1645             if( b_success )
1646             {
1647                 break;
1648             }
1649         }
1650
1651 #if DEBUG_DVBSUB
1652         msg_Dbg( p_enc, "best palette has %d colors", p_fmt->p_palette->i_entries );
1653 #endif
1654
1655 #ifndef RANDOM_DITHERING
1656         pi_delta = malloc( ( p_region->picture.p[0].i_pitch + 1 )
1657                             * sizeof(int) * 4  );
1658         for( i = 0; i < (p_region->picture.p[0].i_pitch + 1) * 4 ; i++ )
1659         {
1660             pi_delta[ i ] = 0;
1661         }
1662 #endif
1663
1664         /* Fill image with our new colours */
1665         for( p = 0; p < p_region->picture.p[0].i_visible_lines ; p++ )
1666         {
1667             int i_ydelta = 0, i_udelta = 0, i_vdelta = 0, i_adelta = 0;
1668
1669             for( n = 0; n < p_region->picture.p[0].i_pitch ; n++ )
1670             {
1671                 int i_offset = p * p_region->picture.p[0].i_pitch + n;
1672                 int y, u, v, a;
1673                 int i_mindist, i_best;
1674
1675                 y = (int)p_region->picture.p[0].p_pixels[i_offset];
1676                 u = (int)p_region->picture.p[1].p_pixels[i_offset];
1677                 v = (int)p_region->picture.p[2].p_pixels[i_offset];
1678                 a = (int)p_region->picture.p[3].p_pixels[i_offset];
1679
1680                 /* Add dithering compensation */
1681 #ifdef RANDOM_DITHERING
1682                 y += ((i_seed & 0xff) - 0x80) * i_tolerance / 0x80;
1683                 u += (((i_seed >> 8) & 0xff) - 0x80) * i_tolerance / 0x80;
1684                 v += (((i_seed >> 16) & 0xff) - 0x80) * i_tolerance / 0x80;
1685                 a += (((i_seed >> 24) & 0xff) - 0x80) * i_tolerance / 0x80;
1686 #else
1687                 y += i_ydelta + pi_delta[ n * 4 ];
1688                 u += i_udelta + pi_delta[ n * 4 + 1 ];
1689                 v += i_vdelta + pi_delta[ n * 4 + 2 ];
1690                 a += i_adelta + pi_delta[ n * 4 + 3 ];
1691 #endif
1692
1693                 /* Find best colour in palette */
1694                 for( i_mindist = 99999999, i_best = 0, j = 0; j < p_fmt->p_palette->i_entries; j++ )
1695                 {
1696                     int i_dist = 0;
1697
1698                     i_dist += abs((int)p_fmt->p_palette->palette[j][0] - y);
1699                     i_dist += abs((int)p_fmt->p_palette->palette[j][1] - u);
1700                     i_dist += abs((int)p_fmt->p_palette->palette[j][2] - v);
1701                     i_dist += 2 * abs((int)p_fmt->p_palette->palette[j][3] - a);
1702
1703                     if( i_dist < i_mindist )
1704                     {
1705                         i_mindist = i_dist;
1706                         i_best = j;
1707                     }
1708                 }
1709
1710                 /* Set pixel to best color */
1711                 p_region->picture.p[0].p_pixels[i_offset] = i_best;
1712
1713                 /* Update dithering state */
1714 #ifdef RANDOM_DITHERING
1715                 i_seed = (i_seed * 0x1283837) ^ 0x789479 ^ (i_seed >> 13);
1716 #else
1717                 i_ydelta = y - (int)p_fmt->p_palette->palette[i_best][0];
1718                 i_udelta = u - (int)p_fmt->p_palette->palette[i_best][1];
1719                 i_vdelta = v - (int)p_fmt->p_palette->palette[i_best][2];
1720                 i_adelta = a - (int)p_fmt->p_palette->palette[i_best][3];
1721                 pi_delta[ n * 4 ] = i_ydelta * 3 / 8;
1722                 pi_delta[ n * 4 + 1 ] = i_udelta * 3 / 8;
1723                 pi_delta[ n * 4 + 2 ] = i_vdelta * 3 / 8;
1724                 pi_delta[ n * 4 + 3 ] = i_adelta * 3 / 8;
1725                 i_ydelta = i_ydelta * 5 / 8;
1726                 i_udelta = i_udelta * 5 / 8;
1727                 i_vdelta = i_vdelta * 5 / 8;
1728                 i_adelta = i_adelta * 5 / 8;
1729 #endif
1730             }
1731         }
1732 #ifndef RANDOM_DITHERING
1733         free( pi_delta );
1734 #endif
1735
1736         /* pad palette */
1737         for( i = p_fmt->p_palette->i_entries; i < i_max_entries; i++ )
1738         {
1739             p_fmt->p_palette->palette[i][0] = 0;
1740             p_fmt->p_palette->palette[i][1] = 0;
1741             p_fmt->p_palette->palette[i][2] = 0;
1742             p_fmt->p_palette->palette[i][3] = 0;
1743         }
1744         p_fmt->p_palette->i_entries = i_max_entries;
1745 #if DEBUG_DVBSUB
1746         msg_Dbg( p_enc, "best palette has %d colors", p_fmt->p_palette->i_entries );
1747 #endif
1748     }
1749     return p_subpic;
1750 } /* End of hack */
1751
1752 /****************************************************************************
1753  * Encode: the whole thing
1754  ****************************************************************************/
1755 static block_t *Encode( encoder_t *p_enc, subpicture_t *p_subpic )
1756 {
1757     subpicture_t *p_temp = NULL;
1758     subpicture_region_t *p_region = NULL;
1759     bs_t bits, *s = &bits;
1760     block_t *p_block;
1761
1762     if( !p_subpic || !p_subpic->p_region ) return NULL;
1763
1764     /* FIXME: this is a hack to convert VLC_FOURCC('Y','U','V','A') into
1765      *  VLC_FOURCC('Y','U','V','P')
1766      */
1767     p_region = p_subpic->p_region;
1768     if( p_region->fmt.i_chroma == VLC_FOURCC('Y','U','V','A') )
1769     {
1770         p_temp = YuvaYuvp( p_enc, p_subpic );
1771         if( !p_temp )
1772         {
1773             msg_Err( p_enc, "no picture in subpicture" );
1774             return NULL;
1775         }
1776         p_region = p_subpic->p_region;
1777     }
1778
1779     /* Sanity check */
1780     if( !p_region ) return NULL;
1781
1782     if( p_region->fmt.i_chroma != VLC_FOURCC('T','E','X','T') &&
1783         p_region->fmt.i_chroma != VLC_FOURCC('Y','U','V','P') ) return NULL;
1784
1785     if( p_region->fmt.p_palette )
1786     {
1787         switch( p_region->fmt.p_palette->i_entries )
1788         {
1789             case 0:
1790             case 4:
1791             case 16:
1792             case 256:
1793                 break;
1794             default:
1795                 msg_Err( p_enc, "subpicture palette (%d) not handled",
1796                             p_region->fmt.p_palette->i_entries );
1797                 return NULL;
1798         }
1799     }
1800     /* End of hack */
1801
1802 #if DEBUG_DVBSUB
1803     msg_Dbg( p_enc, "encoding subpicture" );
1804 #endif
1805     p_block = block_New( p_enc, 64000 );
1806     bs_init( s, p_block->p_buffer, p_block->i_buffer );
1807
1808     bs_write( s, 8, 0x20 ); /* Data identifier */
1809     bs_write( s, 8, 0x0 );  /* Subtitle stream id */
1810
1811     encode_page_composition( p_enc, s, p_subpic );
1812     encode_region_composition( p_enc, s, p_subpic );
1813     encode_clut( p_enc, s, p_subpic );
1814     encode_object( p_enc, s, p_subpic );
1815
1816     /* End of display */
1817     bs_write( s, 8, 0x0f ); /* Sync byte */
1818     bs_write( s, 8, DVBSUB_ST_ENDOFDISPLAY ); /* Segment type */
1819     bs_write( s, 16, 1 );  /* Page id */
1820     bs_write( s, 16, 0 );  /* Segment length */
1821
1822     bs_write( s, 8, 0xff );/* End marker */
1823     p_block->i_buffer = bs_pos( s ) / 8;
1824     p_block->i_pts = p_block->i_dts = p_subpic->i_start;
1825     if( !p_subpic->b_ephemer && p_subpic->i_stop > p_subpic->i_start )
1826     {
1827         block_t *p_block_stop;
1828
1829         p_block->i_length = p_subpic->i_stop - p_subpic->i_start;
1830
1831         /* Send another (empty) subtitle to signal the end of display */
1832         p_block_stop = block_New( p_enc, 64000 );
1833         bs_init( s, p_block_stop->p_buffer, p_block_stop->i_buffer );
1834         bs_write( s, 8, 0x20 ); /* Data identifier */
1835         bs_write( s, 8, 0x0 );  /* Subtitle stream id */
1836         encode_page_composition( p_enc, s, 0 );
1837         bs_write( s, 8, 0x0f ); /* Sync byte */
1838         bs_write( s, 8, DVBSUB_ST_ENDOFDISPLAY ); /* Segment type */
1839         bs_write( s, 16, 1 );  /* Page id */
1840         bs_write( s, 16, 0 );  /* Segment length */
1841         bs_write( s, 8, 0xff );/* End marker */
1842         p_block_stop->i_buffer = bs_pos( s ) / 8;
1843         p_block_stop->i_pts = p_block_stop->i_dts = p_subpic->i_stop;
1844         block_ChainAppend( &p_block, p_block_stop );
1845         p_block_stop->i_length = 100000; /* p_subpic->i_stop - p_subpic->i_start; */
1846     }
1847 #ifdef DEBUG_DVBSUB
1848     msg_Dbg( p_enc, "subpicture encoded properly" );
1849 #endif
1850     return p_block;
1851 }
1852
1853 /*****************************************************************************
1854  * CloseEncoder: encoder destruction
1855  *****************************************************************************/
1856 static void CloseEncoder( vlc_object_t *p_this )
1857 {
1858     encoder_t *p_enc = (encoder_t *)p_this;
1859     encoder_sys_t *p_sys = p_enc->p_sys;
1860
1861     var_Destroy( p_this , ENC_CFG_PREFIX "x" );
1862     var_Destroy( p_this , ENC_CFG_PREFIX "y" );
1863     var_Destroy( p_this , ENC_CFG_PREFIX "timeout" );
1864
1865     if( p_sys->i_regions ) free( p_sys->p_regions );
1866     free( p_sys );
1867 }
1868
1869 static void encode_page_composition( encoder_t *p_enc, bs_t *s,
1870                                      subpicture_t *p_subpic )
1871 {
1872     encoder_sys_t *p_sys = p_enc->p_sys;
1873     subpicture_region_t *p_region;
1874     vlc_bool_t b_mode_change = VLC_FALSE;
1875     int i_regions, i_timeout;
1876
1877     bs_write( s, 8, 0x0f ); /* Sync byte */
1878     bs_write( s, 8, DVBSUB_ST_PAGE_COMPOSITION ); /* Segment type */
1879     bs_write( s, 16, 1 ); /* Page id */
1880
1881     for( i_regions = 0, p_region = p_subpic ? p_subpic->p_region : 0;
1882          p_region; p_region = p_region->p_next, i_regions++ )
1883     {
1884         if( i_regions >= p_sys->i_regions )
1885         {
1886             encoder_region_t region;
1887             region.i_width = region.i_height = 0;
1888             p_sys->p_regions =
1889                 realloc( p_sys->p_regions, sizeof(encoder_region_t) *
1890                          (p_sys->i_regions + 1) );
1891             p_sys->p_regions[p_sys->i_regions++] = region;
1892         }
1893
1894         if( ( p_sys->p_regions[i_regions].i_width <
1895               (int)p_region->fmt.i_visible_width ) || 
1896             ( p_sys->p_regions[i_regions].i_width >
1897               (int)p_region->fmt.i_visible_width ) )
1898         {
1899             b_mode_change = VLC_TRUE;
1900             msg_Dbg( p_enc, "region %i width change: %i -> %i",
1901                      i_regions, p_sys->p_regions[i_regions].i_width,
1902                      p_region->fmt.i_visible_width );
1903             p_sys->p_regions[i_regions].i_width =
1904                 p_region->fmt.i_visible_width;
1905         }
1906         if( p_sys->p_regions[i_regions].i_height <
1907              (int)p_region->fmt.i_visible_height )
1908         {
1909             b_mode_change = VLC_TRUE;
1910             msg_Dbg( p_enc, "region %i height change: %i -> %i",
1911                      i_regions, p_sys->p_regions[i_regions].i_height,
1912                      p_region->fmt.i_visible_height );
1913             p_sys->p_regions[i_regions].i_height =
1914                 p_region->fmt.i_visible_height;
1915         }
1916     }
1917
1918     bs_write( s, 16, i_regions * 6 + 2 ); /* Segment length */
1919
1920     i_timeout = 0;
1921     if( p_subpic && !p_subpic->b_ephemer &&
1922         p_subpic->i_stop > p_subpic->i_start )
1923     {
1924         i_timeout = (p_subpic->i_stop - p_subpic->i_start) / 1000000;
1925     }
1926
1927     bs_write( s, 8, i_timeout ); /* Timeout */
1928     bs_write( s, 4, p_sys->i_page_ver++ );
1929     bs_write( s, 2, b_mode_change ?
1930               DVBSUB_PCS_STATE_CHANGE : DVBSUB_PCS_STATE_ACQUISITION );
1931     bs_write( s, 2, 0 ); /* Reserved */
1932
1933     for( i_regions = 0, p_region = p_subpic ? p_subpic->p_region : 0;
1934          p_region; p_region = p_region->p_next, i_regions++ )
1935     {
1936         bs_write( s, 8, i_regions );
1937         bs_write( s, 8, 0 ); /* Reserved */
1938         if( (p_sys->i_offset_x > 0) && (p_sys->i_offset_y > 0) )
1939         {
1940             bs_write( s, 16, p_sys->i_offset_x ); /* override x position */
1941             bs_write( s, 16, p_sys->i_offset_y ); /* override y position */
1942         }
1943         else
1944         {
1945             bs_write( s, 16, p_region->i_x );
1946             bs_write( s, 16, p_region->i_y );
1947         }
1948     }
1949 }
1950
1951 static void encode_clut( encoder_t *p_enc, bs_t *s, subpicture_t *p_subpic )
1952 {
1953     encoder_sys_t *p_sys = p_enc->p_sys;
1954     subpicture_region_t *p_region = p_subpic->p_region;
1955     video_palette_t *p_pal, pal;
1956     int i;
1957
1958     /* Sanity check */
1959     if( !p_region ) return;
1960
1961     if( p_region->fmt.i_chroma == VLC_FOURCC('Y','U','V','P') )
1962     {
1963         p_pal = p_region->fmt.p_palette;
1964     }
1965     else
1966     {
1967         pal.i_entries = 4;
1968         for( i = 0; i < 4; i++ )
1969         {
1970             pal.palette[i][0] = 0;
1971             pal.palette[i][1] = 0;
1972             pal.palette[i][2] = 0;
1973             pal.palette[i][3] = 0;
1974         }
1975         p_pal = &pal;
1976     }
1977
1978     bs_write( s, 8, 0x0f ); /* Sync byte */
1979     bs_write( s, 8, DVBSUB_ST_CLUT_DEFINITION ); /* Segment type */
1980     bs_write( s, 16, 1 );  /* Page id */
1981
1982     bs_write( s, 16, p_pal->i_entries * 6 + 2 ); /* Segment length */
1983     bs_write( s, 8, 1 ); /* Clut id */
1984     bs_write( s, 4, p_sys->i_clut_ver++ );
1985     bs_write( s, 4, 0 ); /* Reserved */
1986
1987     for( i = 0; i < p_pal->i_entries; i++ )
1988     {
1989         bs_write( s, 8, i ); /* Clut entry id */
1990         bs_write( s, 1, p_pal->i_entries == 4 );   /* 2bit/entry flag */
1991         bs_write( s, 1, p_pal->i_entries == 16 );  /* 4bit/entry flag */
1992         bs_write( s, 1, p_pal->i_entries == 256 ); /* 8bit/entry flag */
1993         bs_write( s, 4, 0 ); /* Reserved */
1994         bs_write( s, 1, 1 ); /* Full range flag */
1995         bs_write( s, 8, p_pal->palette[i][3] ?  /* Y value */
1996                   (p_pal->palette[i][0] ? p_pal->palette[i][0] : 16) : 0 );
1997         bs_write( s, 8, p_pal->palette[i][1] ); /* Cr value */
1998         bs_write( s, 8, p_pal->palette[i][2] ); /* Cb value */
1999         bs_write( s, 8, 0xff - p_pal->palette[i][3] ); /* T value */
2000     }
2001 }
2002
2003 static void encode_region_composition( encoder_t *p_enc, bs_t *s,
2004                                        subpicture_t *p_subpic )
2005 {
2006     encoder_sys_t *p_sys = p_enc->p_sys;
2007     subpicture_region_t *p_region;
2008     int i_region;
2009
2010     for( i_region = 0, p_region = p_subpic->p_region; p_region;
2011          p_region = p_region->p_next, i_region++ )
2012     {
2013         int i_entries = 4, i_depth = 0x1, i_bg = 0;
2014         vlc_bool_t b_text =
2015             p_region->fmt.i_chroma == VLC_FOURCC('T','E','X','T');
2016
2017         if( !b_text )
2018         {
2019             video_palette_t *p_pal = p_region->fmt.p_palette;
2020
2021             if( !p_pal )
2022             {
2023                 msg_Err( p_enc, "subpicture has no palette - ignoring it" );
2024                 break;
2025             }
2026
2027             i_entries = p_pal->i_entries;
2028             i_depth = i_entries == 4 ? 0x1 : i_entries == 16 ? 0x2 : 0x3;
2029
2030             for( i_bg = 0; i_bg < p_pal->i_entries; i_bg++ )
2031             {
2032                 if( !p_pal->palette[i_bg][3] ) break;
2033             }
2034         }
2035
2036         bs_write( s, 8, 0x0f ); /* Sync byte */
2037         bs_write( s, 8, DVBSUB_ST_REGION_COMPOSITION ); /* Segment type */
2038         bs_write( s, 16, 1 );   /* Page id */
2039
2040         bs_write( s, 16, 10 + 6 + (b_text ? 2 : 0) ); /* Segment length */
2041         bs_write( s, 8, i_region );
2042         bs_write( s, 4, p_sys->i_region_ver++ );
2043
2044         /* Region attributes */
2045         bs_write( s, 1, i_bg < i_entries ); /* Fill */
2046         bs_write( s, 3, 0 ); /* Reserved */
2047         bs_write( s, 16, p_sys->p_regions[i_region].i_width );
2048         bs_write( s, 16, p_sys->p_regions[i_region].i_height );
2049         bs_write( s, 3, i_depth );  /* Region level of compatibility */
2050         bs_write( s, 3, i_depth  ); /* Region depth */
2051         bs_write( s, 2, 0 ); /* Reserved */
2052         bs_write( s, 8, 1 ); /* Clut id */
2053         bs_write( s, 8, i_bg ); /* region 8bit pixel code */
2054         bs_write( s, 4, i_bg ); /* region 4bit pixel code */
2055         bs_write( s, 2, i_bg ); /* region 2bit pixel code */
2056         bs_write( s, 2, 0 ); /* Reserved */
2057
2058         /* In our implementation we only have 1 object per region */
2059         bs_write( s, 16, i_region );
2060         bs_write( s, 2, b_text ? DVBSUB_OT_BASIC_CHAR:DVBSUB_OT_BASIC_BITMAP );
2061         bs_write( s, 2, 0 ); /* object provider flag */
2062         bs_write( s, 12, 0 );/* object horizontal position */
2063         bs_write( s, 4, 0 ); /* Reserved */
2064         bs_write( s, 12, 0 );/* object vertical position */
2065
2066         if( b_text )
2067         {
2068             bs_write( s, 8, 1 ); /* foreground pixel code */
2069             bs_write( s, 8, 0 ); /* background pixel code */
2070         }
2071     }
2072 }
2073
2074 static void encode_pixel_data( encoder_t *p_enc, bs_t *s,
2075                                subpicture_region_t *p_region,
2076                                vlc_bool_t b_top );
2077
2078 static void encode_object( encoder_t *p_enc, bs_t *s, subpicture_t *p_subpic )
2079 {
2080     encoder_sys_t *p_sys = p_enc->p_sys;
2081     subpicture_region_t *p_region;
2082     int i_region;
2083
2084     int i_length_pos, i_update_pos, i_pixel_data_pos;
2085
2086     for( i_region = 0, p_region = p_subpic->p_region; p_region;
2087          p_region = p_region->p_next, i_region++ )
2088     {
2089         bs_write( s, 8, 0x0f ); /* Sync byte */
2090         bs_write( s, 8, DVBSUB_ST_OBJECT_DATA ); /* Segment type */
2091         bs_write( s, 16, 1 ); /* Page id */
2092
2093         i_length_pos = bs_pos( s );
2094         bs_write( s, 16, 0 ); /* Segment length */
2095         bs_write( s, 16, i_region ); /* Object id */
2096         bs_write( s, 4, p_sys->i_region_ver++ );
2097
2098         /* object coding method */
2099         switch( p_region->fmt.i_chroma )
2100         {
2101         case VLC_FOURCC( 'Y','U','V','P' ):
2102             bs_write( s, 2, 0 );
2103             break;
2104         case VLC_FOURCC( 'T','E','X','T' ):
2105             bs_write( s, 2, 1 );
2106             break;
2107         default:
2108             msg_Err( p_enc, "FOURCC %d not supported by encoder.", p_region->fmt.i_chroma );
2109             continue;
2110         }
2111
2112         bs_write( s, 1, 0 ); /* non modifying color flag */
2113         bs_write( s, 1, 0 ); /* Reserved */
2114
2115         if( p_region->fmt.i_chroma == VLC_FOURCC( 'T','E','X','T' ) )
2116         {
2117             int i_size, i;
2118
2119             if( !p_region->psz_text ) continue;
2120
2121             i_size = __MIN( strlen( p_region->psz_text ), 256 );
2122
2123             bs_write( s, 8, i_size ); /* number of characters in string */
2124             for( i = 0; i < i_size; i++ )
2125             {
2126                 bs_write( s, 16, p_region->psz_text[i] );
2127             }
2128
2129             /* Update segment length */
2130             SetWBE( &s->p_start[i_length_pos/8],
2131                     (bs_pos(s) - i_length_pos)/8 -2 );
2132             continue;
2133         }
2134
2135         /* Coding of a bitmap object */
2136         i_update_pos = bs_pos( s );
2137         bs_write( s, 16, 0 ); /* topfield data block length */
2138         bs_write( s, 16, 0 ); /* bottomfield data block length */
2139
2140         /* Top field */
2141         i_pixel_data_pos = bs_pos( s );
2142         encode_pixel_data( p_enc, s, p_region, VLC_TRUE );
2143         i_pixel_data_pos = ( bs_pos( s ) - i_pixel_data_pos ) / 8;
2144         SetWBE( &s->p_start[i_update_pos/8], i_pixel_data_pos );
2145
2146         /* Bottom field */
2147         i_pixel_data_pos = bs_pos( s );
2148         encode_pixel_data( p_enc, s, p_region, VLC_FALSE );
2149         i_pixel_data_pos = ( bs_pos( s ) - i_pixel_data_pos ) / 8;
2150         SetWBE( &s->p_start[i_update_pos/8+2], i_pixel_data_pos );
2151
2152         /* Stuffing for word alignment */
2153         bs_align_0( s );
2154         if( bs_pos( s ) % 16 ) bs_write( s, 8, 0 );
2155
2156         /* Update segment length */
2157         SetWBE( &s->p_start[i_length_pos/8], (bs_pos(s) - i_length_pos)/8 -2 );
2158     }
2159 }
2160
2161 static void encode_pixel_line_2bp( encoder_t *p_enc, bs_t *s,
2162                                    subpicture_region_t *p_region,
2163                                    int i_line );
2164 static void encode_pixel_line_4bp( encoder_t *p_enc, bs_t *s,
2165                                    subpicture_region_t *p_region,
2166                                    int i_line );
2167 static void encode_pixel_line_8bp( encoder_t *p_enc, bs_t *s,
2168                                    subpicture_region_t *p_region,
2169                                    int i_line );
2170 static void encode_pixel_data( encoder_t *p_enc, bs_t *s,
2171                                subpicture_region_t *p_region,
2172                                vlc_bool_t b_top )
2173 {
2174     unsigned int i_line;
2175
2176     /* Sanity check */
2177     if( p_region->fmt.i_chroma != VLC_FOURCC('Y','U','V','P') ) return;
2178
2179     /* Encode line by line */
2180     for( i_line = !b_top; i_line < p_region->fmt.i_visible_height;
2181          i_line += 2 )
2182     {
2183         switch( p_region->fmt.p_palette->i_entries )
2184         {
2185         case 0:
2186             break;
2187
2188         case 4:
2189             bs_write( s, 8, 0x10 ); /* 2 bit/pixel code string */
2190             encode_pixel_line_2bp( p_enc, s, p_region, i_line );
2191             break;
2192
2193         case 16:
2194             bs_write( s, 8, 0x11 ); /* 4 bit/pixel code string */
2195             encode_pixel_line_4bp( p_enc, s, p_region, i_line );
2196             break;
2197
2198         case 256:
2199             bs_write( s, 8, 0x12 ); /* 8 bit/pixel code string */
2200             encode_pixel_line_8bp( p_enc, s, p_region, i_line );
2201             break;
2202
2203         default:
2204             msg_Err( p_enc, "subpicture palette (%i) not handled",
2205                      p_region->fmt.p_palette->i_entries );
2206             break;
2207         }
2208
2209         bs_write( s, 8, 0xf0 ); /* End of object line code */
2210     }
2211 }
2212
2213 static void encode_pixel_line_2bp( encoder_t *p_enc, bs_t *s,
2214                                    subpicture_region_t *p_region,
2215                                    int i_line )
2216 {
2217     unsigned int i, i_length = 0;
2218     int i_pitch = p_region->picture.p->i_pitch;
2219     uint8_t *p_data = &p_region->picture.p->p_pixels[ i_pitch * i_line ];
2220     int i_last_pixel = p_data[0];
2221
2222     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2223     {
2224         if( i != p_region->fmt.i_visible_width &&
2225             p_data[i] == i_last_pixel && i_length != 284 )
2226         {
2227             i_length++;
2228             continue;
2229         }
2230
2231         if( i_length == 1 || i_length == 11 || i_length == 28 )
2232         {
2233             /* 2bit/pixel code */
2234             if( i_last_pixel ) bs_write( s, 2, i_last_pixel );
2235             else
2236             {
2237                 bs_write( s, 2, 0 );
2238                 bs_write( s, 1, 0 );
2239                 bs_write( s, 1, 1 ); /* pseudo color 0 */
2240             }
2241             i_length--;
2242         }
2243
2244         if( i_length == 2 )
2245         {
2246             if( i_last_pixel )
2247             {
2248                 bs_write( s, 2, i_last_pixel );
2249                 bs_write( s, 2, i_last_pixel );
2250             }
2251             else
2252             {
2253                 bs_write( s, 2, 0 );
2254                 bs_write( s, 1, 0 );
2255                 bs_write( s, 1, 0 );
2256                 bs_write( s, 2, 1 ); /* 2 * pseudo color 0 */
2257             }
2258         }
2259         else if( i_length > 2 )
2260         {
2261             bs_write( s, 2, 0 );
2262             if( i_length <= 10 )
2263             {
2264                 bs_write( s, 1, 1 );
2265                 bs_write( s, 3, i_length - 3 );
2266                 bs_write( s, 2, i_last_pixel );
2267             }
2268             else
2269             {
2270                 bs_write( s, 1, 0 );
2271                 bs_write( s, 1, 0 );
2272
2273                 if( i_length <= 27 )
2274                 {
2275                     bs_write( s, 2, 2 );
2276                     bs_write( s, 4, i_length - 12 );
2277                     bs_write( s, 2, i_last_pixel );
2278                 }
2279                 else
2280                 {
2281                     bs_write( s, 2, 3 );
2282                     bs_write( s, 8, i_length - 29 );
2283                     bs_write( s, 2, i_last_pixel );
2284                 }
2285             }
2286         }
2287
2288         if( i == p_region->fmt.i_visible_width ) break;
2289
2290         i_last_pixel = p_data[i];
2291         i_length = 1;
2292     }
2293
2294     /* Stop */
2295     bs_write( s, 2, 0 );
2296     bs_write( s, 1, 0 );
2297     bs_write( s, 1, 0 );
2298     bs_write( s, 2, 0 );
2299
2300     /* Stuffing */
2301     bs_align_0( s );
2302 }
2303
2304 static void encode_pixel_line_4bp( encoder_t *p_enc, bs_t *s,
2305                                    subpicture_region_t *p_region,
2306                                    int i_line )
2307 {
2308     unsigned int i, i_length = 0;
2309     int i_pitch = p_region->picture.p->i_pitch;
2310     uint8_t *p_data = &p_region->picture.p->p_pixels[ i_pitch * i_line ];
2311     int i_last_pixel = p_data[0];
2312
2313     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2314     {
2315         if( i != p_region->fmt.i_visible_width &&
2316             p_data[i] == i_last_pixel && i_length != 280 )
2317         {
2318             i_length++;
2319             continue;
2320         }
2321
2322         if( i_length == 1 || (i_length == 3 && i_last_pixel) || i_length == 8 )
2323         {
2324             /* 4bit/pixel code */
2325             if( i_last_pixel ) bs_write( s, 4, i_last_pixel );
2326             else
2327             {
2328                 bs_write( s, 4, 0 );
2329                 bs_write( s, 1, 1 );
2330                 bs_write( s, 1, 1 );
2331                 bs_write( s, 2, 0 ); /* pseudo color 0 */
2332             }
2333             i_length--;
2334         }
2335
2336         if( i_length == 2 )
2337         {
2338             if( i_last_pixel )
2339             {
2340                 bs_write( s, 4, i_last_pixel );
2341                 bs_write( s, 4, i_last_pixel );
2342             }
2343             else
2344             {
2345                 bs_write( s, 4, 0 );
2346                 bs_write( s, 1, 1 );
2347                 bs_write( s, 1, 1 );
2348                 bs_write( s, 2, 1 ); /* 2 * pseudo color 0 */
2349             }
2350         }
2351         else if( !i_last_pixel && i_length >= 3 && i_length <= 9 )
2352         {
2353             bs_write( s, 4, 0 );
2354             bs_write( s, 1, 0 );
2355             bs_write( s, 3, i_length - 2 ); /* (i_length - 2) * color 0 */
2356         }
2357         else if( i_length > 2 )
2358         {
2359             bs_write( s, 4, 0 );
2360             bs_write( s, 1, 1 );
2361
2362             if( i_length <= 7 )
2363             {
2364                 bs_write( s, 1, 0 );
2365                 bs_write( s, 2, i_length - 4 );
2366                 bs_write( s, 4, i_last_pixel );
2367             }
2368             else
2369             {
2370                 bs_write( s, 1, 1 );
2371
2372                 if( i_length <= 24 )
2373                 {
2374                     bs_write( s, 2, 2 );
2375                     bs_write( s, 4, i_length - 9 );
2376                     bs_write( s, 4, i_last_pixel );
2377                 }
2378                 else
2379                 {
2380                     bs_write( s, 2, 3 );
2381                     bs_write( s, 8, i_length - 25 );
2382                     bs_write( s, 4, i_last_pixel );
2383                 }
2384             }
2385         }
2386
2387         if( i == p_region->fmt.i_visible_width ) break;
2388
2389         i_last_pixel = p_data[i];
2390         i_length = 1;
2391     }
2392
2393     /* Stop */
2394     bs_write( s, 8, 0 );
2395
2396     /* Stuffing */
2397     bs_align_0( s );
2398 }
2399
2400 static void encode_pixel_line_8bp( encoder_t *p_enc, bs_t *s,
2401                                    subpicture_region_t *p_region,
2402                                    int i_line )
2403 {
2404     unsigned int i, i_length = 0;
2405     int i_pitch = p_region->picture.p->i_pitch;
2406     uint8_t *p_data = &p_region->picture.p->p_pixels[ i_pitch * i_line ];
2407     int i_last_pixel = p_data[0];
2408
2409     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
2410     {
2411         if( i != p_region->fmt.i_visible_width &&
2412             p_data[i] == i_last_pixel && i_length != 127 )
2413         {
2414             i_length++;
2415             continue;
2416         }
2417
2418         if( i_length == 1 && i_last_pixel )
2419         {
2420             /* 8bit/pixel code */
2421             bs_write( s, 8, i_last_pixel );
2422         }
2423         else if( i_length == 2 && i_last_pixel )
2424         {
2425             /* 8bit/pixel code */
2426             bs_write( s, 8, i_last_pixel );
2427             bs_write( s, 8, i_last_pixel );
2428         }
2429         else if( i_length <= 127 )
2430         {
2431             bs_write( s, 8, 0 );
2432
2433             if( !i_last_pixel )
2434             {
2435                 bs_write( s, 1, 0 );
2436                 bs_write( s, 7, i_length ); /* pseudo color 0 */
2437             }
2438             else
2439             {
2440                 bs_write( s, 1, 1 );
2441                 bs_write( s, 7, i_length );
2442                 bs_write( s, 8, i_last_pixel );
2443             }
2444         }
2445
2446         if( i == p_region->fmt.i_visible_width ) break;
2447
2448         i_last_pixel = p_data[i];
2449         i_length = 1;
2450     }
2451
2452     /* Stop */
2453     bs_write( s, 8, 0 );
2454     bs_write( s, 8, 0 );
2455
2456     /* Stuffing */
2457     bs_align_0( s );
2458 }