diff options
author | wm4 <wm4@nowhere> | 2016-03-05 00:13:30 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-03-05 00:16:23 +0100 |
commit | 740b7013ba827ce5a9d48138af5bd2e8f5d54710 (patch) | |
tree | a5fc53e734201691b72f30b47a3401add5a7dc0c | |
parent | cda0dc907094bcc75ac00f24f05b5a577961e47e (diff) |
sd_ass: always handle subtitles with unknown duration
Deals with broken mkv subtitle tracks generated by tvheadend. The subs
are srt, but without packet durations.
We need this logic for CCs anyway. CCs in particular will be unaffected
by this change because they are also marked with unknown duration. It
could be that there are actual demuxers outputting CCs - in this case,
we rely on the fact that they don't set a (meaningless) packet duration
(or we'd have to work that around).
-rw-r--r-- | sub/sd_ass.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 4426c2ebab..59336ff0ec 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -238,6 +238,8 @@ static bool check_packet_seen(struct sd *sd, int64_t pos) return false; } +#define UNKNOWN_DURATION (INT_MAX / 1000) + static void decode(struct sd *sd, struct demux_packet *packet) { struct sd_ass_priv *ctx = sd->priv; @@ -246,13 +248,22 @@ static void decode(struct sd *sd, struct demux_packet *packet) if (!sd->opts->sub_clear_on_seek && packet->pos >= 0 && check_packet_seen(sd, packet->pos)) return; + if (packet->duration < 0) { + if (!ctx->duration_unknown) { + MP_WARN(sd, "Subtitle with unknown duration.\n"); + ctx->duration_unknown = true; + } + packet->duration = UNKNOWN_DURATION; + } char **r = lavc_conv_decode(ctx->converter, packet); for (int n = 0; r && r[n]; n++) ass_process_data(track, r[n], strlen(r[n])); if (ctx->duration_unknown) { for (int n = 0; n < track->n_events - 1; n++) { - track->events[n].Duration = track->events[n + 1].Start - - track->events[n].Start; + if (track->events[n].Duration == UNKNOWN_DURATION * 1000) { + track->events[n].Duration = track->events[n + 1].Start - + track->events[n].Start; + } } } } else { @@ -440,6 +451,7 @@ static void get_bitmaps(struct sd *sd, struct mp_osd_res dim, double pts, long long ts = find_timestamp(sd, pts); if (ctx->duration_unknown && pts != MP_NOPTS_VALUE) { mp_ass_flush_old_events(track, ts); + ctx->num_seen_packets = 0; } if (no_ass) fill_plaintext(sd, pts); |