changeset 32391:b4c3659d16b1

Use a dynamic list for the sources of EOSD elements.
author cigaes
date Sun, 10 Oct 2010 09:27:11 +0000
parents b33aed46ecda
children 7fd2de8d6f32
files ass_mp.c ass_mp.h eosd.c eosd.h libmpcodecs/vf_ass.c libmpcodecs/vf_vo.c libvo/video_out.h libvo/vo_gl.c libvo/vo_vdpau.c
diffstat 9 files changed, 353 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/ass_mp.c	Sat Oct 09 17:52:35 2010 +0000
+++ b/ass_mp.c	Sun Oct 10 09:27:11 2010 +0000
@@ -28,6 +28,9 @@
 #include "subreader.h"
 
 #include "ass_mp.h"
+#include "eosd.h"
+#include "mpcommon.h"
+#include "libvo/sub.h"
 #include "help_mp.h"
 #include "libvo/font_load.h"
 #include "stream/stream.h"
@@ -313,3 +316,63 @@
 	}
 	return ass_render_frame(priv, track, now, detect_change);
 }
+
+/* EOSD source for ASS subtitles. */
+
+static ASS_Renderer *ass_renderer;
+static int prev_visibility;
+
+static void eosd_ass_update(struct mp_eosd_source *src, const struct mp_eosd_settings *res, double ts)
+{
+	long long ts_ms = (ts + sub_delay) * 1000 + .5;
+	ASS_Image *aimg;
+	struct mp_eosd_image *img;
+	if (res->changed) {
+		double dar = (double) (res->w - res->ml - res->mr) / (res->h - res->mt - res->mb);
+		ass_configure(ass_renderer, res->w, res->h, res->unscaled);
+		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);
+	}
+	aimg = sub_visibility && ass_track && ts != MP_NOPTS_VALUE ?
+		ass_mp_render_frame(ass_renderer, ass_track, ts_ms, &src->changed) :
+		NULL;
+	if (!aimg != !src->images)
+		src->changed = 2;
+	if (src->changed) {
+		eosd_image_remove_all(src);
+		while (aimg) {
+			img = eosd_image_alloc();
+			img->w      = aimg->w;
+			img->h      = aimg->h;
+			img->bitmap = aimg->bitmap;
+			img->stride = aimg->stride;
+			img->color  = aimg->color;
+			img->dst_x  = aimg->dst_x;
+			img->dst_y  = aimg->dst_y;
+			eosd_image_append(src, img);
+			aimg = aimg->next;
+		}
+	}
+	prev_visibility = sub_visibility;
+}
+
+static void eosd_ass_uninit(struct mp_eosd_source *src)
+{
+	eosd_image_remove_all(src);
+	ass_renderer_done(ass_renderer);
+}
+
+static struct mp_eosd_source eosd_ass = {
+	.uninit  = eosd_ass_uninit,
+	.update  = eosd_ass_update,
+	.z_index = 10,
+};
+
+void eosd_ass_init(ASS_Library *ass_library)
+{
+	ass_renderer = ass_renderer_init(ass_library);
+	if (!ass_renderer)
+		return;
+	ass_configure_fonts(ass_renderer);
+	eosd_register(&eosd_ass);
+}
--- a/ass_mp.h	Sat Oct 09 17:52:35 2010 +0000
+++ b/ass_mp.h	Sun Oct 10 09:27:11 2010 +0000
@@ -62,4 +62,9 @@
 extern int ass_force_reload;
 ASS_Image* ass_mp_render_frame(ASS_Renderer *priv, ASS_Track* track, long long now, int* detect_change);
 
+/**
+ * Initialize the use of EOSD for ASS subtitles rendering.
+ */
+void eosd_ass_init(ASS_Library *library);
+
 #endif /* MPLAYER_ASS_MP_H */
--- 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;
+}
--- a/eosd.h	Sat Oct 09 17:52:35 2010 +0000
+++ b/eosd.h	Sun Oct 10 09:27:11 2010 +0000
@@ -22,9 +22,84 @@
 #ifndef MPLAYER_EOSD_H
 #define MPLAYER_EOSD_H
 
