From 94c062d0d2a7369ffbde17a330aeb05973e44ab9 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 5 Dec 2015 23:56:28 +0100 Subject: sub: move subtitle FPS adjustment to sd_ass.c I feel like it's better there. Note that there is no reduced functionality, as bitmaps subs (i.e. not handled by sd_ass.c) were never fully read on init, and thus never went through sub_read_all_packets(). On the other hand, this might lead to confusion, as --sub-fps etc. will now also affect muxed subtitles (which makes not much sense). --- sub/dec_sub.c | 33 ++++----------------------------- sub/sd.h | 4 ++++ sub/sd_ass.c | 22 ++++++++++++++++++++-- 3 files changed, 28 insertions(+), 31 deletions(-) (limited to 'sub') diff --git a/sub/dec_sub.c b/sub/dec_sub.c index 4372c0be91..9e697af521 100644 --- a/sub/dec_sub.c +++ b/sub/dec_sub.c @@ -62,7 +62,6 @@ struct dec_sub { struct MPOpts *opts; struct sd init_sd; - double video_fps; const char *charset; struct sd *sd[MAX_NUM_SD]; @@ -143,7 +142,7 @@ void sub_set_video_res(struct dec_sub *sub, int w, int h) void sub_set_video_fps(struct dec_sub *sub, double fps) { pthread_mutex_lock(&sub->lock); - sub->video_fps = fps; + sub->init_sd.video_fps = fps; pthread_mutex_unlock(&sub->lock); } @@ -208,6 +207,7 @@ void sub_init_from_sh(struct dec_sub *sub, struct sh_stream *sh) sub_set_extradata(sub, sh->extradata, sh->extradata_size); struct sd init_sd = sub->init_sd; init_sd.codec = sh->codec; + init_sd.sh = sh; while (sub->num_sd < MAX_NUM_SD) { struct sd *sd = talloc(NULL, struct sd); @@ -230,6 +230,8 @@ void sub_init_from_sh(struct dec_sub *sub, struct sh_stream *sh) .converted_from = sd->codec, .extradata = sd->output_extradata, .extradata_len = sd->output_extradata_len, + .sh = sub->init_sd.sh, + .video_fps = sub->init_sd.video_fps, .ass_library = sub->init_sd.ass_library, .ass_renderer = sub->init_sd.ass_renderer, .ass_lock = sub->init_sd.ass_lock, @@ -335,17 +337,6 @@ static const char *guess_sub_cp(struct mp_log *log, void *talloc_ctx, return guess; } -static void multiply_timings(struct packet_list *subs, double factor) -{ - for (int n = 0; n < subs->num_packets; n++) { - struct demux_packet *pkt = subs->packets[n]; - if (pkt->pts != MP_NOPTS_VALUE) - pkt->pts *= factor; - if (pkt->duration > 0) - pkt->duration *= factor; - } -} - static void add_sub_list(struct dec_sub *sub, int at, struct packet_list *subs) { struct sd *sd = sub_get_last_sd(sub); @@ -431,22 +422,6 @@ bool sub_read_all_packets(struct dec_sub *sub, struct sh_stream *sh) if (sub->charset && sub->charset[0] && !mp_charset_is_utf8(sub->charset)) MP_INFO(sub, "Using subtitle charset: %s\n", sub->charset); - double sub_speed = 1.0; - - if (sub->video_fps && sh->sub->frame_based > 0) { - MP_VERBOSE(sub, "Frame based format, dummy FPS: %f, video FPS: %f\n", - sh->sub->frame_based, sub->video_fps); - sub_speed *= sh->sub->frame_based / sub->video_fps; - } - - if (opts->sub_fps && sub->video_fps) - sub_speed *= opts->sub_fps / sub->video_fps; - - sub_speed *= opts->sub_speed; - - if (sub_speed != 1.0) - multiply_timings(subs, sub_speed); - add_sub_list(sub, preprocess, subs); pthread_mutex_unlock(&sub->lock); diff --git a/sub/sd.h b/sub/sd.h index 9e6b1eb0ec..cae3e156ee 100644 --- a/sub/sd.h +++ b/sub/sd.h @@ -22,6 +22,8 @@ struct sd { char *extradata; int extradata_len; + struct sh_stream *sh; + // Set to !=NULL if the input packets are being converted from another // format. const char *converted_from; @@ -30,6 +32,8 @@ struct sd { // the resolution of the VO, nor does it have to be the OSD resolution. int sub_video_w, sub_video_h; + double video_fps; + // Shared renderer for ASS - done to avoid reloading embedded fonts. struct ass_library *ass_library; struct ass_renderer *ass_renderer; diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 11943613f9..261d0e1b2d 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -29,6 +29,7 @@ #include "options/options.h" #include "common/common.h" #include "common/msg.h" +#include "demux/stheader.h" #include "video/csputils.h" #include "video/mp_image.h" #include "dec_sub.h" @@ -46,6 +47,7 @@ struct sd_ass_priv { char last_text[500]; struct mp_image_params video_params; struct mp_image_params last_params; + double sub_speed; }; static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts); @@ -117,6 +119,19 @@ static int init(struct sd *sd) pthread_mutex_unlock(sd->ass_lock); + ctx->sub_speed = 1.0; + + if (sd->video_fps && sd->sh && sd->sh->sub->frame_based > 0) { + MP_VERBOSE(sd, "Frame based format, dummy FPS: %f, video FPS: %f\n", + sd->sh->sub->frame_based, sd->video_fps); + ctx->sub_speed *= sd->sh->sub->frame_based / sd->video_fps; + } + + if (opts->sub_fps && sd->video_fps) + ctx->sub_speed *= opts->sub_fps / sd->video_fps; + + ctx->sub_speed *= opts->sub_speed; + return 0; } @@ -251,6 +266,8 @@ static long long find_timestamp(struct sd *sd, double pts) if (pts == MP_NOPTS_VALUE) return 0; + pts /= priv->sub_speed; + long long ts = llrint(pts * 1000); if (!sd->opts->sub_fix_timing) @@ -528,10 +545,11 @@ static int control(struct sd *sd, enum sd_ctrl cmd, void *arg) switch (cmd) { case SD_CTRL_SUB_STEP: { double *a = arg; - long long res = ass_step_sub(ctx->ass_track, a[0] * 1000 + 0.5, a[1]); + long long ts = llrint(a[0] * (1000.0 / ctx->sub_speed)); + long long res = ass_step_sub(ctx->ass_track, ts, a[1]); if (!res) return false; - a[0] = res / 1000.0; + a[0] = res / (1000.0 / ctx->sub_speed); return true; } case SD_CTRL_SET_VIDEO_PARAMS: -- cgit v1.2.3