dvbsub.c 75.9 KB
Newer Older
1
/*****************************************************************************
2 3
 * dvbsub.c : DVB subtitles decoder
 *            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
 *
Gildas Bazin's avatar
Gildas Bazin committed
9 10
 * Authors: Gildas Bazin <gbazin@videolan.org>
 *          Damien LUCAS <damien.lucas@anevia.com>
11
 *          Laurent Aimar <fenrir@via.ecp.fr>
12
 *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
Antoine Cellerier's avatar
Antoine Cellerier committed
26
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27 28 29
 *****************************************************************************/
/*****************************************************************************
 * Preamble
30 31 32
 *
 * FIXME:
 * DVB subtitles coded as strings of characters are not handled correctly.
33
 * The character codes in the string should actually be indexes referring to a
34
 * character table identified in the subtitle descriptor.
35 36 37 38
 *****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
39
#include <vlc/sout.h>
40

41 42
#include "vlc_bits.h"

Jean-Paul Saman's avatar
Jean-Paul Saman committed
43
/* #define DEBUG_DVBSUB 1 */
44

45 46
#define POSX_TEXT N_("Decoding X coordinate")
#define POSX_LONGTEXT N_("X coordinate of the rendered subtitle")
47

48 49
#define POSY_TEXT N_("Decoding Y coordinate")
#define POSY_LONGTEXT N_("Y coordinate of the rendered subtitle") 
50 51 52 53 54

#define POS_TEXT N_("Subpicture position")
#define POS_LONGTEXT N_( \
  "You can enforce the subpicture position on the video " \
  "(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 58 59 60
#define ENC_POSX_TEXT N_("Encoding X coordinate")
#define ENC_POSX_LONGTEXT N_("X coordinate of the encoded subtitle" )
#define ENC_POSY_TEXT N_("Encoding Y coordinate")
#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 };
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
63
static const char *ppsz_pos_descriptions[] =
64 65
{ N_("Center"), N_("Left"), N_("Right"), N_("Top"), N_("Bottom"),
  N_("Top-Left"), N_("Top-Right"), N_("Bottom-Left"), N_("Bottom-Right") };
66

67 68 69
/*****************************************************************************
 * Module descriptor.
 *****************************************************************************/
70 71 72 73
static int  Open ( vlc_object_t * );
static void Close( vlc_object_t * );
static subpicture_t *Decode( decoder_t *, block_t ** );

74 75 76
static int OpenEncoder  ( vlc_object_t * );
static void CloseEncoder( vlc_object_t * );
static block_t *Encode  ( encoder_t *, subpicture_t * );
77 78

vlc_module_begin();
79
#   define DVBSUB_CFG_PREFIX "dvbsub-"
Benjamin Pracht's avatar
Benjamin Pracht committed
80
    set_description( _("DVB subtitles decoder") );
81
    set_capability( "decoder", 50 );
Clément Stenac's avatar
Clément Stenac committed
82 83
    set_category( CAT_INPUT );
    set_subcategory( SUBCAT_INPUT_SCODEC );
84
    set_callbacks( Open, Close );
85

86 87 88
    add_integer( DVBSUB_CFG_PREFIX "position", 8, NULL, POS_TEXT, POS_LONGTEXT, VLC_TRUE );
        change_integer_list( pi_pos_values, ppsz_pos_descriptions, 0 );
    add_integer( DVBSUB_CFG_PREFIX "x", -1, NULL, POSX_TEXT, POSX_LONGTEXT, VLC_FALSE );
Jean-Paul Saman's avatar
Jean-Paul Saman committed
89
    add_integer( DVBSUB_CFG_PREFIX "y", -1, NULL, POSY_TEXT, POSY_LONGTEXT, VLC_FALSE );
90 91 92 93 94 95

#   define ENC_CFG_PREFIX "sout-dvbsub-"
    add_submodule();
    set_description( _("DVB subtitles encoder") );
    set_capability( "encoder", 100 );
    set_callbacks( OpenEncoder, CloseEncoder );
