summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-10-19 19:11:08 +0200
committerwm4 <wm4@nowhere>2012-10-24 21:56:33 +0200
commit97c6425140aecc3910a622fb0ad7d79916cfebbe (patch)
treeff88672104e0533839e28bfcb9e8e0f4420f4e89 /libmpcodecs
parent98f74335d509320f19db2da8786273f95cad2a69 (diff)
downloadmpv-97c6425140aecc3910a622fb0ad7d79916cfebbe.tar.bz2
mpv-97c6425140aecc3910a622fb0ad7d79916cfebbe.tar.xz
sub, vf_ass: allow rendering RGBA subs, replace old vf_ass rendering
Do this by replacing all the old vf_ass drawing code by draw_bmp.c. Change sub.c to always use osd_draw() for the other OSD drawing routines, and simplify the code a bit. spudec.c subtitles (i.e. DVD subs) are now considered subtitles, and are rendered by vf_ass, if that filter is inserted.
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/vf_ass.c171
1 files changed, 15 insertions, 156 deletions
diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_ass.c
index 167ebd6e15..9695ecfdfc 100644
--- a/libmpcodecs/vf_ass.c
+++ b/libmpcodecs/vf_ass.c
@@ -38,25 +38,16 @@
#include "sub/dec_sub.h"
#include "libvo/fastmemcpy.h"
+#include "libvo/csputils.h"
#include "m_option.h"
#include "m_struct.h"
-#include "sub/ass_mp.h"
-
-#define _r(c) ((c)>>24)
-#define _g(c) (((c)>>16)&0xFF)
-#define _b(c) (((c)>>8)&0xFF)
-#define _a(c) ((c)&0xFF)
-#define rgba2y(c) ( (( 263*_r(c) + 516*_g(c) + 100*_b(c)) >> 10) + 16 )
-#define rgba2u(c) ( ((-152*_r(c) - 298*_g(c) + 450*_b(c)) >> 10) + 128 )
-#define rgba2v(c) ( (( 450*_r(c) - 376*_g(c) - 73*_b(c)) >> 10) + 128 )
-
-
static const struct vf_priv_s {
int outh, outw;
unsigned int outfmt;
+ struct mp_csp_details csp;
// 1 = auto-added filter: insert only if chain does not support EOSD already
// 0 = insert always
@@ -64,13 +55,9 @@ static const struct vf_priv_s {
struct osd_state *osd;
struct mp_eosd_res dim;
-
- unsigned char *planes[3];
- struct line_limits {
- uint16_t start;
- uint16_t end;
- } *line_limits;
-} vf_priv_dflt;
+} vf_priv_dflt = {
+ .csp = MP_CSP_DETAILS_DEFAULTS,
+};
static int config(struct vf_instance *vf,
int width, int height, int d_width, int d_height,
@@ -88,10 +75,6 @@ static int config(struct vf_instance *vf,
d_height = d_height * vf->priv->outh / height;
}
- vf->priv->planes[1] = malloc(vf->priv->outw * vf->priv->outh);
- vf->priv->planes[2] = malloc(vf->priv->outw * vf->priv->outh);
- vf->priv->line_limits = malloc((vf->priv->outh + 1) / 2 * sizeof(*vf->priv->line_limits));
-
double dar = (double)d_width / d_height;
double sar = (double)width / height;
@@ -236,148 +219,22 @@ static int prepare_image(struct vf_instance *vf, mp_image_t *mpi)
return 0;
}
-static void update_limits(struct vf_instance *vf, int starty, int endy,
- int startx, int endx)
-{
- starty >>= 1;
- endy = (endy + 1) >> 1;
- startx >>= 1;
- endx = (endx + 1) >> 1;
- for (int i = starty; i < endy; i++) {
- struct line_limits *ll = vf->priv->line_limits + i;
- if (startx < ll->start)
- ll->start = startx;
- if (endx > ll->end)
- ll->end = endx;
- }
-}
-
-/**
- * \brief Copy specified rows from render_context.dmpi to render_context.planes, upsampling to 4:4:4
- */
-static void copy_from_image(struct vf_instance *vf)
-{
- int pl;
-
- for (pl = 1; pl < 3; ++pl) {
- int dst_stride = vf->priv->outw;
- int src_stride = vf->dmpi->stride[pl];
-
- unsigned char *src = vf->dmpi->planes[pl];
- unsigned char *dst = vf->priv->planes[pl];
- for (int i = 0; i < (vf->priv->outh + 1) / 2; i++) {
- struct line_limits *ll = vf->priv->line_limits + i;
- unsigned char *dst_next = dst + dst_stride;
- for (int j = ll->start; j < ll->end; j++) {
- unsigned char val = src[j];
- dst[j << 1] = val;
- dst[(j << 1) + 1] = val;
- dst_next[j << 1] = val;
- dst_next[(j << 1) + 1] = val;
- }
- src += src_stride;
- dst = dst_next + dst_stride;
- }
- }
-}
-
-/**
- * \brief Copy all previously copied rows back to render_context.dmpi
- */
-static void copy_to_image(struct vf_instance *vf)
-{
- int pl;
- int i, j;
- for (pl = 1; pl < 3; ++pl) {
- int dst_stride = vf->dmpi->stride[pl];
- int src_stride = vf->priv->outw;
-
- unsigned char *dst = vf->dmpi->planes[pl];
- unsigned char *src = vf->priv->planes[pl];
- unsigned char *src_next = vf->priv->planes[pl] + src_stride;
- for (i = 0; i < vf->priv->outh / 2; ++i) {
- for (j = vf->priv->line_limits[i].start; j < vf->priv->line_limits[i].end; j++) {
- unsigned val = 0;
- val += src[j << 1];
- val += src[(j << 1) + 1];
- val += src_next[j << 1];
- val += src_next[(j << 1) + 1];
- dst[j] = val >> 2;
- }
- dst += dst_stride;
- src = src_next + src_stride;
- src_next = src + src_stride;
- }
- }
-}
-
-static void my_draw_bitmap(struct vf_instance *vf, unsigned char *bitmap,
- int bitmap_w, int bitmap_h, int stride,
- int dst_x, int dst_y, unsigned color)
-{
- unsigned char y = rgba2y(color);
- unsigned char u = rgba2u(color);
- unsigned char v = rgba2v(color);
- unsigned char opacity = 255 - _a(color);
- unsigned char *src, *dsty, *dstu, *dstv;
- int i, j;
- mp_image_t *dmpi = vf->dmpi;
-
- src = bitmap;
- dsty = dmpi->planes[0] + dst_x + dst_y * dmpi->stride[0];
- dstu = vf->priv->planes[1] + dst_x + dst_y * vf->priv->outw;
- dstv = vf->priv->planes[2] + dst_x + dst_y * vf->priv->outw;
- for (i = 0; i < bitmap_h; ++i) {
- for (j = 0; j < bitmap_w; ++j) {
- unsigned k = (src[j] * opacity + 255) >> 8;
- dsty[j] = (k * y + (255 - k) * dsty[j] + 255) >> 8;
- dstu[j] = (k * u + (255 - k) * dstu[j] + 255) >> 8;
- dstv[j] = (k * v + (255 - k) * dstv[j] + 255) >> 8;
- }
- src += stride;
- dsty += dmpi->stride[0];
- dstu += vf->priv->outw;
- dstv += vf->priv->outw;
- }
-}
-
-static int render_frame(struct vf_instance *vf, mp_image_t *mpi,
- const ASS_Image *img)
-{
- if (img) {
- for (int i = 0; i < (vf->priv->outh + 1) / 2; i++)
- vf->priv->line_limits[i] = (struct line_limits){65535, 0};
- for (const ASS_Image *im = img; im; im = im->next)
- update_limits(vf, im->dst_y, im->dst_y + im->h,
- im->dst_x, im->dst_x + im->w);
- copy_from_image(vf);
- while (img) {
- my_draw_bitmap(vf, img->bitmap, img->w, img->h, img->stride,
- img->dst_x, img->dst_y, img->color);
- img = img->next;
- }
- copy_to_image(vf);
- }
- return 0;
-}
-
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
{
struct vf_priv_s *priv = vf->priv;
struct osd_state *osd = priv->osd;
- struct sub_bitmaps imgs = (struct sub_bitmaps) {0};
+
+ prepare_image(vf, mpi);
+
if (pts != MP_NOPTS_VALUE) {
struct sub_render_params subparams = {
.pts = pts,
.dim = priv->dim,
};
- bool formats[SUBBITMAP_COUNT] = {[SUBBITMAP_LIBASS] = true};
- osd_draw_sub(osd, &imgs, &subparams, formats);
+ osd_draw_on_image(osd, &subparams, OSD_DRAW_SUB_FILTER, vf->dmpi,
+ &priv->csp);
}
- prepare_image(vf, mpi);
- render_frame(vf, mpi, imgs.imgs);
-
return vf_next_put_image(vf, vf->dmpi, pts);
}
@@ -400,15 +257,17 @@ static int control(vf_instance_t *vf, int request, void *data)
break;
case VFCTRL_INIT_OSD:
return CONTROL_TRUE;
+ case VFCTRL_SET_YUV_COLORSPACE: {
+ struct mp_csp_details colorspace = *(struct mp_csp_details *)data;
+ vf->priv->csp = colorspace;
+ break;
+ }
}
return vf_next_control(vf, request, data);
}
static void uninit(struct vf_instance *vf)
{
- free(vf->priv->planes[1]);
- free(vf->priv->planes[2]);
- free(vf->priv->line_limits);
free(vf->priv);
}