[FFmpeg-devel] [PATCH] avcodec/htmlsubtitles: Replace very slow redundant sscanf() calls by cleaner and faster code
wm4
nfxjfg at googlemail.com
Mon Jun 12 12:35:14 EEST 2017
On Sun, 11 Jun 2017 17:58:45 +0200
Michael Niedermayer <michael at niedermayer.cc> wrote:
> This reduces the worst case from O(n²) to O(n) time
>
> Fixes Timeout
> Fixes: 2127/clusterfuzz-testcase-minimized-6595787859427328
>
> Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
> ---
> libavcodec/htmlsubtitles.c | 20 +++++++++++++++-----
> 1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/libavcodec/htmlsubtitles.c b/libavcodec/htmlsubtitles.c
> index 16295daa0c..70311c66d5 100644
> --- a/libavcodec/htmlsubtitles.c
> +++ b/libavcodec/htmlsubtitles.c
> @@ -56,6 +56,7 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in)
> char *param, buffer[128], tmp[128];
> int len, tag_close, sptr = 1, line_start = 1, an = 0, end = 0;
> SrtStack stack[16];
> + int closing_brace_missing = 0;
>
> stack[0].tag[0] = 0;
> strcpy(stack[0].param[PARAM_SIZE], "{\\fs}");
> @@ -83,11 +84,20 @@ int ff_htmlmarkup_to_ass(void *log_ctx, AVBPrint *dst, const char *in)
> and all microdvd like styles such as {Y:xxx} */
> len = 0;
> an += sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0;
> - if ((an != 1 && (len = 0, sscanf(in, "{\\%*[^}]}%n", &len) >= 0 && len > 0)) ||
> - (len = 0, sscanf(in, "{%*1[CcFfoPSsYy]:%*[^}]}%n", &len) >= 0 && len > 0)) {
> - in += len - 1;
> - } else
> - av_bprint_chars(dst, *in, 1);
> +
> + if (!closing_brace_missing) {
> + if ( (an != 1 && in[1] == '\\')
> + || (in[1] && strchr("CcFfoPSsYy", in[1]) && in[2] == ':')) {
> + char *bracep = strchr(in+2, '}');
> + if (bracep) {
> + in = bracep;
> + break;
> + } else
> + closing_brace_missing = 1;
> + }
> + }
> +
> + av_bprint_chars(dst, *in, 1);
> break;
> case '<':
> tag_close = in[1] == '/';
IMO better than before - now anyone can understand this code, and it's
faster. I'm not maintainer of this though.
Would it be possible to move this switch case to a separate function?
ff_htmlmarkup_to_ass is a bit too big.
Btw. as far as ASS tag stripping is concerned, this seems to ignore
drawings, but maybe they're typically not used in SRT.
More information about the ffmpeg-devel
mailing list