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).
This commit is contained in:
wm4 2015-12-05 23:56:28 +01:00
parent 04934e86dd
commit 94c062d0d2
3 changed files with 28 additions and 31 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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: