From 227ec140d3c1bb9e825f32e600f0ffd04cc70873 Mon Sep 17 00:00:00 2001 From: Oneric Date: Sat, 23 May 2020 18:01:32 +0200 Subject: Detect subs converted to ASS by ffmpeg/libav ffmpeg/libav did rely on *VSFilter incompatible libass defaults for years. Avoid breaking them when changing libass' default to match *VSFilter. To this end detection of the generated by ffmpeg signature is added. --- libass/ass.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'libass') diff --git a/libass/ass.c b/libass/ass.c index cb0e9ac..cf72ecb 100644 --- a/libass/ass.c +++ b/libass/ass.c @@ -55,7 +55,9 @@ typedef enum { SINFO_WRAPSTYLE = 1 << 4, SINFO_SCALEDBORDER = 1 << 5, SINFO_COLOURMATRIX = 1 << 6, - SINFO_KERNING = 1 << 7 + SINFO_KERNING = 1 << 7, + // for legacy detection + GENBY_FFMPEG = 1 << 8 // max 32 enumerators } ScriptInfo; @@ -713,6 +715,9 @@ static int process_info_line(ASS_Track *track, char *str) while (*p && ass_isspace(*p)) p++; free(track->Language); track->Language = strndup(p, 2); + } else if (!strncmp(str, "; Script generated by ", 22)) { + if (!strncmp(str + 22,"FFmpeg/Lavc", 11)) + track->parser_priv->header_flags |= GENBY_FFMPEG; } return 0; } @@ -728,6 +733,63 @@ static void event_format_fallback(ASS_Track *track) "No event format found, using fallback"); } +/** + * \brief Return if track is post-signature and pre-SBAS ffmpeg track + * \param track track +*/ +static bool detect_legacy_conv_subs(ASS_Track *track) +{ + /* + * FFmpeg and libav convert srt subtitles to ass. + * In legacy versions, they did not set the 'ScaledBorderAndShadow' header, + * but expected it to default to yes (which libass did). + * To avoid breaking them, we try to detect these + * converted subs by common properties of ffmpeg/libav's converted subs. + * Since files with custom format lines (-2014.10.11) default to SBAS=1 + * regardless of being ffmpeg generated or not, we are only concerned with + * post-signature and pre-SBAS ffmpeg-files (2014.10.11-2020.04.17). + * We want to avoid matching modified ffmpeg files though. + * + * Relevant ffmpeg commits are: + * 2c77c90684e24ef16f7e7c4462e011434cee6a98 2010.12.29 + * Initial conversion format. + * Style "Format:" line is mix of SSA and ASS + * Event "Format:" line + * "Format: Layer, Start, End, Text\r\n" + * Only Header in ScriptInfo is "ScriptType: v4.00+" + * 0e7782c08ec77739edb0b98ba5d896b45e98235f 2012.06.15 + * Adds 'Style' to Event "Format:" line + * 5039aadf68deb9ad6dd0737ea11259fe53d3727b 2014.06.18 + * Adds PlayerRes(X|Y) (384x288) + * (moved below ScriptType: a few minutes later) + * 40b9f28641b696c6bb73ce49dc97c2ce2700cbdb 2014.10.11 14:31:23 +0200 + * Regular full ASS Event and Style "Format:" lines + * 52b0a0ecaa02e17f7e01bead8c3f215f1cfd48dc 2014.10.11 18:37:43 +0200 <== + * Signature comment + * 56bc0a6736cdc7edab837ff8f304661fd16de0e4 2015.02.08 + * Allow custom PlayRes(X|Y) + * a8ba2a2c1294a330a0e79ae7f0d3a203a7599166 2020.04.17 + * Set 'ScaledBorderAndShadow: yes' + * + * libav outputs initial ffmpeg format. (no longer maintained) + */ + + // GENBY_FFMPEG and exact ffmpeg headers required + // Note: If there's SINFO_SCRIPTTYPE in the future this needs to be updated + if (track->parser_priv->header_flags + ^ (SINFO_PLAYRESX | SINFO_PLAYRESY | GENBY_FFMPEG)) + return false; + + // Legacy ffmpeg only ever has one style + // Check 2 not 1 because libass also adds a def style + if (track->n_styles != 2 + || strncmp(track->styles[1].Name, "Default", 7)) + return false; + + return true; +} + + static int process_events_line(ASS_Track *track, char *str) { if (!strncmp(str, "Format:", 7)) { @@ -740,6 +802,14 @@ static int process_events_line(ASS_Track *track, char *str) custom_format_line_compatibility(track, p, ass_event_format); else custom_format_line_compatibility(track, p, ssa_event_format); + + // Guess if we are dealing with legacy ffmpeg subs and change accordingly + // If file has no event format it was probably not created by ffmpeg/libav + if (detect_legacy_conv_subs(track)) { + track->ScaledBorderAndShadow = 1; + ass_msg(track->library, MSGL_INFO, + "Track treated as legacy ffmpeg sub."); + } } else if (!strncmp(str, "Dialogue:", 9)) { // This should never be reached for embedded subtitles. // They have slightly different format and are parsed in ass_process_chunk, -- cgit v1.2.3