Commit 919854e4 authored by Rocky Bernstein's avatar Rocky Bernstein

Work towards handling all planes in subtites, generalizing for CVD, and

some cleanup.
parent 6f8690b5
......@@ -2,7 +2,7 @@
* ogt.c : Overlay Graphics Text (SVCD subtitles) decoder thread
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: ogt.c,v 1.4 2003/12/26 02:47:59 rocky Exp $
* $Id: ogt.c,v 1.5 2003/12/28 02:01:11 rocky Exp $
*
* Authors: Rocky Bernstein
* based on code from:
......@@ -32,13 +32,18 @@
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include "subtitle.h"
#include "ogt.h"
#define DEBUG_LONGTEXT N_( \
"This integer when viewed in binary is a debugging mask\n" \
"external call 1\n" \
"all calls 2\n" \
"misc 4\n" )
"external call 1\n" \
"all calls 2\n" \
"packet assembly info 4\n" \
"image bitmaps 8\n" \
"image transformations 16\n" \
"rendering information 32\n" \
"misc info 64\n" )
/*****************************************************************************
......
......@@ -2,12 +2,9 @@
* ogt.h : Overlay Graphics Text (SVCD subtitles) decoder thread interface
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: ogt.h,v 1.5 2003/12/27 01:49:59 rocky Exp $
* $Id: ogt.h,v 1.6 2003/12/28 02:01:11 rocky Exp $
*
* Author: Rocky Bernstein
* based on code from:
* Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
* Sam Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -24,130 +21,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define DECODE_DBG_EXT 1 /* Calls from external routines */
#define DECODE_DBG_CALL 2 /* all calls */
#define DECODE_DBG_PACKET 4 /* packet assembly info */
#define DECODE_DBG_IMAGE 8 /* image bitmaps */
#define DECODE_DBG_TRANSFORM 16 /* bitmap transformations */
#define DECODE_DBG_INFO 32
#define DECODE_DEBUG 1
#if DECODE_DEBUG
#define dbg_print(mask, s, args...) \
if (p_sys && p_sys->i_debug & mask) \
msg_Dbg(p_dec, "%s: "s, __func__ , ##args)
#else
#define dbg_print(mask, s, args...)
#endif
#define LOG_ERR(args...) msg_Err( p_input, args )
#define LOG_WARN(args...) msg_Warn( p_input, args )
#define GETINT16(p) ( (p[0] << 8) + p[1] ); p +=2;
#define GETINT32(p) ( (p[0] << 24) + (p[1] << 16) + \
(p[2] << 8) + (p[3]) ) ; p += 4;
/* The number of color palette entries allowed in a subtitle. */
#define NUM_SUBTITLE_COLORS 4
typedef enum {
SUBTITLE_BLOCK_EMPTY,
SUBTITLE_BLOCK_PARTIAL,
SUBTITLE_BLOCK_COMPLETE
} packet_state_t;
/* FIXME: REMOVE THE BELOW. */
/* Color and transparency of a pixel or a palette (CLUT) entry */
typedef struct ogt_yuvt_val_s {
uint8_t y;
uint8_t u;
uint8_t v;
uint8_t t;
} ogt_yuvt_t;
/* The storage used by one pixel */
#define PIXEL_SIZE 4
/* Size in bytes of YUV portion above. */
#define YUV_SIZE 3
/* Transparency plane. NOTE: see vlc_video.h for V_PLANE */
#define T_PLANE V_PLANE+1
struct decoder_sys_t
{
int i_debug; /* debugging mask */
mtime_t i_pts; /* Start PTS of subtitle block */
int i_spu;
packet_state_t state; /* data-gathering state for this subtitle */
uint16_t i_image; /* image number in the subtitle stream; 0 is the
first one. */
uint8_t i_packet;/* packet number for above image number; 0 is the
first one. */
block_t *p_block;/* Bytes of the packet. */
uint8_t buffer[65536 + 20 ]; /* we will never overflow more than 11
bytes if I'm right */
int b_packetizer;
int i_spu_size; /* goal for subtitle_data_pos while gathering,
size of used subtitle_data later */
vout_thread_t *p_vout;
/* FIXME: Remove this? */
uint8_t *subtitle_data; /* buffer used to accumulate data from
successive packets in the same subtitle */
int subtitle_data_size; /* size of the allocated subtitle_data */
/* Move into subpicture_sys_t? */
uint16_t comp_image_offset; /* offset from subtitle_data to compressed
image data */
int comp_image_length; /* size of the compressed image data */
int second_field_offset; /* offset of odd raster lines */
int metadata_offset; /* offset to data describing the image */
int metadata_length; /* length of metadata */
int subtitle_data_pos; /* where to write next chunk */
uint32_t i_duration; /* how long to display the image, 0 stands
for "until next subtitle" */
uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
image when displayed */
uint16_t i_width, i_height; /* dimensions in pixels of image */
ogt_yuvt_t pi_palette[NUM_SUBTITLE_COLORS];
uint8_t i_options;
uint8_t i_options2;
uint8_t i_cmd;
uint32_t i_cmd_arg;
};
struct subpicture_sys_t
{
mtime_t i_pts; /* presentation timestamp */
u_int8_t *p_data; /* Image data one byte T, Y, U, V */
/* Color information */
vlc_bool_t b_palette;
/* Link to our input */
vlc_object_t * p_input;
/* Cropping properties */
vlc_mutex_t lock;
vlc_bool_t b_crop;
unsigned int i_x_start, i_y_start, i_x_end, i_y_end;
};
/*****************************************************************************
* Prototypes
*****************************************************************************/
void E_(ParseHeader)( decoder_t *, uint8_t *, block_t * );
void E_(ParsePacket)( decoder_t * );
void E_(RenderSPU) ( vout_thread_t *, picture_t *, const subpicture_t * );
......@@ -2,7 +2,7 @@
* parse.c: Philips OGT (SVCD subtitle) packet parser
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: parse.c,v 1.2 2003/12/27 01:49:59 rocky Exp $
* $Id: parse.c,v 1.3 2003/12/28 02:01:11 rocky Exp $
*
* Authors: Rocky Bernstein
* based on code from:
......@@ -32,6 +32,8 @@
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include "subtitle.h"
#include "render.h"
#include "ogt.h"
/* An image color is a two-bit palette entry: 0..3 */
......@@ -105,12 +107,13 @@ void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
p_sys->i_height = GETINT16(p);
for (i=0; i<4; i++) {
p_sys->pi_palette[i].y = *p++;
p_sys->pi_palette[i].u = *p++;
p_sys->pi_palette[i].v = *p++;
/* We have just 4-bit resolution for alpha, but the value for SVCD
* has 8 bits so we scale down the values to the acceptable range */
p_sys->pi_palette[i].t = (*p++) >> 4;
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.
*/
p_sys->pi_palette[i].s.t = *p++;
}
p_sys->i_cmd = *p++;
/* We do not really know this, FIXME */
......@@ -135,8 +138,8 @@ void E_(ParseHeader)( decoder_t *p_dec, uint8_t *p_buffer, block_t *p_block )
for (i=0; i<4; i++) {
msg_Dbg( p_dec, "palette[%d]= T: %2x, Y: %2x, u: %2x, v: %2x", i,
p_sys->pi_palette[i].t, p_sys->pi_palette[i].y,
p_sys->pi_palette[i].u, p_sys->pi_palette[i].v );
p_sys->pi_palette[i].s.t, p_sys->pi_palette[i].s.y,
p_sys->pi_palette[i].s.u, p_sys->pi_palette[i].s.v );
}
}
}
......@@ -174,15 +177,15 @@ E_(ParsePacket)( decoder_t *p_dec)
/* Fill the p_spu structure */
vlc_mutex_init( p_dec, &p_spu->p_sys->lock );
p_spu->pf_render = E_(RenderSPU);
p_spu->pf_render = VCDRenderSPU;
p_spu->pf_destroy = DestroySPU;
p_spu->p_sys->p_data = (uint8_t*)p_spu->p_sys + sizeof( subpicture_sys_t );
p_spu->p_sys->b_palette = VLC_FALSE;
p_spu->p_sys->i_x_end = p_sys->i_x_start + p_sys->i_width - 1;
p_spu->p_sys->i_y_end = p_sys->i_y_start + p_sys->i_height - 1;
p_spu->i_x = p_sys->i_x_start / 2;
/* FIXME: use aspect ratio for x? */
p_spu->i_x = p_sys->i_x_start * 3 / 4;
p_spu->i_y = p_sys->i_y_start;
p_spu->i_width = p_sys->i_width;
p_spu->i_height = p_sys->i_height;
......@@ -190,7 +193,8 @@ E_(ParsePacket)( decoder_t *p_dec)
p_spu->i_start = p_sys->i_pts;
p_spu->i_stop = p_sys->i_pts + (p_sys->i_duration * 10);
p_spu->p_sys->b_crop = VLC_FALSE;
p_spu->p_sys->b_crop = VLC_FALSE;
p_spu->p_sys->i_debug = p_sys->i_debug;
/* Get display time now. If we do it later, we may miss the PTS. */
p_spu->p_sys->i_pts = p_sys->i_pts;
......@@ -266,7 +270,7 @@ ScaleX( decoder_t *p_dec, subpicture_t *p_spu,
for ( i_row=0; i_row <= p_spu->i_height - 1; i_row++ ) {
if (used != 0) {
/* Discard the remaining piece of the colum of the previous line*/
/* Discard the remaining piece of the column of the previous line*/
used=0;
p_src1 = p_src2;
p_src2 += PIXEL_SIZE;
......@@ -299,7 +303,7 @@ ScaleX( decoder_t *p_dec, subpicture_t *p_spu,
ogt_yuvt_t *p_source = (ogt_yuvt_t *) p_spu->p_sys->p_data;
for ( i_row=0; i_row < p_spu->i_height - 1; i_row++ ) {
for ( i_col=0; i_col < p_spu->i_width - 1; i_col++ ) {
printf("%1x", p_source->t);
printf("%1x", p_source->s.t);
p_source++;
}
printf("\n");
......
......@@ -2,7 +2,7 @@
* render.c : Philips OGT (SVCD Subtitle) renderer
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: render.c,v 1.2 2003/12/27 01:49:59 rocky Exp $
* $Id: render.c,v 1.3 2003/12/28 02:01:11 rocky Exp $
*
* Author: Rocky Bernstein
* based on code from:
......@@ -32,7 +32,15 @@
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include "ogt.h"
#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)
#define MAX_ALPHA ((1<<ALPHA_BITS) - 1)
/* Horrible hack to get dbg_print to do the right thing */
#define p_dec p_vout
/*****************************************************************************
* Local prototypes
......@@ -51,13 +59,13 @@ static void RenderI420( vout_thread_t *, picture_t *, const subpicture_t *,
routine can be as fast as possible.
*****************************************************************************/
void E_(RenderSPU)( vout_thread_t *p_vout, picture_t *p_pic,
const subpicture_t *p_spu )
void VCDRenderSPU( vout_thread_t *p_vout, picture_t *p_pic,
const subpicture_t *p_spu )
{
/*
printf("+++%x\n", p_vout->output.i_chroma);
*/
struct subpicture_sys_t *p_sys = p_spu->p_sys;
dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER),
"chroma %x", p_vout->output.i_chroma );
switch( p_vout->output.i_chroma )
{
......@@ -99,82 +107,98 @@ static void RenderI420( vout_thread_t *p_vout, picture_t *p_pic,
uint8_t *p_dest;
uint8_t *p_destptr;
ogt_yuvt_t *p_source;
unsigned int i_plane;
int i_x, i_y;
uint16_t i_colprecomp, i_destalpha;
/* Crop-specific */
int i_x_start, i_y_start, i_x_end, i_y_end;
/* int i=0; */
struct subpicture_sys_t *p_sys = p_spu->p_sys;
p_dest = p_pic->Y_PIXELS + p_spu->i_x + p_spu->i_width
+ p_pic->Y_PITCH * ( p_spu->i_y + p_spu->i_height );
i_x_start = p_spu->i_width - p_spu->p_sys->i_x_end;
i_y_start = p_pic->Y_PITCH * (p_spu->i_height - p_spu->p_sys->i_y_end );
i_x_end = p_spu->i_width - p_spu->p_sys->i_x_start;
i_y_end = p_pic->Y_PITCH * (p_spu->i_height - p_spu->p_sys->i_y_start );
p_source = (ogt_yuvt_t *)p_spu->p_sys->p_data;
dbg_print( (DECODE_DBG_CALL|DECODE_DBG_RENDER),
"spu width: %d, height %d, pitch (%d, %d, %d)",
p_spu->i_width, p_spu->i_height,
p_pic->Y_PITCH, p_pic->U_PITCH, p_pic->V_PITCH );
/* printf("+++spu width: %d, height %d\n", p_spu->i_width,
p_spu->i_height); */
/* Draw until we reach the bottom of the subtitle */
for( i_y = p_spu->i_height * p_pic->Y_PITCH ;
i_y ;
i_y -= p_pic->Y_PITCH )
/*for ( i_plane = 0; i_plane < p_pic->i_planes ; i_plane++ )*/
for ( i_plane = 0; i_plane < 1 ; i_plane++ )
{
/* printf("+++begin line: %d,\n", i++); */
/* Draw until we reach the end of the line */
for( i_x = p_spu->i_width ; i_x ; i_x--, p_source++ )
{
if( b_crop
&& ( i_x < i_x_start || i_x > i_x_end
|| i_y < i_y_start || i_y > i_y_end ) )
{
continue;
}
/* printf( "t: %x, y: %x, u: %x, v: %x\n",
p_source->t, p_source->y, p_source->u, p_source->v ); */
switch( p_source->t )
{
case 0x00:
/* Completely transparent. Don't change underlying pixel */
break;
p_dest = p_pic->p[i_plane].p_pixels + p_spu->i_x + p_spu->i_width
+ p_pic->p[i_plane].i_pitch * ( p_spu->i_y + p_spu->i_height );
i_x_start = p_spu->i_width - p_sys->i_x_end;
i_y_start = p_pic->p[i_plane].i_pitch
* (p_spu->i_height - p_sys->i_y_end );
i_x_end = p_spu->i_width - p_sys->i_x_start;
i_y_end = p_pic->p[i_plane].i_pitch
* (p_spu->i_height - p_sys->i_y_start );
p_source = (ogt_yuvt_t *)p_sys->p_data;
/* Draw until we reach the bottom of the subtitle */
for( i_y = p_spu->i_height * p_pic->p[i_plane].i_pitch ;
i_y ;
i_y -= p_pic->p[i_plane].i_pitch )
{
/* printf("+++begin line: %d,\n", i++); */
/* Draw until we reach the end of the line */
for( i_x = p_spu->i_width ; i_x ; i_x--, p_source++ )
{
case 0x0f:
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
p_destptr = p_dest - i_x - i_y;
i_colprecomp = (uint16_t) ( p_source->y * 15 );
*p_destptr = i_colprecomp >> 4;
break;
if( b_crop
&& ( i_x < i_x_start || i_x > i_x_end
|| i_y < i_y_start || i_y > i_y_end ) )
{
continue;
}
default:
/* Blend in underlying pixel subtitle pixel. */
/* To be able to divide by 16 (>>4) we add 1 to the alpha.
* This means Alpha 0 won't be completely transparent, but
* that's handled in a special case above anyway. */
p_destptr = p_dest - i_x - i_y;
i_colprecomp = (uint16_t) ( (p_source->y
* (uint16_t)(p_source->t + 1) ) );
i_destalpha = 15 - p_source->t;
*p_destptr = ( i_colprecomp +
(uint16_t)*p_destptr * i_destalpha ) >> 4;
break;
}
}
}
/* printf( "t: %x, y: %x, u: %x, v: %x\n",
p_source->s.t, p_source->y, p_source->u, p_source->v ); */
switch( p_source->s.t )
{
case 0x00:
/* Completely transparent. Don't change underlying pixel */
break;
case MAX_ALPHA:
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
p_destptr = p_dest - i_x - i_y;
i_colprecomp =
(uint16_t) ( p_source->plane[i_plane] * MAX_ALPHA );
*p_destptr = i_colprecomp >> ALPHA_BITS;
break;
default:
/* Blend in underlying pixel subtitle pixel. */
/* To be able to ALPHA_BITS, we add 1 to the alpha.
* This means Alpha 0 won't be completely transparent, but
* that's handled in a special case above anyway. */
p_destptr = p_dest - i_x - i_y;
i_colprecomp = (uint16_t) (p_source->plane[i_plane]
* (uint16_t) (p_source->s.t+1) );
i_destalpha = MAX_ALPHA - p_source->s.t;
*p_destptr = ( i_colprecomp +
(uint16_t)*p_destptr * i_destalpha )
>> ALPHA_BITS;
break;
}
}
}
}
}
/*****************************************************************************
* render.h : Common SVCD and CVD rendering routine(s).
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: render.h,v 1.1 2003/12/28 02:01:11 rocky Exp $
*
* Author: Rocky Bernstein
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Prototypes
*****************************************************************************/
void VCDRenderSPU ( vout_thread_t *, picture_t *, const subpicture_t * );
/*****************************************************************************
* subtitle.h : Common SVCD and CVD subtitles header
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: subtitle.h,v 1.1 2003/12/28 02:01:11 rocky Exp $
*
* Author: Rocky Bernstein
* based on code from:
* Julio Sanchez Fernandez (http://subhandler.sourceforge.net)
* Sam Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#define DECODE_DBG_EXT 1 /* Calls from external routines */
#define DECODE_DBG_CALL 2 /* all calls */
#define DECODE_DBG_PACKET 4 /* packet assembly info */
#define DECODE_DBG_IMAGE 8 /* image bitmaps */
#define DECODE_DBG_TRANSFORM 16 /* bitmap transformations */
#define DECODE_DBG_RENDER 32 /* rendering information */
#define DECODE_DBG_INFO 64
#define DECODE_DEBUG 1
#if DECODE_DEBUG
#define dbg_print(mask, s, args...) \
if (p_sys && p_sys->i_debug & mask) \
msg_Dbg(p_dec, "%s: "s, __func__ , ##args)
#else
#define dbg_print(mask, s, args...)
#endif
#define LOG_ERR(args...) msg_Err( p_input, args )
#define LOG_WARN(args...) msg_Warn( p_input, args )
#define GETINT16(p) ( (p[0] << 8) + p[1] ); p +=2;
#define GETINT32(p) ( (p[0] << 24) + (p[1] << 16) + \
(p[2] << 8) + (p[3]) ) ; p += 4;
/* The number of color palette entries allowed in a subtitle. */
#define NUM_SUBTITLE_COLORS 4
typedef enum {
SUBTITLE_BLOCK_EMPTY,
SUBTITLE_BLOCK_PARTIAL,
SUBTITLE_BLOCK_COMPLETE
} packet_state_t;
/* Color and transparency of a pixel or a palette (CLUT) entry */
typedef union {
uint8_t plane[4];
struct {
uint8_t y;
uint8_t u;
uint8_t v;
uint8_t t;
} s;
} ogt_yuvt_t;
/* The storage used by one pixel */
#define PIXEL_SIZE 4
/* Size in bytes of YUV portion above. */
#define YUV_SIZE 3
/* Transparency plane. NOTE: see vlc_video.h for V_PLANE */
#define T_PLANE V_PLANE+1
struct decoder_sys_t
{
int i_debug; /* debugging mask */
mtime_t i_pts; /* Start PTS of subtitle block */
int i_spu;
packet_state_t state; /* data-gathering state for this subtitle */
uint16_t i_image; /* image number in the subtitle stream; 0 is the
first one. */
uint8_t i_packet;/* packet number for above image number; 0 is the
first one. */
block_t *p_block;/* Bytes of the packet. */
uint8_t buffer[65536 + 20 ]; /* we will never overflow more than 11
bytes if I'm right */
int b_packetizer;
int i_spu_size; /* goal for subtitle_data_pos while gathering,
size of used subtitle_data later */
vout_thread_t *p_vout;
/* FIXME: Remove this? */
uint8_t *subtitle_data; /* buffer used to accumulate data from
successive packets in the same subtitle */
int subtitle_data_size; /* size of the allocated subtitle_data */
/* Move into subpicture_sys_t? */
uint16_t comp_image_offset; /* offset from subtitle_data to compressed
image data */
int comp_image_length; /* size of the compressed image data */
int second_field_offset; /* offset of odd raster lines */
int metadata_offset; /* offset to data describing the image */
int metadata_length; /* length of metadata */
int subtitle_data_pos; /* where to write next chunk */
uint32_t i_duration; /* how long to display the image, 0 stands
for "until next subtitle" */
uint16_t i_x_start, i_y_start; /* position of top leftmost pixel of
image when displayed */
uint16_t i_width, i_height; /* dimensions in pixels of image */
ogt_yuvt_t pi_palette[NUM_SUBTITLE_COLORS];
uint8_t i_options;
uint8_t i_options2;
uint8_t i_cmd;
uint32_t i_cmd_arg;
};
struct subpicture_sys_t
{
int i_debug; /* debugging mask */
mtime_t i_pts; /* presentation timestamp */
u_int8_t *p_data; /* Image data one byte T, Y, U, V */
/* Link to our input */
vlc_object_t * p_input;
/* Cropping properties */
vlc_mutex_t lock;
vlc_bool_t b_crop;
unsigned int i_x_start, i_y_start, i_x_end, i_y_end;
};
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