From fd5c4a19849b768986a0e652bb2f398c922f42dd Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 7 Oct 2012 22:02:03 +0200 Subject: Remove things related to old OSD To ease changing all the VOs to the new OSD rendering, fallbacks, conversions, support code etc. was left all over the code. Now that all VOs have been changed, all that code is inactive. Remove it. Strip down spudec.c. We don't need the old grayscale and scaling stuff anymore. (Not removing spudec itself yet - I'm not confident that the libavcodec DVD sub decoder is sufficient, and it would also require some hacks to get DVD palette and resolution information from libdvdread to libavcodec.) The option --spuaa, --spualign, --spugauss were used with the old sub scaling code, and don't do anything anymore. --- DOCS/man/en/options.rst | 24 -- Makefile | 1 - cfg-mplayer.h | 3 - libvo/osd.c | 224 -------------- libvo/osd.h | 34 --- libvo/osd_template.c | 383 ------------------------ libvo/vo_corevideo.m | 1 - libvo/vo_lavc.c | 1 - libvo/vo_opengl.c | 1 - libvo/vo_opengl_old.c | 1 - libvo/vo_x11.c | 1 - libvo/vo_xv.c | 1 - sub/img_convert.c | 198 +------------ sub/img_convert.h | 3 - sub/spudec.c | 772 ------------------------------------------------ sub/spudec.h | 18 -- sub/sub.c | 52 ---- sub/sub.h | 24 -- 18 files changed, 1 insertion(+), 1741 deletions(-) delete mode 100644 libvo/osd.c delete mode 100644 libvo/osd.h delete mode 100644 libvo/osd_template.c diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index ca245f6d32..3be707bfad 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -1781,30 +1781,6 @@ --speed=<0.01-100> Slow down or speed up playback by the factor given as parameter. ---spuaa= - Antialiasing/scaling mode for DVD/VOBsub. A value of 16 may be added to - in order to force scaling even when original and scaled frame size - already match. This can be employed to e.g. smooth subtitles with gaussian - blur. Available modes are: - - :0: none (fastest, very ugly) - :1: approximate (broken?) - :2: full (slow) - :3: bilinear (default, fast and not too bad) - :4: uses swscaler gaussian blur (looks very good) - ---spualign=<-1-2> - Specify how SPU (DVD/VOBsub) subtitles should be aligned. - - :-1: Original position - :0: Align at top (original behavior, default). - :1: Align at center. - :2: Align at bottom. - ---spugauss=<0.0-3.0> - Variance parameter of gaussian used by ``--spuaa=4``. Higher means more - blur (default: 1.0). - --srate= Select the output sample rate to be used (of course sound cards have limits on this). If the sample frequency selected is different from that diff --git a/Makefile b/Makefile index ecd33359c2..dd476d2a28 100644 --- a/Makefile +++ b/Makefile @@ -198,7 +198,6 @@ SRCS_COMMON = asxparser.c \ libmpdemux/mf.c \ libmpdemux/mp_taglists.c \ libmpdemux/video.c \ - libvo/osd.c \ libvo/bitmap_packer.c \ osdep/numcores.c \ osdep/io.c \ diff --git a/cfg-mplayer.h b/cfg-mplayer.h index 581f363148..975c11b9ff 100644 --- a/cfg-mplayer.h +++ b/cfg-mplayer.h @@ -532,9 +532,6 @@ const m_option_t common_opts[] = { {"ffactor", &font_factor, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 10.0, NULL}, {"sub-pos", &sub_pos, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL}, {"subwidth", &sub_width_p, CONF_TYPE_INT, CONF_RANGE, 10, 100, NULL}, - {"spualign", &spu_alignment, CONF_TYPE_INT, CONF_RANGE, -1, 2, NULL}, - {"spuaa", &spu_aamode, CONF_TYPE_INT, CONF_RANGE, 0, 31, NULL}, - {"spugauss", &spu_gaussvar, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 3.0, NULL}, {"subfont-encoding", &subtitle_font_encoding, CONF_TYPE_STRING, 0, 0, 0, NULL}, {"subfont-text-scale", &text_font_scale_factor, CONF_TYPE_FLOAT, CONF_RANGE, 0, 100, NULL}, {"subfont-osd-scale", &osd_font_scale_factor, CONF_TYPE_FLOAT, CONF_RANGE, 0, 100, NULL}, diff --git a/libvo/osd.c b/libvo/osd.c deleted file mode 100644 index 2fd294a13a..0000000000 --- a/libvo/osd.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * generic alpha renderers for all YUV modes and RGB depths - * These are "reference implementations", should be optimized later (MMX, etc). - * templating code by Michael Niedermayer (michaelni@gmx.at) - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" -#include "osd.h" -#include "mp_msg.h" -#include -#include -#include "cpudetect.h" - -#if ARCH_X86 -static const uint64_t bFF __attribute__((aligned(8))) = 0xFFFFFFFFFFFFFFFFULL; -static const unsigned long long mask24lh __attribute__((aligned(8))) = 0xFFFF000000000000ULL; -static const unsigned long long mask24hl __attribute__((aligned(8))) = 0x0000FFFFFFFFFFFFULL; -#endif - -//Note: we have C, X86-nommx, MMX, MMX2 -//Plain C versions -#define COMPILE_C - -#if ARCH_X86 - -#define COMPILE_MMX -#define COMPILE_MMX2 - -#endif /* ARCH_X86 */ - -#undef HAVE_MMX -#undef HAVE_MMX2 -#define HAVE_MMX 0 -#define HAVE_MMX2 0 - -#if ! ARCH_X86 - -#ifdef COMPILE_C -#undef HAVE_MMX -#undef HAVE_MMX2 -#define HAVE_MMX 0 -#define HAVE_MMX2 0 -#define RENAME(a) a ## _C -#include "osd_template.c" -#endif - -#else - -//X86 noMMX versions -#ifdef COMPILE_C -#undef RENAME -#undef HAVE_MMX -#undef HAVE_MMX2 -#define HAVE_MMX 0 -#define HAVE_MMX2 0 -#define RENAME(a) a ## _X86 -#include "osd_template.c" -#endif - -//MMX versions -#ifdef COMPILE_MMX -#undef RENAME -#undef HAVE_MMX -#undef HAVE_MMX2 -#define HAVE_MMX 1 -#define HAVE_MMX2 0 -#define RENAME(a) a ## _MMX -#include "osd_template.c" -#endif - -//MMX2 versions -#ifdef COMPILE_MMX2 -#undef RENAME -#undef HAVE_MMX -#undef HAVE_MMX2 -#define HAVE_MMX 1 -#define HAVE_MMX2 1 -#define RENAME(a) a ## _MMX2 -#include "osd_template.c" -#endif - -#endif /* ARCH_X86 */ - -void vo_draw_alpha_yv12(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ -#if ARCH_X86 - // ordered by speed / fastest first - if(gCpuCaps.hasMMX2) - vo_draw_alpha_yv12_MMX2(w, h, src, srca, srcstride, dstbase, dststride); - else if(gCpuCaps.hasMMX) - vo_draw_alpha_yv12_MMX(w, h, src, srca, srcstride, dstbase, dststride); - else - vo_draw_alpha_yv12_X86(w, h, src, srca, srcstride, dstbase, dststride); -#else - vo_draw_alpha_yv12_C(w, h, src, srca, srcstride, dstbase, dststride); -#endif -} - -void vo_draw_alpha_yuy2(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ -#if ARCH_X86 - // ordered by speed / fastest first - if(gCpuCaps.hasMMX2) - vo_draw_alpha_yuy2_MMX2(w, h, src, srca, srcstride, dstbase, dststride); - else if(gCpuCaps.hasMMX) - vo_draw_alpha_yuy2_MMX(w, h, src, srca, srcstride, dstbase, dststride); - else - vo_draw_alpha_yuy2_X86(w, h, src, srca, srcstride, dstbase, dststride); -#else - vo_draw_alpha_yuy2_C(w, h, src, srca, srcstride, dstbase, dststride); -#endif -} - -void vo_draw_alpha_rgb24(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ -#if ARCH_X86 - // ordered by speed / fastest first - if(gCpuCaps.hasMMX2) - vo_draw_alpha_rgb24_MMX2(w, h, src, srca, srcstride, dstbase, dststride); - else if(gCpuCaps.hasMMX) - vo_draw_alpha_rgb24_MMX(w, h, src, srca, srcstride, dstbase, dststride); - else - vo_draw_alpha_rgb24_X86(w, h, src, srca, srcstride, dstbase, dststride); -#else - vo_draw_alpha_rgb24_C(w, h, src, srca, srcstride, dstbase, dststride); -#endif -} - -void vo_draw_alpha_rgb32(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ -#if ARCH_X86 - // ordered by speed / fastest first - if(gCpuCaps.hasMMX2) - vo_draw_alpha_rgb32_MMX2(w, h, src, srca, srcstride, dstbase, dststride); - else if(gCpuCaps.hasMMX) - vo_draw_alpha_rgb32_MMX(w, h, src, srca, srcstride, dstbase, dststride); - else - vo_draw_alpha_rgb32_X86(w, h, src, srca, srcstride, dstbase, dststride); -#else - vo_draw_alpha_rgb32_C(w, h, src, srca, srcstride, dstbase, dststride); -#endif -} - -void vo_draw_alpha_rgb12(int w, int h, unsigned char* src, unsigned char *srca, - int srcstride, unsigned char* dstbase, int dststride) { - int y; - for (y = 0; y < h; y++) { - register unsigned short *dst = (unsigned short*) dstbase; - register int x; - for (x = 0; x < w; x++) { - if(srca[x]){ - unsigned char r = dst[x] & 0x0F; - unsigned char g = (dst[x] >> 4) & 0x0F; - unsigned char b = (dst[x] >> 8) & 0x0F; - r = (((r*srca[x]) >> 4) + src[x]) >> 4; - g = (((g*srca[x]) >> 4) + src[x]) >> 4; - b = (((b*srca[x]) >> 4) + src[x]) >> 4; - dst[x] = (b << 8) | (g << 4) | r; - } - } - src += srcstride; - srca += srcstride; - dstbase += dststride; - } - return; -} - -void vo_draw_alpha_rgb15(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ - int y; - for(y=0;y>5)&0x1F; - unsigned char b=(dst[x]>>10)&0x1F; - r=(((r*srca[x])>>5)+src[x])>>3; - g=(((g*srca[x])>>5)+src[x])>>3; - b=(((b*srca[x])>>5)+src[x])>>3; - dst[x]=(b<<10)|(g<<5)|r; - } - } - src+=srcstride; - srca+=srcstride; - dstbase+=dststride; - } - return; -} - -void vo_draw_alpha_rgb16(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ - int y; - for(y=0;y>5)&0x3F; - unsigned char b=(dst[x]>>11)&0x1F; - r=(((r*srca[x])>>5)+src[x])>>3; - g=(((g*srca[x])>>6)+src[x])>>2; - b=(((b*srca[x])>>5)+src[x])>>3; - dst[x]=(b<<11)|(g<<5)|r; - } - } - src+=srcstride; - srca+=srcstride; - dstbase+=dststride; - } - return; -} diff --git a/libvo/osd.h b/libvo/osd.h deleted file mode 100644 index 4e8064a93f..0000000000 --- a/libvo/osd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * generic alpha renderers for all YUV modes and RGB depths - * These are "reference implementations", should be optimized later (MMX, etc). - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_OSD_H -#define MPLAYER_OSD_H - -void vo_draw_alpha_yv12(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride); -void vo_draw_alpha_yuy2(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride); -void vo_draw_alpha_rgb24(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride); -void vo_draw_alpha_rgb32(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride); -void vo_draw_alpha_rgb12(int w, int h, unsigned char* src, unsigned char *srca, - int srcstride, unsigned char* dstbase, int dststride); -void vo_draw_alpha_rgb15(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride); -void vo_draw_alpha_rgb16(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride); - -#endif /* MPLAYER_OSD_H */ diff --git a/libvo/osd_template.c b/libvo/osd_template.c deleted file mode 100644 index 40a335e30e..0000000000 --- a/libvo/osd_template.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - * generic alpha renderers for all YUV modes and RGB depths - * Optimized by Nick and Michael. - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#undef PREFETCH -#undef EMMS -#undef PREFETCHW -#undef PAVGB - -#if HAVE_MMX2 -#define PREFETCH "prefetchnta" -#define PREFETCHW "prefetcht0" -#define PAVGB "pavgb" -#else -#define PREFETCH " # nop" -#define PREFETCHW " # nop" -#endif - -#define EMMS "emms" - -static inline void RENAME(vo_draw_alpha_yv12)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ - int y; -#if HAVE_MMX - __asm__ volatile( - "pcmpeqb %%mm5, %%mm5\n\t" // F..F - "movq %%mm5, %%mm4\n\t" - "movq %%mm5, %%mm7\n\t" - "psllw $8, %%mm5\n\t" //FF00FF00FF00 - "psrlw $8, %%mm4\n\t" //00FF00FF00FF - ::); -#endif - for(y=0;y>8)+src[x]; - } -#endif - src+=srcstride; - srca+=srcstride; - dstbase+=dststride; - } -#if HAVE_MMX - __asm__ volatile(EMMS:::"memory"); -#endif - return; -} - -static inline void RENAME(vo_draw_alpha_yuy2)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ - int y; -#if HAVE_MMX - __asm__ volatile( - "pxor %%mm7, %%mm7\n\t" - "pcmpeqb %%mm5, %%mm5\n\t" // F..F - "movq %%mm5, %%mm6\n\t" - "movq %%mm5, %%mm4\n\t" - "psllw $8, %%mm5\n\t" //FF00FF00FF00 - "psrlw $8, %%mm4\n\t" //00FF00FF00FF - ::); -#endif - for(y=0;y>8)+src[x]; - dstbase[2*x+1]=((((signed)dstbase[2*x+1]-128)*srca[x])>>8)+128; - } - } -#endif - src+=srcstride; - srca+=srcstride; - dstbase+=dststride; - } -#if HAVE_MMX - __asm__ volatile(EMMS:::"memory"); -#endif - return; -} - -static inline void RENAME(vo_draw_alpha_rgb24)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ - int y; -#if HAVE_MMX - __asm__ volatile( - "pxor %%mm7, %%mm7\n\t" - "pcmpeqb %%mm6, %%mm6\n\t" // F..F - ::); -#endif - for(y=0;y>8)+src[x]; - dst[1]=((dst[1]*srca[x])>>8)+src[x]; - dst[2]=((dst[2]*srca[x])>>8)+src[x]; - } - dst+=3; // 24bpp - } -#endif /* arch_x86 */ - src+=srcstride; - srca+=srcstride; - dstbase+=dststride; - } -#if HAVE_MMX - __asm__ volatile(EMMS:::"memory"); -#endif - return; -} - -static inline void RENAME(vo_draw_alpha_rgb32)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){ - int y; -#if BYTE_ORDER == BIG_ENDIAN - dstbase++; -#endif -#if HAVE_MMX - __asm__ volatile( - "pxor %%mm7, %%mm7\n\t" - "pcmpeqb %%mm5, %%mm5\n\t" // F..F - "movq %%mm5, %%mm4\n\t" - "psllw $8, %%mm5\n\t" //FF00FF00FF00 - "psrlw $8, %%mm4\n\t" //00FF00FF00FF - ::); -#endif /* HAVE_MMX */ - for(y=0;y>8)+src[x]; - dstbase[4*x+1]=((dstbase[4*x+1]*srca[x])>>8)+src[x]; - dstbase[4*x+2]=((dstbase[4*x+2]*srca[x])>>8)+src[x]; - } - } -#endif /* arch_x86 */ - src+=srcstride; - srca+=srcstride; - dstbase+=dststride; - } -#if HAVE_MMX - __asm__ volatile(EMMS:::"memory"); -#endif - return; -} diff --git a/libvo/vo_corevideo.m b/libvo/vo_corevideo.m index 6775762787..c3d832d589 100644 --- a/libvo/vo_corevideo.m +++ b/libvo/vo_corevideo.m @@ -32,7 +32,6 @@ #import "csputils.h" #import "libmpcodecs/vfcap.h" #import "libmpcodecs/mp_image.h" -#import "osd.h" #import "gl_common.h" #import "gl_osd.h" diff --git a/libvo/vo_lavc.c b/libvo/vo_lavc.c index 4cf4003031..5ba548926e 100644 --- a/libvo/vo_lavc.c +++ b/libvo/vo_lavc.c @@ -35,7 +35,6 @@ #include "sub/sub.h" #include "sub/draw_bmp.h" -#include "libvo/osd.h" struct priv { uint8_t *buffer; diff --git a/libvo/vo_opengl.c b/libvo/vo_opengl.c index cbf1b46f8b..413ca78710 100644 --- a/libvo/vo_opengl.c +++ b/libvo/vo_opengl.c @@ -45,7 +45,6 @@ #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" #include "geometry.h" -#include "osd.h" #include "sub/sub.h" #include "bitmap_packer.h" diff --git a/libvo/vo_opengl_old.c b/libvo/vo_opengl_old.c index 6dfe90c17d..98a111b454 100644 --- a/libvo/vo_opengl_old.c +++ b/libvo/vo_opengl_old.c @@ -35,7 +35,6 @@ #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" #include "geometry.h" -#include "osd.h" #include "sub/sub.h" #include "gl_common.h" diff --git a/libvo/vo_x11.c b/libvo/vo_x11.c index c23dd47fd2..8725279bb8 100644 --- a/libvo/vo_x11.c +++ b/libvo/vo_x11.c @@ -25,7 +25,6 @@ #include "video_out.h" #include "aspect.h" #include "csputils.h" -#include "osd.h" #include "libmpcodecs/mp_image.h" #include "libmpcodecs/vfcap.h" diff --git a/libvo/vo_xv.c b/libvo/vo_xv.c index e12f8cbaf8..b62eaf18d7 100644 --- a/libvo/vo_xv.c +++ b/libvo/vo_xv.c @@ -47,7 +47,6 @@ #include "video_out.h" #include "libmpcodecs/vfcap.h" #include "libmpcodecs/mp_image.h" -#include "osd.h" #include "x11_common.h" #include "fastmemcpy.h" #include "sub/sub.h" diff --git a/sub/img_convert.c b/sub/img_convert.c index 9437226c64..aa5c89401a 100644 --- a/sub/img_convert.c +++ b/sub/img_convert.c @@ -33,140 +33,11 @@ struct osd_conv_cache { struct sub_bitmap part; struct sub_bitmap *parts; - // for osd_conv_cache_alloc_old_p() (SUBBITMAP_PLANAR) - int allocated, stride; - struct old_osd_planar bmp; - // for osd_conv_idx_to_old_p(), a spudec.c handle - void *spudec; }; -static int osd_conv_cache_destroy(void *p) -{ - struct osd_conv_cache *c = p; - av_free(c->bmp.bitmap); - av_free(c->bmp.alpha); - if (c->spudec) - spudec_free(c->spudec); - return 0; -} - struct osd_conv_cache *osd_conv_cache_new(void) { - struct osd_conv_cache *c = talloc_zero(NULL, struct osd_conv_cache); - talloc_set_destructor(c, &osd_conv_cache_destroy); - return c; -} - -// allocates/enlarges the alpha/bitmap buffer -static void osd_conv_cache_alloc_old_p(struct osd_conv_cache *c, int w, int h) -{ - assert(w > 0 && h > 0); - c->stride = (w + 7) & (~7); - int len = c->stride * h; - if (c->allocated < len) { - av_free(c->bmp.bitmap); - av_free(c->bmp.alpha); - c->allocated = len; - c->bmp.bitmap = av_malloc(len); - c->bmp.alpha = av_malloc(len); - } - memset(c->bmp.bitmap, sub_bg_color, len); - memset(c->bmp.alpha, sub_bg_alpha, len); - c->part = (struct sub_bitmap) { - .bitmap = &c->bmp, - .stride = c->stride, - .w = w, .h = h, - .dw = w, .dh = h, - }; -} - -static void draw_alpha_ass_to_old(unsigned char *src, int src_w, int src_h, - int src_stride, unsigned char *dst_a, - unsigned char *dst_i, size_t dst_stride, - int dst_x, int dst_y, uint32_t color) -{ - const unsigned int r = (color >> 24) & 0xff; - const unsigned int g = (color >> 16) & 0xff; - const unsigned int b = (color >> 8) & 0xff; - const unsigned int a = 0xff - (color & 0xff); - - int gray = (r + g + b) / 3; // not correct - - dst_a += dst_y * dst_stride + dst_x; - dst_i += dst_y * dst_stride + dst_x; - - int src_skip = src_stride - src_w; - int dst_skip = dst_stride - src_w; - - for (int y = 0; y < src_h; y++) { - for (int x = 0; x < src_w; x++) { - unsigned char as = (*src * a) >> 8; - unsigned char bs = (gray * as) >> 8; - // to mplayer scale - as = -as; - - unsigned char *a = dst_a; - unsigned char *b = dst_i; - - // NOTE: many special cases, because alpha=0 means transparency, - // while alpha=1..255 is opaque..transparent - if (as) { - *b = ((*b * as) >> 8) + bs; - if (*a) { - *a = (*a * as) >> 8; - if (*a < 1) - *a = 1; - } else { - *a = as; - } - } - - dst_a++; - dst_i++; - src++; - } - dst_a += dst_skip; - dst_i += dst_skip; - src += src_skip; - } -} - -static void render_ass_to_old(unsigned char *a, unsigned char *i, - size_t stride, int x, int y, - struct sub_bitmaps *imgs) -{ - for (int n = 0; n < imgs->num_parts; n++) { - struct sub_bitmap *p = &imgs->parts[n]; - draw_alpha_ass_to_old(p->bitmap, p->w, p->h, p->stride, a, i, stride, - x + p->x, y + p->y, p->libass.color); - } -} - -// SUBBITMAP_LIBASS -> SUBBITMAP_OLD_PLANAR -bool osd_conv_ass_to_old_p(struct osd_conv_cache *c, struct sub_bitmaps *imgs) -{ - struct sub_bitmaps src = *imgs; - if (src.format != SUBBITMAP_LIBASS || src.scaled) - return false; - - imgs->format = SUBBITMAP_OLD_PLANAR; - imgs->num_parts = 0; - imgs->parts = NULL; - - int x1, y1, x2, y2; - if (!sub_bitmaps_bb(&src, &x1, &y1, &x2, &y2)) - return true; - - osd_conv_cache_alloc_old_p(c, x2 - x1, y2 - y1); - - render_ass_to_old(c->bmp.alpha, c->bmp.bitmap, c->stride, -x1, -y1, &src); - - c->part.x = x1; - c->part.y = y1; - - imgs->parts = &c->part; - imgs->num_parts = 1; - return true; + return talloc_zero(NULL, struct osd_conv_cache); } static void rgba_to_premultiplied_rgba(uint32_t *colors, size_t count) @@ -216,70 +87,3 @@ bool osd_conv_idx_to_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs) } return true; } - -bool osd_conv_idx_to_old_p(struct osd_conv_cache *c, struct sub_bitmaps *imgs, - int screen_w, int screen_h) -{ - struct sub_bitmaps src = *imgs; - if (src.format != SUBBITMAP_INDEXED) - return false; - - imgs->format = SUBBITMAP_OLD_PLANAR; - imgs->num_parts = 0; - imgs->parts = NULL; - if (src.num_parts == 0) - return true; - - // assume they are all evenly scaled (and size 0 is not possible) - // could put more effort into it to reduce rounding errors, but it doesn't - // make much sense anyway - struct sub_bitmap *s0 = &src.parts[0]; - double scale_x = (double)s0->w / s0->dw; - double scale_y = (double)s0->h / s0->dh; - double scale = FFMIN(scale_x, scale_y); - - int xmin, ymin, xmax, ymax; - - xmin = ymin = INT_MAX; - xmax = ymax = INT_MIN; - for (int n = 0; n < src.num_parts; n++) { - struct sub_bitmap *s = &src.parts[n]; - int sx = s->x * scale; - int sy = s->y * scale; - xmin = FFMIN(xmin, sx); - ymin = FFMIN(ymin, sy); - xmax = FFMAX(xmax, sx + s->w); - ymax = FFMAX(ymax, sy + s->h); - } - - int w = xmax - xmin; - int h = ymax - ymin; - - struct spu_packet_t *packet = spudec_packet_create(xmin, ymin, w, h); - if (!packet) - return false; - spudec_packet_clear(packet); - for (int n = 0; n < src.num_parts; n++) { - struct sub_bitmap *s = &src.parts[n]; - struct osd_bmp_indexed *sb = s->bitmap; - int sx = s->x * scale; - int sy = s->y * scale; - assert(sx >= xmin); - assert(sy >= ymin); - assert(sx - xmin + s->w <= w); - assert(sy - ymin + s->h <= h); - // assumes sub-images are not overlapping - spudec_packet_fill(packet, sb->bitmap, s->stride, sb->palette, - sx - xmin, sy - ymin, s->w, s->h); - } - if (!c->spudec) - c->spudec = spudec_new_scaled(NULL, 0, 0, NULL, 0); - spudec_packet_send(c->spudec, packet, MP_NOPTS_VALUE, MP_NOPTS_VALUE); - spudec_set_res(c->spudec, screen_w * scale, screen_h * scale); - spudec_heartbeat(c->spudec, 0); - spudec_get_bitmap(c->spudec, screen_w, screen_h, imgs); - imgs->render_index = src.render_index; - imgs->bitmap_id = src.bitmap_id; - imgs->bitmap_pos_id = src.bitmap_pos_id; - return true; -} diff --git a/sub/img_convert.h b/sub/img_convert.h index ac766fb0ed..c947c44f01 100644 --- a/sub/img_convert.h +++ b/sub/img_convert.h @@ -10,9 +10,6 @@ struct osd_conv_cache *osd_conv_cache_new(void); // These functions convert from one OSD format to another. On success, they copy // the converted image data into c, and change imgs to point to the data. -bool osd_conv_ass_to_old_p(struct osd_conv_cache *c, struct sub_bitmaps *imgs); bool osd_conv_idx_to_rgba(struct osd_conv_cache *c, struct sub_bitmaps *imgs); -bool osd_conv_idx_to_old_p(struct osd_conv_cache *c, struct sub_bitmaps *imgs, - int screen_w, int screen_h); #endif diff --git a/sub/spudec.c b/sub/spudec.c index 4eea10ed8f..734b8f1846 100644 --- a/sub/spudec.c +++ b/sub/spudec.c @@ -38,7 +38,6 @@ #include #include -#include #include "config.h" #include "mp_msg.h" @@ -48,18 +47,6 @@ #include "sub.h" #include "mpcommon.h" -/* Valid values for spu_aamode: - 0: none (fastest, most ugly) - 1: approximate - 2: full (slowest) - 3: bilinear (similiar to vobsub, fast and not too bad) - 4: uses swscaler gaussian (this is the only one that looks good) - */ - -int spu_aamode = 3; -int spu_alignment = -1; -float spu_gaussvar = 1.0; - typedef struct spu_packet_t packet_t; struct spu_packet_t { int is_decoded; @@ -79,13 +66,6 @@ struct spu_packet_t { packet_t *next; }; -struct palette_crop_cache { - int valid; - uint32_t palette; - int sx, sy, ex, ey; - int result; -}; - typedef struct { packet_t *queue_head; packet_t *queue_tail; @@ -107,25 +87,15 @@ typedef struct { unsigned int width, height, stride; size_t image_size; /* Size of the image buffer */ unsigned char *image; /* Grayscale value */ - unsigned char *aimage; /* Alpha value */ unsigned int pal_start_col, pal_start_row; unsigned int pal_width, pal_height; unsigned char *pal_image; /* palette entry value */ - unsigned int scaled_frame_width, scaled_frame_height; - unsigned int scaled_start_col, scaled_start_row; - unsigned int scaled_width, scaled_height, scaled_stride; - size_t scaled_image_size; - unsigned char *scaled_image; - unsigned char *scaled_aimage; int auto_palette; /* 1 if we lack a palette and must use an heuristic. */ int font_start_level; /* Darkest value used for the computed font */ int spu_changed; unsigned int forced_subs_only; /* flag: 0=display all subtitle, !0 display only forced subtitles */ unsigned int is_forced_sub; /* true if current subtitle is a forced subtitle */ - struct palette_crop_cache palette_crop_cache; - - struct old_osd_planar borrowed_sub_image; struct sub_bitmap sub_part, borrowed_sub_part; struct osd_bmp_indexed borrowed_bmp; } spudec_handle_t; @@ -190,40 +160,6 @@ static inline unsigned char get_nibble(packet_t *packet) return nib; } -/* Cut the sub to visible part */ -static inline void spudec_cut_image(spudec_handle_t *this) -{ - unsigned int fy, ly; - unsigned int first_y, last_y; - - if (this->stride == 0 || this->height == 0) { - return; - } - - for (fy = 0; fy < this->image_size && !this->aimage[fy]; fy++); - for (ly = this->stride * this->height-1; ly && !this->aimage[ly]; ly--); - first_y = fy / this->stride; - last_y = ly / this->stride; - //printf("first_y: %d, last_y: %d\n", first_y, last_y); - this->start_row += first_y; - - // Some subtitles trigger this condition - if (last_y + 1 > first_y ) { - this->height = last_y - first_y +1; - } else { - this->height = 0; - return; - } - -// printf("new h %d new start %d (sz %d st %d)---\n\n", this->height, this->start_row, this->image_size, this->stride); - - if (first_y > 0) { - memmove(this->image, this->image + this->stride * first_y, this->stride * this->height); - memmove(this->aimage, this->aimage + this->stride * first_y, this->stride * this->height); - } -} - - static int spudec_alloc_image(spudec_handle_t *this, int stride, int height) { if (this->width > stride) // just a safeguard @@ -240,7 +176,6 @@ static int spudec_alloc_image(spudec_handle_t *this, int stride, int height) this->image = malloc(2 * this->stride * this->height); if (this->image) { this->image_size = this->stride * this->height; - this->aimage = this->image + this->image_size; // use stride here as well to simplify reallocation checks this->pal_image = malloc(this->stride * this->height); } @@ -248,102 +183,6 @@ static int spudec_alloc_image(spudec_handle_t *this, int stride, int height) return this->image != NULL; } -/** - * \param pal palette in MPlayer-style gray-alpha values, i.e. - * alpha == 0 means transparent, 1 fully opaque, - * gray value <= 256 - alpha. - */ -static void pal2gray_alpha(const uint16_t *pal, - const uint8_t *src, int src_stride, - uint8_t *dst, uint8_t *dsta, - int dst_stride, int w, int h) -{ - int x, y; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - uint16_t pixel = pal[src[x]]; - *dst++ = pixel; - *dsta++ = pixel >> 8; - } - for (; x < dst_stride; x++) - *dsta++ = *dst++ = 0; - src += src_stride; - } -} - -static int apply_palette_crop(spudec_handle_t *this, - unsigned crop_x, unsigned crop_y, - unsigned crop_w, unsigned crop_h) -{ - int i; - uint8_t *src; - uint16_t pal[4]; - unsigned stride = (crop_w + 7) & ~7; - if (crop_x > this->pal_width || crop_y > this->pal_height || - crop_w > this->pal_width - crop_x || crop_h > this->pal_width - crop_y || - crop_w > 0x8000 || crop_h > 0x8000 || - stride * crop_h > this->image_size) { - return 0; - } - for (i = 0; i < 4; ++i) { - int color; - int alpha = this->alpha[i]; - // extend 4 -> 8 bit - alpha |= alpha << 4; - if (this->custom && (this->cuspal[i] >> 31) != 0) - alpha = 0; - color = this->custom ? this->cuspal[i] : - this->global_palette[this->palette[i]]; - color = (color >> 16) & 0xff; - // convert to MPlayer-style gray/alpha palette - color = FFMIN(color, alpha); - pal[i] = (-alpha << 8) | color; - } - src = this->pal_image + crop_y * this->pal_width + crop_x; - pal2gray_alpha(pal, src, this->pal_width, - this->image, this->aimage, stride, - crop_w, crop_h); - this->width = crop_w; - this->height = crop_h; - this->stride = stride; - this->start_col = this->pal_start_col + crop_x; - this->start_row = this->pal_start_row + crop_y; - spudec_cut_image(this); - - // reset scaled image - this->scaled_frame_width = 0; - this->scaled_frame_height = 0; - this->palette_crop_cache.valid = 0; - return 1; -} - -int spudec_apply_palette_crop(void *this, uint32_t palette, - int sx, int sy, int ex, int ey) -{ - spudec_handle_t *spu = this; - struct palette_crop_cache *c = &spu->palette_crop_cache; - if (c->valid && c->palette == palette && - c->sx == sx && c->sy == sy && c->ex == ex && c->ey == ey) - return c->result; - spu->palette[0] = (palette >> 28) & 0xf; - spu->palette[1] = (palette >> 24) & 0xf; - spu->palette[2] = (palette >> 20) & 0xf; - spu->palette[3] = (palette >> 16) & 0xf; - spu->alpha[0] = (palette >> 12) & 0xf; - spu->alpha[1] = (palette >> 8) & 0xf; - spu->alpha[2] = (palette >> 4) & 0xf; - spu->alpha[3] = palette & 0xf; - spu->spu_changed = 1; - c->result = apply_palette_crop(spu, - sx - spu->pal_start_col, sy - spu->pal_start_row, - ex - sx, ey - sy); - c->palette = palette; - c->sx = sx; c->sy = sy; - c->ex = ex; c->ey = ey; - c->valid = 1; - return c->result; -} - static void setup_palette(spudec_handle_t *spu, uint32_t palette[256]) { memset(palette, 0, sizeof(palette)); @@ -454,7 +293,6 @@ static void spudec_process_data(spudec_handle_t *this, packet_t *packet) memset(dst, color, len); dst += len; } - apply_palette_crop(this, 0, 0, this->pal_width, this->pal_height); struct sub_bitmap *sub_part = &this->sub_part; struct osd_bmp_indexed *bmp = &this->borrowed_bmp; @@ -765,17 +603,12 @@ void spudec_heartbeat(void *this, unsigned int pts100) free(spu->image); spu->image_size = packet->data_len; spu->image = packet->packet; - spu->aimage = packet->packet + packet->stride * packet->height; packet->packet = NULL; spu->width = packet->width; spu->height = packet->height; spu->stride = packet->stride; spu->start_col = packet->start_col; spu->start_row = packet->start_row; - - // reset scaled image - spu->scaled_frame_width = 0; - spu->scaled_frame_height = 0; } else { if (spu->auto_palette) compute_palette(spu, packet); @@ -803,40 +636,6 @@ void spudec_set_forced_subs_only(void * const this, const unsigned int flag) } } -static void get_data(void *ctx, int x0,int y0, int w,int h, unsigned char* src, - unsigned char *srca, int stride) -{ - struct sub_bitmaps *bmp = ctx; - assert(bmp->num_parts == 0); - bmp->num_parts = 1; - struct sub_bitmap *s = &bmp->parts[0]; - struct old_osd_planar *p = s->bitmap; - // We know that the data stays valid until the next SPU related call - p->bitmap = src; - p->alpha = srca; - *s = (struct sub_bitmap) { - .bitmap = p, .stride = stride, - .x = x0, .y = y0, - .w = w, .h = h, - .dw = w, .dh = h, - }; -} - -void spudec_get_bitmap(void *this, int w, int h, struct sub_bitmaps *res) -{ - spudec_handle_t *spu = this; - *res = (struct sub_bitmaps) { - .format = SUBBITMAP_OLD_PLANAR, - .parts = &spu->borrowed_sub_part, - }; - res->parts[0].bitmap = &spu->borrowed_sub_image; - if (w == -1 && h == -1) { - spudec_draw(this, get_data, res); - } else { - spudec_draw_scaled(this, w, h, get_data, res); - } -} - void spudec_get_indexed(void *this, struct mp_eosd_res *dim, struct sub_bitmaps *res) { @@ -863,482 +662,6 @@ void spudec_get_indexed(void *this, struct mp_eosd_res *dim, } } -void spudec_draw(void *this, void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx) -{ - spudec_handle_t *spu = this; - if (spudec_visible(spu)) - { - draw_alpha(ctx, spu->start_col, spu->start_row, spu->width, spu->height, - spu->image, spu->aimage, spu->stride); - spu->spu_changed = 0; - } -} - -/* calc the bbox for spudec subs */ -void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox) -{ - spudec_handle_t *spu = me; - if (spu->orig_frame_width == 0 || spu->orig_frame_height == 0 - || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys)) { - // unscaled - bbox[0] = spu->start_col; - bbox[1] = spu->start_col + spu->width; - bbox[2] = spu->start_row; - bbox[3] = spu->start_row + spu->height; - } - else { - // scaled - unsigned int scalex = 0x100 * dxs / spu->orig_frame_width; - unsigned int scaley = 0x100 * dys / spu->orig_frame_height; - bbox[0] = spu->start_col * scalex / 0x100; - bbox[1] = spu->start_col * scalex / 0x100 + spu->width * scalex / 0x100; - switch (spu_alignment) { - case 0: - bbox[3] = dys*sub_pos/100 + spu->height * scaley / 0x100; - if (bbox[3] > dys) bbox[3] = dys; - bbox[2] = bbox[3] - spu->height * scaley / 0x100; - break; - case 1: - if (sub_pos < 50) { - bbox[2] = dys*sub_pos/100 - spu->height * scaley / 0x200; - bbox[3] = bbox[2] + spu->height; - } else { - bbox[3] = dys*sub_pos/100 + spu->height * scaley / 0x200; - if (bbox[3] > dys) bbox[3] = dys; - bbox[2] = bbox[3] - spu->height * scaley / 0x100; - } - break; - case 2: - bbox[2] = dys*sub_pos/100 - spu->height * scaley / 0x100; - bbox[3] = bbox[2] + spu->height; - break; - default: /* -1 */ - bbox[2] = spu->start_row * scaley / 0x100; - bbox[3] = spu->start_row * scaley / 0x100 + spu->height * scaley / 0x100; - break; - } - } -} -/* transform mplayer's alpha value into an opacity value that is linear */ -static inline int canon_alpha(int alpha) -{ - return (uint8_t)-alpha; -} - -typedef struct { - unsigned position; - unsigned left_up; - unsigned right_down; -}scale_pixel; - - -static void scale_table(unsigned int start_src, unsigned int start_tar, unsigned int end_src, unsigned int end_tar, scale_pixel * table) -{ - unsigned int t; - unsigned int delta_src = end_src - start_src; - unsigned int delta_tar = end_tar - start_tar; - int src = 0; - int src_step; - if (delta_src == 0 || delta_tar == 0) { - return; - } - src_step = (delta_src << 16) / delta_tar >>1; - for (t = 0; t<=delta_tar; src += (src_step << 1), t++){ - table[t].position= FFMIN(src >> 16, end_src - 1); - table[t].right_down = src & 0xffff; - table[t].left_up = 0x10000 - table[t].right_down; - } -} - -/* bilinear scale, similar to vobsub's code */ -static void scale_image(int x, int y, scale_pixel* table_x, scale_pixel* table_y, spudec_handle_t * spu) -{ - int alpha[4]; - int color[4]; - unsigned int scale[4]; - int base = table_y[y].position * spu->stride + table_x[x].position; - int scaled = y * spu->scaled_stride + x; - alpha[0] = canon_alpha(spu->aimage[base]); - alpha[1] = canon_alpha(spu->aimage[base + 1]); - alpha[2] = canon_alpha(spu->aimage[base + spu->stride]); - alpha[3] = canon_alpha(spu->aimage[base + spu->stride + 1]); - color[0] = spu->image[base]; - color[1] = spu->image[base + 1]; - color[2] = spu->image[base + spu->stride]; - color[3] = spu->image[base + spu->stride + 1]; - scale[0] = (table_x[x].left_up * table_y[y].left_up >> 16) * alpha[0]; - if (table_y[y].left_up == 0x10000) // necessary to avoid overflow-case - scale[0] = table_x[x].left_up * alpha[0]; - scale[1] = (table_x[x].right_down * table_y[y].left_up >>16) * alpha[1]; - scale[2] = (table_x[x].left_up * table_y[y].right_down >> 16) * alpha[2]; - scale[3] = (table_x[x].right_down * table_y[y].right_down >> 16) * alpha[3]; - spu->scaled_image[scaled] = (color[0] * scale[0] + color[1] * scale[1] + color[2] * scale[2] + color[3] * scale[3])>>24; - spu->scaled_aimage[scaled] = (scale[0] + scale[1] + scale[2] + scale[3]) >> 16; - if (spu->scaled_aimage[scaled]){ - // ensure that MPlayer's simplified alpha-blending can not overflow - spu->scaled_image[scaled] = FFMIN(spu->scaled_image[scaled], spu->scaled_aimage[scaled]); - // convert to MPlayer-style alpha - spu->scaled_aimage[scaled] = -spu->scaled_aimage[scaled]; - } -} - -static void sws_spu_image(unsigned char *d1, unsigned char *d2, int dw, int dh, - int ds, const unsigned char* s1, unsigned char* s2, - int sw, int sh, int ss) -{ - struct SwsContext *ctx; - static SwsFilter filter; - static int firsttime = 1; - static float oldvar; - int i; - - if (!firsttime && oldvar != spu_gaussvar) sws_freeVec(filter.lumH); - if (firsttime) { - filter.lumH = filter.lumV = - filter.chrH = filter.chrV = sws_getGaussianVec(spu_gaussvar, 3.0); - sws_normalizeVec(filter.lumH, 1.0); - firsttime = 0; - oldvar = spu_gaussvar; - } - - ctx=sws_getContext(sw, sh, PIX_FMT_GRAY8, dw, dh, PIX_FMT_GRAY8, SWS_GAUSS, &filter, NULL, NULL); - sws_scale(ctx,&s1,&ss,0,sh,&d1,&ds); - for (i=ss*sh-1; i>=0; i--) s2[i] = -s2[i]; - sws_scale(ctx,(const uint8_t **)&s2,&ss,0,sh,&d2,&ds); - for (i=ds*dh-1; i>=0; i--) d2[i] = -d2[i]; - sws_freeContext(ctx); -} - -void spudec_draw_scaled(void *me, unsigned int dxs, unsigned int dys, void (*draw_alpha)(void *ctx, int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride), void *ctx) -{ - spudec_handle_t *spu = me; - scale_pixel *table_x; - scale_pixel *table_y; - - if (spudec_visible(spu)) { - - // check if only forced subtitles are requested - if( (spu->forced_subs_only) && !(spu->is_forced_sub) ){ - return; - } - - if (!(spu_aamode&16) && (spu->orig_frame_width == 0 || spu->orig_frame_height == 0 - || (spu->orig_frame_width == dxs && spu->orig_frame_height == dys))) { - spudec_draw(spu, draw_alpha, ctx); - } - else { - if (spu->scaled_frame_width != dxs || spu->scaled_frame_height != dys) { /* Resizing is needed */ - /* scaled_x = scalex * x / 0x100 - scaled_y = scaley * y / 0x100 - order of operations is important because of rounding. */ - unsigned int scalex = 0x100 * dxs / spu->orig_frame_width; - unsigned int scaley = 0x100 * dys / spu->orig_frame_height; - spu->scaled_start_col = spu->start_col * scalex / 0x100; - spu->scaled_start_row = spu->start_row * scaley / 0x100; - spu->scaled_width = spu->width * scalex / 0x100; - spu->scaled_height = spu->height * scaley / 0x100; - /* Kludge: draw_alpha needs width multiple of 8 */ - spu->scaled_stride = (spu->scaled_width + 7) & ~7; - if (spu->scaled_image_size < spu->scaled_stride * spu->scaled_height) { - if (spu->scaled_image) { - free(spu->scaled_image); - spu->scaled_image_size = 0; - } - spu->scaled_image = malloc(2 * spu->scaled_stride * spu->scaled_height); - if (spu->scaled_image) { - spu->scaled_image_size = spu->scaled_stride * spu->scaled_height; - spu->scaled_aimage = spu->scaled_image + spu->scaled_image_size; - } - } - if (spu->scaled_image) { - unsigned int x, y; - // needs to be 0-initialized because draw_alpha draws always a - // multiple of 8 pixels. TODO: optimize - if (spu->scaled_width & 7) - memset(spu->scaled_image, 0, 2 * spu->scaled_image_size); - if (spu->scaled_width <= 1 || spu->scaled_height <= 1) { - goto nothing_to_do; - } - switch(spu_aamode&15) { - case 4: - sws_spu_image(spu->scaled_image, spu->scaled_aimage, - spu->scaled_width, spu->scaled_height, spu->scaled_stride, - spu->image, spu->aimage, spu->width, spu->height, spu->stride); - break; - case 3: - table_x = calloc(spu->scaled_width, sizeof(scale_pixel)); - table_y = calloc(spu->scaled_height, sizeof(scale_pixel)); - if (!table_x || !table_y) { - mp_msg(MSGT_SPUDEC, MSGL_FATAL, "Fatal: spudec_draw_scaled: calloc failed\n"); - } - scale_table(0, 0, spu->width - 1, spu->scaled_width - 1, table_x); - scale_table(0, 0, spu->height - 1, spu->scaled_height - 1, table_y); - for (y = 0; y < spu->scaled_height; y++) - for (x = 0; x < spu->scaled_width; x++) - scale_image(x, y, table_x, table_y, spu); - free(table_x); - free(table_y); - break; - case 0: - /* no antialiasing */ - for (y = 0; y < spu->scaled_height; ++y) { - int unscaled_y = y * 0x100 / scaley; - int strides = spu->stride * unscaled_y; - int scaled_strides = spu->scaled_stride * y; - for (x = 0; x < spu->scaled_width; ++x) { - int unscaled_x = x * 0x100 / scalex; - spu->scaled_image[scaled_strides + x] = spu->image[strides + unscaled_x]; - spu->scaled_aimage[scaled_strides + x] = spu->aimage[strides + unscaled_x]; - } - } - break; - case 1: - { - /* Intermediate antialiasing. */ - for (y = 0; y < spu->scaled_height; ++y) { - const unsigned int unscaled_top = y * spu->orig_frame_height / dys; - unsigned int unscaled_bottom = (y + 1) * spu->orig_frame_height / dys; - if (unscaled_bottom >= spu->height) - unscaled_bottom = spu->height - 1; - for (x = 0; x < spu->scaled_width; ++x) { - const unsigned int unscaled_left = x * spu->orig_frame_width / dxs; - unsigned int unscaled_right = (x + 1) * spu->orig_frame_width / dxs; - unsigned int color = 0; - unsigned int alpha = 0; - unsigned int walkx, walky; - unsigned int base, tmp; - if (unscaled_right >= spu->width) - unscaled_right = spu->width - 1; - for (walky = unscaled_top; walky <= unscaled_bottom; ++walky) - for (walkx = unscaled_left; walkx <= unscaled_right; ++walkx) { - base = walky * spu->stride + walkx; - tmp = canon_alpha(spu->aimage[base]); - alpha += tmp; - color += tmp * spu->image[base]; - } - base = y * spu->scaled_stride + x; - spu->scaled_image[base] = alpha ? color / alpha : 0; - spu->scaled_aimage[base] = - alpha * (1 + unscaled_bottom - unscaled_top) * (1 + unscaled_right - unscaled_left); - /* spu->scaled_aimage[base] = - alpha * dxs * dys / spu->orig_frame_width / spu->orig_frame_height; */ - if (spu->scaled_aimage[base]) { - spu->scaled_aimage[base] = 256 - spu->scaled_aimage[base]; - if (spu->scaled_aimage[base] + spu->scaled_image[base] > 255) - spu->scaled_image[base] = 256 - spu->scaled_aimage[base]; - } - } - } - } - 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 (y = 0; y < spu->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 = FFMIN(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 (x = 0; x < spu->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 = FFMIN(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 = spu->stride * (unsigned int) unscaled_y; - tmp = left * top * canon_alpha(spu->aimage[base + (unsigned int) unscaled_x]); - alpha += tmp; - color += tmp * spu->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 = spu->stride * (unsigned int) unscaled_y + walkx; - tmp = /* 1.0 * */ top * canon_alpha(spu->aimage[base]); - alpha += tmp; - color += tmp * spu->image[base]; - } - } - /* 3: top right part */ - if (right > 0.0) { - base = spu->stride * (unsigned int) unscaled_y + (unsigned int) unscaled_x_right; - tmp = right * top * canon_alpha(spu->aimage[base]); - alpha += tmp; - color += tmp * spu->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 = spu->stride * walky + (unsigned int) unscaled_x; - tmp = left /* * 1.0 */ * canon_alpha(spu->aimage[base]); - alpha += tmp; - color += tmp * spu->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 = spu->stride * walky; - for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) { - tmp = /* 1.0 * 1.0 * */ canon_alpha(spu->aimage[base + walkx]); - alpha += tmp; - color += tmp * spu->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 = spu->stride * walky + (unsigned int) unscaled_x_right; - tmp = right /* * 1.0 */ * canon_alpha(spu->aimage[base]); - alpha += tmp; - color += tmp * spu->image[base]; - } - } - /* 7: bottom left part */ - if (bottom > 0.0) { - base = spu->stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x; - tmp = left * bottom * canon_alpha(spu->aimage[base]); - alpha += tmp; - color += tmp * spu->image[base]; - } - /* 8: bottom center part */ - if (width > 0 && bottom > 0.0) { - unsigned int walkx; - base = spu->stride * (unsigned int) unscaled_y_bottom; - for (walkx = left_right_column; walkx < (unsigned int) unscaled_x_right; ++walkx) { - tmp = /* 1.0 * */ bottom * canon_alpha(spu->aimage[base + walkx]); - alpha += tmp; - color += tmp * spu->image[base + walkx]; - } - } - /* 9: bottom right part */ - if (right > 0.0 && bottom > 0.0) { - base = spu->stride * (unsigned int) unscaled_y_bottom + (unsigned int) unscaled_x_right; - tmp = right * bottom * canon_alpha(spu->aimage[base]); - alpha += tmp; - color += tmp * spu->image[base]; - } - /* Finally mix these transparency and brightness information suitably */ - base = spu->scaled_stride * y + x; - spu->scaled_image[base] = alpha > 0 ? color / alpha : 0; - spu->scaled_aimage[base] = alpha * scalex * scaley / 0x10000; - if (spu->scaled_aimage[base]) { - spu->scaled_aimage[base] = 256 - spu->scaled_aimage[base]; - if (spu->scaled_aimage[base] + spu->scaled_image[base] > 255) - spu->scaled_image[base] = 256 - spu->scaled_aimage[base]; - } - } - } - } - } -nothing_to_do: - /* Kludge: draw_alpha needs width multiple of 8. */ - if (spu->scaled_width < spu->scaled_stride) - for (y = 0; y < spu->scaled_height; ++y) { - memset(spu->scaled_aimage + y * spu->scaled_stride + spu->scaled_width, 0, - spu->scaled_stride - spu->scaled_width); - } - spu->scaled_frame_width = dxs; - spu->scaled_frame_height = dys; - } - } - if (spu->scaled_image){ - switch (spu_alignment) { - case 0: - spu->scaled_start_row = dys*sub_pos/100; - if (spu->scaled_start_row + spu->scaled_height > dys) - spu->scaled_start_row = dys - spu->scaled_height; - break; - case 1: - spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height/2; - if (sub_pos >= 50 && spu->scaled_start_row + spu->scaled_height > dys) - spu->scaled_start_row = dys - spu->scaled_height; - break; - case 2: - spu->scaled_start_row = dys*sub_pos/100 - spu->scaled_height; - break; - } - draw_alpha(ctx, spu->scaled_start_col, spu->scaled_start_row, spu->scaled_width, spu->scaled_height, - spu->scaled_image, spu->scaled_aimage, spu->scaled_stride); - spu->spu_changed = 0; - } - } - } - else - { - mp_msg(MSGT_SPUDEC,MSGL_DBG2,"SPU not displayed: start_pts=%d end_pts=%d now_pts=%d\n", - spu->start_pts, spu->end_pts, spu->now_pts); - } -} - void spudec_set_font_factor(void * this, double factor) { spudec_handle_t *spu = this; @@ -1428,14 +751,6 @@ void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigne return this; } -void spudec_set_res(void *this, unsigned int frame_width, unsigned int frame_height) -{ - spudec_handle_t *spu = this; - // intentionally do not apply resolution heuristics - spu->orig_frame_width = frame_width; - spu->orig_frame_height = frame_height; -} - void *spudec_new(unsigned int *palette) { return spudec_new_scaled(palette, 0, 0, NULL, 0); @@ -1449,11 +764,8 @@ void spudec_free(void *this) spudec_free_packet(spudec_dequeue_packet(spu)); free(spu->packet); spu->packet = NULL; - free(spu->scaled_image); - spu->scaled_image = NULL; free(spu->image); spu->image = NULL; - spu->aimage = NULL; free(spu->pal_image); spu->pal_image = NULL; spu->image_size = 0; @@ -1461,87 +773,3 @@ void spudec_free(void *this) free(spu); } } - -#define MP_NOPTS_VALUE (-1LL<<63) //both int64_t and double should be able to represent this exactly - -packet_t *spudec_packet_create(int x, int y, int w, int h) -{ - packet_t *packet; - int stride = (w + 7) & ~7; - if ((unsigned)w >= 0x8000 || (unsigned)h > 0x4000) - return NULL; - packet = calloc(1, sizeof(packet_t)); - packet->is_decoded = 1; - packet->width = w; - packet->height = h; - packet->stride = stride; - packet->start_col = x; - packet->start_row = y; - packet->data_len = 2 * stride * h; - if (packet->data_len) { // size 0 is a special "clear" packet - packet->packet = malloc(packet->data_len); - if (!packet->packet) { - free(packet); - packet = NULL; - } - } - return packet; -} - -void spudec_packet_clear(packet_t *packet) -{ - /* clear alpha and value, as value is premultiplied */ - memset(packet->packet, 0, packet->data_len); -} - -void spudec_packet_fill(packet_t *packet, - const uint8_t *pal_img, int pal_stride, - const void *palette, - int x, int y, int w, int h) -{ - const uint32_t *pal = palette; - uint8_t *img = packet->packet + x + y * packet->stride; - uint8_t *aimg = img + packet->stride * packet->height; - int i; - uint16_t g8a8_pal[256]; - - for (i = 0; i < 256; i++) { - uint32_t pixel = pal[i]; - int alpha = pixel >> 24; - int gray = (((pixel & 0x000000ff) >> 0) + - ((pixel & 0x0000ff00) >> 7) + - ((pixel & 0x00ff0000) >> 16)) >> 2; - gray = FFMIN(gray, alpha); - g8a8_pal[i] = (-alpha << 8) | gray; - } - pal2gray_alpha(g8a8_pal, pal_img, pal_stride, -