comparison spudec.c @ 6215:e435026183c3

spu/vobsub speedup patch, new all better bilinear scaler similiar to win vobsub ones. ptyh by Hephooey.
author atmos4
date Tue, 28 May 2002 02:16:01 +0000
parents bd6748605681
children 7833c711d62b
comparison
equal deleted inserted replaced
6214:0398cb49fe5e 6215:e435026183c3
1 /* Valid values for ANTIALIASING_ALGORITHM: 1 /* Valid values for ANTIALIASING_ALGORITHM:
2 -1: bilinear (similiar to vobsub, fast and good quality)
2 0: none (fastest, most ugly) 3 0: none (fastest, most ugly)
3 1: aproximate 4 1: aproximate
4 2: full (slowest, best looking) 5 2: full (slowest, best looking)
5 */ 6 */
6 #define ANTIALIASING_ALGORITHM 2 7 #define ANTIALIASING_ALGORITHM -1
8
9 /* Valid values for SUBPOS:
10 0: leave the sub on it's original place
11 1: put the sub at the bottom of the picture
12 */
13 #define SUBPOS 0
7 14
8 /* SPUdec.c 15 /* SPUdec.c
9 Skeleton of function spudec_process_controll() is from xine sources. 16 Skeleton of function spudec_process_controll() is from xine sources.
10 Further works: 17 Further works:
11 LGB,... (yeah, try to improve it and insert your name here! ;-) 18 LGB,... (yeah, try to improve it and insert your name here! ;-)
117 default: 124 default:
118 return (0xf - i) << 4; 125 return (0xf - i) << 4;
119 } 126 }
120 } 127 }
121 128
129 /* Cut the sub to visible part */
130 static inline void spudec_cut_image(spudec_handle_t *this)
131 {
132 unsigned int fy, ly;
133 unsigned int first_y, last_y;
134 unsigned char *image;
135 unsigned char *aimage;
136 for (fy = 0; fy < this->image_size && !this->aimage[fy]; fy++);
137 for (ly = this->stride * this->height-1; ly && !this->aimage[ly]; ly--);
138 first_y = fy / this->stride;
139 last_y = ly / this->stride;
140 //printf("first_y: %d, last_y: %d\n", first_y, last_y);
141 this->start_row += first_y;
142 this->height = last_y - first_y +1;
143 //printf("new h %d new start %d (sz %d st %d)---\n\n", this->height, this->start_row, this->image_size, this->stride);
144 image = malloc(2 * this->stride * this->height);
145 if(image){
146 this->image_size = this->stride * this->height;
147 aimage = image + this->image_size;
148 memcpy(image, this->image + this->stride * first_y, this->image_size);
149 memcpy(aimage, this->aimage + this->stride * first_y, this->image_size);
150 free(this->image);
151 this->image = image;
152 this->aimage = aimage;
153 }
154 else
155 perror("Fatal: update_spu: malloc");
156 }
157
122 static void spudec_process_data(spudec_handle_t *this) 158 static void spudec_process_data(spudec_handle_t *this)
123 { 159 {
124 unsigned int cmap[4], alpha[4]; 160 unsigned int cmap[4], alpha[4];
125 unsigned int i, x, y; 161 unsigned int i, x, y;
126 162
193 next_line(this); 229 next_line(this);
194 x = 0; 230 x = 0;
195 ++y; 231 ++y;
196 } 232 }
197 } 233 }
234 spudec_cut_image(this);
198 } 235 }
199 236
200 237
201 /* 238 /*
202 This function tries to create a usable palette. 239 This function tries to create a usable palette.
450 if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts && spu->image) 487 if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts && spu->image)
451 draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height, 488 draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
452 spu->image, spu->aimage, spu->stride); 489 spu->image, spu->aimage, spu->stride);
453 } 490 }
454 491
492 /* calc the bbox for spudec subs */
455 void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox) 493 void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox)
456 { 494 {
457 spudec_handle_t *spu; 495 spudec_handle_t *spu;
458 spu = (spudec_handle_t *)me; 496 spu = (spudec_handle_t *)me;
459 if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0 497 if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
466 else if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) { 504 else if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) {
467 unsigned int scalex = 0x100 * dxs / spu->orig_frame_width; 505 unsigned int scalex = 0x100 * dxs / spu->orig_frame_width;
468 unsigned int scaley = 0x100 * dys / spu->orig_frame_height; 506 unsigned int scaley = 0x100 * dys / spu->orig_frame_height;
469 bbox[0] = spu->start_col * scalex / 0x100; 507 bbox[0] = spu->start_col * scalex / 0x100;
470 bbox[1] = spu->start_col * scalex / 0x100 + spu->width * scalex / 0x100; 508 bbox[1] = spu->start_col * scalex / 0x100 + spu->width * scalex / 0x100;
509 #if SUBPOS == 0
471 bbox[2] = spu->start_row * scaley / 0x100; 510 bbox[2] = spu->start_row * scaley / 0x100;
472 bbox[3] = spu->start_row * scaley / 0x100 + spu->height * scaley / 0x100; 511 bbox[3] = spu->start_row * scaley / 0x100 + spu->height * scaley / 0x100;
473 } 512 #elif SUBPOS == 1
474 } 513 bbox[3] = dys -1;
475 514 bbox[2] = bbox[3] -spu->height * scaley / 0x100;
515 #endif
516 }
517 }
476 /* transform mplayer's alpha value into an opacity value that is linear */ 518 /* transform mplayer's alpha value into an opacity value that is linear */
477 static inline int canon_alpha(int alpha) 519 static inline int canon_alpha(int alpha)
478 { 520 {
479 return alpha ? 256 - alpha : 0; 521 return alpha ? 256 - alpha : 0;
480 } 522 }
481 523
524 typedef struct {
525 unsigned position;
526 unsigned left_up;
527 unsigned right_down;
528 }scale_pixel;
529
530
531 static int scale_table(unsigned int start_src, unsigned int start_tar, unsigned int end_src, unsigned int end_tar, scale_pixel * table)
532 {
533 unsigned int t;
534 unsigned int delta_src = end_src - start_src;
535 unsigned int delta_tar = end_tar - start_tar;
536 int src = 0;
537 int src_step = (delta_src << 16) / delta_tar >>1;
538 for (t = 0; t<=delta_tar; src += (src_step << 1), t++){
539 table[t].position= MIN(src >> 16, end_src - 1);
540 table[t].right_down = src & 0xffff;
541 table[t].left_up = 0x10000 - table[t].right_down;
542 }
543 }
544
545 /* bilinear scale, similar to vobsub's code */
546 static int scale_image(int x, int y, scale_pixel* table_x, scale_pixel* table_y, spudec_handle_t * spu)
547 {
548 int i;
549 int alpha[4];
550 int color[4];
551 unsigned int scale[4];
552 int base = table_y[y].position * spu->stride + table_x[x].position;
553 int scaled = y * spu->scaled_stride + x;
554 alpha[0] = canon_alpha(spu->aimage[base]);
555 alpha[1] = canon_alpha(spu->aimage[base + 1]);
556 alpha[2] = canon_alpha(spu->aimage[base + spu->stride]);
557 alpha[3] = canon_alpha(spu->aimage[base + spu->stride + 1]);
558 color[0] = spu->image[base];
559 color[1] = spu->image[base + 1];
560 color[2] = spu->image[base + spu->stride];
561 color[3] = spu->image[base + spu->stride + 1];
562 scale[0] = (table_x[x].left_up * table_y[y].left_up >> 16) * alpha[0];
563 scale[1] = (table_x[x].right_down * table_y[y].left_up >>16) * alpha[1];
564 scale[2] = (table_x[x].left_up * table_y[y].right_down >> 16) * alpha[2];
565 scale[3] = (table_x[x].right_down * table_y[y].right_down >> 16) * alpha[3];
566 spu->scaled_image[scaled] = (color[0] * scale[0] + color[1] * scale[1] + color[2] * scale[2] + color[3] * scale[3])>>24;
567 spu->scaled_aimage[scaled] = (scale[0] + scale[1] + scale[2] + scale[3]) >> 16;
568 if (spu->scaled_aimage[scaled]){
569 spu->scaled_aimage[scaled] = 256 - spu->scaled_aimage[scaled];
570 if(spu->scaled_aimage[scaled] + spu->scaled_image[scaled] > 255)
571 spu->scaled_image[scaled] = 256 - spu->scaled_aimage[scaled];
572 }
573 }
574
482 void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)) 575 void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride))
483 { 576 {
484 spudec_handle_t *spu = (spudec_handle_t *)me; 577 spudec_handle_t *spu = (spudec_handle_t *)me;
578 scale_pixel *table_x;
579 scale_pixel *table_y;
485 if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts) { 580 if (spu->start_pts <= spu->now_pts && spu->now_pts < spu->end_pts) {
486 if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0 581 if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0
487 || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys)) { 582 || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys)) {
488 if (spu->image) 583 if (spu->image)
489 draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height, 584 draw_alpha(spu->start_col, spu->start_row, spu->width, spu->height,
522 spu->scaled_stride - spu->scaled_width); 617 spu->scaled_stride - spu->scaled_width);
523 /* FIXME: Why is this one needed? */ 618 /* FIXME: Why is this one needed? */
524 memset(spu->scaled_image + y * spu->scaled_stride + spu->scaled_width, 0, 619 memset(spu->scaled_image + y * spu->scaled_stride + spu->scaled_width, 0,
525 spu->scaled_stride - spu->scaled_width); 620 spu->scaled_stride - spu->scaled_width);
526 } 621 }
527 #if ANTIALIASING_ALGORITHM == 0 622 #if ANTIALIASING_ALGORITHM == -1
623 table_x = calloc(spu->scaled_width, sizeof(scale_pixel));
624 table_y = calloc(spu->scaled_height, sizeof(scale_pixel));
625 scale_table(0, 0, spu->width - 1, spu->scaled_width - 1, table_x);
626 scale_table(0, 0, spu->height - 1, spu->scaled_height - 1, table_y);
627 for (y = 0; y < spu->scaled_height; y++)
628 for (x = 0; x < spu->scaled_width; x++)
629 scale_image(x, y, table_x, table_y, spu);
630 if(table_x)
631 free(table_x);
632 if(table_y)
633 free(table_y);
634 #elif ANTIALIASING_ALGORITHM == 0
528 /* no antialiasing */ 635 /* no antialiasing */
529 for (y = 0; y < spu->scaled_height; ++y) { 636 for (y = 0; y < spu->scaled_height; ++y) {
530 int unscaled_y = y * 0x100 / scaley; 637 int unscaled_y = y * 0x100 / scaley;
531 int strides = spu->stride * unscaled_y; 638 int strides = spu->stride * unscaled_y;
532 int scaled_strides = spu->scaled_stride * y; 639 int scaled_strides = spu->scaled_stride * y;
745 spu->scaled_frame_width = dxs; 852 spu->scaled_frame_width = dxs;
746 spu->scaled_frame_height = dys; 853 spu->scaled_frame_height = dys;
747 } 854 }
748 } 855 }
749 if (spu->scaled_image){ 856 if (spu->scaled_image){
857 #if SUBPOS == 1
858 /*set subs at the bottom, i don't like to put it at the very bottom, so -1 :)*/
859 spu->scaled_start_row = dys - spu->scaled_height - 1;
860 #endif
750 draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height, 861 draw_alpha(spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height,
751 spu->scaled_image, spu->scaled_aimage, spu->scaled_stride); 862 spu->scaled_image, spu->scaled_aimage, spu->scaled_stride);
752 spu_changed = 0; 863 spu_changed = 0;
753 } 864 }
754 } 865 }