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