From 3bb0ad8dc81c949303658499cf5661cf6a876ee5 Mon Sep 17 00:00:00 2001 From: Rocky Bernstein Date: Mon, 29 Dec 2003 04:47:44 +0000 Subject: [PATCH] cvd: bitmap extraction further completed - not fully done. ogt_parse.c, render.c: go back to 4-bit alpha since that's what DVD and CVD have. --- modules/codec/ogt/cvd.c | 5 +- modules/codec/ogt/cvd_parse.c | 155 ++++++++++++++++++++++++++++------ modules/codec/ogt/ogt_parse.c | 17 ++-- modules/codec/ogt/render.c | 9 +- 4 files changed, 147 insertions(+), 39 deletions(-) diff --git a/modules/codec/ogt/cvd.c b/modules/codec/ogt/cvd.c index 8f008aeaf8..679675f55b 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.2 2003/12/28 11:26:52 rocky Exp $ + * $Id: cvd.c,v 1.3 2003/12/29 04:47:44 rocky Exp $ * * Authors: Rocky Bernstein * based on code from: @@ -231,6 +231,9 @@ Reassemble( decoder_t *p_dec, block_t **pp_block ) p_buffer[5], p_buffer[6], p_block->i_buffer); + if( config_GetInt( p_dec, "spu-channel" ) != p_buffer[0] ) + return NULL; + /* There is little data on the format, but it does not seem to have a good way to detect the first packet in the subtitle. It seems, however, that it has a valid pts while later packets for the same diff --git a/modules/codec/ogt/cvd_parse.c b/modules/codec/ogt/cvd_parse.c index 4dde2e920d..3f469e11fa 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.2 2003/12/28 11:26:52 rocky Exp $ + * $Id: cvd_parse.c,v 1.3 2003/12/29 04:47:44 rocky Exp $ * * Authors: Rocky Bernstein * based on code from: @@ -181,32 +181,30 @@ E_(ParsePacket)( decoder_t *p_dec) } -/* Advance pointer to image pointer, update internal i_remaining counter - and check that we haven't goine too far in the image data. */ -#define advance_color_pointer_byte \ +#define advance_color_byte_pointer \ p++; \ - i_remaining=4; \ + i_remaining = 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 \ + * that in vob2sub \ + */ \ if (p >= maxp) { \ msg_Warn( p_dec, \ - "broken subtitle - tried to access beyond end " \ - "in image extraction"); \ + "broken subtitle - overflow while decoding " \ + " padding (%d,%d,%d)\n", \ + i_field, i_row, i_column ); \ return VLC_EGENERIC; \ - } \ - -#define advance_color_pointer \ - i_remaining--; \ - if ( i_remaining == 0 ) { \ - advance_color_pointer_byte; \ } /* 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. */ -static inline ogt_color_t +static inline uint8_t ExtractField(uint8_t *p, unsigned int i_remaining) { - return ( ( *p >> 2*(i_remaining-1) ) & 0x3 ); + return ( ( *p >> 4*(i_remaining-1) ) & 0xf ); } /***************************************************************************** @@ -215,20 +213,22 @@ ExtractField(uint8_t *p, unsigned int i_remaining) This part parses the subtitle graphical data and stores it in a more convenient structure for later rendering. - The image is encoded using two bits per pixel that select a palette - entry except that value 0 starts a limited run-length encoding for - color 0. When 0 is seen, the next two bits encode one less than the - number of pixels, so we can encode run lengths from 1 to 4. These get - filled with the color in palette entry 0. - - The encoding of each line is padded to a whole number of bytes. The - first field is padded to an even byte length and the complete subtitle - is padded to a 4-byte multiple that always include one zero byte at - the end. + Image data comes interlaced and is run-length encoded (RLE). Each + field is a four-bit nibbles that is further subdivided in a two-bit + repeat count and a two-bit color number - up to three pixels can be + described in four bits. What a 0 repeat count means is unknown. It + might be used for RLE extension. There is a special case of a 0 + repeat count 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. However we'll transform this so that that the RLE is expanded and interlacing will also be removed. On output each pixel entry will by - an 8-bit alpha, y, u, and v entry. + a 4-bit alpha (filling 8 bits), and 8-bit y, u, and v entry. *****************************************************************************/ static int @@ -236,9 +236,108 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) { decoder_sys_t *p_sys = p_dec->p_sys; - dbg_print( (DECODE_DBG_CALL) , ""); + unsigned int 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 */ + + unsigned int i_width = p_sys->i_width; + unsigned int i_height = p_sys->i_height; + + 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 */ + 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 */ + ogt_color_t i_color=0; /* current pixel color: 0..3 */ + 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 ", + i_width, i_height); + + if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) + printf("\n"); + + 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; + + for ( i_row=i_field; i_row < i_height; i_row += 2 ) { + for ( i_column=0; i_column= maxp) { + msg_Warn( p_dec, + "broken subtitle - overflow while decoding " + " filling (%d,%d,%d)", + i_field, i_row, i_column); + /* return VLC_EGENERIC; */ + } + } + b_filling = VLC_TRUE; + } else { + /* Normal case: get color and repeat count, + this iteration will output the first (or only) + instance */ + i_pending = (i_val >> 2); + i_color = i_val & 0x3; + /* This time counts against the total */ + i_pending--; + } + } + /* Color is 0-3. */ + p_dest[i_row*i_width+i_column] = i_color; + + if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) + printf("%1d", i_color); + + } + + if ( i_remaining != 0 && i_remaining !=2 ) { + advance_color_byte_pointer; + } + + if (p_sys && p_sys->i_debug & DECODE_DBG_IMAGE) + printf("\n"); + } + } + + /* The video is automatically scaled. However subtitle bitmaps + assume a 1:1 aspect ratio. So we need to scale to compensate for + or undo the effects of video output scaling. + */ + /* FIXME do the right scaling depending on vout. It may not be 4:3 */ + VCDSubScaleX( p_dec, p_spu, 3, 4 ); + /* To be finished...*/ - return VLC_EGENERIC; + return VLC_SUCCESS; } diff --git a/modules/codec/ogt/ogt_parse.c b/modules/codec/ogt/ogt_parse.c index d12af15ba2..3fcae76dfa 100644 --- a/modules/codec/ogt/ogt_parse.c +++ b/modules/codec/ogt/ogt_parse.c @@ -2,7 +2,7 @@ * Philips OGT (SVCD subtitle) packet parser ***************************************************************************** * Copyright (C) 2003 VideoLAN - * $Id: ogt_parse.c,v 1.2 2003/12/28 11:26:52 rocky Exp $ + * $Id: ogt_parse.c,v 1.3 2003/12/29 04:47:44 rocky Exp $ * * Author: Rocky Bernstein * based on code from: @@ -107,10 +107,11 @@ void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block ) p_sys->pi_palette[i].s.y = *p++; p_sys->pi_palette[i].s.u = *p++; p_sys->pi_palette[i].s.v = *p++; - /* Note alpha is 8 bits. DVD's use only 4 bits. Our rendering routine - will use an 8-bit transparancy. + /* OGT has 8-bit resolution for alpha, but DVD's and CVDS use 4-bits. + Since we want to use the same render routine, rather than scale up + CVD (and DVD) subtitles, we'll scale down ours. */ - p_sys->pi_palette[i].s.t = *p++; + p_sys->pi_palette[i].s.t = (*p++) >> 4; } p_sys->i_cmd = *p++; /* We do not really know this, FIXME */ @@ -259,8 +260,8 @@ ExtractField(uint8_t *p, unsigned int i_remaining) the end. However we'll transform this so that that the RLE is expanded and - interlacing will also be removed. On output each pixel entry will by - an 8-bit alpha, y, u, and v entry. + interlacing will also be removed. On output each pixel entry will by + an 4-bit alpha (filling 8 bits), and 8-bit y, u, and v entry. *****************************************************************************/ static int @@ -282,7 +283,7 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) uint8_t i_remaining; /* number of 2-bit pixels remaining in byte of *p */ uint8_t i_pending_zero = 0; /* number of pixels to fill with - color zero 0..4 */ + color zero 0..3 */ ogt_color_t i_color; /* current pixel color: 0..3 */ uint8_t *p = p_sys->subtitle_data + p_sys->comp_image_offset; uint8_t *maxp = p + p_sys->comp_image_length; @@ -299,6 +300,8 @@ ParseImage( decoder_t *p_dec, subpicture_t * p_spu ) for ( i_column=0; i_column