96

97 98
    add_integer( ENC_CFG_PREFIX "x", -1, NULL, ENC_POSX_TEXT, ENC_POSX_LONGTEXT, VLC_FALSE );
    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 101
vlc_module_end();

102
static const char *ppsz_enc_options[] = { "x", "y", NULL };
103

104 105 106 107 108 109 110 111 112
/****************************************************************************
 * Local structures
 ****************************************************************************
 * Those structures refer closely to the ETSI 300 743 Object model
 ****************************************************************************/

/* The object definition gives the position of the object in a region */
typedef struct dvbsub_objectdef_s
{
Gildas Bazin's avatar
Gildas Bazin committed
113 114 115 116 117 118
    int i_id;
    int i_type;
    int i_x;
    int i_y;
    int i_fg_pc;
    int i_bg_pc;
119
    char *psz_text; /* for string of characters objects */
120

121 122
} dvbsub_objectdef_t;

Gildas Bazin's avatar
Gildas Bazin committed
123 124
/* The entry in the palette CLUT */
typedef struct
125
{
Gildas Bazin's avatar
Gildas Bazin committed
126 127 128 129
    uint8_t                 Y;
    uint8_t                 Cr;
    uint8_t                 Cb;
    uint8_t                 T;
130

Gildas Bazin's avatar
Gildas Bazin committed
131
} dvbsub_color_t;
132

Gildas Bazin's avatar
Gildas Bazin committed
133 134
/* */
typedef struct dvbsub_clut_s
135
{
Gildas Bazin's avatar
Gildas Bazin committed
136 137 138 139 140
    uint8_t                 i_id;
    uint8_t                 i_version;
    dvbsub_color_t          c_2b[4];
    dvbsub_color_t          c_4b[16];
    dvbsub_color_t          c_8b[256];
141

Gildas Bazin's avatar
Gildas Bazin committed
142 143 144
    struct dvbsub_clut_s    *p_next;

} 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 149
typedef struct dvbsub_region_s
{
Gildas Bazin's avatar
Gildas Bazin committed
150 151 152 153 154 155 156 157 158
    int i_id;
    int i_version;
    int i_x;
    int i_y;
    int i_width;
    int i_height;
    int i_level_comp;
    int i_depth;
    int i_clut;
159

Gildas Bazin's avatar
Gildas Bazin committed
160
    uint8_t *p_pixbuf;
161

Gildas Bazin's avatar
Gildas Bazin committed
162 163
    int                    i_object_defs;
    dvbsub_objectdef_t     *p_object_defs;
164

Gildas Bazin's avatar
Gildas Bazin committed
165
    struct dvbsub_region_s *p_next;
166

Gildas Bazin's avatar
Gildas Bazin committed
167
} dvbsub_region_t;
168

Gildas Bazin's avatar
Gildas Bazin committed
169 170
/* The object definition gives the position of the object in a region */
typedef struct dvbsub_regiondef_s
171
{
Gildas Bazin's avatar
Gildas Bazin committed
172 173 174
    int i_id;
    int i_x;
    int i_y;
175

Gildas Bazin's avatar
Gildas Bazin committed
176
} dvbsub_regiondef_t;
177

Gildas Bazin's avatar
Gildas Bazin committed
178
/* The page defines the list of regions */
179 180
typedef struct
{
Gildas Bazin's avatar
Gildas Bazin committed
181
    int i_id;
182
    int i_timeout; /* in seconds */
Gildas Bazin's avatar
Gildas Bazin committed
183 184
    int i_state;
    int i_version;
185

Gildas Bazin's avatar
Gildas Bazin committed
186 187 188 189
    int                i_region_defs;
    dvbsub_regiondef_t *p_region_defs;

} dvbsub_page_t;
190

191 192
struct decoder_sys_t
{
193 194 195
    bs_t            bs;

