[MPlayer-dev-eng] [PATCH] Simplify and factorize EOSD code

Nicolas George nicolas.george at normalesup.org
Wed Feb 25 16:29:38 CET 2009


Hi.

The attached patch the EOSD code in order to, hopefully, simplify it and
reduce code duplication.

Here is a summary of what the patch actually changes:

- There is a pair of new files, eosd.[ch], with the code specific to the
  EOSD stuff and not ASS in particular.

- There was a littne namespace pollution in libass.

- I assumed that ass_mp.[ch] means "glue between libass and mplayer", and
  moved into it most of the ASS-related variables that were floating around
  everywhere.

- The update of the ASS subtitles, including timestamps arithmetic, is done
  in update_subtitles in mpcommon.c, like the rest of the subtitles stuff.

- In vf_ass, vf_vo, vo_gl and vo_vdpau:

  - The display resolution, instead of being returned to an control message,
    is pushed to the new API when necessary.

  - The rendering of the EOSD is done by pulling the contents from the new
    API when needed and not in reaction of a control message.

I find this structure easier to understand, and it will make it easier to
add what I really want to add: the possibility to add EOSD objects from
other parts of mplayer than libass.

Please note that I could not actually test the vo_vdpau part, having no
NVidia card: it builds and I think it is correct (the changes were small),
though.

Regards,

-- 
  Nicolas George
-------------- next part --------------
 Makefile             |    1 +
 eosd.c               |   58 ++++++++++++++
 eosd.h               |  110 ++++++++++++++++++++++++++
 libass/ass.c         |    6 +-
 libass/ass.h         |    2 +
 libass/ass_mp.c      |  209 +++++++++++++++++++++++++++++++------------------
 libass/ass_mp.h      |   23 +++---
 libmpcodecs/vf_ass.c |   38 ++++-----
 libmpcodecs/vf_vo.c  |   59 +-------------
 libmpdemux/demuxer.c |   20 ++---
 libvo/vo_gl.c        |   39 +++++-----
 libvo/vo_vdpau.c     |   34 ++++----
 mpcommon.c           |    9 ++-
 mplayer.c            |   38 +++++-----
 14 files changed, 410 insertions(+), 236 deletions(-)

diff --git a/Makefile b/Makefile
index 449b058..fa52118 100644
--- a/Makefile
+++ b/Makefile
@@ -37,6 +37,7 @@ SRCS_COMMON = asxparser.c \
               codec-cfg.c \
               cpudetect.c \
               edl.c \
+              eosd.c \
               find_sub.c \
               fmt-conversion.c \
               get_path.c \
diff --git a/eosd.c b/eosd.c
new file mode 100644
index 0000000..c0b423a
--- /dev/null
+++ b/eosd.c
@@ -0,0 +1,58 @@
+#include "eosd.h"
+#include "mpcommon.h"
+#include "libvo/sub.h"
+
+#include "libass/ass_mp.h"
+
+static struct eosd_client *clients, **next_client = &clients;
+static mp_eosd_images_t images;
+
+void eosd_client_register(struct eosd_client *client)
+{
+    client->next = NULL;
+    *next_client = client;
+    next_client = &client->next;
+}
+
+void eosd_client_set_images(ass_image_t *i, int changed)
+{
+    images.imgs = i;
+    images.changed = changed;
+}
+
+void eosd_driver_configure(struct eosd_settings *s)
+{
+    struct eosd_client *c;
+    int inw, inh;
+
+    images.imgs = NULL;
+    images.changed = 2;
+
+    inw = s->width - s->margin_left - s->margin_right;
+    inh = s->height - s->margin_top - s->margin_bottom;
+    if (s->inner_aspect_ratio != 0) {
+        s->pixel_aspect_ratio = s->inner_aspect_ratio * inh / inw;
+        s->outer_aspect_ratio = s->pixel_aspect_ratio * s->width / s->height;
+    } else if (s->outer_aspect_ratio != 0) {
+        s->pixel_aspect_ratio = s->outer_aspect_ratio * s->height / s->width;
+        s->inner_aspect_ratio = s->pixel_aspect_ratio * inw / inh;
+    } else {
+        if(s->pixel_aspect_ratio == 0)
+            s->pixel_aspect_ratio = 1;
+        s->outer_aspect_ratio = s->pixel_aspect_ratio * s->width / s->height;
+        s->inner_aspect_ratio = s->pixel_aspect_ratio * inw / inh;
+    }
+
+    for (c = clients; c != NULL; c = c->next)
+        c->configure(c, s);
+}
+
+mp_eosd_images_t *eosd_driver_get_images(void)
+{
+    return &images;
+}
+
+void eosd_driver_release(void)
+{
+    images.changed = 0;
+}
diff --git a/eosd.h b/eosd.h
new file mode 100644
index 0000000..4ef09f7
--- /dev/null
+++ b/eosd.h
@@ -0,0 +1,110 @@
+/*
+ * EOSD subsystem
+ *
+ * Copyright (C) 2009 Nicolas George
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPLAYER_EOSD_H
+#define MPLAYER_EOSD_H
+
+#include "libass/ass.h"
+
+/**
+ * EOSD driver settings
+ * This structure is used by the EOSD subsystem to notify the clients of the
+ * particular settings of the driver.
+ * The margins are counted inside the rendering area.
+ */
+struct eosd_settings {
+    int width;
+    int height;
+    double inner_aspect_ratio;
+    double outer_aspect_ratio;
+    double pixel_aspect_ratio;
+    int unscaled; ///< if set, the overlay will not be scaled again
+    int margin_left;
+    int margin_right;
+    int margin_top;
+    int margin_bottom;
+};
+
+#define EOSD_SETTINGS_CLEAR ((struct eosd_settings){ })
+
+/**
+ * EOSD client handle
+ * An EOSD client must create and initialize an instance of this structure
+ * in order to be able to register to the EOSD subsystem.
+ */
+struct eosd_client {
+
+    struct eosd_client *next; ///< private
+
+    /**
+     * The configure callback will be called whenever the settings of the
+     * driver are known or change.
+     * When this happens, the EOSD subsystem is blanked, and all objects
+     * must be recomputed and added.
+     */
+    void (*configure)(struct eosd_client *, const struct eosd_settings *);
+
+};
+
+/**
+ * EOSD image list
+ */
+typedef struct {
+    ass_image_t *imgs; ///< linked list of all images
+    int changed; ///< 0: nothing, 1: only coordinates, 2: anything
+} mp_eosd_images_t;
+
+/**
+ * Registers a client to the EOSD subsystem
+ * The eosd_client structure must never be freed.
+ * It can be a part of a bigger structure.
+ */
+void eosd_client_register(struct eosd_client *);
+
+/**
+ * Sets the images to be shown by the EOSD subsystem
+ * @param images linked list of images
+ * @param changed: what changed since the previous call:
+ *                 0: nothing, 1: only coordinates, 2: anything
+ * @note This is (hopefully) a temporary API, since it does not allow to
+ * merge the images from various clients.
+ */
+void eosd_client_set_images(ass_image_t *images, int changed);
+
+/**
+ * Configures the output settings of the driver
+ * Only one aspect ratio must be set, the others will be derived from it.
+ */
+void eosd_driver_configure(struct eosd_settings *);
+
+/**
+ * Gets the list of currently shown objects
+ */
+mp_eosd_images_t *eosd_driver_get_images(void);
+
+/**
+ * Releases the objects after they have been rendered
+ * Currently, this only reset the changed field.
+ */
+void eosd_driver_release(void);
+
+#endif /* MPLAYER_EOSD_H */
diff --git a/libass/ass.c b/libass/ass.c
index 8022dfc..fc900a9 100644
--- a/libass/ass.c
+++ b/libass/ass.c
@@ -324,7 +324,7 @@ static int process_event_tail(ass_track_t* track, ass_event_t* event, char* str,
  * \param track track to apply overrides to
  * The format for overrides is [StyleName.]Field=Value
  */
-void process_force_style(ass_track_t* track) {
+void ass_process_force_style(ass_track_t* track) {
 	char **fs, *eq, *dt, *style, *tname, *token;
 	ass_style_t* target;
 	int sid;
@@ -755,7 +755,7 @@ void ass_process_codec_private(ass_track_t* track, char *data, int size)
 			track->event_format = strdup("Format: Layer, Start, End, Style, Actor, MarginL, MarginR, MarginV, Effect, Text");
 	}
 
-	process_force_style(track);
+	ass_process_force_style(track);
 }
 
 static int check_duplicate_event(ass_track_t* track, int ReadOrder)
@@ -982,7 +982,7 @@ static ass_track_t* parse_memory(ass_library_t* library, char* buf)
 		return 0;
 	}
 
-	process_force_style(track);
+	ass_process_force_style(track);
 
 	return track;
 }
diff --git a/libass/ass.h b/libass/ass.h
index 4bdea3a..0e1dbf0 100644
--- a/libass/ass.h
+++ b/libass/ass.h
@@ -145,6 +145,8 @@ int ass_alloc_event(ass_track_t* track);
  */
 void ass_free_style(ass_track_t* track, int sid);
 
+void ass_process_force_style(ass_track_t* track);
+
 /**
  * \brief delete an event
  * \param track track
diff --git a/libass/ass_mp.c b/libass/ass_mp.c
index 40da63c..6ad28d4 100644
--- a/libass/ass_mp.c
+++ b/libass/ass_mp.c
@@ -26,6 +26,9 @@
 
 #include "mp_msg.h"
 #include "get_path.h"
+#include "libvo/sub.h"
+#include "eosd.h"
+#include "mpcommon.h"
 
 #include "ass.h"
 #include "ass_utils.h"
@@ -36,8 +39,11 @@
 #include <fontconfig/fontconfig.h>
 #endif
 
+static ass_library_t* ass_library;
+static ass_renderer_t* ass_renderer;
+static struct eosd_client ass_eosd_client;
+
 // libass-related command line options
-ass_library_t* ass_library;
 int ass_enabled = 0;
 float ass_font_scale = 1.;
 float ass_line_spacing = 0.;
@@ -71,10 +77,79 @@ extern char* sub_cp;
 static char* sub_cp = 0;
 #endif
 
-void process_force_style(ass_track_t* track);
+static void ass_mp_configure(struct eosd_client *client, const struct eosd_settings *settings) {
+	int hinting;
+	(void)client;
 
-ass_track_t* ass_default_track(ass_library_t* library) {
-	ass_track_t* track = ass_new_track(library);
+	ass_set_frame_size(ass_renderer, settings->width, settings->height);
+	ass_set_margins(ass_renderer, settings->margin_top, settings->margin_bottom, 0, 0);
+	ass_set_use_margins(ass_renderer, ass_use_margins);
+	ass_set_font_scale(ass_renderer, ass_font_scale);
+	if (!settings->unscaled && (ass_hinting & 4))
+		hinting = 0;
+	else
+		hinting = ass_hinting & 3;
+	ass_set_hinting(ass_renderer, hinting);
+	ass_set_line_spacing(ass_renderer, ass_line_spacing);
+	ass_set_aspect_ratio(ass_renderer, settings->outer_aspect_ratio);
+}
+
+static void ass_mp_configure_fonts(void) {
+	char *dir, *path, *family;
+	dir = get_path("fonts");
+	if (font_fontconfig < 0 && sub_font_name) path = strdup(sub_font_name);
+	else if (font_fontconfig < 0 && font_name) path = strdup(font_name);
+	else path = get_path("subfont.ttf");
+	if (font_fontconfig >= 0 && sub_font_name) family = strdup(sub_font_name);
+	else if (font_fontconfig >= 0 && font_name) family = strdup(font_name);
+	else family = 0;
+
+	if (font_fontconfig >= 0)
+		ass_set_fonts(ass_renderer, path, family);
+	else
+		ass_set_fonts_nofc(ass_renderer, path, family);
+
+	free(dir);
+	free(path);
+	free(family);
+}
+
+void ass_mp_library_init(void) {
+	if (ass_enabled) {
+		char* path = get_path("fonts");
+		ass_library = ass_library_init();
+		ass_set_fonts_dir(ass_library, path);
+		ass_set_extract_fonts(ass_library, extract_embedded_fonts);
+		ass_set_style_overrides(ass_library, ass_force_style_list);
+		free(path);
+		ass_eosd_client.configure = ass_mp_configure;
+		eosd_client_register(&ass_eosd_client);
+	}
+}
+
+void ass_mp_library_done(void) {
+	if (ass_library)
+		ass_library_done(ass_library);
+	ass_library = NULL;
+}
+
+void ass_mp_renderer_init(void) {
+	ass_renderer = ass_renderer_init(ass_library);
+	ass_mp_configure_fonts();
+}
+
+void ass_mp_renderer_done(void) {
+	if (ass_renderer)
+		ass_renderer_done(ass_renderer);
+	ass_renderer = NULL;
+}
+
+ass_track_t* ass_mp_new_track(void) {
+	return ass_new_track(ass_library);
+}
+
+ass_track_t* ass_mp_default_track(void) {
+	ass_track_t* track = ass_new_track(ass_library);
 
 	track->track_type = TRACK_TYPE_ASS;
 	track->Timer = 100.;
@@ -122,10 +197,17 @@ ass_track_t* ass_default_track(ass_library_t* library) {
 		style->ScaleY = 1.;
 	}
 
-	process_force_style(track);
+	ass_process_force_style(track);
 	return track;
 }
 
+ass_track_t* ass_mp_read_file(char* fname, char* codepage) {
+	if (ass_enabled)
+		return ass_read_file(ass_library, fname, codepage);
+	else
+		return NULL;
+}
+
 static int check_duplicate_plaintext_event(ass_track_t* track)
 {
 	int i;
@@ -140,6 +222,31 @@ static int check_duplicate_plaintext_event(ass_track_t* track)
 }
 
 /**
+ * \brief Convert subdata to ass_track
+ * \param subdata subtitles struct from subreader
+ * \param fps video framerate
+ * \return newly allocated ass_track, filled with subtitles from subdata
+ */
+ass_track_t* ass_mp_read_subdata(sub_data* subdata, double fps) {
+	ass_track_t* track;
+	int i;
+
+	track = ass_mp_default_track();
+	track->name = subdata->filename ? strdup(subdata->filename) : 0;
+
+	for (i = 0; i < subdata->sub_num; ++i) {
+		int eid = ass_mp_process_subtitle(track, subdata->subtitles + i);
+		if (eid < 0)
+			continue;
+		if (!subdata->sub_uses_time) {
+			track->events[eid].Start *= 100. / fps;
+			track->events[eid].Duration *= 100. / fps;
+		}
+	}
+	return track;
+}
+
+/**
  * \brief Convert subtitle to ass_event_t for the given track
  * \param ass_track_t track
  * \param sub subtitle to convert
@@ -147,7 +254,7 @@ static int check_duplicate_plaintext_event(ass_track_t* track)
  * note: assumes that subtitle is _not_ fps-based; caller must manually correct
  *   Start and Duration in other case.
  **/
-int ass_process_subtitle(ass_track_t* track, subtitle* sub)
+int ass_mp_process_subtitle(ass_track_t* track, subtitle* sub)
 {
         int eid;
         ass_event_t* event;
@@ -194,85 +301,33 @@ int ass_process_subtitle(ass_track_t* track, subtitle* sub)
 	return eid;
 }
 
