Mercurial > mplayer.hg
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 } |