input: add an input_item_t arg to input_CreateFilename()
[vlc.git] / modules / codec / cvdsub.c
blob9d185ca2288511522e85e8269c4216d12f446337
1 /*****************************************************************************
2 * cvdsub.c : CVD Subtitle 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>
38 #include <vlc_bits.h>
40 #define DEBUG_CVDSUB 1
42 /*****************************************************************************
43 * Module descriptor.
44 *****************************************************************************/
45 static int DecoderOpen ( vlc_object_t * );
46 static int PacketizerOpen( vlc_object_t * );
47 static void DecoderClose ( vlc_object_t * );
49 vlc_module_begin ()
50 set_description( N_("CVD subtitle decoder") )
51 set_capability( "spu decoder", 50 )
52 set_callbacks( DecoderOpen, DecoderClose )
54 add_submodule ()
55 set_description( N_("Chaoji VCD subtitle packetizer") )
56 set_capability( "packetizer", 50 )
57 set_callbacks( PacketizerOpen, DecoderClose )
58 vlc_module_end ()
60 /*****************************************************************************
61 * Local prototypes
62 *****************************************************************************/
63 static int Decode( decoder_t *, block_t * );
64 static block_t *Packetize ( decoder_t *, block_t ** );
65 static block_t *Reassemble ( decoder_t *, block_t * );
66 static void ParseMetaInfo ( decoder_t *, block_t * );
67 static void ParseHeader ( decoder_t *, block_t * );
68 static subpicture_t *DecodePacket( decoder_t *, block_t * );
69 static void RenderImage( decoder_t *, block_t *, subpicture_region_t * );
71 #define SUBTITLE_BLOCK_EMPTY 0
72 #define SUBTITLE_BLOCK_PARTIAL 1
73 #define SUBTITLE_BLOCK_COMPLETE 2
75 typedef struct
77 int b_packetizer;
79 int i_state; /* data-gathering state for this subtitle */
81 block_t *p_spu; /* Bytes of the packet. */
83 size_t i_spu_size; /* goal for subtitle_data_pos while gathering,
84 size of used subtitle_data later */
86 uint16_t i_image_offset; /* offset from subtitle_data to compressed
87 image data */
88 size_t i_image_length; /* size of the compressed image data */
89 size_t first_field_offset; /* offset of even raster lines */
90 size_t second_field_offset; /* offset of odd raster lines */
91 size_t metadata_offset; /* offset to data describing the image */
92 size_t metadata_length; /* length of metadata */
94 vlc_tick_t i_duration; /* how long to display the image, 0 stands
95 for "until next subtitle" */
97 uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
98 image when displayed */
99 uint16_t i_width, i_height; /* dimensions in pixels of image */
101 uint8_t p_palette[4][4]; /* Palette of colors used in subtitle */
102 uint8_t p_palette_highlight[4][4];
103 } decoder_sys_t;
105 static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
107 decoder_t *p_dec = (decoder_t*)p_this;
108 decoder_sys_t *p_sys;
110 if( p_dec->fmt_in.i_codec != VLC_CODEC_CVD )
111 return VLC_EGENERIC;
113 p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
114 if( !p_sys )
115 return VLC_ENOMEM;
117 p_sys->b_packetizer = b_packetizer;
119 p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
120 p_sys->p_spu = NULL;
122 if( b_packetizer )
124 p_dec->pf_packetize = Packetize;
125 p_dec->fmt_out.i_codec = VLC_CODEC_CVD;
127 else
129 p_dec->pf_decode = Decode;
130 p_dec->fmt_out.i_codec = VLC_CODEC_YUVP;
133 return VLC_SUCCESS;
135 /*****************************************************************************
136 * DecoderOpen: open/initialize the cvdsub decoder.
137 *****************************************************************************/
138 static int DecoderOpen( vlc_object_t *p_this )
140 return OpenCommon( p_this, false );
143 /*****************************************************************************
144 * PacketizerOpen: open/initialize the cvdsub packetizer.
145 *****************************************************************************/
146 static int PacketizerOpen( vlc_object_t *p_this )
148 return OpenCommon( p_this, true );
151 /*****************************************************************************
152 * DecoderClose: closes the cvdsub 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 block_t *p_data;
170 if( p_block == NULL ) /* No Drain */
171 return VLCDEC_SUCCESS;
173 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
175 block_Release( p_block );
176 return VLCDEC_SUCCESS;
179 if( !(p_data = Reassemble( p_dec, p_block )) )
180 return VLCDEC_SUCCESS;
182 /* Parse and decode */
183 subpicture_t *p_spu = DecodePacket( p_dec, p_data );
184 block_Release( p_data );
185 if( p_spu != NULL )
186 decoder_QueueSub( p_dec, p_spu );
187 return VLCDEC_SUCCESS;
190 /*****************************************************************************
191 * Packetize:
192 *****************************************************************************/
193 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
195 block_t *p_block, *p_spu;
197 if( pp_block == NULL || *pp_block == NULL ) return NULL;
199 p_block = *pp_block;
200 *pp_block = NULL;
202 if( !(p_spu = Reassemble( p_dec, p_block )) ) return NULL;
204 p_spu->i_dts = p_spu->i_pts;
205 p_spu->i_length = 0;
207 return p_spu;
211 /*****************************************************************************
212 Reassemble:
214 Data for single screen subtitle may come in several non-contiguous
215 packets of a stream. This routine is called when the next packet in
216 the stream comes in. The job of this routine is to parse the header,
217 if this is the beginning, and combine the packets into one complete
218 subtitle unit.
220 If everything is complete, we will return a block. Otherwise return
221 NULL.
223 *****************************************************************************/
224 #define SPU_HEADER_LEN 1
226 static block_t *Reassemble( decoder_t *p_dec, block_t *p_block )
228 decoder_sys_t *p_sys = p_dec->p_sys;
230 if( p_block->i_buffer < SPU_HEADER_LEN )
232 msg_Dbg( p_dec, "invalid packet header (size %zu < %u)" ,
233 p_block->i_buffer, SPU_HEADER_LEN );
234 block_Release( p_block );
235 return NULL;
238 /* From the scant data on the format, there is only only way known
239 * to detect the first packet in a subtitle. The first packet
240 * seems to have a valid PTS while later packets for the same
241 * image don't. */
242 if( p_sys->i_state == SUBTITLE_BLOCK_EMPTY && p_block->i_pts == VLC_TICK_INVALID )
244 msg_Warn( p_dec, "first packet expected but no PTS present");
245 return NULL;
248 p_block->p_buffer += SPU_HEADER_LEN;
249 p_block->i_buffer -= SPU_HEADER_LEN;
251 /* First packet in the subtitle block */
252 if( p_sys->i_state == SUBTITLE_BLOCK_EMPTY ) ParseHeader( p_dec, p_block );
254 block_ChainAppend( &p_sys->p_spu, p_block );
255 p_sys->p_spu = block_ChainGather( p_sys->p_spu );
257 if( p_sys->p_spu->i_buffer >= p_sys->i_spu_size )
259 block_t *p_spu = p_sys->p_spu;
261 if( p_spu->i_buffer != p_sys->i_spu_size )
263 msg_Warn( p_dec, "SPU packets size=%zu should be %zu",
264 p_spu->i_buffer, p_sys->i_spu_size );
267 msg_Dbg( p_dec, "subtitle packet complete, size=%zuu", p_spu->i_buffer);
269 ParseMetaInfo( p_dec, p_spu );
271 p_sys->i_state = SUBTITLE_BLOCK_EMPTY;
272 p_sys->p_spu = 0;
273 return p_spu;
275 else
277 /* Not last block in subtitle, so wait for another. */
278 p_sys->i_state = SUBTITLE_BLOCK_PARTIAL;
281 return NULL;
285 We do not have information on the subtitle format used on CVD's
286 except the submux sample code and a couple of samples of dubious
287 origin. Thus, this is the result of reading some code whose
288 correctness is not known and some experimentation.
290 CVD subtitles are different in several ways from SVCD OGT subtitles.
291 Image comes first and metadata is at the end. So that the metadata
292 can be found easily, the subtitle packet starts with two bytes
293 (everything is big-endian again) that give the total size of the
294 subtitle data and the offset to the metadata - i.e. size of the
295 image data plus the four bytes at the beginning.
297 Image data comes interlaced is run-length encoded. Each field is a
298 four-bit nibble. Each nibble contains a two-bit repeat count and a
299 two-bit color number so that up to three pixels can be described in
300 four bits. The function of a 0 repeat count is unknown; it might be
301 used for RLE extension. However when the full nibble is zero, the
302 rest of the line is filled with the color value in the next nibble.
303 It is unknown what happens if the color value is greater than three.
304 The rest seems to use a 4-entries palette. It is not impossible
305 that the fill-line complete case above is not as described and the
306 zero repeat count means fill line. The sample code never produces
307 this, so it may be untested.
310 static void ParseHeader( decoder_t *p_dec, block_t *p_block )
312 decoder_sys_t *p_sys = p_dec->p_sys;
313 uint8_t *p = p_block->p_buffer;
315 p_sys->i_spu_size = (p[0] << 8) + p[1] + 4; p += 2;
317 /* FIXME: check data sanity */
318 p_sys->metadata_offset = (p[0] << 8) + p[1]; p +=2;
319 p_sys->metadata_length = p_sys->i_spu_size - p_sys->metadata_offset;
321 p_sys->i_image_offset = 4;
322 p_sys->i_image_length = p_sys->metadata_offset - p_sys->i_image_offset;
324 #ifdef DEBUG_CVDSUB
325 msg_Dbg( p_dec, "total size: %zu image size: %zu",
326 p_sys->i_spu_size, p_sys->i_image_length );
327 #endif
331 We parse the metadata information here.
333 Although metadata information does not have to come in a fixed field
334 order, every metadata field consists of a tag byte followed by
335 parameters. In all cases known, the size including tag byte is
336 exactly four bytes in length.
339 #define ExtractXY(x, y) x = ((p[1]&0x0f)<<6) + (p[2]>>2); \
340 y = ((p[2]&0x03)<<8) + p[3];
342 static void ParseMetaInfo( decoder_t *p_dec, block_t *p_spu )
344 /* Last packet in subtitle block. */
346 decoder_sys_t *p_sys = p_dec->p_sys;
347 uint8_t *p = p_spu->p_buffer + p_sys->metadata_offset;
348 uint8_t *p_end = p + p_sys->metadata_length;
350 for( ; p < p_end; p += 4 )
352 switch( p[0] )
354 case 0x04: /* subtitle duration in 1/90000ths of a second */
355 p_sys->i_duration = (p[1]<<16) + (p[2]<<8) + p[3];
357 #ifdef DEBUG_CVDSUB
358 msg_Dbg( p_dec, "subtitle display duration %lu secs",
359 (long unsigned int)(p_sys->i_duration / 90000) );
360 #endif
361 p_sys->i_duration *= 100 / 9;
362 break;
364 case 0x0c: /* unknown */
365 #ifdef DEBUG_CVDSUB
366 msg_Dbg( p_dec, "subtitle command unknown 0x%0x 0x%0x 0x%0x 0x%0x",
367 (int)p[0], (int)p[1], (int)p[2], (int)p[3] );
368 #endif
369 break;
371 case 0x17: /* coordinates of subtitle upper left x, y position */
372 ExtractXY(p_sys->i_x_start, p_sys->i_y_start);
374 #ifdef DEBUG_CVDSUB
375 msg_Dbg( p_dec, "start position (%d,%d)",
376 p_sys->i_x_start, p_sys->i_y_start );
377 #endif
378 break;
380 case 0x1f: /* coordinates of subtitle bottom right x, y position */
382 int lastx;
383 int lasty;
384 ExtractXY(lastx, lasty);
385 p_sys->i_width = lastx - p_sys->i_x_start + 1;
386 p_sys->i_height = lasty - p_sys->i_y_start + 1;
388 #ifdef DEBUG_CVDSUB
389 msg_Dbg( p_dec, "end position (%d,%d), w x h: %dx%d",
390 lastx, lasty, p_sys->i_width, p_sys->i_height );
391 #endif
392 break;
395 case 0x24:
396 case 0x25:
397 case 0x26:
398 case 0x27:
400 uint8_t v = p[0] - 0x24;
402 #ifdef DEBUG_CVDSUB
403 /* Primary Palette */
404 msg_Dbg( p_dec, "primary palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)",
405 (int)v, (int)p[1], (int)p[2], (int)p[3] );
406 #endif
408 p_sys->p_palette[v][0] = p[1]; /* Y */
409 p_sys->p_palette[v][1] = p[3]; /* Cr / V */
410 p_sys->p_palette[v][2] = p[2]; /* Cb / U */
411 break;
414 case 0x2c:
415 case 0x2d:
416 case 0x2e:
417 case 0x2f:
419 uint8_t v = p[0] - 0x2c;
421 #ifdef DEBUG_CVDSUB
422 msg_Dbg( p_dec,"highlight palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)",
423 (int)v, (int)p[1], (int)p[2], (int)p[3] );
424 #endif
426 /* Highlight Palette */
427 p_sys->p_palette_highlight[v][0] = p[1]; /* Y */
428 p_sys->p_palette_highlight[v][1] = p[3]; /* Cr / V */
429 p_sys->p_palette_highlight[v][2] = p[2]; /* Cb / U */
430 break;
433 case 0x37:
434 /* transparency for primary palette */
435 p_sys->p_palette[0][3] = (p[3] & 0x0f) << 4;
436 p_sys->p_palette[1][3] = (p[3] >> 4) << 4;
437 p_sys->p_palette[2][3] = (p[2] & 0x0f) << 4;
438 p_sys->p_palette[3][3] = (p[2] >> 4) << 4;
440 #ifdef DEBUG_CVDSUB
441 msg_Dbg( p_dec, "transparency for primary palette 0..3: "
442 "0x%0x 0x%0x 0x%0x 0x%0x",
443 (int)p_sys->p_palette[0][3], (int)p_sys->p_palette[1][3],
444 (int)p_sys->p_palette[2][3], (int)p_sys->p_palette[3][3]);
445 #endif
446 break;
448 case 0x3f:
449 /* transparency for highlight palette */
450 p_sys->p_palette_highlight[0][3] = (p[2] & 0x0f) << 4;
451 p_sys->p_palette_highlight[1][3] = (p[2] >> 4) << 4;
452 p_sys->p_palette_highlight[2][3] = (p[1] & 0x0f) << 4;
453 p_sys->p_palette_highlight[3][3] = (p[1] >> 4) << 4;
455 #ifdef DEBUG_CVDSUB
456 msg_Dbg( p_dec, "transparency for highlight palette 0..3: "
457 "0x%0x 0x%0x 0x%0x 0x%0x",
458 (int)p_sys->p_palette_highlight[0][3],
459 (int)p_sys->p_palette_highlight[1][3],
460 (int)p_sys->p_palette_highlight[2][3],
461 (int)p_sys->p_palette_highlight[3][3] );
462 #endif
463 break;
465 case 0x47:
466 /* offset to start of even rows of interlaced image, we correct
467 * to make it relative to i_image_offset (usually 4) */
468 p_sys->first_field_offset =
469 (p[2] << 8) + p[3] - p_sys->i_image_offset;
470 #ifdef DEBUG_CVDSUB
471 msg_Dbg( p_dec, "1st_field_offset %zu",
472 p_sys->first_field_offset );
473 #endif
474 break;
476 case 0x4f:
477 /* offset to start of odd rows of interlaced image, we correct
478 * to make it relative to i_image_offset (usually 4) */
479 p_sys->second_field_offset =
480 (p[2] << 8) + p[3] - p_sys->i_image_offset;
481 #ifdef DEBUG_CVDSUB
482 msg_Dbg( p_dec, "2nd_field_offset %zu",
483 p_sys->second_field_offset);
484 #endif
485 break;
487 default:
488 #ifdef DEBUG_CVDSUB
489 msg_Warn( p_dec, "unknown sequence in control header "
490 "0x%0x 0x%0x 0x%0x 0x%0x", p[0], p[1], p[2], p[3]);
491 #endif
496 /*****************************************************************************
497 * DecodePacket: parse and decode an SPU packet
498 *****************************************************************************
499 * This function parses and decodes an SPU packet and, if valid, returns a
500 * subpicture.
501 *****************************************************************************/
502 static subpicture_t *DecodePacket( decoder_t *p_dec, block_t *p_data )
504 decoder_sys_t *p_sys = p_dec->p_sys;
505 subpicture_t *p_spu;
506 subpicture_region_t *p_region;
507 video_format_t fmt;
508 video_palette_t palette;
509 int i;
511 /* Allocate the subpicture internal data. */
512 p_spu = decoder_NewSubpicture( p_dec, NULL );
513 if( !p_spu ) return NULL;
515 p_spu->i_start = p_data->i_pts;
516 p_spu->i_stop = p_data->i_pts + p_sys->i_duration;
517 p_spu->b_ephemer = true;
519 /* Create new SPU region */
520 video_format_Init( &fmt, VLC_CODEC_YUVP );
521 fmt.i_sar_num = 1;
522 fmt.i_sar_den = 1;
523 fmt.i_width = fmt.i_visible_width = p_sys->i_width;
524 fmt.i_height = fmt.i_visible_height = p_sys->i_height;
525 fmt.i_x_offset = fmt.i_y_offset = 0;
526 fmt.p_palette = &palette;
527 fmt.p_palette->i_entries = 4;
528 for( i = 0; i < fmt.p_palette->i_entries; i++ )
530 fmt.p_palette->palette[i][0] = p_sys->p_palette[i][0];
531 fmt.p_palette->palette[i][1] = p_sys->p_palette[i][1];
532 fmt.p_palette->palette[i][2] = p_sys->p_palette[i][2];
533 fmt.p_palette->palette[i][3] = p_sys->p_palette[i][3];
536 p_region = subpicture_region_New( &fmt );
537 if( !p_region )
539 msg_Err( p_dec, "cannot allocate SPU region" );
540 subpicture_Delete( p_spu );
541 return NULL;
544 p_spu->p_region = p_region;
545 p_region->i_x = p_sys->i_x_start;
546 p_region->i_x = p_region->i_x * 3 / 4; /* FIXME: use aspect ratio for x? */
547 p_region->i_y = p_sys->i_y_start;
549 RenderImage( p_dec, p_data, p_region );
551 return p_spu;
554 /*****************************************************************************
555 * ParseImage: parse and render the image part of the subtitle
556 *****************************************************************************
557 This part parses the subtitle graphical data and renders it.
559 Image data comes interlaced and is run-length encoded (RLE). Each
560 field is a four-bit nibbles that is further subdivided in a two-bit
561 repeat count and a two-bit color number - up to three pixels can be
562 described in four bits. What a 0 repeat count means is unknown. It
563 might be used for RLE extension. There is a special case of a 0
564 repeat count though. When the full nibble is zero, the rest of the
565 line is filled with the color value in the next nibble. It is
566 unknown what happens if the color value is greater than three. The
567 rest seems to use a 4-entries palette. It is not impossible that the
568 fill-line complete case above is not as described and the zero repeat
569 count means fill line. The sample code never produces this, so it
570 may be untested.
572 However we'll transform this so that that the RLE is expanded and
573 interlacing will also be removed. On output each pixel entry will by
574 a 4-bit alpha (filling 8 bits), and 8-bit y, u, and v entry.
576 *****************************************************************************/
577 static void RenderImage( decoder_t *p_dec, block_t *p_data,
578 subpicture_region_t *p_region )
580 decoder_sys_t *p_sys = p_dec->p_sys;
581 uint8_t *p_dest = p_region->p_picture->Y_PIXELS;
582 int i_field; /* The subtitles are interlaced */
583 int i_row, i_column; /* scanline row/column number */
584 uint8_t i_color, i_count;
585 bs_t bs;
587 bs_init( &bs, p_data->p_buffer + p_sys->i_image_offset,
588 p_data->i_buffer - p_sys->i_image_offset );
590 for( i_field = 0; i_field < 2; i_field++ )
592 for( i_row = i_field; i_row < p_sys->i_height; i_row += 2 )
594 for( i_column = 0; i_column < p_sys->i_width; i_column++ )
596 uint8_t i_val = bs_read( &bs, 4 );
598 if( i_val == 0 )
600 /* Fill the rest of the line with next color */
601 i_color = bs_read( &bs, 4 );
603 memset( &p_dest[i_row * p_region->p_picture->Y_PITCH +
604 i_column], i_color,
605 p_sys->i_width - i_column );
606 i_column = p_sys->i_width;
607 continue;
609 else
611 /* Normal case: get color and repeat count */
612 i_count = (i_val >> 2);
613 i_color = i_val & 0x3;
615 i_count = __MIN( i_count, p_sys->i_width - i_column );
617 memset( &p_dest[i_row * p_region->p_picture->Y_PITCH +
618 i_column], i_color, i_count );
619 i_column += i_count - 1;
620 continue;
624 bs_align( &bs );