filter_sdh: convert --sub-sdh-enclosures to a string list
This lets users specify any possible pair of characters to remote text from in the SDH filter as opposed to the old way which would automatically map ( to ) internally. Additionally, this fixes #16597 because the old implementation relied on looping over a single string using strlen for matching chars. That doesn't work because strlen loops over bytes and non-ASCII characters can have multiple bytes leading to false positives since the bytes could match. There's various ways to deal with this, but simply using mpv's internal stringlist type sidesteps that problem.
This commit is contained in:
1 parent
cc660f8609
commit
b5c629fd12
5 files changed
+37
-37
No files matched your search
@@ -0,0 +1 @@
|
||||
the `--sub-sdh-enclosures` option is now a string list option
|
||||
@@ -3162,13 +3162,13 @@ Subtitles
|
||||
Default: ``no``.
|
||||
|
||||
``--sub-filter-sdh-enclosures=<string>``
|
||||
Specify a string of characters that ``--sub-filter-sdh`` will use to potentially
|
||||
remove text. Text that is enclosed within characters specified by this string will
|
||||
be removed. Note that bracket characters with known pairs (such as ``(`` or ``[``)
|
||||
will be mapped internally to their matching right hand character, so you only need
|
||||
to specify left hand characters.
|
||||
Specify pairs of characters that ``--sub-filter-sdh`` will use to
|
||||
potentially remove text. This is a string list option. See `List Options`_
|
||||
for details. Text that is enclosed within each specified pair will be
|
||||
removed. Note that parenthesis pairs (normal and full width) are treated as
|
||||
a special case and require ``--sub-fitler-sdh-harder`` to be removed.
|
||||
|
||||
Default: ``([(``.
|
||||
Default: ``(),[],()``
|
||||
|
||||
``--sub-filter-regex-...=...``
|
||||
Set a list of regular expressions to match on text subtitles, and remove any
|
||||
|
||||
+22
-28
@@ -33,13 +33,6 @@
|
||||
// all SDH parts.
|
||||
// It is for filtering ASS encoded subtitles
|
||||
|
||||
static const char *const enclosure_pair[][2] = {
|
||||
{"(", ")"},
|
||||
{"[", "]"},
|
||||
{"\uFF08", "\uFF09"},
|
||||
{0},
|
||||
};
|
||||
|
||||
struct buffer {
|
||||
char *string;
|
||||
int length;
|
||||
@@ -84,26 +77,26 @@ static int get_char_bytes(char *str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *get_right_enclosure(char *left)
|
||||
static bool is_parenthesis_pair(const char *left, const char *right)
|
||||
{
|
||||
// See if the right hand character is mapped. If not, just return the same thing.
|
||||
for (int i = 0; enclosure_pair[i][0]; i++) {
|
||||
if (strcmp(left, enclosure_pair[i][0]) == 0)
|
||||
return enclosure_pair[i][1];
|
||||
}
|
||||
return left;
|
||||
if (!strcmp(left, "(") && !strcmp(right, ")"))
|
||||
return true;
|
||||
if (!strcmp(left, "\uFF08") && !strcmp(right, "\uFF09"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool valid_left_enclosure(struct sd_filter *sd, char *str)
|
||||
static int matching_enclosure(char **enclosures, char *str)
|
||||
{
|
||||
// All characters in this string are valid left hand enclosure characters.
|
||||
char *enclosures = sd->opts->sub_filter_SDH_enclosures;
|
||||
int len = strlen(enclosures);
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (str && str[0] && str[0] == enclosures[i])
|
||||
return true;
|
||||
int len = get_char_bytes(str);
|
||||
for (int i = 0; len && enclosures && enclosures[i]; ++i) {
|
||||
if (!strncmp(str, enclosures[i], len) &&
|
||||
len == get_char_bytes(enclosures[i])) // str doesn't end early
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -246,7 +239,7 @@ static bool skip_enclosed(struct sd_filter *sd, char **rpp, struct buffer *buf,
|
||||
bool filter_harder = sd->opts->sub_filter_SDH_harder;
|
||||
char *rp = *rpp;
|
||||
int old_pos = buf->pos;
|
||||
bool parenthesis = strcmp(left, "(") == 0 || strcmp(left, "\uFF08") == 0;
|
||||
bool parenthesis = is_parenthesis_pair(left, right);
|
||||
|
||||
// skip past the left character
|
||||
rp += get_char_bytes(rp);
|
||||
@@ -380,15 +373,16 @@ static char *filter_SDH(struct sd_filter *sd, char *data, int length, ptrdiff_t
|
||||
while (*rp && !(rp[0] == '\\' && rp[1] == 'N')) {
|
||||
copy_ass(sd, &rp, buf);
|
||||
char left[5] = {0};
|
||||
const char *right = NULL;
|
||||
if (valid_left_enclosure(sd, rp)) {
|
||||
char **enclosures = sd->opts->sub_filter_SDH_enclosures;
|
||||
int index = matching_enclosure(enclosures, rp);
|
||||
if (index > -1) {
|
||||
int bytes = get_char_bytes(rp);
|
||||
for (int i = 0; i < bytes; i++)
|
||||
left[i] = rp[i];
|
||||
left[bytes] = '\0';
|
||||
right = get_right_enclosure(left);
|
||||
}
|
||||
if (left[0] && right && right[0]) {
|
||||
if (left[0]) {
|
||||
// Skip left character
|
||||
char *right = enclosures[index] + get_char_bytes(enclosures[index]);
|
||||
if (!skip_enclosed(sd, &rp, buf, left, right)) {
|
||||
append(sd, buf, rp[0]);
|
||||
rp++;
|
||||
|
||||
@@ -70,7 +70,7 @@ void lavc_conv_uninit(struct lavc_conv *priv);
|
||||
struct mp_sub_filter_opts {
|
||||
bool sub_filter_SDH;
|
||||
bool sub_filter_SDH_harder;
|
||||
char *sub_filter_SDH_enclosures;
|
||||
char **sub_filter_SDH_enclosures;
|
||||
bool rf_enable;
|
||||
bool rf_plain;
|
||||
char **rf_items;
|
||||
|
||||
+7
-2
@@ -75,7 +75,7 @@ const struct m_sub_options mp_sub_filter_opts = {
|
||||
.opts = (const struct m_option[]){
|
||||
{"sdh", OPT_BOOL(sub_filter_SDH)},
|
||||
{"sdh-harder", OPT_BOOL(sub_filter_SDH_harder)},
|
||||
{"sdh-enclosures", OPT_STRING(sub_filter_SDH_enclosures)},
|
||||
{"sdh-enclosures", OPT_STRINGLIST(sub_filter_SDH_enclosures)},
|
||||
{"regex-enable", OPT_BOOL(rf_enable)},
|
||||
{"regex-plain", OPT_BOOL(rf_plain)},
|
||||
{"regex", OPT_STRINGLIST(rf_items)},
|
||||
@@ -85,7 +85,12 @@ const struct m_sub_options mp_sub_filter_opts = {
|
||||
},
|
||||
.size = sizeof(OPT_BASE_STRUCT),
|
||||
.defaults = &(OPT_BASE_STRUCT){
|
||||
.sub_filter_SDH_enclosures = "([\uFF08",
|
||||
.sub_filter_SDH_enclosures = (char *[]) {
|
||||
"()",
|
||||
"[]",
|
||||
"\uFF08\uFF09",
|
||||
NULL
|
||||
},
|
||||
.rf_enable = true,
|
||||
},
|
||||
.change_flags = UPDATE_SUB_FILT,
|
||||
|
||||
Reference in new issue
Block a user