On 06/19/2012 12:11 AM, Anton Khirnov wrote: > > On Sun, 10 Jun 2012 17:50:12 -0400, Justin Ruggles <[email protected]> > wrote: >> simplifies allocation >> --- >> Fixed a memleak in the previous patch. >> >> libavfilter/af_amix.c | 77 >> +++++++++++++++++++++++-------------------------- >> 1 files changed, 36 insertions(+), 41 deletions(-) >> >> diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c >> index 7e26400..d249af1 100644 >> --- a/libavfilter/af_amix.c >> +++ b/libavfilter/af_amix.c >> @@ -151,6 +151,12 @@ static int frame_list_add_frame(FrameList *frame_list, >> int nb_samples, int64_t p >> } >> >> >> +typedef struct MixInput { >> + AVAudioFifo *fifo; /**< audio fifo */ >> + uint8_t state; /**< current state */ >> + float scale; /**< mixing scale factor */ >> +} MixInput; >> + >> typedef struct MixContext { >> const AVClass *class; /**< class for AVOptions */ >> AVFloatDSPContext fdsp; >> @@ -163,12 +169,10 @@ typedef struct MixContext { >> int nb_channels; /**< number of channels */ >> int sample_rate; /**< sample rate */ >> int planar; >> - AVAudioFifo **fifos; /**< audio fifo for each input */ >> - uint8_t *input_state; /**< current state of each input */ >> - float *input_scale; /**< mixing scale factor for each input */ >> float scale_norm; /**< normalization factor for all inputs */ >> int64_t next_pts; /**< calculated pts for next output frame */ >> FrameList *frame_list; /**< list of frame info for the first input >> */ >> + MixInput *inputs; /**< per-input information and data */ >> } MixContext; >> >> #define OFFSET(x) offsetof(MixContext, x) >> @@ -212,10 +216,10 @@ static void calculate_scales(MixContext *s, int >> nb_samples) >> } >> >> for (i = 0; i < s->nb_inputs; i++) { >> - if (s->input_state[i] == INPUT_ON) >> - s->input_scale[i] = 1.0f / s->scale_norm; >> + if (s->inputs[i].state == INPUT_ON) >> + s->inputs[i].scale = 1.0f / s->scale_norm; >> else >> - s->input_scale[i] = 0.0f; >> + s->inputs[i].scale = 0.0f; >> } >> } >> >> @@ -235,26 +239,20 @@ static int config_output(AVFilterLink *outlink) >> if (!s->frame_list) >> return AVERROR(ENOMEM); >> >> - s->fifos = av_mallocz(s->nb_inputs * sizeof(*s->fifos)); >> - if (!s->fifos) >> + s->nb_channels = >> av_get_channel_layout_nb_channels(outlink->channel_layout); >> + >> + s->inputs = av_mallocz(s->nb_inputs * sizeof(*s->inputs)); >> + if (!s->inputs) >> return AVERROR(ENOMEM); >> >> - s->nb_channels = >> av_get_channel_layout_nb_channels(outlink->channel_layout); >> for (i = 0; i < s->nb_inputs; i++) { >> - s->fifos[i] = av_audio_fifo_alloc(outlink->format, s->nb_channels, >> 1024); >> - if (!s->fifos[i]) >> + s->inputs[i].fifo = av_audio_fifo_alloc(outlink->format, >> s->nb_channels, 1024); >> + if (!s->inputs[i].fifo) >> return AVERROR(ENOMEM); >> - } >> >> - s->input_state = av_malloc(s->nb_inputs); >> - if (!s->input_state) >> - return AVERROR(ENOMEM); >> - memset(s->input_state, INPUT_ON, s->nb_inputs); >> + s->inputs[i].state = INPUT_ON; >> + } >> s->active_inputs = s->nb_inputs; >> - >> - s->input_scale = av_mallocz(s->nb_inputs * sizeof(*s->input_scale)); >> - if (!s->input_scale) >> - return AVERROR(ENOMEM); >> s->scale_norm = s->active_inputs; >> calculate_scales(s, 0); >> >> @@ -288,10 +286,10 @@ static int output_frame(AVFilterLink *outlink, int >> nb_samples) >> return AVERROR(ENOMEM); >> >> for (i = 0; i < s->nb_inputs; i++) { >> - if (s->input_state[i] == INPUT_ON) { >> + if (s->inputs[i].state == INPUT_ON) { >> int planes, plane_size, p; >> >> - av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data, >> + av_audio_fifo_read(s->inputs[i].fifo, (void >> **)in_buf->extended_data, >> nb_samples); >> >> planes = s->planar ? s->nb_channels : 1; >> @@ -301,7 +299,7 @@ static int output_frame(AVFilterLink *outlink, int >> nb_samples) >> for (p = 0; p < planes; p++) { >> s->fdsp.vector_fmac_scalar((float >> *)out_buf->extended_data[p], >> (float *) >> in_buf->extended_data[p], >> - s->input_scale[i], plane_size); >> + s->inputs[i].scale, plane_size); >> } >> } >> } >> @@ -329,9 +327,9 @@ static int get_available_samples(MixContext *s) >> >> for (i = 1; i < s->nb_inputs; i++) { >> int nb_samples; >> - if (s->input_state[i] == INPUT_OFF) >> + if (s->inputs[i].state == INPUT_OFF) >> continue; >> - nb_samples = av_audio_fifo_size(s->fifos[i]); >> + nb_samples = av_audio_fifo_size(s->inputs[i].fifo); >> available_samples = FFMIN(available_samples, nb_samples); >> } >> if (available_samples == INT_MAX) >> @@ -351,13 +349,13 @@ static int request_samples(AVFilterContext *ctx, int >> min_samples) >> >> for (i = 1; i < s->nb_inputs; i++) { >> ret = 0; >> - if (s->input_state[i] == INPUT_OFF) >> + if (s->inputs[i].state == INPUT_OFF) >> continue; >> - while (!ret && av_audio_fifo_size(s->fifos[i]) < min_samples) >> + while (!ret && av_audio_fifo_size(s->inputs[i].fifo) < min_samples) >> ret = ff_request_frame(ctx->inputs[i]); >> if (ret == AVERROR_EOF) { >> - if (av_audio_fifo_size(s->fifos[i]) == 0) { >> - s->input_state[i] = INPUT_OFF; >> + if (av_audio_fifo_size(s->inputs[i].fifo) == 0) { >> + s->inputs[i].state = INPUT_OFF; >> continue; >> } >> } else if (ret) >> @@ -377,11 +375,11 @@ static int calc_active_inputs(MixContext *s) >> int i; >> int active_inputs = 0; >> for (i = 0; i < s->nb_inputs; i++) >> - active_inputs += !!(s->input_state[i] != INPUT_OFF); >> + active_inputs += !!(s->inputs[i].state != INPUT_OFF); >> s->active_inputs = active_inputs; >> >> if (!active_inputs || >> - (s->duration_mode == DURATION_FIRST && s->input_state[0] == >> INPUT_OFF) || >> + (s->duration_mode == DURATION_FIRST && s->inputs[0].state == >> INPUT_OFF) || >> (s->duration_mode == DURATION_SHORTEST && active_inputs != >> s->nb_inputs)) >> return AVERROR_EOF; >> return 0; >> @@ -398,7 +396,7 @@ static int request_frame(AVFilterLink *outlink) >> if (ret < 0) >> return ret; >> >> - if (s->input_state[0] == INPUT_OFF) { >> + if (s->inputs[0].state == INPUT_OFF) { >> ret = request_samples(ctx, 1); >> if (ret < 0) >> return ret; >> @@ -417,7 +415,7 @@ static int request_frame(AVFilterLink *outlink) >> if (s->frame_list->nb_frames == 0) { >> ret = ff_request_frame(ctx->inputs[0]); >> if (ret == AVERROR_EOF) { >> - s->input_state[0] = INPUT_OFF; >> + s->inputs[0].state = INPUT_OFF; >> if (s->nb_inputs == 1) >> return AVERROR_EOF; >> else >> @@ -473,7 +471,7 @@ static void filter_samples(AVFilterLink *inlink, >> AVFilterBufferRef *buf) >> frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts); >> } >> >> - av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data, >> + av_audio_fifo_write(s->inputs[i].fifo, (void **)buf->extended_data, >> buf->audio->nb_samples); >> >> avfilter_unref_buffer(buf); >> @@ -515,15 +513,12 @@ static void uninit(AVFilterContext *ctx) >> int i; >> MixContext *s = ctx->priv; >> >> - if (s->fifos) { >> - for (i = 0; i < s->nb_inputs; i++) >> - av_audio_fifo_free(s->fifos[i]); >> - av_freep(&s->fifos); >> - } >> + for (i = 0; i < s->nb_inputs; i++) >> + av_audio_fifo_free(s->inputs[i].fifo); > > If init fails without allocating inputs, uninit will still be called i > think.
av_audio_fifo_free() can be called with NULL. -Justin _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
