demux: mp4: avoid audio cuts on seek
[vlc.git] / modules / codec / svcdsub.c
blob581c9c3059e5bdd0cc5ebfb8b9b29a6ecc96bf29
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 ( MODULE_STRING "-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) ( (p[0] << 8) + p[1] ) ; p +=2;
74 #define GETINT32(p) ( (p[0] << 24) + (p[1] << 16) + \
75 (p[2] << 8) + (p[3]) ) ; p += 4;
77 typedef enum {
78 SUBTITLE_BLOCK_EMPTY = 0,
79 SUBTITLE_BLOCK_PARTIAL = 1,
80 SUBTITLE_BLOCK_COMPLETE = 2
81 } packet_state_t;
83 struct decoder_sys_t
85 packet_state_t i_state; /* data-gathering state for this subtitle */
87 block_t *p_spu; /* Bytes of the packet. */
89 uint16_t i_image; /* image number in the subtitle stream */
90 uint8_t i_packet; /* packet number for above image number */
92 size_t i_spu_size; /* goal for subtitle_data_pos while gathering,
93 size of used subtitle_data later */
95 uint16_t i_image_offset; /* offset from subtitle_data to compressed
96 image data */
97 size_t i_image_length; /* size of the compressed image data */
98 size_t second_field_offset; /* offset of odd raster lines */
99 size_t metadata_offset; /* offset to data describing the image */
100 size_t metadata_length; /* length of metadata */
102 mtime_t i_duration; /* how long to display the image, 0 stands
103 for "until next subtitle" */
105 uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
106 image when displayed */
107 uint16_t i_width, i_height; /* dimensions in pixels of image */
109 uint8_t p_palette[4][4]; /* Palette of colors used in subtitle */
112 /*****************************************************************************
113 * DecoderOpen: open/initialize the svcdsub decoder.
114 *****************************************************************************/
115 static int DecoderOpen( vlc_object_t *p_this )
117 decoder_t *p_dec = (decoder_t*)p_this;
118 decoder_sys_t *p_sys;
120 if( p_dec->fmt_in.i_codec != VLC_CODEC_OGT )
121 return VLC_EGENERIC;
123 p_dec->p_sys = p_sys = calloc( 1, sizeof( decoder_sys_t ) );
124 if( p_sys == NULL )
125 return VLC_ENOMEM;
128 p_sys->i_image = -1;
130 p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
131 p_sys->p_spu = NULL;
133 p_dec->fmt_out.i_codec = VLC_CODEC_OGT;
135 p_dec->pf_decode = Decode;
136 p_dec->pf_packetize = Packetize;
138 return VLC_SUCCESS;
141 /*****************************************************************************
142 * PacketizerOpen: open/initialize the svcdsub packetizer.
143 *****************************************************************************/
144 static int PacketizerOpen( vlc_object_t *p_this )
146 if( DecoderOpen( p_this ) != VLC_SUCCESS ) return VLC_EGENERIC;
148 return VLC_SUCCESS;
151 /*****************************************************************************
152 * DecoderClose: closes the svcdsub decoder/packetizer.
153 *****************************************************************************/
154 void DecoderClose( vlc_object_t *p_this )
156 decoder_t *p_dec = (decoder_t*)p_this;
157 decoder_sys_t *p_sys = p_dec->p_sys;
159 if( p_sys->p_spu ) block_ChainRelease( p_sys->p_spu );
160 free( p_sys );
163 /*****************************************************************************
164 * Decode:
165 *****************************************************************************/
166 static int Decode( decoder_t *p_dec, block_t *p_block )
168 #ifndef NDEBUG
169 msg_Dbg( p_dec, "Decode" );
170 #endif
172 if( p_block == NULL ) /* No Drain */
173 return VLCDEC_SUCCESS;
175 if( !(p_block = Reassemble( p_dec, p_block )) )
176 return VLCDEC_SUCCESS;
178 /* Parse and decode */
179 subpicture_t *p_spu = DecodePacket( p_dec, p_block );
180 if( p_spu != NULL )
181 decoder_QueueSub( p_dec, p_spu );
182 return VLCDEC_SUCCESS;
185 /*****************************************************************************
186 * Packetize:
187 *****************************************************************************/
188 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
190 block_t *p_block, *p_spu;
192 if( pp_block == NULL || *pp_block == NULL ) return NULL;
194 p_block = *pp_block;
195 *pp_block = NULL;
197 if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
199 p_spu->i_dts = p_spu->i_pts;
200 p_spu->i_length = 0;
202 return p_spu;
205 /*****************************************************************************
206 Reassemble:
208 The data for single screen subtitle may come in one of many
209 non-contiguous packets of a stream. This routine is called when the
210 next packet in the stream comes in. The job of this routine is to
211 parse the header, if this is the beginning, and combine the packets
212 into one complete subtitle unit.
214 If everything is complete, we will return a block. Otherwise return
215 NULL.
218 The format of the beginning of the subtitle packet that is used here.
220 size description
221 -------------------------------------------
222 byte subtitle channel (0..7) in bits 0-3
223 byte subtitle packet number of this subtitle image 0-N,
224 if the subtitle packet is complete, the top bit of the byte is 1.
225 uint16 subtitle image number
227 *****************************************************************************/
228 #define SPU_HEADER_LEN 5
230 static block_t *Reassemble( decoder_t *p_dec, block_t *p_block )
232 decoder_sys_t *p_sys = p_dec->p_sys;
233 uint8_t *p_buffer;
234 uint16_t i_expected_image;
235 uint8_t i_packet, i_expected_packet;
237 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED) )
239 block_Release( p_block );
240 return NULL;
243 if( p_block->i_buffer < SPU_HEADER_LEN )
245 msg_Dbg( p_dec, "invalid packet header (size %zu < %u)" ,
246 p_block->i_buffer, SPU_HEADER_LEN );
247 block_Release( p_block );
248 return NULL;
251 p_buffer = p_block->p_buffer;
253 if( p_sys->i_state == SUBTITLE_BLOCK_EMPTY )
255 i_expected_image = p_sys->i_image + 1;
256 i_expected_packet = 0;
258 else
260 i_expected_image = p_sys->i_image;
261 i_expected_packet = p_sys->i_packet + 1;
264 /* The dummy ES that the menu selection uses has an 0x70 at
265 the head which we need to strip off. */
266 p_buffer += 2;
268 if( *p_buffer & 0x80 )
270 p_sys->i_state = SUBTITLE_BLOCK_COMPLETE;
271 i_packet = *p_buffer++ & 0x7F;
273 else
275 p_sys->i_state = SUBTITLE_BLOCK_PARTIAL;
276 i_packet = *p_buffer++;
279 p_sys->i_image = GETINT16(p_buffer);
281 if( p_sys->i_image != i_expected_image )
283 msg_Warn( p_dec, "expected subtitle image %u but found %u",
284 i_expected_image, p_sys->i_image );
287 if( i_packet != i_expected_packet )
289 msg_Warn( p_dec, "expected subtitle image packet %u but found %u",
290 i_expected_packet, i_packet );
293 p_block->p_buffer += SPU_HEADER_LEN;
294 p_block->i_buffer -= SPU_HEADER_LEN;
296 p_sys->i_packet = i_packet;
297 /* First packet in the subtitle block */
298 if( !p_sys->i_packet ) ParseHeader( p_dec, p_block );
300 block_ChainAppend( &p_sys->p_spu, p_block );
302 if( p_sys->i_state == SUBTITLE_BLOCK_COMPLETE )
304 block_t *p_spu = block_ChainGather( p_sys->p_spu );
306 if( unlikely( !p_spu ) )
308 block_ChainRelease( p_sys->p_spu );
309 p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
310 p_sys->p_spu = NULL;
312 msg_Warn( p_dec, "unable to assemble blocks, discarding" );
313 return NULL;
316 if( p_spu->i_buffer != p_sys->i_spu_size )
318 msg_Warn( p_dec, "subtitle packets size=%zu should be %zu",
319 p_spu->i_buffer, p_sys->i_spu_size );
322 msg_Dbg( p_dec, "subtitle packet complete, size=%zu", p_spu->i_buffer );
324 p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
325 p_sys->p_spu = NULL;
326 return p_spu;
329 return NULL;
332 /******************************************************************************
333 The format is roughly as follows (everything is big-endian):
335 size description
336 -------------------------------------------
337 byte subtitle channel (0..7) in bits 0-3
338 byte subtitle packet number of this subtitle image 0-N,
339 if the subtitle packet is complete, the top bit of the byte is 1.
340 u_int16 subtitle image number
341 u_int16 length in bytes of the rest
342 byte option flags, unknown meaning except bit 3 (0x08) indicates
343 presence of the duration field
344 byte unknown
345 u_int32 duration in 1/90000ths of a second (optional), start time
346 is as indicated by the PTS in the PES header
347 u_int32 xpos
348 u_int32 ypos
349 u_int32 width (must be even)
350 u_int32 height (must be even)
351 byte[16] palette, 4 palette entries, each contains values for
352 Y, U, V and transparency, 0 standing for transparent
353 byte command,
354 cmd>>6==1 indicates shift
355 (cmd>>4)&3 is direction from, (0=top,1=left,2=right,3=bottom)
356 u_int32 shift duration in 1/90000ths of a second
357 u_int16 offset of odd-numbered scanlines - subtitle images are
358 given in interlace order
359 byte[] limited RLE image data in interlace order (0,2,4... 1,3,5) with
360 2-bits per palette number
361 ******************************************************************************/
362 static void ParseHeader( decoder_t *p_dec, block_t *p_block )
364 decoder_sys_t *p_sys = p_dec->p_sys;
365 uint8_t *p = p_block->p_buffer;
366 uint8_t i_options, i_options2, i_cmd, i_cmd_arg;
367 int i;
369 p_sys->i_spu_size = GETINT16(p);
370 i_options = *p++;
371 i_options2 = *p++;
373 if( i_options & 0x08 ) { p_sys->i_duration = GETINT32(p); }
374 else p_sys->i_duration = 0; /* Ephemer subtitle */
375 p_sys->i_duration *= 100 / 9;
377 p_sys->i_x_start = GETINT16(p);
378 p_sys->i_y_start = GETINT16(p);
379 p_sys->i_width = GETINT16(p);
380 p_sys->i_height = GETINT16(p);
382 for( i = 0; i < 4; i++ )
384 p_sys->p_palette[i][0] = *p++; /* Y */
385 p_sys->p_palette[i][2] = *p++; /* Cr / V */
386 p_sys->p_palette[i][1] = *p++; /* Cb / U */
387 p_sys->p_palette[i][3] = *p++; /* T */
390 i_cmd = *p++;
391 /* We do not really know this, FIXME */
392 if( i_cmd ) {i_cmd_arg = GETINT32(p);}
394 /* Actually, this is measured against a different origin, so we have to
395 * adjust it */
396 p_sys->second_field_offset = GETINT16(p);
397 p_sys->i_image_offset = p - p_block->p_buffer;
398 p_sys->i_image_length = p_sys->i_spu_size - p_sys->i_image_offset;
399 p_sys->metadata_length = p_sys->i_image_offset;
401 #ifndef NDEBUG
402 msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
403 "spu size: %zu, duration: %"PRIu64" (d:%zu p:%"PRIu16")",
404 p_sys->i_x_start, p_sys->i_y_start,
405 p_sys->i_width, p_sys->i_height,
406 p_sys->i_spu_size, p_sys->i_duration,
407 p_sys->i_image_length, p_sys->i_image_offset);
409 for( i = 0; i < 4; i++ )
411 msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
412 p_sys->p_palette[i][3], p_sys->p_palette[i][0],
413 p_sys->p_palette[i][1], p_sys->p_palette[i][2] );
415 #endif
418 /*****************************************************************************
419 * DecodePacket: parse and decode an subtitle packet
420 *****************************************************************************
421 * This function parses and decodes an SPU packet and, if valid, returns a
422 * subpicture.
423 *****************************************************************************/
424 static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
426 decoder_sys_t *p_sys = p_dec->p_sys;
427 subpicture_t *p_spu;
428 subpicture_region_t *p_region;
429 video_format_t fmt;
430 video_palette_t palette;
431 int i;
433 /* Allocate the subpicture internal data. */
434 p_spu = decoder_NewSubpicture( p_dec, NULL );
435 if( !p_spu ) return NULL;
437 p_spu->i_start = p_data->i_pts;
438 p_spu->i_stop = p_data->i_pts + p_sys->i_duration;
439 p_spu->b_ephemer = true;
441 /* Create new subtitle region */
442 video_format_Init( &fmt, VLC_CODEC_YUVP );
445 The video on which the subtitle sits, is scaled, probably
446 4:3. However subtitle bitmaps assume an 1:1 aspect ratio.
448 FIXME: We should get the video aspect ratio from somewhere.
449 Two candidates are the video and the other possibility would be
450 the access module.
452 fmt.i_sar_num = p_sys->i_height;
453 fmt.i_sar_den = p_sys->i_width;
455 fmt.i_width = fmt.i_visible_width = p_sys->i_width;
456 fmt.i_height = fmt.i_visible_height = p_sys->i_height;
457 fmt.i_x_offset = fmt.i_y_offset = 0;
458 fmt.p_palette = &palette;
459 fmt.p_palette->i_entries = 4;
460 for( i = 0; i < fmt.p_palette->i_entries; i++ )
462 fmt.p_palette->palette[i][0] = p_sys->p_palette[i][0];
463 fmt.p_palette->palette[i][1] = p_sys->p_palette[i][1];
464 fmt.p_palette->palette[i][2] = p_sys->p_palette[i][2];
465 fmt.p_palette->palette[i][3] = p_sys->p_palette[i][3];
468 p_region = subpicture_region_New( &fmt );
469 fmt.p_palette = NULL;
470 video_format_Clean( &fmt );
471 if( !p_region )
473 msg_Err( p_dec, "cannot allocate SVCD subtitle region" );
474 subpicture_Delete( p_spu );
475 return NULL;
478 p_spu->p_region = p_region;
479 p_region->i_x = p_sys->i_x_start;
480 p_region->i_y = p_sys->i_y_start;
482 SVCDSubRenderImage( p_dec, p_data, p_region );
484 return p_spu;
487 /*****************************************************************************
488 * SVCDSubRenderImage: reorders bytes of image data in subpicture region.
489 *****************************************************************************
491 The image is encoded using two bits per pixel that select a palette
492 entry except that value 0 starts a limited run-length encoding for
493 color 0. When 0 is seen, the next two bits encode one less than the
494 number of pixels, so we can encode run lengths from 1 to 4. These get
495 filled with the color in palette entry 0.
497 The encoding of each line is padded to a whole number of bytes. The
498 first field is padded to an even byte length and the complete subtitle
499 is padded to a 4-byte multiple that always include one zero byte at
500 the end.
502 However we'll transform this so that that the RLE is expanded and
503 interlacing will also be removed.
504 *****************************************************************************/
505 static void SVCDSubRenderImage( decoder_t *p_dec, block_t *p_data,
506 subpicture_region_t *p_region )
508 decoder_sys_t *p_sys = p_dec->p_sys;
509 uint8_t *p_dest = p_region->p_picture->Y_PIXELS;
510 int i_field; /* The subtitles are interlaced */
511 int i_row, i_column; /* scanline row/column number */
512 uint8_t i_color, i_count;
513 bs_t bs;
515 bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset,
516 p_data->i_buffer - p_sys->i_image_offset );
518 for( i_field = 0; i_field < 2; i_field++ )
520 for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 )
522 for( i_column = 0; i_column < p_sys->i_width; i_column++ )
524 i_color = bs_read( &bs, 2 );
525 if( i_color == 0 && (i_count = bs_read( &bs, 2 )) )
527 i_count = __MIN( i_count, p_sys->i_width - i_column );
528 memset( &p_dest[i_row * p_region->p_picture->Y_PITCH +
529 i_column], 0, i_count + 1 );
530 i_column += i_count;
531 continue;
534 p_dest[i_row * p_region->p_picture->Y_PITCH + i_column] = i_color;
537 bs_align( &bs );
540 /* odd field */
541 bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset +
542 p_sys->second_field_offset,
543 p_data->i_buffer - p_sys->i_image_offset -
544 p_sys->second_field_offset );