demux: libmp4: fix ReadBoxUsing function return check
[vlc.git] / modules / codec / svcdsub.c
blobc7579b185123eade94d0eb3ccd8a3f1cdc289e1b
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 #include "../demux/mpeg/timestamps.h"
41 /*****************************************************************************
42 * Module descriptor.
43 *****************************************************************************/
44 static int DecoderOpen ( vlc_object_t * );
45 static int PacketizerOpen( vlc_object_t * );
46 static void DecoderClose ( vlc_object_t * );
48 vlc_module_begin ()
49 set_description( N_("Philips OGT (SVCD subtitle) decoder") )
50 set_shortname( N_("SVCD subtitles") )
51 set_category( CAT_INPUT )
52 set_subcategory( SUBCAT_INPUT_SCODEC )
53 set_capability( "spu decoder", 50 )
54 set_callbacks( DecoderOpen, DecoderClose )
56 add_obsolete_integer ( "svcdsub-debug" )
58 add_submodule ()
59 set_description( N_("Philips OGT (SVCD subtitle) packetizer") )
60 set_capability( "packetizer", 50 )
61 set_callbacks( PacketizerOpen, DecoderClose )
62 vlc_module_end ()
64 /*****************************************************************************
65 * Local prototypes
66 *****************************************************************************/
67 static int Decode( decoder_t *, block_t * );
68 static block_t *Packetize ( decoder_t *, block_t ** );
69 static block_t *Reassemble ( decoder_t *, block_t * );
70 static void ParseHeader( decoder_t *, block_t * );
71 static subpicture_t *DecodePacket( decoder_t *, block_t * );
72 static void SVCDSubRenderImage( decoder_t *, block_t *, subpicture_region_t * );
74 #define GETINT16(p) GetWBE(p) ; p +=2;
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 = VLC_TICK_INVALID;
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 = FROM_SCALE_NZ(GetDWBE(p)); p += 4; }
379 else p_sys->i_duration = 0; /* Ephemer subtitle */
381 p_sys->i_x_start = GETINT16(p);
382 p_sys->i_y_start = GETINT16(p);
383 p_sys->i_width = GETINT16(p);
384 p_sys->i_height = GETINT16(p);
386 for( i = 0; i < 4; i++ )
388 p_sys->p_palette[i][0] = *p++; /* Y */
389 p_sys->p_palette[i][2] = *p++; /* Cr / V */
390 p_sys->p_palette[i][1] = *p++; /* Cb / U */
391 p_sys->p_palette[i][3] = *p++; /* T */
394 i_cmd = *p++;
395 /* We do not really know this, FIXME */
396 if( i_cmd ) { p += 4; }
398 /* Actually, this is measured against a different origin, so we have to
399 * adjust it */
400 p_sys->second_field_offset = GETINT16(p);
401 p_sys->i_image_offset = p - p_block->p_buffer;
402 p_sys->i_image_length = p_sys->i_spu_size - p_sys->i_image_offset;
403 p_sys->metadata_length = p_sys->i_image_offset;
405 #ifndef NDEBUG
406 msg_Dbg( p_dec, "x-start: %d, y-start: %d, width: %d, height %d, "
407 "spu size: %zu, duration: %"PRIu64" (d:%zu p:%"PRIu16")",
408 p_sys->i_x_start, p_sys->i_y_start,
409 p_sys->i_width, p_sys->i_height,
410 p_sys->i_spu_size, p_sys->i_duration,
411 p_sys->i_image_length, p_sys->i_image_offset);
413 for( i = 0; i < 4; i++ )
415 msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
416 p_sys->p_palette[i][3], p_sys->p_palette[i][0],
417 p_sys->p_palette[i][1], p_sys->p_palette[i][2] );
419 #endif
422 /*****************************************************************************
423 * DecodePacket: parse and decode an subtitle packet
424 *****************************************************************************
425 * This function parses and decodes an SPU packet and, if valid, returns a
426 * subpicture.
427 *****************************************************************************/
428 static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
430 decoder_sys_t *p_sys = p_dec->p_sys;
431 subpicture_t *p_spu;
432 subpicture_region_t *p_region;
433 video_format_t fmt;
434 video_palette_t palette;
435 int i;
437 /* Allocate the subpicture internal data. */
438 p_spu = decoder_NewSubpicture( p_dec, NULL );
439 if( !p_spu ) return NULL;
441 p_spu->i_start = p_data->i_pts;
442 p_spu->i_stop = p_data->i_pts + p_sys->i_duration;
443 p_spu->b_ephemer = true;
445 /* Create new subtitle region */
446 video_format_Init( &fmt, VLC_CODEC_YUVP );
449 The video on which the subtitle sits, is scaled, probably
450 4:3. However subtitle bitmaps assume an 1:1 aspect ratio.
452 FIXME: We should get the video aspect ratio from somewhere.
453 Two candidates are the video and the other possibility would be
454 the access module.
456 fmt.i_sar_num = p_sys->i_height;
457 fmt.i_sar_den = p_sys->i_width;
459 fmt.i_width = fmt.i_visible_width = p_sys->i_width;
460 fmt.i_height = fmt.i_visible_height = p_sys->i_height;
461 fmt.i_x_offset = fmt.i_y_offset = 0;
462 fmt.p_palette = &palette;
463 fmt.p_palette->i_entries = 4;
464 for( i = 0; i < fmt.p_palette->i_entries; i++ )
466 fmt.p_palette->palette[i][0] = p_sys->p_palette[i][0];
467 fmt.p_palette->palette[i][1] = p_sys->p_palette[i][1];
468 fmt.p_palette->palette[i][2] = p_sys->p_palette[i][2];
469 fmt.p_palette->palette[i][3] = p_sys->p_palette[i][3];
472 p_region = subpicture_region_New( &fmt );
473 fmt.p_palette = NULL;
474 video_format_Clean( &fmt );
475 if( !p_region )
477 msg_Err( p_dec, "cannot allocate SVCD subtitle region" );
478 subpicture_Delete( p_spu );
479 return NULL;
482 p_spu->p_region = p_region;
483 p_region->i_x = p_sys->i_x_start;
484 p_region->i_y = p_sys->i_y_start;
486 SVCDSubRenderImage( p_dec, p_data, p_region );
488 return p_spu;
491 /*****************************************************************************
492 * SVCDSubRenderImage: reorders bytes of image data in subpicture region.
493 *****************************************************************************
495 The image is encoded using two bits per pixel that select a palette
496 entry except that value 0 starts a limited run-length encoding for
497 color 0. When 0 is seen, the next two bits encode one less than the
498 number of pixels, so we can encode run lengths from 1 to 4. These get
499 filled with the color in palette entry 0.
501 The encoding of each line is padded to a whole number of bytes. The
502 first field is padded to an even byte length and the complete subtitle
503 is padded to a 4-byte multiple that always include one zero byte at
504 the end.
506 However we'll transform this so that that the RLE is expanded and
507 interlacing will also be removed.
508 *****************************************************************************/
509 static void SVCDSubRenderImage( decoder_t *p_dec, block_t *p_data,
510 subpicture_region_t *p_region )
512 decoder_sys_t *p_sys = p_dec->p_sys;
513 uint8_t *p_dest = p_region->p_picture->Y_PIXELS;
514 int i_field; /* The subtitles are interlaced */
515 int i_row, i_column; /* scanline row/column number */
516 uint8_t i_color, i_count;
517 bs_t bs;
519 bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset,
520 p_data->i_buffer - p_sys->i_image_offset );
522 for( i_field = 0; i_field < 2; i_field++ )
524 for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 )
526 for( i_column = 0; i_column < p_sys->i_width; i_column++ )
528 i_color = bs_read( &bs, 2 );
529 if( i_color == 0 && (i_count = bs_read( &bs, 2 )) )
531 i_count = __MIN( i_count, p_sys->i_width - i_column );
532 memset( &p_dest[i_row * p_region->p_picture->Y_PITCH +
533 i_column], 0, i_count + 1 );
534 i_column += i_count;
535 continue;
538 p_dest[i_row * p_region->p_picture->Y_PITCH + i_column] = i_color;
541 bs_align( &bs );
544 /* odd field */
545 bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset +
546 p_sys->second_field_offset,
547 p_data->i_buffer - p_sys->i_image_offset -
548 p_sys->second_field_offset );