diff options
author | Paul B Mahol <onemda@gmail.com> | 2016-08-16 15:52:30 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2016-08-16 15:56:12 +0200 |
commit | 1457786d6920736dd1d71fda285a191d86fadf1b (patch) | |
tree | 7e413030e8b45248a1ad52ebc42f7a855a553953 | |
parent | ea58dd2bebf8748be4c2716936e1056dc6c507fc (diff) | |
download | ffmpeg-1457786d6920736dd1d71fda285a191d86fadf1b.tar.gz |
avfilter/avf_showspectrum: do not let multiple threads to write to same part of memory
-rw-r--r-- | libavfilter/avf_showspectrum.c | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c index bb00a05c8f..b4cc51b652 100644 --- a/libavfilter/avf_showspectrum.c +++ b/libavfilter/avf_showspectrum.c @@ -77,6 +77,7 @@ typedef struct { float gain; int hop_size; float *combine_buffer; ///< color combining buffer (3 * h items) + float **color_buffer; ///< color buffer (3 * h * ch items) AVAudioFifo *fifo; int64_t pts; int single_pic; @@ -230,12 +231,17 @@ static av_cold void uninit(AVFilterContext *ctx) for (i = 0; i < s->nb_display_channels; i++) av_fft_end(s->fft[i]); } + av_freep(&s->fft); if (s->fft_data) { for (i = 0; i < s->nb_display_channels; i++) av_freep(&s->fft_data[i]); } - av_freep(&s->fft); av_freep(&s->fft_data); + if (s->color_buffer) { + for (i = 0; i < s->nb_display_channels; i++) + av_freep(&s->color_buffer[i]); + } + av_freep(&s->color_buffer); av_freep(&s->window_func_lut); if (s->magnitudes) { for (i = 0; i < s->nb_display_channels; i++) @@ -366,6 +372,16 @@ static int config_output(AVFilterLink *outlink) return AVERROR(ENOMEM); } + av_freep(&s->color_buffer); + s->color_buffer = av_calloc(s->nb_display_channels, sizeof(*s->color_buffer)); + if (!s->color_buffer) + return AVERROR(ENOMEM); + for (i = 0; i < s->nb_display_channels; i++) { + s->color_buffer[i] = av_malloc_array(s->orientation == VERTICAL ? s->h * 3 : s->w * 3, sizeof(**s->color_buffer)); + if (!s->color_buffer[i]) + return AVERROR(ENOMEM); + } + s->fft_data = av_calloc(s->nb_display_channels, sizeof(*s->fft_data)); if (!s->fft_data) return AVERROR(ENOMEM); @@ -613,13 +629,13 @@ static void pick_color(ShowSpectrumContext *s, + color_table[cm][i].v * lerpfrac; } - out[0] += y * yf; - out[1] += u * uf; - out[2] += v * vf; + out[0] = y * yf; + out[1] = u * uf; + out[2] = v * vf; } else { - out[0] += a * yf; - out[1] += a * uf; - out[2] += a * vf; + out[0] = a * yf; + out[1] = a * uf; + out[2] = a * vf; } } @@ -650,7 +666,7 @@ static int plot_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) /* draw the channel */ for (y = 0; y < h; y++) { int row = (s->mode == COMBINED) ? y : ch * h + y; - float *out = &s->combine_buffer[3 * row]; + float *out = &s->color_buffer[ch][3 * row]; float a; switch (s->data) { @@ -702,14 +718,21 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples) AVFilterLink *outlink = ctx->outputs[0]; ShowSpectrumContext *s = ctx->priv; AVFrame *outpicref = s->outpicref; - int ret, plane, x, y; + int ret, plane, x, y, z = s->orientation == VERTICAL ? s->h : s->w; /* fill a new spectrum column */ /* initialize buffer for combining to black */ - clear_combine_buffer(s, s->orientation == VERTICAL ? s->h : s->w); + clear_combine_buffer(s, z); ctx->internal->execute(ctx, plot_channel, NULL, NULL, s->nb_display_channels); + for (y = 0; y < z * 3; y++) { + s->combine_buffer[y] += s->color_buffer[0][y]; + for (x = 1; x < s->nb_display_channels; x++) { + s->combine_buffer[y] += s->color_buffer[x][y]; + } + } + av_frame_make_writable(s->outpicref); /* copy to output */ if (s->orientation == VERTICAL) { |