diff options
Diffstat (limited to 'sub')
-rw-r--r-- | sub/ass_mp.c | 129 | ||||
-rw-r--r-- | sub/ass_mp.h | 9 | ||||
-rw-r--r-- | sub/dec_sub.c | 370 | ||||
-rw-r--r-- | sub/dec_sub.h | 38 | ||||
-rw-r--r-- | sub/find_sub.c | 174 | ||||
-rw-r--r-- | sub/find_subfiles.c | 9 | ||||
-rw-r--r-- | sub/osd_libass.c | 20 | ||||
-rw-r--r-- | sub/sd.h | 74 | ||||
-rw-r--r-- | sub/sd_ass.c | 247 | ||||
-rw-r--r-- | sub/sd_lavc.c | 49 | ||||
-rw-r--r-- | sub/sd_lavc_conv.c | 165 | ||||
-rw-r--r-- | sub/sd_microdvd.c | 346 | ||||
-rw-r--r-- | sub/sd_movtext.c | 55 | ||||
-rw-r--r-- | sub/sd_spu.c | 102 | ||||
-rw-r--r-- | sub/sd_srt.c (renamed from sub/subassconvert.c) | 277 | ||||
-rw-r--r-- | sub/spudec.c | 33 | ||||
-rw-r--r-- | sub/spudec.h | 4 | ||||
-rw-r--r-- | sub/sub.c | 64 | ||||
-rw-r--r-- | sub/sub.h | 26 | ||||
-rw-r--r-- | sub/subassconvert.h | 27 | ||||
-rw-r--r-- | sub/subreader.c | 334 | ||||
-rw-r--r-- | sub/subreader.h | 24 |
22 files changed, 1456 insertions, 1120 deletions
diff --git a/sub/ass_mp.c b/sub/ass_mp.c index 497e307953..258dd57688 100644 --- a/sub/ass_mp.c +++ b/sub/ass_mp.c @@ -38,7 +38,9 @@ #include "stream/stream.h" #include "core/options.h" -void mp_ass_set_style(ASS_Style *style, struct osd_style_opts *opts) +// res_y should be track->PlayResY +// It determines scaling of font sizes and more. +void mp_ass_set_style(ASS_Style *style, int res_y, struct osd_style_opts *opts) { if (opts->font) { free(style->FontName); @@ -46,9 +48,9 @@ void mp_ass_set_style(ASS_Style *style, struct osd_style_opts *opts) style->treat_fontname_as_pattern = 1; } - // libass_font_size = FontSize * (window_height / MP_ASS_FONT_PLAYRESY) - // scale translates parameters from PlayResY=720 to MP_ASS_FONT_PLAYRESY - double scale = MP_ASS_FONT_PLAYRESY / 720.0; + // libass_font_size = FontSize * (window_height / res_y) + // scale translates parameters from PlayResY=720 to res_y + double scale = res_y / 720.0; style->FontSize = opts->font_size * scale; style->PrimaryColour = MP_ASS_COLOR(opts->color); @@ -74,129 +76,40 @@ void mp_ass_set_style(ASS_Style *style, struct osd_style_opts *opts) #endif } -ASS_Track *mp_ass_default_track(ASS_Library *library, struct MPOpts *opts) +// Add default styles, if the track does not have any styles yet. +// Apply style overrides if the user provides any. +void mp_ass_add_default_styles(ASS_Track *track, struct MPOpts *opts) { - ASS_Track *track = ass_new_track(library); - - track->track_type = TRACK_TYPE_ASS; - track->Timer = 100.; - track->PlayResY = MP_ASS_FONT_PLAYRESY; - track->WrapStyle = 0; - if (opts->ass_styles_file && opts->ass_style_override) - ass_read_styles(track, opts->ass_styles_file, sub_cp); + ass_read_styles(track, opts->ass_styles_file, opts->sub_cp); if (track->n_styles == 0) { + if (!track->PlayResY) { + track->PlayResY = MP_ASS_FONT_PLAYRESY; + track->PlayResX = track->PlayResY * 4 / 3; + } track->Kerning = true; int sid = ass_alloc_style(track); track->default_style = sid; ASS_Style *style = track->styles + sid; style->Name = strdup("Default"); style->Alignment = 2; - mp_ass_set_style(style, opts->sub_text_style); + mp_ass_set_style(style, track->PlayResY, opts->sub_text_style); } if (opts->ass_style_override) 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_Events for the given track - * \param track 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. - **/ -static int ass_process_subtitle(ASS_Track *track, subtitle *sub) +ASS_Track *mp_ass_default_track(ASS_Library *library, struct MPOpts *opts) { - 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 = track->default_style; - - 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; -} - + ASS_Track *track = ass_new_track(library); -/** - * \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 *mp_ass_read_subdata(ASS_Library *library, struct MPOpts *opts, - sub_data *subdata, double fps) -{ - ASS_Track *track; - int i; + track->track_type = TRACK_TYPE_ASS; + track->Timer = 100.; - track = mp_ass_default_track(library, opts); - track->name = subdata->filename ? strdup(subdata->filename) : 0; + mp_ass_add_default_styles(track, opts); - 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; } @@ -244,7 +157,7 @@ void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts, if (opts->ass_style_override) { set_use_margins = opts->ass_use_margins; #if LIBASS_VERSION >= 0x01010000 - set_sub_pos = 100 - sub_pos; + set_sub_pos = 100 - opts->sub_pos; #endif set_line_spacing = opts->ass_line_spacing; set_font_scale = opts->sub_scale; diff --git a/sub/ass_mp.h b/sub/ass_mp.h index 0f67b17fe1..9f40b34166 100644 --- a/sub/ass_mp.h +++ b/sub/ass_mp.h @@ -27,7 +27,8 @@ #include "config.h" #include "subreader.h" -// font sizes and explicit tags in subassconvert.c assume this size (?) +// This is probably arbitrary. +// sd_lavc_conv might indirectly still assume this PlayResY, though. #define MP_ASS_FONT_PLAYRESY 288 #define MP_ASS_RGBA(r, g, b, a) \ @@ -44,11 +45,11 @@ struct MPOpts; struct mp_osd_res; struct osd_style_opts; -void mp_ass_set_style(ASS_Style *style, struct osd_style_opts *opts); +void mp_ass_set_style(ASS_Style *style, int res_y, struct osd_style_opts *opts); + +void mp_ass_add_default_styles(ASS_Track *track, struct MPOpts *opts); ASS_Track *mp_ass_default_track(ASS_Library *library, struct MPOpts *opts); -ASS_Track *mp_ass_read_subdata(ASS_Library *library, struct MPOpts *opts, - sub_data *subdata, double fps); ASS_Track *mp_ass_read_stream(ASS_Library *library, const char *fname, char *charset); diff --git a/sub/dec_sub.c b/sub/dec_sub.c index d3cedea80d..b72630470c 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -22,105 +22,351 @@ #include "config.h" #include "demux/stheader.h" -#include "sub/sd.h" -#include "sub/sub.h" -#include "sub/dec_sub.h" +#include "sd.h" +#include "sub.h" +#include "dec_sub.h" +#include "subreader.h" #include "core/options.h" +#include "core/mp_msg.h" extern const struct sd_functions sd_ass; extern const struct sd_functions sd_lavc; +extern const struct sd_functions sd_spu; +extern const struct sd_functions sd_movtext; +extern const struct sd_functions sd_srt; +extern const struct sd_functions sd_microdvd; +extern const struct sd_functions sd_lavc_conv; -bool is_text_sub(const char *t) +static const struct sd_functions *sd_list[] = { +#ifdef CONFIG_ASS + &sd_ass, +#endif + &sd_lavc, + &sd_spu, + &sd_movtext, + &sd_srt, + &sd_microdvd, + &sd_lavc_conv, + NULL +}; + +#define MAX_NUM_SD 3 + +struct dec_sub { + struct MPOpts *opts; + struct sd init_sd; + + struct sd *sd[MAX_NUM_SD]; + int num_sd; +}; + +struct dec_sub *sub_create(struct MPOpts *opts) { - return t && (is_ass_sub(t) || - strcmp(t, "text") == 0 || - strcmp(t, "subrip") == 0 || - strcmp(t, "mov_text") == 0); + struct dec_sub *sub = talloc_zero(NULL, struct dec_sub); + sub->opts = opts; + return sub; } -bool is_ass_sub(const char *t) +static void sub_uninit(struct dec_sub *sub) { - return t && (strcmp(t, "ass") == 0 || - strcmp(t, "ssa") == 0); + sub_reset(sub); + for (int n = 0; n < sub->num_sd; n++) { + if (sub->sd[n]->driver->uninit) + sub->sd[n]->driver->uninit(sub->sd[n]); + talloc_free(sub->sd[n]); + } + sub->num_sd = 0; } -bool is_dvd_sub(const char *t) +void sub_destroy(struct dec_sub *sub) { - return t && strcmp(t, "dvd_subtitle") == 0; + if (!sub) + return; + sub_uninit(sub); + talloc_free(sub); } -void sub_init(struct sh_sub *sh, struct osd_state *osd) +bool sub_is_initialized(struct dec_sub *sub) { - struct MPOpts *opts = sh->opts; + return !!sub->num_sd; +} - assert(!osd->sh_sub); - if (sd_lavc.probe(sh)) - sh->sd_driver = &sd_lavc; -#ifdef CONFIG_ASS - if (opts->ass_enabled && sd_ass.probe(sh)) - sh->sd_driver = &sd_ass; -#endif - if (sh->sd_driver) { - if (sh->sd_driver->init(sh, osd) < 0) +struct sd *sub_get_last_sd(struct dec_sub *sub) +{ + return sub->num_sd ? sub->sd[sub->num_sd - 1] : NULL; +} + +void sub_set_video_res(struct dec_sub *sub, int w, int h) +{ + sub->init_sd.sub_video_w = w; + sub->init_sd.sub_video_h = h; +} + +void sub_set_extradata(struct dec_sub *sub, void *data, int data_len) +{ + sub->init_sd.extradata = data_len ? talloc_memdup(sub, data, data_len) : NULL; + sub->init_sd.extradata_len = data_len; +} + +void sub_set_ass_renderer(struct dec_sub *sub, struct ass_library *ass_library, + struct ass_renderer *ass_renderer) +{ + sub->init_sd.ass_library = ass_library; + sub->init_sd.ass_renderer = ass_renderer; +} + +static void print_chain(struct dec_sub *sub) +{ + mp_msg(MSGT_OSD, MSGL_V, "Subtitle filter chain: "); + for (int n = 0; n < sub->num_sd; n++) { + struct sd *sd = sub->sd[n]; + mp_msg(MSGT_OSD, MSGL_V, "%s%s (%s)", n > 0 ? " -> " : "", + sd->driver->name, sd->codec); + } + mp_msg(MSGT_OSD, MSGL_V, "\n"); +} + +// Subtitles read with subreader.c +static void read_sub_data(struct dec_sub *sub, struct sub_data *subdata) +{ + assert(sub_accept_packets_in_advance(sub)); + char *temp = NULL; + + struct sd *sd = sub_get_last_sd(sub); + + sd->no_remove_duplicates = true; + + for (int i = 0; i < subdata->sub_num; i++) { + subtitle *st = &subdata->subtitles[i]; + // subdata is in 10 ms ticks, pts is in seconds + double t = subdata->sub_uses_time ? 0.01 : (1 / subdata->fallback_fps); + + int len = 0; + for (int j = 0; j < st->lines; j++) + len += st->text[j] ? strlen(st->text[j]) : 0; + + len += 2 * st->lines; // '\N', including the one after the last line + len += 6; // {\anX} + len += 1; // '\0' + + if (talloc_get_size(temp) < len) { + talloc_free(temp); + temp = talloc_array(NULL, char, len); + } + + char *p = temp; + char *end = p + len; + + if (st->alignment) + p += snprintf(p, end - p, "{\\an%d}", st->alignment); + + for (int j = 0; j < st->lines; j++) + p += snprintf(p, end - p, "%s\\N", st->text[j]); + + if (st->lines > 0) + p -= 2; // remove last "\N" + *p = 0; + + struct demux_packet pkt = {0}; + pkt.pts = st->start * t; + pkt.duration = (st->end - st->start) * t; + pkt.buffer = temp; + pkt.len = strlen(temp); + + sub_decode(sub, &pkt); + } + + // Hack for broken FFmpeg packet format: make sd_ass keep the subtitle + // events on reset(), even though broken FFmpeg ASS packets were received + // (from sd_lavc_conv.c). Normally, these events are removed on seek/reset, + // but this is obviously unwanted in this case. + if (sd && sd->driver->fix_events) + sd->driver->fix_events(sd); + + sd->no_remove_duplicates = false; + + talloc_free(temp); +} + +static int sub_init_decoder(struct dec_sub *sub, struct sd *sd) +{ + sd->driver = NULL; + for (int n = 0; sd_list[n]; n++) { + if (sd_list[n]->supports_format(sd->codec)) { + sd->driver = sd_list[n]; + break; + } + } + + if (!sd->driver) + return -1; + + if (sd->driver->init(sd) < 0) + return -1; + + return 0; +} + +void sub_init_from_sh(struct dec_sub *sub, struct sh_sub *sh) +{ + assert(!sub->num_sd); + + if (sh->extradata && !sub->init_sd.extradata) + sub_set_extradata(sub, sh->extradata, sh->extradata_len); + struct sd init_sd = sub->init_sd; + init_sd.codec = sh->gsh->codec; + init_sd.ass_track = sh->track; + + while (sub->num_sd < MAX_NUM_SD) { + struct sd *sd = talloc(NULL, struct sd); + *sd = init_sd; + sd->opts = sub->opts; + if (sub_init_decoder(sub, sd) < 0) { + talloc_free(sd); + break; + } + sub->sd[sub->num_sd] = sd; + sub->num_sd++; + // Try adding new converters until a decoder is reached + if (sd->driver->get_bitmaps || sd->driver->get_text) { + print_chain(sub); + if (sh->sub_data) + read_sub_data(sub, sh->sub_data); return; - osd->sh_sub = sh; - osd->switch_sub_id++; - sh->initialized = true; - sh->active = true; + } + init_sd = (struct sd) { + .codec = sd->output_codec, + .converted_from = sd->codec, + .extradata = sd->output_extradata, + .extradata_len = sd->output_extradata_len, + .ass_library = sub->init_sd.ass_library, + .ass_renderer = sub->init_sd.ass_renderer, + }; + } + + sub_uninit(sub); + mp_msg(MSGT_OSD, MSGL_ERR, "Could not find subtitle decoder for format '%s'.\n", + sh->gsh->codec ? sh->gsh->codec : "<unknown>"); +} + +bool sub_accept_packets_in_advance(struct dec_sub *sub) +{ + // Converters are assumed to always accept packets in advance + struct sd *sd = sub_get_last_sd(sub); + return sd && sd->driver->accept_packets_in_advance; +} + +static void decode_next(struct dec_sub *sub, int n, struct demux_packet *packet) +{ + struct sd *sd = sub->sd[n]; + sd->driver->decode(sd, packet); + if (n + 1 >= sub->num_sd || !sd->driver->get_converted) + return; + while (1) { + struct demux_packet *next = + sd->driver->get_converted ? sd->driver->get_converted(sd) : NULL; + if (!next) + break; + decode_next(sub, n + 1, next); } } -void sub_decode(struct sh_sub *sh, struct osd_state *osd, void *data, - int data_len, double pts, double duration) +void sub_decode(struct dec_sub *sub, struct demux_packet *packet) { - if (sh->active && sh->sd_driver->decode) - sh->sd_driver->decode(sh, osd, data, data_len, pts, duration); + if (sub->num_sd > 0) + decode_next(sub, 0, packet); } -void sub_get_bitmaps(struct osd_state *osd, struct mp_osd_res dim, double pts, +void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, double pts, struct sub_bitmaps *res) { - struct MPOpts *opts = osd->opts; + struct MPOpts *opts = sub->opts; + struct sd *sd = sub_get_last_sd(sub); *res = (struct sub_bitmaps) {0}; - if (!opts->sub_visibility || !osd->sh_sub || !osd->sh_sub->active) { - /* Change ID in case we just switched from visible subtitles - * to current state. Hopefully, unnecessarily claiming that - * things may have changed is harmless for empty contents. - * Increase osd-> values ahead so that _next_ returned id - * is also guaranteed to differ from this one. - */ - osd->switch_sub_id++; - } else { - if (osd->sh_sub->sd_driver->get_bitmaps) - osd->sh_sub->sd_driver->get_bitmaps(osd->sh_sub, osd, dim, pts, res); + if (sd && opts->sub_visibility) { + if (sd->driver->get_bitmaps) + sd->driver->get_bitmaps(sd, dim, pts, res); } +} - res->bitmap_id += osd->switch_sub_id; - res->bitmap_pos_id += osd->switch_sub_id; - osd->switch_sub_id = 0; +bool sub_has_get_text(struct dec_sub *sub) +{ + struct sd *sd = sub_get_last_sd(sub); + return sd && sd->driver->get_text; } -void sub_reset(struct sh_sub *sh, struct osd_state *osd) +char *sub_get_text(struct dec_sub *sub, double pts) { - if (sh->active && sh->sd_driver->reset) - sh->sd_driver->reset(sh, osd); + struct MPOpts *opts = sub->opts; + struct sd *sd = sub_get_last_sd(sub); + char *text = NULL; + if (sd && opts->sub_visibility) { + if (sd->driver->get_text) + text = sd->driver->get_text(sd, pts); + } + return text; } -void sub_switchoff(struct sh_sub *sh, struct osd_state *osd) +void sub_reset(struct dec_sub *sub) { - if (sh->active && sh->sd_driver->switch_off) { - assert(osd->sh_sub == sh); - sh->sd_driver->switch_off(sh, osd); - osd->sh_sub = NULL; + for (int n = 0; n < sub->num_sd; n++) { + if (sub->sd[n]->driver->reset) + sub->sd[n]->driver->reset(sub->sd[n]); } - sh->active = false; } -void sub_uninit(struct sh_sub *sh) +#define MAX_PACKETS 10 +#define MAX_BYTES 10000 + +struct sd_conv_buffer { + struct demux_packet pkt[MAX_PACKETS]; + int num_pkt; + int read_pkt; + char buffer[MAX_BYTES]; + int cur_buffer; +}; + +void sd_conv_add_packet(struct sd *sd, void *data, int data_len, double pts, + double duration) +{ + if (!sd->sd_conv_buffer) + sd->sd_conv_buffer = talloc_zero(sd, struct sd_conv_buffer); + struct sd_conv_buffer *buf = sd->sd_conv_buffer; + if (buf->num_pkt >= MAX_PACKETS || buf->cur_buffer + data_len + 1 > MAX_BYTES) + goto out_of_space; + if (buf->read_pkt == buf->num_pkt) + sd_conv_def_reset(sd); + assert(buf->read_pkt == 0); // no mixing of reading/adding allowed + struct demux_packet *pkt = &buf->pkt[buf->num_pkt++]; + *pkt = (struct demux_packet) { + .buffer = &buf->buffer[buf->cur_buffer], + .len = data_len, + .pts = pts, + .duration = duration, + }; + memcpy(pkt->buffer, data, data_len); + pkt->buffer[data_len] = 0; + buf->cur_buffer += data_len + 1; + return; + +out_of_space: + mp_msg(MSGT_OSD, MSGL_ERR, "Subtitle too big.\n"); +} + +struct demux_packet *sd_conv_def_get_converted(struct sd *sd) { - assert (!sh->active); - if (sh->initialized && sh->sd_driver->uninit) - sh->sd_driver->uninit(sh); - sh->initialized = false; + struct sd_conv_buffer *buf = sd->sd_conv_buffer; + if (buf && buf->read_pkt < buf->num_pkt) + return &buf->pkt[buf->read_pkt++]; + return NULL; +} + +void sd_conv_def_reset(struct sd *sd) +{ + struct sd_conv_buffer *buf = sd->sd_conv_buffer; + if (buf) { + buf->read_pkt = buf->num_pkt = 0; + buf->cur_buffer = 0; + } } diff --git a/sub/dec_sub.h b/sub/dec_sub.h index 593eac1e03..805a87ef5c 100644 --- a/sub/dec_sub.h +++ b/sub/dec_sub.h @@ -9,26 +9,36 @@ struct sh_sub; struct ass_track; struct MPOpts; +struct demux_packet; +struct ass_library; +struct ass_renderer; -bool is_text_sub(const char *t); -bool is_ass_sub(const char *t); -bool is_dvd_sub(const char *t); +struct dec_sub; +struct sd; -void sub_decode(struct sh_sub *sh, struct osd_state *osd, void *data, - int data_len, double pts, double duration); -void sub_get_bitmaps(struct osd_state *osd, struct mp_osd_res dim, double pts, +struct dec_sub *sub_create(struct MPOpts *opts); +void sub_destroy(struct dec_sub *sub); + +void sub_set_video_res(struct dec_sub *sub, int w, int h); +void sub_set_extradata(struct dec_sub *sub, void *data, int data_len); +void sub_set_ass_renderer(struct dec_sub *sub, struct ass_library *ass_library, + struct ass_renderer *ass_renderer); +void sub_init_from_sh(struct dec_sub *sub, struct sh_sub *sh); + +bool sub_is_initialized(struct dec_sub *sub); + +bool sub_accept_packets_in_advance(struct dec_sub *sub); +void sub_decode(struct dec_sub *sub, struct demux_packet *packet); +void sub_get_bitmaps(struct dec_sub *sub, struct mp_osd_res dim, double pts, struct sub_bitmaps *res); -void sub_init(struct sh_sub *sh, struct osd_state *osd); -void sub_reset(struct sh_sub *sh, struct osd_state *osd); -void sub_switchoff(struct sh_sub *sh, struct osd_state *osd); -void sub_uninit(struct sh_sub *sh); +bool sub_has_get_text(struct dec_sub *sub); +char *sub_get_text(struct dec_sub *sub, double pts); +void sub_reset(struct dec_sub *sub); -struct sh_sub *sd_ass_create_from_track(struct ass_track *track, - bool vsfilter_aspect, - struct MPOpts *opts); +struct sd *sub_get_last_sd(struct dec_sub *sub); #ifdef CONFIG_ASS -struct ass_track *sub_get_ass_track(struct osd_state *osd); +struct ass_track *sub_get_ass_track(struct dec_sub *sub); #endif #endif diff --git a/sub/find_sub.c b/sub/find_sub.c deleted file mode 100644 index 5feef2a3e9..0000000000 --- a/sub/find_sub.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * .SUB - * - * 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 "config.h" - -#include <stdio.h> - -#include "sub.h" -#include "subreader.h" - -#include "core/mp_msg.h" -#include "core/mp_common.h" -#include "core/mplayer.h" - -static int current_sub=0; - -//static subtitle* subtitles=NULL; -static int nosub_range_start=-1; -static int nosub_range_end=-1; -static const sub_data *last_sub_data = NULL; - -void step_sub(sub_data *subd, float pts, int movement) { - subtitle *subs; - int key; - - if (subd == NULL) return; - subs = subd->subtitles; - key = (pts+sub_delay) * (subd->sub_uses_time ? 100 : sub_fps); - - /* Tell the OSD subsystem that the OSD contents will change soon */ - vo_osd_changed(OSDTYPE_SUBTITLE); - - /* If we are moving forward, don't count the next (current) subtitle - * if we haven't displayed it yet. Same when moving other direction. - */ - if (movement > 0 && key < subs[current_sub].start) - movement--; - if (movement < 0 && key >= subs[current_sub].end) - movement++; - - /* Never move beyond first or last subtitle. */ - if (current_sub+movement < 0) - movement = 0-current_sub; - if (current_sub+movement >= subd->sub_num) - movement = subd->sub_num - current_sub - 1; - - current_sub += movement; - sub_delay = subs[current_sub].start / (subd->sub_uses_time ? 100 : sub_fps) - pts; -} - -void find_sub(struct MPContext *mpctx, sub_data* subd,int key){ - subtitle *subs; - subtitle *new_sub = NULL; - int i,j; - - if ( !subd || subd->sub_num == 0) return; - subs = subd->subtitles; - - if (last_sub_data != subd) { - // Sub data changed, reset nosub range. - last_sub_data = subd; - nosub_range_start = -1; - nosub_range_end = -1; - } - - if(vo_sub){ - if(key>=vo_sub->start && key<=vo_sub->end) return; // OK! - } else { - if(key>nosub_range_start && key<nosub_range_end) return; // OK! - } - // sub changed! - - /* Tell the OSD subsystem that the OSD contents will change soon */ - vo_osd_changed(OSDTYPE_SUBTITLE); - - if(key<=0){ - // no sub here - goto update; - } - -// printf("\r---- sub changed ----\n"); - - // check next sub. - if(current_sub>=0 && current_sub+1 < subd->sub_num){ - if(key>subs[current_sub].end && key<subs[current_sub+1].start){ - // no sub - nosub_range_start=subs[current_sub].end; - nosub_range_end=subs[current_sub+1].start; - goto update; - } - // next sub? - ++current_sub; - new_sub=&subs[current_sub]; - if(key>=new_sub->start && key<=new_sub->end) goto update; // OK! - } - -// printf("\r---- sub log search... ----\n"); - - // use logarithmic search: - i=0; - j = subd->sub_num - 1; -// printf("Searching %d in %d..%d\n",key,subs[i].start,subs[j].end); - while(j>=i){ - current_sub=(i+j+1)/2; - new_sub=&subs[current_sub]; - if(key<new_sub->start) j=current_sub-1; - else if(key>new_sub->end) i=current_sub+1; - else goto update; // found! - } -// if(key>=new_sub->start && key<=new_sub->end) return; // OK! - - // check where are we... - if(key<new_sub->start){ - if(current_sub<=0){ - // before the first sub - nosub_range_start=key-1; // tricky - nosub_range_end=new_sub->start; -// printf("FIRST... key=%d end=%d \n",key,new_sub->start); - new_sub=NULL; - goto update; - } - --current_sub; - if(key>subs[current_sub].end && key<subs[current_sub+1].start){ - // no sub - nosub_range_start=subs[current_sub].end; - nosub_range_end=subs[current_sub+1].start; -// printf("No sub... 1 \n"); - new_sub=NULL; - goto update; - } - printf("HEH???? "); - } else { - if(key<=new_sub->end) printf("JAJJ! "); else - if(current_sub+1 >= subd->sub_num){ - // at the end? - nosub_range_start=new_sub->end; - nosub_range_end=0x7FFFFFFF; // MAXINT -// printf("END!?\n"); - new_sub=NULL; - goto update; - } else - if(key>subs[current_sub].end && key<subs[current_sub+1].start){ - // no sub - nosub_range_start=subs[current_sub].end; - nosub_range_end=subs[current_sub+1].start; -// printf("No sub... 2 \n"); - new_sub=NULL; - goto update; - } - } - - mp_msg(MSGT_FIXME,MSGL_FIXME,"SUB ERROR: %d ? %d --- %d [%d] \n",key,(int)new_sub->start,(int)new_sub->end,current_sub); - - new_sub=NULL; // no sub here -update: - set_osd_subtitle(mpctx, new_sub); -} diff --git a/sub/find_subfiles.c b/sub/find_subfiles.c index e77015114b..3519e5c386 100644 --- a/sub/find_subfiles.c +++ b/sub/find_subfiles.c @@ -12,7 +12,6 @@ #include "core/mp_common.h" #include "sub/find_subfiles.h" #include "sub/sub.h" -#include "sub/subreader.h" static struct bstr strip_ext(struct bstr str) { @@ -119,9 +118,9 @@ static void append_dir_subtitles(struct MPOpts *opts, // does it end with a subtitle extension? #ifdef CONFIG_ICONV #ifdef CONFIG_ENCA - int i = (sub_cp && strncasecmp(sub_cp, "enca", 4) != 0) ? 3 : 0; + int i = (opts->sub_cp && strncasecmp(opts->sub_cp, "enca", 4) != 0) ? 3 : 0; #else - int i = sub_cp ? 3 : 0; + int i = opts->sub_cp ? 3 : 0; #endif #else int i = 0; @@ -153,12 +152,12 @@ static void append_dir_subtitles(struct MPOpts *opts, if (!prio && bstrcmp(tmp_fname_trim, f_fname_trim) == 0) prio = 3; // matches the movie name if (!prio && bstr_find(tmp_fname_trim, f_fname_trim) >= 0 - && sub_match_fuzziness >= 1) + && opts->sub_match_fuzziness >= 1) prio = 2; |