+#include <stdint.h>
 #include "libmpcodecs/vf.h"
-#include "libvo/video_out.h"
-#include "ass_mp.h"
+
+enum {
+    EOSD_CHANGED_LAYOUT = 0x1,
+    EOSD_CHANGED_BITMAP = 0x2,
+};
+
+struct mp_eosd_settings {
+    int w, h;           ///< screen dimensions, including black borders
+    int srcw, srch;     ///< unscaled source dimensions
+    int mt, mb, ml, mr; ///< borders (top, bottom, left, right)
+    int unscaled;       ///< EOSD objects are rendered at native resolution
+    int changed;        ///< settings have changed since last update
+};
+
+struct mp_eosd_image {
+    struct mp_eosd_image *next; ///< Next image, or NULL
+    uint8_t *bitmap;            ///< 1bpp stride*h alpha buffer
+    void *opaque;               ///< Arbitrary value for the client's use
+    int w, h;                   ///< Bitmap width, height
+    int stride;                 ///< Bitmap stride
+    uint32_t color;             ///< Bitmap color and transparency, RGBT
+                                ///  T is the complement of A (alpha=opacity).
+    int dst_x, dst_y;           ///< Bitmap placement inside the video frame
+};
+
+struct mp_eosd_source {
+
+    /**
+     * Linked list of images element.
+     * The client is responsible for initializing and maintaining this list.
+     * It can alter it at any time in the main MPlayer thread.
+     */
+    struct mp_eosd_image *images;
+
+    /**
+     * Pointer to the next field of the last image, or to images if the list
+     * is empty.
+     * The client is not required to handle this field, but list
+     * manipulation functions (see below) use it.
+     */
+    struct mp_eosd_image **images_tail;
+
+    /**
+     * Callback to update the images. Can be NULL.
+     */
+    void (*update)(struct mp_eosd_source *, const struct mp_eosd_settings *,
+                   double);
+
+    /**
+     * Callback to uninit the source. Can be NULL.
+     */
+    void (*uninit)(struct mp_eosd_source *);
+
+    /**
+     * Changed flags of the images.
+     * The client must set it to a combination of EOSD_CHANGED_* whenever
+     * the images are altered.
+     * The core EOSD system resets it.
+     */
+    int changed;
+
+    /**
+     * Z-index of the images.
+     * Images with a higher Z-index are rendered on top.
+     */
+    int z_index;
+
+    struct mp_eosd_source *priv_next;
+};
+
+struct mp_eosd_image_list {
+    struct mp_eosd_source *first_source;
+    struct mp_eosd_source *source;
+    struct mp_eosd_image *image;
+    int changed;
+};
 
 /**
  * Initialize the EOSD subsystem.
@@ -39,22 +114,22 @@
  * settings change.
  *
  * @param res      resolution and margins of the rendering area.
- * @param hinting  nonzero if hinting is useful.
  */
-void eosd_configure(mp_eosd_res_t *res, int hinting);
+void eosd_configure(struct mp_eosd_settings *res);
 
 /**
  * Renders the EOSD elements for the current frame.
  * Should be called by the rendering engine when it is about to do or
  * prepare the rendering.
  *
- * @param ts       presentation timestamp of the frame.
- * @param changed  if not NULL, will be set to 0 if the elements are
- *                 identical since the last call, 1 if they have changed
- *                 only in coordinates, and 2 if they have really changed.
- * @return         a linked list of EOSD elements.
+ * @param[in]  ts      presentation timestamp of the frame.
+ * @param[out] images  list of images to render.
+ *                     The list and list elements are only valid until any
+ *                     client alter them.
+ *                     The renderer should therefore not call anything that
+ *                     may alter the EOSD elements.
  */