    /* Decoder internal data */
196 197 198
    int             i_id;
    int             i_ancillary_id;
    mtime_t         i_pts;
199

200 201 202 203
    vlc_bool_t      b_absolute;
    int             i_spu_position;
    int             i_spu_x;
    int             i_spu_y;
204

205
    vlc_bool_t      b_page;
206 207
    dvbsub_page_t   *p_page;
    dvbsub_region_t *p_regions;
Gildas Bazin's avatar
Gildas Bazin committed
208
    dvbsub_clut_t   *p_cluts;
209
    dvbsub_clut_t   default_clut;
210 211 212
};


213 214
/* List of different SEGMENT TYPES */
/* According to EN 300-743, table 2 */
215 216 217 218 219 220
#define DVBSUB_ST_PAGE_COMPOSITION      0x10
#define DVBSUB_ST_REGION_COMPOSITION    0x11
#define DVBSUB_ST_CLUT_DEFINITION       0x12
#define DVBSUB_ST_OBJECT_DATA           0x13
#define DVBSUB_ST_ENDOFDISPLAY          0x80
#define DVBSUB_ST_STUFFING              0xff
221 222
/* List of different OBJECT TYPES */
/* According to EN 300-743, table 6 */
223 224 225
#define DVBSUB_OT_BASIC_BITMAP          0x00
#define DVBSUB_OT_BASIC_CHAR            0x01
#define DVBSUB_OT_COMPOSITE_STRING      0x02
226
/* Pixel DATA TYPES */
227
/* According to EN 300-743, table 9 */ 
228 229 230 231 232 233 234
#define DVBSUB_DT_2BP_CODE_STRING       0x10
#define DVBSUB_DT_4BP_CODE_STRING       0x11
#define DVBSUB_DT_8BP_CODE_STRING       0x12
#define DVBSUB_DT_24_TABLE_DATA         0x20
#define DVBSUB_DT_28_TABLE_DATA         0x21
#define DVBSUB_DT_48_TABLE_DATA         0x22
#define DVBSUB_DT_END_LINE              0xf0
235 236
/* List of different Page Composition Segment state */
/* 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 242

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
243 244 245 246 247 248
static void decode_segment( decoder_t *, bs_t * );
static void decode_page_composition( decoder_t *, bs_t * );
static void decode_region_composition( decoder_t *, bs_t * );
static void decode_object( decoder_t *, bs_t * );
static void decode_clut( decoder_t *, bs_t * );
static void free_all( decoder_t * );
249

250
static void default_clut_init( decoder_t * );
251

Gildas Bazin's avatar
Gildas Bazin committed
252 253
static subpicture_t *render( decoder_t * );

254
/*****************************************************************************
255
 * Open: probe the decoder and return score
256 257 258 259
 *****************************************************************************
 * Tries to launch a decoder and return score so that the interface is able
 * to chose.
 *****************************************************************************/
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

Gildas Bazin's avatar
 
Gildas Bazin committed
267
    if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','v','b','s') )
268 269 270
    {
        return VLC_EGENERIC;
    }
271

272
    p_dec->pf_decode_sub = Decode;
273
    p_sys = p_dec->p_sys = malloc( sizeof(decoder_sys_t) );
Gildas Bazin's avatar
Gildas Bazin committed
274
    memset( p_sys, 0, sizeof(decoder_sys_t) );
275

276
    p_sys->i_pts          = (mtime_t) 0;    
277 278
    p_sys->i_id           = p_dec->fmt_in.subs.dvb.i_id & 0xFFFF;
    p_sys->i_ancillary_id = p_dec->fmt_in.subs.dvb.i_id >> 16;
279

280
    p_sys->p_regions      = NULL;
Gildas Bazin's avatar
Gildas Bazin committed
281 282
    p_sys->p_cluts        = NULL;
    p_sys->p_page         = NULL;
283

