]> git.sesse.net Git - vlc/blob - modules/codec/dvbsub.c
Improvements to preferences
[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-2004 VideoLAN
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  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
26  *****************************************************************************/
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include <vlc/vlc.h>
31 #include <vlc/vout.h>
32 #include <vlc/decoder.h>
33 #include <vlc/sout.h>
34
35 #include "vlc_bits.h"
36
37 //#define DEBUG_DVBSUB 1
38
39 /*****************************************************************************
40  * Module descriptor.
41  *****************************************************************************/
42 static int  Open ( vlc_object_t * );
43 static void Close( vlc_object_t * );
44 static subpicture_t *Decode( decoder_t *, block_t ** );
45
46 static int OpenEncoder  ( vlc_object_t * );
47 static void CloseEncoder( vlc_object_t * );
48 static block_t *Encode  ( encoder_t *, subpicture_t * );
49
50 vlc_module_begin();
51     set_description( _("DVB subtitles decoder") );
52     set_capability( "decoder", 50 );
53     set_category( CAT_INPUT );
54     set_subcategory( SUBCAT_INPUT_SCODEC );
55     set_callbacks( Open, Close );
56
57 #   define ENC_CFG_PREFIX "sout-dvbsub-"
58     add_submodule();
59     set_description( _("DVB subtitles encoder") );
60     set_capability( "encoder", 100 );
61     set_callbacks( OpenEncoder, CloseEncoder );
62 vlc_module_end();
63
64 static const char *ppsz_enc_options[] = { NULL };
65
66 /****************************************************************************
67  * Local structures
68  ****************************************************************************
69  * Those structures refer closely to the ETSI 300 743 Object model
70  ****************************************************************************/
71
72 /* The object definition gives the position of the object in a region */
73 typedef struct dvbsub_objectdef_s
74 {
75     int i_id;
76     int i_type;
77     int i_x;
78     int i_y;
79     int i_fg_pc;
80     int i_bg_pc;
81
82 } dvbsub_objectdef_t;
83
84 /* The entry in the palette CLUT */
85 typedef struct
86 {
87     uint8_t                 Y;
88     uint8_t                 Cr;
89     uint8_t                 Cb;
90     uint8_t                 T;
91
92 } dvbsub_color_t;
93
94 /* */
95 typedef struct dvbsub_clut_s
96 {
97     uint8_t                 i_id;
98     uint8_t                 i_version;
99     dvbsub_color_t          c_2b[4];
100     dvbsub_color_t          c_4b[16];
101     dvbsub_color_t          c_8b[256];
102
103     struct dvbsub_clut_s    *p_next;
104
105 } dvbsub_clut_t;
106
107 /* The Region is an aera on the image
108  * with a list of the object definitions associated and a CLUT */
109 typedef struct dvbsub_region_s
110 {
111     int i_id;
112     int i_version;
113     int i_x;
114     int i_y;
115     int i_width;
116     int i_height;
117     int i_level_comp;
118     int i_depth;
119     int i_clut;
120
121     uint8_t *p_pixbuf;
122
123     int                    i_object_defs;
124     dvbsub_objectdef_t     *p_object_defs;
125
126     struct dvbsub_region_s *p_next;
127
128 } dvbsub_region_t;
129
130 /* The object definition gives the position of the object in a region */
131 typedef struct dvbsub_regiondef_s
132 {
133     int i_id;
134     int i_x;
135     int i_y;
136
137 } dvbsub_regiondef_t;
138
139 /* The page defines the list of regions */
140 typedef struct
141 {
142     int i_id;
143     int i_timeout;
144     int i_state;
145     int i_version;
146
147     int                i_region_defs;
148     dvbsub_regiondef_t *p_region_defs;
149
150 } dvbsub_page_t;
151
152 struct decoder_sys_t
153 {
154     bs_t            bs;
155
156     /* Decoder internal data */
157     int             i_id;
158     int             i_ancillary_id;
159     mtime_t         i_pts;
160
161     dvbsub_page_t   *p_page;
162     dvbsub_region_t *p_regions;
163     dvbsub_clut_t   *p_cluts;
164     dvbsub_clut_t   default_clut;
165 };
166
167
168 // List of different SEGMENT TYPES
169 // According to EN 300-743, table 2
170 #define DVBSUB_ST_PAGE_COMPOSITION      0x10
171 #define DVBSUB_ST_REGION_COMPOSITION    0x11
172 #define DVBSUB_ST_CLUT_DEFINITION       0x12
173 #define DVBSUB_ST_OBJECT_DATA           0x13
174 #define DVBSUB_ST_ENDOFDISPLAY          0x80
175 #define DVBSUB_ST_STUFFING              0xff
176 // List of different OBJECT TYPES
177 // According to EN 300-743, table 6
178 #define DVBSUB_OT_BASIC_BITMAP          0x00
179 #define DVBSUB_OT_BASIC_CHAR            0x01
180 #define DVBSUB_OT_COMPOSITE_STRING      0x02
181 // Pixel DATA TYPES
182 // According to EN 300-743, table 9
183 #define DVBSUB_DT_2BP_CODE_STRING       0x10
184 #define DVBSUB_DT_4BP_CODE_STRING       0x11
185 #define DVBSUB_DT_8BP_CODE_STRING       0x12
186 #define DVBSUB_DT_24_TABLE_DATA         0x20
187 #define DVBSUB_DT_28_TABLE_DATA         0x21
188 #define DVBSUB_DT_48_TABLE_DATA         0x22
189 #define DVBSUB_DT_END_LINE              0xf0
190 // List of different Page Composition Segment state
191 // According to EN 300-743, 7.2.1 table 3
192 #define DVBSUB_PCS_STATE_ACQUISITION    0x01
193 #define DVBSUB_PCS_STATE_CHANGE         0x10
194
195 /*****************************************************************************
196  * Local prototypes
197  *****************************************************************************/
198 static void decode_segment( decoder_t *, bs_t * );
199 static void decode_page_composition( decoder_t *, bs_t * );
200 static void decode_region_composition( decoder_t *, bs_t * );
201 static void decode_object( decoder_t *, bs_t * );
202 static void decode_clut( decoder_t *, bs_t * );
203 static void free_all( decoder_t * );
204
205 static void default_clut_init( decoder_t * );
206
207 static subpicture_t *render( decoder_t * );
208
209 /*****************************************************************************
210  * Open: probe the decoder and return score
211  *****************************************************************************
212  * Tries to launch a decoder and return score so that the interface is able
213  * to chose.
214  *****************************************************************************/
215 static int Open( vlc_object_t *p_this )
216 {
217     decoder_t     *p_dec = (decoder_t *) p_this;
218     decoder_sys_t *p_sys;
219
220     if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
221     {
222         return VLC_EGENERIC;
223     }
224
225     p_dec->pf_decode_sub = Decode;
226     p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) );
227     memset( p_sys, 0, sizeof(decoder_sys_t) );
228
229     p_sys->i_pts          = 0;
230     p_sys->i_id           = p_dec->fmt_in.subs.dvb.i_id & 0xFFFF;
231     p_sys->i_ancillary_id = p_dec->fmt_in.subs.dvb.i_id >> 16;
232     p_sys->p_regions      = NULL;
233     p_sys->p_cluts        = NULL;
234     p_sys->p_page         = NULL;
235
236     es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'd','v','b','s' ) );
237
238     default_clut_init( p_dec );
239
240     return VLC_SUCCESS;
241 }
242
243 /*****************************************************************************
244  * Close:
245  *****************************************************************************/
246 static void Close( vlc_object_t *p_this )
247 {
248     decoder_t     *p_dec = (decoder_t*) p_this;
249     decoder_sys_t *p_sys = p_dec->p_sys;
250
251     free_all( p_dec );
252     free( p_sys );
253 }
254
255 /*****************************************************************************
256  * Decode:
257  *****************************************************************************/
258 static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
259 {
260     decoder_sys_t *p_sys = p_dec->p_sys;
261     block_t       *p_block;
262     subpicture_t  *p_spu = NULL;
263
264     if( pp_block == NULL || *pp_block == NULL ) return NULL;
265     p_block = *pp_block;
266     *pp_block = NULL;
267
268     p_sys->i_pts = p_block->i_pts;
269     if( p_sys->i_pts <= 0 )
270     {
271 #ifdef DEBUG_DVBSUB
272         /* Some DVB channels send stuffing segments in non-dated packets so
273          * don't complain too loudly. */
274         msg_Warn( p_dec, "non dated subtitle" );
275 #endif
276         block_Release( p_block );
277         return NULL;
278     }
279
280     bs_init( &p_sys->bs, p_block->p_buffer, p_block->i_buffer );
281
282     if( bs_read( &p_sys->bs, 8 ) != 0x20 ) /* Data identifier */
283     {
284         msg_Dbg( p_dec, "invalid data identifier" );
285         block_Release( p_block );
286         return NULL;
287     }
288
289     if( bs_read( &p_sys->bs, 8 ) ) /* Subtitle stream id */
290     {
291         msg_Dbg( p_dec, "invalid subtitle stream id" );
292         block_Release( p_block );
293         return NULL;
294     }
295
296 #ifdef DEBUG_DVBSUB
297     msg_Dbg( p_dec, "subtitle packet received: "I64Fd, p_sys->i_pts );
298 #endif
299
300     while( bs_show( &p_sys->bs, 8 ) == 0x0f ) /* Sync byte */
301     {
302         decode_segment( p_dec, &p_sys->bs );
303     }
304
305     if( bs_read( &p_sys->bs, 8 ) != 0xff ) /* End marker */
306     {
307         msg_Warn( p_dec, "end marker not found (corrupted subtitle ?)" );
308         block_Release( p_block );
309         return NULL;
310     }
311
312     /* Check if the page is to be displayed */
313     if( p_sys->p_page ) p_spu = render( p_dec );
314
315     block_Release( p_block );
316
317     return p_spu;
318 }
319
320 /* following functions are local */
321
322 /*****************************************************************************
323  * default_clut_init: default clut as defined in EN 300-743 section 10
324  *****************************************************************************/
325 static void default_clut_init( decoder_t *p_dec )
326 {
327     decoder_sys_t *p_sys = p_dec->p_sys;
328     uint8_t i;
329
330 #define RGB_TO_Y(r, g, b) ((int16_t) 77 * r + 150 * g + 29 * b) / 256;
331 #define RGB_TO_U(r, g, b) ((int16_t) -44 * r - 87 * g + 131 * b) / 256;
332 #define RGB_TO_V(r, g, b) ((int16_t) 131 * r - 110 * g - 21 * b) / 256;
333
334     /* 4 entries CLUT */
335     for( i = 0; i < 4; i++ )
336     {
337         uint8_t R = 0, G = 0, B = 0, T = 0;
338
339         if( !(i & 0x2) && !(i & 0x1) ) T = 0xFF;
340         else if( !(i & 0x2) && (i & 0x1) ) R = G = B = 0xFF;
341         else if( (i & 0x2) && !(i & 0x1) ) R = G = B = 0;
342         else R = G = B = 0x7F;
343
344         p_sys->default_clut.c_2b[i].Y = RGB_TO_Y(R,G,B);
345         p_sys->default_clut.c_2b[i].Cr = RGB_TO_U(R,G,B);
346         p_sys->default_clut.c_2b[i].Cb = RGB_TO_V(R,G,B);
347         p_sys->default_clut.c_2b[i].T = T;
348     }
349
350     /* 16 entries CLUT */
351     for( i = 0; i < 16; i++ )
352     {
353         uint8_t R = 0, G = 0, B = 0, T = 0;
354
355         if( !(i & 0x8) )
356         {
357             if( !(i & 0x4) && !(i & 0x2) && !(i & 0x1) )
358             {
359                 T = 0xFF;
360             }
361             else
362             {
363                 R = (i & 0x1) ? 0xFF : 0;
364                 G = (i & 0x2) ? 0xFF : 0;
365                 B = (i & 0x4) ? 0xFF : 0;
366             }
367         }
368         else
369         {
370             R = (i & 0x1) ? 0x7F : 0;
371             G = (i & 0x2) ? 0x7F : 0;
372             B = (i & 0x4) ? 0x7F : 0;
373         }
374
375         p_sys->default_clut.c_4b[i].Y = RGB_TO_Y(R,G,B);
376         p_sys->default_clut.c_4b[i].Cr = RGB_TO_U(R,G,B);
377         p_sys->default_clut.c_4b[i].Cb = RGB_TO_V(R,G,B);
378         p_sys->default_clut.c_4b[i].T = T;
379     }
380
381     /* 256 entries CLUT (TODO) */
382     memset( p_sys->default_clut.c_8b, 0xFF, 256 * sizeof(dvbsub_color_t) );
383 }
384
385 static void decode_segment( decoder_t *p_dec, bs_t *s )
386 {
387     decoder_sys_t *p_sys = p_dec->p_sys;
388     int i_type;
389     int i_page_id;
390     int i_size;
391
392     /* sync_byte (already checked) */
393     bs_skip( s, 8 );
394
395     /* segment type */
396     i_type = bs_read( s, 8 );
397
398     /* page id */
399     i_page_id = bs_read( s, 16 );
400
401     /* segment size */
402     i_size = bs_show( s, 16 );
403
404     if( i_page_id != p_sys->i_id && i_page_id != p_sys->i_ancillary_id )
405     {
406 #ifdef DEBUG_DVBSUB
407         msg_Dbg( p_dec, "subtitle skipped (page id: %i, %i)",
408                  i_page_id, p_sys->i_id );
409 #endif
410         bs_skip( s,  8 * ( 2 + i_size ) );
411         return;
412     }
413
414 #ifdef DEBUG_DVBSUB
415     if( i_page_id == p_sys->i_id )
416         msg_Dbg( p_dec, "segment (id: %i)", i_page_id );
417     else
418         msg_Dbg( p_dec, "ancillary segment (id: %i)", i_page_id );
419 #endif
420
421     switch( i_type )
422     {
423     case DVBSUB_ST_PAGE_COMPOSITION:
424 #ifdef DEBUG_DVBSUB
425         msg_Dbg( p_dec, "decode_page_composition" );
426 #endif
427         decode_page_composition( p_dec, s );
428         break;
429
430     case DVBSUB_ST_REGION_COMPOSITION:
431 #ifdef DEBUG_DVBSUB
432         msg_Dbg( p_dec, "decode_region_composition" );
433 #endif
434         decode_region_composition( p_dec, s );
435         break;
436
437     case DVBSUB_ST_CLUT_DEFINITION:
438 #ifdef DEBUG_DVBSUB
439         msg_Dbg( p_dec, "decode_clut" );
440 #endif
441         decode_clut( p_dec, s );
442         break;
443
444     case DVBSUB_ST_OBJECT_DATA:
445 #ifdef DEBUG_DVBSUB
446         msg_Dbg( p_dec, "decode_object" );
447 #endif
448         decode_object( p_dec, s );
449         break;
450
451     case DVBSUB_ST_ENDOFDISPLAY:
452 #ifdef DEBUG_DVBSUB
453         msg_Dbg( p_dec, "end of display" );
454 #endif
455         bs_skip( s,  8 * ( 2 + i_size ) );
456         break;
457
458     case DVBSUB_ST_STUFFING:
459 #ifdef DEBUG_DVBSUB
460         msg_Dbg( p_dec, "skip stuffing" );
461 #endif
462         bs_skip( s,  8 * ( 2 + i_size ) );
463         break;
464
465     default:
466         msg_Warn( p_dec, "unsupported segment type: (%04x)", i_type );
467         bs_skip( s,  8 * ( 2 + i_size ) );
468         break;
469     }
470 }
471
472 static void decode_clut( decoder_t *p_dec, bs_t *s )
473 {
474     decoder_sys_t *p_sys = p_dec->p_sys;
475     uint16_t      i_segment_length;
476     uint16_t      i_processed_length;
477     dvbsub_clut_t *p_clut, *p_next;
478     int           i_id, i_version;
479
480     i_segment_length = bs_read( s, 16 );
481     i_id             = bs_read( s, 8 );
482     i_version        = bs_read( s, 4 );
483
484     /* Check if we already have this clut */
485     for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )
486     {
487         if( p_clut->i_id == i_id ) break;
488     }
489
490     /* Check version number */
491     if( p_clut && p_clut->i_version == i_version )
492     {
493         /* Nothing to do */
494         bs_skip( s, 8 * i_segment_length - 12 );
495         return;
496     }
497
498     if( !p_clut )
499     {
500 #ifdef DEBUG_DVBSUB
501         msg_Dbg( p_dec, "new clut: %i", i_id );
502 #endif
503         p_clut = malloc( sizeof(dvbsub_clut_t) );
504         p_clut->p_next = p_sys->p_cluts;
505         p_sys->p_cluts = p_clut;
506     }
507
508     /* Initialize to default clut */
509     p_next = p_clut->p_next;
510     *p_clut = p_sys->default_clut;
511     p_clut->p_next = p_next;
512
513     /* We don't have this version of the CLUT: Parse it */
514     p_clut->i_version = i_version;
515     p_clut->i_id = i_id;
516     bs_skip( s, 4 ); /* Reserved bits */
517     i_processed_length = 2;
518     while( i_processed_length < i_segment_length )
519     {
520         uint8_t y, cb, cr, t;
521         uint8_t i_id;
522         uint8_t i_type;
523
524         i_id = bs_read( s, 8 );
525         i_type = bs_read( s, 3 );
526
527         bs_skip( s, 4 );
528
529         if( bs_read( s, 1 ) )
530         {
531             y  = bs_read( s, 8 );
532             cr = bs_read( s, 8 );
533             cb = bs_read( s, 8 );
534             t  = bs_read( s, 8 );
535             i_processed_length += 6;
536         }
537         else
538         {
539             y  = bs_read( s, 6 ) << 2;
540             cr = bs_read( s, 4 ) << 4;
541             cb = bs_read( s, 4 ) << 4;
542             t  = bs_read( s, 2 ) << 6;
543             i_processed_length += 4;
544         }
545
546         /* We are not entirely compliant here as full transparency is indicated
547          * with a luma value of zero, not a transparency value of 0xff
548          * (full transparency would actually be 0xff + 1). */
549
550         if( y == 0 )
551         {
552             cr = cb = 0;
553             t  = 0xff;
554         }
555
556         /* According to EN 300-743 section 7.2.3 note 1, type should
557          * not have more than 1 bit set to one, but some streams don't
558          * respect this note. */
559
560         if( i_type & 0x04 && i_id < 4 )
561         {
562             p_clut->c_2b[i_id].Y = y;
563             p_clut->c_2b[i_id].Cr = cr;
564             p_clut->c_2b[i_id].Cb = cb;
565             p_clut->c_2b[i_id].T = t;
566         }
567         if( i_type & 0x02 && i_id < 16 )
568         {
569             p_clut->c_4b[i_id].Y = y;
570             p_clut->c_4b[i_id].Cr = cr;
571             p_clut->c_4b[i_id].Cb = cb;
572             p_clut->c_4b[i_id].T = t;
573         }
574         if( i_type & 0x01 )
575         {
576             p_clut->c_8b[i_id].Y = y;
577             p_clut->c_8b[i_id].Cr = cr;
578             p_clut->c_8b[i_id].Cb = cb;
579             p_clut->c_8b[i_id].T = t;
580         }
581     }
582 }
583
584 static void decode_page_composition( decoder_t *p_dec, bs_t *s )
585 {
586     decoder_sys_t *p_sys = p_dec->p_sys;
587     int i_version, i_state, i_segment_length, i_timeout, i;
588
589     /* A page is composed by 0 or more region */
590
591     i_segment_length = bs_read( s, 16 );
592     i_timeout = bs_read( s, 8 );
593     i_version = bs_read( s, 4 );
594     i_state = bs_read( s, 2 );
595     bs_skip( s, 2 ); /* Reserved */
596
597     if( i_state == DVBSUB_PCS_STATE_CHANGE )
598     {
599         /* End of an epoch, reset decoder buffer */
600 #ifdef DEBUG_DVBSUB
601         msg_Dbg( p_dec, "page composition mode change" );
602 #endif
603         free_all( p_dec );
604     }
605     else if( !p_sys->p_page && i_state != DVBSUB_PCS_STATE_ACQUISITION &&
606              i_state != DVBSUB_PCS_STATE_CHANGE )
607     {
608         /* Not a full PCS, we need to wait for one */
609         msg_Dbg( p_dec, "didn't receive an acquisition page yet" );
610
611 #if 0 /* Try to start decoding even without an acquisition page */
612         bs_skip( s,  8 * (i_segment_length - 2) );
613         return;
614 #endif
615     }
616
617 #ifdef DEBUG_DVBSUB
618     if( i_state == DVBSUB_PCS_STATE_ACQUISITION )
619         msg_Dbg( p_dec, "acquisition page composition" );
620 #endif
621
622     /* Check version number */
623     if( p_sys->p_page && p_sys->p_page->i_version == i_version )
624     {
625         bs_skip( s,  8 * (i_segment_length - 2) );
626         return;
627     }
628     else if( p_sys->p_page )
629     {
630         if( p_sys->p_page->i_region_defs )
631             free( p_sys->p_page->p_region_defs );
632         p_sys->p_page->i_region_defs = 0;
633     }
634
635     if( !p_sys->p_page )
636     {
637 #ifdef DEBUG_DVBSUB
638         msg_Dbg( p_dec, "new page" );
639 #endif
640         /* Allocate a new page */
641         p_sys->p_page = malloc( sizeof(dvbsub_page_t) );
642     }
643
644     p_sys->p_page->i_version = i_version;
645     p_sys->p_page->i_timeout = i_timeout;
646
647     /* Number of regions */
648     p_sys->p_page->i_region_defs = (i_segment_length - 2) / 6;
649
650     if( p_sys->p_page->i_region_defs == 0 ) return;
651
652     p_sys->p_page->p_region_defs =
653         malloc( p_sys->p_page->i_region_defs * sizeof(dvbsub_region_t) );
654     for( i = 0; i < p_sys->p_page->i_region_defs; i++ )
655     {
656         p_sys->p_page->p_region_defs[i].i_id = bs_read( s, 8 );
657         bs_skip( s, 8 ); /* Reserved */
658         p_sys->p_page->p_region_defs[i].i_x = bs_read( s, 16 );
659         p_sys->p_page->p_region_defs[i].i_y = bs_read( s, 16 );
660
661 #ifdef DEBUG_DVBSUB
662         msg_Dbg( p_dec, "page_composition, region %i (%i,%i)",
663                  i, p_sys->p_page->p_region_defs[i].i_x,
664                  p_sys->p_page->p_region_defs[i].i_y );
665 #endif
666     }
667 }
668
669 static void decode_region_composition( decoder_t *p_dec, bs_t *s )
670 {
671     decoder_sys_t *p_sys = p_dec->p_sys;
672     dvbsub_region_t *p_region, **pp_region = &p_sys->p_regions;
673     int i_segment_length, i_processed_length, i_id, i_version;
674     int i_width, i_height, i_level_comp, i_depth, i_clut;
675     int i_8_bg, i_4_bg, i_2_bg;
676     vlc_bool_t b_fill;
677
678     i_segment_length = bs_read( s, 16 );
679     i_id = bs_read( s, 8 );
680     i_version = bs_read( s, 4 );
681
682     /* Check if we already have this region */
683     for( p_region = p_sys->p_regions; p_region != NULL;
684          p_region = p_region->p_next )
685     {
686         pp_region = &p_region->p_next;
687         if( p_region->i_id == i_id ) break;
688     }
689
690     /* Check version number */
691     if( p_region && p_region->i_version == i_version )
692     {
693         bs_skip( s, 8 * (i_segment_length - 1) - 4 );
694         return;
695     }
696
697     if( !p_region )
698     {
699 #ifdef DEBUG_DVBSUB
700         msg_Dbg( p_dec, "new region: %i", i_id );
701 #endif
702         p_region = *pp_region = malloc( sizeof(dvbsub_region_t) );
703         memset( p_region, 0, sizeof(dvbsub_region_t) );
704         p_region->p_object_defs = NULL;
705         p_region->p_pixbuf = NULL;
706         p_region->p_next = NULL;
707     }
708
709     /* Region attributes */
710     p_region->i_id = i_id;
711     p_region->i_version = i_version;
712     b_fill = bs_read( s, 1 );
713     bs_skip( s, 3 ); /* Reserved */
714
715     i_width = bs_read( s, 16 );
716     i_height = bs_read( s, 16 );
717     i_level_comp = bs_read( s, 3 );
718     i_depth = bs_read( s, 3 );
719     bs_skip( s, 2 ); /* Reserved */
720     i_clut = bs_read( s, 8 );
721
722     i_8_bg = bs_read( s, 8 );
723     i_4_bg = bs_read( s, 4 );
724     i_2_bg = bs_read( s, 2 );
725     bs_skip( s, 2 ); /* Reserved */
726     p_region->i_object_defs    = 0;
727
728     /* Extra sanity checks */
729     if( p_region->i_width != i_width || p_region->i_height != i_height )
730     {
731         if( p_region->p_pixbuf )
732         {
733             msg_Dbg( p_dec, "region size changed (not allowed)" );
734             free( p_region->p_pixbuf );
735         }
736
737         p_region->p_pixbuf = malloc( i_height * i_width );
738         p_region->i_depth = 0;
739         b_fill = VLC_TRUE;
740     }
741     if( p_region->i_depth && (p_region->i_depth != i_depth ||
742         p_region->i_level_comp != i_level_comp || p_region->i_clut != i_clut) )
743     {
744         msg_Dbg( p_dec, "region parameters changed (not allowed)" );
745     }
746
747     /* Erase background of region */
748     if( b_fill )
749     {
750         int i_background = (p_region->i_depth == 1) ? i_2_bg :
751             (p_region->i_depth == 2) ? i_4_bg : i_8_bg;
752         memset( p_region->p_pixbuf, i_background, i_width * i_height );
753     }
754
755     p_region->i_width = i_width;
756     p_region->i_height = i_height;
757     p_region->i_level_comp = i_level_comp;
758     p_region->i_depth = i_depth;
759     p_region->i_clut = i_clut;
760
761     /* List of objects in the region */
762     i_processed_length = 10;
763     while( i_processed_length < i_segment_length )
764     {
765         dvbsub_objectdef_t *p_obj;
766
767         /* We create a new object */
768         p_region->i_object_defs++;
769         p_region->p_object_defs =
770             realloc( p_region->p_object_defs,
771                      sizeof(dvbsub_objectdef_t) * p_region->i_object_defs );
772
773         /* We parse object properties */
774         p_obj = &p_region->p_object_defs[p_region->i_object_defs - 1];
775         p_obj->i_id         = bs_read( s, 16 );
776         p_obj->i_type       = bs_read( s, 2 );
777         bs_skip( s, 2 ); /* Provider */
778         p_obj->i_x          = bs_read( s, 12 );
779         bs_skip( s, 4 ); /* Reserved */
780         p_obj->i_y          = bs_read( s, 12 );
781
782         i_processed_length += 6;
783
784         if( p_obj->i_type == DVBSUB_OT_BASIC_CHAR ||
785             p_obj->i_type == DVBSUB_OT_COMPOSITE_STRING )
786         {
787             p_obj->i_fg_pc =  bs_read( s, 8 );
788             p_obj->i_bg_pc =  bs_read( s, 8 );
789             i_processed_length += 2;
790         }
791     }
792 }
793
794 static void dvbsub_render_pdata( decoder_t *, dvbsub_region_t *, int, int,
795                                  uint8_t *, int );
796 static void dvbsub_pdata2bpp( bs_t *, uint8_t *, int, int * );
797 static void dvbsub_pdata4bpp( bs_t *, uint8_t *, int, int * );
798 static void dvbsub_pdata8bpp( bs_t *, uint8_t *, int, int * );
799
800 static void decode_object( decoder_t *p_dec, bs_t *s )
801 {
802     decoder_sys_t *p_sys = p_dec->p_sys;
803     dvbsub_region_t *p_region;
804     int i_segment_length, i_coding_method, i_version, i_id, i;
805     vlc_bool_t b_non_modify_color;
806
807     i_segment_length = bs_read( s, 16 );
808     i_id             = bs_read( s, 16 );
809     i_version        = bs_read( s, 4 );
810     i_coding_method  = bs_read( s, 2 );
811
812     if( i_coding_method )
813     {
814         /* TODO: DVB subtitling as characters */
815         msg_Dbg( p_dec, "DVB subtitling as characters is not handled!" );
816         bs_skip( s, 8 * (i_segment_length - 2) - 6 );
817         return;
818     }
819
820     /* Check if the object needs to be rendered in at least one
821      * of the regions */
822     for( p_region = p_sys->p_regions; p_region != NULL;
823          p_region = p_region->p_next )
824     {
825         for( i = 0; i < p_region->i_object_defs; i++ )
826             if( p_region->p_object_defs[i].i_id == i_id ) break;
827
828         if( i != p_region->i_object_defs ) break;
829     }
830     if( !p_region )
831     {
832         bs_skip( s, 8 * (i_segment_length - 2) - 6 );
833         return;
834     }
835
836 #ifdef DEBUG_DVBSUB
837     msg_Dbg( p_dec, "new object: %i", i_id );
838 #endif
839
840     b_non_modify_color = bs_read( s, 1 );
841     bs_skip( s, 1 ); /* Reserved */
842
843     if( i_coding_method == 0x00 )
844     {
845         int i_topfield, i_bottomfield;
846         uint8_t *p_topfield, *p_bottomfield;
847
848         i_topfield    = bs_read( s, 16 );
849         i_bottomfield = bs_read( s, 16 );
850         p_topfield    = s->p_start + bs_pos( s ) / 8;
851         p_bottomfield = p_topfield + i_topfield;
852
853         bs_skip( s, 8 * (i_segment_length - 7) );
854
855         /* Sanity check */
856         if( i_segment_length < i_topfield + i_bottomfield + 7 ||
857             p_topfield + i_topfield + i_bottomfield > s->p_end )
858         {
859             msg_Dbg( p_dec, "corrupted object data" );
860             return;
861         }
862
863         for( p_region = p_sys->p_regions; p_region != NULL;
864              p_region = p_region->p_next )
865         {
866             for( i = 0; i < p_region->i_object_defs; i++ )
867             {
868                 if( p_region->p_object_defs[i].i_id != i_id ) continue;
869
870                 dvbsub_render_pdata( p_dec, p_region,
871                                      p_region->p_object_defs[i].i_x,
872                                      p_region->p_object_defs[i].i_y,
873                                      p_topfield, i_topfield );
874
875                 if( i_bottomfield )
876                 {
877                     dvbsub_render_pdata( p_dec, p_region,
878                                          p_region->p_object_defs[i].i_x,
879                                          p_region->p_object_defs[i].i_y + 1,
880                                          p_bottomfield, i_bottomfield );
881                 }
882                 else
883                 {
884                     /* Duplicate the top field */
885                     dvbsub_render_pdata( p_dec, p_region,
886                                          p_region->p_object_defs[i].i_x,
887                                          p_region->p_object_defs[i].i_y + 1,
888                                          p_topfield, i_topfield );
889                 }
890             }
891         }
892     }
893     else
894     {
895         /* TODO: DVB subtitling as characters */
896     }
897
898 #ifdef DEBUG_DVBSUB
899     msg_Dbg( p_dec, "end object: %i", i_id );
900 #endif
901 }
902
903 static void dvbsub_render_pdata( decoder_t *p_dec, dvbsub_region_t *p_region,
904                                  int i_x, int i_y,
905                                  uint8_t *p_field, int i_field )
906 {
907     uint8_t *p_pixbuf;
908     int i_offset = 0;
909     bs_t bs;
910
911     /* Sanity check */
912     if( !p_region->p_pixbuf )
913     {
914         msg_Err( p_dec, "region %i has no pixel buffer!", p_region->i_id );
915         return;
916     }
917     if( i_y < 0 || i_x < 0 || i_y >= p_region->i_height ||
918         i_x >= p_region->i_width )
919     {
920         msg_Dbg( p_dec, "invalid offset (%i,%i)", i_x, i_y );
921         return;
922     }
923
924     p_pixbuf = p_region->p_pixbuf + i_y * p_region->i_width;
925     bs_init( &bs, p_field, i_field );
926
927     while( !bs_eof( &bs ) )
928     {
929         /* Sanity check */
930         if( i_y >= p_region->i_height ) return;
931
932         switch( bs_read( &bs, 8 ) )
933         {
934         case 0x10:
935             dvbsub_pdata2bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
936                               &i_offset );
937             break;
938
939         case 0x11:
940             dvbsub_pdata4bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
941                               &i_offset );
942             break;
943
944         case 0x12:
945             dvbsub_pdata8bpp( &bs, p_pixbuf + i_x, p_region->i_width - i_x,
946                               &i_offset );
947             break;
948
949         case 0x20:
950         case 0x21:
951         case 0x22:
952             /* We don't use map tables */
953             break;
954
955         case 0xf0: /* End of line code */
956             p_pixbuf += 2*p_region->i_width;
957             i_offset = 0; i_y += 2;
958             break;
959         }
960     }
961 }
962
963 static void dvbsub_pdata2bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
964 {
965     vlc_bool_t b_stop = 0;
966
967     while( !b_stop && !bs_eof( s ) )
968     {
969         int i_count = 0, i_color = 0;
970
971         if( (i_color = bs_read( s, 2 )) != 0x00 )
972         {
973             i_count = 1;
974         }
975         else
976         {
977             if( bs_read( s, 1 ) == 0x01 )         // Switch1
978             {
979                 i_count = 3 + bs_read( s, 3 );
980                 i_color = bs_read( s, 2 );
981             }
982             else
983             {
984                 if( bs_read( s, 1 ) == 0x00 )     //Switch2
985                 {
986                     switch( bs_read( s, 2 ) )     //Switch3
987                     {
988                     case 0x00:
989                         b_stop = 1;
990                         break;
991                     case 0x01:
992                         i_count = 2;
993                         break;
994                     case 0x02:
995                         i_count =  12 + bs_read( s, 4 );
996                         i_color = bs_read( s, 2 );
997                         break;
998                     case 0x03:
999                         i_count =  29 + bs_read( s, 8 );
1000                         i_color = bs_read( s, 2 );
1001                         break;
1002                     default:
1003                         break;
1004                     }
1005                 }
1006                 else
1007                 {
1008                     /* 1 pixel color 0 */
1009                     i_count = 1;
1010                 }
1011             }
1012         }
1013
1014         if( !i_count ) continue;
1015
1016         /* Sanity check */
1017         if( i_count + *pi_off > i_width ) break;
1018
1019         if( i_count == 1 ) p[*pi_off] = i_color;
1020         else memset( p + *pi_off, i_color, i_count );
1021
1022         (*pi_off) += i_count;
1023     }
1024
1025     bs_align( s );
1026 }
1027
1028 static void dvbsub_pdata4bpp( bs_t *s, uint8_t *p, int i_width, int *pi_off )
1029 {
1030     vlc_bool_t b_stop = 0;
1031
1032     while( !b_stop && !bs_eof( s ) )
1033     {
1034         int i_count = 0, i_color = 0;
1035
1036         if( (i_color = bs_read( s, 4 )) != 0x00 )
1037         {
1038             /* Add 1 pixel */
1039             i_count = 1;
1040         }
1041         else
1042         {
1043             if( bs_read( s, 1 ) == 0x00 )           // Switch1
1044             {
1045                 if( bs_show( s, 3 ) != 0x00 )
1046                 {
1047                     i_count = 2 + bs_read( s, 3 );
1048                 }
1049                 else
1050                 {
1051                     bs_skip( s, 3 );
1052                     b_stop = 1;
1053                 }
1054             }
1055             else
1056             {
1057                 if( bs_read( s, 1 ) == 0x00)        //Switch2
1058                 {
1059                     i_count =  4 + bs_read( s, 2 );
1060                     i_color = bs_read( s, 4 );
1061                 }
1062                 else
1063                 {
1064                     switch ( bs_read( s, 2 ) )     //Switch3
1065                     {
1066                     case 0x0:
1067                         i_count = 1;
1068                         break;
1069                     case 0x1:
1070                         i_count = 2;
1071                         break;
1072                     case 0x2:
1073                         i_count = 9 + bs_read( s, 4 );
1074                         i_color = bs_read( s, 4 );
1075                         break;
1076                     case 0x3:
1077                         i_count= 25 + bs_read( s, 8 );
1078                         i_color = bs_read( s, 4 );
1079                         break;
1080                     }
1081                 }
1082             }
1083         }
1084
1085         if( !i_count ) continue;
1086
1087         /* Sanity check */
1088         if( i_count + *pi_off > i_width ) break;
1089
1090         if( i_count == 1 ) p[*pi_off] = i_color;
1091         else memset( p + *pi_off, i_color, i_count );
1092
1093         (*pi_off) += i_count;
1094     }
1095
1096     bs_align( s );
1097 }
1098
1099 static void dvbsub_pdata8bpp( 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, 8 )) != 0x00 )
1108         {
1109             /* Add 1 pixel */
1110             i_count = 1;
1111         }
1112         else
1113         {
1114             if( bs_read( s, 1 ) == 0x00 )           // Switch1
1115             {
1116                 if( bs_show( s, 7 ) != 0x00 )
1117                 {
1118                     i_count = bs_read( s, 7 );
1119                 }
1120                 else
1121                 {
1122                     bs_skip( s, 7 );
1123                     b_stop = 1;
1124                 }
1125             }
1126             else
1127             {
1128                 i_count = bs_read( s, 7 );
1129                 i_color = bs_read( s, 8 );
1130             }
1131         }
1132
1133         if( !i_count ) continue;
1134
1135         /* Sanity check */
1136         if( i_count + *pi_off > i_width ) break;
1137
1138         if( i_count == 1 ) p[*pi_off] = i_color;
1139         else memset( p + *pi_off, i_color, i_count );
1140
1141         (*pi_off) += i_count;
1142     }
1143
1144     bs_align( s );
1145 }
1146
1147 static void free_all( decoder_t *p_dec )
1148 {
1149     decoder_sys_t *p_sys = p_dec->p_sys;
1150     dvbsub_region_t *p_reg, *p_reg_next;
1151     dvbsub_clut_t *p_clut, *p_clut_next;
1152
1153     for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut_next )
1154     {
1155         p_clut_next = p_clut->p_next;
1156         free( p_clut );
1157     }
1158     p_sys->p_cluts = NULL;
1159
1160     for( p_reg = p_sys->p_regions; p_reg != NULL; p_reg = p_reg_next )
1161     {
1162         p_reg_next = p_reg->p_next;
1163         if( p_reg->i_object_defs ) free( p_reg->p_object_defs );
1164         if( p_reg->p_pixbuf ) free( p_reg->p_pixbuf );
1165         free( p_reg );
1166     }
1167     p_sys->p_regions = NULL;
1168
1169     if( p_sys->p_page )
1170     {
1171         if( p_sys->p_page->i_region_defs )
1172             free( p_sys->p_page->p_region_defs );
1173         free( p_sys->p_page );
1174     }
1175     p_sys->p_page = NULL;
1176 }
1177
1178 static subpicture_t *render( decoder_t *p_dec )
1179 {
1180     decoder_sys_t *p_sys = p_dec->p_sys;
1181     subpicture_t *p_spu;
1182     subpicture_region_t **pp_spu_region;
1183     int i, j, i_timeout = 0;
1184
1185     /* Allocate the subpicture internal data. */
1186     p_spu = p_dec->pf_spu_buffer_new( p_dec );
1187     if( !p_spu ) return NULL;
1188
1189     pp_spu_region = &p_spu->p_region;
1190
1191     /* Loop on region definitions */
1192 #ifdef DEBUG_DVBSUB
1193     if( p_sys->p_page )
1194         msg_Dbg( p_dec, "rendering %i regions", p_sys->p_page->i_region_defs );
1195 #endif
1196
1197     for( i = 0; p_sys->p_page && i < p_sys->p_page->i_region_defs; i++ )
1198     {
1199         dvbsub_region_t     *p_region;
1200         dvbsub_regiondef_t  *p_regiondef;
1201         dvbsub_clut_t       *p_clut;
1202         dvbsub_color_t      *p_color;
1203         subpicture_region_t *p_spu_region;
1204         uint8_t *p_src, *p_dst;
1205         video_format_t fmt;
1206         int i_pitch;
1207
1208         i_timeout = p_sys->p_page->i_timeout;
1209
1210         p_regiondef = &p_sys->p_page->p_region_defs[i];
1211
1212 #ifdef DEBUG_DVBSUB
1213         msg_Dbg( p_dec, "rendering region %i (%i,%i)", i,
1214                  p_regiondef->i_x, p_regiondef->i_y );
1215 #endif
1216
1217         /* Find associated region */
1218         for( p_region = p_sys->p_regions; p_region != NULL;
1219              p_region = p_region->p_next )
1220         {
1221             if( p_regiondef->i_id == p_region->i_id ) break;
1222         }
1223
1224         if( !p_region )
1225         {
1226             msg_Dbg( p_dec, "region %i not found", p_regiondef->i_id );
1227             continue;
1228         }
1229
1230         /* Find associated CLUT */
1231         for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )
1232         {
1233             if( p_region->i_clut == p_clut->i_id ) break;
1234         }
1235         if( !p_clut )
1236         {
1237             msg_Dbg( p_dec, "clut %i not found", p_region->i_clut );
1238             continue;
1239         }
1240
1241         /* Create new SPU region */
1242         memset( &fmt, 0, sizeof(video_format_t) );
1243         fmt.i_chroma = VLC_FOURCC('Y','U','V','P');
1244         fmt.i_aspect = VOUT_ASPECT_FACTOR;
1245         fmt.i_width = fmt.i_visible_width = p_region->i_width;
1246         fmt.i_height = fmt.i_visible_height = p_region->i_height;
1247         fmt.i_x_offset = fmt.i_y_offset = 0;
1248         p_spu_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
1249         if( !p_region )
1250         {
1251             msg_Err( p_dec, "cannot allocate SPU region" );
1252             continue;
1253         }
1254         p_spu_region->i_x = p_regiondef->i_x;
1255         p_spu_region->i_y = p_regiondef->i_y;
1256         *pp_spu_region = p_spu_region;
1257         pp_spu_region = &p_spu_region->p_next;
1258
1259         /* Build palette */
1260         fmt.p_palette->i_entries = p_region->i_depth == 1 ? 4 :
1261             p_region->i_depth == 2 ? 16 : 256;
1262         p_color = (p_region->i_depth == 1) ? p_clut->c_2b :
1263             (p_region->i_depth == 2) ? p_clut->c_4b : p_clut->c_8b;
1264         for( j = 0; j < fmt.p_palette->i_entries; j++ )
1265         {
1266             fmt.p_palette->palette[j][0] = p_color[j].Y;
1267             fmt.p_palette->palette[j][1] = p_color[j].Cr;
1268             fmt.p_palette->palette[j][2] = p_color[j].Cb;
1269             fmt.p_palette->palette[j][3] = 0xff - p_color[j].T;
1270         }
1271
1272         p_src = p_region->p_pixbuf;
1273         p_dst = p_spu_region->picture.Y_PIXELS;
1274         i_pitch = p_spu_region->picture.Y_PITCH;
1275
1276         /* Copy pixel buffer */
1277         for( j = 0; j < p_region->i_height; j++ )
1278         {
1279             memcpy( p_dst, p_src, p_region->i_width );
1280             p_src += p_region->i_width;
1281             p_dst += i_pitch;
1282         }
1283     }
1284
1285     /* Set the pf_render callback */
1286     p_spu->i_start = p_sys->i_pts;
1287     p_spu->i_stop = p_spu->i_start + i_timeout * 1000000;
1288     p_spu->b_ephemer = VLC_TRUE;
1289
1290     return p_spu;
1291 }
1292
1293 /*****************************************************************************
1294  * encoder_sys_t : encoder descriptor
1295  *****************************************************************************/
1296 typedef struct encoder_region_t
1297 {
1298     int i_width;
1299     int i_height;
1300
1301 } encoder_region_t;
1302
1303 struct encoder_sys_t
1304 {
1305     unsigned int i_page_ver;
1306     unsigned int i_region_ver;
1307     unsigned int i_clut_ver;
1308
1309     int i_regions;
1310     encoder_region_t *p_regions;
1311
1312     mtime_t i_pts;
1313 };
1314
1315 static void encode_page_composition( encoder_t *, bs_t *, subpicture_t * );
1316 static void encode_clut( encoder_t *, bs_t *, subpicture_t * );
1317 static void encode_region_composition( encoder_t *, bs_t *, subpicture_t * );
1318 static void encode_object( encoder_t *, bs_t *, subpicture_t * );
1319
1320 /*****************************************************************************
1321  * OpenEncoder: probe the encoder and return score
1322  *****************************************************************************/
1323 static int OpenEncoder( vlc_object_t *p_this )
1324 {
1325     encoder_t *p_enc = (encoder_t *)p_this;
1326     encoder_sys_t *p_sys;
1327
1328     if( p_enc->fmt_out.i_codec != VLC_FOURCC('d','v','b','s') &&
1329         !p_enc->b_force )
1330     {
1331         return VLC_EGENERIC;
1332     }
1333
1334     /* Allocate the memory needed to store the decoder's structure */
1335     if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
1336     {
1337         msg_Err( p_enc, "out of memory" );
1338         return VLC_EGENERIC;
1339     }
1340     p_enc->p_sys = p_sys;
1341
1342     p_enc->pf_encode_sub = Encode;
1343     p_enc->fmt_out.i_codec = VLC_FOURCC('d','v','b','s');
1344     p_enc->fmt_out.subs.dvb.i_id  = 1 << 16 | 1;
1345
1346     sout_CfgParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );
1347
1348     p_sys->i_page_ver = 0;
1349     p_sys->i_region_ver = 0;
1350     p_sys->i_clut_ver = 0;
1351     p_sys->i_regions = 0;
1352     p_sys->p_regions = 0;
1353
1354     return VLC_SUCCESS;
1355 }
1356
1357 /****************************************************************************
1358  * Encode: the whole thing
1359  ****************************************************************************/
1360 static block_t *Encode( encoder_t *p_enc, subpicture_t *p_subpic )
1361 {
1362     bs_t bits, *s = &bits;
1363     block_t *p_block;
1364
1365     if( !p_subpic || !p_subpic->p_region ) return 0;
1366
1367     msg_Dbg( p_enc, "encoding subpicture" );
1368
1369     p_block = block_New( p_enc, 64000 );
1370     bs_init( s, p_block->p_buffer, p_block->i_buffer );
1371
1372     bs_write( s, 8, 0x20 ); /* Data identifier */
1373     bs_write( s, 8, 0x0 ); /* Subtitle stream id */
1374
1375     encode_page_composition( p_enc, s, p_subpic );
1376     encode_region_composition( p_enc, s, p_subpic );
1377     encode_clut( p_enc, s, p_subpic );
1378     encode_object( p_enc, s, p_subpic );
1379
1380     /* End of display */
1381     bs_write( s, 8, 0x0f ); /* Sync byte */
1382     bs_write( s, 8, DVBSUB_ST_ENDOFDISPLAY ); /* Segment type */
1383     bs_write( s, 16, 1 ); /* Page id */
1384     bs_write( s, 16, 0 ); /* Segment length */
1385
1386     bs_write( s, 8, 0xff ); /* End marker */
1387     p_block->i_buffer = bs_pos( s ) / 8;
1388     p_block->i_pts = p_block->i_dts = p_subpic->i_start;
1389     if( !p_subpic->b_ephemer && p_subpic->i_stop > p_subpic->i_start )
1390     {
1391         block_t *p_block_stop;
1392
1393         p_block->i_length = p_subpic->i_stop - p_subpic->i_start;
1394
1395         /* Send another (empty) subtitle to signal the end of display */
1396         p_block_stop = block_New( p_enc, 64000 );
1397         bs_init( s, p_block_stop->p_buffer, p_block_stop->i_buffer );
1398         bs_write( s, 8, 0x20 ); /* Data identifier */
1399         bs_write( s, 8, 0x0 ); /* Subtitle stream id */
1400         encode_page_composition( p_enc, s, 0 );
1401         bs_write( s, 8, 0x0f ); /* Sync byte */
1402         bs_write( s, 8, DVBSUB_ST_ENDOFDISPLAY ); /* Segment type */
1403         bs_write( s, 16, 1 ); /* Page id */
1404         bs_write( s, 16, 0 ); /* Segment length */
1405         bs_write( s, 8, 0xff ); /* End marker */
1406         p_block_stop->i_buffer = bs_pos( s ) / 8;
1407         p_block_stop->i_pts = p_block_stop->i_dts = p_subpic->i_stop;
1408         block_ChainAppend( &p_block, p_block_stop );
1409         p_block_stop->i_length = 100000;//p_subpic->i_stop - p_subpic->i_start;
1410     }
1411
1412     msg_Dbg( p_enc, "subpicture encoded properly" );
1413
1414     return p_block;
1415 }
1416
1417 /*****************************************************************************
1418  * CloseEncoder: encoder destruction
1419  *****************************************************************************/
1420 static void CloseEncoder( vlc_object_t *p_this )
1421 {
1422     encoder_t *p_enc = (encoder_t *)p_this;
1423     encoder_sys_t *p_sys = p_enc->p_sys;
1424
1425     if( p_sys->i_regions ) free( p_sys->p_regions );
1426     free( p_sys );
1427 }
1428
1429 static void encode_page_composition( encoder_t *p_enc, bs_t *s,
1430                                      subpicture_t *p_subpic )
1431 {
1432     encoder_sys_t *p_sys = p_enc->p_sys;
1433     subpicture_region_t *p_region;
1434     vlc_bool_t b_mode_change = VLC_FALSE;
1435     int i_regions, i_timeout;
1436
1437     bs_write( s, 8, 0x0f ); /* Sync byte */
1438     bs_write( s, 8, DVBSUB_ST_PAGE_COMPOSITION ); /* Segment type */
1439     bs_write( s, 16, 1 ); /* Page id */
1440
1441     for( i_regions = 0, p_region = p_subpic ? p_subpic->p_region : 0;
1442          p_region; p_region = p_region->p_next, i_regions++ )
1443     {
1444         if( i_regions >= p_sys->i_regions )
1445         {
1446             encoder_region_t region;
1447             region.i_width = region.i_height = 0;
1448             p_sys->p_regions =
1449                 realloc( p_sys->p_regions, sizeof(encoder_region_t) *
1450                          (p_sys->i_regions + 1) );
1451             p_sys->p_regions[p_sys->i_regions++] = region;
1452         }
1453
1454         if( p_sys->p_regions[i_regions].i_width <
1455             (int)p_region->fmt.i_visible_width )
1456         {
1457             b_mode_change = VLC_TRUE;
1458             msg_Dbg( p_enc, "region %i width change: %i -> %i",
1459                      i_regions, p_sys->p_regions[i_regions].i_width,
1460                      p_region->fmt.i_visible_width );
1461             p_sys->p_regions[i_regions].i_width =
1462                 p_region->fmt.i_visible_width;
1463         }
1464         if( p_sys->p_regions[i_regions].i_height <
1465             (int)p_region->fmt.i_visible_height )
1466         {
1467             b_mode_change = VLC_TRUE;
1468             msg_Dbg( p_enc, "region %i height change: %i -> %i",
1469                      i_regions, p_sys->p_regions[i_regions].i_height,
1470                      p_region->fmt.i_visible_height );
1471             p_sys->p_regions[i_regions].i_height =
1472                 p_region->fmt.i_visible_height;
1473         }
1474     }
1475
1476     bs_write( s, 16, i_regions * 6 + 2 ); /* Segment length */
1477
1478     i_timeout = 0;
1479     if( p_subpic && !p_subpic->b_ephemer &&
1480         p_subpic->i_stop > p_subpic->i_start )
1481     {
1482         i_timeout = (p_subpic->i_stop - p_subpic->i_start) / 1000000;
1483     }
1484
1485     bs_write( s, 8, i_timeout + 15 ); /* Timeout */
1486     bs_write( s, 4, p_sys->i_page_ver++ );
1487     bs_write( s, 2, b_mode_change ?
1488               DVBSUB_PCS_STATE_CHANGE : DVBSUB_PCS_STATE_ACQUISITION );
1489     bs_write( s, 2, 0 ); /* Reserved */
1490
1491     for( i_regions = 0, p_region = p_subpic ? p_subpic->p_region : 0;
1492          p_region; p_region = p_region->p_next, i_regions++ )
1493     {
1494         bs_write( s, 8, i_regions );
1495         bs_write( s, 8, 0 ); /* Reserved */
1496         bs_write( s, 16, p_region->i_x );
1497         bs_write( s, 16, p_region->i_y );
1498     }
1499 }
1500
1501 static void encode_clut( encoder_t *p_enc, bs_t *s, subpicture_t *p_subpic )
1502 {
1503     encoder_sys_t *p_sys = p_enc->p_sys;
1504     subpicture_region_t *p_region = p_subpic->p_region;
1505     video_palette_t *p_pal;
1506     int i;
1507
1508     /* Sanity check */
1509     if( !p_region || !p_region->fmt.p_palette ||
1510         p_region->fmt.i_chroma != VLC_FOURCC('Y','U','V','P') ) return;
1511
1512     bs_write( s, 8, 0x0f ); /* Sync byte */
1513     bs_write( s, 8, DVBSUB_ST_CLUT_DEFINITION ); /* Segment type */
1514     bs_write( s, 16, 1 ); /* Page id */
1515
1516     p_pal = p_region->fmt.p_palette;
1517
1518     bs_write( s, 16, p_pal->i_entries * 6 + 2 ); /* Segment length */
1519     bs_write( s, 8, 1 ); /* Clut id */
1520     bs_write( s, 4, p_sys->i_clut_ver++ );
1521     bs_write( s, 4, 0 ); /* Reserved */
1522
1523     for( i = 0; i < p_pal->i_entries; i++ )
1524     {
1525         bs_write( s, 8, i ); /* Clut entry id */
1526         bs_write( s, 1, p_pal->i_entries == 4 );   /* 2bit/entry flag */
1527         bs_write( s, 1, p_pal->i_entries == 16 );  /* 4bit/entry flag */
1528         bs_write( s, 1, p_pal->i_entries == 256 ); /* 8bit/entry flag */
1529         bs_write( s, 4, 0 ); /* Reserved */
1530         bs_write( s, 1, 1 ); /* Full range flag */
1531         bs_write( s, 8, p_pal->palette[i][3] ?  /* Y value */
1532                   (p_pal->palette[i][0] ? p_pal->palette[i][0] : 16) : 0 );
1533         bs_write( s, 8, p_pal->palette[i][1] ); /* Cr value */
1534         bs_write( s, 8, p_pal->palette[i][2] ); /* Cb value */
1535         bs_write( s, 8, 0xff - p_pal->palette[i][3] ); /* T value */
1536     }
1537 }
1538
1539 static void encode_region_composition( encoder_t *p_enc, bs_t *s,
1540                                        subpicture_t *p_subpic )
1541 {
1542     encoder_sys_t *p_sys = p_enc->p_sys;
1543     subpicture_region_t *p_region;
1544     int i_region, i_bg;
1545
1546     for( i_region = 0, p_region = p_subpic->p_region; p_region;
1547          p_region = p_region->p_next, i_region++ )
1548     {
1549         video_palette_t *p_pal = p_region->fmt.p_palette;
1550         int i_depth = p_pal->i_entries == 4 ? 0x1 :
1551             p_pal->i_entries == 16 ? 0x2 : 0x3;
1552
1553         for( i_bg = 0; i_bg < p_pal->i_entries; i_bg++ )
1554         {
1555             if( !p_pal->palette[i_bg][3] ) break;
1556         }
1557
1558         bs_write( s, 8, 0x0f ); /* Sync byte */
1559         bs_write( s, 8, DVBSUB_ST_REGION_COMPOSITION ); /* Segment type */
1560         bs_write( s, 16, 1 ); /* Page id */
1561
1562         bs_write( s, 16, 10 + 6 ); /* Segment length */
1563         bs_write( s, 8, i_region );
1564         bs_write( s, 4, p_sys->i_region_ver++ );
1565
1566         /* Region attributes */
1567         bs_write( s, 1, i_bg < p_pal->i_entries ); /* Fill */
1568         bs_write( s, 3, 0 ); /* Reserved */
1569         bs_write( s, 16, p_sys->p_regions[i_region].i_width );
1570         bs_write( s, 16, p_sys->p_regions[i_region].i_height );
1571         bs_write( s, 3, i_depth );  /* Region level of compatibility */
1572         bs_write( s, 3, i_depth  ); /* Region depth */
1573         bs_write( s, 2, 0 ); /* Reserved */
1574         bs_write( s, 8, 1 ); /* Clut id */
1575         bs_write( s, 8, i_bg ); /* region 8bit pixel code */
1576         bs_write( s, 4, i_bg ); /* region 4bit pixel code */
1577         bs_write( s, 2, i_bg ); /* region 2bit pixel code */
1578         bs_write( s, 2, 0 ); /* Reserved */
1579
1580         /* In our implementation we only have 1 object per region */
1581         bs_write( s, 16, i_region );
1582         bs_write( s, 2, DVBSUB_OT_BASIC_BITMAP );
1583         bs_write( s, 2, 0 ); /* object provider flag */
1584         bs_write( s, 12, 0 ); /* object horizontal position */
1585         bs_write( s, 4, 0 ); /* Reserved */
1586         bs_write( s, 12, 0 ); /* object vertical position */
1587     }
1588 }
1589
1590 static void encode_pixel_data( encoder_t *p_enc, bs_t *s,
1591                                subpicture_region_t *p_region,
1592                                vlc_bool_t b_top );
1593
1594 static void encode_object( encoder_t *p_enc, bs_t *s, subpicture_t *p_subpic )
1595 {
1596     encoder_sys_t   *p_sys = p_enc->p_sys;
1597     subpicture_region_t *p_region;
1598     int i_region;
1599
1600     int i_length_pos, i_update_pos, i_pixel_data_pos;
1601
1602     for( i_region = 0, p_region = p_subpic->p_region; p_region;
1603          p_region = p_region->p_next, i_region++ )
1604     {
1605         bs_write( s, 8, 0x0f ); /* Sync byte */
1606         bs_write( s, 8, DVBSUB_ST_OBJECT_DATA ); /* Segment type */
1607         bs_write( s, 16, 1 ); /* Page id */
1608
1609         i_length_pos = bs_pos( s );
1610         bs_write( s, 16, 0 ); /* Segment length */
1611         bs_write( s, 16, i_region ); /* Object id */
1612         bs_write( s, 4, p_sys->i_region_ver++ );
1613         bs_write( s, 2, 0 ); /* object coding method */
1614
1615         bs_write( s, 1, 0 ); /* non modifying color flag */
1616         bs_write( s, 1, 0 ); /* Reserved */
1617
1618         i_update_pos = bs_pos( s );
1619         bs_write( s, 16, 0 ); /* topfield data block length */
1620         bs_write( s, 16, 0 ); /* bottomfield data block length */
1621
1622         /* Top field */
1623         i_pixel_data_pos = bs_pos( s );
1624         encode_pixel_data( p_enc, s, p_region, VLC_TRUE );
1625         i_pixel_data_pos = ( bs_pos( s ) - i_pixel_data_pos ) / 8;
1626         SetWBE( &s->p_start[i_update_pos/8], i_pixel_data_pos );
1627
1628         /* Bottom field */
1629         i_pixel_data_pos = bs_pos( s );
1630         encode_pixel_data( p_enc, s, p_region, VLC_FALSE );
1631         i_pixel_data_pos = ( bs_pos( s ) - i_pixel_data_pos ) / 8;
1632         SetWBE( &s->p_start[i_update_pos/8+2], i_pixel_data_pos );
1633
1634         /* Stuffing for word alignment */
1635         bs_align_0( s );
1636         if( bs_pos( s ) % 16 ) bs_write( s, 8, 0 );
1637
1638         /* Update segment length */
1639         SetWBE( &s->p_start[i_length_pos/8], (bs_pos(s) - i_length_pos)/8 -2 );
1640     }
1641 }
1642
1643 static void encode_pixel_line_2bp( encoder_t *p_enc, bs_t *s,
1644                                    subpicture_region_t *p_region,
1645                                    int i_line );
1646 static void encode_pixel_line_4bp( encoder_t *p_enc, bs_t *s,
1647                                    subpicture_region_t *p_region,
1648                                    int i_line );
1649 static void encode_pixel_data( encoder_t *p_enc, bs_t *s,
1650                                subpicture_region_t *p_region,
1651                                vlc_bool_t b_top )
1652 {
1653     unsigned int i_line;
1654
1655     /* Sanity check */
1656     if( p_region->fmt.i_chroma != VLC_FOURCC('Y','U','V','P') ) return;
1657
1658     /* Encode line by line */
1659     for( i_line = !b_top; i_line < p_region->fmt.i_visible_height;
1660          i_line += 2 )
1661     {
1662         switch( p_region->fmt.p_palette->i_entries )
1663         {
1664         case 4:
1665             bs_write( s, 8, 0x10 ); /* 2 bit/pixel code string */
1666             encode_pixel_line_2bp( p_enc, s, p_region, i_line );
1667             break;
1668
1669         case 16:
1670             bs_write( s, 8, 0x11 ); /* 4 bit/pixel code string */
1671             encode_pixel_line_4bp( p_enc, s, p_region, i_line );
1672             break;
1673
1674         default:
1675             msg_Err( p_enc, "subpicture palette (%i) not handled",
1676                      p_region->fmt.p_palette->i_entries );
1677             break;
1678         }
1679
1680         bs_write( s, 8, 0xf0 ); /* End of object line code */
1681     }
1682 }
1683
1684 static void encode_pixel_line_2bp( encoder_t *p_enc, bs_t *s,
1685                                    subpicture_region_t *p_region,
1686                                    int i_line )
1687 {
1688     unsigned int i, i_length = 0;
1689     int i_pitch = p_region->picture.p->i_pitch;
1690     uint8_t *p_data = &p_region->picture.p->p_pixels[ i_pitch * i_line ];
1691     int i_last_pixel = p_data[0];
1692
1693     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
1694     {
1695         if( i != p_region->fmt.i_visible_width &&
1696             p_data[i] == i_last_pixel && i_length != 284 )
1697         {
1698             i_length++;
1699             continue;
1700         }
1701
1702         if( i_length == 1 || i_length == 11 || i_length == 28 )
1703         {
1704             /* 2bit/pixel code */
1705             if( i_last_pixel ) bs_write( s, 2, i_last_pixel );
1706             else
1707             {
1708                 bs_write( s, 2, 0 );
1709                 bs_write( s, 1, 0 );
1710                 bs_write( s, 1, 1 ); /* pseudo color 0 */
1711             }
1712             i_length--;
1713         }
1714
1715         if( i_length == 2 )
1716         {
1717             if( i_last_pixel )
1718             {
1719                 bs_write( s, 2, i_last_pixel );
1720                 bs_write( s, 2, i_last_pixel );
1721             }
1722             else
1723             {
1724                 bs_write( s, 2, 0 );
1725                 bs_write( s, 1, 0 );
1726                 bs_write( s, 1, 0 );
1727                 bs_write( s, 2, 1 ); /* 2 * pseudo color 0 */
1728             }
1729         }
1730         else if( i_length > 2 )
1731         {
1732             bs_write( s, 2, 0 );
1733             if( i_length <= 10 )
1734             {
1735                 bs_write( s, 1, 1 );
1736                 bs_write( s, 3, i_length - 3 );
1737                 bs_write( s, 2, i_last_pixel );
1738             }
1739             else
1740             {
1741                 bs_write( s, 1, 0 );
1742                 bs_write( s, 1, 0 );
1743
1744                 if( i_length <= 27 )
1745                 {
1746                     bs_write( s, 2, 2 );
1747                     bs_write( s, 4, i_length - 12 );
1748                     bs_write( s, 2, i_last_pixel );
1749                 }
1750                 else
1751                 {
1752                     bs_write( s, 2, 3 );
1753                     bs_write( s, 8, i_length - 29 );
1754                     bs_write( s, 2, i_last_pixel );
1755                 }
1756             }
1757         }
1758
1759         if( i == p_region->fmt.i_visible_width ) break;
1760
1761         i_last_pixel = p_data[i];
1762         i_length = 1;
1763     }
1764
1765     /* Stop */
1766     bs_write( s, 2, 0 );
1767     bs_write( s, 1, 0 );
1768     bs_write( s, 1, 0 );
1769     bs_write( s, 2, 0 );
1770
1771     /* Stuffing */
1772     bs_align_0( s );
1773 }
1774
1775 static void encode_pixel_line_4bp( encoder_t *p_enc, bs_t *s,
1776                                    subpicture_region_t *p_region,
1777                                    int i_line )
1778 {
1779     unsigned int i, i_length = 0;
1780     int i_pitch = p_region->picture.p->i_pitch;
1781     uint8_t *p_data = &p_region->picture.p->p_pixels[ i_pitch * i_line ];
1782     int i_last_pixel = p_data[0];
1783
1784     for( i = 0; i <= p_region->fmt.i_visible_width; i++ )
1785     {
1786         if( i != p_region->fmt.i_visible_width &&
1787             p_data[i] == i_last_pixel && i_length != 1 )
1788         {
1789             i_length++;
1790             continue;
1791         }
1792
1793         if( i_length == 1 )
1794         {
1795             /* 4bit/pixel code */
1796             if( i_last_pixel ) bs_write( s, 4, i_last_pixel );
1797             else
1798             {
1799                 bs_write( s, 4, 0 );
1800                 bs_write( s, 1, 1 );
1801                 bs_write( s, 1, 1 );
1802                 bs_write( s, 2, 0 ); /* pseudo color 0 */
1803             }
1804         }
1805
1806         if( i == p_region->fmt.i_visible_width ) break;
1807
1808         i_last_pixel = p_data[i];
1809         i_length = 1;
1810     }
1811
1812     /* Stop */
1813     bs_write( s, 8, 0 );
1814
1815     /* Stuffing */
1816     bs_align_0( s );
1817 }