-struct ass_image *eosd_render_frame(double ts, int *changed);
+void eosd_render_frame(double ts, struct mp_eosd_image_list *images);
 
 /**
  * Shut down the EOSD subsystem and free the associated resources.
@@ -62,8 +137,56 @@
 void eosd_uninit(void);
 
 /**
- * Initialize the use of EOSD for ASS subtitles rendering.
+ * Register a source of EOSD images.
+ */
+void eosd_register(struct mp_eosd_source *source);
+
+/**
+ * Allocate a structure for an EOSD image.
+ */
+struct mp_eosd_image *eosd_image_alloc(void);
+
+/**
+ * Free a previously allocated structure.
+ */
+void eosd_image_free(struct mp_eosd_image *image);
+
+/**
+ * Append an image to the list of images associated to a source.
+ * This function requires that the images_tail pointer is correctly set.
  */
-void eosd_ass_init(ASS_Library *ass_library);
+void eosd_image_append(struct mp_eosd_source *source,
+                       struct mp_eosd_image *image);
+
+/**
+ * Remove an image from the list of images associated to a source.
+ * The image structure is freed using eosd_image_free.
+ *
+ * @param source  source where the image is.
+ * @param image   image to remove.
+ * @param prev    pointeur to the prev field of the previous image,
+ *                or to source->images if this is the first image.
+ */
+void eosd_image_remove(struct mp_eosd_source *source,
+                       struct mp_eosd_image *image,
+                       struct mp_eosd_image **prev);
+
+/**
+ * Remove all images associated to a source and free the corresponding
+ * structures.
+ * This function also resets the images_tail pointer.
+ */
+void eosd_image_remove_all(struct mp_eosd_source *source);
+
+/**
+ * Reset the cursor of an image list and get the first image.
+ */
+struct mp_eosd_image *eosd_image_first(struct mp_eosd_image_list *images);
+
+/**
+ * Get the next image in an image list.
+ * The renderer must NOT use the next field in the image structure.
+ */
+struct mp_eosd_image *eosd_image_next(struct mp_eosd_image_list *images);
 
 #endif /* MPLAYER_EOSD_H */
--- a/libmpcodecs/vf_ass.c	Sat Oct 09 17:52:35 2010 +0000
+++ b/libmpcodecs/vf_ass.c	Sun Oct 10 09:27:11 2010 +0000
@@ -37,7 +37,6 @@
 
 #include "libvo/fastmemcpy.h"
 #include "libvo/sub.h"
-#include "libvo/video_out.h"
 #include "m_option.h"
 #include "m_struct.h"
 
@@ -71,7 +70,7 @@
                   int width, int height, int d_width, int d_height,
                   unsigned int flags, unsigned int outfmt)
 {
-    mp_eosd_res_t res = { 0 };
+    struct mp_eosd_settings res = {0};
 
     if (outfmt == IMGFMT_IF09)
         return 0;
@@ -94,7 +93,7 @@
     res.srch = height;
     res.mt   = ass_top_margin;
     res.mb   = ass_bottom_margin;
-    eosd_configure(&res, 0);
+    eosd_configure(&res);
 
     return vf_next_config(vf, vf->priv->outw, vf->priv->outh, d_width,
                           d_height, flags, outfmt);
@@ -334,29 +333,29 @@
     }
 }
 
-static int render_frame(struct vf_instance *vf, mp_image_t *mpi,
-                        const ASS_Image *img)
+static void render_frame(struct vf_instance *vf, mp_image_t *mpi,
+                         struct mp_eosd_image_list *images)
 {
-    if (img) {
+    struct mp_eosd_image *img;
+    img = eosd_image_first(images);
+    if (!img)
+        return;
         memset(vf->priv->dirty_rows, 0, vf->priv->outh);        // reset dirty rows
         while (img) {
             copy_from_image(vf, img->dst_y, img->dst_y + img->h);
             my_draw_bitmap(vf, img->bitmap, img->w, img->h, img->stride,
                            img->dst_x, img->dst_y, img->color);
-            img = img->next;
+            img = eosd_image_next(images);
         }
         copy_to_image(vf);
-    }
-    return 0;
 }
 
 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
 {
-    ASS_Image *images = eosd_render_frame(pts, NULL);
+    struct mp_eosd_image_list images;
+    eosd_render_frame(pts, &images);
     prepare_image(vf, mpi);
-    if (images)
-        render_frame(vf, mpi, images);
-
+    render_frame(vf, mpi, &images);
     return vf_next_put_image(vf, vf->dmpi, pts);
 }
 