-
-/**
- * \brief Convert subdata to ass_track
- * \param subdata subtitles struct from subreader
- * \param fps video framerate
- * \return newly allocated ass_track, filled with subtitles from subdata
- */
-ass_track_t* ass_read_subdata(ass_library_t* library, sub_data* subdata, double fps) {
-	ass_track_t* track;
-	int i;
-
-	track = ass_default_track(library);
-	track->name = subdata->filename ? strdup(subdata->filename) : 0;
-
-	for (i = 0; i < subdata->sub_num; ++i) {
-		int eid = ass_process_subtitle(track, subdata->subtitles + i);
-		if (eid < 0)
-			continue;
-		if (!subdata->sub_uses_time) {
-			track->events[eid].Start *= 100. / fps;
-			track->events[eid].Duration *= 100. / fps;
-		}
+void ass_mp_add_font(char* name, char* data, int data_size) {
+	if (ass_enabled && ass_library) {
+		ass_add_font(ass_library, name, data, data_size);
 	}
-	return track;
 }
 
-void ass_configure(ass_renderer_t* priv, int w, int h, int unscaled) {
-	int hinting;
-	ass_set_frame_size(priv, w, h);
-	ass_set_margins(priv, ass_top_margin, ass_bottom_margin, 0, 0);
-	ass_set_use_margins(priv, ass_use_margins);
-	ass_set_font_scale(priv, ass_font_scale);
-	if (!unscaled && (ass_hinting & 4))
-		hinting = 0;
-	else
-		hinting = ass_hinting & 3;
-	ass_set_hinting(priv, hinting);
-	ass_set_line_spacing(priv, ass_line_spacing);
-}
-
-void ass_configure_fonts(ass_renderer_t* priv) {
-	char *dir, *path, *family;
-	dir = get_path("fonts");
-	if (font_fontconfig < 0 && sub_font_name) path = strdup(sub_font_name);
-	else if (font_fontconfig < 0 && font_name) path = strdup(font_name);
-	else path = get_path("subfont.ttf");
-	if (font_fontconfig >= 0 && sub_font_name) family = strdup(sub_font_name);
-	else if (font_fontconfig >= 0 && font_name) family = strdup(font_name);
-	else family = 0;
-
-	if (font_fontconfig >= 0)
-		ass_set_fonts(priv, path, family);
-	else
-		ass_set_fonts_nofc(priv, path, family);
-
-	free(dir);
-	free(path);
-	free(family);
-}
-
-ass_library_t* ass_init(void) {
-	ass_library_t* priv;
-	char* path = get_path("fonts");
-	priv = ass_library_init();
-	ass_set_fonts_dir(priv, path);
-	ass_set_extract_fonts(priv, extract_embedded_fonts);
-	ass_set_style_overrides(priv, ass_force_style_list);
-	free(path);
-	return priv;
+void ass_mp_clear_fonts(void) {
+	if (ass_library)
+		ass_clear_fonts(ass_library);
 }
 
 int ass_force_reload = 0; // flag set if global ass-related settings were changed
 
-ass_image_t* ass_mp_render_frame(ass_renderer_t *priv, ass_track_t* track, long long now, int* detect_change) {
+void ass_mp_update(double pts) {
+	ass_image_t *images;
+	int changed;
+
+	if(ass_track == NULL || ass_renderer == NULL || !sub_visibility) {
+		eosd_client_set_images(NULL, changed);
+		return;
+	}
 	if (ass_force_reload) {
-		ass_set_margins(priv, ass_top_margin, ass_bottom_margin, 0, 0);
-		ass_set_use_margins(priv, ass_use_margins);
-		ass_set_font_scale(priv, ass_font_scale);
+		ass_set_margins(ass_renderer, ass_top_margin, ass_bottom_margin, 0, 0);
+		ass_set_use_margins(ass_renderer, ass_use_margins);
+		ass_set_font_scale(ass_renderer, ass_font_scale);
 		ass_force_reload = 0;
 	}
-	return ass_render_frame(priv, track, now, detect_change);
+	images = ass_render_frame(ass_renderer, ass_track, pts * 1000 + .5, &changed);
+	eosd_client_set_images(images, changed);
 }
diff --git a/libass/ass_mp.h b/libass/ass_mp.h
index 64b411a..54bb5ba 100644
--- a/libass/ass_mp.h
+++ b/libass/ass_mp.h
@@ -27,7 +27,6 @@
 #include "ass_types.h"
 #include "ass.h"
 
-extern ass_library_t* ass_library;
 extern int ass_enabled;
 extern float ass_font_scale;
 extern float ass_line_spacing;
@@ -41,20 +40,22 @@ extern char* ass_border_color;
 extern char* ass_styles_file;
 extern int ass_hinting;
 
-ass_track_t* ass_default_track(ass_library_t* library);
-int ass_process_subtitle(ass_track_t* track, subtitle* sub);
-ass_track_t* ass_read_subdata(ass_library_t* library, sub_data* subdata, double fps);
+void ass_mp_library_init(void);
+void ass_mp_library_done(void);
+void ass_mp_renderer_init(void);
+void ass_mp_renderer_done(void);
 
-void ass_configure(ass_renderer_t* priv, int w, int h, int hinting);
-void ass_configure_fonts(ass_renderer_t* priv);
-ass_library_t* ass_init(void);
+ass_track_t* ass_mp_new_track(void);
+ass_track_t* ass_mp_default_track(void);
+ass_track_t* ass_mp_read_file(char* fname, char* codepage);
+ass_track_t* ass_mp_read_subdata(sub_data* subdata, double fps);
+int ass_mp_process_subtitle(ass_track_t* track, subtitle* sub);
 
-typedef struct {
-	ass_image_t* imgs;
-	int changed;
-} mp_eosd_images_t;
+void ass_mp_add_font(char* name, char* data, int data_size);
+void ass_mp_clear_fonts(void);
 
 extern int ass_force_reload;
+void ass_mp_update(double pts);
 ass_image_t* ass_mp_render_frame(ass_renderer_t *priv, ass_track_t* track, long long now, int* detect_change);
 
 #endif /* LIBASS_MP_H */
diff --git a/libmpcodecs/vf_ass.c b/libmpcodecs/vf_ass.c
index f33aba4..178366b 100644
--- a/libmpcodecs/vf_ass.c
+++ b/libmpcodecs/vf_ass.c
@@ -41,7 +41,7 @@
 #include "m_option.h"
 #include "m_struct.h"
 
-#include "libass/ass.h"
+#include "eosd.h"
 #include "libass/ass_mp.h"
 
 #define _r(c)  ((c)>>24)
@@ -62,8 +62,6 @@ static const struct vf_priv_s {
 	// 0 = insert always
 	int auto_insert;
 
-	ass_renderer_t* ass_priv;
-
 	unsigned char* planes[3];
 	unsigned char* dirty_rows;
 } vf_priv_dflt;
@@ -71,14 +69,12 @@ static const struct vf_priv_s {
 extern int opt_screen_size_x;
 extern int opt_screen_size_y;
 
-extern ass_track_t* ass_track;
-extern float sub_delay;
-extern int sub_visibility;
-
 static int config(struct vf_instance_s* vf,
 	int width, int height, int d_width, int d_height,
 	unsigned int flags, unsigned int outfmt)
 {
+	struct eosd_settings eosd = EOSD_SETTINGS_CLEAR;
+
 	if (outfmt == IMGFMT_IF09) return 0;
 
 	vf->priv->outh = height + ass_top_margin + ass_bottom_margin;
@@ -93,10 +89,15 @@ static int config(struct vf_instance_s* vf,
 	vf->priv->planes[2] = malloc(vf->priv->outw * vf->priv->outh);
 	vf->priv->dirty_rows = malloc(vf->priv->outh);
 	
-	if (vf->priv->ass_priv) {
-		ass_configure(vf->priv->ass_priv, vf->priv->outw, vf->priv->outh, 0);
-		ass_set_aspect_ratio(vf->priv->ass_priv, ((double)d_width) / d_height);
-	}
+	eosd.width = width;
+	eosd.height = height + ass_top_margin + ass_bottom_margin;
+	eosd.margin_left = 0;
+	eosd.margin_right = 0;
+	eosd.margin_top = ass_top_margin;
+	eosd.margin_bottom = ass_bottom_margin;
+	eosd.inner_aspect_ratio = (double)d_width / d_height;
+	eosd.unscaled = 0;
+	eosd_driver_configure(&eosd);
 
 	return vf_next_config(vf, vf->priv->outw, vf->priv->outh, d_width, d_height, flags, outfmt);
 }
@@ -326,12 +327,10 @@ static int render_frame(struct vf_instance_s* vf, mp_image_t *mpi, const ass_ima
 
 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts)
 {
-	ass_image_t* images = 0;
-	if (sub_visibility && vf->priv->ass_priv && ass_track && (pts != MP_NOPTS_VALUE))
-		images = ass_mp_render_frame(vf->priv->ass_priv, ass_track, (pts+sub_delay) * 1000 + .5, NULL);
-	
+	mp_eosd_images_t *images = eosd_driver_get_images();
 	prepare_image(vf, mpi);
-	if (images) render_frame(vf, mpi, images);
+	if (images->imgs) render_frame(vf, mpi, images->imgs);
+	eosd_driver_release();
 
 	return vf_next_put_image(vf, vf->dmpi, pts);
 }
@@ -351,12 +350,9 @@ static int control(vf_instance_t *vf, int request, void *data)
 {
 	switch (request) {
 	case VFCTRL_INIT_EOSD:
-		vf->priv->ass_priv = ass_renderer_init((ass_library_t*)data);
-		if (!vf->priv->ass_priv) return CONTROL_FALSE;
-		ass_configure_fonts(vf->priv->ass_priv);
 		return CONTROL_TRUE;
 	case VFCTRL_DRAW_EOSD:
-		if (vf->priv->ass_priv) return CONTROL_TRUE;
+		return CONTROL_TRUE;
 		break;
 	}
 	return vf_next_control(vf, request, data);
@@ -364,8 +360,6 @@ static int control(vf_instance_t *vf, int request, void *data)
 
 static void uninit(struct vf_instance_s* vf)
 {
-	if (vf->priv->ass_priv)
-		ass_renderer_done(vf->priv->ass_priv);
 	if (vf->priv->planes[1])
 		free(vf->priv->planes[1]);
 	if (vf->priv->planes[2])
diff --git a/libmpcodecs/vf_vo.c b/libmpcodecs/vf_vo.c
index affffa6..02ede49 100644
--- a/libmpcodecs/vf_vo.c
+++ b/libmpcodecs/vf_vo.c
@@ -10,11 +10,7 @@
 
 #include "libvo/video_out.h"
 
-#ifdef CONFIG_ASS
-#include "libass/ass.h"
-#include "libass/ass_mp.h"
-extern ass_track_t* ass_track;
-#endif
+#include "eosd.h"
 
 //===========================================================================//
 
@@ -24,10 +20,6 @@ extern float sub_delay;
 struct vf_priv_s {
     double pts;
     const vo_functions_t *vo;
-#ifdef CONFIG_ASS
-    ass_renderer_t* ass_priv;
-    int prev_visibility;
-#endif
 };
 #define video_out (vf->priv->vo)
 
@@ -67,11 +59,6 @@ static int config(struct vf_instance_s* vf,
     if(config_video_out(video_out,width,height,d_width,d_height,flags,"MPlayer",outfmt))
 	return 0;
 
-#ifdef CONFIG_ASS
-    if (vf->priv->ass_priv)
-	ass_configure(vf->priv->ass_priv, width, height, !!(vf->default_caps & VFCAP_EOSD_UNSCALED));
-#endif
-
     ++vo_config_count;
     return 1;
 }
@@ -113,45 +100,11 @@ static int control(struct vf_instance_s* vf, int request, void* data)
 	if(!vo_config_count) return CONTROL_FALSE; // vo not configured?
 	return (video_out->control(VOCTRL_GET_EQUALIZER, eq->item, &eq->value) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
     }
-#ifdef CONFIG_ASS
-    case VFCTRL_INIT_EOSD:
-    {
-        vf->priv->ass_priv = ass_renderer_init((ass_library_t*)data);
-        if (!vf->priv->ass_priv) return CONTROL_FALSE;
-        ass_configure_fonts(vf->priv->ass_priv);
-        vf->priv->prev_visibility = 0;
-        return CONTROL_TRUE;
-    }
     case VFCTRL_DRAW_EOSD:
-    {
-        mp_eosd_images_t images = {NULL, 2};
-        double pts = vf->priv->pts;
-        if (!vo_config_count || !vf->priv->ass_priv) return CONTROL_FALSE;
-        if (sub_visibility && vf->priv->ass_priv && ass_track && (pts != MP_NOPTS_VALUE)) {
-            mp_eosd_res_t res;
-            memset(&res, 0, sizeof(res));
-            if (video_out->control(VOCTRL_GET_EOSD_RES, &res) == VO_TRUE) {
-                ass_set_frame_size(vf->priv->ass_priv, res.w, res.h);
-                ass_set_margins(vf->priv->ass_priv, res.mt, res.mb, res.ml, res.mr);
-                ass_set_aspect_ratio(vf->priv->ass_priv, (double)res.w / res.h);
-            }
-
-            images.imgs = ass_mp_render_frame(vf->priv->ass_priv, ass_track, (pts+sub_delay) * 1000 + .5, &images.changed);
-            if (!vf->priv->prev_visibility)
-                images.changed = 2;
-            vf->priv->prev_visibility = 1;
-        } else
-            vf->priv->prev_visibility = 0;
-        vf->priv->prev_visibility = sub_visibility;
-        return (video_out->control(VOCTRL_DRAW_EOSD, &images) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
-    }
-#endif
+        return (video_out->control(VOCTRL_DRAW_EOSD, NULL) == VO_TRUE) ? CONTROL_TRUE : CONTROL_FALSE;
     case VFCTRL_GET_PTS:
-    {
-	*(double *)data = vf->priv->pts;
 	return CONTROL_TRUE;
     }
-    }
     // return video_out->control(request,data);
     return CONTROL_UNKNOWN;
 }
@@ -207,13 +160,7 @@ static void draw_slice(struct vf_instance_s* vf,
 
 static void uninit(struct vf_instance_s* vf)
 {
-    if (vf->priv) {
-#ifdef CONFIG_ASS
-        if (vf->priv->ass_priv)
-            ass_renderer_done(vf->priv->ass_priv);
-#endif
-        free(vf->priv);
-    }
+    free(vf->priv);
 }
 //===========================================================================//
 
diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c
index 74bbd8e..420b1ea 100644
--- a/libmpdemux/demuxer.c
+++ b/libmpdemux/demuxer.c
@@ -911,17 +911,15 @@ static demuxer_t *demux_open_stream(stream_t *stream, int file_format,
                sh_video->i_bps / 1024.0f);
     }
 #ifdef CONFIG_ASS
-    if (ass_enabled && ass_library) {
-        for (i = 0; i < MAX_S_STREAMS; ++i) {
-            sh_sub_t *sh = demuxer->s_streams[i];
-            if (sh && sh->type == 'a') {
-                sh->ass_track = ass_new_track(ass_library);
-                if (sh->ass_track && sh->extradata)
-                    ass_process_codec_private(sh->ass_track, sh->extradata,
-                                              sh->extradata_len);
-            } else if (sh && sh->type != 'v')
-                sh->ass_track = ass_default_track(ass_library);
-        }
+    for (i = 0; i < MAX_S_STREAMS; ++i) {
+        sh_sub_t *sh = demuxer->s_streams[i];
+        if (sh && sh->type == 'a') {
+            sh->ass_track = ass_mp_new_track();
+            if (sh->ass_track && sh->extradata)
+                ass_process_codec_private(sh->ass_track, sh->extradata,
+                                          sh->extradata_len);
+        } else if (sh && sh->type != 'v')
+            sh->ass_track = ass_mp_default_track();
     }
 #endif
     return demuxer;
diff --git a/libvo/vo_gl.c b/libvo/vo_gl.c
index 0ffcab0..124407a 100644
--- a/libvo/vo_gl.c
+++ b/libvo/vo_gl.c
@@ -35,8 +35,7 @@
 #include "gui/interface.h"
 #endif
 #include "fastmemcpy.h"
-#include "libass/ass.h"
-#include "libass/ass_mp.h"
+#include "eosd.h"
 
 static const vo_info_t info = 
 {
@@ -145,6 +144,7 @@ static unsigned int slice_height = 1;
 static void redraw(void);
 
 static void resize(int x,int y){
+  struct eosd_settings eosd = EOSD_SETTINGS_CLEAR;
   mp_msg(MSGT_VO, MSGL_V, "[gl] Resize: %dx%d\n",x,y);
   if (WinID >= 0) {
     int top = 0, left = 0, w = x, h = y;
@@ -182,6 +182,22 @@ static void resize(int x,int y){
   vo_osd_changed(OSDTYPE_OSD);
   }
   glClear(GL_COLOR_BUFFER_BIT);
+
+  if (scaled_osd) {
+    eosd.width = image_width;
+    eosd.height = image_height;
+  } else if(vo_fs) {
+    eosd.width = vo_screenwidth;
+    eosd.height = vo_screenheight;
+    eosd.margin_left = eosd.margin_right = ass_border_x;
+    eosd.margin_top = eosd.margin_bottom = ass_border_y;
+  } else {
+    eosd.width = vo_dwidth;
+    eosd.height = vo_dheight;
+  }
+  eosd.unscaled = !scaled_osd;
+  eosd_driver_configure(&eosd);
+
   redraw();
 }
 
@@ -663,6 +679,8 @@ static void do_render(void) {
 }
 
 static void do_render_osd(void) {
+  genEOSD(eosd_driver_get_images());
+  eosd_driver_release();
   if (osdtexCnt > 0 || eosdDispList) {
     // set special rendering parameters
     if (!scaled_osd) {
@@ -1110,23 +1128,6 @@ static int control(uint32_t request, void *data, ...)
   case VOCTRL_DRAW_IMAGE:
     return draw_image(data);
   case VOCTRL_DRAW_EOSD:
-    if (!data)
-      return VO_FALSE;
-    genEOSD(data);
-    return VO_TRUE;
-  case VOCTRL_GET_EOSD_RES:
-    {
-      mp_eosd_res_t *r = data;
-      r->mt = r->mb = r->ml = r->mr = 0;
-      if (scaled_osd) {r->w = image_width; r->h = image_height;}
-      else if (vo_fs) {
-        r->w = vo_screenwidth; r->h = vo_screenheight;
-        r->ml = r->mr = ass_border_x;
-        r->mt = r->mb = ass_border_y;
-      } else {
-        r->w = vo_dwidth; r->h = vo_dheight;
-      }
-    }
     return VO_TRUE;
   case VOCTRL_GUISUPPORT:
     return VO_TRUE;
diff --git a/libvo/vo_vdpau.c b/libvo/vo_vdpau.c
index b06fe31..86a0762 100644
--- a/libvo/vo_vdpau.c
+++ b/libvo/vo_vdpau.c
@@ -50,8 +50,7 @@
 
 #include "libavutil/common.h"
 
-#include "libass/ass.h"
-#include "libass/ass_mp.h"
+#include "eosd.h"
 
 static vo_info_t info = {
     "VDPAU with X11",
@@ -240,6 +239,7 @@ static void resize(void)
     struct vo_rect src_rect;
     struct vo_rect dst_rect;
     struct vo_rect borders;
+    struct eosd_settings eosd = EOSD_SETTINGS_CLEAR;
     calc_src_dst_rects(vid_width, vid_height, &src_rect, &dst_rect, &borders, NULL);
     out_rect_vid.x0 = dst_rect.left;
     out_rect_vid.x1 = dst_rect.right;
@@ -277,6 +277,18 @@ static void resize(void)
             mp_msg(MSGT_VO, MSGL_DBG2, "OUT CREATE: %u\n", output_surfaces[i]);
         }
     }
+
+    if (vo_fs) {
+        eosd.width = vo_screenwidth;
+        eosd.height = vo_screenheight;
+        eosd.margin_left = eosd.margin_right = border_x;
+        eosd.margin_top = eosd.margin_bottom = border_y;
+    } else {
+        eosd.width = vo_dwidth;
+        eosd.height = vo_dheight;
+    }
+    eosd_driver_configure(&eosd);
+
     video_to_output_surface();
     if (visible_buf)
         flip_page();
@@ -732,6 +744,8 @@ static void draw_osd(void)
 {
     mp_msg(MSGT_VO, MSGL_DBG2, "DRAW_OSD\n");
 
+    generate_eosd(eosd_driver_get_images());
+    eosd_driver_release();
     draw_eosd();
     vo_draw_text_ext(vo_dwidth, vo_dheight, border_x, border_y, border_x, border_y,
                      vid_width, vid_height, draw_osd_I8A8);
@@ -1027,7 +1041,7 @@ static int control(uint32_t request, void *data, ...)
         case VOCTRL_BORDER:
             vo_x11_border();
             resize();
-	    return VO_TRUE;
+            return VO_TRUE;
         case VOCTRL_FULLSCREEN:
             vo_x11_fullscreen();
             resize();
@@ -1064,22 +1078,8 @@ static int control(uint32_t request, void *data, ...)
             update_xinerama_info();
             return VO_TRUE;
         case VOCTRL_DRAW_EOSD:
-            if (!data)
-                return VO_FALSE;
-            generate_eosd(data);
             return VO_TRUE;
         case VOCTRL_GET_EOSD_RES: {
-            mp_eosd_res_t *r = data;
-            r->mt = r->mb = r->ml = r->mr = 0;
-            if (vo_fs) {
-                r->w = vo_screenwidth;
-                r->h = vo_screenheight;
-                r->ml = r->mr = border_x;
-                r->mt = r->mb = border_y;
-            } else {
-                r->w = vo_dwidth;
-                r->h = vo_dheight;
-            }
             return VO_TRUE;
         }
     }
diff --git a/mpcommon.c b/mpcommon.c
index 1165fc4..684e4b1 100644
--- a/mpcommon.c
+++ b/mpcommon.c
@@ -11,6 +11,7 @@
 #include "spudec.h"
 #include "version.h"
 #include "vobsub.h"
+#include "eosd.h"
 #ifdef CONFIG_TV_TELETEXT
 #include "stream/tv.h"
 #endif
@@ -98,6 +99,10 @@ void update_subtitles(sh_video_t *sh_video, demux_stream_t *d_dvdsub, int reset)
         }
     }
 
+#ifdef CONFIG_ASS
+    ass_mp_update(sh_video->pts + sub_delay);
+#endif
+
     // DVD sub:
     if (vo_config_count && vo_spudec &&
         (vobsub_id >= 0 || (dvdsub_id >= 0 && type == 'v'))) {
@@ -145,6 +150,8 @@ void update_subtitles(sh_video_t *sh_video, demux_stream_t *d_dvdsub, int reset)
         if (spudec_changed(vo_spudec))
             vo_osd_changed(OSDTYPE_SPU);
     } else if (dvdsub_id >= 0 && (type == 't' || type == 'm' || type == 'a')) {
+        /* The variable is called dvdsub_id, but it is about any
+         * stream-embedded subtitles. */
         double curpts = sh_video->pts + sub_delay;
         double endpts;
         vo_sub = &subs;
@@ -176,7 +183,7 @@ void update_subtitles(sh_video_t *sh_video, demux_stream_t *d_dvdsub, int reset)
                         sub_add_text(&subs, packet, len, endpts);
                         subs.start = pts * 100;
                         subs.end = endpts * 100;
-                        ass_process_subtitle(ass_track, &subs);
+                        ass_mp_process_subtitle(ass_track, &subs);
                     }
                 }
                 continue;
diff --git a/mplayer.c b/mplayer.c
index 1b6a350..433ea35 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -704,7 +704,9 @@ void exit_player_with_rc(exit_reason_t how, int rc){
   free_osd_list();
 
 #ifdef CONFIG_ASS
-  ass_library_done(ass_library);
+  current_module="uninit_ass";
+  ass_mp_renderer_done();
+  ass_mp_library_done();
 #endif
 
   current_module="exit_player";
@@ -1036,14 +1038,13 @@ void add_subtitles(char *filename, float fps, int noerr)
 
     subd = sub_read_file(filename, fps);
 #ifdef CONFIG_ASS
-    if (ass_enabled)
 #ifdef CONFIG_ICONV
-        asst = ass_read_file(ass_library, filename, sub_cp);
+        asst = ass_mp_read_file(filename, sub_cp);
 #else
-        asst = ass_read_file(ass_library, filename, 0);
+        asst = ass_mp_read_file(filename, 0);
 #endif
     if (ass_enabled && subd && !asst)
-        asst = ass_read_subdata(ass_library, subd, fps);
+        asst = ass_mp_read_subdata(subd, fps);
 
     if (!asst && !subd)
 #else
@@ -2195,8 +2196,10 @@ int reinit_video_chain(void) {
   sh_video->vfilter=(void*)append_filters(sh_video->vfilter);
 
 #ifdef CONFIG_ASS
-  if (ass_enabled)
-    ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, ass_library);
+  if (ass_enabled) {
+    ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_INIT_EOSD, NULL);
+    ass_mp_renderer_init();
+  }
 #endif
 
   current_module="init_video_codec";
@@ -2769,7 +2772,7 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){
   vo_init_osd();
 
 #ifdef CONFIG_ASS
-  ass_library = ass_init();
+  ass_mp_library_init();
 #endif
 
 #ifdef HAVE_RTC
@@ -3278,15 +3281,13 @@ if (mpctx->global_sub_size <= mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + dvds
   mpctx->global_sub_size = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + dvdsub_id + 1;
 
 #ifdef CONFIG_ASS
-if (ass_enabled && ass_library) {
-  for (i = 0; i < mpctx->demuxer->num_attachments; ++i) {
-    demux_attachment_t* att = mpctx->demuxer->attachments + i;
-    if (extract_embedded_fonts &&
-        att->name && att->type && att->data && att->data_size &&
-        (strcmp(att->type, "application/x-truetype-font") == 0 ||
-         strcmp(att->type, "application/x-font") == 0))
-      ass_add_font(ass_library, att->name, att->data, att->data_size);
-  }
+for (i = 0; i < mpctx->demuxer->num_attachments; ++i) {
+  demux_attachment_t* att = mpctx->demuxer->attachments + i;
+  if (extract_embedded_fonts &&
+      att->name && att->type && att->data && att->data_size &&
+      (strcmp(att->type, "application/x-truetype-font") == 0 ||
+       strcmp(att->type, "application/x-font") == 0))
+    ass_mp_add_font(att->name, att->data, att->data_size);
 }
 #endif
 
@@ -3945,8 +3946,7 @@ vo_sub_last = vo_sub=NULL;
 subdata=NULL;
 #ifdef CONFIG_ASS
 ass_track = NULL;
-if(ass_library)
-    ass_clear_fonts(ass_library);
+ass_mp_clear_fonts();
 #endif
 
 if(mpctx->eof == PT_NEXT_ENTRY || mpctx->eof == PT_PREV_ENTRY) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20090225/870b472d/attachment.pgp>


More information about the MPlayer-dev-eng mailing list