考虑以下片段:(来自 https://ffmpeg.org/doxygen/trunk/encode_audio_8c-example.html )
for (i = 0; i < 200; i++) {
/* make sure the frame is writable -- makes a copy if the encoder
* kept a reference internally */
ret = av_frame_make_writable(frame);
if (ret < 0)
exit(1);
samples = (uint16_t*)frame->data[0];
for (j = 0; j < c->frame_size; j++) {
samples[2*j] = (int)(sin(t) * 10000);
for (k = 1; k < c->channels; k++)
samples[2*j + k] = samples[2*j];
t += tincr;
}
encode(c, frame, pkt, f);
}
如果我正确理解了这个例子,生成的音频流正好包含 200 帧大小 c->frame_size
它们被编码并保存到磁盘。但是,如果我想对大小为
soundsize
的通用数据流进行编码,我会有一定数量的固定大小的帧c->frame_size
,即 size_t nframes = soundsize / c->frame_size;
加上最后一帧大小: size_t rem_lastframe = soundsize % c->frame_size;
你能解释一下如何处理最后一帧吗? frame_size 似乎是由编解码器固定和选择的。
最佳答案
这就是 ffmpeg 所做的。
if (src->nb_samples < avctx->frame_size) {
ret = pad_last_frame(avctx, dst, src);
...
您可以使用 apad 过滤器或模仿 libavcodec 的功能/**
* Pad last frame with silence.
*/
static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src)
{
int ret;
frame->format = src->format;
frame->channel_layout = src->channel_layout;
frame->channels = src->channels;
frame->nb_samples = s->frame_size;
ret = av_frame_get_buffer(frame, 0);
if (ret < 0)
goto fail;
ret = av_frame_copy_props(frame, src);
if (ret < 0)
goto fail;
if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0,
src->nb_samples, s->channels, s->sample_fmt)) < 0)
goto fail;
if ((ret = av_samples_set_silence(frame->extended_data, src->nb_samples,
frame->nb_samples - src->nb_samples,
s->channels, s->sample_fmt)) < 0)
goto fail;
return 0;
fail:
av_frame_unref(frame);
return ret;
}
关于FFmpeg:如何编码最后一个音频帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66738829/