ffmpeg | branch: master | James Almer <jamr...@gmail.com> | Mon Nov 6 18:46:05 2017 -0300| [7d1c79f533e0c80cbcda60d3cbd8216551a1bac5] | committer: James Almer
Merge commit 'a594f17f83a1ffdc1eec18818208fe39487dd5d7' * commit 'a594f17f83a1ffdc1eec18818208fe39487dd5d7': dvbsubdec: Free subrect memory on allocation error dvbsubdec: Fixed segfault when decoding subtitles See fbb59a3bf4c8668197521b3db5f26d0e93aed1a6 39dfe6801a3f67c2964a829b65e8e38e3cb22217 Merged-by: James Almer <jamr...@gmail.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7d1c79f533e0c80cbcda60d3cbd8216551a1bac5 --- libavcodec/dvbsubdec.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index 85a59f3ced..4e08dba35c 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -753,8 +753,13 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou goto fail; } - for(i=0; i<sub->num_rects; i++) + for (i = 0; i < sub->num_rects; i++) { sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); + if (!sub->rects[i]) { + ret = AVERROR(ENOMEM); + goto fail; + } + } i = 0; ====================================================================== diff --cc libavcodec/dvbsubdec.c index 85a59f3ced,b97ff8027b..4e08dba35c --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@@ -647,203 -602,7 +647,208 @@@ static int dvbsub_read_8bit_string(AVCo return pixels_read; } +static void compute_default_clut(AVSubtitleRect *rect, int w, int h) +{ + uint8_t list[256] = {0}; + uint8_t list_inv[256]; + int counttab[256] = {0}; + int count, i, x, y; + ptrdiff_t stride = rect->linesize[0]; +#define V(x,y) rect->data[0][(x) + (y)*stride] + for (y = 0; y<h; y++) { + for (x = 0; x<w; x++) { + int v = V(x,y) + 1; + int vl = x ? V(x-1,y) + 1 : 0; + int vr = x+1<w ? V(x+1,y) + 1 : 0; + int vt = y ? V(x,y-1) + 1 : 0; + int vb = y+1<h ? V(x,y+1) + 1 : 0; + counttab[v-1] += !!((v!=vl) + (v!=vr) + (v!=vt) + (v!=vb)); + } + } +#define L(x,y) list[d[(x) + (y)*stride]] + + for (i = 0; i<256; i++) { + int scoretab[256] = {0}; + int bestscore = 0; + int bestv = 0; + for (y = 0; y<h; y++) { + for (x = 0; x<w; x++) { + uint8_t *d = &rect->data[0][x + y*stride]; + int v = *d; + int l_m = list[v]; + int l_l = x ? L(-1, 0) : 1; + int l_r = x+1<w ? L( 1, 0) : 1; + int l_t = y ? L( 0,-1) : 1; + int l_b = y+1<h ? L( 0, 1) : 1; + if (l_m) + continue; + scoretab[v] += l_l + l_r + l_t + l_b; + } + } + for (x = 0; x < 256; x++) { + if (scoretab[x]) { + int score = 1024LL*scoretab[x] / counttab[x]; + if (score > bestscore) { + bestscore = score; + bestv = x; + } + } + } + if (!bestscore) + break; + list [ bestv ] = 1; + list_inv[ i ] = bestv; + } + + 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)); + } +} + + +static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output) +{ + DVBSubContext *ctx = avctx->priv_data; + DVBSubRegionDisplay *display; + DVBSubDisplayDefinition *display_def = ctx->display_definition; + DVBSubRegion *region; + AVSubtitleRect *rect; + DVBSubCLUT *clut; + uint32_t *clut_table; + int i; + int offset_x=0, offset_y=0; + int ret = 0; + + + if (display_def) { + offset_x = display_def->x; + offset_y = display_def->y; + } + + /* Not touching AVSubtitles again*/ + if(sub->num_rects) { + avpriv_request_sample(ctx, "Different Version of Segment asked Twice"); + return AVERROR_PATCHWELCOME; + } + for (display = ctx->display_list; display; display = display->next) { + region = get_region(ctx, display->region_id); + if (region && region->dirty) + sub->num_rects++; + } + + if(ctx->compute_edt == 0) { + sub->end_display_time = ctx->time_out * 1000; + *got_output = 1; + } else if (ctx->prev_start != AV_NOPTS_VALUE) { + sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1; + *got_output = 1; + } + if (sub->num_rects > 0) { + + sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects); + if (!sub->rects) { + ret = AVERROR(ENOMEM); + goto fail; + } + - for(i=0; i<sub->num_rects; i++) ++ for (i = 0; i < sub->num_rects; i++) { + sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); ++ if (!sub->rects[i]) { ++ ret = AVERROR(ENOMEM); ++ goto fail; ++ } ++ } + + i = 0; + + for (display = ctx->display_list; display; display = display->next) { + region = get_region(ctx, display->region_id); + + if (!region) + continue; + + if (!region->dirty) + continue; + + rect = sub->rects[i]; + rect->x = display->x_pos + offset_x; + rect->y = display->y_pos + offset_y; + rect->w = region->width; + rect->h = region->height; + rect->nb_colors = (1 << region->depth); + rect->type = SUBTITLE_BITMAP; + rect->linesize[0] = region->width; + + clut = get_clut(ctx, region->clut); + + if (!clut) + clut = &default_clut; + + switch (region->depth) { + case 2: + clut_table = clut->clut4; + break; + case 8: + clut_table = clut->clut256; + break; + case 4: + default: + clut_table = clut->clut16; + break; + } + + rect->data[1] = av_mallocz(AVPALETTE_SIZE); + if (!rect->data[1]) { + ret = AVERROR(ENOMEM); + goto fail; + } + memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(uint32_t)); + + rect->data[0] = av_malloc(region->buf_size); + if (!rect->data[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + 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 FF_API_AVPICTURE +FF_DISABLE_DEPRECATION_WARNINGS +{ + int j; + for (j = 0; j < 4; j++) { + rect->pict.data[j] = rect->data[j]; + rect->pict.linesize[j] = rect->linesize[j]; + } +} +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + i++; + } + } + return 0; +fail: + if (sub->rects) { + for(i=0; i<sub->num_rects; i++) { + rect = sub->rects[i]; + if (rect) { + av_freep(&rect->data[0]); + av_freep(&rect->data[1]); + } + av_freep(&sub->rects[i]); + } + av_freep(&sub->rects); + } + sub->num_rects = 0; + return ret; +} static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display, const uint8_t *buf, int buf_size, int top_bottom, int non_mod) _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog