[FFmpeg-cvslog] Merge commit 'a594f17f83a1ffdc1eec18818208fe39487dd5d7'
James Almer
git at videolan.org
Mon Nov 6 23:47:19 EET 2017
ffmpeg | branch: master | James Almer <jamrial at 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 <jamrial at 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)
More information about the ffmpeg-cvslog
mailing list