af_channelmap: properly set the supported output channel layouts

The current code expects query_formats() to be called exactly once, it
will leak if it's not called at all (filter initialized, but never
configured or used) or try to read freed memory if it's called more than
once.

Found-by: James Almer <jamrial@gmail.com>
CC: libav-stable@libav.org
pull/140/head
Anton Khirnov 10 years ago
parent aed7715b8f
commit 22ecfcd4c7
  1. 8
      libavfilter/af_channelmap.c

@ -57,7 +57,6 @@ enum MappingMode {
#define MAX_CH 64 #define MAX_CH 64
typedef struct ChannelMapContext { typedef struct ChannelMapContext {
const AVClass *class; const AVClass *class;
AVFilterChannelLayouts *channel_layouts;
char *mapping_str; char *mapping_str;
char *channel_layout_str; char *channel_layout_str;
uint64_t output_layout; uint64_t output_layout;
@ -276,8 +275,6 @@ static av_cold int channelmap_init(AVFilterContext *ctx)
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
ff_add_channel_layout(&s->channel_layouts, s->output_layout);
if (mode == MAP_PAIR_INT_STR || mode == MAP_PAIR_STR_STR) { if (mode == MAP_PAIR_INT_STR || mode == MAP_PAIR_STR_STR) {
for (i = 0; i < s->nch; i++) { for (i = 0; i < s->nch; i++) {
s->map[i].out_channel_idx = av_get_channel_layout_channel_index( s->map[i].out_channel_idx = av_get_channel_layout_channel_index(
@ -291,11 +288,14 @@ static av_cold int channelmap_init(AVFilterContext *ctx)
static int channelmap_query_formats(AVFilterContext *ctx) static int channelmap_query_formats(AVFilterContext *ctx)
{ {
ChannelMapContext *s = ctx->priv; ChannelMapContext *s = ctx->priv;
AVFilterChannelLayouts *channel_layouts = NULL;
ff_add_channel_layout(&channel_layouts, s->output_layout);
ff_set_common_formats(ctx, ff_planar_sample_fmts()); ff_set_common_formats(ctx, ff_planar_sample_fmts());
ff_set_common_samplerates(ctx, ff_all_samplerates()); ff_set_common_samplerates(ctx, ff_all_samplerates());
ff_channel_layouts_ref(ff_all_channel_layouts(), &ctx->inputs[0]->out_channel_layouts); ff_channel_layouts_ref(ff_all_channel_layouts(), &ctx->inputs[0]->out_channel_layouts);
ff_channel_layouts_ref(s->channel_layouts, &ctx->outputs[0]->in_channel_layouts); ff_channel_layouts_ref(channel_layouts, &ctx->outputs[0]->in_channel_layouts);
return 0; return 0;
} }

Loading…
Cancel
Save