--- a/libmpcodecs/vf_vo.c	Sat Oct 09 17:52:35 2010 +0000
+++ b/libmpcodecs/vf_vo.c	Sun Oct 10 09:27:11 2010 +0000
@@ -28,6 +28,7 @@
 
 #include "libvo/sub.h"
 #include "libvo/video_out.h"
+#include "eosd.h"
 
 #include "eosd.h"
 
@@ -123,13 +124,14 @@
     }
     case VFCTRL_DRAW_EOSD:
     {
-        EOSD_ImageList images = {NULL, 2};
-        mp_eosd_res_t res = {0};
+        struct mp_eosd_image_list images;
+        struct mp_eosd_settings res = {0};
         double pts = vf->priv->pts;
         if (!vo_config_count) return CONTROL_FALSE;
+        res.unscaled = !!(vf->default_caps & VFCAP_EOSD_UNSCALED);
         if (video_out->control(VOCTRL_GET_EOSD_RES, &res) == VO_TRUE)
-            eosd_configure(&res, !!(vf->default_caps & VFCAP_EOSD_UNSCALED));
-        images.imgs = eosd_render_frame(pts, &images.changed);
+            eosd_configure(&res);
+        eosd_render_frame(pts, &images);
         return (video_out->control(VOCTRL_DRAW_EOSD, &images) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
     }
 #endif
--- a/libvo/video_out.h	Sat Oct 09 17:52:35 2010 +0000
+++ b/libvo/video_out.h	Sun Oct 10 09:27:11 2010 +0000
@@ -74,11 +74,6 @@
 #define VOCTRL_BORDER 27
 #define VOCTRL_DRAW_EOSD 28
 #define VOCTRL_GET_EOSD_RES 29
-typedef struct {
-  int w, h; // screen dimensions, including black borders
-  int srcw, srch; // unscaled source dimensions
-  int mt, mb, ml, mr; // borders (top, bottom, left, right)
-} mp_eosd_res_t;
 
 #define VOCTRL_SET_DEINTERLACE 30
 #define VOCTRL_GET_DEINTERLACE 31
--- a/libvo/vo_gl.c	Sat Oct 09 17:52:35 2010 +0000
+++ b/libvo/vo_gl.c	Sun Oct 10 09:27:11 2010 +0000
@@ -38,6 +38,7 @@
 #include "gl_common.h"
 #include "aspect.h"
 #include "fastmemcpy.h"
+#include "eosd.h"
 
 #ifdef CONFIG_GL_SDL
 #ifdef CONFIG_SDL_SDL_H
@@ -313,11 +314,11 @@
   eosdtex = NULL;
 }
 
