Skip to content

Commit f284869

Browse files
committed
subs, libass: support the YCbCr Matrix ASS header
Also switch vf_ass to using mp_get_rgb2yuv_coeffs.
1 parent 9a5ed65 commit f284869

File tree

5 files changed

+76
-10
lines changed

5 files changed

+76
-10
lines changed

libmpcodecs/vf_ass.c

+26-10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "vf.h"
3636
#include "sub/dec_sub.h"
3737

38+
#include "libvo/csputils.h"
3839
#include "libvo/fastmemcpy.h"
3940

4041
#include "m_option.h"
@@ -46,15 +47,16 @@
4647
#define _g(c) (((c)>>16)&0xFF)
4748
#define _b(c) (((c)>>8)&0xFF)
4849
#define _a(c) ((c)&0xFF)
49-
#define rgba2y(c) ( (( 263*_r(c) + 516*_g(c) + 100*_b(c) + 512) >> 10) + 16 )
50-
#define rgba2u(c) ( ((-152*_r(c) - 298*_g(c) + 450*_b(c) + 512) >> 10) + 128 )
51-
#define rgba2v(c) ( (( 450*_r(c) - 377*_g(c) - 73*_b(c) + 512) >> 10) + 128 )
50+
#define from_rgb(c, m) \
51+
( (int) ((m)[COL_R]*_r(c) + (m)[COL_G]*_g(c) + \
52+
(m)[COL_B]*_b(c) + (m)[COL_C]*255 + 0.5f) )
5253

5354

5455
static const struct vf_priv_s {
5556
int outh, outw;
5657

5758
unsigned int outfmt;
59+
struct mp_csp_details video_colorspace;
5860

5961
// 1 = auto-added filter: insert only if chain does not support EOSD already
6062
// 0 = insert always
@@ -300,11 +302,11 @@ static void copy_to_image(struct vf_instance *vf)
300302

301303
static void my_draw_bitmap(struct vf_instance *vf, unsigned char *bitmap,
302304
int bitmap_w, int bitmap_h, int stride,
303-
int dst_x, int dst_y, unsigned color)
305+
int dst_x, int dst_y, unsigned color, float rgb2yuv[3][4])
304306
{
305-
unsigned char y = rgba2y(color);
306-
unsigned char u = rgba2u(color);
307-
unsigned char v = rgba2v(color);
307+
unsigned char y = from_rgb(color, rgb2yuv[0]);
308+
unsigned char u = from_rgb(color, rgb2yuv[1]);
309+
unsigned char v = from_rgb(color, rgb2yuv[2]);
308310
unsigned char opacity = 255 - _a(color);
309311
unsigned char *src, *dsty, *dstu, *dstv;
310312
int i, j;
@@ -329,7 +331,7 @@ static void my_draw_bitmap(struct vf_instance *vf, unsigned char *bitmap,
329331
}
330332

331333
static int render_frame(struct vf_instance *vf, mp_image_t *mpi,
332-
const ASS_Image *img)
334+
const ASS_Image *img, float rgb2yuv[3][4])
333335
{
334336
if (img) {
335337
for (int i = 0; i < (vf->priv->outh + 1) / 2; i++)
@@ -340,7 +342,7 @@ static int render_frame(struct vf_instance *vf, mp_image_t *mpi,
340342
copy_from_image(vf);
341343
while (img) {
342344
my_draw_bitmap(vf, img->bitmap, img->w, img->h, img->stride,
343-
img->dst_x, img->dst_y, img->color);
345+
img->dst_x, img->dst_y, img->color, rgb2yuv);
344346
img = img->next;
345347
}
346348
copy_to_image(vf);
@@ -354,6 +356,7 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
354356
struct MPOpts *opts = vf->opts;
355357
struct osd_state *osd = priv->osd;
356358
ASS_Image *images = 0;
359+
float rgb2yuv[3][4];
357360
if (pts != MP_NOPTS_VALUE) {
358361
osd->dim = (struct mp_eosd_res){ .w = vf->priv->outw,
359362
.h = vf->priv->outh,
@@ -366,10 +369,20 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
366369
struct sub_bitmaps b;
367370
sub_get_bitmaps(osd, &b);
368371
images = b.imgs;
372+
if (b.colorspace.format == MP_CSP_AUTO)
373+
b.colorspace = vf->priv->video_colorspace;
374+
struct mp_csp_params csp_params = { .colorspace = b.colorspace,
375+
.brightness = 0,
376+
.contrast = 1,
377+
.hue = 0,
378+
.saturation = 1,
379+
.texture_bits = 8,
380+
.input_bits = 8 };
381+
mp_get_rgb2yuv_coeffs(&csp_params, rgb2yuv);
369382
}
370383

371384
prepare_image(vf, mpi);
372-
render_frame(vf, mpi, images);
385+
render_frame(vf, mpi, images, rgb2yuv);
373386

374387
return vf_next_put_image(vf, vf->dmpi, pts);
375388
}
@@ -391,6 +404,9 @@ static int control(vf_instance_t *vf, int request, void *data)
391404
case VFCTRL_SET_OSD_OBJ:
392405
vf->priv->osd = data;
393406
break;
407+
case VFCTRL_SET_YUV_COLORSPACE:
408+
vf->priv->video_colorspace = *(struct mp_csp_details *)data;
409+
break;
394410
case VFCTRL_INIT_EOSD:
395411
return CONTROL_TRUE;
396412
case VFCTRL_DRAW_EOSD:

sub/ass_mp.c

+42
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
#include "stream/stream.h"
3939
#include "options.h"
4040

41+
#include "libvo/csputils.h"
42+
4143
#ifndef CONFIG_ICONV
4244
static char *sub_cp = 0;
4345
#endif
@@ -287,3 +289,43 @@ ASS_Library *mp_ass_init(struct MPOpts *opts)
287289
free(path);
288290
return priv;
289291
}
292+
293+
struct mp_csp_details mp_ass_get_colorspace(ASS_Track *track)
294+
{
295+
struct mp_csp_details colorspace;
296+
colorspace.levels_out = MP_CSP_LEVELS_PC;
297+
switch (track->YCbCrMatrix) {
298+
case YCBCR_NONE:
299+
colorspace.format = MP_CSP_AUTO;
300+
colorspace.levels_in = MP_CSP_LEVELS_AUTO;
301+
break;
302+
case YCBCR_BT601_TV:
303+
case YCBCR_DEFAULT:
304+
case YCBCR_UNKNOWN:
305+
default:
306+
colorspace.format = MP_CSP_BT_601;
307+
colorspace.levels_in = MP_CSP_LEVELS_TV;
308+
break;
309+
case YCBCR_BT601_PC:
310+
colorspace.format = MP_CSP_BT_601;
311+
colorspace.levels_in = MP_CSP_LEVELS_PC;
312+
break;
313+
case YCBCR_BT709_TV:
314+
colorspace.format = MP_CSP_BT_709;
315+
colorspace.levels_in = MP_CSP_LEVELS_TV;
316+
break;
317+
case YCBCR_BT709_PC:
318+
colorspace.format = MP_CSP_BT_709;
319+
colorspace.levels_in = MP_CSP_LEVELS_PC;
320+
break;
321+
case YCBCR_SMPTE240M_TV:
322+
colorspace.format = MP_CSP_SMPTE_240M;
323+
colorspace.levels_in = MP_CSP_LEVELS_TV;
324+
break;
325+
case YCBCR_SMPTE240M_PC:
326+
colorspace.format = MP_CSP_SMPTE_240M;
327+
colorspace.levels_in = MP_CSP_LEVELS_PC;
328+
break;
329+
}
330+
return colorspace;
331+
}

sub/ass_mp.h

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "config.h"
2828
#include "subreader.h"
2929

30+
#include "libvo/csputils.h"
31+
3032
#ifdef CONFIG_ASS
3133
#include <ass/ass.h>
3234
#include <ass/ass_types.h>
@@ -46,6 +48,8 @@ void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts,
4648
void mp_ass_configure_fonts(ASS_Renderer *priv);
4749
ASS_Library *mp_ass_init(struct MPOpts *opts);
4850

51+
struct mp_csp_details mp_ass_get_colorspace(ASS_Track *track);
52+
4953
#else /* CONFIG_ASS */
5054

5155
/* Needed for EOSD code using this type to compile */

sub/dec_sub.h

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef MPLAYER_DEC_SUB_H
22
#define MPLAYER_DEC_SUB_H
33

4+
#include "libvo/csputils.h"
5+
46
struct sh_sub;
57
struct osd_state;
68
struct ass_track;
@@ -42,6 +44,7 @@ typedef struct sub_bitmaps {
4244
enum sub_bitmap_type type;
4345

4446
struct ass_image *imgs;
47+
struct mp_csp_details colorspace;
4548

4649
struct sub_bitmap {
4750
int w, h;

sub/sd_ass.c

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
141141
mp_ass_configure(renderer, opts, &osd->dim, osd->unscaled);
142142
ass_set_aspect_ratio(renderer, scale, 1);
143143
int changed;
144+
res->colorspace = mp_ass_get_colorspace(ctx->ass_track);
144145
res->imgs = ass_render_frame(renderer, ctx->ass_track,
145146
osd->sub_pts * 1000 + .5, &changed);
146147
if (changed == 2)

0 commit comments

Comments
 (0)