Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
a11a1831
Commit
a11a1831
authored
Feb 01, 2004
by
Rocky Bernstein
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
RGB2 transparency now works. Common 8-bit RGB averaging routine
hoisted. Some doc additions.
parent
b0e78a0a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
182 additions
and
144 deletions
+182
-144
modules/codec/ogt/render.c
modules/codec/ogt/render.c
+182
-144
No files found.
modules/codec/ogt/render.c
View file @
a11a1831
/*****************************************************************************
* render.c : Philips OGT and CVD (VCD Subtitle) blending routines
* render.c : Philips OGT and CVD (VCD Subtitle) blending routines.
* stuff from here might be pulled out, abstracted or used
* by DVD subtitles.
*****************************************************************************
* Copyright (C) 2003, 2004 VideoLAN
* $Id: render.c,v 1.2
7 2004/01/31 05:53:35
rocky Exp $
* $Id: render.c,v 1.2
8 2004/02/01 05:15:22
rocky Exp $
*
* Author: Rocky Bernstein <rocky@panix.com>
* based on code from:
...
...
@@ -38,15 +40,16 @@
#include "subtitle.h"
#include "render.h"
/* We use 4 bits for an alpha value: 0..15, 15 is completely transparent and
0 completely opaque. Note that although SVCD allow 8-bits, pixels
previously should be scaled down to 4 bits to use these routines.
/* We use 4 bits for an transparency value: 0..15, 15 is completely
transparent and 0 completely opaque. Note that although SVCD allow
8-bits, for these routines pixels should previously have been be
scaled down to 4 bits (the range used by DVDs).
*/
#define
ALPHA
_BITS (4)
#define MAX_
ALPHA ((1<<ALPHA
_BITS) - 1)
#define
ALPHA_SCALEDOWN (8-ALPHA
_BITS)
#define
TRANS
_BITS (4)
#define MAX_
TRANS ((1<<TRANS
_BITS) - 1)
#define
TRANS_SCALEDOWN (8-TRANS
_BITS)
/* We use a fixed-point arithmetic
to
scaling ratios so that we
/* We use a fixed-point arithmetic
in
scaling ratios so that we
can use integer arithmetic and still get fairly precise
results. ASCALE is a left shift amount.
*/
...
...
@@ -55,6 +58,30 @@
/* Horrible hack to get dbg_print to do the right thing */
#define p_dec p_vout
/**
Take two 8-bit RGB values and a transparency and do a weighted
average of them. The "weight" comes from i_trans which is in the
range 0..MAX_TRANS. To have greater precision using integer
arithmetic, the RGB values are scaled. The uint16_t cast below is
to make sure we don't overflow the product in the multiplication
(MAX_TRANS - i_trans) is the additive "inverse" of i_trans, i.e.
i_trans + (MAX_TRANS - i_trans) = MAX_TRANS. So the resulting sum
of rgb1*i_trans + rgb2*(MAX_TRANS-i_trans) will be scaled by
MAX_TRANS. To reduce the value back down to 8 bits, we shift by
TRANS_BITS, noting that 1 << TRANS_BITS is roughly
MAX_TRANS. (Actually it is MAX_TRANS - 1).
*/
#define avg_8bit_rgb(rgb_vout, rgb_sub, i_trans) \
{ \
int i; \
for (i=0; i < RGB_SIZE; i++) { \
rgb_vout[i] = ( (uint16_t) rgb_vout[i]*(MAX_TRANS-i_trans) + \
(uint16_t) rgb_sub [i]*i_trans ) >> TRANS_BITS; \
} \
}
/*****************************************************************************
* Local prototypes
*****************************************************************************/
...
...
@@ -236,7 +263,7 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
}
#ifdef TESTING_TRANSPARENCY
if
(
p_source
->
s
.
t
==
MAX_
ALPHA
)
p_source
->
s
.
t
>>=
1
;
if
(
p_source
->
s
.
t
==
MAX_
TRANS
)
p_source
->
s
.
t
>>=
1
;
#endif
switch
(
p_source
->
s
.
t
)
...
...
@@ -245,7 +272,7 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
/* Completely transparent. Don't change pixel. */
break
;
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
...
...
@@ -289,7 +316,7 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
*/
uint16_t
i_pixel_color_Y
=
(
uint16_t
)
(
*
p_pixel_Y
*
(
uint16_t
)
(
MAX_
ALPHA
-
p_source
->
s
.
t
)
)
;
(
uint16_t
)
(
MAX_
TRANS
-
p_source
->
s
.
t
)
)
;
/* Scale the 12-bit result back down to 8 bits. A
precise scaling after adding the two components,
...
...
@@ -299,7 +326,7 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
transparent and all opaque) aren't handled properly.
But we deal with them in special cases above. */
*
p_pixel_Y
=
(
i_sub_color_Y
+
i_pixel_color_Y
)
>>
ALPHA
_BITS
;
*
p_pixel_Y
=
(
i_sub_color_Y
+
i_pixel_color_Y
)
>>
TRANS
_BITS
;
if
(
even_scanline
&&
i_x
%
2
==
0
)
{
uint8_t
*
p_pixel_U
=
p_pixel_base_U_y
+
i_x
/
2
...
...
@@ -315,12 +342,12 @@ static void BlendI420( vout_thread_t *p_vout, picture_t *p_pic,
(
uint16_t
)
(
p_source
->
s
.
t
)
);
uint16_t
i_pixel_color_U
=
(
uint16_t
)
(
*
p_pixel_U
*
(
uint16_t
)
(
MAX_
ALPHA
-
p_source
->
s
.
t
)
)
;
(
uint16_t
)
(
MAX_
TRANS
-
p_source
->
s
.
t
)
)
;
uint16_t
i_pixel_color_V
=
(
uint16_t
)
(
*
p_pixel_V
*
(
uint16_t
)
(
MAX_
ALPHA
-
p_source
->
s
.
t
)
)
;
*
p_pixel_U
=
(
i_sub_color_U
+
i_pixel_color_U
)
>>
ALPHA
_BITS
;
*
p_pixel_V
=
(
i_sub_color_V
+
i_pixel_color_V
)
>>
ALPHA
_BITS
;
(
uint16_t
)
(
MAX_
TRANS
-
p_source
->
s
.
t
)
)
;
*
p_pixel_U
=
(
i_sub_color_U
+
i_pixel_color_U
)
>>
TRANS
_BITS
;
*
p_pixel_V
=
(
i_sub_color_V
+
i_pixel_color_V
)
>>
TRANS
_BITS
;
}
break
;
}
...
...
@@ -427,15 +454,15 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
/* Favor opaque subtitle pixels. */
if
(
(
p_source
->
s
.
t
==
0
)
&&
(
p_source
+
1
)
->
s
.
t
==
MAX_
ALPHA
)
if
(
(
p_source
->
s
.
t
==
0
)
&&
(
p_source
+
1
)
->
s
.
t
==
MAX_
TRANS
)
i_avg_tr
=
(
p_source
+
1
)
->
s
.
t
;
else
if
(
(
p_source
->
s
.
t
==
MAX_
ALPHA
)
&&
(
p_source
+
1
)
->
s
.
t
==
0
)
else
if
(
(
p_source
->
s
.
t
==
MAX_
TRANS
)
&&
(
p_source
+
1
)
->
s
.
t
==
0
)
i_avg_tr
=
p_source
->
s
.
t
;
else
i_avg_tr
=
(
p_source
->
s
.
t
+
(
p_source
+
1
)
->
s
.
t
)
/
2
;
#ifdef TESTING_TRANSPARENCY
if
(
i_avg_tr
==
MAX_
ALPHA
)
i_avg_tr
>>=
1
;
if
(
i_avg_tr
==
MAX_
TRANS
)
i_avg_tr
>>=
1
;
#endif
switch
(
i_avg_tr
)
...
...
@@ -444,7 +471,7 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
/* Completely transparent. Don't change pixel. */
break
;
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
...
...
@@ -455,10 +482,10 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
uint8_t
i_avg_v
;
/* Favor opaque subtitle pixel. */
if
(
p_source
->
s
.
t
==
MAX_
ALPHA
)
{
if
(
p_source
->
s
.
t
==
MAX_
TRANS
)
{
i_avg_u
=
p_source
->
plane
[
U_PLANE
]
;
i_avg_v
=
p_source
->
plane
[
V_PLANE
]
;
}
else
if
(
(
p_source
+
1
)
->
s
.
t
==
MAX_
ALPHA
)
{
}
else
if
(
(
p_source
+
1
)
->
s
.
t
==
MAX_
TRANS
)
{
i_avg_u
=
(
p_source
+
1
)
->
plane
[
U_PLANE
]
;
i_avg_v
=
(
p_source
+
1
)
->
plane
[
V_PLANE
]
;
}
else
{
...
...
@@ -514,16 +541,16 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
uint16_t
i_pixel_color_Y1
=
(
uint16_t
)
(
*
(
p_pixel
)
*
(
uint16_t
)
(
MAX_
ALPHA
-
i_avg_tr
)
)
;
(
uint16_t
)
(
MAX_
TRANS
-
i_avg_tr
)
)
;
uint16_t
i_pixel_color_Y2
=
(
uint16_t
)
(
*
(
p_pixel
+
2
)
*
(
uint16_t
)
(
MAX_
ALPHA
-
i_avg_tr
)
)
;
(
uint16_t
)
(
MAX_
TRANS
-
i_avg_tr
)
)
;
uint16_t
i_pixel_color_U
=
(
uint16_t
)
(
*
(
p_pixel
+
1
)
*
(
uint16_t
)
(
MAX_
ALPHA
-
i_avg_tr
)
)
;
(
uint16_t
)
(
MAX_
TRANS
-
i_avg_tr
)
)
;
uint16_t
i_pixel_color_V
=
(
uint16_t
)
(
*
(
p_pixel
+
3
)
*
(
uint16_t
)
(
MAX_
ALPHA
-
i_avg_tr
)
)
;
(
uint16_t
)
(
MAX_
TRANS
-
i_avg_tr
)
)
;
/* draw a two contiguous pixels: 2 Y values, 1 U, and 1 V. */
...
...
@@ -535,10 +562,10 @@ static void BlendYUY2( vout_thread_t *p_vout, picture_t *p_pic,
transparent and all opaque) aren't handled properly.
But we deal with them in special cases above. */
*
p_pixel
++
=
(
i_sub_color_Y1
+
i_pixel_color_Y1
)
>>
ALPHA
_BITS
;
*
p_pixel
++
=
(
i_sub_color_U
+
i_pixel_color_U
)
>>
ALPHA
_BITS
;
*
p_pixel
++
=
(
i_sub_color_Y2
+
i_pixel_color_Y2
)
>>
ALPHA
_BITS
;
*
p_pixel
++
=
(
i_sub_color_V
+
i_pixel_color_V
)
>>
ALPHA
_BITS
;
*
p_pixel
++
=
(
i_sub_color_Y1
+
i_pixel_color_Y1
)
>>
TRANS
_BITS
;
*
p_pixel
++
=
(
i_sub_color_U
+
i_pixel_color_U
)
>>
TRANS
_BITS
;
*
p_pixel
++
=
(
i_sub_color_Y2
+
i_pixel_color_Y2
)
>>
TRANS
_BITS
;
*
p_pixel
++
=
(
i_sub_color_V
+
i_pixel_color_V
)
>>
TRANS
_BITS
;
break
;
}
}
...
...
@@ -623,68 +650,62 @@ yuv2rgb565(ogt_yuvt_t *p_yuv, uint8_t *p_rgb1, uint8_t *p_rgb2 )
static
inline
void
rv16_pack_blend
(
uint8_t
*
p_pixel
,
ogt_yuvt_t
*
p_source
,
uint8_t
*
p_rgb1
,
uint8_t
*
p_rgb2
,
vlc_bool_t
b_15bpp
,
uint8_t
i_
alpha
,
uint8_t
*
p_rgb2
,
vlc_bool_t
b_15bpp
,
uint8_t
i_
trans
,
int
a_scale_down
)
{
uint8_t
rgb_s
ource
[
3
];
uint8_t
rgb
[
RGB_SIZE
];
uint8_t
rgb_s
ub
[
3
];
uint8_t
rgb
_vout
[
RGB_SIZE
];
int
i
;
#ifdef FIXED_RV16_TRANSPARENCY
uint8_t
i_dest_alpha
=
MAX_ALPHA
-
i_alpha
;
#endif
yuv2rgb
(
p_source
,
rgb_s
ource
);
yuv2rgb
(
p_source
,
rgb_s
ub
);
/* Scale RGB from 8 bits down to 6 or 5. */
rgb_s
ource
[
GREEN_PIXEL
]
>>=
(
8
-
5
);
rgb_s
ource
[
BLUE_PIXEL
]
>>=
(
8
-
5
);
rgb_s
ub
[
GREEN_PIXEL
]
>>=
(
8
-
5
);
rgb_s
ub
[
BLUE_PIXEL
]
>>=
(
8
-
5
);
rgb
[
GREEN_PIXEL
]
=
*
(
p_pixel
+
1
)
&
0x1f
;
rgb
_vout
[
GREEN_PIXEL
]
=
*
(
p_pixel
+
1
)
&
0x1f
;
if
(
b_15bpp
)
{
rgb_s
ource
[
RED_PIXEL
]
>>=
(
8
-
5
);
rgb
[
BLUE_PIXEL
]
=
((
*
p_pixel
)
>>
2
)
&
0x1f
;
rgb
[
RED_PIXEL
]
=
((
*
p_pixel
&
0x03
)
<<
3
)
|
((
*
(
p_pixel
+
1
)
&
0xe0
)
>>
5
);
rgb_s
ub
[
RED_PIXEL
]
>>=
(
8
-
5
);
rgb
_vout
[
BLUE_PIXEL
]
=
((
*
p_pixel
)
>>
2
)
&
0x1f
;
rgb
_vout
[
RED_PIXEL
]
=
((
*
p_pixel
&
0x03
)
<<
3
)
|
((
*
(
p_pixel
+
1
)
&
0xe0
)
>>
5
);
}
else
{
rgb_s
ource
[
RED_PIXEL
]
>>=
(
8
-
6
);
rgb
[
BLUE_PIXEL
]
=
((
*
p_pixel
)
>>
3
)
&
0x1f
;
rgb
[
RED_PIXEL
]
=
((
*
p_pixel
&
0x07
)
<<
3
)
|
((
*
(
p_pixel
+
1
)
&
0xe0
)
>>
5
);
rgb_s
ub
[
RED_PIXEL
]
>>=
(
8
-
6
);
rgb
_vout
[
BLUE_PIXEL
]
=
((
*
p_pixel
)
>>
3
)
&
0x1f
;
rgb
_vout
[
RED_PIXEL
]
=
((
*
p_pixel
&
0x07
)
<<
3
)
|
((
*
(
p_pixel
+
1
)
&
0xe0
)
>>
5
);
}
#if 0
printf("r,g,b=(%d,%d,%d), s
ource r,g,b=(%d,%d,%d), alpha %d, dest_alpha
%d\n",
rgb
[RED_PIXEL], rgb[GREEN_PIXEL], rgb
[BLUE_PIXEL],
rgb_s
ource[RED_PIXEL], rgb_source
[GREEN_PIXEL],
rgb_s
ource[BLUE_PIXEL], i_alpha, i_dest_alpha
);
printf("r,g,b=(%d,%d,%d), s
ub r,g,b=(%d,%d,%d), trans %d, inv_trans
%d\n",
rgb
_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout
[BLUE_PIXEL],
rgb_s
ub[RED_PIXEL], rgb_sub
[GREEN_PIXEL],
rgb_s
ub[BLUE_PIXEL], i_trans, i_inv_trans
);
#endif
for
(
i
=
0
;
i
<
RGB_SIZE
;
i
++
)
{
/* Average the two pixels. */
#ifdef FIXED_RV16_TRANSPARENCY
rgb
[
i
]
=
(
(
uint16_t
)
rgb_source
[
i
]
*
i_alpha
+
rgb
[
i
]
*
i_dest_alpha
)
>>
ALPHA_BITS
;
avg_8bit_rgb
(
rgb_vout
,
rgb_sub
,
i_trans
);
#else
for
(
i
=
0
;
i
<
RGB_SIZE
;
i
++
)
{
/* For now the Best we can do is fade the color. Picking up
video underneath doesn't work. */
/* rgb
[i] = ( (uint16_t) rgb[i]*i_dest_alpha ) >> ALPHA
_BITS; */
rgb
[
i
]
=
(
(
uint16_t
)
rgb_source
[
i
]
*
i_alpha
)
>>
ALPHA
_BITS
;
/* rgb
_vout[i] = ( (uint16_t) rgb_vout[i]*i_inv_trans ) >> TRANS
_BITS; */
rgb
_vout
[
i
]
=
(
(
uint16_t
)
rgb_sub
[
i
]
*
i_trans
)
>>
TRANS
_BITS
;
#endif
}
#if 0
printf("avg r,g,b=(%d,%d,%d)\n",
rgb
[RED_PIXEL], rgb[GREEN_PIXEL], rgb
[BLUE_PIXEL] );
rgb
_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout
[BLUE_PIXEL] );
#endif
#if 0
if (b_15bpp) {
*p_rgb1 = ( (rgb
[BLUE_PIXEL] << 2)&0x7c )|( (rgb
[RED_PIXEL]>>3)&0x03 );
*p_rgb1 = ( (rgb
_vout[BLUE_PIXEL] << 2)&0x7c )|( (rgb_vout
[RED_PIXEL]>>3)&0x03 );
} else {
*p_rgb1 = ( (rgb
[BLUE_PIXEL] << 3)&0xF8 )|( (rgb
[RED_PIXEL]>>3)&0x07 );
*p_rgb1 = ( (rgb
_vout[BLUE_PIXEL] << 3)&0xF8 )|( (rgb_vout
[RED_PIXEL]>>3)&0x07 );
}
*p_rgb2 = ( (rgb
[RED_PIXEL] << 5)&0xe0 ) | ( rgb
[GREEN_PIXEL]&0x1f );
*p_rgb2 = ( (rgb
_vout[RED_PIXEL] << 5)&0xe0 ) | ( rgb_vout
[GREEN_PIXEL]&0x1f );
#else
*
p_rgb1
=
(
*
p_rgb1
)
+
1
;
*
p_rgb2
=
(
*
p_rgb2
)
+
1
;
...
...
@@ -802,7 +823,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
}
#ifdef TESTING_TRANSPARENCY
if
(
p_source
->
s
.
t
==
MAX_
ALPHA
)
p_source
->
s
.
t
>>=
1
;
if
(
p_source
->
s
.
t
==
MAX_
TRANS
)
p_source
->
s
.
t
>>=
1
;
#endif
switch
(
p_source
->
s
.
t
)
...
...
@@ -811,7 +832,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
/* Completely transparent. Don't change pixel. */
break
;
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
...
...
@@ -857,7 +878,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
for
(
len
=
i_xlast
-
i_xdest
;
len
;
len
--
)
{
rv16_pack_blend
(
p_dest
,
p_source
,
&
i_rgb1
,
&
i_rgb2
,
b_15bpp
,
p_source
->
s
.
t
,
ALPHA
_SCALEDOWN
);
b_15bpp
,
p_source
->
s
.
t
,
TRANS
_SCALEDOWN
);
*
p_dest
++
=
i_rgb1
;
*
p_dest
++
=
i_rgb2
;
}
...
...
@@ -900,7 +921,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
/* Completely transparent. Don't change pixel. */
break
;
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
...
...
@@ -944,7 +965,7 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
uint8_t
*
p_dest
=
p_pixel_base
+
i_ytmp
;
for
(
len
=
i_xlast
-
i_xdest
;
len
;
len
--
)
{
rv16_pack_blend
(
p_dest
,
p_source
,
&
i_rgb1
,
&
i_rgb2
,
b_15bpp
,
p_source
->
s
.
t
,
ALPHA
_SCALEDOWN
);
b_15bpp
,
p_source
->
s
.
t
,
TRANS
_SCALEDOWN
);
*
p_dest
++
=
i_rgb1
;
*
p_dest
++
=
i_rgb2
;
}
...
...
@@ -961,33 +982,26 @@ BlendRV16( vout_thread_t *p_vout, picture_t *p_pic,
#define BYTES_PER_PIXEL 4
static
inline
void
rv24_pack_blend
(
uint8_t
*
p_pixel
,
uint8_t
*
rgb_source
,
uint8_t
i_alpha
,
rv24_pack_blend
(
uint8_t
*
rgb_vout
,
const
uint8_t
*
rgb_sub
,
uint8_t
i_trans
,
int
a_scale_down
)
{
int
i
;
uint8_t
i_dest_alpha
=
MAX_ALPHA
-
i_alpha
;
#if 0
printf("r,g,b=(%d,%d,%d), source r,g,b=(%d,%d,%d),
alpha %d, dest_alpha
%d\n",
p_pixel[RED_PIXEL], p_pixel[GREEN_PIXEL], p_pixel
[BLUE_PIXEL],
rgb_s
ource[RED_PIXEL], rgb_source
[GREEN_PIXEL],
rgb_s
ource[BLUE_PIXEL], i_alpha, i_dest_alpha
);
printf("r,g,b=(%d,%d,%d), source r,g,b=(%d,%d,%d),
trans
%d\n",
rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout
[BLUE_PIXEL],
rgb_s
ub[RED_PIXEL], rgb_sub
[GREEN_PIXEL],
rgb_s
ub[BLUE_PIXEL], i_trans
);
#endif
#ifdef WORDS_BIGENDIAN
*
p_pixel
++
;
*
rgb_vout
++
;
#endif
for
(
i
=
0
;
i
<
RGB_SIZE
;
i
++
)
{
/* Average the two pixels. */
p_pixel
[
i
]
=
(
(
uint16_t
)
rgb_source
[
i
]
*
i_alpha
+
p_pixel
[
i
]
*
i_dest_alpha
)
>>
ALPHA_BITS
;
}
avg_8bit_rgb
(
rgb_vout
,
rgb_sub
,
i_trans
);
#if 0
printf("avg r,g,b=(%d,%d,%d)\n",
rgb
[RED_PIXEL], rgb[GREEN_PIXEL], rgb
[BLUE_PIXEL] );
rgb
_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout
[BLUE_PIXEL] );
#endif
}
...
...
@@ -1111,7 +1125,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
}
#ifdef TESTING_TRANSPARENCY
if
(
p_source
->
s
.
t
==
MAX_
ALPHA
)
p_source
->
s
.
t
>>=
2
;
if
(
p_source
->
s
.
t
==
MAX_
TRANS
)
p_source
->
s
.
t
>>=
2
;
#endif
switch
(
p_source
->
s
.
t
)
...
...
@@ -1120,7 +1134,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
/* Completely transparent. Don't change pixel. */
break
;
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
...
...
@@ -1153,10 +1167,12 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
*
BYTES_PER_PIXEL
);
uint32_t
len
=
i_xlast
-
i_xdest
*
BYTES_PER_PIXEL
;
/* To be able to scale correctly for full opaqueness, we
add 1 to the alpha. This means alpha value 0 won't
be completely transparent and is not correct, but
that's handled in a special case above anyway. */
/* To be able to scale correctly for full
opaqueness, we add 1 to the transparency.
This means transparency value 0 won't be
completely transparent which is not correct.
But that's handled in a special case above
anyway. */
/* This is the location that's going to get changed. */
uint8_t
*
p_dest
=
p_pixel_base_y
+
i_xdest
;
...
...
@@ -1166,7 +1182,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
for
(
len
=
i_xlast
-
i_xdest
;
len
;
len
--
)
{
rv24_pack_blend
(
p_dest
,
rgb
,
p_source
->
s
.
t
,
ALPHA
_SCALEDOWN
);
TRANS
_SCALEDOWN
);
p_dest
+=
BYTES_PER_PIXEL
;
}
break
;
...
...
@@ -1209,7 +1225,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
/* Completely transparent. Don't change pixel. */
break
;
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
...
...
@@ -1267,7 +1283,7 @@ BlendRV24( vout_thread_t *p_vout, picture_t *p_pic,
for
(
len
=
i_xlast
-
i_xdest
;
len
;
len
--
)
{
rv24_pack_blend
(
p_dest
,
rgb
,
p_source
->
s
.
t
,
ALPHA
_SCALEDOWN
);
TRANS
_SCALEDOWN
);
p_dest
+=
BYTES_PER_PIXEL
;
}
}
...
...
@@ -1407,7 +1423,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
break
;
default:
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
...
...
@@ -1448,7 +1464,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
be completely transparent and is not correct, but
that's handled in a special case above anyway. */
uint8_t
i_destalpha
=
MAX_
ALPHA
-
p_source
->
s
.
t
;
uint8_t
i_destalpha
=
MAX_
TRANS
-
p_source
->
s
.
t
;
uint8_t
rgb
[
RGB_SIZE
];
/* This is the location that's going to get changed. */
...
...
@@ -1456,7 +1472,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
yuv2rgb
(
p_source
,
rgb
);
rv32_pack_blend
(
p_dest
,
rgb
,
dest_alpha
,
ALPHA
_SCALEDOWN
);
TRANS
_SCALEDOWN
);
for
(
len
=
i_xlast
-
i_xdest
;
len
;
len
--
)
{
*
p_dest
++
=
rgb
[
BLUE_PIXEL
];
...
...
@@ -1506,7 +1522,7 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
break
;
default:
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
/* Completely opaque. Completely overwrite underlying
pixel with subtitle pixel. */
...
...
@@ -1562,9 +1578,9 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
be completely transparent and is not correct, but
that's handled in a special case above anyway. */
uint8_t
i_destalpha
=
MAX_
ALPHA
-
p_source
->
s
.
t
;
uint8_t
i_destalpha
=
MAX_
TRANS
-
p_source
->
s
.
t
;
rv32_pack_blend
(
p_dest
,
rgb
,
dest_alpha
,
ALPHA
_SCALEDOWN
);
TRANS
_SCALEDOWN
);
}
break
;
#endif
/*TRANSPARENCY_FINISHED*/
...
...
@@ -1574,60 +1590,68 @@ BlendRV32( vout_thread_t *p_vout, picture_t *p_pic,
}
}
/* 4-entry array of colormap indices */
static
uint8_t
cmap
[
NUM_SUBTITLE_COLORS
];
/* Actual RGB values for above; this is used in blending.*/
static
uint8_t
cmap_rgb
[
NUM_SUBTITLE_COLORS
][
RGB_SIZE
];
/*
Return the colormap index for the average of
p
_pixel and a subtitle
pixel
in RGB form.
Return the colormap index for the average of
i
_pixel and a subtitle
pixel
whose subtitle palette entry is i_cmap.
*/
static
inline
cmap_t
avg_rgb2
(
const
vout_thread_t
*
p_vout
,
uint8_t
i_pixel
,
cmap_t
i_cmap_sub
,
const
uint8_t
rgb_sub
[]
)
avg_rgb2
(
const
vout_thread_t
*
p_vout
,
uint8_t
i_pixel
,
uint8_t
i_trans
,
int
i_cmap
,
mtime_t
i_pts
)
{
uint8_t
rgb_vout
[
RGB_SIZE
];
static
cmap_t
avg_cache
[
CMAP_RGB2_SIZE
][
NUM_SUBTITLE_COLORS
];
static
vlc_bool_t
b_first_time
=
VLC_TRUE
;
int
i
;
/* FIXME: really we need to save subtitle number since in theory
the palette can change each on each distinct subtitle. In practice
this doesn't happen that much.
/* Cache the average of a vout colormap entry and a subtitle palette
entry. There are not too many of these 256*4 = 1024.
*/
if
(
b_first_time
)
static
cmap_t
avg_cache
[
CMAP_RGB2_SIZE
][
NUM_SUBTITLE_COLORS
];
/* subtitle palettes might change between two subtitles. i_last_pts
will be used to figure out if the subtitle has changed, and
we have to invalidate the cache. */
static
mtime_t
i_last_pts
=
-
1
;
if
(
i_pts
!=
i_last_pts
)
{
int
i
,
j
;
for
(
i
=
0
;
i
<
CMAP_RGB2_SIZE
;
i
++
)
for
(
j
=
0
;
j
<
NUM_SUBTITLE_COLORS
;
j
++
)
avg_cache
[
i
][
j
]
=
INVALID_CMAP_ENTRY
;
/* Hack: We rely on the fact that INVALID_CMAP_ENTRY is repeated
0xFF.
*/
memset
(
avg_cache
,
0xFF
,
sizeof
(
avg_cache
));
i_last_pts
=
i_pts
;
}
if
(
avg_cache
[
i_pixel
][
i_cmap
_sub
]
!=
INVALID_CMAP_ENTRY
)
return
avg_cache
[
i_pixel
][
i_cmap
_sub
];
if
(
avg_cache
[
i_pixel
][
i_cmap
]
!=
INVALID_CMAP_ENTRY
)
return
avg_cache
[
i_pixel
][
i_cmap
];
if
(
!
query_color
(
p_vout
,
i_pixel
,
rgb_vout
)
)
return
INVALID_CMAP_ENTRY
;
for
(
i
=
0
;
i
<
RGB_SIZE
;
i
++
)
{
rgb_vout
[
i
]
=
(
rgb_vout
[
i
]
+
rgb_sub
[
i
])
/
2
;
}
avg_8bit_rgb
(
rgb_vout
,
cmap_rgb
[
i_cmap
],
i_trans
);
#if 0
{
uint8_t rgb_approx[RGB_SIZE];
avg_cache[i_pixel][i_cmap
_sub
] =
avg_cache[i_pixel][i_cmap] =
find_cmap_rgb8_nearest(p_vout, rgb_vout, rgb_approx);
printf(
"cmap old %0x new 0%x sub=(%0x, %0x, %0x) "
"avg=(%0x, %0x, %0x) vout=(%0x, %0x, %0x)\n",
i_pixel, i_cmap,
rgb_sub[RED_PIXEL], rgb_sub[GREEN_PIXEL], rgb_sub[BLUE_PIXEL],
"cmap old %0x avg approx 0%x sub: %d sub=(%0x, %0x, %0x) "
"approx=(%0x, %0x, %0x) avg vout=(%0x, %0x, %0x)\n",
i_pixel, avg_cache[i_pixel][i_cmap], i_cmap,
cmap_rgb[i_cmap][RED_PIXEL], cmap_rgb[i_cmap][GREEN_PIXEL],
cmap_rgb[i_cmap][BLUE_PIXEL],
rgb_approx[RED_PIXEL], rgb_approx[GREEN_PIXEL], rgb_approx[BLUE_PIXEL],
rgb_vout[RED_PIXEL], rgb_vout[GREEN_PIXEL], rgb_vout[BLUE_PIXEL]);
}
#else
avg_cache
[
i_pixel
][
i_cmap
_sub
]
=
avg_cache
[
i_pixel
][
i_cmap
]
=
find_cmap_rgb8_nearest
(
p_vout
,
rgb_vout
,
NULL
);
#endif
return
avg_cache
[
i_pixel
][
i_cmap
_sub
];
return
avg_cache
[
i_pixel
][
i_cmap
];
}
#undef BYTES_PER_PIXEL
...
...
@@ -1642,6 +1666,7 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
uint8_t
*
p_src_start
=
(
uint8_t
*
)
p_spu
->
p_sys
->
p_data
;
uint8_t
*
p_src_end
=
&
p_src_start
[
p_spu
->
i_height
*
p_spu
->
i_width
];
uint8_t
*
p_source
;
/* This is the where the subtitle pixels come from */
int
i
;
int
i_x
,
i_y
;
int
i_y_src
;
...
...
@@ -1657,13 +1682,6 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
/* Crop-specific */
int
i_x_start
,
i_y_start
,
i_x_end
,
i_y_end
;
/* 4-entry array of colormap indices */
uint8_t
cmap
[
NUM_SUBTITLE_COLORS
];
int
i
;
/* Actual RGB values for above; this is used in blending.*/
uint8_t
cmap_rgb
[
NUM_SUBTITLE_COLORS
][
RGB_SIZE
];
struct
subpicture_sys_t
*
p_sys
=
p_spu
->
p_sys
;
unsigned
int
i_aspect_x
,
i_aspect_y
;
...
...
@@ -1694,10 +1712,9 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
if
(
p_sys
->
p_palette
[
i
].
s
.
t
!=
0
)
{
uint8_t
rgb
[
RGB_SIZE
];
uint8_t
approx_rgb
[
RGB_SIZE
];
yuv2rgb
(
&
(
p_sys
->
p_palette
[
i
]),
rgb
);
cmap
[
i
]
=
find_cmap_rgb8_nearest
(
p_vout
,
rgb
,
approx_rgb
);
find_cmap_rgb8_nearest
(
p_vout
,
rgb
,
cmap_rgb
[
i
]
);
dbg_print
(
(
DECODE_DBG_RENDER
),
"palette %d RGB=(%0x, %0x, %0x)
\n
"
,
i
,
rgb
[
RED_PIXEL
],
rgb
[
GREEN_PIXEL
],
rgb
[
BLUE_PIXEL
]);
...
...
@@ -1768,7 +1785,7 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
p_yuvt
=
p_sys
->
p_palette
[
*
p_source
&
0x3
];
#ifdef TESTING_TRANSPARENCY
if
(
p_yuvt
.
s
.
t
==
MAX_
ALPHA
)
p_yuvt
.
s
.
t
>>=
1
;
if
(
p_yuvt
.
s
.
t
==
MAX_
TRANS
)
p_yuvt
.
s
.
t
>>=
1
;
#endif
switch
(
p_yuvt
.
s
.
t
)
...
...
@@ -1779,7 +1796,7 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
printf(" "); /*++++*/
#endif
break
;
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
uint32_t
i_xdest
=
(
((
i_x
*
i_xscale
)
>>
ASCALE
)
*
BYTES_PER_PIXEL
);
...
...
@@ -1803,15 +1820,25 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
uint8_t
*
p_pixel
=
p_pixel_base_y
+
i_xdest
;
uint32_t
len
=
i_xlast
-
i_xdest
;
#if FULL_TRANSPARENCY
/* This is what should be done, but it may be too
slow. */
for
(
len
=
i_xlast
-
i_xdest
-
1
;
len
>=
0
;
len
--
)
{
cmap_t
i_cmap
=
avg_rgb2
(
p_vout
,
*
p_pixel
,
cmap
[
*
p_source
],
cmap_rgb
[
*
p_source
]);
cmap_t
i_cmap
=
avg_rgb2
(
p_vout
,
*
p_pixel
,
p_yuvt
.
s
.
t
,
*
p_source
,
p_sys
->
i_pts
);
if
(
i_cmap
!=
INVALID_CMAP_ENTRY
)
*
p_pixel
=
(
uint8_t
)
i_cmap
;
p_pixel
++
;
}
#else
cmap_t
i_cmap
=
avg_rgb2
(
p_vout
,
*
p_pixel
,
p_yuvt
.
s
.
t
,
*
p_source
,
p_sys
->
i_pts
);
if
(
i_cmap
!=
INVALID_CMAP_ENTRY
)
memset
(
p_pixel
,
i_cmap
,
len
);
#endif
#if 0
printf("%1d", *p_source); /*++++*/
#endif
...
...
@@ -1851,7 +1878,7 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
}
#ifdef TESTING_TRANSPARENCY
if
(
p_yuvt
.
s
.
t
==
MAX_
ALPHA
)
p_yuvt
.
s
.
t
>>=
1
;
if
(
p_yuvt
.
s
.
t
==
MAX_
TRANS
)
p_yuvt
.
s
.
t
>>=
1
;
#endif
switch
(
p_yuvt
.
s
.
t
)
{
...
...
@@ -1861,7 +1888,7 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
printf(" "); /*++++*/
#endif
break
;
case
MAX_
ALPHA
:
case
MAX_
TRANS
:
{
uint32_t
i_xdest
=
(
((
i_x
*
i_xscale
)
>>
ASCALE
)
*
BYTES_PER_PIXEL
);
...
...
@@ -1884,7 +1911,7 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
*
BYTES_PER_PIXEL
);
uint32_t
i_xlast
=
(
(((
i_x
+
1
)
*
i_xscale
)
>>
ASCALE
)
*
BYTES_PER_PIXEL
);
int32_t
len
;
int32_t
len
=
i_xlast
-
i_xdest
;
#if 0
printf("%1d", *p_source); /*++++*/
#endif
...
...
@@ -1893,15 +1920,26 @@ BlendRGB2( vout_thread_t *p_vout, picture_t *p_pic,
i_ytmp
+=
p_pic
->
p
->
i_pitch
)
{
/* This is the pixel that's going to change;*/
uint8_t
*
p_pixel
=
p_pixel_base
+
i_ytmp
+
i_xdest
;
#if FULL_TRANSPARENCY
/* This is what should be done, but it may be too
slow. */
for
(
len
=
i_xlast
-
i_xdest
-
1
;
len
>=
0
;
len
--
)
{
cmap_t
i_cmap
=
avg_rgb2
(
p_vout
,
*
p_pixel
,
cmap
[
*
p_source
],
cmap_rgb
[
*
p_source
]
);
p_yuvt
.
s
.
t
,
*
p_source
,
p_sys
->
i_pts
);
if
(
i_cmap
!=
INVALID_CMAP_ENTRY
)
*
p_pixel
=
(
uint8_t
)
i_cmap
;
p_pixel
++
;
}
#else
cmap_t
i_cmap
=
avg_rgb2
(
p_vout
,
*
p_pixel
,
p_yuvt
.
s
.
t
,
*
p_source
,
p_sys
->
i_pts
);
if
(
i_cmap
!=
INVALID_CMAP_ENTRY
)
memset
(
p_pixel
,
i_cmap
,
len
);
#endif
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment