Why does avcodec_fill_audio_frame return -22 when only sample count is different?

主宰稳场 提交于 2021-02-10 14:19:44

问题


My problem is very fast to explain: I have to encode audio samples using FFmpeg (raw PCM to G.711 mu-law). This is the guilty part of my code (I put raw parameters in this example to be explicit):

AVFrame* frame = av_frame_alloc();
frame->nb_samples = 8000;
frame->format = AV_SAMPLE_FMT_S16;
frame->channels = 1;
frame->channel_layout = AV_CH_LAYOUT_MONO;
frame->sample_rate = 8000;
frame->quality = 1;

int res = avcodec_fill_audio_frame(frame, 1, AV_SAMPLE_FMT_S16, /*my samples data*/, 16000, 0);

// If res >= 0, continue with avcodec_encode_audio2

And it works :) ... Well, I mean...

When my input is 8000 audio samples (S16 format so 16000 bytes), it works. But when I have 6000 audio samples (still S16 format so 12000 bytes), it fails with a -22 (invalid parameters). Any idea?

PRECISION: This sample count is not dynamically changing. I have sessions with data always composed by 8000 sample (and it works), and other sessions with data always composed by 6000 sample (and it fails). Sample count and data size are the only parameters that are not the same between these sessions.

EDIT: If I set or not the frame_size field in AVCodecContext, it returns to 0 after avcodec_open2 but the mu-law encoder selected has the AV_CODEC_CAP_VARIABLE_FRAME_SIZE capability so it sounds normal.


回答1:


The input to each call to avcodec_encode_audio2() should be exactly N samples, where N is AVCodecContext::frame_size. In some cases this depends on the codec (e.g. mp3 frame size is constant), but in other cases it can be variable. It should still be constant in an encoding for most encoders. It looks like your value is just whatever the default was and mulaw has no built-in constant, so you can just specify a different frame_size value before calling avcodec_open2() and you should be OK.

If your number of samples chnages dynamically, you need a ring buffer to make sure the input to avcodec_encode_audio2() still has a constant number of samples.




回答2:


Ok, I solved my own question, this was an alignment issue. There is two ways to solve it:

  • Giving input buffer initialized and filled according to the default alignment desired by libavcodec. You can use av_samples_get_buffer_size with the alignment value to 0 get the proper size.

  • Calling avcodec_fill_audio_frame with the alignment param to 1 to ignore alignment.

Hope this will help someone else :)



来源:https://stackoverflow.com/questions/45241185/why-does-avcodec-fill-audio-frame-return-22-when-only-sample-count-is-different

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!