diff eosd.c @ 32391:b4c3659d16b1

Use a dynamic list for the sources of EOSD elements.
author cigaes
date Sun, 10 Oct 2010 09:27:11 +0000
parents ef21cbba62ee
children b3110e526e19
line wrap: on
line diff
--- a/eosd.c	Sat Oct 09 17:52:35 2010 +0000
+++ b/eosd.c	Sun Oct 10 09:27:11 2010 +0000
@@ -26,54 +26,134 @@
 #include "ass_mp.h"
 #include "eosd.h"
 
-#ifdef CONFIG_ASS
-static ASS_Renderer *ass_renderer;
-int prev_visibility;
-
-void eosd_ass_init(ASS_Library *ass_library)
-{
-    ass_renderer = ass_renderer_init(ass_library);
-    if (!ass_renderer)
-        return;
-    ass_configure_fonts(ass_renderer);
-}
-#endif
+static struct mp_eosd_source *sources;
+static struct mp_eosd_settings settings;
+static struct mp_eosd_image *image_pool;
 
 void eosd_init(vf_instance_t *vf)
 {
     vf->control(vf, VFCTRL_INIT_EOSD, NULL);
 }
 
-void eosd_configure(mp_eosd_res_t *res, int hinting)
+void eosd_register(struct mp_eosd_source *src)
 {
-#ifdef CONFIG_ASS
-    double dar = (double) (res->w - res->ml - res->mr) / (res->h - res->mt - res->mb);
-    if (ass_renderer) {
-        ass_configure(ass_renderer, res->w, res->h, hinting);
-        ass_set_margins(ass_renderer, res->mt, res->mb, res->ml, res->mr);
-        ass_set_aspect_ratio(ass_renderer, dar, (double)res->srcw/res->srch);
-    }
-#endif
+    struct mp_eosd_source *p, **prev = &sources;
+    for (p = sources; p && p->z_index < src->z_index; p = p->priv_next)
+        prev = &p->priv_next;
+    src->priv_next = p;
+    *prev          = src;
 }
 
-ASS_Image *eosd_render_frame(double ts, int *changed)
+void eosd_configure(struct mp_eosd_settings *res)
 {
-    ASS_Image *r = NULL;
-#ifdef CONFIG_ASS
-    if (sub_visibility && ass_renderer && ass_track && ts != MP_NOPTS_VALUE) {
-        r = ass_mp_render_frame(ass_renderer, ass_track, (ts+sub_delay) * 1000 + .5, changed);
-        if (!prev_visibility && changed)
-            *changed = 2;
+    if (res->w        != settings.w        ||
+        res->h        != settings.h        ||
+        res->srcw     != settings.srcw     ||
+        res->srch     != settings.srch     ||
+        res->mt       != settings.mt       ||
+        res->mt       != settings.mb       ||
+        res->mt       != settings.ml       ||
+        res->mt       != settings.mr       ||
+        res->unscaled != settings.unscaled) {
+        settings         = *res;
+        settings.changed = 1;
     }
-    prev_visibility = sub_visibility;
-#endif
-    return r;
+}
+
+void eosd_render_frame(double ts, struct mp_eosd_image_list *images)
+{
+    struct mp_eosd_source *src;
+    int changed = 0;
+    for (src = sources; src; src = src->priv_next) {
+        if (src->update)
+            src->update(src, &settings, ts);
+        changed |= src->changed;
+        src->changed = 0;
+    }
+    settings.changed = 0;
+    images->first_source = sources;
+    images->changed      = changed;
 }
 
 void eosd_uninit(void)
 {
-#ifdef CONFIG_ASS
-    if (ass_renderer)
-        ass_renderer_done(ass_renderer);
-#endif
+    struct mp_eosd_source *src;
+    for (src = sources; src; src = src->priv_next)
+        if (src->uninit)
+            src->uninit(src);
+}
+
+struct mp_eosd_image *eosd_image_alloc(void)
+{
+    struct mp_eosd_image *r;
+    if (!image_pool) {
+        const unsigned n_alloc = 127; /* arbitrary */
+        unsigned i;
+        image_pool = calloc(n_alloc, sizeof(*image_pool));
+        for (i = 0; i < n_alloc - 1; i++)
+            image_pool[i].next = image_pool + i + 1;
+        image_pool[i].next = NULL;
+    }
+    r          = image_pool;
+    image_pool = image_pool->next;
+    return r;
+}
+
+void eosd_image_free(struct mp_eosd_image *image)
+{
+    image->next = image_pool;
+    image_pool  = image;
+}
+
+void eosd_image_append(struct mp_eosd_source *source,
+                       struct mp_eosd_image *image)
+{
+    image->next          = NULL;
+    *source->images_tail = image;
+    source->images_tail  = &image->next;
 }
+
+void eosd_image_remove(struct mp_eosd_source *source,
+                       struct mp_eosd_image *image,
+                       struct mp_eosd_image **prev)
+{
+    *prev = image->next;
+    if (!*prev)
+        source->images_tail = prev;
+    eosd_image_free(image);
+}
+
+void eosd_image_remove_all(struct mp_eosd_source *source)
+{
+    struct mp_eosd_image *image;
+
+    while (source->images) {
+        image          = source->images;
+        source->images = source->images->next;
+        eosd_image_free(image);
+    }
+    source->images_tail = &source->images;
+}
+
+static void next_image_in_sources(struct mp_eosd_image_list *images,
+                                  struct mp_eosd_source *src)
+{
+    images->source = src;
+    while (images->source && !images->source->images)
+        images->source = images->source->priv_next;
+    images->image = images->source ? images->source->images : NULL;
+}
+
+struct mp_eosd_image *eosd_image_first(struct mp_eosd_image_list *images)
+{
+    next_image_in_sources(images, images->first_source);
+    return images->image;
+}
+
+struct mp_eosd_image *eosd_image_next(struct mp_eosd_image_list *images)
+{
+    images->image = images->image->next;
+    if (!images->image)
+        next_image_in_sources(images, images->source->priv_next);
+    return images->image;
+}