From: Rocky Bernstein Date: Tue, 30 Dec 2003 04:43:52 +0000 (+0000) Subject: common.*: add common routine to eliminate palette from pixmap. X-Git-Tag: 0.7.0~23 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=c17dee7dcc0c7470a76edda19f8813d9dbde18f1;p=vlc common.*: add common routine to eliminate palette from pixmap. cvd*: finally shows subtitles (with some bugs) ogt_parse.c: use common just added above. --- diff --git a/modules/codec/ogt/common.c b/modules/codec/ogt/common.c index 925de46769..81574f2f41 100644 --- a/modules/codec/ogt/common.c +++ b/modules/codec/ogt/common.c @@ -2,7 +2,7 @@ * Common SVCD and VCD subtitle routines. ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: common.c,v 1.1 2003/12/28 04:51:52 rocky Exp $ + * $Id: common.c,v 1.2 2003/12/30 04:43:52 rocky Exp $ * * Author: Rocky Bernstein * based on code from: @@ -161,6 +161,25 @@ vout_thread_t *VCDSubFindVout( decoder_t *p_dec ) } + +/* Remove color palette by expanding pixel entries to contain the + palette values. We work from the free space at the end to the + beginning so we can expand inline. + */ +void +VCDInlinePalette ( /*inout*/ uint8_t *p_dest, decoder_sys_t *p_sys, + unsigned int i_height, unsigned int i_width ) +{ + int n = (i_height * i_width) - 1; + uint8_t *p_from = p_dest; + ogt_yuvt_t *p_to = (ogt_yuvt_t *) p_dest; + + for ( ; n >= 0 ; n-- ) { + p_to[n] = p_sys->pi_palette[p_from[n]]; + } +} + + /* Scales down (reduces size) of p_dest in the x direction as determined through aspect ratio x_scale by y_scale. Scaling is done in place. p_spu->i_width, is updated to new width diff --git a/modules/codec/ogt/common.h b/modules/codec/ogt/common.h index 41e03e16eb..7cb05101c1 100644 --- a/modules/codec/ogt/common.h +++ b/modules/codec/ogt/common.h @@ -2,7 +2,7 @@ * Header for Common SVCD and VCD subtitle routines. ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: common.h,v 1.1 2003/12/28 04:51:52 rocky Exp $ + * $Id: common.h,v 1.2 2003/12/30 04:43:52 rocky Exp $ * * Author: Rocky Bernstein * @@ -35,5 +35,9 @@ int VCDSubCropCallback( vlc_object_t *p_object, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ); void VCDSubUpdateSPU( subpicture_t *p_spu, vlc_object_t *p_object ); +void VCDInlinePalette ( /*inout*/ uint8_t *p_dest, + decoder_sys_t *p_sys, unsigned int i_height, + unsigned int i_width ); + diff --git a/modules/codec/ogt/cvd.c b/modules/codec/ogt/cvd.c index 679675f55b..9797dc1050 100644 --- a/modules/codec/ogt/cvd.c +++ b/modules/codec/ogt/cvd.c @@ -2,7 +2,7 @@ * cvd.c : CVD Subtitle decoder thread ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: cvd.c,v 1.3 2003/12/29 04:47:44 rocky Exp $ + * $Id: cvd.c,v 1.4 2003/12/30 04:43:52 rocky Exp $ * * Authors: Rocky Bernstein * based on code from: @@ -305,7 +305,7 @@ Reassemble( decoder_t *p_dec, block_t **pp_block ) p_sys->i_width = lastx - p_sys->i_x_start + 1; p_sys->i_height = lasty - p_sys->i_y_start + 1; dbg_print( DECODE_DBG_PACKET, - "end position: (%d,%d): %.2x %.2x %.2x, w x h: %d x %d", + "end position: (%d,%d): %.2x %.2x %.2x, w x h: %dx%d", lastx, lasty, p[1], p[2], p[3], p_sys->i_width, p_sys->i_height ); break; @@ -357,9 +357,12 @@ Reassemble( decoder_t *p_dec, block_t **pp_block ) p_sys->pi_palette[3].s.t = p[2] >> 4; dbg_print( DECODE_DBG_PACKET, - "transparancy for primary palette (y,u,v): " - "0x%0x 0x%0x 0x%0x", - p[1], p[2], p[3]); + "transparancy for primary palette 0..3: " + "0x%0x 0x%0x 0x%0x 0x%0x", + p_sys->pi_palette[0].s.t, + p_sys->pi_palette[1].s.t, + p_sys->pi_palette[2].s.t, + p_sys->pi_palette[3].s.t ); break; @@ -371,9 +374,12 @@ Reassemble( decoder_t *p_dec, block_t **pp_block ) p_sys->pi_palette_highlight[3].s.t = p[1] >> 4; dbg_print( DECODE_DBG_PACKET, - "transparancy for highlight palette (y,u,v): " - "0x%0x 0x%0x 0x%0x", - p[1], p[2], p[3]); + "transparancy for primary palette 0..3: " + "0x%0x 0x%0x 0x%0x 0x%0x", + p_sys->pi_palette_highlight[0].s.t, + p_sys->pi_palette_highlight[1].s.t, + p_sys->pi_palette_highlight[2].s.t, + p_sys->pi_palette_highlight[3].s.t ); break; diff --git a/modules/codec/ogt/cvd_parse.c b/modules/codec/ogt/cvd_parse.c index 3f469e11fa..e57184b8ec 100644 --- a/modules/codec/ogt/cvd_parse.c +++ b/modules/codec/ogt/cvd_parse.c @@ -2,7 +2,7 @@ * parse.c: Philips OGT (SVCD subtitle) packet parser ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: cvd_parse.c,v 1.3 2003/12/29 04:47:44 rocky Exp $ + * $Id: cvd_parse.c,v 1.4 2003/12/30 04:43:52 rocky Exp $ * * Authors: Rocky Bernstein * based on code from: @@ -46,41 +46,36 @@ typedef uint8_t ogt_color_t; static int ParseImage ( decoder_t *, subpicture_t * ); /* - * We do not have information on the subtitle format used on CVD's - * except the submux sample code and a couple of samples of dubious - * origin. Thus, this is the result of reading some code whose - * correctness is not known and some experimentation. - * - * CVD subtitles present several differences compared to SVCD OGT - * subtitles. Firstly, the image comes first and the metadata is at - * the end. So that the metadata can be found easily, the subtitle - * begins with two two-byte (everything is big-endian again) that - * describe, the total size of the subtitle data and the offset to the - * metadata (size of the image data plus the four bytes at the - * beginning. - * - * Image data comes interlaced and uses RLE. Coding is based in - * four-bit nibbles that are further subdivided in a two-bit repeat - * count and a two-bit color number so that up to three pixels can be - * describe with a total of four bits. The function of a 0 repeat - * count is unknown. It might be used for RLE extension. There is a - * special case, though. When the full nibble is zero, the rest of - * the line is filled with the color value in the next nibble. It is - * unknown what happens if the color value is greater than three. The - * rest seems to use a 4-entries palette. It is not impossible that - * the fill-line complete case above is not as described and the zero - * repeat count means fill line. The sample code never produces this, - * so it may be untested. - * - * The metadata section does not follow a fixed pattern, every - * metadata item consists of a tag byte followed by parameters. In all - * cases known, the block (including the tag byte) is exactly four - * bytes in length. Read the code for the rest. - */ - -/* FIXME: do we really need p_buffer and p? - Can't all of thes _offset's and _lengths's get removed? + We do not have information on the subtitle format used on CVD's + except the submux sample code and a couple of samples of dubious + origin. Thus, this is the result of reading some code whose + correctness is not known and some experimentation. + + CVD subtitles are different in severl ways from SVCD OGT subtitles. + First, the image comes first and the metadata is at the end. So + that the metadata can be found easily, the subtitle packet starts + with two bytes (everything is big-endian again) that give the total + size of the subtitle data and the offset to the metadata - i.e. size + of the image data plus the four bytes at the beginning. + + Image data comes interlaced is run-length encoded. Each field is a + four-bit nibble. Each nibble contains a two-bit repeat count and a + two-bit color number so that up to three pixels can be described in + four bits. The function of a 0 repeat count is unknown; it might be + used for RLE extension. However when the full nibble is zero, the + rest of the line is filled with the color value in the next nibble. + It is unknown what happens if the color value is greater than three. + The rest seems to use a 4-entries palette. It is not impossible + that the fill-line complete case above is not as described and the + zero repeat count means fill line. The sample code never produces + this, so it may be untested. + + The metadata section does not follow a fixed pattern, every + metadata item consists of a tag byte followed by parameters. In all + cases known, the block (including the tag byte) is exactly four + bytes in length. Read the code for the rest. */ + void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block ) { decoder_sys_t *p_sys = p_dec->p_sys; @@ -156,7 +151,7 @@ E_(ParsePacket)( decoder_t *p_dec) p_spu->i_height = p_sys->i_height; p_spu->i_start = p_sys->i_pts; - p_spu->i_stop = p_sys->i_pts + (p_sys->i_duration * 10); + p_spu->i_stop = p_sys->i_pts + (p_sys->i_duration * 5); p_spu->p_sys->b_crop = VLC_FALSE; p_spu->p_sys->i_debug = p_sys->i_debug; @@ -183,7 +178,7 @@ E_(ParsePacket)( decoder_t *p_dec) #define advance_color_byte_pointer \ p++; \ - i_remaining = 2; \ + i_nibble_field = 2; \ /* \ * This is wrong, it may exceed maxp if it is the last, check \ * should be moved to use location or the algorithm changed to \ @@ -197,14 +192,17 @@ E_(ParsePacket)( decoder_t *p_dec) return VLC_EGENERIC; \ } -/* Get the next field - either a palette index or a RLE count for - color 0. To do this we use byte image pointer p, and i_remaining - which indicates where we are in the byte. +#define CVD_FIELD_BITS (4) +#define CVD_FIELD_MASK ((1<> 4*(i_remaining-1) ) & 0xf ); + return ( ( *p >> (CVD_FIELD_BITS*(i_nibble_field-1)) ) & CVD_FIELD_MASK ); } /***************************************************************************** @@ -236,9 +234,8 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) { decoder_sys_t *p_sys = p_dec->p_sys; - unsigned int i_field; /* The subtitles are interlaced, are we on an + uint8_t i_field; /* The subtitles are interlaced, are we on an even or odd scanline? */ - unsigned int i_row; /* scanline row number */ unsigned int i_column; /* scanline column number */ @@ -247,8 +244,8 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) uint8_t *p_dest = (uint8_t *)p_spu->p_sys->p_data; - uint8_t i_remaining; /* number of 2-bit pixels remaining - in byte of *p */ + uint8_t i_nibble_field; /* The 2-bit pixels remaining in byte of *p. + Has value 0..2. */ vlc_bool_t b_filling; /* Filling i_color to the of the line. */ uint8_t i_pending = 0; /* number of pixels to fill with color zero 0..3 */ @@ -256,7 +253,7 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) uint8_t *p = p_sys->subtitle_data + p_sys->comp_image_offset; uint8_t *maxp = p + p_sys->comp_image_length; - dbg_print( (DECODE_DBG_CALL) , "width x height: %dx%d ", + dbg_print( (DECODE_DBG_CALL) , "width x height: %dx%d", i_width, i_height); if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) @@ -265,10 +262,10 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) i_pending = 0; for ( i_field=0; i_field < 2; i_field++ ) { - i_remaining = 2; /* 4-bit pieces available in *p */ - b_filling = VLC_FALSE; + i_nibble_field = 2; /* 4-bit pieces available in *p */ for ( i_row=i_field; i_row < i_height; i_row += 2 ) { + b_filling = VLC_FALSE; for ( i_column=0; i_columni_debug & DECODE_DBG_IMAGE) { + uint8_t *p = p_dest; + printf("-------------------------------------\n++"); + for ( i_row=0; i_row < i_height; i_row ++ ) { + for ( i_column=0; i_column= maxp) { \ msg_Warn( p_dec, \ "broken subtitle - tried to access beyond end " \ @@ -227,19 +227,22 @@ E_(ParsePacket)( decoder_t *p_dec) } \ #define advance_color_pointer \ - i_remaining--; \ - if ( i_remaining == 0 ) { \ + i_2bit_field--; \ + if ( i_2bit_field == 0 ) { \ advance_color_pointer_byte; \ } +#define OGT_FIELD_BITS (2) +#define OGT_FIELD_MASK ((1<> 2*(i_remaining-1) ) & 0x3 ); + return ( ( *p >> (OGT_FIELD_BITS*(i_2bit_field-1)) ) & OGT_FIELD_MASK ); } /***************************************************************************** @@ -280,8 +283,8 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) uint8_t *p_dest = (uint8_t *)p_spu->p_sys->p_data; - uint8_t i_remaining; /* number of 2-bit pixels remaining - in byte of *p */ + uint8_t i_2bit_field; /* The 2-bit field to sue in byte of *p. + Has value 0..4. */ uint8_t i_pending_zero = 0; /* number of pixels to fill with color zero 0..3 */ ogt_color_t i_color; /* current pixel color: 0..3 */ @@ -295,7 +298,7 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) printf("\n"); for ( i_field=0; i_field < 2; i_field++ ) { - i_remaining = 4; + i_2bit_field = 4; for ( i_row=i_field; i_row < i_height; i_row += 2 ) { for ( i_column=0; i_columni_debug & DECODE_DBG_IMAGE) printf("\n"); - if ( i_remaining != 4 ) { + if ( i_2bit_field != 4 ) { /* Lines are padded to complete bytes, ignore padding */ advance_color_pointer_byte; } @@ -347,19 +350,7 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) printf("\n-------------------------------------\n"); } - /* Remove color palette by expanding pixel entries to contain the - palette values. We work from the free space at the end to the - beginning so we can expand inline. - */ - { - int n = (i_height * i_width) - 1; - uint8_t *p_from = p_dest; - ogt_yuvt_t *p_to = (ogt_yuvt_t *) p_dest; - - for ( ; n >= 0 ; n-- ) { - p_to[n] = p_sys->pi_palette[p_from[n]]; - } - } + VCDInlinePalette( p_dest, p_sys, i_height, i_width ); /* The video is automatically scaled. However subtitle bitmaps assume a 1:1 aspect ratio. So we need to scale to compensate for