]> git.sesse.net Git - vlc/blob - modules/codec/svcdsub.c
* modules/codec/svcdsub.c,cvdsub.c: fixed Cr/Cb inversion in palette.
[vlc] / modules / codec / svcdsub.c
1 /*****************************************************************************
2  * svcdsub.c : Overlay Graphics Text (SVCD subtitles) decoder
3  *****************************************************************************
4  * Copyright (C) 2003, 2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Rocky Bernstein
8  *          Gildas Bazin <gbazin@videolan.org>
9  *          Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
10  *          Laurent Aimar <fenrir@via.ecp.fr>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
25  *****************************************************************************/
26
27 #define DEBUG_SVCD 1
28
29 /*****************************************************************************
30  * Preamble
31  *****************************************************************************/
32 #include <vlc/vlc.h>
33 #include <vlc/decoder.h>
34
35 #include "vlc_bits.h"
36
37 /*****************************************************************************
38  * Module descriptor.
39  *****************************************************************************/
40 static int  DecoderOpen   ( vlc_object_t * );
41 static int  PacketizerOpen( vlc_object_t * );
42 static void DecoderClose  ( vlc_object_t * );
43
44 vlc_module_begin();
45     set_description( _("Philips OGT (SVCD subtitle) decoder") );
46     set_capability( "decoder", 50 );
47     set_callbacks( DecoderOpen, DecoderClose );
48
49     add_submodule();
50     set_description( _("Philips OGT (SVCD subtitle) packetizer") );
51     set_capability( "packetizer", 50 );
52     set_callbacks( PacketizerOpen, DecoderClose );
53 vlc_module_end();
54
55 /*****************************************************************************
56  * Local prototypes
57  *****************************************************************************/
58 static subpicture_t *Decode( decoder_t *, block_t ** );
59 static block_t *Packetize  ( decoder_t *, block_t ** );
60 static block_t *Reassemble ( decoder_t *, block_t * );
61 static void ParseHeader( decoder_t *, block_t * );
62 static subpicture_t *DecodePacket( decoder_t *, block_t * );
63 static void RenderImage( decoder_t *, block_t *, subpicture_region_t * );
64
65 #define GETINT16(p) ( (p[0] <<  8) +   p[1] )  ; p +=2;
66
67 #define GETINT32(p) ( (p[0] << 24) +  (p[1] << 16) +    \
68                       (p[2] <<  8) +  (p[3]) ) ; p += 4;
69
70 #define SUBTITLE_BLOCK_EMPTY 0
71 #define SUBTITLE_BLOCK_PARTIAL 1
72 #define SUBTITLE_BLOCK_COMPLETE 2
73
74 struct decoder_sys_t
75 {
76   int      b_packetizer;
77
78   int      i_state;    /* data-gathering state for this subtitle */
79
80   block_t  *p_spu;   /* Bytes of the packet. */
81
82   uint16_t i_image;  /* image number in the subtitle stream */
83   uint8_t  i_packet; /* packet number for above image number */
84
85   int     i_spu_size;     /* goal for subtitle_data_pos while gathering,
86                              size of used subtitle_data later */
87
88   uint16_t i_image_offset;      /* offset from subtitle_data to compressed
89                                    image data */
90   int i_image_length;           /* size of the compressed image data */
91   int second_field_offset;      /* offset of odd raster lines */
92   int metadata_offset;          /* offset to data describing the image */
93   int metadata_length;          /* length of metadata */
94
95   mtime_t i_duration;   /* how long to display the image, 0 stands
96                            for "until next subtitle" */
97
98   uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
99                                     image when displayed */
100   uint16_t i_width, i_height;    /* dimensions in pixels of image */
101
102   uint8_t p_palette[4][4];       /* Palette of colors used in subtitle */
103 };
104
105 /*****************************************************************************
106  * DecoderOpen: open/initialize the svcdsub decoder.
107  *****************************************************************************/
108 static int DecoderOpen( vlc_object_t *p_this )
109 {
110     decoder_t     *p_dec = (decoder_t*)p_this;
111     decoder_sys_t *p_sys;
112
113     if( p_dec->fmt_in.i_codec != VLC_FOURCC( 'o','g','t',' ' ) )
114     {
115         return VLC_EGENERIC;
116     }
117
118     p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
119
120     p_sys->b_packetizer  = VLC_FALSE;
121     p_sys->i_image       = -1;
122
123     p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
124     p_sys->p_spu   = NULL;
125
126     es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_FOURCC( 'o','g','t',' ' ) );
127
128     p_dec->pf_decode_sub = Decode;
129     p_dec->pf_packetize  = Packetize;
130
131     return VLC_SUCCESS;
132 }
133
134 /*****************************************************************************
135  * PacketizerOpen: open/initialize the svcdsub packetizer.
136  *****************************************************************************/
137 static int PacketizerOpen( vlc_object_t *p_this )
138 {
139     decoder_t *p_dec = (decoder_t*)p_this;
140
141     if( DecoderOpen( p_this ) != VLC_SUCCESS ) return VLC_EGENERIC;
142
143     p_dec->p_sys->b_packetizer = VLC_TRUE;
144
145     return VLC_SUCCESS;
146 }
147
148 /*****************************************************************************
149  * DecoderClose: closes the svcdsub decoder/packetizer.
150  *****************************************************************************/
151 void DecoderClose( vlc_object_t *p_this )
152 {
153     decoder_t     *p_dec = (decoder_t*)p_this;
154     decoder_sys_t *p_sys = p_dec->p_sys;
155
156     if( p_sys->p_spu ) block_ChainRelease( p_sys->p_spu );
157     free( p_sys );
158 }
159
160 /*****************************************************************************
161  * Decode:
162  *****************************************************************************/
163 static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
164 {
165     block_t *p_block, *p_spu;
166
167     if( pp_block == NULL || *pp_block == NULL ) return NULL;
168
169     p_block = *pp_block;
170     *pp_block = NULL;
171
172     if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
173
174     /* Parse and decode */
175     return DecodePacket( p_dec, p_spu );
176 }
177
178 /*****************************************************************************
179  * Packetize:
180  *****************************************************************************/
181 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
182 {
183     block_t *p_block, *p_spu;
184
185     if( pp_block == NULL || *pp_block == NULL ) return NULL;
186
187     p_block = *pp_block;
188     *pp_block = NULL;
189
190     if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
191
192     p_spu->i_dts = p_spu->i_pts;
193     p_spu->i_length = 0;
194
195     return p_spu;
196 }
197
198 /*****************************************************************************
199  Reassemble:
200
201  The data for single screen subtitle may come in one of many
202  non-contiguous packets of a stream. This routine is called when the
203  next packet in the stream comes in. The job of this routine is to
204  parse the header, if this is the beginning, and combine the packets
205  into one complete subtitle unit.
206
207  If everything is complete, we will return a block. Otherwise return
208  NULL.
209
210
211  The format of the beginning of the subtitle packet that is used here.
212
213    size    description
214    -------------------------------------------
215    byte    subtitle channel (0..7) in bits 0-3
216    byte    subtitle packet number of this subtitle image 0-N,
217            if the subtitle packet is complete, the top bit of the byte is 1.
218    uint16  subtitle image number
219
220  *****************************************************************************/
221 #define SPU_HEADER_LEN 5
222
223 static block_t *Reassemble( decoder_t *p_dec, block_t *p_block )
224 {
225     decoder_sys_t *p_sys = p_dec->p_sys;
226     uint8_t *p_buffer;
227     uint16_t i_expected_image;
228     uint8_t  i_packet, i_expected_packet;
229
230     if( p_block->i_buffer < SPU_HEADER_LEN )
231     {
232         msg_Dbg( p_dec, "invalid packet header (size %d < %d)" ,
233                  p_block->i_buffer, SPU_HEADER_LEN );
234         block_Release( p_block );
235         return NULL;
236     }
237
238     p_buffer = p_block->p_buffer;
239
240     if( p_sys->i_state == SUBTITLE_BLOCK_EMPTY )
241     {
242         i_expected_image  = p_sys->i_image + 1;
243         i_expected_packet = 0;
244     }
245     else
246     {
247         i_expected_image  = p_sys->i_image;
248         i_expected_packet = p_sys->i_packet + 1;
249     }
250
251     p_buffer += 2;
252
253     if( *p_buffer & 0x80 )
254     {
255         p_sys->i_state = SUBTITLE_BLOCK_COMPLETE;
256         i_packet       = *p_buffer++ & 0x7F;
257     }
258     else
259     {
260         p_sys->i_state = SUBTITLE_BLOCK_PARTIAL;
261         i_packet       = *p_buffer++;
262     }
263
264     p_sys->i_image = GETINT16(p_buffer);
265
266     if( p_sys->i_image != i_expected_image )
267     {
268         msg_Warn( p_dec, "expected subtitle image %u but found %u",
269                   i_expected_image, p_sys->i_image );
270     }
271
272     if( i_packet != i_expected_packet )
273     {
274         msg_Warn( p_dec, "expected subtitle image packet %u but found %u",
275                   i_expected_packet, i_packet );
276     }
277
278     p_block->p_buffer += SPU_HEADER_LEN;
279     p_block->i_buffer -= SPU_HEADER_LEN;
280
281     p_sys->i_packet = i_packet;
282     /* First packet in the subtitle block */
283     if( !p_sys->i_packet ) ParseHeader( p_dec, p_block );
284
285     block_ChainAppend( &p_sys->p_spu, p_block );
286
287     if( p_sys->i_state == SUBTITLE_BLOCK_COMPLETE )
288     {
289         block_t *p_spu = block_ChainGather( p_sys->p_spu );
290
291         if( p_spu->i_buffer != p_sys->i_spu_size )
292         {
293             msg_Warn( p_dec, "SPU packets size=%d should be %d",
294                       p_spu->i_buffer, p_sys->i_spu_size );
295         }
296
297         msg_Dbg( p_dec, "subtitle packet complete, size=%d", p_spu->i_buffer);
298
299         p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
300         p_sys->p_spu = 0;
301         return p_spu;
302     }
303
304     return NULL;
305 }
306
307 /******************************************************************************
308   The format is roughly as follows (everything is big-endian):
309  
310    size     description
311    -------------------------------------------
312    byte     subtitle channel (0..7) in bits 0-3 
313    byte     subtitle packet number of this subtitle image 0-N,
314             if the subtitle packet is complete, the top bit of the byte is 1.
315    u_int16  subtitle image number
316    u_int16  length in bytes of the rest
317    byte     option flags, unknown meaning except bit 3 (0x08) indicates
318             presence of the duration field
319    byte     unknown 
320    u_int32  duration in 1/90000ths of a second (optional), start time
321             is as indicated by the PTS in the PES header
322    u_int32  xpos
323    u_int32  ypos
324    u_int32  width (must be even)
325    u_int32  height (must be even)
326    byte[16] palette, 4 palette entries, each contains values for
327             Y, U, V and transparency, 0 standing for transparent
328    byte     command,
329             cmd>>6==1 indicates shift
330             (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)
331    u_int32  shift duration in 1/90000ths of a second
332    u_int16  offset of odd-numbered scanlines - subtitle images are 
333             given in interlace order
334    byte[]   limited RLE image data in interlace order (0,2,4... 1,3,5) with
335             2-bits per palette number
336 ******************************************************************************/
337 static void ParseHeader( decoder_t *p_dec, block_t *p_block )
338 {
339     decoder_sys_t *p_sys = p_dec->p_sys;
340     uint8_t *p = p_block->p_buffer;
341     uint8_t i_options, i_options2, i_cmd, i_cmd_arg;
342     int i;
343
344     p_sys->i_spu_size = GETINT16(p);
345     i_options  = *p++;
346     i_options2 = *p++;
347
348     if( i_options & 0x08 ) { p_sys->i_duration = GETINT32(p); }
349     else p_sys->i_duration = 0; /* Ephemer subtitle */
350     p_sys->i_duration *= 100 / 9;
351
352     p_sys->i_x_start = GETINT16(p);
353     p_sys->i_y_start = GETINT16(p);
354     p_sys->i_width   = GETINT16(p);
355     p_sys->i_height  = GETINT16(p);
356
357     for( i = 0; i < 4; i++ )
358     {
359         p_sys->p_palette[i][0] = *p++; /* Y */
360         p_sys->p_palette[i][2] = *p++; /* Cr / V */
361         p_sys->p_palette[i][1] = *p++; /* Cb / U */
362         p_sys->p_palette[i][3] = *p++; /* T */
363     }
364
365     i_cmd = *p++;
366     /* We do not really know this, FIXME */
367     if( i_cmd ) {i_cmd_arg = GETINT32(p);}
368
369     /* Actually, this is measured against a different origin, so we have to
370      * adjust it */
371     p_sys->second_field_offset = GETINT16(p);
372     p_sys->i_image_offset  = p - p_block->p_buffer;
373     p_sys->i_image_length  = p_sys->i_spu_size - p_sys->i_image_offset;
374     p_sys->metadata_length = p_sys->i_image_offset;
375
376 #ifdef DEBUG_SVCD
377     msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
378              "spu size: %d, duration: %lu (d:%d p:%d)",
379              p_sys->i_x_start, p_sys->i_y_start, 
380              p_sys->i_width, p_sys->i_height, 
381              p_sys->i_spu_size, (long unsigned int) p_sys->i_duration,
382              p_sys->i_image_length, p_sys->i_image_offset);
383
384     for( i = 0; i < 4; i++ )
385     {
386         msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
387                  p_sys->p_palette[i][3], p_sys->p_palette[i][0], 
388                  p_sys->p_palette[i][1], p_sys->p_palette[i][2] );
389     }
390 #endif
391 }
392
393 /*****************************************************************************
394  * DecodePacket: parse and decode an SPU packet
395  *****************************************************************************
396  * This function parses and decodes an SPU packet and, if valid, returns a
397  * subpicture.
398  *****************************************************************************/
399 static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
400 {
401     decoder_sys_t *p_sys = p_dec->p_sys;
402     subpicture_t  *p_spu;
403     subpicture_region_t *p_region;
404     video_format_t fmt;
405     int i;
406
407     /* Allocate the subpicture internal data. */
408     p_spu = p_dec->pf_spu_buffer_new( p_dec );
409     if( !p_spu ) return NULL;
410
411     p_spu->i_x = p_sys->i_x_start;
412     p_spu->i_x = p_spu->i_x * 3 / 4; /* FIXME: use aspect ratio for x? */
413     p_spu->i_y = p_sys->i_y_start;
414     p_spu->i_start = p_data->i_pts;
415     p_spu->i_stop  = p_data->i_pts + p_sys->i_duration;
416     p_spu->b_ephemer = VLC_TRUE;
417
418     /* Create new SPU region */
419     memset( &fmt, 0, sizeof(video_format_t) );
420     fmt.i_chroma = VLC_FOURCC('Y','U','V','P');
421     fmt.i_aspect = VOUT_ASPECT_FACTOR;
422     fmt.i_width = fmt.i_visible_width = p_sys->i_width;
423     fmt.i_height = fmt.i_visible_height = p_sys->i_height;
424     fmt.i_x_offset = fmt.i_y_offset = 0;
425     p_region = p_spu->pf_create_region( VLC_OBJECT(p_dec), &fmt );
426     if( !p_region )
427     {
428         msg_Err( p_dec, "cannot allocate SPU region" );
429         //goto error;
430     }
431
432     p_spu->p_region = p_region;
433     p_region->i_x = p_region->i_y = 0;
434
435     /* Build palette */
436     fmt.p_palette->i_entries = 4;
437     for( i = 0; i < fmt.p_palette->i_entries; i++ )
438     {
439         fmt.p_palette->palette[i][0] = p_sys->p_palette[i][0];
440         fmt.p_palette->palette[i][1] = p_sys->p_palette[i][1];
441         fmt.p_palette->palette[i][2] = p_sys->p_palette[i][2];
442         fmt.p_palette->palette[i][3] = p_sys->p_palette[i][3];
443     }
444
445     RenderImage( p_dec, p_data, p_region );
446
447     return p_spu;
448 }
449
450 /*****************************************************************************
451  * ParseImage: parse the image part of the subtitle
452  *****************************************************************************
453  This part parses the subtitle graphical data and renders it.
454
455  The image is encoded using two bits per pixel that select a palette
456  entry except that value 0 starts a limited run-length encoding for
457  color 0.  When 0 is seen, the next two bits encode one less than the
458  number of pixels, so we can encode run lengths from 1 to 4. These get
459  filled with the color in palette entry 0.
460
461  The encoding of each line is padded to a whole number of bytes.  The
462  first field is padded to an even byte length and the complete subtitle
463  is padded to a 4-byte multiple that always include one zero byte at
464  the end.
465
466  However we'll transform this so that that the RLE is expanded and
467  interlacing will also be removed.
468  *****************************************************************************/
469 static void RenderImage( decoder_t *p_dec, block_t *p_data,
470                          subpicture_region_t *p_region )
471 {
472     decoder_sys_t *p_sys = p_dec->p_sys;
473     uint8_t *p_dest = p_region->picture.Y_PIXELS;
474     int i_field;            /* The subtitles are interlaced */
475     int i_row, i_column;    /* scanline row/column number */
476     uint8_t i_color, i_count;
477     bs_t bs;
478
479     bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset,
480              p_data->i_buffer - p_sys->i_image_offset );
481
482     for( i_field = 0; i_field < 2; i_field++ )
483     {
484         for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 )
485         {
486             for( i_column = 0; i_column < p_sys->i_width; i_column++ )
487             {
488                 i_color = bs_read( &bs, 2 );
489                 if( i_color == 0 && (i_count = bs_read( &bs, 2 )) )
490                 {
491                     i_count = __MIN( i_count, p_sys->i_width - i_column );
492                     memset( &p_dest[i_row * p_region->picture.Y_PITCH +
493                                     i_column], 0, i_count + 1 );
494                     i_column += i_count;
495                     continue;
496                 }
497
498                 p_dest[i_row * p_region->picture.Y_PITCH + i_column] = i_color;
499             }
500
501             bs_align( &bs );
502         }
503
504         /* odd field */
505         bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset +
506                  p_sys->second_field_offset,
507                  p_data->i_buffer - p_sys->i_image_offset -
508                  p_sys->second_field_offset );
509     }
510 }