gpt4 book ai didi

c++ - 如何将音频数据放入 AVFrame 进行编码

转载 作者:行者123 更新时间:2023-12-03 00:24:50 32 4
gpt4 key购买 nike

我尝试将原始 PCM 声音编码为 G711A 和 G711U,然后对其进行解码,使用此编解码器一切正常,因为我可以为 AVCodecContext frame_size 选择任何值进行编码,但在 Opus 编解码器的情况下,AVCodecContext frame_size 等于 120,所以如果我理解正确,如果我的输入数据数组大小大于 120,那么我需要进行某种缓冲并将我的输入数据分成几个部分,然后依次将其放入 AVFrame->data 并将 AVFrame 传递给编码。

结果我得到了一个非常糟糕的声音,我不仅在使用 Opus 编解码器时得到这个结果,而且在 G711 中如果我将它的 AVCodecContext frame_size 设置为某个小于我输入数据大小的值。

所以我的问题是:如果输入数据的大小大于 AVCodecContext frame_size,那么编码输入数据的正确方法是什么?我是否需要将我的输入数据拆分为 <= AVCodecContext frame_size 如果是这样我应该怎么做?

此时我的代码如下所示:

void encode(uint8_t *data, unsigned int length)
{
int rawOffset = 0;
int rawDelta = 0;
int rawSamplesCount = frameEncode->nb_samples <= length ? frameEncode->nb_samples : length;

while (rawSamplesCount > 0)
{
memcpy(frameEncode->data[0], &data[rawOffset], sizeof(uint8_t) * rawSamplesCount);

encodeFrame();

rawOffset += rawSamplesCount;
rawDelta = length - rawOffset;
rawSamplesCount = rawDelta > frameEncode->nb_samples ? frameEncode->nb_samples : rawDelta;
}

av_frame_unref(frameEncode);
}

void encodeFrame()
{
/* send the frame for encoding */
int ret = avcodec_send_frame(contextEncoder, frameEncode);
if (ret < 0)
{
LOGE(TAG, "[encodeFrame] avcodec_send_frame error: %s", av_err2str(ret));
return;
}

/* read all the available output packets (in general there may be any number of them) */
while (ret >= 0)
{
ret = avcodec_receive_packet(contextEncoder, packetEncode);
if (ret < 0 && ret != AVERROR(EAGAIN)) LOGE(TAG, "[encodeFrame] error in avcodec_receive_packet: %s", av_err2str(ret));
if (ret < 0) break;
std::pair<uint8_t*, unsigned int> p = std::pair<uint8_t*, unsigned int>();
p.first = (uint8_t *)(malloc(sizeof(uint8_t) * packetEncode->size));
memcpy(p.first, packetEncode->data, (size_t)packetEncode->size);
p.second = (unsigned int)(packetEncode->size);

listEncode.push_back(p); // place encoded data into list to finally create one array of encoded data from it
}
av_packet_unref(packetEncode);
}

您可以看到我将输入数据分成几个部分,然后将其放入 frame->data 中,然后将帧传递给编码,但我不确定这是正确的方法。

UPD:我注意到,当我使用 G711 时,如果我将 AVCodecContext frame_size 设置为 160,并且我的输入数据大小为 160 或 320,一切正常,但如果输入数据大小为 640,那么我会听到糟糕的嗡嗡声。

最佳答案

你说了这么多,“所以如果我理解正确,如果我的输入数据数组大小大于 120,那么我需要做一些缓冲并将我的输入数据分成几个部分,然后依次将其放入 AVFrame->data 并传递AVFrame 进行编码。”

这就是你需要的。 BUffer样本并每次发送固定数量进行编码。

关于c++ - 如何将音频数据放入 AVFrame 进行编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61224796/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com