Reputation: 5095
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
.
Upvotes: 4
Views: 3844
Reputation: 21
you don't control the frame size explicitly, it is set by the encoder depending on the codecs provided at initialization (opening) time
once avcodec_open2()
is successful, you can retrieve the frame's buffer size with av_samples_get_buffer_size()
Upvotes: 0
Reputation: 1988
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 inavcodec_open2()
. Each submitted frame except the last must contain exactlyframe_size
samples per channel.
May be0
when the codec hasAV_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.
Upvotes: 2