input: add an input_item_t arg to input_CreateFilename()
[vlc.git] / modules / codec / svcdsub.c
blob3fcb0528ad78dfa701b55779789d1371f8cd7267
1 /*****************************************************************************
2 * svcdsub.c : Overlay Graphics Text (SVCD subtitles) decoder
3 *****************************************************************************
4 * Copyright (C) 2003, 2004 VLC authors and VideoLAN
5 * $Id$
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>
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 of the License, or
15 * (at your option) any later version.
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 Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
28 * Preamble
29 *****************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_codec.h>
37 #include <vlc_bits.h>
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 * );
46 vlc_module_begin ()
47 set_description( N_("Philips OGT (SVCD subtitle) decoder") )
48 set_shortname( N_("SVCD subtitles") )
49 set_category( CAT_INPUT )
50 set_subcategory( SUBCAT_INPUT_SCODEC )
51 set_capability( "spu decoder", 50 )
52 set_callbacks( DecoderOpen, DecoderClose )
54 add_obsolete_integer ( "svcdsub-debug" )
56 add_submodule ()
57 set_description( N_("Philips OGT (SVCD subtitle) packetizer") )
58 set_capability( "packetizer", 50 )
59 set_callbacks( PacketizerOpen, DecoderClose )
60 vlc_module_end ()
62 /*****************************************************************************
63 * Local prototypes
64 *****************************************************************************/
65 static int Decode( decoder_t *, block_t * );
66 static block_t *Packetize ( decoder_t *, block_t ** );
67 static block_t *Reassemble ( decoder_t *, block_t * );
68 static void ParseHeader( decoder_t *, block_t * );
69 static subpicture_t *DecodePacket( decoder_t *, block_t * );
70 static void SVCDSubRenderImage( decoder_t *, block_t *, subpicture_region_t * );
72 #define GETINT16(p) GetWBE(p) ; p +=2;
74 #define GETINT32(p) GetDWBE(p) ; p += 4;
76 typedef enum {
77 SUBTITLE_BLOCK_EMPTY = 0,
78 SUBTITLE_BLOCK_PARTIAL = 1,
79 SUBTITLE_BLOCK_COMPLETE = 2
80 } packet_state_t;
82 typedef struct
84 packet_state_t i_state; /* data-gathering state for this subtitle */
86 block_t *p_spu; /* Bytes of the packet. */
88 uint16_t i_image; /* image number in the subtitle stream */
89 uint8_t i_packet; /* packet number for above image number */
91 size_t i_spu_size; /* goal for subtitle_data_pos while gathering,
92 size of used subtitle_data later */
94 uint16_t i_image_offset; /* offset from subtitle_data to compressed
95 image data */
96 size_t i_image_length; /* size of the compressed image data */
97 size_t second_field_offset; /* offset of odd raster lines */
98 size_t metadata_offset; /* offset to data describing the image */
99 size_t metadata_length; /* length of metadata */
101 vlc_tick_t i_duration; /* how long to display the image, 0 stands
102 for "until next subtitle" */
104 uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
105 image when displayed */
106 uint16_t i_width, i_height; /* dimensions in pixels of image */
108 uint8_t p_palette[4][4]; /* Palette of colors used in subtitle */
109 } decoder_sys_t;
111 static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
113 decoder_t *p_dec = (decoder_t*)p_this;
114 decoder_sys_t *p_sys;
116 if( p_dec->fmt_in.i_codec != VLC_CODEC_OGT )
117 return VLC_EGENERIC;
119 p_dec->p_sys = p_sys = calloc( 1, sizeof( decoder_sys_t ) );
120 if( p_sys == NULL )
121 return VLC_ENOMEM;
124 p_sys->i_image = -1;
126 p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
127 p_sys->p_spu = NULL;
129 p_dec->fmt_out.i_codec = VLC_CODEC_OGT;
131 if( b_packetizer )
132 p_dec->pf_packetize = Packetize;
133 else
134 p_dec->pf_decode = Decode;
136 return VLC_SUCCESS;
139 /*****************************************************************************
140 * DecoderOpen: open/initialize the svcdsub decoder.
141 *****************************************************************************/
142 static int DecoderOpen( vlc_object_t *p_this )
144 return OpenCommon( p_this, false );
147 /*****************************************************************************
148 * PacketizerOpen: open/initialize the svcdsub packetizer.
149 *****************************************************************************/
150 static int PacketizerOpen( vlc_object_t *p_this )
152 return OpenCommon( p_this, true );
155 /*****************************************************************************
156 * DecoderClose: closes the svcdsub decoder/packetizer.
157 *****************************************************************************/
158 void DecoderClose( vlc_object_t *p_this )
160 decoder_t *p_dec = (decoder_t*)p_this;
161 decoder_sys_t *p_sys = p_dec->p_sys;
163 if( p_sys->p_spu ) block_ChainRelease( p_sys->p_spu );
164 free( p_sys );
167 /*****************************************************************************
168 * Decode:
169 *****************************************************************************/
170 static int Decode( decoder_t *p_dec, block_t *p_block )
172 #ifndef NDEBUG
173 msg_Dbg( p_dec, "Decode" );
174 #endif
176 if( p_block == NULL ) /* No Drain */
177 return VLCDEC_SUCCESS;
179 if( !(p_block = Reassemble( p_dec, p_block )) )
180 return VLCDEC_SUCCESS;
182 /* Parse and decode */
183 subpicture_t *p_spu = DecodePacket( p_dec, p_block );
184 if( p_spu != NULL )
185 decoder_QueueSub( p_dec, p_spu );
186 return VLCDEC_SUCCESS;
189 /*****************************************************************************
190 * Packetize:
191 *****************************************************************************/
192 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
194 block_t *p_block, *p_spu;
196 if( pp_block == NULL || *pp_block == NULL ) return NULL;
198 p_block = *pp_block;
199 *pp_block = NULL;
201 if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
203 p_spu->i_dts = p_spu->i_pts;
204 p_spu->i_length = 0;
206 return p_spu;
209 /*****************************************************************************
210 Reassemble:
212 The data for single screen subtitle may come in one of many
213 non-contiguous packets of a stream. This routine is called when the
214 next packet in the stream comes in. The job of this routine is to
215 parse the header, if this is the beginning, and combine the packets
216 into one complete subtitle unit.
218 If everything is complete, we will return a block. Otherwise return
219 NULL.
222 The format of the beginning of the subtitle packet that is used here.
224 size description
225 -------------------------------------------
226 byte subtitle channel (0..7) in bits 0-3
227 byte subtitle packet number of this subtitle image 0-N,
228 if the subtitle packet is complete, the top bit of the byte is 1.
229 uint16 subtitle image number
231 *****************************************************************************/
232 #define SPU_HEADER_LEN 5
234 static block_t *Reassemble( decoder_t *p_dec, block_t *p_block )
236 decoder_sys_t *p_sys = p_dec->p_sys;
237 uint8_t *p_buffer;
238 uint16_t i_expected_image;
239 uint8_t i_packet, i_expected_packet;
241 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED) )
243 block_Release( p_block );
244 return NULL;
247 if( p_block->i_buffer < SPU_HEADER_LEN )
249 msg_Dbg( p_dec, "invalid packet header (size %zu < %u)" ,
250 p_block->i_buffer, SPU_HEADER_LEN );
251 block_Release( p_block );
252 return NULL;
255 p_buffer = p_block->p_buffer;
257 if( p_sys->i_state == SUBTITLE_BLOCK_EMPTY )
259 i_expected_image = p_sys->i_image + 1;
260 i_expected_packet = 0;
262 else
264 i_expected_image = p_sys->i_image;
265 i_expected_packet = p_sys->i_packet + 1;
268 /* The dummy ES that the menu selection uses has an 0x70 at
269 the head which we need to strip off. */
270 p_buffer += 2;
272 if( *p_buffer & 0x80 )
274 p_sys->i_state = SUBTITLE_BLOCK_COMPLETE;
275 i_packet = *p_buffer++ & 0x7F;
277 else
279 p_sys->i_state = SUBTITLE_BLOCK_PARTIAL;
280 i_packet = *p_buffer++;
283 p_sys->i_image = GETINT16(p_buffer);
285 if( p_sys->i_image != i_expected_image )
287 msg_Warn( p_dec, "expected subtitle image %u but found %u",
288 i_expected_image, p_sys->i_image );
291 if( i_packet != i_expected_packet )
293 msg_Warn( p_dec, "expected subtitle image packet %u but found %u",
294 i_expected_packet, i_packet );
297 p_block->p_buffer += SPU_HEADER_LEN;
298 p_block->i_buffer -= SPU_HEADER_LEN;
300 p_sys->i_packet = i_packet;
301 /* First packet in the subtitle block */
302 if( !p_sys->i_packet ) ParseHeader( p_dec, p_block );
304 block_ChainAppend( &p_sys->p_spu, p_block );
306 if( p_sys->i_state == SUBTITLE_BLOCK_COMPLETE )
308 block_t *p_spu = block_ChainGather( p_sys->p_spu );
310 if( unlikely( !p_spu ) )
312 block_ChainRelease( p_sys->p_spu );
313 p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
314 p_sys->p_spu = NULL;
316 msg_Warn( p_dec, "unable to assemble blocks, discarding" );
317 return NULL;
320 if( p_spu->i_buffer != p_sys->i_spu_size )
322 msg_Warn( p_dec, "subtitle packets size=%zu should be %zu",
323 p_spu->i_buffer, p_sys->i_spu_size );
326 msg_Dbg( p_dec, "subtitle packet complete, size=%zu", p_spu->i_buffer );
328 p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
329 p_sys->p_spu = NULL;
330 return p_spu;
333 return NULL;
336 /******************************************************************************
337 The format is roughly as follows (everything is big-endian):
339 size description
340 -------------------------------------------
341 byte subtitle channel (0..7) in bits 0-3
342 byte subtitle packet number of this subtitle image 0-N,
343 if the subtitle packet is complete, the top bit of the byte is 1.
344 u_int16 subtitle image number
345 u_int16 length in bytes of the rest
346 byte option flags, unknown meaning except bit 3 (0x08) indicates
347 presence of the duration field
348 byte unknown
349 u_int32 duration in 1/90000ths of a second (optional), start time
350 is as indicated by the PTS in the PES header
351 u_int32 xpos
352 u_int32 ypos
353 u_int32 width (must be even)
354 u_int32 height (must be even)
355 byte[16] palette, 4 palette entries, each contains values for
356 Y, U, V and transparency, 0 standing for transparent
357 byte command,
358 cmd>>6==1 indicates shift
359 (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)
360 u_int32 shift duration in 1/90000ths of a second
361 u_int16 offset of odd-numbered scanlines - subtitle images are
362 given in interlace order
363 byte[] limited RLE image data in interlace order (0,2,4... 1,3,5) with
364 2-bits per palette number
365 ******************************************************************************/
366 static void ParseHeader( decoder_t *p_dec, block_t *p_block )
368 decoder_sys_t *p_sys = p_dec->p_sys;
369 uint8_t *p = p_block->p_buffer;
370 uint8_t i_options, i_cmd;
371 int i;
373 p_sys->i_spu_size = GETINT16(p);
374 i_options = *p++;
375 // Skip over unused value
376 p++;
378 if( i_options & 0x08 ) { p_sys->i_duration = GETINT32(p); }
379 else p_sys->i_duration = 0; /* Ephemer subtitle */
380 p_sys->i_duration *= 100 / 9;
382 p_sys->i_x_start = GETINT16(p);
383 p_sys->i_y_start = GETINT16(p);
384 p_sys->i_width = GETINT16(p);
385 p_sys->i_height = GETINT16(p);
387 for( i = 0; i < 4; i++ )
389 p_sys->p_palette[i][0] = *p++; /* Y */
390 p_sys->p_palette[i][2] = *p++; /* Cr / V */
391 p_sys->p_palette[i][1] = *p++; /* Cb / U */
392 p_sys->p_palette[i][3] = *p++; /* T */
395 i_cmd = *p++;
396 /* We do not really know this, FIXME */
397 if( i_cmd ) { p += 4; }
399 /* Actually, this is measured against a different origin, so we have to
400 * adjust it */
401 p_sys->second_field_offset = GETINT16(p);
402 p_sys->i_image_offset = p - p_block->p_buffer;
403 p_sys->i_image_length = p_sys->i_spu_size - p_sys->i_image_offset;
404 p_sys->metadata_length = p_sys->i_image_offset;
406 #ifndef NDEBUG
407 msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
408 "spu size: %zu, duration: %"PRIu64" (d:%zu p:%"PRIu16")",
409 p_sys->i_x_start, p_sys->i_y_start,
410 p_sys->i_width, p_sys->i_height,
411 p_sys->i_spu_size, p_sys->i_duration,
412 p_sys->i_image_length, p_sys->i_image_offset);
414 for( i = 0; i < 4; i++ )
416 msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
417 p_sys->p_palette[i][3], p_sys->p_palette[i][0],
418 p_sys->p_palette[i][1], p_sys->p_palette[i][2] );
420 #endif
423 /*****************************************************************************
424 * DecodePacket: parse and decode an subtitle packet
425 *****************************************************************************
426 * This function parses and decodes an SPU packet and, if valid, returns a
427 * subpicture.
428 *****************************************************************************/
429 static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
431 decoder_sys_t *p_sys = p_dec->p_sys;
432 subpicture_t *p_spu;
433 subpicture_region_t *p_region;
434 video_format_t fmt;
435 video_palette_t palette;
436 int i;
438 /* Allocate the subpicture internal data. */
439 p_spu = decoder_NewSubpicture( p_dec, NULL );
440 if( !p_spu ) return NULL;
442 p_spu->i_start = p_data->i_pts;
443 p_spu->i_stop = p_data->i_pts + p_sys->i_duration;
444 p_spu->b_ephemer = true;
446 /* Create new subtitle region */
447 video_format_Init( &fmt, VLC_CODEC_YUVP );
450 The video on which the subtitle sits, is scaled, probably
451 4:3. However subtitle bitmaps assume an 1:1 aspect ratio.
453 FIXME: We should get the video aspect ratio from somewhere.
454 Two candidates are the video and the other possibility would be
455 the access module.
457 fmt.i_sar_num = p_sys->i_height;
458 fmt.i_sar_den = p_sys->i_width;
460 fmt.i_width = fmt.i_visible_width = p_sys->i_width;
461 fmt.i_height = fmt.i_visible_height = p_sys->i_height;
462 fmt.i_x_offset = fmt.i_y_offset = 0;
463 fmt.p_palette = &palette;
464 fmt.p_palette->i_entries = 4;
465 for( i = 0; i < fmt.p_palette->i_entries; i++ )
467 fmt.p_palette->palette[i][0] = p_sys->p_palette[i][0];
468 fmt.p_palette->palette[i][1] = p_sys->p_palette[i][1];
469 fmt.p_palette->palette[i][2] = p_sys->p_palette[i][2];
470 fmt.p_palette->palette[i][3] = p_sys->p_palette[i][3];
473 p_region = subpicture_region_New( &fmt );
474 fmt.p_palette = NULL;
475 video_format_Clean( &fmt );
476 if( !p_region )
478 msg_Err( p_dec, "cannot allocate SVCD subtitle region" );
479 subpicture_Delete( p_spu );
480 return NULL;
483 p_spu->p_region = p_region;
484 p_region->i_x = p_sys->i_x_start;
485 p_region->i_y = p_sys->i_y_start;
487 SVCDSubRenderImage( p_dec, p_data, p_region );
489 return p_spu;
492 /*****************************************************************************
493 * SVCDSubRenderImage: reorders bytes of image data in subpicture region.
494 *****************************************************************************
496 The image is encoded using two bits per pixel that select a palette
497 entry except that value 0 starts a limited run-length encoding for
498 color 0. When 0 is seen, the next two bits encode one less than the
499 number of pixels, so we can encode run lengths from 1 to 4. These get
500 filled with the color in palette entry 0.
502 The encoding of each line is padded to a whole number of bytes. The
503 first field is padded to an even byte length and the complete subtitle
504 is padded to a 4-byte multiple that always include one zero byte at
505 the end.
507 However we'll transform this so that that the RLE is expanded and
508 interlacing will also be removed.
509 *****************************************************************************/
510 static void SVCDSubRenderImage( decoder_t *p_dec, block_t *p_data,
511 subpicture_region_t *p_region )
513 decoder_sys_t *p_sys = p_dec->p_sys;
514 uint8_t *p_dest = p_region->p_picture->Y_PIXELS;
515 int i_field; /* The subtitles are interlaced */
516 int i_row, i_column; /* scanline row/column number */
517 uint8_t i_color, i_count;
518 bs_t bs;
520 bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset,
521 p_data->i_buffer - p_sys->i_image_offset );
523 for( i_field = 0; i_field < 2; i_field++ )
525 for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 )
527 for( i_column = 0; i_column < p_sys->i_width; i_column++ )
529 i_color = bs_read( &bs, 2 );
530 if( i_color == 0 && (i_count = bs_read( &bs, 2 )) )
532 i_count = __MIN( i_count, p_sys->i_width - i_column );
533 memset( &p_dest[i_row * p_region->p_picture->Y_PITCH +
534 i_column], 0, i_count + 1 );
535 i_column += i_count;
536 continue;
539 p_dest[i_row * p_region->p_picture->Y_PITCH + i_column] = i_color;
542 bs_align( &bs );
545 /* odd field */
546 bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset +
547 p_sys->second_field_offset,
548 p_data->i_buffer - p_sys->i_image_offset -
549 p_sys->second_field_offset );