]> granicus.if.org Git - libass/commitdiff
render: add refcounting functionality to image lists
authorDr.Smile <vabnick@gmail.com>
Sun, 1 May 2016 19:29:35 +0000 (22:29 +0300)
committerDr.Smile <vabnick@gmail.com>
Thu, 30 Jun 2016 20:13:54 +0000 (23:13 +0300)
libass/ass_render.c
libass/ass_render.h
libass/ass_render_api.c

index 92fe1ed4bb2bf0718c6046fbbf8ccb044d9974a4..9bbaaa32023331f64ed104430129c88f5b41f7ab 100644 (file)
@@ -116,8 +116,8 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
 
 void ass_renderer_done(ASS_Renderer *render_priv)
 {
-    ass_free_images(render_priv->images_root);
-    ass_free_images(render_priv->prev_images_root);
+    ass_frame_unref(render_priv->images_root);
+    ass_frame_unref(render_priv->prev_images_root);
 
     ass_cache_done(render_priv->cache.composite_cache);
     ass_cache_done(render_priv->cache.bitmap_cache);
@@ -177,6 +177,7 @@ static ASS_Image *my_draw_bitmap(unsigned char *bitmap, int bitmap_w,
 
     img->source = source;
     ass_cache_inc_ref(source);
+    img->ref_count = 0;
 
     return &img->result;
 }
@@ -2632,24 +2633,6 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
     return 0;
 }
 
-/**
- * \brief deallocate image list
- * \param img list pointer
- */
-void ass_free_images(ASS_Image *img)
-{
-    while (img) {
-        ASS_Image *next = img->next;
-        ASS_ImagePriv *priv = (ASS_ImagePriv *) img;
-        if (priv->source)
-            ass_cache_dec_ref(priv->source);
-        else
-            ass_aligned_free(img->bitmap);
-        free(priv);
-        img = next;
-    }
-}
-
 /**
  * \brief Check cache limits and reset cache if they are exceeded
  */
@@ -2707,7 +2690,7 @@ ass_start_frame(ASS_Renderer *render_priv, ASS_Track *track,
     render_priv->font_scale_x = par;
 
     render_priv->prev_images_root = render_priv->images_root;
-    render_priv->images_root = 0;
+    render_priv->images_root = NULL;
 
     check_cache_limits(render_priv, &render_priv->cache);
 
@@ -2979,7 +2962,7 @@ ASS_Image *ass_render_frame(ASS_Renderer *priv, ASS_Track *track,
         if (detect_change) {
             *detect_change = 2;
         }
-        return 0;
+        return NULL;
     }
 
     // render events separately
@@ -3023,13 +3006,44 @@ ASS_Image *ass_render_frame(ASS_Renderer *priv, ASS_Track *track,
             cur = cur->next;
         }
     }
+    ass_frame_ref(priv->images_root);
 
     if (detect_change)
         *detect_change = ass_detect_change(priv);
 
     // free the previous image list
-    ass_free_images(priv->prev_images_root);
-    priv->prev_images_root = 0;
+    ass_frame_unref(priv->prev_images_root);
+    priv->prev_images_root = NULL;
 
     return priv->images_root;
 }
+
+/**
+ * \brief Add reference to a frame image list.
+ * \param image_list image list returned by ass_render_frame()
+ */
+void ass_frame_ref(ASS_Image *img)
+{
+    if (!img)
+        return;
+    ((ASS_ImagePriv *) img)->ref_count++;
+}
+
+/**
+ * \brief Release reference to a frame image list.
+ * \param image_list image list returned by ass_render_frame()
+ */
+void ass_frame_unref(ASS_Image *img)
+{
+    if (!img || --((ASS_ImagePriv *) img)->ref_count)
+        return;
+    do {
+        ASS_ImagePriv *priv = (ASS_ImagePriv *) img;
+        img = img->next;
+        if (priv->source)
+            ass_cache_dec_ref(priv->source);
+        else
+            ass_aligned_free(priv->result.bitmap);
+        free(priv);
+    } while (img);
+}
index 2330eb07319c63641b213c598ad64329858ee69c..6e3963ebf23a07b5c6cdfee5f4c22d084e2df170 100644 (file)
@@ -63,6 +63,7 @@ typedef struct {
 typedef struct {
     ASS_Image result;
     CompositeHashValue *source;
+    size_t ref_count;
 } ASS_ImagePriv;
 
 typedef struct {
@@ -349,7 +350,8 @@ typedef struct {
 } Segment;
 
 void reset_render_context(ASS_Renderer *render_priv, ASS_Style *style);
-void ass_free_images(ASS_Image *img);
+void ass_frame_ref(ASS_Image *img);
+void ass_frame_unref(ASS_Image *img);
 
 // XXX: this is actually in ass.c, includes should be fixed later on
 void ass_lazy_track_init(ASS_Library *lib, ASS_Track *track);
index f19ce41afda0534243e904a5b1437dda4ffd6f8c..c59c204d232e5acac4d9940fee98ef53ac4a7e0e 100644 (file)
@@ -27,11 +27,11 @@ static void ass_reconfigure(ASS_Renderer *priv)
     ASS_Settings *settings = &priv->settings;
 
     priv->render_id++;
-    ass_free_images(priv->images_root);
+    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 = 0;
+    priv->images_root = NULL;
 
     priv->width = settings->frame_width;
     priv->height = settings->frame_height;