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, - img, aimg, packet->stride, w, h); -} - -void spudec_packet_send(void *spu, packet_t *packet, double pts, double endpts) -{ - packet->start_pts = 0; - packet->end_pts = 0x7fffffff; - if (pts != MP_NOPTS_VALUE) - packet->start_pts = pts * 90000; - if (endpts != MP_NOPTS_VALUE) - packet->end_pts = endpts * 90000; - spudec_queue_packet(spu, packet); -} - -/** - * palette must contain at least 256 32-bit entries, otherwise crashes - * are possible - */ -void spudec_set_paletted(void *spu, const uint8_t *pal_img, int pal_stride, - const void *palette, - int x, int y, int w, int h, - double pts, double endpts) -{ - packet_t *packet = spudec_packet_create(x, y, w, h); - if (!packet) - return; - if (packet->data_len) // size 0 is a special "clear" packet - spudec_packet_fill(packet, pal_img, pal_stride, palette, 0, 0, w, h); - spudec_packet_send(spu, packet, pts, endpts); -} diff --git a/sub/spudec.h b/sub/spudec.h index 411aafeb19..6611a28327 100644 --- a/sub/spudec.h +++ b/sub/spudec.h @@ -26,32 +26,14 @@ struct mp_eosd_res; void spudec_heartbeat(void *this, unsigned int pts100); void spudec_assemble(void *this, unsigned char *packet, unsigned int len, int pts100); -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); -void spudec_draw_scaled(void *this, 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); -void spudec_get_bitmap(void *this, int w, int h, struct sub_bitmaps *res); void spudec_get_indexed(void *this, struct mp_eosd_res *dim, struct sub_bitmaps *res); -int spudec_apply_palette_crop(void *this, uint32_t palette, int sx, int ex, int sy, int ey); void *spudec_new_scaled(unsigned int *palette, unsigned int frame_width, unsigned int frame_height, uint8_t *extradata, int extradata_len); -void spudec_set_res(void *this, unsigned int frame_width, unsigned int frame_height); void *spudec_new(unsigned int *palette); void spudec_free(void *this); void spudec_reset(void *this); // called after seek int spudec_visible(void *this); // check if spu is visible void spudec_set_font_factor(void * this, double factor); // sets the equivalent to ffactor int spudec_changed(void *this); -void spudec_calc_bbox(void *me, unsigned int dxs, unsigned int dys, unsigned int* bbox); void spudec_set_forced_subs_only(void * const this, const unsigned int flag); -void spudec_set_paletted(void *this, const uint8_t *pal_img, int stride, - const void *palette, - int x, int y, int w, int h, - double pts, double endpts); -struct spu_packet_t *spudec_packet_create(int x, int y, int w, int h); -void spudec_packet_fill(struct spu_packet_t *packet, - const uint8_t *pal_img, int pal_stride, - const void *palette, - int x, int y, int w, int h); -void spudec_packet_send(void *spu, struct spu_packet_t *packet, - double pts, double endpts); -void spudec_packet_clear(struct spu_packet_t *packet); #endif /* MPLAYER_SPUDEC_H */ diff --git a/sub/sub.c b/sub/sub.c index f175563974..862f5d1f6e 100644 --- a/sub/sub.c +++ b/sub/sub.c @@ -219,16 +219,6 @@ static bool render_object(struct osd_state *osd, struct osd_object *obj, cached |= osd_conv_idx_to_rgba(obj->cache[0], out_imgs); } - if (formats[SUBBITMAP_OLD_PLANAR] && out_imgs->format == SUBBITMAP_INDEXED) - { - cached |= osd_conv_idx_to_old_p(obj->cache[1], out_imgs, - osd->res.w, osd->res.h); - } - - if (formats[SUBBITMAP_OLD_PLANAR] && out_imgs->format == SUBBITMAP_LIBASS) { - cached |= osd_conv_ass_to_old_p(obj->cache[2], out_imgs); - } - if (cached) obj->cached = *out_imgs; @@ -325,48 +315,6 @@ bool osd_draw_on_image(struct osd_state *osd, struct mp_image *dest, return changed; } -void osd_draw_text_ext(struct osd_state *osd, int w, int h, - int ml, int mt, int mr, int mb, int unused0, int unused1, - void (*draw_alpha)(void *ctx, int x0, int y0, int w, - int h, unsigned char* src, - unsigned char *srca, - int stride), - void *ctx) -{ - struct mp_eosd_res dim = - {.w = w, .h = h, .ml = ml, .mt = mt, .mr = mr, .mb = mb}; - osd_update_ext(osd, dim); - struct sub_render_params subparams = { - .pts = osd->vo_sub_pts, - .dim = dim, - .normal_scale = 1, - .vsfilter_scale = 1, // unknown - }; - for (int n = 0; n < MAX_OSD_PARTS; n++) { - struct osd_object *obj = osd->objs[n]; - if (obj->is_sub && osd->render_subs_in_filter) - continue; - struct sub_bitmaps imgs; - bool formats[SUBBITMAP_COUNT] = {[SUBBITMAP_OLD_PLANAR] = true}; - if (render_object(osd, obj, &imgs, &subparams, formats)) { - assert(imgs.num_parts == 1); - struct sub_bitmap *part = &imgs.parts[0]; - struct old_osd_planar *bmp = part->bitmap; - draw_alpha(ctx, part->x, part->y, part->w, part->h, - bmp->bitmap, bmp->alpha, part->stride); - } - } -} - -void osd_draw_text(struct osd_state *osd, int w, int h, - void (*draw_alpha)(void *ctx, int x0, int y0, int w, int h, - unsigned char* src, unsigned char *srca, - int stride), - void *ctx) -{ - osd_draw_text_ext(osd, w, h, 0, 0, 0, 0, 0, 0, draw_alpha, ctx); -} - void vo_osd_changed(int new_value) { struct osd_state *osd = global_osd; diff --git a/sub/sub.h b/sub/sub.h index cc59077011..4f3ca905b6 100644 --- a/sub/sub.h +++ b/sub/sub.h @@ -32,7 +32,6 @@ enum sub_bitmap_format { SUBBITMAP_LIBASS, // A8, with a per-surface blend color (libass.color) SUBBITMAP_RGBA, // B8G8R8A8 (MSB=A, LSB=B), scaled, premultiplied alpha SUBBITMAP_INDEXED, // scaled, bitmap points to osd_bmp_indexed - SUBBITMAP_OLD_PLANAR, // like previous, but bitmap points to old_osd_planar SUBBITMAP_COUNT }; @@ -44,12 +43,6 @@ struct osd_bmp_indexed { uint32_t palette[256]; }; -// For SUBBITMAP_OLD_PANAR -struct old_osd_planar { - unsigned char *bitmap; - unsigned char *alpha; -}; - struct sub_bitmap { void *bitmap; int stride; @@ -191,9 +184,6 @@ extern int sub_pos; extern int sub_width_p; extern int sub_bg_color; /* subtitles background color */ extern int sub_bg_alpha; -extern int spu_alignment; -extern int spu_aamode; -extern float spu_gaussvar; extern char *subtitle_font_encoding; extern float text_font_scale_factor; @@ -210,20 +200,6 @@ extern float sub_fps; extern int sub_justify; -void osd_draw_text(struct osd_state *osd, int dxs, 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); -void osd_draw_text_ext(struct osd_state *osd, int dxs, int dys, - int left_border, int top_border, int right_border, - int bottom_border, int orig_w, int orig_h, - void (*draw_alpha)(void *ctx, int x0, int y0, int w, - int h, unsigned char* src, - unsigned char *srca, - int stride), - void *ctx); - void draw_osd_with_eosd(struct vo *vo, struct osd_state *osd); struct osd_state *osd_create(struct MPOpts *opts, struct ass_library *asslib);