diff options
author | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2021-07-22 20:23:13 +0300 |
---|---|---|
committer | avih <avih@users.noreply.github.com> | 2021-08-05 21:32:22 +0300 |
commit | ab689a33a86d806726ee551fb25994fd0918a2a2 (patch) | |
tree | 4f4c8381209c44788e80215495990a021cc71402 /sub | |
parent | 24357cb7b5a1a8ca4407c2e6d9316f07a7a5ef0d (diff) | |
download | mpv-ab689a33a86d806726ee551fb25994fd0918a2a2.tar.bz2 mpv-ab689a33a86d806726ee551fb25994fd0918a2a2.tar.xz |
sub: add filter text utils, use from filter-regex (no-op)
Add two stand-alone function to help with the text-extraction task
which ass filters need. Makes it easier to add new filters without
cargo-culting this functionality.
Currently, on malformed event (which shouldn't happen), a warning is
printed when a filter tries to extract the text, so if few filters
are enabled, we'll get multiple warnings (like before) - not critical.
The regex filter now uses these utils, the SDH filter not yet.
Diffstat (limited to 'sub')
-rw-r--r-- | sub/filter_regex.c | 25 | ||||
-rw-r--r-- | sub/sd.h | 11 | ||||
-rw-r--r-- | sub/sd_ass.c | 25 |
3 files changed, 39 insertions, 22 deletions
diff --git a/sub/filter_regex.c b/sub/filter_regex.c index a5aa03a849..66e4b1a1da 100644 --- a/sub/filter_regex.c +++ b/sub/filter_regex.c @@ -44,15 +44,7 @@ static bool rf_init(struct sd_filter *ft) if (!p->num_regexes) return false; - char *headers = ft->event_format; - while (headers && headers[0]) { - p->offset += 1; - headers = strchr(headers, ','); - if (headers) - headers += 1; - } - p->offset -= 1; // removes Start/End, adds ReadOrder - + p->offset = sd_ass_fmt_offset(ft->event_format); return true; } @@ -68,20 +60,9 @@ static struct demux_packet *rf_filter(struct sd_filter *ft, struct demux_packet *pkt) { struct priv *p = ft->priv; - char *line = bstrto0(NULL, (bstr){(char *)pkt->buffer, pkt->len}); + char *text = bstrto0(NULL, sd_ass_pkt_text(ft, pkt, p->offset)); bool drop = false; - char *text = line; - for (int n = 0; n < p->offset - 1; n++) { - text = strchr(text, ','); - if (!text) { - MP_WARN(ft, "Malformed event: '%s'\n", line); - text = line; // shouldn't happen; random fallback - break; - } - text = text + 1; - } - for (int n = 0; n < p->num_regexes; n++) { int err = regexec(&p->regexes[n], text, 0, NULL, 0); if (err == 0) { @@ -94,7 +75,7 @@ static struct demux_packet *rf_filter(struct sd_filter *ft, } } - talloc_free(line); + talloc_free(text); return drop ? NULL : pkt; } @@ -89,4 +89,15 @@ struct sd_filter_functions { extern const struct sd_filter_functions sd_filter_sdh; extern const struct sd_filter_functions sd_filter_regex; + +// convenience utils for filters with ass codec + +// num commas to skip at an ass-event before the "Text" field (always last) +// (doesn't change, can be retrieved once on filter init) +int sd_ass_fmt_offset(const char *event_format); + +// the event (pkt->buffer) "Text" content according to the calculated offset. +// on malformed event: warns and returns (bstr){NULL,0} +bstr sd_ass_pkt_text(struct sd_filter *ft, struct demux_packet *pkt, int offset); + #endif diff --git a/sub/sd_ass.c b/sub/sd_ass.c index e5e12cbc04..0da6df41c8 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -945,3 +945,28 @@ static void mangle_colors(struct sd *sd, struct sub_bitmaps *parts) sb->libass.color = MP_ASS_RGBA(rgb[0], rgb[1], rgb[2], a); } } + +int sd_ass_fmt_offset(const char *evt_fmt) +{ + // "Text" is always last (as it's arbitrary content in buf), e.g. format: + // "Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" + int n = 0; + while (evt_fmt && (evt_fmt = strchr(evt_fmt, ','))) + evt_fmt++, n++; + return n-1; // buffer is without the format's Start/End, with ReadOrder +} + +bstr sd_ass_pkt_text(struct sd_filter *ft, struct demux_packet *pkt, int offset) +{ + // e.g. pkt->buffer ("4" is ReadOrder): "4,0,Default,,0,0,0,,fifth line" + bstr txt = {(char *)pkt->buffer, pkt->len}, t0 = txt; + while (offset-- > 0) { + int n = bstrchr(txt, ','); + if (n < 0) { // shouldn't happen + MP_WARN(ft, "Malformed event '%.*s'\n", BSTR_P(t0)); + return (bstr){NULL, 0}; + } + txt = bstr_cut(txt, n+1); + } + return txt; +} |