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);
img->source = source;
ass_cache_inc_ref(source);
+ img->ref_count = 0;
return &img->result;
}
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
*/
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);
if (detect_change) {
*detect_change = 2;
}
- return 0;
+ return NULL;
}
// render events separately
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);
+}
typedef struct {
ASS_Image result;
CompositeHashValue *source;
+ size_t ref_count;
} ASS_ImagePriv;
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);
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;