[Libav-user] Fwd: Not able to get mono channel output libswresample

Josh Gustafson josh.gustafson at simplecontrol.com
Thu Jun 15 21:49:52 EEST 2017

On Thu, Jun 15, 2017 at 5:45 AM, amey jain <amey.jain7 at gmail.com> wrote:
> Hello all,
> I want an output stream of audio, mono channel, down sampled to 5512
> Hz, and output in a float array. I used libswresample API tutorial on
> page and it is working. But there are two problems I am facing right
> now or not able to understand context.
> 1. If channel layout is set as AV_CH_LAYOUT_MONO in
> out_channel_layout, and number of output samples I get are nb_samples
> (say), then size of buffer should be nb_samples * byte_per_sample *
> nb_channels. Since channel is mono nb_channel should be one. However
> when I get size allocated using av_samples_alloc with sample_fmt
> AV_SAMPLE_FMT_FLT I get size double of what I calculated.

Correct me if I'm wrong, but my understanding is that in general there
is no way to know exactly how many samples swr_convert will return,
without actually calling swr_convert and seeing the result.
swr_get_out_samples will give you an _upper bound_, but you may get
less than that number. The return value of swr_convert tells you the
number of samples (per channel) that were actually filled into your

> 2. The output is in an array of uint8_t type and I have selected for
> output AV_SAMPLE_FMT_FLT. So is there a way to get output in float or
> I will have to convert this output only to float using bitwise
> operations.

swr_convert will return float data, you just need to cast. Either
declare your buffer as a buffer of floats and cast when you pass it
it, or declare it as a buffer of uint8_t and cast when you use it. I
prefer the former, but YMMV:

float* out = (pointer to buffer)
int converted_count = swr_convert(swr, (uint8_t**)&out, out_count,
(const uint8_t **) in, in_count);

>   av_opt_set_channel_layout(swr, "in_channel_layout", frame->channel_layout, 0);
>   av_opt_set_channel_layout(swr, "out_channel_layout", AV_CH_LAYOUT_MONO, 0);
>   av_opt_set_int(swr, "in_sample_rate",frame->sample_rate, 0);
>   av_opt_set_int(swr, "out_sample_rate", 5512, 0);
>   av_opt_set_sample_fmt(swr, "in_sample_fmt", src_sample_fmt, 0);
>   av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_FLT, 0);
>   ret = swr_init(swr);
>   nb_samples = av_rescale_rnd(swr_get_delay(swr, frame->sample_rate) +
> frame->nb_samples, 5512, frame->sample_rate, AV_ROUND_UP); //number of
> output samples
>   // buf_size is double of what calculated by nb_samples *
> byte_per_sample * nb_channels
>   buf_size = av_samples_alloc(&out, NULL, 2, out_count, AV_SAMPLE_FMT_FLT, 0);
>   ret = swr_convert(swr, &out, out_count, (const uint8_t **) in, in_count);
> Regards
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user

More information about the Libav-user mailing list