diff options
author | Oneric <oneric@oneric.stub> | 2022-10-04 01:16:30 +0200 |
---|---|---|
committer | Oneric <oneric@oneric.stub> | 2022-10-14 20:21:09 +0200 |
commit | 75a3dbac9bd41842a4d00b0d42c9513e2c8aec67 (patch) | |
tree | b34f583444de02d4d0abf28f63d6b5c6b95049c4 | |
parent | 82c654056acfc240ef1400c2bdc67489be0d98fd (diff) | |
download | libass-75a3dbac9bd41842a4d00b0d42c9513e2c8aec67.tar.bz2 libass-75a3dbac9bd41842a4d00b0d42c9513e2c8aec67.tar.xz |
Parse ScriptType header
VSFilter uses it for Dialogue lines and Style lines
not preceeded by a styles section header.
libass requires section headers to parse styles,
but this still helps for files without a Styles
section (placed before the Events section) and
also makes our legacy-FFmpeg detection more accurate.
In fact, VSFilter takes _only_ the ScriptType
header into account for Dialogue lines and keeps
a separate version for styles which is also affected
by style section headers.
This dual versioning is not implemented by this commit and the
lack of any issue reports about it suggests such files may not
exist in practice. If however it turned out they do, an additional
version variable can be added to parser_priv and we need to decide
which one to present to API users.
-rw-r--r-- | libass/ass.c | 26 | ||||
-rw-r--r-- | libass/ass_priv.h | 3 |
2 files changed, 26 insertions, 3 deletions
diff --git a/libass/ass.c b/libass/ass.c index e08a76a..ef3b471 100644 --- a/libass/ass.c +++ b/libass/ass.c @@ -681,6 +681,26 @@ static int process_styles_line(ASS_Track *track, char *str) return ret; } +static inline void parse_script_type(ASS_Track *track, const char *str) +{ + // VSF compat: don't check for leading 'v' and + // parse value from the last non-space backwards + const char *p = str + strlen(str); + rskip_spaces((char **) &p, (char *) str); + size_t len = p - str; + if (len < 4) // rskip_spaces stops _at_ last space + return; + + int ver = TRACK_TYPE_SSA; + if (*(p-1) == '+') { + ver = TRACK_TYPE_ASS; + --len; --p; + } + + if (len >= 4 && !strncmp(p-4, "4.00", 4)) + track->track_type = ver; +} + static inline void check_duplicate_info_line(const ASS_Track *const track, const ScriptInfo si, const char *const name) @@ -723,6 +743,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, "ScriptType:", 11)) { + check_duplicate_info_line(track, SINFO_SCRIPTTYPE, "ScriptType"); + parse_script_type(track, str + 11); } else if (!strncmp(str, "; Script generated by ", 22)) { if (!strncmp(str + 22,"FFmpeg/Lavc", 11)) track->parser_priv->header_flags |= GENBY_FFMPEG; @@ -783,9 +806,8 @@ static bool detect_legacy_conv_subs(ASS_Track *track) */ // 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)) + != (SINFO_SCRIPTTYPE | SINFO_PLAYRESX | SINFO_PLAYRESY | GENBY_FFMPEG)) return false; // Legacy ffmpeg only ever has one style diff --git a/libass/ass_priv.h b/libass/ass_priv.h index 43a89c8..8c9d3cf 100644 --- a/libass/ass_priv.h +++ b/libass/ass_priv.h @@ -41,8 +41,9 @@ typedef enum { SINFO_SCALEDBORDER = 1 << 5, SINFO_COLOURMATRIX = 1 << 6, SINFO_KERNING = 1 << 7, + SINFO_SCRIPTTYPE = 1 << 8, // for legacy detection - GENBY_FFMPEG = 1 << 8 + GENBY_FFMPEG = 1 << 14 // max 32 enumerators } ScriptInfo; |