1 /*****************************************************************************
2 * parse.c: Philips OGT (SVCD subtitle) packet parser
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: cvd_parse.c,v 1.2 2003/12/28 11:26:52 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 /* Advance pointer to image pointer, update internal i_remaining counter
185 and check that we haven't goine too far in the image data. */
186 #define advance_color_pointer_byte \
191 "broken subtitle - tried to access beyond end " \
192 "in image extraction"); \
193 return VLC_EGENERIC; \
196 #define advance_color_pointer \
198 if ( i_remaining == 0 ) { \
199 advance_color_pointer_byte; \
202 /* Get the next field - either a palette index or a RLE count for
203 color 0. To do this we use byte image pointer p, and i_remaining
204 which indicates where we are in the byte.
206 static inline ogt_color_t
207 ExtractField(uint8_t *p, unsigned int i_remaining)
209 return ( ( *p >> 2*(i_remaining-1) ) & 0x3 );
212 /*****************************************************************************
213 * ParseImage: parse the image part of the subtitle
214 *****************************************************************************
215 This part parses the subtitle graphical data and stores it in a more
216 convenient structure for later rendering.
218 The image is encoded using two bits per pixel that select a palette
219 entry except that value 0 starts a limited run-length encoding for
220 color 0. When 0 is seen, the next two bits encode one less than the
221 number of pixels, so we can encode run lengths from 1 to 4. These get
222 filled with the color in palette entry 0.
224 The encoding of each line is padded to a whole number of bytes. The
225 first field is padded to an even byte length and the complete subtitle
226 is padded to a 4-byte multiple that always include one zero byte at
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 an 8-bit alpha, 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 dbg_print( (DECODE_DBG_CALL) , "");
240 /* To be finished...*/