]> granicus.if.org Git - libass/commitdiff
render_api: do not discard old images on reconfiguration fix-change-detection
authorwm4 <wm4@nowhere>
Fri, 13 Jan 2017 08:19:23 +0000 (09:19 +0100)
committerwm4 <wm4@nowhere>
Fri, 13 Jan 2017 08:19:28 +0000 (09:19 +0100)
I noticed that when resizing the mpv window while playback is ongoing
and with subtitles, that subtitles could sometimes get "stuck" on the
screen. The stuck subtitle would remain until the next subtitle event,
or until seeking to a position that has subtitles again.

It turned out that this was a libass change detection bug. The following
steps should reproduce the problem:

1. call ass_render_frame() with a time that has subtitles
2. call ass_set_frame_size() with a different size
3. call ass_render_frame() with a time that has no subtitles

The previous call will return with *detect_change==0.

To make this worse, libass will deallocate image data before the next
ass_render_frame() or ass_renderer_done(), which violates the API and
could possibly make some API users crash. (That the user can rely on
this is not documented though.)

There are two possible solutions:

1. Set a flag in ass_reconfigure(), that makes the next
   ass_render_frame() call always return *detect_change==2.
2. Do not discard the previous subtitles (images_root), so change
   detection can work reliably.

This commit implements 2. - I prefer this in part because it doesn't
clobber the previously returned image list before the next
ass_render_frame() call. (As pointed out above, this might be unexpected
behavior to the API user.)

This is a regression and was possibly broken by commit dd06ca and later.
I did not check whether it actually behaved sanely before that change,
but it probably did to a degree.

libass/ass_render_api.c

index d4b55de2d5165ff5e40331c81cbb8a47ff0d13d4..2e61b7ebe39bc1fbba977b6300ad1b26ded4eed6 100644 (file)
@@ -27,11 +27,9 @@ static void ass_reconfigure(ASS_Renderer *priv)
     ASS_Settings *settings = &priv->settings;
 
     priv->render_id++;
-    ass_frame_unref(priv->images_root);
     ass_cache_empty(priv->cache.composite_cache);
     ass_cache_empty(priv->cache.bitmap_cache);
     ass_cache_empty(priv->cache.outline_cache);
-    priv->images_root = NULL;
 
     priv->width = settings->frame_width;
     priv->height = settings->frame_height;