diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2017-11-04 00:26:56 +0100 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2017-11-15 17:31:09 +0100 |
commit | eec67f7b24da5407cc2e8933ffe72358336811ab (patch) | |
tree | 952112875659f91a0c7b01fb4f79c1d91a0c65e9 | |
parent | 380b48fb9fdc7b0c40d67e026f9b3accb12794eb (diff) | |
download | ffmpeg-eec67f7b24da5407cc2e8933ffe72358336811ab.tar.gz |
avcodec/dvbsubdec: Avoid re-computing clut
Fixes: Timeout
Fixes: 3218/clusterfuzz-testcase-5390672154591232
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavcodec/dvbsubdec.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index 4e08dba35c..a657b1d3d0 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -96,6 +96,9 @@ typedef struct DVBSubRegion { int clut; int bgcolor; + uint8_t computed_clut[4*256]; + int has_computed_clut; + uint8_t *pbuf; int buf_size; int dirty; @@ -647,7 +650,7 @@ static int dvbsub_read_8bit_string(AVCodecContext *avctx, return pixels_read; } -static void compute_default_clut(AVSubtitleRect *rect, int w, int h) +static void compute_default_clut(uint8_t *clut, AVSubtitleRect *rect, int w, int h) { uint8_t list[256] = {0}; uint8_t list_inv[256]; @@ -703,7 +706,7 @@ static void compute_default_clut(AVSubtitleRect *rect, int w, int h) count = FFMAX(i - 1, 1); for (i--; i>=0; i--) { int v = i*255/count; - AV_WN32(rect->data[1] + 4*list_inv[i], RGBA(v/2,v,v/2,v)); + AV_WN32(clut + 4*list_inv[i], RGBA(v/2,v,v/2,v)); } } @@ -814,8 +817,14 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou memcpy(rect->data[0], region->pbuf, region->buf_size); - if ((clut == &default_clut && ctx->compute_clut == -1) || ctx->compute_clut == 1) - compute_default_clut(rect, rect->w, rect->h); + if ((clut == &default_clut && ctx->compute_clut == -1) || ctx->compute_clut == 1) { + if (!region->has_computed_clut) { + compute_default_clut(region->computed_clut, rect, rect->w, rect->h); + region->has_computed_clut = 1; + } + + memcpy(rect->data[1], region->computed_clut, sizeof(region->computed_clut)); + } #if FF_API_AVPICTURE FF_DISABLE_DEPRECATION_WARNINGS @@ -964,6 +973,7 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis } } + region->has_computed_clut = 0; } static int dvbsub_parse_object_segment(AVCodecContext *avctx, |