Mercurial > mplayer.hg
changeset 32461:bc43cf7638e6
Move ass_mp.[ch] to the sub directory.
author | cigaes |
---|---|
date | Wed, 27 Oct 2010 17:08:36 +0000 |
parents | d80bbc5868de |
children | 6e7c20b56c89 |
files | Makefile ass_mp.c ass_mp.h command.c gui/cfg.c gui/interface.c libmpcodecs/vf_ass.c libmpdemux/demux_mkv.c libmpdemux/demuxer.c libmpdemux/demuxer.h libvo/vo_gl.c libvo/vo_vdpau.c mencoder.c mpcommon.c mpcommon.h mplayer.c sub/ass_mp.c sub/ass_mp.h sub/eosd.c sub/subreader.c |
diffstat | 20 files changed, 466 insertions(+), 466 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Wed Oct 27 17:03:26 2010 +0000 +++ b/Makefile Wed Oct 27 17:08:36 2010 +0000 @@ -128,7 +128,7 @@ SRCS_COMMON-$(LADSPA) += libaf/af_ladspa.c SRCS_COMMON-$(LIBA52) += libmpcodecs/ad_liba52.c SRCS_COMMON-$(LIBASS) += libmpcodecs/vf_ass.c \ - ass_mp.c \ + sub/ass_mp.c \ subassconvert.c \ SRCS_COMMON-$(LIBASS_INTERNAL) += libass/ass.c \
--- a/ass_mp.c Wed Oct 27 17:03:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,380 +0,0 @@ -/* - * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> - * - * 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. - */ - -#include <inttypes.h> -#include <string.h> -#include <stdlib.h> - -#include "mp_msg.h" -#include "mpcommon.h" -#include "path.h" -#include "sub/subreader.h" - -#include "ass_mp.h" -#include "sub/eosd.h" -#include "mpcommon.h" -#include "libvo/sub.h" -#include "help_mp.h" -#include "libvo/font_load.h" -#include "stream/stream.h" - -#ifdef CONFIG_FONTCONFIG -#include <fontconfig/fontconfig.h> -#endif - -// libass-related command line options -ASS_Library* ass_library; -int ass_enabled = 0; -float ass_font_scale = 1.; -float ass_line_spacing = 0.; -int ass_top_margin = 0; -int ass_bottom_margin = 0; -int extract_embedded_fonts = 1; -char **ass_force_style_list = NULL; -int ass_use_margins = 0; -char* ass_color = NULL; -char* ass_border_color = NULL; -char* ass_styles_file = NULL; -int ass_hinting = ASS_HINTING_NATIVE + 4; // native hinting for unscaled osd - -ASS_Track* ass_default_track(ASS_Library* library) { - ASS_Track* track = ass_new_track(library); - - track->track_type = TRACK_TYPE_ASS; - track->Timer = 100.; - track->PlayResY = 288; - track->WrapStyle = 0; - - if (ass_styles_file) - ass_read_styles(track, ass_styles_file, sub_cp); - - if (track->n_styles == 0) { - ASS_Style* style; - int sid; - double fs; - uint32_t c1, c2; - - sid = ass_alloc_style(track); - style = track->styles + sid; - style->Name = strdup("Default"); - style->FontName = (font_fontconfig >= 0 && sub_font_name) ? strdup(sub_font_name) : (font_fontconfig >= 0 && font_name) ? strdup(font_name) : strdup("Sans"); - style->treat_fontname_as_pattern = 1; - - fs = track->PlayResY * text_font_scale_factor / 100.; - // approximate autoscale coefficients - if (subtitle_autoscale == 2) - fs *= 1.3; - else if (subtitle_autoscale == 3) - fs *= 1.4; - style->FontSize = fs; - - if (ass_color) c1 = strtoll(ass_color, NULL, 16); - else c1 = 0xFFFF0000; - if (ass_border_color) c2 = strtoll(ass_border_color, NULL, 16); - else c2 = 0x00000000; - - style->PrimaryColour = c1; - style->SecondaryColour = c1; - style->OutlineColour = c2; - style->BackColour = 0x00000000; - style->BorderStyle = 1; - style->Alignment = 2; - style->Outline = 2; - style->MarginL = 10; - style->MarginR = 10; - style->MarginV = 5; - style->ScaleX = 1.; - style->ScaleY = 1.; - } - - ass_process_force_style(track); - return track; -} - -static int check_duplicate_plaintext_event(ASS_Track* track) -{ - int i; - ASS_Event* evt = track->events + track->n_events - 1; - - for (i = 0; i<track->n_events - 1; ++i) // ignoring last event, it is the one we are comparing with - if (track->events[i].Start == evt->Start && - track->events[i].Duration == evt->Duration && - strcmp(track->events[i].Text, evt->Text) == 0) - return 1; - return 0; -} - -/** - * \brief Convert subtitle to ASS_Event for the given track - * \param track ASS_Track - * \param sub subtitle to convert - * \return event id - * note: assumes that subtitle is _not_ fps-based; caller must manually correct - * Start and Duration in other case. - **/ -int ass_process_subtitle(ASS_Track* track, subtitle* sub) -{ - int eid; - ASS_Event* event; - int len = 0, j; - char* p; - char* end; - - eid = ass_alloc_event(track); - event = track->events + eid; - - event->Start = sub->start * 10; - event->Duration = (sub->end - sub->start) * 10; - event->Style = 0; - - for (j = 0; j < sub->lines; ++j) - len += sub->text[j] ? strlen(sub->text[j]) : 0; - - len += 2 * sub->lines; // '\N', including the one after the last line - len += 6; // {\anX} - len += 1; // '\0' - - event->Text = malloc(len); - end = event->Text + len; - p = event->Text; - - if (sub->alignment) - p += snprintf(p, end - p, "{\\an%d}", sub->alignment); - - for (j = 0; j < sub->lines; ++j) - p += snprintf(p, end - p, "%s\\N", sub->text[j]); - - if (sub->lines > 0) p-=2; // remove last "\N" - *p = 0; - - if (check_duplicate_plaintext_event(track)) { - ass_free_event(track, eid); - track->n_events--; - return -1; - } - - mp_msg(MSGT_ASS, MSGL_V, "plaintext event at %" PRId64 ", +%" PRId64 ": %s \n", - (int64_t)event->Start, (int64_t)event->Duration, event->Text); - - 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* ass_read_subdata(ASS_Library* library, sub_data* subdata, double fps) { - ASS_Track* 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; - } - } - return track; -} - -ASS_Track* ass_read_stream(ASS_Library* library, const char *fname, char *charset) { - char *buf = NULL; - ASS_Track *track; - size_t sz = 0; - size_t buf_alloc = 0; - stream_t *fd; - - fd = open_stream(fname, NULL, NULL); - if (!fd) { - mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FopenFailed, fname); - return NULL; - } - if (fd->end_pos > STREAM_BUFFER_SIZE) - /* read entire file if size is known */ - buf_alloc = fd->end_pos; - for (;;) { - int i; - if (buf_alloc >= 100*1024*1024) { - mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_RefusingToLoadSubtitlesLargerThan100M, fname); - sz = 0; - break; - } - if (buf_alloc < sz + STREAM_BUFFER_SIZE) - buf_alloc += STREAM_BUFFER_SIZE; - buf = realloc(buf, buf_alloc + 1); - i = stream_read(fd, buf + sz, buf_alloc - sz); - if (i <= 0) break; - sz += i; - } - free_stream(fd); - if (!sz) { - free(buf); - return NULL; - } - buf[sz] = 0; - buf = realloc(buf, sz + 1); - track = ass_read_memory(library, buf, sz, charset); - if (track) { - free(track->name); - track->name = strdup(fname); - } - free(buf); - return track; -} - -void ass_configure(ASS_Renderer* 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* 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; - - ass_set_fonts(priv, path, family, font_fontconfig, NULL, 1); - - free(dir); - free(path); - free(family); -} - -static void message_callback(int level, const char *format, va_list va, void *ctx) -{ - int n; - char *str; - va_list dst; - - va_copy(dst, va); - n = vsnprintf(NULL, 0, format, va); - if (n > 0 && (str = malloc(n + 1))) { - vsnprintf(str, n + 1, format, dst); - mp_msg(MSGT_ASS, level, "[ass] %s\n", str); - free(str); - } -} - -ASS_Library* ass_init(void) { - ASS_Library* priv; - char* path = get_path("fonts"); - priv = ass_library_init(); - ass_set_message_cb(priv, message_callback, NULL); - 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; -} - -int ass_force_reload = 0; // flag set if global ass-related settings were changed - -ASS_Image* ass_mp_render_frame(ASS_Renderer *priv, ASS_Track* track, long long now, int* detect_change) { - 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_force_reload = 0; - } - 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 || !src->initialized) { - 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); - src->initialized = 1; - } - 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); - if (!eosd_registered(&eosd_ass)) - eosd_register(&eosd_ass); -}
--- a/ass_mp.h Wed Oct 27 17:03:26 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> - * - * 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_ASS_MP_H -#define MPLAYER_ASS_MP_H - -#include "config.h" -#include <stdint.h> - -#include "sub/subreader.h" -#if defined(CONFIG_ASS_INTERNAL) || !defined(CONFIG_ASS) -#include "libass/ass.h" -#else -#include <ass/ass.h> -#endif - -extern ASS_Library* ass_library; -extern int ass_enabled; -extern float ass_font_scale; -extern float ass_line_spacing; -extern int ass_top_margin; -extern int ass_bottom_margin; -extern int extract_embedded_fonts; -extern char **ass_force_style_list; -extern int ass_use_margins; -extern char* ass_color; -extern char* ass_border_color; -extern char* ass_styles_file; -extern int ass_hinting; - -ASS_Track* ass_default_track(ASS_Library* library); -int ass_process_subtitle(ASS_Track* track, subtitle* sub); -ASS_Track* ass_read_subdata(ASS_Library* library, sub_data* subdata, double fps); -ASS_Track* ass_read_stream(ASS_Library* library, const char *fname, char *charset); - -void ass_configure(ASS_Renderer* priv, int w, int h, int hinting); -void ass_configure_fonts(ASS_Renderer* priv); -ASS_Library* ass_init(void); - -typedef struct { - ASS_Image* imgs; - int changed; -} EOSD_ImageList; - -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/command.c Wed Oct 27 17:03:26 2010 +0000 +++ b/command.c Wed Oct 27 17:08:36 2010 +0000 @@ -58,7 +58,7 @@ #include "stream/stream_dvd.h" #endif #include "stream/stream_dvdnav.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "m_struct.h" #include "libmenu/menu.h" #include "gui/interface.h"
--- a/gui/cfg.c Wed Oct 27 17:03:26 2010 +0000 +++ b/gui/cfg.c Wed Oct 27 17:08:36 2010 +0000 @@ -21,7 +21,7 @@ #include <string.h> #include "config.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "mp_msg.h" #include "help_mp.h" #include "mixer.h"
--- a/gui/interface.c Wed Oct 27 17:03:26 2010 +0000 +++ b/gui/interface.c Wed Oct 27 17:08:36 2010 +0000 @@ -33,7 +33,7 @@ #include "mplayer/play.h" #include "access_mpcontext.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "app.h" #include "cfg.h" #include "help_mp.h"
--- a/libmpcodecs/vf_ass.c Wed Oct 27 17:03:26 2010 +0000 +++ b/libmpcodecs/vf_ass.c Wed Oct 27 17:08:36 2010 +0000 @@ -40,7 +40,7 @@ #include "m_option.h" #include "m_struct.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "sub/eosd.h" #define _r(c) ((c)>>24)
--- a/libmpdemux/demux_mkv.c Wed Oct 27 17:03:26 2010 +0000 +++ b/libmpdemux/demux_mkv.c Wed Oct 27 17:08:36 2010 +0000 @@ -35,7 +35,7 @@ #include "matroska.h" #include "demux_real.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "mp_msg.h" #include "help_mp.h"
--- a/libmpdemux/demuxer.c Wed Oct 27 17:03:26 2010 +0000 +++ b/libmpdemux/demuxer.c Wed Oct 27 17:08:36 2010 +0000 @@ -48,7 +48,7 @@ #ifdef CONFIG_ASS #include "libass/ass.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #endif #ifdef CONFIG_FFMPEG
--- a/libmpdemux/demuxer.h Wed Oct 27 17:03:26 2010 +0000 +++ b/libmpdemux/demuxer.h Wed Oct 27 17:08:36 2010 +0000 @@ -26,7 +26,7 @@ #include "stream/stream.h" #ifdef CONFIG_ASS -#include "ass_mp.h" +#include "sub/ass_mp.h" #endif #include "m_option.h"
--- a/libvo/vo_gl.c Wed Oct 27 17:03:26 2010 +0000 +++ b/libvo/vo_gl.c Wed Oct 27 17:08:36 2010 +0000 @@ -27,7 +27,7 @@ #include <math.h> #include "config.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "mp_msg.h" #include "subopt-helper.h" #include "video_out.h"
--- a/libvo/vo_vdpau.c Wed Oct 27 17:03:26 2010 +0000 +++ b/libvo/vo_vdpau.c Wed Oct 27 17:08:36 2010 +0000 @@ -35,7 +35,7 @@ #include <stdio.h> #include "config.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "mp_msg.h" #include "video_out.h" #include "video_out_internal.h"
--- a/mencoder.c Wed Oct 27 17:03:26 2010 +0000 +++ b/mencoder.c Wed Oct 27 17:08:36 2010 +0000 @@ -82,7 +82,7 @@ #include "stream/stream_dvd.h" #endif #include "stream/stream_dvdnav.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "codec-cfg.h" #include "edl.h" #include "help_mp.h"
--- a/mpcommon.c Wed Oct 27 17:03:26 2010 +0000 +++ b/mpcommon.c Wed Oct 27 17:08:36 2010 +0000 @@ -46,7 +46,7 @@ double sub_last_pts = -303; #ifdef CONFIG_ASS -#include "ass_mp.h" +#include "sub/ass_mp.h" ASS_Track* ass_track = 0; // current track to render #endif
--- a/mpcommon.h Wed Oct 27 17:03:26 2010 +0000 +++ b/mpcommon.h Wed Oct 27 17:08:36 2010 +0000 @@ -23,7 +23,7 @@ #include "m_option.h" #include "sub/subreader.h" #include "libmpdemux/demuxer.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" struct sh_video;
--- a/mplayer.c Wed Oct 27 17:03:26 2010 +0000 +++ b/mplayer.c Wed Oct 27 17:08:36 2010 +0000 @@ -96,7 +96,7 @@ #include "stream/stream_radio.h" #include "stream/tv.h" #include "access_mpcontext.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "cfg-mplayer-def.h" #include "codec-cfg.h" #include "command.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sub/ass_mp.c Wed Oct 27 17:08:36 2010 +0000 @@ -0,0 +1,380 @@ +/* + * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> + * + * 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. + */ + +#include <inttypes.h> +#include <string.h> +#include <stdlib.h> + +#include "mp_msg.h" +#include "mpcommon.h" +#include "path.h" +#include "sub/subreader.h" + +#include "sub/ass_mp.h" +#include "sub/eosd.h" +#include "mpcommon.h" +#include "libvo/sub.h" +#include "help_mp.h" +#include "libvo/font_load.h" +#include "stream/stream.h" + +#ifdef CONFIG_FONTCONFIG +#include <fontconfig/fontconfig.h> +#endif + +// libass-related command line options +ASS_Library* ass_library; +int ass_enabled = 0; +float ass_font_scale = 1.; +float ass_line_spacing = 0.; +int ass_top_margin = 0; +int ass_bottom_margin = 0; +int extract_embedded_fonts = 1; +char **ass_force_style_list = NULL; +int ass_use_margins = 0; +char* ass_color = NULL; +char* ass_border_color = NULL; +char* ass_styles_file = NULL; +int ass_hinting = ASS_HINTING_NATIVE + 4; // native hinting for unscaled osd + +ASS_Track* ass_default_track(ASS_Library* library) { + ASS_Track* track = ass_new_track(library); + + track->track_type = TRACK_TYPE_ASS; + track->Timer = 100.; + track->PlayResY = 288; + track->WrapStyle = 0; + + if (ass_styles_file) + ass_read_styles(track, ass_styles_file, sub_cp); + + if (track->n_styles == 0) { + ASS_Style* style; + int sid; + double fs; + uint32_t c1, c2; + + sid = ass_alloc_style(track); + style = track->styles + sid; + style->Name = strdup("Default"); + style->FontName = (font_fontconfig >= 0 && sub_font_name) ? strdup(sub_font_name) : (font_fontconfig >= 0 && font_name) ? strdup(font_name) : strdup("Sans"); + style->treat_fontname_as_pattern = 1; + + fs = track->PlayResY * text_font_scale_factor / 100.; + // approximate autoscale coefficients + if (subtitle_autoscale == 2) + fs *= 1.3; + else if (subtitle_autoscale == 3) + fs *= 1.4; + style->FontSize = fs; + + if (ass_color) c1 = strtoll(ass_color, NULL, 16); + else c1 = 0xFFFF0000; + if (ass_border_color) c2 = strtoll(ass_border_color, NULL, 16); + else c2 = 0x00000000; + + style->PrimaryColour = c1; + style->SecondaryColour = c1; + style->OutlineColour = c2; + style->BackColour = 0x00000000; + style->BorderStyle = 1; + style->Alignment = 2; + style->Outline = 2; + style->MarginL = 10; + style->MarginR = 10; + style->MarginV = 5; + style->ScaleX = 1.; + style->ScaleY = 1.; + } + + ass_process_force_style(track); + return track; +} + +static int check_duplicate_plaintext_event(ASS_Track* track) +{ + int i; + ASS_Event* evt = track->events + track->n_events - 1; + + for (i = 0; i<track->n_events - 1; ++i) // ignoring last event, it is the one we are comparing with + if (track->events[i].Start == evt->Start && + track->events[i].Duration == evt->Duration && + strcmp(track->events[i].Text, evt->Text) == 0) + return 1; + return 0; +} + +/** + * \brief Convert subtitle to ASS_Event for the given track + * \param track ASS_Track + * \param sub subtitle to convert + * \return event id + * note: assumes that subtitle is _not_ fps-based; caller must manually correct + * Start and Duration in other case. + **/ +int ass_process_subtitle(ASS_Track* track, subtitle* sub) +{ + int eid; + ASS_Event* event; + int len = 0, j; + char* p; + char* end; + + eid = ass_alloc_event(track); + event = track->events + eid; + + event->Start = sub->start * 10; + event->Duration = (sub->end - sub->start) * 10; + event->Style = 0; + + for (j = 0; j < sub->lines; ++j) + len += sub->text[j] ? strlen(sub->text[j]) : 0; + + len += 2 * sub->lines; // '\N', including the one after the last line + len += 6; // {\anX} + len += 1; // '\0' + + event->Text = malloc(len); + end = event->Text + len; + p = event->Text; + + if (sub->alignment) + p += snprintf(p, end - p, "{\\an%d}", sub->alignment); + + for (j = 0; j < sub->lines; ++j) + p += snprintf(p, end - p, "%s\\N", sub->text[j]); + + if (sub->lines > 0) p-=2; // remove last "\N" + *p = 0; + + if (check_duplicate_plaintext_event(track)) { + ass_free_event(track, eid); + track->n_events--; + return -1; + } + + mp_msg(MSGT_ASS, MSGL_V, "plaintext event at %" PRId64 ", +%" PRId64 ": %s \n", + (int64_t)event->Start, (int64_t)event->Duration, event->Text); + + 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* ass_read_subdata(ASS_Library* library, sub_data* subdata, double fps) { + ASS_Track* 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; + } + } + return track; +} + +ASS_Track* ass_read_stream(ASS_Library* library, const char *fname, char *charset) { + char *buf = NULL; + ASS_Track *track; + size_t sz = 0; + size_t buf_alloc = 0; + stream_t *fd; + + fd = open_stream(fname, NULL, NULL); + if (!fd) { + mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FopenFailed, fname); + return NULL; + } + if (fd->end_pos > STREAM_BUFFER_SIZE) + /* read entire file if size is known */ + buf_alloc = fd->end_pos; + for (;;) { + int i; + if (buf_alloc >= 100*1024*1024) { + mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_RefusingToLoadSubtitlesLargerThan100M, fname); + sz = 0; + break; + } + if (buf_alloc < sz + STREAM_BUFFER_SIZE) + buf_alloc += STREAM_BUFFER_SIZE; + buf = realloc(buf, buf_alloc + 1); + i = stream_read(fd, buf + sz, buf_alloc - sz); + if (i <= 0) break; + sz += i; + } + free_stream(fd); + if (!sz) { + free(buf); + return NULL; + } + buf[sz] = 0; + buf = realloc(buf, sz + 1); + track = ass_read_memory(library, buf, sz, charset); + if (track) { + free(track->name); + track->name = strdup(fname); + } + free(buf); + return track; +} + +void ass_configure(ASS_Renderer* 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* 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; + + ass_set_fonts(priv, path, family, font_fontconfig, NULL, 1); + + free(dir); + free(path); + free(family); +} + +static void message_callback(int level, const char *format, va_list va, void *ctx) +{ + int n; + char *str; + va_list dst; + + va_copy(dst, va); + n = vsnprintf(NULL, 0, format, va); + if (n > 0 && (str = malloc(n + 1))) { + vsnprintf(str, n + 1, format, dst); + mp_msg(MSGT_ASS, level, "[ass] %s\n", str); + free(str); + } +} + +ASS_Library* ass_init(void) { + ASS_Library* priv; + char* path = get_path("fonts"); + priv = ass_library_init(); + ass_set_message_cb(priv, message_callback, NULL); + 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; +} + +int ass_force_reload = 0; // flag set if global ass-related settings were changed + +ASS_Image* ass_mp_render_frame(ASS_Renderer *priv, ASS_Track* track, long long now, int* detect_change) { + 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_force_reload = 0; + } + 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 || !src->initialized) { + 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); + src->initialized = 1; + } + 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); + if (!eosd_registered(&eosd_ass)) + eosd_register(&eosd_ass); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sub/ass_mp.h Wed Oct 27 17:08:36 2010 +0000 @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2006 Evgeniy Stepanov <eugeni.stepanov@gmail.com> + * + * 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_ASS_MP_H +#define MPLAYER_ASS_MP_H + +#include "config.h" +#include <stdint.h> + +#include "sub/subreader.h" +#if defined(CONFIG_ASS_INTERNAL) || !defined(CONFIG_ASS) +#include "libass/ass.h" +#else +#include <ass/ass.h> +#endif + +extern ASS_Library* ass_library; +extern int ass_enabled; +extern float ass_font_scale; +extern float ass_line_spacing; +extern int ass_top_margin; +extern int ass_bottom_margin; +extern int extract_embedded_fonts; +extern char **ass_force_style_list; +extern int ass_use_margins; +extern char* ass_color; +extern char* ass_border_color; +extern char* ass_styles_file; +extern int ass_hinting; + +ASS_Track* ass_default_track(ASS_Library* library); +int ass_process_subtitle(ASS_Track* track, subtitle* sub); +ASS_Track* ass_read_subdata(ASS_Library* library, sub_data* subdata, double fps); +ASS_Track* ass_read_stream(ASS_Library* library, const char *fname, char *charset); + +void ass_configure(ASS_Renderer* priv, int w, int h, int hinting); +void ass_configure_fonts(ASS_Renderer* priv); +ASS_Library* ass_init(void); + +typedef struct { + ASS_Image* imgs; + int changed; +} EOSD_ImageList; + +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/sub/eosd.c Wed Oct 27 17:03:26 2010 +0000 +++ b/sub/eosd.c Wed Oct 27 17:08:36 2010 +0000 @@ -23,7 +23,7 @@ #include "libmpcodecs/vf.h" #include "libvo/video_out.h" #include "libvo/sub.h" -#include "ass_mp.h" +#include "sub/ass_mp.h" #include "sub/eosd.h" static struct mp_eosd_source *sources;