History

avfilter/af_speechnorm: fix possible memleak on error to make frame writable

Fix this by adding support for non-writable frames.

Paul B Mahol committed 5 years ago

Commit 3fe49b51 parent 2ee40771 file · +25 −13Browse files

Showing the changes to libavfilter (1 of 1 file). Show all

Unified · Split

libavfilter/af_speechnorm.c+25−13
@@ -84,7 +84,7 @@ typedef struct SpeechNormalizerContext { · 83 unmodified lines
84 void (*analyze_channel)(AVFilterContext *ctx, ChannelContext *cc,84 void (*analyze_channel)(AVFilterContext *ctx, ChannelContext *cc,
85 const uint8_t *srcp, int nb_samples);85 const uint8_t *srcp, int nb_samples);
86 void (*filter_channels[2])(AVFilterContext *ctx,86 void (*filter_channels[2])(AVFilterContext *ctx,
87 AVFrame *in, int nb_samples);87 AVFrame *in, AVFrame *out, int nb_samples);
88} SpeechNormalizerContext;88} SpeechNormalizerContext;
89 89
90#define OFFSET(x) offsetof(SpeechNormalizerContext, x)90#define OFFSET(x) offsetof(SpeechNormalizerContext, x)
@@ -295,14 +295,15 @@ ANALYZE_CHANNEL(flt, float, 0.f, (float)MIN_PEAK) · 204 unmodified lines
295 295
296#define FILTER_CHANNELS(name, ptype) \296#define FILTER_CHANNELS(name, ptype) \
297static void filter_channels_## name (AVFilterContext *ctx, \297static void filter_channels_## name (AVFilterContext *ctx, \
298 AVFrame *in, int nb_samples) \298 AVFrame *in, AVFrame *out, int nb_samples) \
299{ \299{ \
300 SpeechNormalizerContext *s = ctx->priv; \300 SpeechNormalizerContext *s = ctx->priv; \
301 AVFilterLink *inlink = ctx->inputs[0]; \301 AVFilterLink *inlink = ctx->inputs[0]; \
302 \302 \
303 for (int ch = 0; ch < inlink->channels; ch++) { \303 for (int ch = 0; ch < inlink->channels; ch++) { \
304 ChannelContext *cc = &s->cc[ch]; \304 ChannelContext *cc = &s->cc[ch]; \
305 ptype *dst = (ptype *)in->extended_data[ch]; \305 const ptype *src = (const ptype *)in->extended_data[ch]; \
306 ptype *dst = (ptype *)out->extended_data[ch]; \
306 const int bypass = !(av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels); \307 const int bypass = !(av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels); \
307 int n = 0; \308 int n = 0; \
308 \309 \
@@ -316,7 +317,7 @@ static void filter_channels_## name (AVFilterContext *ctx, · 7 unmodified lines
316 gain = cc->gain_state; \317 gain = cc->gain_state; \
317 consume_pi(cc, size); \318 consume_pi(cc, size); \
318 for (int i = n; !ctx->is_disabled && i < n + size; i++) \319 for (int i = n; !ctx->is_disabled && i < n + size; i++) \
319 dst[i] *= gain; \320 dst[i] = src[i] * gain; \
320 n += size; \321 n += size; \
321 } \322 } \
322 } \323 } \
@@ -337,7 +338,8 @@ static float flerp(float min, float max, float mix) · 14 unmodified lines
337 338
338#define FILTER_LINK_CHANNELS(name, ptype, tlerp) \339#define FILTER_LINK_CHANNELS(name, ptype, tlerp) \
339static void filter_link_channels_## name (AVFilterContext *ctx, \340static void filter_link_channels_## name (AVFilterContext *ctx, \
340 AVFrame *in, int nb_samples) \341 AVFrame *in, AVFrame *out, \
342 int nb_samples) \
341{ \343{ \
342 SpeechNormalizerContext *s = ctx->priv; \344 SpeechNormalizerContext *s = ctx->priv; \
343 AVFilterLink *inlink = ctx->inputs[0]; \345 AVFilterLink *inlink = ctx->inputs[0]; \
@@ -369,7 +371,8 @@ static void filter_link_channels_## name (AVFilterContext *ctx, · 25 unmodified lines
369 \371 \
370 for (int ch = 0; ch < inlink->channels; ch++) { \372 for (int ch = 0; ch < inlink->channels; ch++) { \
371 ChannelContext *cc = &s->cc[ch]; \373 ChannelContext *cc = &s->cc[ch]; \
372 ptype *dst = (ptype *)in->extended_data[ch]; \374 const ptype *src = (const ptype *)in->extended_data[ch]; \
375 ptype *dst = (ptype *)out->extended_data[ch]; \
373 \376 \
374 consume_pi(cc, min_size); \377 consume_pi(cc, min_size); \
375 if (cc->bypass) \378 if (cc->bypass) \
@@ -377,7 +380,7 @@ static void filter_link_channels_## name (AVFilterContext *ctx, · 1 unmodified line
377 \380 \
378 for (int i = n; !ctx->is_disabled && i < n + min_size; i++) { \381 for (int i = n; !ctx->is_disabled && i < n + min_size; i++) { \
379 ptype g = tlerp(s->prev_gain, gain, (i - n) / (ptype)min_size); \382 ptype g = tlerp(s->prev_gain, gain, (i - n) / (ptype)min_size); \
380 dst[i] *= g; \383 dst[i] = src[i] * g; \
381 } \384 } \
382 } \385 } \
383 \386 \
@@ -398,7 +401,7 @@ static int filter_frame(AVFilterContext *ctx) · 14 unmodified lines
398 401
399 while (s->queue.available > 0) {402 while (s->queue.available > 0) {
400 int min_pi_nb_samples;403 int min_pi_nb_samples;
401 AVFrame *in;404 AVFrame *in, *out;
402 405
403 in = ff_bufqueue_peek(&s->queue, 0);406 in = ff_bufqueue_peek(&s->queue, 0);
404 if (!in)407 if (!in)
@@ -410,16 +413,25 @@ static int filter_frame(AVFilterContext *ctx) · 5 unmodified lines
410 413
411 in = ff_bufqueue_get(&s->queue);414 in = ff_bufqueue_get(&s->queue);
412 415
413 ret = av_frame_make_writable(in);416 if (av_frame_is_writable(in)) {
414 if (ret < 0)417 out = in;
415 return ret;418 } else {
419 out = ff_get_audio_buffer(outlink, in->nb_samples);
420 if (!out) {
421 av_frame_free(&in);
422 return AVERROR(ENOMEM);
423 }
424 av_frame_copy_props(out, in);
425 }
416 426
417 s->filter_channels[s->link](ctx, in, in->nb_samples);427 s->filter_channels[s->link](ctx, in, out, in->nb_samples);
418 428
419 s->pts = in->pts + av_rescale_q(in->nb_samples, av_make_q(1, outlink->sample_rate),429 s->pts = in->pts + av_rescale_q(in->nb_samples, av_make_q(1, outlink->sample_rate),
420 outlink->time_base);430 outlink->time_base);
421 431
422 return ff_filter_frame(outlink, in);432 if (out != in)
433 av_frame_free(&in);
434 return ff_filter_frame(outlink, out);
423 }435 }
424 436
425 for (int f = 0; f < ff_inlink_queued_frames(inlink); f++) {437 for (int f = 0; f < ff_inlink_queued_frames(inlink); f++) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t