1 /*****************************************************************************
2 * parse.c: Philips OGT (SVCD subtitle) packet parser
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: cvd_parse.c,v 1.3 2003/12/29 04:47:44 rocky Exp $
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>
40 /* An image color is a two-bit palette entry: 0..3 */
41 typedef uint8_t ogt_color_t;
43 /*****************************************************************************
45 *****************************************************************************/
46 static int ParseImage ( decoder_t *, subpicture_t * );
49 * We do not have information on the subtitle format used on CVD's
50 * except the submux sample code and a couple of samples of dubious
51 * origin. Thus, this is the result of reading some code whose
52 * correctness is not known and some experimentation.
54 * CVD subtitles present several differences compared to SVCD OGT
55 * subtitles. Firstly, the image comes first and the metadata is at
56 * the end. So that the metadata can be found easily, the subtitle
57 * begins with two two-byte (everything is big-endian again) that
58 * describe, the total size of the subtitle data and the offset to the
59 * metadata (size of the image data plus the four bytes at the
62 * Image data comes interlaced and uses RLE. Coding is based in
63 * four-bit nibbles that are further subdivided in a two-bit repeat
64 * count and a two-bit color number so that up to three pixels can be
65 * describe with a total of four bits. The function of a 0 repeat
66 * count is unknown. It might be used for RLE extension. There is a
67 * special case, though. When the full nibble is zero, the rest of
68 * the line is filled with the color value in the next nibble. It is
69 * unknown what happens if the color value is greater than three. The
70 * rest seems to use a 4-entries palette. It is not impossible that
71 * the fill-line complete case above is not as described and the zero
72 * repeat count means fill line. The sample code never produces this,
73 * so it may be untested.
75 * The metadata section does not follow a fixed pattern, every
76 * metadata item consists of a tag byte followed by parameters. In all
77 * cases known, the block (including the tag byte) is exactly four
78 * bytes in length. Read the code for the rest.
81 /* FIXME: do we really need p_buffer and p?
82 Can't all of thes _offset's and _lengths's get removed?
84 void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
86 decoder_sys_t *p_sys = p_dec->p_sys;
87 u_int8_t *p = p_buffer+1;
89 dbg_print( (DECODE_DBG_CALL|DECODE_DBG_PACKET),
90 "header: 0x%02x 0x%02x 0x%02x 0x%02x, 0x%02x, 0x%02x, size: %i",
91 p_buffer[0], p_buffer[1], p_buffer[2], p_buffer[3],
92 p_buffer[4], p_buffer[5],
95 dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
97 p_sys->i_pts = p_block->i_pts;
98 p_sys->i_spu_size = (p[0] << 8) + p[1] + 4; p += 2;
100 /* FIXME: check data sanity */
101 p_sys->metadata_offset = GETINT16(p);
102 p_sys->metadata_length = p_sys->i_spu_size - p_sys->metadata_offset;
104 p_sys->comp_image_offset = 4;
105 p_sys->comp_image_length = p_sys->metadata_offset - p_sys->comp_image_offset;
107 dbg_print(DECODE_DBG_PACKET, "total size: %d image size: %d\n",
108 p_sys->i_spu_size, p_sys->comp_image_length);
113 /*****************************************************************************
114 * ParsePacket: parse an SPU packet and send it to the video output
115 *****************************************************************************
116 * This function parses the SPU packet and, if valid, sends it to the
118 *****************************************************************************/
120 E_(ParsePacket)( decoder_t *p_dec)
122 decoder_sys_t *p_sys = p_dec->p_sys;
126 dbg_print( (DECODE_DBG_CALL|DECODE_DBG_EXT) , "");
128 /* Allocate the subpicture internal data. */
129 p_spu = vout_CreateSubPicture( p_sys->p_vout, MEMORY_SUBPICTURE );
135 /* In ParseImage we expand the run-length encoded color 0's; also
136 we expand pixels and remove the color palette. This should
137 facilitate scaling and antialiasing and speed up rendering.
139 p_spu->p_sys = malloc( sizeof( subpicture_sys_t )
140 + PIXEL_SIZE * (p_sys->i_width * p_sys->i_height) );
142 /* Fill the p_spu structure */
143 vlc_mutex_init( p_dec, &p_spu->p_sys->lock );
145 p_spu->pf_render = VCDSubRender;
146 p_spu->pf_destroy = VCDSubDestroySPU;
147 p_spu->p_sys->p_data = (uint8_t*)p_spu->p_sys + sizeof( subpicture_sys_t );
149 p_spu->p_sys->i_x_end = p_sys->i_x_start + p_sys->i_width - 1;
150 p_spu->p_sys->i_y_end = p_sys->i_y_start + p_sys->i_height - 1;
152 /* FIXME: use aspect ratio for x? */
153 p_spu->i_x = p_sys->i_x_start * 3 / 4;
154 p_spu->i_y = p_sys->i_y_start;
155 p_spu->i_width = p_sys->i_width;
156 p_spu->i_height = p_sys->i_height;
158 p_spu->i_start = p_sys->i_pts;
159 p_spu->i_stop = p_sys->i_pts + (p_sys->i_duration * 10);
161 p_spu->p_sys->b_crop = VLC_FALSE;
162 p_spu->p_sys->i_debug = p_sys->i_debug;
164 /* Get display time now. If we do it later, we may miss the PTS. */
165 p_spu->p_sys->i_pts = p_sys->i_pts;
167 /* Attach to our input thread */
168 p_spu->p_sys->p_input = vlc_object_find( p_dec,
169 VLC_OBJECT_INPUT, FIND_PARENT );
171 /* We try to display it */
172 if( ParseImage( p_dec, p_spu ) )
174 /* There was a parse error, delete the subpicture */
175 vout_DestroySubPicture( p_sys->p_vout, p_spu );
179 /* SPU is finished - we can ask the video output to display it */
180 vout_DisplaySubPicture( p_sys->p_vout, p_spu );
184 #define advance_color_byte_pointer \
188 * This is wrong, it may exceed maxp if it is the last, check \
189 * should be moved to use location or the algorithm changed to \
194 "broken subtitle - overflow while decoding " \
195 " padding (%d,%d,%d)\n", \
196 i_field, i_row, i_column ); \
197 return VLC_EGENERIC; \
200 /* Get the next field - either a palette index or a RLE count for
201 color 0. To do this we use byte image pointer p, and i_remaining
202 which indicates where we are in the byte.
204 static inline uint8_t
205 ExtractField(uint8_t *p, unsigned int i_remaining)
207 return ( ( *p >> 4*(i_remaining-1) ) & 0xf );
210 /*****************************************************************************
211 * ParseImage: parse the image part of the subtitle
212 *****************************************************************************
213 This part parses the subtitle graphical data and stores it in a more
214 convenient structure for later rendering.
216 Image data comes interlaced and is run-length encoded (RLE). Each
217 field is a four-bit nibbles that is further subdivided in a two-bit
218 repeat count and a two-bit color number - up to three pixels can be
219 described in four bits. What a 0 repeat count means is unknown. It
220 might be used for RLE extension. There is a special case of a 0
221 repeat count though. When the full nibble is zero, the rest of the
222 line is filled with the color value in the next nibble. It is
223 unknown what happens if the color value is greater than three. The
224 rest seems to use a 4-entries palette. It is not impossible that the
225 fill-line complete case above is not as described and the zero repeat
226 count means fill line. The sample code never produces this, so it
229 However we'll transform this so that that the RLE is expanded and
230 interlacing will also be removed. On output each pixel entry will by
231 a 4-bit alpha (filling 8 bits), and 8-bit y, u, and v entry.
233 *****************************************************************************/
235 ParseImage( decoder_t *p_dec, subpicture_t * p_spu )
237 decoder_sys_t *p_sys = p_dec->p_sys;
239 unsigned int i_field; /* The subtitles are interlaced, are we on an
240 even or odd scanline? */
242 unsigned int i_row; /* scanline row number */
243 unsigned int i_column; /* scanline column number */
245 unsigned int i_width = p_sys->i_width;
246 unsigned int i_height = p_sys->i_height;
248 uint8_t *p_dest = (uint8_t *)p_spu->p_sys->p_data;
250 uint8_t i_remaining; /* number of 2-bit pixels remaining
252 vlc_bool_t b_filling; /* Filling i_color to the of the line. */
253 uint8_t i_pending = 0; /* number of pixels to fill with
255 ogt_color_t i_color=0; /* current pixel color: 0..3 */
256 uint8_t *p = p_sys->subtitle_data + p_sys->comp_image_offset;
257 uint8_t *maxp = p + p_sys->comp_image_length;
259 dbg_print( (DECODE_DBG_CALL) , "width x height: %dx%d ",
262 if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)
267 for ( i_field=0; i_field < 2; i_field++ ) {
268 i_remaining = 2; /* 4-bit pieces available in *p */
269 b_filling = VLC_FALSE;
271 for ( i_row=i_field; i_row < i_height; i_row += 2 ) {
272 for ( i_column=0; i_column<i_width; i_column++ ) {
274 /* We are in the middle of a RLE expansion, just decrement and
275 fall through with current color value */
277 } else if ( b_filling ) {
278 /* We are just filling to the end of line with one color, just
279 reuse current color value */
281 uint8_t i_val = ExtractField(p, i_remaining--);
282 if ( i_remaining == 0 ) {
283 advance_color_byte_pointer;
286 /* fill the rest of the line with next color */
287 i_color = ExtractField( p, i_remaining-- );
288 if ( i_remaining == 0 ) {
292 This is wrong, it may exceed maxp if it is the
293 last, check should be moved to use location or the
294 algorithm changed to that in vob2sub
298 "broken subtitle - overflow while decoding "
299 " filling (%d,%d,%d)",
300 i_field, i_row, i_column);
301 /* return VLC_EGENERIC; */
304 b_filling = VLC_TRUE;
306 /* Normal case: get color and repeat count,
307 this iteration will output the first (or only)
309 i_pending = (i_val >> 2);
310 i_color = i_val & 0x3;
311 /* This time counts against the total */
316 p_dest[i_row*i_width+i_column] = i_color;
318 if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)
319 printf("%1d", i_color);
323 if ( i_remaining != 0 && i_remaining !=2 ) {
324 advance_color_byte_pointer;
327 if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE)
332 /* The video is automatically scaled. However subtitle bitmaps
333 assume a 1:1 aspect ratio. So we need to scale to compensate for
334 or undo the effects of video output scaling.
336 /* FIXME do the right scaling depending on vout. It may not be 4:3 */
337 VCDSubScaleX( p_dec, p_spu, 3, 4 );
339 /* To be finished...*/