summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-03-04 00:28:10 +0100
committerwm4 <wm4@nowhere>2014-03-04 00:28:10 +0100
commit5606cf29482b096df7a6b4b515c9ecb3d40fdf89 (patch)
tree94445a6a8ffe27ccaed6c39677f1478a37950580
parent43e997ca07f43598f49e1a0f1f3c52e08a9179f3 (diff)
downloadmpv-5606cf29482b096df7a6b4b515c9ecb3d40fdf89.tar.bz2
mpv-5606cf29482b096df7a6b4b515c9ecb3d40fdf89.tar.xz
sub: use new FFmpeg API to check MicroDVD FPS
Before this, it wasn't possible to distinguish MicroDVD subtitles without FPS header, and subtitles with FPS header equal to FFmpeg's fallback FPS.
-rw-r--r--demux/demux_lavf.c18
-rw-r--r--demux/demux_subreader.c2
-rw-r--r--demux/stheader.h3
-rw-r--r--sub/dec_sub.c8
4 files changed, 21 insertions, 10 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index d85e4b8095..cc503383ea 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -461,11 +461,19 @@ static void handle_stream(demuxer_t *demuxer, int i)
sh_sub->w = codec->width;
sh_sub->h = codec->height;
- // Hack for MicroDVD: if time_base matches the ffmpeg microdvd reader's
- // default FPS (23.976), assume the MicroDVD file did not declare a
- // FPS, and the MicroDVD file uses frame based timing.
- if (codec->time_base.num == 125 && codec->time_base.den == 2997)
- sh_sub->frame_based = true;
+ if (matches_avinputformat_name(priv, "microdvd")) {
+ AVRational r;
+ if (av_opt_get_q(avfc, "subfps", AV_OPT_SEARCH_CHILDREN, &r) >= 0) {
+ // File headers don't have a FPS set.
+ if (r.num < 1 || r.den < 1)
+ sh_sub->frame_based = av_q2d(av_inv_q(codec->time_base));
+ } else {
+ // Older libavcodec versions. If the FPS matches the microdvd
+ // reader's default, assume it uses frame based timing.
+ if (codec->time_base.num == 125 && codec->time_base.den == 2997)
+ sh_sub->frame_based = 23.976;
+ }
+ }
break;
}
case AVMEDIA_TYPE_ATTACHMENT: {
diff --git a/demux/demux_subreader.c b/demux/demux_subreader.c
index 1fa449d7f0..d72cc209c9 100644
--- a/demux/demux_subreader.c
+++ b/demux/demux_subreader.c
@@ -1361,7 +1361,7 @@ static int d_open_file(struct demuxer *demuxer, enum demux_check check)
p->sh = new_sh_stream(demuxer, STREAM_SUB);
p->sh->codec = sd->codec;
- p->sh->sub->frame_based = !sd->sub_uses_time;
+ p->sh->sub->frame_based = sd->sub_uses_time ? 0 : 23.976;
p->sh->sub->is_utf8 = sr.args.utf16 != 0; // converted from utf-16 -> utf-8
add_sub_data(demuxer, sd);
diff --git a/demux/stheader.h b/demux/stheader.h
index 177bf50b39..573d6ac3c6 100644
--- a/demux/stheader.h
+++ b/demux/stheader.h
@@ -88,7 +88,8 @@ typedef struct sh_sub {
unsigned char *extradata; // extra header data passed from demuxer
int extradata_len;
int w, h; // mp4 vobsubs
- int frame_based; // timestamps are frame-based
+ double frame_based; // timestamps are frame-based (and this is the
+ // fallback framerate used for timestamps)
bool is_utf8; // if false, subtitle packet charset is unknown
struct ass_track *track; // loaded by libass
struct dec_sub *dec_sub; // decoder context
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index fdb8d8f648..0a62e52a15 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -464,9 +464,11 @@ bool sub_read_all_packets(struct dec_sub *sub, struct sh_stream *sh)
double sub_speed = 1.0;
- // 23.976 FPS is used as default timebase for frame based formats
- if (sub->video_fps && sh->sub->frame_based)
- sub_speed *= 23.976 / sub->video_fps;
+ 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;