summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-04-24 14:41:50 +0200
committerwm4 <wm4@nowhere>2020-04-24 14:41:50 +0200
commit71295fb872ba6593c8591cff7398498e05afb298 (patch)
treed205cb839328edbc2ce87609ca8fa7f244c8d3b9
parent8909bf3317b26f35265efa7dae534f430c636bb3 (diff)
downloadmpv-71295fb872ba6593c8591cff7398498e05afb298.tar.bz2
mpv-71295fb872ba6593c8591cff7398498e05afb298.tar.xz
video: add alpha type metadata
This is mostly for testing. It adds passing through the metadata through the video chain. The metadata can be manipulated with vf_format. Support for zimg alpha conversion (if built with zimg after it gained alpha support) is implemented. Support premultiplied input in vo_gpu. Some things still seem to be buggy.
-rw-r--r--DOCS/man/vf.rst8
-rw-r--r--video/csputils.c7
-rw-r--r--video/csputils.h8
-rw-r--r--video/filter/vf_format.c4
-rw-r--r--video/mp_image.c9
-rw-r--r--video/mp_image.h1
-rw-r--r--video/out/gpu/video.c6
-rw-r--r--video/zimg.c3
8 files changed, 42 insertions, 4 deletions
diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst
index 4f9268256c..3797ad26bd 100644
--- a/DOCS/man/vf.rst
+++ b/DOCS/man/vf.rst
@@ -339,6 +339,14 @@ Available mpv-only filters are:
Force a specific scaler backend, if applicable. This is a debug option
and could go away any time.
+ ``<alpha=auto|straight|premul>``
+ Set the kind of alpha the video uses. Undefined effect if the image
+ format has no alpha channel (could be ignored or cause an error,
+ depending on how mpv internals evolve). Setting this may or may not
+ cause downstream image processing to treat alpha differently, depending
+ on support. With ``convert`` and zimg used, this will convert the alpha.
+ libswscale and other FFmpeg components completely ignore this.
+
``lavfi=graph[:sws-flags[:o=opts]]``
Filter video using FFmpeg's libavfilter.
diff --git a/video/csputils.c b/video/csputils.c
index cc9aa4d64a..ef26813af0 100644
--- a/video/csputils.c
+++ b/video/csputils.c
@@ -108,6 +108,13 @@ const struct m_opt_choice_alternatives mp_chroma_names[] = {
{0}
};
+const struct m_opt_choice_alternatives mp_alpha_names[] = {
+ {"auto", MP_ALPHA_AUTO},
+ {"straight", MP_ALPHA_STRAIGHT},
+ {"premul", MP_ALPHA_PREMUL},
+ {0}
+};
+
void mp_colorspace_merge(struct mp_colorspace *orig, struct mp_colorspace *new)
{
if (!orig->space)
diff --git a/video/csputils.h b/video/csputils.h
index f817779584..fc6f04db6a 100644
--- a/video/csputils.h
+++ b/video/csputils.h
@@ -189,6 +189,14 @@ enum mp_chroma_location {
extern const struct m_opt_choice_alternatives mp_chroma_names[];
+enum mp_alpha_type {
+ MP_ALPHA_AUTO,
+ MP_ALPHA_STRAIGHT,
+ MP_ALPHA_PREMUL,
+};
+
+extern const struct m_opt_choice_alternatives mp_alpha_names[];
+
extern const struct m_sub_options mp_csp_equalizer_conf;
enum mp_csp_equalizer_param {
diff --git a/video/filter/vf_format.c b/video/filter/vf_format.c
index 793e37bc4a..8687db783b 100644
--- a/video/filter/vf_format.c
+++ b/video/filter/vf_format.c
@@ -50,6 +50,7 @@ struct vf_format_opts {
int chroma_location;
int stereo_in;
int rotate;
+ int alpha;
int w, h;
int dw, dh;
double dar;
@@ -87,6 +88,8 @@ static void set_params(struct vf_format_opts *p, struct mp_image_params *out,
out->stereo3d = p->stereo_in;
if (p->rotate >= 0)
out->rotate = p->rotate;
+ if (p->alpha)
+ out->alpha = p->alpha;
if (p->w > 0 && set_size)
out->w = p->w;
@@ -196,6 +199,7 @@ static const m_option_t vf_opts_fields[] = {
{"chroma-location", OPT_CHOICE_C(chroma_location, mp_chroma_names)},
{"stereo-in", OPT_CHOICE_C(stereo_in, mp_stereo3d_names)},
{"rotate", OPT_INT(rotate), M_RANGE(-1, 359)},
+ {"alpha", OPT_CHOICE_C(alpha, mp_alpha_names)},
{"w", OPT_INT(w)},
{"h", OPT_INT(h)},
{"dw", OPT_INT(dw)},
diff --git a/video/mp_image.c b/video/mp_image.c
index ea04bab26e..dba787452e 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -512,6 +512,7 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
dst->params.p_h = src->params.p_h;
dst->params.color = src->params.color;
dst->params.chroma_location = src->params.chroma_location;
+ dst->params.alpha = src->params.alpha;
dst->nominal_fps = src->nominal_fps;
// ensure colorspace consistency
if (mp_image_params_get_forced_csp(&dst->params) !=
@@ -643,6 +644,10 @@ char *mp_image_params_to_str_buf(char *b, size_t bs,
mp_snprintf_cat(b, bs, " stereo=%s",
MP_STEREO3D_NAME_DEF(p->stereo3d, "?"));
}
+ if (p->alpha) {
+ mp_snprintf_cat(b, bs, " A=%s",
+ m_opt_choice_str(mp_alpha_names, p->alpha));
+ }
} else {
snprintf(b, bs, "???");
}
@@ -687,7 +692,8 @@ bool mp_image_params_equal(const struct mp_image_params *p1,
mp_colorspace_equal(p1->color, p2->color) &&
p1->chroma_location == p2->chroma_location &&
p1->rotate == p2->rotate &&
- p1->stereo3d == p2->stereo3d;
+ p1->stereo3d == p2->stereo3d &&
+ p1->alpha == p2->alpha;
}
// Set most image parameters, but not image format or size.
@@ -862,6 +868,7 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
dst->params.stereo3d = p->stereo3d;
// Might be incorrect if colorspace changes.
dst->params.color.light = p->color.light;
+ dst->params.alpha = p->alpha;
}
sd = av_frame_get_side_data(src, AV_FRAME_DATA_ICC_PROFILE);
diff --git a/video/mp_image.h b/video/mp_image.h
index 16bae6e7d9..e51022dd5c 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -51,6 +51,7 @@ struct mp_image_params {
// The image should be rotated clockwise (0-359 degrees).
int rotate;
enum mp_stereo3d_mode stereo3d; // image is encoded with this mode
+ enum mp_alpha_type alpha; // usually auto; only set if explicitly known
};
/* Memory management:
diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c
index 9d5df7c739..4d14eb8019 100644
--- a/video/out/gpu/video.c
+++ b/video/out/gpu/video.c
@@ -2357,9 +2357,11 @@ static void pass_convert_yuv(struct gl_video *p)
p->components = 3;
if (!p->has_alpha || p->opts.alpha_mode == ALPHA_NO) {
GLSL(color.a = 1.0;)
- } else { // alpha present in image
+ } else if (p->image_params.alpha == MP_ALPHA_PREMUL) {
p->components = 4;
- GLSL(color = vec4(color.rgb * color.a, color.a);)
+ } else {
+ p->components = 4;
+ GLSL(color = vec4(color.rgb * color.a, color.a);) // straight -> premul
}
}
diff --git a/video/zimg.c b/video/zimg.c
index 635696f686..2f52537c07 100644
--- a/video/zimg.c
+++ b/video/zimg.c
@@ -1137,7 +1137,8 @@ static bool setup_format_ne(zimg_image_format *zfmt, struct mp_zimg_repack *r,
r->z_planes[3] = n; // alpha, always plane 4 in zimg
#if HAVE_ZIMG_ALPHA
- zfmt->alpha = ZIMG_ALPHA_STRAIGHT;
+ zfmt->alpha = fmt.alpha == MP_ALPHA_PREMUL
+ ? ZIMG_ALPHA_PREMULTIPLIED : ZIMG_ALPHA_STRAIGHT;
#else
return false;
#endif