dvbsub.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:54k
源码类别:

多媒体

开发平台:

MultiPlatform

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