vf_gpu: render subtitles

Pretty annoying affair. The vo_gpu code could of course not trigger
rendering from filters yet, so it needed to be extended. Also, this uses
some icky stuff made for vf_sub (and this was the reason I marked vf_sub
as deprecated), so everything is terrible.
This commit is contained in:
wm4 2019-11-30 18:09:31 +01:00
parent 6a88e7463e
commit 78f1629a53
4 changed files with 25 additions and 12 deletions

View File

@ -729,9 +729,9 @@ Available mpv-only filters are:
.. warning::
This does not do OSD rendering. If you see OSD or subtitles, then these
have been renderer by the VO backend (or the ``sub`` video filter). This
is normally done in software, and potentially questionable quality.
This does not do OSD rendering. If you see OSD, then it has been
rendered by the VO backend. (Subtitles are rendered by the ``gpu``
filter, if possible.)
.. warning::

View File

@ -176,6 +176,14 @@ static struct mp_image *gpu_render_frame(struct mp_filter *f, struct mp_image *i
struct mp_rect src, dst;
struct mp_osd_res osd;
struct mp_stream_info *info = mp_filter_find_stream_info(f);
struct osd_state *osd_state = info ? info->osd : NULL;
if (osd_state) {
osd_set_render_subs_in_filter(osd_state, true);
// Assume the osd_state doesn't somehow disappear.
gl_video_set_osd_source(priv->renderer, osd_state);
}
mp_get_src_dst_rects(f->log, priv->vo_opts, VO_CAP_ROTATE90, &in->params,
w, h, 1, &src, &dst, &osd);
@ -202,7 +210,7 @@ static struct mp_image *gpu_render_frame(struct mp_filter *f, struct mp_image *i
}
// (it doesn't have access to the OSD though)
int flags = RENDER_FRAME_SUBS | RENDER_FRAME_OSD;
int flags = RENDER_FRAME_SUBS | RENDER_FRAME_VF_SUBS;
gl_video_render_frame(priv->renderer, &frame, (struct ra_fbo){priv->target},
flags);

View File

@ -2803,13 +2803,17 @@ static void pass_dither(struct gl_video *p)
// Draws the OSD, in scene-referred colors.. If cms is true, subtitles are
// instead adapted to the display's gamut.
static void pass_draw_osd(struct gl_video *p, int draw_flags, double pts,
struct mp_osd_res rect, struct ra_fbo fbo, bool cms)
static void pass_draw_osd(struct gl_video *p, int osd_flags, int frame_flags,
double pts, struct mp_osd_res rect, struct ra_fbo fbo,
bool cms)
{
if ((draw_flags & OSD_DRAW_SUB_ONLY) && (draw_flags & OSD_DRAW_OSD_ONLY))
if (frame_flags & RENDER_FRAME_VF_SUBS)
osd_flags |= OSD_DRAW_SUB_FILTER;
if ((osd_flags & OSD_DRAW_SUB_ONLY) && (osd_flags & OSD_DRAW_OSD_ONLY))
return;
mpgl_osd_generate(p->osd, rect, pts, p->image_params.stereo3d, draw_flags);
mpgl_osd_generate(p->osd, rect, pts, p->image_params.stereo3d, osd_flags);
timer_pool_start(p->osd_timer);
for (int n = 0; n < MAX_OSD_PARTS; n++) {
@ -2922,7 +2926,7 @@ static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi,
};
finish_pass_tex(p, &p->blend_subs_tex, rect.w, rect.h);
struct ra_fbo fbo = { p->blend_subs_tex };
pass_draw_osd(p, OSD_DRAW_SUB_ONLY, vpts, rect, fbo, false);
pass_draw_osd(p, OSD_DRAW_SUB_ONLY, flags, vpts, rect, fbo, false);
pass_read_tex(p, p->blend_subs_tex);
pass_describe(p, "blend subs video");
}
@ -2954,7 +2958,7 @@ static bool pass_render_frame(struct gl_video *p, struct mp_image *mpi,
}
finish_pass_tex(p, &p->blend_subs_tex, p->texture_w, p->texture_h);
struct ra_fbo fbo = { p->blend_subs_tex };
pass_draw_osd(p, OSD_DRAW_SUB_ONLY, vpts, rect, fbo, false);
pass_draw_osd(p, OSD_DRAW_SUB_ONLY, flags, vpts, rect, fbo, false);
pass_read_tex(p, p->blend_subs_tex);
pass_describe(p, "blend subs");
}
@ -3329,7 +3333,7 @@ done:
if (!(flags & RENDER_FRAME_OSD))
osd_flags |= OSD_DRAW_SUB_ONLY;
pass_draw_osd(p, osd_flags, p->osd_pts, p->osd_rect, fbo, true);
pass_draw_osd(p, osd_flags, flags, p->osd_pts, p->osd_rect, fbo, true);
debug_check_gl(p, "after OSD rendering");
}

View File

@ -159,7 +159,8 @@ struct voctrl_screenshot;
enum {
RENDER_FRAME_SUBS = 1 << 0,
RENDER_FRAME_OSD = 2 << 0,
RENDER_FRAME_OSD = 1 << 1,
RENDER_FRAME_VF_SUBS = 1 << 2,
RENDER_FRAME_DEF = RENDER_FRAME_SUBS | RENDER_FRAME_OSD,
};