284 285
    var_Create( p_this, DVBSUB_CFG_PREFIX "position",
                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
286 287
    var_Get( p_this, DVBSUB_CFG_PREFIX "position", &val );
    p_sys->i_spu_position = val.i_int;
288 289
    var_Create( p_this, DVBSUB_CFG_PREFIX "x",
                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
290
    var_Get( p_this, DVBSUB_CFG_PREFIX "x", &val );
291 292 293
    i_posx = val.i_int;
    var_Create( p_this, DVBSUB_CFG_PREFIX "y",
                VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
294
    var_Get( p_this, DVBSUB_CFG_PREFIX "y", &val );
295
    i_posy = val.i_int;
296

297 298
    /* Check if subpicture position was overridden */
    p_sys->b_absolute = VLC_TRUE;
299 300 301
    p_sys->i_spu_x = p_sys->i_spu_y = 0;

    if( i_posx >= 0 && i_posy >= 0 )
302 303
    {
        p_sys->b_absolute = VLC_FALSE;
304 305
        p_sys->i_spu_x = i_posx;
        p_sys->i_spu_y = i_posy;
306
    }
307

308 309
    es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'd','v','b','s' ) );

310 311
    default_clut_init( p_dec );

312 313
    return VLC_SUCCESS;
}
314 315 316 317 318 319 320 321 322

/*****************************************************************************
 * Close:
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    decoder_t     *p_dec = (decoder_t*) p_this;
    decoder_sys_t *p_sys = p_dec->p_sys;

323 324
    var_Destroy( p_this, DVBSUB_CFG_PREFIX "x" );
    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 337
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t       *p_block;
338
    subpicture_t  *p_spu = NULL;
339

340
    if( pp_block == NULL || *pp_block == NULL ) return NULL;
341 342 343
    p_block = *pp_block;
    *pp_block = NULL;

344 345
    p_sys->i_pts = p_block->i_pts;
    if( p_sys->i_pts <= 0 )
346
    {
Gildas Bazin's avatar
Gildas Bazin committed
347 348 349
#ifdef DEBUG_DVBSUB
        /* Some DVB channels send stuffing segments in non-dated packets so
         * don't complain too loudly. */
350
        msg_Warn( p_dec, "non dated subtitle" );
Gildas Bazin's avatar
Gildas Bazin committed
351
#endif
352
        block_Release( p_block );
353
        return NULL;
354 355
    }

356 357 358
    bs_init( &p_sys->bs, p_block->p_buffer, p_block->i_buffer );

    if( bs_read( &p_sys->bs, 8 ) != 0x20 ) /* Data identifier */
359
    {
360 361
        msg_Dbg( p_dec, "invalid data identifier" );
        block_Release( p_block );
362
        return NULL;
363
    }
364

Gildas Bazin's avatar
Gildas Bazin committed
365
    if( bs_read( &p_sys->bs, 8 ) ) /* Subtitle stream id */
366 367 368
    {
        msg_Dbg( p_dec, "invalid subtitle stream id" );
        block_Release( p_block );
369
        return NULL;
370
    }
371

Gildas Bazin's avatar
Gildas Bazin committed
372 373 374 375
#ifdef DEBUG_DVBSUB
    msg_Dbg( p_dec, "subtitle packet received: "I64Fd, p_sys->i_pts );
#endif

376
    p_sys->b_page = VLC_FALSE;
377 378 379 380
    while( bs_show( &p_sys->bs, 8 ) == 0x0f ) /* Sync byte */
    {
        decode_segment( p_dec, &p_sys->bs );
    }
381

