Commit 3bb0ad8d authored by Rocky Bernstein's avatar Rocky Bernstein
Browse files

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.
parent 3cbdd393
......@@ -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
......
......@@ -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<i_width; i_column++ ) {
if ( i_pending ) {
/* We are in the middle of a RLE expansion, just decrement and
fall through with current color value */
i_pending--;
} else if ( b_filling ) {
/* We are just filling to the end of line with one color, just
reuse current color value */
} else {
uint8_t i_val = ExtractField(p, i_remaining--);
if ( i_remaining == 0 ) {
advance_color_byte_pointer;
}
if ( i_val == 0 ) {
/* fill the rest of the line with next color */
i_color = ExtractField( p, i_remaining-- );
if ( i_remaining == 0 ) {
p++;
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 - 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;
}
......@@ -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<i_width; i_column++ ) {
if ( i_pending_zero ) {
/* We are in the middle of a RLE expansion, just decrement and
fall through with current color value */
i_pending_zero--;
i_color = 0;
} else {
......
......@@ -2,7 +2,7 @@
* render.c : Philips OGT (SVCD Subtitle) renderer
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: render.c,v 1.4 2003/12/28 04:51:52 rocky Exp $
* $Id: render.c,v 1.5 2003/12/29 04:47:44 rocky Exp $
*
* Author: Rocky Bernstein
* based on code from:
......@@ -35,8 +35,11 @@
#include "subtitle.h"
#include "render.h"
/* We use 8 bits for an alpha value: 0..255. Note: For DVDs; 0.15. */
#define ALPHA_BITS (8)
/* We use 4 bits for an alpha value: 0..15, 15 is completely transparent and
0 completely opaque. Note that SVCD allow 8-bits, it should be
scaled down to use these routines.
*/
#define ALPHA_BITS (4)
#define MAX_ALPHA ((1<<ALPHA_BITS) - 1)
/* Horrible hack to get dbg_print to do the right thing */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment