]> git.sesse.net Git - vlc/blob - modules/codec/svcdsub.c
Merge branch 1.0-bugfix
[vlc] / modules / codec / svcdsub.c
1 /*****************************************************************************
2  * svcdsub.c : Overlay Graphics Text (SVCD subtitles) decoder
3  *****************************************************************************
4  * Copyright (C) 2003, 2004 the VideoLAN team
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  *****************************************************************************/
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_codec.h>
37 #include <vlc_osd.h>
38 #include "vlc_bits.h"
39
40 /*****************************************************************************
41  * Module descriptor.
42  *****************************************************************************/
43 static int  DecoderOpen   ( vlc_object_t * );
44 static int  PacketizerOpen( vlc_object_t * );
45 static void DecoderClose  ( vlc_object_t * );
46
47 #define DEBUG_TEXT N_("Enable debug")
48
49 #define DEBUG_LONGTEXT  \
50     N_("This integer when viewed in binary is a debugging mask\n" \
51     "calls                 1\n" \
52     "packet assembly info  2\n" )
53
54 vlc_module_begin ()
55     set_description( N_("Philips OGT (SVCD subtitle) decoder") )
56     set_shortname( N_("SVCD subtitles") )
57     set_category( CAT_INPUT )
58     set_subcategory( SUBCAT_INPUT_SCODEC )
59     set_capability( "decoder", 50 )
60     set_callbacks( DecoderOpen, DecoderClose )
61
62     add_integer ( MODULE_STRING "-debug", 0, NULL,
63                   DEBUG_TEXT, DEBUG_LONGTEXT, true )
64
65     add_submodule ()
66     set_description( N_("Philips OGT (SVCD subtitle) packetizer") )
67     set_capability( "packetizer", 50 )
68     set_callbacks( PacketizerOpen, DecoderClose )
69 vlc_module_end ()
70
71 /*****************************************************************************
72  * Local prototypes
73  *****************************************************************************/
74 static subpicture_t *Decode( decoder_t *, block_t ** );
75 static block_t *Packetize  ( decoder_t *, block_t ** );
76 static block_t *Reassemble ( decoder_t *, block_t * );
77 static void ParseHeader( decoder_t *, block_t * );
78 static subpicture_t *DecodePacket( decoder_t *, block_t * );
79 static void SVCDSubRenderImage( decoder_t *, block_t *, subpicture_region_t * );
80
81 #define DECODE_DBG_CALL        1 /* calls */
82 #define DECODE_DBG_PACKET      2 /* packet assembly info */
83
84 #define GETINT16(p) ( (p[0] <<  8) +   p[1] )  ; p +=2;
85
86 #define GETINT32(p) ( (p[0] << 24) +  (p[1] << 16) +    \
87                       (p[2] <<  8) +  (p[3]) ) ; p += 4;
88
89 typedef enum  {
90   SUBTITLE_BLOCK_EMPTY    = 0,
91   SUBTITLE_BLOCK_PARTIAL  = 1,
92   SUBTITLE_BLOCK_COMPLETE = 2
93 } packet_state_t;
94
95 #ifndef DECODE_DEBUG
96 #define DECODE_DEBUG 1
97 #endif
98 #if DECODE_DEBUG
99 #define dbg_print(mask, s, args...) \
100    if (p_sys && p_sys->i_debug & mask) \
101      msg_Dbg(p_dec, "%s: "s, __func__ , ##args)
102 #else
103 #define dbg_print(mask, s, args...)
104 #endif
105
106 struct decoder_sys_t
107 {
108   int      i_debug;       /* debugging mask */
109
110   packet_state_t i_state; /* data-gathering state for this subtitle */
111
112   block_t  *p_spu;        /* Bytes of the packet. */
113
114   uint16_t i_image;       /* image number in the subtitle stream */
115   uint8_t  i_packet;      /* packet number for above image number */
116
117   size_t   i_spu_size;     /* goal for subtitle_data_pos while gathering,
118                              size of used subtitle_data later */
119
120   uint16_t i_image_offset;      /* offset from subtitle_data to compressed
121                                    image data */
122   size_t i_image_length;           /* size of the compressed image data */
123   size_t second_field_offset;      /* offset of odd raster lines */
124   size_t metadata_offset;          /* offset to data describing the image */
125   size_t metadata_length;          /* length of metadata */
126
127   mtime_t i_duration;   /* how long to display the image, 0 stands
128                            for "until next subtitle" */
129
130   uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
131                                     image when displayed */
132   uint16_t i_width, i_height;    /* dimensions in pixels of image */
133
134   uint8_t p_palette[4][4];       /* Palette of colors used in subtitle */
135 };
136
137 /*****************************************************************************
138  * DecoderOpen: open/initialize the svcdsub decoder.
139  *****************************************************************************/
140 static int DecoderOpen( vlc_object_t *p_this )
141 {
142     decoder_t     *p_dec = (decoder_t*)p_this;
143     decoder_sys_t *p_sys;
144
145     if( p_dec->fmt_in.i_codec != VLC_CODEC_OGT )
146         return VLC_EGENERIC;
147
148     p_dec->p_sys = p_sys = calloc( 1, sizeof( decoder_sys_t ) );
149     if( p_sys == NULL )
150         return VLC_ENOMEM;
151
152     p_sys->i_debug       = config_GetInt( p_this, MODULE_STRING "-debug" );
153
154     p_sys->i_image       = -1;
155
156     p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
157     p_sys->p_spu   = NULL;
158
159     es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_CODEC_OGT );
160
161     p_dec->pf_decode_sub = Decode;
162     p_dec->pf_packetize  = Packetize;
163
164     dbg_print( (DECODE_DBG_CALL) , "");
165     return VLC_SUCCESS;
166 }
167
168 /*****************************************************************************
169  * PacketizerOpen: open/initialize the svcdsub packetizer.
170  *****************************************************************************/
171 static int PacketizerOpen( vlc_object_t *p_this )
172 {
173     if( DecoderOpen( p_this ) != VLC_SUCCESS ) return VLC_EGENERIC;
174
175     return VLC_SUCCESS;
176 }
177
178 /*****************************************************************************
179  * DecoderClose: closes the svcdsub decoder/packetizer.
180  *****************************************************************************/
181 void DecoderClose( vlc_object_t *p_this )
182 {
183     decoder_t     *p_dec = (decoder_t*)p_this;
184     decoder_sys_t *p_sys = p_dec->p_sys;
185
186     if( p_sys->p_spu ) block_ChainRelease( p_sys->p_spu );
187     free( p_sys );
188 }
189
190 /*****************************************************************************
191  * Decode:
192  *****************************************************************************/
193 static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
194 {
195     block_t *p_block, *p_spu;
196     decoder_sys_t *p_sys = p_dec->p_sys;
197
198     dbg_print( (DECODE_DBG_CALL) , "");
199
200     if( pp_block == NULL || *pp_block == NULL ) return NULL;
201
202     p_block = *pp_block;
203     *pp_block = NULL;
204
205     if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
206
207     /* Parse and decode */
208     return DecodePacket( p_dec, p_spu );
209 }
210
211 /*****************************************************************************
212  * Packetize:
213  *****************************************************************************/
214 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
215 {
216     block_t *p_block, *p_spu;
217
218     if( pp_block == NULL || *pp_block == NULL ) return NULL;
219
220     p_block = *pp_block;
221     *pp_block = NULL;
222
223     if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
224
225     p_spu->i_dts = p_spu->i_pts;
226     p_spu->i_length = 0;
227
228     return p_spu;
229 }
230
231 /*****************************************************************************
232  Reassemble:
233
234  The data for single screen subtitle may come in one of many
235  non-contiguous packets of a stream. This routine is called when the
236  next packet in the stream comes in. The job of this routine is to
237  parse the header, if this is the beginning, and combine the packets
238  into one complete subtitle unit.
239
240  If everything is complete, we will return a block. Otherwise return
241  NULL.
242
243
244  The format of the beginning of the subtitle packet that is used here.
245
246    size    description
247    -------------------------------------------
248    byte    subtitle channel (0..7) in bits 0-3
249    byte    subtitle packet number of this subtitle image 0-N,
250            if the subtitle packet is complete, the top bit of the byte is 1.
251    uint16  subtitle image number
252
253  *****************************************************************************/
254 #define SPU_HEADER_LEN 5
255
256 static block_t *Reassemble( decoder_t *p_dec, block_t *p_block )
257 {
258     decoder_sys_t *p_sys = p_dec->p_sys;
259     uint8_t *p_buffer;
260     uint16_t i_expected_image;
261     uint8_t  i_packet, i_expected_packet;
262
263     if( p_block->i_buffer < SPU_HEADER_LEN )
264     {
265         msg_Dbg( p_dec, "invalid packet header (size %zu < %u)" ,
266                  p_block->i_buffer, SPU_HEADER_LEN );
267         block_Release( p_block );
268         return NULL;
269     }
270
271     p_buffer = p_block->p_buffer;
272
273     /* Attach to our input thread and see if subtitle is selected. */
274     {
275         vlc_object_t * p_input;
276         vlc_value_t val;
277
278         p_input = vlc_object_find( p_dec, VLC_OBJECT_INPUT, FIND_PARENT );
279
280         if( !p_input ) return NULL;
281
282         if( var_Get( p_input, "sub-track", &val ) )
283         {
284             vlc_object_release( p_input );
285             return NULL;
286         }
287
288         vlc_object_release( p_input );
289         dbg_print( (DECODE_DBG_PACKET),
290                    "val.i_int %x p_buffer[i] %x", val.i_int, p_buffer[1]);
291
292         /* The dummy ES that the menu selection uses has an 0x70 at
293            the head which we need to strip off. */
294         if( val.i_int == -1 || (val.i_int & 0x03) != p_buffer[1] )
295         {
296             dbg_print( DECODE_DBG_PACKET, "subtitle not for us.\n");
297             return NULL;
298         }
299     }
300
301     if( p_sys->i_state == SUBTITLE_BLOCK_EMPTY )
302     {
303         i_expected_image  = p_sys->i_image + 1;
304         i_expected_packet = 0;
305     }
306     else
307     {
308         i_expected_image  = p_sys->i_image;
309         i_expected_packet = p_sys->i_packet + 1;
310     }
311
312     p_buffer += 2;
313
314     if( *p_buffer & 0x80 )
315     {
316         p_sys->i_state = SUBTITLE_BLOCK_COMPLETE;
317         i_packet       = *p_buffer++ & 0x7F;
318     }
319     else
320     {
321         p_sys->i_state = SUBTITLE_BLOCK_PARTIAL;
322         i_packet       = *p_buffer++;
323     }
324
325     p_sys->i_image = GETINT16(p_buffer);
326
327     if( p_sys->i_image != i_expected_image )
328     {
329         msg_Warn( p_dec, "expected subtitle image %u but found %u",
330                   i_expected_image, p_sys->i_image );
331     }
332
333     if( i_packet != i_expected_packet )
334     {
335         msg_Warn( p_dec, "expected subtitle image packet %u but found %u",
336                   i_expected_packet, i_packet );
337     }
338
339     p_block->p_buffer += SPU_HEADER_LEN;
340     p_block->i_buffer -= SPU_HEADER_LEN;
341
342     p_sys->i_packet = i_packet;
343     /* First packet in the subtitle block */
344     if( !p_sys->i_packet ) ParseHeader( p_dec, p_block );
345
346     block_ChainAppend( &p_sys->p_spu, p_block );
347
348     if( p_sys->i_state == SUBTITLE_BLOCK_COMPLETE )
349     {
350         block_t *p_spu = block_ChainGather( p_sys->p_spu );
351
352         if( p_spu->i_buffer != p_sys->i_spu_size )
353         {
354             msg_Warn( p_dec, "subtitle packets size=%zu should be %zu",
355                       p_spu->i_buffer, p_sys->i_spu_size );
356         }
357
358     dbg_print( (DECODE_DBG_PACKET),
359                  "subtitle packet complete, size=%zu", p_spu->i_buffer );
360
361         p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
362         p_sys->p_spu = 0;
363         return p_spu;
364     }
365
366     return NULL;
367 }
368
369 /******************************************************************************
370   The format is roughly as follows (everything is big-endian):
371  
372    size     description
373    -------------------------------------------
374    byte     subtitle channel (0..7) in bits 0-3
375    byte     subtitle packet number of this subtitle image 0-N,
376             if the subtitle packet is complete, the top bit of the byte is 1.
377    u_int16  subtitle image number
378    u_int16  length in bytes of the rest
379    byte     option flags, unknown meaning except bit 3 (0x08) indicates
380             presence of the duration field
381    byte     unknown
382    u_int32  duration in 1/90000ths of a second (optional), start time
383             is as indicated by the PTS in the PES header
384    u_int32  xpos
385    u_int32  ypos
386    u_int32  width (must be even)
387    u_int32  height (must be even)
388    byte[16] palette, 4 palette entries, each contains values for
389             Y, U, V and transparency, 0 standing for transparent
390    byte     command,
391             cmd>>6==1 indicates shift
392             (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)
393    u_int32  shift duration in 1/90000ths of a second
394    u_int16  offset of odd-numbered scanlines - subtitle images are
395             given in interlace order
396    byte[]   limited RLE image data in interlace order (0,2,4... 1,3,5) with
397             2-bits per palette number
398 ******************************************************************************/
399 static void ParseHeader( decoder_t *p_dec, block_t *p_block )
400 {
401     decoder_sys_t *p_sys = p_dec->p_sys;
402     uint8_t *p = p_block->p_buffer;
403     uint8_t i_options, i_options2, i_cmd, i_cmd_arg;
404     int i;
405
406     p_sys->i_spu_size = GETINT16(p);
407     i_options  = *p++;
408     i_options2 = *p++;
409
410     if( i_options & 0x08 ) { p_sys->i_duration = GETINT32(p); }
411     else p_sys->i_duration = 0; /* Ephemer subtitle */
412     p_sys->i_duration *= 100 / 9;
413
414     p_sys->i_x_start = GETINT16(p);
415     p_sys->i_y_start = GETINT16(p);
416     p_sys->i_width   = GETINT16(p);
417     p_sys->i_height  = GETINT16(p);
418
419     for( i = 0; i < 4; i++ )
420     {
421         p_sys->p_palette[i][0] = *p++; /* Y */
422         p_sys->p_palette[i][2] = *p++; /* Cr / V */
423         p_sys->p_palette[i][1] = *p++; /* Cb / U */
424         p_sys->p_palette[i][3] = *p++; /* T */
425     }
426
427     i_cmd = *p++;
428     /* We do not really know this, FIXME */
429     if( i_cmd ) {i_cmd_arg = GETINT32(p);}
430
431     /* Actually, this is measured against a different origin, so we have to
432      * adjust it */
433     p_sys->second_field_offset = GETINT16(p);
434     p_sys->i_image_offset  = p - p_block->p_buffer;
435     p_sys->i_image_length  = p_sys->i_spu_size - p_sys->i_image_offset;
436     p_sys->metadata_length = p_sys->i_image_offset;
437
438   if( p_sys->i_debug & DECODE_DBG_PACKET )
439   {
440       msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
441            "spu size: %zu, duration: %"PRIu64" (d:%zu p:%"PRIu16")",
442            p_sys->i_x_start, p_sys->i_y_start,
443            p_sys->i_width, p_sys->i_height,
444            p_sys->i_spu_size, p_sys->i_duration,
445            p_sys->i_image_length, p_sys->i_image_offset);
446
447       for( i = 0; i < 4; i++ )
448       {
449           msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
450            p_sys->p_palette[i][3], p_sys->p_palette[i][0],
451            p_sys->p_palette[i][1], p_sys->p_palette[i][2] );
452       }
453   }
454 }
455
456 /*****************************************************************************
457  * DecodePacket: parse and decode an subtitle packet
458  *****************************************************************************
459  * This function parses and decodes an SPU packet and, if valid, returns a
460  * subpicture.
461  *****************************************************************************/
462 static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
463 {
464     decoder_sys_t *p_sys = p_dec->p_sys;
465     subpicture_t  *p_spu;
466     subpicture_region_t *p_region;
467     video_format_t fmt;
468     video_palette_t palette;
469     int i;
470
471     /* Allocate the subpicture internal data. */
472     p_spu = decoder_NewSubpicture( p_dec );
473     if( !p_spu ) return NULL;
474
475     p_spu->i_start = p_data->i_pts;
476     p_spu->i_stop  = p_data->i_pts + p_sys->i_duration;
477     p_spu->b_ephemer = true;
478
479     /* Create new subtitle region */
480     memset( &fmt, 0, sizeof(video_format_t) );
481     fmt.i_chroma = VLC_CODEC_YUVP;
482
483     /**
484        The video on which the subtitle sits, is scaled, probably
485        4:3. However subtitle bitmaps assume an 1:1 aspect ratio.
486
487        FIXME: We should get the video aspect ratio from somewhere.
488        Two candidates are the video and the other possibility would be
489        the access module.
490     */
491     fmt.i_aspect = VOUT_ASPECT_FACTOR;
492
493     fmt.i_width = fmt.i_visible_width = p_sys->i_width;
494     fmt.i_height = fmt.i_visible_height = p_sys->i_height;
495     fmt.i_x_offset = fmt.i_y_offset = 0;
496     fmt.p_palette = &palette;
497     fmt.p_palette->i_entries = 4;
498     for( i = 0; i < fmt.p_palette->i_entries; i++ )
499     {
500         fmt.p_palette->palette[i][0] = p_sys->p_palette[i][0];
501         fmt.p_palette->palette[i][1] = p_sys->p_palette[i][1];
502         fmt.p_palette->palette[i][2] = p_sys->p_palette[i][2];
503         fmt.p_palette->palette[i][3] = p_sys->p_palette[i][3];
504     }
505
506     p_region = subpicture_region_New( &fmt );
507     if( !p_region )
508     {
509         msg_Err( p_dec, "cannot allocate SVCD subtitle region" );
510         decoder_DeleteSubpicture( p_dec, p_spu );
511         return NULL;
512     }
513
514     p_spu->p_region = p_region;
515     p_region->i_x = p_sys->i_x_start;
516     p_region->i_y = p_sys->i_y_start;
517
518     SVCDSubRenderImage( p_dec, p_data, p_region );
519
520     return p_spu;
521 }
522
523 /*****************************************************************************
524  * SVCDSubRenderImage: reorders bytes of image data in subpicture region.
525  *****************************************************************************
526
527  The image is encoded using two bits per pixel that select a palette
528  entry except that value 0 starts a limited run-length encoding for
529  color 0.  When 0 is seen, the next two bits encode one less than the
530  number of pixels, so we can encode run lengths from 1 to 4. These get
531  filled with the color in palette entry 0.
532
533  The encoding of each line is padded to a whole number of bytes.  The
534  first field is padded to an even byte length and the complete subtitle
535  is padded to a 4-byte multiple that always include one zero byte at
536  the end.
537
538  However we'll transform this so that that the RLE is expanded and
539  interlacing will also be removed.
540  *****************************************************************************/
541 static void SVCDSubRenderImage( decoder_t *p_dec, block_t *p_data,
542                 subpicture_region_t *p_region )
543 {
544     decoder_sys_t *p_sys = p_dec->p_sys;
545     uint8_t *p_dest = p_region->p_picture->Y_PIXELS;
546     int i_field;            /* The subtitles are interlaced */
547     int i_row, i_column;    /* scanline row/column number */
548     uint8_t i_color, i_count;
549     bs_t bs;
550
551     bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset,
552              p_data->i_buffer - p_sys->i_image_offset );
553
554     for( i_field = 0; i_field < 2; i_field++ )
555     {
556         for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 )
557         {
558             for( i_column = 0; i_column < p_sys->i_width; i_column++ )
559             {
560                 i_color = bs_read( &bs, 2 );
561                 if( i_color == 0 && (i_count = bs_read( &bs, 2 )) )
562                 {
563                     i_count = __MIN( i_count, p_sys->i_width - i_column );
564                     memset( &p_dest[i_row * p_region->p_picture->Y_PITCH +
565                                     i_column], 0, i_count + 1 );
566                     i_column += i_count;
567                     continue;
568                 }
569
570                 p_dest[i_row * p_region->p_picture->Y_PITCH + i_column] = i_color;
571             }
572
573             bs_align( &bs );
574         }
575
576         /* odd field */
577         bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset +
578                  p_sys->second_field_offset,
579                  p_data->i_buffer - p_sys->i_image_offset -
580                  p_sys->second_field_offset );
581     }
582 }