382 383 384 385
    if( bs_read( &p_sys->bs, 8 ) != 0xff ) /* End marker */
    {
        msg_Warn( p_dec, "end marker not found (corrupted subtitle ?)" );
        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 405
    decoder_sys_t *p_sys = p_dec->p_sys;
    uint8_t i;
406

407 408 409
#define RGB_TO_Y(r, g, b) ((int16_t) 77 * r + 150 * g + 29 * b) / 256;
#define RGB_TO_U(r, g, b) ((int16_t) -44 * r - 87 * g + 131 * b) / 256;
#define RGB_TO_V(r, g, b) ((int16_t) 131 * r - 110 * g - 21 * b) / 256;
410

411 412 413 414
    /* 4 entries CLUT */
    for( i = 0; i < 4; i++ )
    {
        uint8_t R = 0, G = 0, B = 0, T = 0;
415

416 417 418 419
        if( !(i & 0x2) && !(i & 0x1) ) T = 0xFF;
        else if( !(i & 0x2) && (i & 0x1) ) R = G = B = 0xFF;
        else if( (i & 0x2) && !(i & 0x1) ) R = G = B = 0;
        else R = G = B = 0x7F;
420

421 422
        p_sys->default_clut.c_2b[i].Y = RGB_TO_Y(R,G,B);
        p_sys->default_clut.c_2b[i].Cb = RGB_TO_V(R,G,B);
423
        p_sys->default_clut.c_2b[i].Cr = RGB_TO_U(R,G,B);
424
        p_sys->default_clut.c_2b[i].T = T;
425
    }
426 427

    /* 16 entries CLUT */
428 429
    for( i = 0; i < 16; i++ )
    {
430
        uint8_t R = 0, G = 0, B = 0, T = 0;
431

432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
        if( !(i & 0x8) )
        {
            if( !(i & 0x4) && !(i & 0x2) && !(i & 0x1) )
            {
                T = 0xFF;
            }
            else
            {
                R = (i & 0x1) ? 0xFF : 0;
                G = (i & 0x2) ? 0xFF : 0;
                B = (i & 0x4) ? 0xFF : 0;
            }
        }
        else
        {
            R = (i & 0x1) ? 0x7F : 0;
            G = (i & 0x2) ? 0x7F : 0;
            B = (i & 0x4) ? 0x7F : 0;
        }
451

452
        p_sys->default_clut.c_4b[i].Y = RGB_TO_Y(R,G,B);
453 454
        p_sys->default_clut.c_4b[i].Cr = RGB_TO_V(R,G,B);
        p_sys->default_clut.c_4b[i].Cb = RGB_TO_U(R,G,B);
455 456
        p_sys->default_clut.c_4b[i].T = T;
    }
457

458
    /* 256 entries CLUT */
459 460
    memset( p_sys->default_clut.c_8b, 0xFF, 256 * sizeof(dvbsub_color_t) );
}
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 466 467 468
    int i_type;
    int i_page_id;
    int i_size;

469
    /* sync_byte (already checked) */
470 471 472 473 474 475 476 477 478 479 480
    bs_skip( s, 8 );

    /* segment type */
    i_type = bs_read( s, 8 );

    /* page id */
    i_page_id = bs_read( s, 16 );

    /* segment size */
    i_size = bs_show( s, 16 );

481
    if( i_page_id != p_sys->i_id && i_page_id != p_sys->i_ancillary_id )
482
    {
483
#ifdef DEBUG_DVBSUB
484 485
        msg_Dbg( p_dec, "subtitle skipped (page id: %i, %i)",
                 i_page_id, p_sys->i_id );
486
#endif
487
        bs_skip( s,  8 * ( 2 + i_size ) );
488 489
        return;
    }
490

491 492 493 494 495 496 497 498 499 500 501
    if( p_sys->i_ancillary_id != p_sys->i_id &&
        i_type == DVBSUB_ST_PAGE_COMPOSITION &&
        i_page_id == p_sys->i_ancillary_id )
    {
#ifdef DEBUG_DVBSUB
        msg_Dbg( p_dec, "skipped invalid ancillary subtitle packet" );
#endif
        bs_skip( s,  8 * ( 2 + i_size ) );
        return;
    }

502 503 504 505 506 507 508
#ifdef DEBUG_DVBSUB
    if( i_page_id == p_sys->i_id )
        msg_Dbg( p_dec, "segment (id: %i)", i_page_id );
    else
        msg_Dbg( p_dec, "ancillary segment (id: %i)", i_page_id );
#endif

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 533
    case DVBSUB_ST_OBJECT_DATA:
#ifdef DEBUG_DVBSUB
534
        msg_Dbg( p_dec, "decode_object" );
535
#endif
536
        decode_object( p_dec, s );
537
        break;
538

539 540
    case DVBSUB_ST_ENDOFDISPLAY:
#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 548 549 550 551 552
#ifdef DEBUG_DVBSUB
        msg_Dbg( p_dec, "skip stuffing" );
#endif
        bs_skip( s,  8 * ( 2 + i_size ) );
        break;

553 554 555 556
    default:
        msg_Warn( p_dec, "unsupported segment type: (%04x)", i_type );
        bs_skip( s,  8 * ( 2 + i_size ) );
        break;
557 558 559
    }
}

560
static void decode_clut( decoder_t *p_dec, bs_t *s )
561
{
562 563 564
    decoder_sys_t *p_sys = p_dec->p_sys;
    uint16_t      i_segment_length;
    uint16_t      i_processed_length;
565
    dvbsub_clut_t *p_clut, *p_next;
Gildas Bazin's avatar
Gildas Bazin committed
566
    int           i_id, i_version;
567 568

    i_segment_length = bs_read( s, 16 );
Gildas Bazin's avatar
Gildas Bazin committed
569 570
    i_id             = bs_read( s, 8 );
    i_version        = bs_read( s, 4 );
571

Gildas Bazin's avatar
Gildas Bazin committed
572 573 574 575 576 577 578 579
    /* Check if we already have this clut */
    for( p_clut = p_sys->p_cluts; p_clut != NULL; p_clut = p_clut->p_next )
    {
        if( p_clut->i_id == i_id ) break;
    }

    /* Check version number */
    if( p_clut && p_clut->i_version == i_version )
580
    {
581
        /* Nothing to do */
Gildas Bazin's avatar
Gildas Bazin committed
582
        bs_skip( s, 8 * i_segment_length - 12 );
583
        return;
584
    }
585

Gildas Bazin's avatar
Gildas Bazin committed
586
    if( !p_clut )
587
    {
Gildas Bazin's avatar
Gildas Bazin committed
588 589 590 591 592 593
#ifdef DEBUG_DVBSUB
        msg_Dbg( p_dec, "new clut: %i", i_id );
#endif
        p_clut = malloc( sizeof(dvbsub_clut_t) );
        p_clut->p_next = p_sys->p_cluts;
        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 */
Gildas Bazin's avatar
Gildas Bazin committed
602 603
    p_clut->i_version = i_version;
    p_clut->i_id = i_id;
604 605 606
    bs_skip( s, 4 ); /* Reserved bits */
    i_processed_length = 2;
    while( i_processed_length < i_segment_length )
607
    {
608 609 610 611 612 613 614 615 616 617
        uint8_t y, cb, cr, t;
        uint8_t i_id;
        uint8_t i_type;

        i_id = bs_read( s, 8 );
        i_type = bs_read( s, 3 );

        bs_skip( s, 4 );

        if( bs_read( s, 1 ) )
618
        {
619 620 621 622 623
            y  = bs_read( s, 8 );
            cr = bs_read( s, 8 );
            cb = bs_read( s, 8 );
            t  = bs_read( s, 8 );
            i_processed_length += 6;
624 625 626
        }
        else
        {
Gildas Bazin's avatar
Gildas Bazin committed
627 628 629 630
            y  = bs_read( s, 6 ) << 2;
            cr = bs_read( s, 4 ) << 4;
            cb = bs_read( s, 4 ) << 4;
            t  = bs_read( s, 2 ) << 6;
631 632 633
            i_processed_length += 4;
        }

Gildas Bazin's avatar
Gildas Bazin committed
634 635 636 637 638 639 640 641 642
        /* We are not entirely compliant here as full transparency is indicated
         * with a luma value of zero, not a transparency value of 0xff
         * (full transparency would actually be 0xff + 1). */
        if( y == 0 )
        {
            cr = cb = 0;
            t  = 0xff;
        }

643
        /* According to EN 300-743 section 7.2.3 note 1, type should
Gildas Bazin's avatar
Gildas Bazin committed
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 649 650 651
            p_clut->c_2b[i_id].Y = y;
            p_clut->c_2b[i_id].Cr = cr;
            p_clut->c_2b[i_id].Cb = cb;
            p_clut->c_2b[i_id].T = t;
652
        }
653
        if( i_type & 0x02 && i_id < 16 )
654
        {
655 656 657 658
            p_clut->c_4b[i_id].Y = y;
            p_clut->c_4b[i_id].Cr = cr;
            p_clut->c_4b[i_id].Cb = cb;
            p_clut->c_4b[i_id].T = t;
659
        }
660
        if( i_type & 0x01 )
661
        {
662 663 664 665
            p_clut->c_8b[i_id].Y = y;
            p_clut->c_8b[i_id].Cr = cr;
            p_clut->c_8b[i_id].Cb = cb;
            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;
Gildas Bazin's avatar
Gildas Bazin committed
673
    int i_version, i_state, i_segment_length, i_timeout, i;
674

Gildas Bazin's avatar
Gildas Bazin committed
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 );
Gildas Bazin's avatar
Gildas Bazin committed
678
    i_version = bs_read( s, 4 );
679
    i_state = bs_read( s, 2 );
680 681
    bs_skip( s, 2 ); /* Reserved */

682 683 684 685 686 687 688 689
    if( i_state == DVBSUB_PCS_STATE_CHANGE )
    {
        /* End of an epoch, reset decoder buffer */
#ifdef DEBUG_DVBSUB
        msg_Dbg( p_dec, "page composition mode change" );
#endif
        free_all( p_dec );
    }
690 691
    else if( !p_sys->p_page && i_state != DVBSUB_PCS_STATE_ACQUISITION &&
             i_state != DVBSUB_PCS_STATE_CHANGE )
692 693
    {
        /* Not a full PCS, we need to wait for one */
Gildas Bazin's avatar
Gildas Bazin committed
694
        msg_Dbg( p_dec, "didn't receive an acquisition page yet" );
695

696 697
#if 0
        /* Try to start decoding even without an acquisition page */
698
        bs_skip( s,  8 * (i_segment_length - 2) );
699
        return;
Gildas Bazin's avatar
Gildas Bazin committed
700
#endif
701 702
    }

Gildas Bazin's avatar
Gildas Bazin committed
703
#ifdef DEBUG_DVBSUB
Gildas Bazin's avatar
Gildas Bazin committed
704
    if( i_state == DVBSUB_PCS_STATE_ACQUISITION )
Gildas Bazin's avatar
Gildas Bazin committed
705 706
        msg_Dbg( p_dec, "acquisition page composition" );
#endif
707

708
    /* Check version number */
Gildas Bazin's avatar
Gildas Bazin committed
709
    if( p_sys->p_page && p_sys->p_page->i_version == i_version )
710 711 712 713 714 715 716 717 718 719
    {
        bs_skip( s,  8 * (i_segment_length - 2) );
        return;
    }
    else if( p_sys->p_page )
    {
        if( p_sys->p_page->i_region_defs )
            free( p_sys->p_page->p_region_defs );
        p_sys->p_page->i_region_defs = 0;
    }
720

721
    if( !p_sys->p_page )
722
    {
Gildas Bazin's avatar
Gildas Bazin committed
723 724 725
#ifdef DEBUG_DVBSUB
        msg_Dbg( p_dec, "new page" );
#endif
726 727
        /* Allocate a new page */
        p_sys->p_page = malloc( sizeof(dvbsub_page_t) );
728 729
    }

Gildas Bazin's avatar
Gildas Bazin committed
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 735 736 737 738 739 740 741

    /* Number of regions */
    p_sys->p_page->i_region_defs = (i_segment_length - 2) / 6;

    if( p_sys->p_page->i_region_defs == 0 ) return;

    p_sys->p_page->p_region_defs =
        malloc( p_sys->p_page->i_region_defs * sizeof(dvbsub_region_t) );
    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 746 747 748 749 750 751 752
        p_sys->p_page->p_region_defs[i].i_x = bs_read( s, 16 );
        p_sys->p_page->p_region_defs[i].i_y = bs_read( s, 16 );

#ifdef DEBUG_DVBSUB
        msg_Dbg( p_dec, "page_composition, region %i (%i,%i)",
                 i, p_sys->p_page->p_region_defs[i].i_x,
                 p_sys->p_page->p_region_defs[i].i_y );
#endif
753 754 755
    }
}

756
static void decode_region_composition( decoder_t *p_dec, bs_t *s )
757
{
758 759
    decoder_sys_t *p_sys = p_dec->p_sys;
    dvbsub_region_t *p_region, **pp_region = &p_sys->p_regions;
Gildas Bazin's avatar
Gildas Bazin committed
760 761 762 763
    int i_segment_length, i_processed_length, i_id, i_version;
    int i_width, i_height, i_level_comp, i_depth, i_clut;
    int i_8_bg, i_4_bg, i_2_bg;
    vlc_bool_t b_fill;
764 765

    i_segment_length = bs_read( s, 16 );
Gildas Bazin's avatar
Gildas Bazin committed
766 767
    i_id = bs_read( s, 8 );
    i_version = bs_read( s, 4 );
768 769 770 771

    /* Check if we already have this region */
    for( p_region = p_sys->p_regions; p_region != NULL;
         p_region = p_region->p_next )
772
    {
773
        pp_region = &p_region->p_next;
Gildas Bazin's avatar
Gildas Bazin committed
774
        if( p_region->i_id == i_id ) break;
775 776
    }

777
    /* Check version number */
Gildas Bazin's avatar
Gildas Bazin committed
778
    if( p_region && p_region->i_version == i_version )
779
    {
Gildas Bazin's avatar
Gildas Bazin committed
780
        bs_skip( s, 8 * (i_segment_length - 1) - 4 );
781
        return;
782
    }
783

784
    if( !p_region )
785
    {
786
#ifdef DEBUG_DVBSUB
Gildas Bazin's avatar
Gildas Bazin committed
787
        msg_Dbg( p_dec, "new region: %i", i_id );
788 789
#endif
        p_region = *pp_region = malloc( sizeof(dvbsub_region_t) );
Gildas Bazin's avatar
Gildas Bazin committed
790 791 792
        memset( p_region, 0, sizeof(dvbsub_region_t) );
        p_region->p_object_defs = NULL;
        p_region->p_pixbuf = NULL;
793
        p_region->p_next = NULL;
794
    }
795 796

    /* Region attributes */
Gildas Bazin's avatar
Gildas Bazin committed
797 798 799
    p_region->i_id = i_id;
    p_region->i_version = i_version;
    b_fill = bs_read( s, 1 );
800
    bs_skip( s, 3 ); /* Reserved */
Gildas Bazin's avatar
Gildas Bazin committed
801 802 803

    i_width = bs_read( s, 16 );
    i_height = bs_read( s, 16 );
804 805 806
#ifdef DEBUG_DVBSUB
    msg_Dbg( p_dec, " width=%d height=%d", i_width, i_height );
#endif
Gildas Bazin's avatar
Gildas Bazin committed
807 808
    i_level_comp = bs_read( s, 3 );
    i_depth = bs_read( s, 3 );
809
    bs_skip( s, 2 ); /* Reserved */
Gildas Bazin's avatar
Gildas Bazin committed
810 811 812 813 814
    i_clut = bs_read( s, 8 );

    i_8_bg = bs_read( s, 8 );
    i_4_bg = bs_read( s, 4 );
    i_2_bg = bs_read( s, 2 );
815
    bs_skip( s, 2 ); /* Reserved */
816 817 818 819 820 821 822 823