mirror of
https://github.com/mpv-player/mpv
synced 2025-02-16 20:27:23 +00:00
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.
This commit is contained in:
parent
24357cb7b5
commit
ab689a33a8
@ -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;
|
||||
}
|
||||
|
||||
|
11
sub/sd.h
11
sub/sd.h
@ -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
|
||||
|
25
sub/sd_ass.c
25
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user