Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ffmpeg audio encoder frame size

I need to convert audio data from AV_CODEC_ID_PCM_S16LE to AV_CODEC_ID_PCM_ALAW and I am using this code as an example. The example code does essentially this (error checking omitted for brevity):

const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
AVCodecContext* c = avcodec_alloc_context3(codec);
c->bit_rate       = 64000;
c->sample_fmt     = AV_SAMPLE_FMT_S16;
c->sample_rate    = select_sample_rate(codec);
c->channel_layout = select_channel_layout(codec);
c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
avcodec_open2(c, codec, NULL);
AVFrame* frame = av_frame_alloc();
frame->nb_samples     = c->frame_size;
frame->format         = c->sample_fmt;
frame->channel_layout = c->channel_layout;

The example code subsequently uses c->frame_size in a for loop.

My code is similar to the above with the following differences:

const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_PCM_ALAW);
c->sample_rate    = 8000;
c->channel_layout = AV_CH_LAYOUT_MONO;
c->channels       = 1;

After calling avcodec_open2, c->frame_size is zero. The example code never sets the frame size so I assume that it expects either avcodec_alloc_context3 or avcodec_open2 to set it. Is this a correct assumption? Is the setting of the frame size based on the codec being used? If I have to set the frame size explicitly, is there a recommended size?

EDIT:

Based on @the-kamilz answer it appears that the example code is not robust. The example assumes that c->frame_size will be set but that appears to be dependent on the codec. In my case, codec->capabilities was in fact set to AV_CODEC_CAP_VARIABLE_FRAME_SIZE. So I modified my code to check c->frame_size and use it only if it is not zero. If it is zero, I just picked an arbitrary one second worth of data for frame->nb_samples.

like image 842
Jim Rhodes Avatar asked Oct 14 '25 07:10

Jim Rhodes


1 Answers

In the FFmpeg documentation it is mentioned as:

int AVCodecContext::frame_size

Number of samples per channel in an audio frame.

encoding: set by libavcodec in avcodec_open2(). Each submitted frame except the last must contain exactly frame_size samples per channel.
May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the frame size is not restricted.
decoding: may be set by some decoders to indicate constant frame size

Hope that helps.

like image 169
the kamilz Avatar answered Oct 17 '25 11:10

the kamilz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!