-static inline int is_tinytex(ASS_Image *i, int tinytexcur) {
+static inline int is_tinytex(struct mp_eosd_image *i, int tinytexcur) {
   return i->w < TINYTEX_SIZE && i->h < TINYTEX_SIZE && tinytexcur < TINYTEX_MAX;
 }
 
-static inline int is_smalltex(ASS_Image *i, int smalltexcur) {
+static inline int is_smalltex(struct mp_eosd_image *i, int smalltexcur) {
   return i->w < SMALLTEX_SIZE && i->h < SMALLTEX_SIZE && smalltexcur < SMALLTEX_MAX;
 }
 
@@ -336,14 +337,14 @@
  * \param img image list to create OSD from.
  *            A value of NULL has the same effect as clearEOSD()
  */
-static void genEOSD(EOSD_ImageList *imgs) {
+static void genEOSD(struct mp_eosd_image_list *imgs) {
   int sx, sy;
   int tinytexcur = 0;
   int smalltexcur = 0;
   GLuint *curtex;
   GLint scale_type = scaled_osd ? GL_LINEAR : GL_NEAREST;
-  ASS_Image *img = imgs->imgs;
-  ASS_Image *i;
+  struct mp_eosd_image *img = eosd_image_first(imgs);
+  struct mp_eosd_image *i;
 
   if (imgs->changed == 0) // there are elements, but they are unchanged
       return;
@@ -360,7 +361,7 @@
     mpglBindTexture(gl_target, largeeosdtex[1]);
     glCreateClearTex(gl_target, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, scale_type, LARGE_EOSD_TEX_SIZE, LARGE_EOSD_TEX_SIZE, 0);
   }
-  for (i = img; i; i = i->next)
+  for (i = img; i; i = eosd_image_next(imgs))
   {
     if (i->w <= 0 || i->h <= 0 || i->stride < i->w)
       continue;
@@ -378,7 +379,7 @@
     mpglGenTextures(eosdtexCnt, eosdtex);
   }
   tinytexcur = smalltexcur = 0;
-  for (i = img, curtex = eosdtex; i; i = i->next) {
+  for (i = eosd_image_first(imgs), curtex = eosdtex; i; i = eosd_image_next(imgs)) {
     int x = 0, y = 0;
     if (i->w <= 0 || i->h <= 0 || i->stride < i->w) {
       mp_msg(MSGT_VO, MSGL_V, "Invalid dimensions OSD for part!\n");
@@ -404,7 +405,7 @@
 skip_upload:
   mpglNewList(eosdDispList, GL_COMPILE);
   tinytexcur = smalltexcur = 0;
-  for (i = img, curtex = eosdtex; i; i = i->next) {
+  for (i = eosd_image_first(imgs), curtex = eosdtex; i; i = eosd_image_next(imgs)) {
     int x = 0, y = 0;
     if (i->w <= 0 || i->h <= 0 || i->stride < i->w)
       continue;
@@ -1323,7 +1324,7 @@
     return VO_TRUE;
   case VOCTRL_GET_EOSD_RES:
     {
-      mp_eosd_res_t *r = data;
+      struct mp_eosd_settings *r = data;
       r->w = vo_dwidth; r->h = vo_dheight;
       r->srcw = image_width; r->srch = image_height;
       r->mt = r->mb = r->ml = r->mr = 0;
--- a/libvo/vo_vdpau.c	Sat Oct 09 17:52:35 2010 +0000
+++ b/libvo/vo_vdpau.c	Sun Oct 10 09:27:11 2010 +0000
@@ -43,6 +43,7 @@
 #include "aspect.h"
 #include "font_load.h"
 #include "sub.h"
+#include "eosd.h"
 #include "subopt-helper.h"
 
 #include "libavcodec/vdpau.h"
@@ -854,13 +855,13 @@
     }
 }
 
-static void generate_eosd(EOSD_ImageList *imgs)
+static void generate_eosd(struct mp_eosd_image_list *imgs)
 {
     VdpStatus vdp_st;
     VdpRect destRect;
     int j, found;
-    ASS_Image *img = imgs->imgs;
-    ASS_Image *i;
+    struct mp_eosd_image *img = eosd_image_first(imgs);
+    struct mp_eosd_image *i;
 
     // Nothing changed, no need to redraw
     if (imgs->changed == 0)
@@ -876,7 +877,7 @@
     for (j = 0; j < eosd_surface_count; j++)
         eosd_surfaces[j].in_use = 0;
 
-    for (i = img; i; i = i->next) {
+    for (i = img; i; i = eosd_image_next(imgs)) {
         // Try to reuse a suitable surface
         found = -1;
         for (j = 0; j < eosd_surface_count; j++) {
@@ -927,7 +928,7 @@
 
 eosd_skip_upload:
     eosd_render_count = 0;
-    for (i = img; i; i = i->next) {
+    for (i = eosd_image_first(imgs); i; i = eosd_image_next(imgs)) {
         // Render dest, color, etc.
         eosd_targets[eosd_render_count].color.alpha = 1.0 - ((i->color >>  0) & 0xff) / 255.0;
         eosd_targets[eosd_render_count].color.blue  =       ((i->color >>  8) & 0xff) / 255.0;
@@ -1400,7 +1401,7 @@
         draw_eosd();
         return VO_TRUE;
     case VOCTRL_GET_EOSD_RES: {
-        mp_eosd_res_t *r = data;
+        struct mp_eosd_settings *r = data;
         r->mt = r->mb = r->ml = r->mr = 0;
         r->srcw = vid_width; r->srch = vid_height;
         if (vo_fs) {