📄 spudec.cpp
字号:
memset(scaled_aimageY + y * scaled_strideY + scaled_width, 0, scaled_strideY - scaled_width);
/* FIXME: Why is self one needed? */
memset(scaled_imageY + y * scaled_strideY + scaled_width, 0, scaled_strideY - scaled_width);
}
/*
if (scaled_width/2 < scaled_strideUV)
for (unsigned int y = 0; y < scaled_height/2; ++y)
{
memset(scaled_aimageUV + y * scaled_strideUV + scaled_width/2, 128, scaled_strideUV - scaled_width/2);
memset(scaled_imageUV + y * scaled_strideUV + scaled_width/2, 128, scaled_strideUV - scaled_width/2);
}*/
memset(scaled_imageUV ,0,scaled_strideUV*(scaled_height/2));
memset(scaled_aimageUV,128,scaled_strideUV*((scaled_height+1)/2));
if (scaled_width <= 1 || scaled_height <= 1) {
goto nothing_to_do;
}
switch(spu_aamode&15) {
case 4:
sws_spu_image(scaled_imageY, scaled_aimageY,
scaled_width, scaled_height, scaled_strideY,
image, aimage, width, height, stride,prefs);
break;
case 3:
table_x = (scale_pixel*)calloc(scaled_width, sizeof(scale_pixel));
table_y = (scale_pixel*)calloc(scaled_height, sizeof(scale_pixel));
if (!table_x || !table_y) {
DPRINTF(_l("Fatal: spudec_draw_scaled: calloc failed"));
}
scale_table(0, 0, width - 1, scaled_width - 1, table_x);
scale_table(0, 0, height - 1, scaled_height - 1, table_y);
for (unsigned int y = 0; y < scaled_height; y++)
for (unsigned int x = 0; x < scaled_width; x++)
scale_image(x, y, table_x, table_y);
free(table_x);
free(table_y);
break;
case 0:
/* no antialiasing */
for (unsigned int y = 0; y < scaled_height; ++y) {
int unscaled_y = y * 0x100 / scaley;
int strides = stride * unscaled_y;
int scaled_strides = scaled_strideY * y;
for (unsigned int x = 0; x < scaled_width; ++x) {
int unscaled_x = x * 0x100 / scalex;
scaled_imageY[scaled_strides + x] = image[strides + unscaled_x];
scaled_aimageY[scaled_strides + x] = (unsigned char)canon_alpha(aimage[strides + unscaled_x]);
}
}
break;
case 1:
{
/* Intermediate antialiasing. */
for (unsigned int y = 0; y < scaled_height; ++y) {
const unsigned int unscaled_top = y * 0x100 / scaley;
unsigned int unscaled_bottom = (y + 1) * 0x100 / scaley;
if (unscaled_bottom >= height)
unscaled_bottom = height - 1;
for (unsigned int x = 0; x < scaled_width; ++x) {
const unsigned int unscaled_left = x * 0x100 / scalex;
unsigned int unscaled_right = (x + 1) * 0x100 / scalex;
unsigned int color = 0;
unsigned int alpha = 0;
unsigned int walkx, walky;
unsigned int base, tmp;
if (unscaled_right >= width)
unscaled_right = width - 1;
for (walky = unscaled_top; walky <= unscaled_bottom; ++walky)
for (walkx = unscaled_left; walkx <= unscaled_right; ++walkx) {
base = walky * stride + walkx;
tmp = canon_alpha(aimage[base]);
alpha += tmp;
color += tmp * image[base];
}
base = y * scaled_strideY + x;
scaled_imageY[base] = (unsigned char)(alpha ? color / alpha : 0);
scaled_aimageY[base] = (unsigned char)(alpha * (1 + unscaled_bottom - unscaled_top) * (1 + unscaled_right - unscaled_left));
}
}
}
break;
case 2:
{
/* Best antialiasing. Very slow. */
/* Any pixel (x, y) represents pixels from the original
rectangular region comprised between the columns
unscaled_y and unscaled_y + 0x100 / scaley and the rows
unscaled_x and unscaled_x + 0x100 / scalex
The original rectangular region that the scaled pixel
represents is cut in 9 rectangular areas like this:
+---+-----------------+---+
| 1 | 2 | 3 |
+---+-----------------+---+
| | | |
| 4 | 5 | 6 |
| | | |
+---+-----------------+---+
| 7 | 8 | 9 |
+---+-----------------+---+
The width of the left column is at most one pixel and
it is never null and its right column is at a pixel
boundary. The height of the top row is at most one
pixel it is never null and its bottom row is at a
pixel boundary. The width and height of region 5 are
integral values. The width of the right column is
what remains and is less than one pixel. The height
of the bottom row is what remains and is less than
one pixel.
The row above 1, 2, 3 is unscaled_y. The row between
1, 2, 3 and 4, 5, 6 is top_low_row. The row between 4,
5, 6 and 7, 8, 9 is (unsigned int)unscaled_y_bottom.
The row beneath 7, 8, 9 is unscaled_y_bottom.
The column left of 1, 4, 7 is unscaled_x. The column
between 1, 4, 7 and 2, 5, 8 is left_right_column. The
column between 2, 5, 8 and 3, 6, 9 is (unsigned
int)unscaled_x_right. The column right of 3, 6, 9 is
unscaled_x_right. */
const double inv_scalex = (double) 0x100 / scalex;
const double inv_scaley = (double) 0x100 / scaley;
for (unsigned int y = 0; y < scaled_height; ++y) {
const double unscaled_y = y * inv_scaley;
const double unscaled_y_bottom = unscaled_y + inv_scaley;
const unsigned int top_low_row = (unsigned int)std::min(unscaled_y_bottom, unscaled_y + 1.0);
const double top = top_low_row - unscaled_y;
const unsigned int height = unscaled_y_bottom > top_low_row
? (unsigned int) unscaled_y_bottom - top_low_row
: 0;
const double bottom = unscaled_y_bottom > top_low_row
? unscaled_y_bottom - floor(unscaled_y_bottom)
: 0.0;
for (unsigned int x = 0; x < scaled_width; ++x) {
const double unscaled_x = x * inv_scalex;
const double unscaled_x_right = unscaled_x + inv_scalex;
const unsigned int left_right_column = (unsigned int)std::min(unscaled_x_right, unscaled_x + 1.0);
const double left = left_right_column - unscaled_x;
const unsigned int width = unscaled_x_right > left_right_column
? (unsigned int) unscaled_x_right - left_right_column
: 0;
const double right = unscaled_x_right > left_right_column
? unscaled_x_right - floor(unscaled_x_right)
: 0.0;
double color = 0.0;
double alpha = 0.0;
double tmp;
unsigned int base;
/* Now use these informations to compute a good alpha,
and lightness. The sum is on each of the 9
region's surface and alpha and lightness.
transformed alpha = sum(surface * alpha) / sum(surface)
transformed color = sum(surface * alpha * color) / sum(surface * alpha)
*/
/* 1: top left part */
base = stride * (unsigned int) unscaled_y;
tmp = left * top * canon_alpha(aimage[base + (unsigned int) unscaled_x]);
alpha += tmp;
color += tmp * image[base + (unsigned int) unscaled_x];
/* 2: top center part */
if (width > 0) {
unsigned int walkx;
for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
base = stride * (unsigned int) unscaled_y + walkx;
tmp = /* 1.0 * */ top * canon_alpha(aimage[base]);
alpha += tmp;
color += tmp * image[base];
}
}
/* 3: top right part */
if (right > 0.0) {
base = stride * (unsigned int) unscaled_y + (unsigned int) unscaled_x_right;
tmp = right * top * canon_alpha(aimage[base]);
alpha += tmp;
color += tmp * image[base];
}
/* 4: center left part */
if (height > 0) {
unsigned int walky;
for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
base = stride * walky + (unsigned int) unscaled_x;
tmp = left /* * 1.0 */ * canon_alpha(aimage[base]);
alpha += tmp;
color += tmp * image[base];
}
}
/* 5: center part */
if (width > 0 && height > 0) {
unsigned int walky;
for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
unsigned int walkx;
base = stride * walky;
for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
tmp = /* 1.0 * 1.0 * */ canon_alpha(aimage[base + walkx]);
alpha += tmp;
color += tmp * image[base + walkx];
}
}
}
/* 6: center right part */
if (right > 0.0 && height > 0) {
unsigned int walky;
for (walky = top_low_row; walky < (unsigned int) unscaled_y_bottom; ++walky) {
base = stride * walky + (unsigned int) unscaled_x_right;
tmp = right /* * 1.0 */ * canon_alpha(aimage[base]);
alpha += tmp;
color += tmp * image[base];
}
}
/* 7: bottom left part */
if (bottom > 0.0) {
base = stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x;
tmp = left * bottom * canon_alpha(aimage[base]);
alpha += tmp;
color += tmp * image[base];
}
/* 8: bottom center part */
if (width > 0 && bottom > 0.0) {
unsigned int walkx;
base = stride * (unsigned int) unscaled_y_bottom;
for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) {
tmp = /* 1.0 * */ bottom * canon_alpha(aimage[base + walkx]);
alpha += tmp;
color += tmp * image[base + walkx];
}
}
/* 9: bottom right part */
if (right > 0.0 && bottom > 0.0) {
base = stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x_right;
tmp = right * bottom * canon_alpha(aimage[base]);
alpha += tmp;
color += tmp * image[base];
}
/* Finally mix these transparency and brightness information suitably */
base = scaled_strideY * y + x;
scaled_imageY[base] = (unsigned char)(alpha > 0 ? color / alpha : 0);
scaled_aimageY[base] = (unsigned char)(alpha * scalex * scaley / 0x10000);
/*
if (scaled_aimage[base]) {
scaled_aimage[base] = (unsigned char)(256 - scaled_aimage[base]);
if (scaled_aimage[base] + scaled_image[base] > 255)
scaled_image[base] = (unsigned char)(256 - scaled_aimage[base]);
}*/
}
}
}
}
nothing_to_do:
scaled_frame_width = dxs;
scaled_frame_height = dys;
for (unsigned int y=0;y<scaled_height/2;y++)
for (unsigned int x=0;x<scaled_width/2;x++)
{
scaled_imageUV[x+scaled_strideUV*y]=0;
scaled_aimageUV[x+scaled_strideUV*y]=scaled_aimageY[x*2+scaled_strideY*(y*2)];
}
}
}
if (scaled_imageY){
switch (spu_alignment) {
case 0:
scaled_start_row = dys*sub_pos/100;
if (scaled_start_row + scaled_height > dys)
scaled_start_row = dys - scaled_height;
break;
case 1:
y1 = dys*sub_pos/100 - scaled_height/2;
if (sub_pos < 50) {
if (y1 < 0) scaled_start_row = 0; else scaled_start_row = y1;
} else {
if (y1 + scaled_height > dys)
scaled_start_row = dys - scaled_height;
else
scaled_start_row = y1;
}
break;
case 2:
y1 = dys*sub_pos/100 - scaled_height;
if (y1 < 0) scaled_start_row = 0; else scaled_start_row = 0;
break;
}
draw_alpha(scaled_start_col, scaled_start_row, scaled_width, scaled_height,
scaled_imageY, scaled_aimageY, scaled_strideY,scaled_imageUV, scaled_aimageUV, scaled_strideUV,prefs);
spu_changed = 0;
}
}
}
else
{
DPRINTF(_l("SPU not displayed: start_pts=%d end_pts=%d now_pts=%d"),start_pts, end_pts, now_pts);
}
}
void Tspudec::spudec_update_palette( unsigned int *palette)
{
if (palette) {
memcpy(global_palette, palette, sizeof(global_palette));
}
}
void Tspudec::spudec_set_font_factor( double factor)
{
font_start_level = (int)(0xF0-(0xE0*factor));
}
/*
Tspudec::Tspudec(unsigned int *palette, unsigned int frame_width, unsigned int frame_height)
{
Tspudec(palette, NULL, 0, frame_width, frame_height);
}
*/
/* get palette custom color, width, height from .idx file */
Tspudec::Tspudec(IffdshowBase *Ideci,const AM_DVD_YUV *palette, const AM_DVD_YUV *cuspal, unsigned int custom, unsigned int frame_width, unsigned int frame_height)
{
memset(this,0,sizeof(*this));
deci=Ideci;
spu_aamode = 4;
spu_alignment = -1;
sub_pos=0;
oldgauss=-1;
deci->getPostproc(&libmplayer);
this->packet = NULL;
this->image = NULL;
this->scaled_imageY=this->scaled_imageUV = NULL;
/* XXX Although the video frame is some size, the SPU frame is
always maximum size i.e. 720 wide and 576 or 480 high */
this->orig_frame_width = 720;
this->orig_frame_height = (frame_height == 480 || frame_height == 240) ? 480 : 576;
this->custom = custom;
// set up palette:
this->auto_palette = 1;
if (palette){
memcpy(this->global_palette, palette, sizeof(this->global_palette));
this->auto_palette = 0;
}
this->custom = custom;
if (custom && cuspal) {
memcpy(this->cuspal, cuspal, sizeof(this->cuspal));
this->auto_palette = 0;
}
// forced subtitles default: show all subtitles
this->forced_subs_only=0;
this->is_forced_sub=0;
packet_pts=0;
}
/*
Tspudec::Tspudec(unsigned int *palette)
{
Tspudec(palette, 0, 0);
}
*/
Tspudec::~Tspudec()
{
if (filter.lumH) libmplayer->sws_freeVec(filter.lumH);
while (queue_head)
spudec_free_packet(spudec_dequeue_packet());
if (packet)
free(packet);
if (scaled_imageY)
free(scaled_imageY);
if (scaled_imageUV)
free(scaled_imageUV);
if (image)
free(image);
libmplayer->Release();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -