summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOneric <oneric@oneric.stub>2022-10-04 01:16:30 +0200
committerOneric <oneric@oneric.stub>2022-10-14 20:21:09 +0200
commit75a3dbac9bd41842a4d00b0d42c9513e2c8aec67 (patch)
treeb34f583444de02d4d0abf28f63d6b5c6b95049c4
parent82c654056acfc240ef1400c2bdc67489be0d98fd (diff)
downloadlibass-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.c26
-rw-r--r--libass/ass_priv.h3
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;