1 /*****************************************************************************
2 * parse.c: Philips OGT (SVCD subtitle) packet parser
3 *****************************************************************************
4 * Copyright (C) 2003, 2004 VideoLAN
7 * Authors: Rocky Bernstein
9 * Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
10 * Sam Hocevar <sam@zoy.org>
11 * Laurent Aimar <fenrir@via.ecp.fr>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
26 *****************************************************************************/
28 /*****************************************************************************
30 *****************************************************************************/
33 #include <vlc/decoder.h>
44 /* An image color is a two-bit palette entry: 0..3 */
45 typedef uint8_t ogt_color_t;
47 /*****************************************************************************
49 *****************************************************************************/
50 static int ParseImage ( decoder_t *, subpicture_t * );
53 We do not have information on the subtitle format used on CVD's
54 except the submux sample code and a couple of samples of dubious
55 origin. Thus, this is the result of reading some code whose
56 correctness is not known and some experimentation.
58 CVD subtitles are different in several ways from SVCD OGT subtitles.
59 Image comes first and metadata is at the end. So that the metadata
60 can be found easily, the subtitle packet starts with two bytes
61 (everything is big-endian again) that give the total size of the
62 subtitle data and the offset to the metadata - i.e. size of the
63 image data plus the four bytes at the beginning.
65 Image data comes interlaced is run-length encoded. Each field is a
66 four-bit nibble. Each nibble contains a two-bit repeat count and a
67 two-bit color number so that up to three pixels can be described in
68 four bits. The function of a 0 repeat count is unknown; it might be
69 used for RLE extension. However when the full nibble is zero, the
70 rest of the line is filled with the color value in the next nibble.
71 It is unknown what happens if the color value is greater than three.
72 The rest seems to use a 4-entries palette. It is not impossible
73 that the fill-line complete case above is not as described and the
74 zero repeat count means fill line. The sample code never produces
75 this, so it may be untested.
78 void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
80 decoder_sys_t *p_sys = p_dec->p_sys;
81 uint8_t *p = p_buffer+1;
83 dbg_print( (DECODE_DBG_CALL|DECODE_DBG_PACKET),
84 "header: 0x%02x 0x%02x 0x%02x 0x%02x, 0x%02x, 0x%02x, size: %i",
85 p_buffer[0], p_buffer[1], p_buffer[2], p_buffer[3],
86 p_buffer[4], p_buffer[5],
89 dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
91 p_sys->i_pts = p_block->i_pts;
92 p_sys->i_spu_size = (p[0] << 8) + p[1] + 4; p += 2;
94 /* FIXME: check data sanity */
95 p_sys->metadata_offset = GETINT16(p);
96 p_sys->metadata_length = p_sys->i_spu_size - p_sys->metadata_offset;
98 p_sys->i_image_offset = 4;
99 p_sys->i_image_length = p_sys->metadata_offset - p_sys->i_image_offset;
101 dbg_print(DECODE_DBG_PACKET, "total size: %d image size: %d\n",
102 p_sys->i_spu_size, p_sys->i_image_length);
106 #define ExtractXY(x, y) \
107 x = ((p[1]&0x0f)<<6) + (p[2]>>2); \
108 y = ((p[2]&0x03)<<8) + p[3];
112 We parse the metadata information here.
114 Although metadata information does not have to come in a fixed field
115 order, every metadata field consists of a tag byte followed by
116 parameters. In all cases known, the size including tag byte is
117 exactly four bytes in length.
120 void E_(ParseMetaInfo)( decoder_t *p_dec )
122 /* last packet in subtitle block. */
124 decoder_sys_t *p_sys = p_dec->p_sys;
125 uint8_t *p = p_sys->subtitle_data + p_sys->metadata_offset;
126 uint8_t *p_end = p + p_sys->metadata_length;
128 dbg_print( (DECODE_DBG_PACKET),
129 "subtitle packet complete, size=%d", p_sys->i_spu );
131 p_sys->state = SUBTITLE_BLOCK_COMPLETE;
134 for ( ; p < p_end; p += 4 ) {
138 case 0x04: /* subtitle duration in 1/90000ths of a second */
140 mtime_t i_duration = (p[1]<<16) + (p[2]<<8) + p[3];
141 mtime_t i_duration_scale = config_GetInt( p_dec, MODULE_STRING
142 "-duration-scaling" );
144 dbg_print( DECODE_DBG_PACKET,
145 "subtitle display duration %lu secs (scaled %lu secs)",
146 (long unsigned int) (i_duration / 90000),
147 (long unsigned int) (i_duration * i_duration_scale / 90000)
149 p_sys->i_duration = i_duration * i_duration_scale ;
154 case 0x0c: /* unknown */
155 dbg_print( DECODE_DBG_PACKET,
156 "subtitle command unknown 0x%0x 0x%0x 0x%0x 0x%0x\n",
157 p[0], p[1], p[2], p[3]);
160 case 0x17: /* coordinates of subtitle upper left x, y position */
161 ExtractXY(p_sys->i_x_start, p_sys->i_y_start);
164 case 0x1f: /* coordinates of subtitle bottom right x, y position */
168 ExtractXY(lastx, lasty);
169 p_sys->i_width = lastx - p_sys->i_x_start + 1;
170 p_sys->i_height = lasty - p_sys->i_y_start + 1;
171 dbg_print( DECODE_DBG_PACKET,
172 "end position: (%d,%d): %.2x %.2x %.2x, w x h: %dx%d",
173 lastx, lasty, p[1], p[2], p[3],
174 p_sys->i_width, p_sys->i_height );
184 uint8_t v = p[0]-0x24;
186 /* Primary Palette */
187 dbg_print( DECODE_DBG_PACKET,
188 "primary palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)",
189 v, p[1], p[2], p[3]);
191 p_sys->p_palette[v].s.y = p[1];
192 p_sys->p_palette[v].s.u = p[2];
193 p_sys->p_palette[v].s.v = p[3];
203 uint8_t v = p[0]-0x2c;
205 dbg_print( DECODE_DBG_PACKET,
206 "highlight palette %d (y,u,v): (0x%0x,0x%0x,0x%0x)",
207 v, p[1], p[2], p[3]);
209 /* Highlight Palette */
210 p_sys->p_palette_highlight[v].s.y = p[1];
211 p_sys->p_palette_highlight[v].s.u = p[2];
212 p_sys->p_palette_highlight[v].s.v = p[3];
217 /* transparency for primary palette */
218 p_sys->p_palette[0].s.t = p[3] & 0x0f;
219 p_sys->p_palette[1].s.t = p[3] >> 4;
220 p_sys->p_palette[2].s.t = p[2] & 0x0f;
221 p_sys->p_palette[3].s.t = p[2] >> 4;
223 dbg_print( DECODE_DBG_PACKET,
224 "transparency for primary palette 0..3: "
225 "0x%0x 0x%0x 0x%0x 0x%0x",
226 p_sys->p_palette[0].s.t,
227 p_sys->p_palette[1].s.t,
228 p_sys->p_palette[2].s.t,
229 p_sys->p_palette[3].s.t );
234 /* transparency for highlight palette */
235 p_sys->p_palette_highlight[0].s.t = p[2] & 0x0f;
236 p_sys->p_palette_highlight[1].s.t = p[2] >> 4;
237 p_sys->p_palette_highlight[2].s.t = p[1] & 0x0f;
238 p_sys->p_palette_highlight[3].s.t = p[1] >> 4;
240 dbg_print( DECODE_DBG_PACKET,
241 "transparency for primary palette 0..3: "
242 "0x%0x 0x%0x 0x%0x 0x%0x",
243 p_sys->p_palette_highlight[0].s.t,
244 p_sys->p_palette_highlight[1].s.t,
245 p_sys->p_palette_highlight[2].s.t,
246 p_sys->p_palette_highlight[3].s.t );
251 /* offset to start of even rows of interlaced image, we correct
252 to make it relative to i_image_offset (usually 4) */
253 p_sys->first_field_offset =
254 (p[2] << 8) + p[3] - p_sys->i_image_offset;
255 dbg_print( DECODE_DBG_PACKET,
256 "first_field_offset %d", p_sys->first_field_offset);
260 /* offset to start of odd rows of interlaced image, we correct
261 to make it relative to i_image_offset (usually 4) */
262 p_sys->second_field_offset =
263 (p[2] << 8) + p[3] - p_sys->i_image_offset;
264 dbg_print( DECODE_DBG_PACKET,
265 "second_field_offset %d", p_sys->second_field_offset);
270 "unknown sequence in control header "
271 "0x%0x 0x%0x 0x%0x 0x%0x",
272 p[0], p[1], p[2], p[3]);
274 p_sys->subtitle_data_pos = 0;
279 /*****************************************************************************
280 * ParsePacket: parse an SPU packet and send it to the video output
281 *****************************************************************************
282 * This function parses the SPU packet and, if valid, sends it to the
284 *****************************************************************************/
286 E_(ParsePacket)( decoder_t *p_dec)
288 decoder_sys_t *p_sys = p_dec->p_sys;
292 dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
294 /* Allocate the subpicture internal data. */
295 p_spu = spu_CreateSubpicture( p_sys->p_vout->p_spu );
296 if( p_spu == NULL ) return;
298 p_spu->i_channel = p_sys->i_subpic_channel;
300 /* In ParseImage we expand the run-length encoded color 0's; also
301 we expand pixels and remove the color palette. This should
302 facilitate scaling and antialiasing and speed up rendering.
304 p_spu->p_sys = malloc( sizeof( subpicture_sys_t )
305 + PIXEL_SIZE * (p_sys->i_width * p_sys->i_height) );
307 /* Fill the p_spu structure */
308 vlc_mutex_init( p_dec, &p_spu->p_sys->lock );
310 p_spu->pf_render = VCDSubBlend;
311 p_spu->pf_destroy = VCDSubDestroySPU;
312 p_spu->p_sys->p_data = (uint8_t*)p_spu->p_sys + sizeof( subpicture_sys_t );
314 p_spu->p_sys->i_x_end = p_sys->i_x_start + p_sys->i_width - 1;
315 p_spu->p_sys->i_y_end = p_sys->i_y_start + p_sys->i_height - 1;
317 p_spu->i_x = p_sys->i_x_start
318 + config_GetInt( p_dec, MODULE_STRING "-horizontal-correct" );
320 p_spu->p_sys->p_palette[0] = p_sys->p_palette[0];
321 p_spu->p_sys->p_palette[1] = p_sys->p_palette[1];
322 p_spu->p_sys->p_palette[2] = p_sys->p_palette[2];
323 p_spu->p_sys->p_palette[3] = p_sys->p_palette[3];
325 /* FIXME: use aspect ratio for x? */
326 p_spu->i_x = (p_spu->i_x * 3) / 4;
327 p_spu->i_y = p_sys->i_y_start
328 + config_GetInt( p_dec, MODULE_STRING "-vertical-correct" );
330 p_spu->i_width = p_sys->i_width;
331 p_spu->i_height = p_sys->i_height;
333 p_spu->i_start = p_sys->i_pts;
334 p_spu->i_stop = p_sys->i_pts + (p_sys->i_duration);
336 p_spu->p_sys->b_crop = VLC_FALSE;
337 p_spu->p_sys->i_debug = p_sys->i_debug;
339 /* Get display time now. If we do it later, we may miss the PTS. */
340 p_spu->p_sys->i_pts = p_sys->i_pts;
342 /* Attach to our input thread */
343 p_spu->p_sys->p_input = vlc_object_find( p_dec,
344 VLC_OBJECT_INPUT, FIND_PARENT );
346 /* We try to display it */
347 if( ParseImage( p_dec, p_spu ) )
349 /* There was a parse error, delete the subpicture */
350 spu_DestroySubpicture( p_sys->p_vout->p_spu, p_spu );
354 /* SPU is finished - we can ask the video output to display it */
355 spu_DisplaySubpicture( p_sys->p_vout->p_spu, p_spu );
359 #define advance_color_byte_pointer \
361 i_nibble_field = 2; \
363 * This is wrong, it may exceed maxp if it is the last, check \
364 * should be moved to use location or the algorithm changed to \
369 "broken subtitle - overflow while decoding " \
370 " padding (%d,%d,%d)\n", \
371 i_field, i_row, i_column ); \
372 return VLC_EGENERIC; \
375 #define CVD_FIELD_BITS (4)
376 #define CVD_FIELD_MASK ((1<<CVD_FIELD_BITS) - 1)
378 /* Get the next field - a 2-bit palette index and a run count. To do
379 this we use byte image pointer p, and i_nibble_field which
380 indicates where we are in the byte.
382 static inline uint8_t
383 ExtractField(uint8_t *p, uint8_t i_nibble_field)
385 return ( ( *p >> (CVD_FIELD_BITS*(i_nibble_field-1)) ) & CVD_FIELD_MASK );
388 /*****************************************************************************
389 * ParseImage: parse the image part of the subtitle
390 *****************************************************************************
391 This part parses the subtitle graphical data and stores it in a more
392 convenient structure for later rendering.
394 Image data comes interlaced and is run-length encoded (RLE). Each
395 field is a four-bit nibbles that is further subdivided in a two-bit
396 repeat count and a two-bit color number - up to three pixels can be
397 described in four bits. What a 0 repeat count means is unknown. It
398 might be used for RLE extension. There is a special case of a 0
399 repeat count though. When the full nibble is zero, the rest of the
400 line is filled with the color value in the next nibble. It is
401 unknown what happens if the color value is greater than three. The
402 rest seems to use a 4-entries palette. It is not impossible that the
403 fill-line complete case above is not as described and the zero repeat
404 count means fill line. The sample code never produces this, so it
407 However we'll transform this so that that the RLE is expanded and
408 interlacing will also be removed. On output each pixel entry will by
409 a 4-bit alpha (filling 8 bits), and 8-bit y, u, and v entry.
411 *****************************************************************************/
413 ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
415 decoder_sys_t *p_sys = p_dec->p_sys;
417 uint8_t i_field; /* The subtitles are interlaced, are we on an
418 even or odd scanline? */
419 unsigned int i_row; /* scanline row number */
420 unsigned int i_column; /* scanline column number */
422 unsigned int i_width = p_sys->i_width;
423 unsigned int i_height = p_sys->i_height;
425 uint8_t *p_dest = (uint8_t *)p_spu->p_sys->p_data;
427 uint8_t i_nibble_field; /* The 2-bit pixels remaining in byte of *p.
429 vlc_bool_t b_filling; /* Filling i_color to the of the line. */
430 uint8_t i_pending = 0; /* number of pixels to fill with
432 ogt_color_t i_color=0; /* current pixel color: 0..3 */
433 uint8_t *p = p_sys->subtitle_data + p_sys->i_image_offset;
434 uint8_t *maxp = p + p_sys->i_image_length;
436 dbg_print( (DECODE_DBG_CALL) , "width x height: %dx%d",
439 if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)
444 for ( i_field=0; i_field < 2; i_field++ ) {
445 i_nibble_field = 2; /* 4-bit pieces available in *p */
450 for (i=0; i< i_width * i_height; i++)
451 printf ("%02x", b[i]);
455 for ( i_row=i_field; i_row < i_height; i_row += 2 ) {
456 b_filling = VLC_FALSE;
457 for ( i_column=0; i_column<i_width; i_column++ ) {
459 /* We are in the middle of a RLE expansion, just decrement and
460 fall through with current color value */
462 } else if ( b_filling ) {
463 /* We are just filling to the end of line with one color, just
464 reuse current color value */
466 uint8_t i_val = ExtractField(p, i_nibble_field--);
467 if ( i_nibble_field == 0 ) {
468 advance_color_byte_pointer;
471 /* fill the rest of the line with next color */
472 i_color = ExtractField( p, i_nibble_field-- );
473 if ( i_nibble_field == 0 ) {
477 This is wrong, it may exceed maxp if it is the
478 last, check should be moved to use location or the
479 algorithm changed to that in vob2sub
483 "broken subtitle - overflow while decoding "
484 " filling (%d,%d,%d)",
485 i_field, i_row, i_column);
486 /* return VLC_EGENERIC; */
489 b_filling = VLC_TRUE;
491 /* Normal case: get color and repeat count,
492 this iteration will output the first (or only)
494 i_pending = (i_val >> 2);
495 i_color = i_val & 0x3;
496 /* This time counts against the total */
501 p_dest[i_row*i_width+i_column] = i_color;
503 if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)
504 printf("%1d", i_color);
508 if ( i_nibble_field == 1 ) {
509 advance_color_byte_pointer;
512 if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)
517 if (p_sys && (p_sys->i_debug & DECODE_DBG_IMAGE)) {
518 /* Dump out image not interlaced... */
519 VCDSubDumpImage( p_dest, i_height, i_width );
523 if (p_sys && (p_sys->i_debug & DECODE_DBG_PNG)) {
525 /* Dump image to a file in PNG format. */
527 png_text text_ptr[TEXT_COUNT];
529 text_ptr[0].key = "Preparer";
530 text_ptr[0].text = "VLC";
531 text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
532 text_ptr[1].key = "Description";
533 text_ptr[1].text = "CVD Subtitle";
534 text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
536 snprintf(filename, 300, "%s%d.png", "/tmp/vlc-cvd-sub", p_sys->i_image);
537 VCDSubDumpPNG( p_dest, p_dec, i_height, i_width, filename,
538 text_ptr, TEXT_COUNT );
540 #endif /*HAVE_LIBPNG*/
542 VCDSubHandleScaling( p_spu, p_dec );