[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