Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

av_audio_enc_start Ringbuffer of AFE is full的问题, VOIP例程中出现的问题 (AUD-6071) #1373

Closed
JeremyXXJ opened this issue Feb 13, 2025 · 19 comments

Comments

@JeremyXXJ
Copy link

JeremyXXJ commented Feb 13, 2025

我在VOIP例程上进行修改,我有两块ESP32_S3_KORVO2_V3_BOARD开发板
我将SIP服务期去除掉并使用 UDP socket进行音频数据的传输
我的路径是这样的
发送端 av_audio_enc_start 然后av_audio_enc_read(&udp_send_audio_frame, av_stream); udp_send_audio_frame是我设置的缓存区
再接着通过sendto 发送出去
接收端 av_audio_dec_start 收到以后 int received = recvfrom(sock, udp_receive_audio_frame.data, 160, 0, (struct sockaddr *)&source_addr, &addr_len); ,av_audio_dec_write(&udp_receive_audio_frame, av_stream);再解码播放。
这是只接受和发送没有问题。

情况1:但是当我全双工的时候 一边录制一边播放的时候出现了问题,AFE_VC: Ringbuffer of AFE is full, Please use fetch() to retrieve data from the ringbuffer soon to avoid data loss or overwriting!!! 报错并且此时抓包没有数据传输 ,打印日志发现两端均在打印AFE_VC: Ringbuffer of AFE is full, Please use fetch() to retrieve data from the ringbuffer soon to avoid data loss or overwriting!!!

情况2: 在半双工的基础上,当我再接收端加上网络发送和编码的代码时,发现可以正常发送数据,此时我又加了一个板子作为接收端,第三个板子出现了声音的延迟。

情况3: 在半双工的基础上,当我再发送端加上网络接收和解码的代码时,报错
AFE_VC: Ringbuffer of AFE is full, Please use fetch() to retrieve data from the ringbuffer soon to avoid data loss or overwriting!!!
AFE_VC: Ringbuffer of AFE is full, Please use fetch() to retrieve data from the ringbuffer soon to avoid data loss or overwriting!!!
此时无法正常工作了。

@JeremyXXJ JeremyXXJ changed the title av_audio_enc_start Ringbuffer of AFE is full的问题, VOIP例程中出现的 av_audio_enc_start Ringbuffer of AFE is full的问题, VOIP例程中出现的问题 Feb 13, 2025
@github-actions github-actions bot changed the title av_audio_enc_start Ringbuffer of AFE is full的问题, VOIP例程中出现的问题 av_audio_enc_start Ringbuffer of AFE is full的问题, VOIP例程中出现的问题 (AUD-6071) Feb 13, 2025
@JeremyXXJ
Copy link
Author

值得一提是当我修改 UDP数据收发线程的 延时时间从30到100也会出现这个日志 同时出现声音出现了延迟

@ALToast
Copy link

ALToast commented Feb 13, 2025

Hi @JeremyXXJ ,该打印提示您 afe 的输出 buffer 已满,可以提高 afe->fetch() 的执行频率尽快取走数据。

@shootao
Copy link

shootao commented Feb 13, 2025

@JeremyXXJ 打印出现task 信息, 看一下 task 的状态

@JeremyXXJ
Copy link
Author

@JeremyXXJ 打印出现task 信息, 看一下 task 的状态

Image

Image

Image

Image

Image

Image这是日志 和状态 十分感谢您

@shootao
Copy link

shootao commented Feb 13, 2025

你这个怀疑是 aec 出来之后的数据 没有处理导致的

@JeremyXXJ
Copy link
Author

Hi @JeremyXXJ ,该打印提示您 afe 的输出 buffer 已满,可以提高 afe->fetch() 的执行频率尽快取走数据。

好的感谢您 我会排查一下您说的问题

@JeremyXXJ
Copy link
Author

你这个怀疑是 aec 出来之后的数据 没有处理导致的

static void _audio_enc(void* pv)
{
av_stream_handle_t av_stream = (av_stream_handle_t) pv;
xEventGroupClearBits(av_stream->aenc_state, ENCODER_STOPPED_BIT);

char *frame_buf = NULL;
int len = 0, timeout = 25 / portTICK_PERIOD_MS;
int16_t *g711_buffer_16 = NULL;

if (av_stream->config.acodec_type == AV_ACODEC_AAC_LC) {
    frame_buf = audio_malloc_align(16, AUDIO_MAX_SIZE);
} else {
    frame_buf = audio_calloc(1, AUDIO_MAX_SIZE);
    g711_buffer_16 = (int16_t *)(frame_buf);
}
AUDIO_NULL_CHECK(TAG, frame_buf, return);

while (av_stream->aenc_run) {
    int read_len = raw_stream_read(av_stream->audio_enc_read, frame_buf, av_stream->config.hal.audio_framesize);
    if (read_len == AEL_IO_TIMEOUT) {
        continue;
    } else if (read_len < 0) {
        break;
    }

    av_stream_frame_t enc;
    enc.len = read_len;
    enc.data = audio_calloc(1, AUDIO_MAX_SIZE);
    AUDIO_NULL_CHECK(TAG, enc.data, break);
    av_stream->audio_pos += enc.len;
    enc.pts = (av_stream->audio_pos * 1000) / (av_stream->config.hal.audio_samplerate * 1 * 16 / 8);
    switch ((int)av_stream->config.acodec_type) {
        case AV_ACODEC_PCM:
            memcpy(enc.data, frame_buf, enc.len);
            break;
        case AV_ACODEC_AAC_LC:
            esp_aac_enc_process(av_stream->aac_enc, (uint8_t *)frame_buf, enc.len, enc.data, &len);
            enc.len = len;
            timeout = 0;
            break;
        case AV_ACODEC_G711A:
            for (int i = 0; i < enc.len; i++) {
                enc.data[i] = esp_g711a_encode(g711_buffer_16[i]);
            }
            enc.len = enc.len/2;
            break;
        case AV_ACODEC_G711U:
            for (int i = 0; i < enc.len; i++) {
                enc.data[i] = esp_g711u_encode(g711_buffer_16[i]);
            }
            enc.len = enc.len/2;
            break;
    }
    if (xQueueSend(av_stream->aenc_queue, &enc, timeout) != pdTRUE) {
        ESP_LOGD(TAG, "send aenc buf queue timeout !");
        free(enc.data);
    }
}
ESP_LOGI(TAG, "_audio_enc task stoped");

if (av_stream->config.acodec_type == AV_ACODEC_AAC_LC) {
    jpeg_free_align(frame_buf);
} else {
    free(frame_buf);
}

xEventGroupSetBits(av_stream->aenc_state, ENCODER_STOPPED_BIT);
vTaskDelete(NULL);

} 您好这会是库函数的问题吗 因为我没有对库函数做修改 我仅仅是调用了这个函数 我在发送端调用该函数的时候没有出现问题 只是修改循环延时的时候 出现了 这个问题已经困扰了我很久了 aec 出来之后的数据是在哪里进行处理呢 很抱歉这个时间打扰到您

@JeremyXXJ
Copy link
Author

你这个怀疑是 aec 出来之后的数据 没有处理导致的

从声音来看 他确实和VOIP例程里的声音不一样 有一些回音

@shootao
Copy link

shootao commented Feb 13, 2025

把你的 整个 c 文件贴出来看看

@JeremyXXJ
Copy link
Author

把你的 整个 c 文件贴出来看看

voip.txt或有一些语法错误 此时板子不在身边

@shootao
Copy link

shootao commented Feb 13, 2025

av_stream.c 里面的代码有改过嘛?

@JeremyXXJ
Copy link
Author

av_stream.c 里面的代码有改过嘛?

应该没有 我明天再确认下

@JeremyXXJ
Copy link
Author

av_stream.c 里面的代码有改过嘛?

voip.txt
av_stream.txt 没有修改过

@TempoTian
Copy link
Contributor

看代码应该是自己实现的 VOIP,encode 完的数据可以保存下来听听是否有问题。没问题整个encoder通路都就是OK的。
encode 完的数据会通过网络发送,确保发送接收task的优先级较高比如编码抢占而不被占用。另外用socket尽量不要用delay的方式可以用 selec t取,monitor可用状态。

@JeremyXXJ
Copy link
Author

看代码应该是自己实现的 VOIP,encode 完的数据可以保存下来听听是否有问题。没问题整个encoder通路都就是OK的。 encode 完的数据会通过网络发送,确保发送接收task的优先级较高比如编码抢占而不被占用。另外用socket尽量不要用delay的方式可以用 selec t取,monitor可用状态。

谢谢您的指导 我想知道我现在暂时不用select 出现我所提到的问题吗 encode在半双工时看起来是没有问题的 “确保发送接收task的优先级较高比如编码抢占而不被占用”这句话我不太理解 是要网络发送任务的优先级高于编解码中 21的优先级吗

@TempoTian
Copy link
Contributor

是的,编解码配置为21太高了,网络任务优先级要高于编解码任务的优先级。保证网络低CPU占用率的任务能及时调度到

@JeremyXXJ
Copy link
Author

是的,编解码配置为21太高了,网络任务优先级要高于编解码任务的优先级。保证网络低CPU占用率的任务能及时调度到

我已经修改了,但问题没有解决 ,此时我又丰富了一下 出现情况的描述,希望您能给予指导

情况1:但是当我全双工的时候 一边录制一边播放的时候出现了问题,AFE_VC: Ringbuffer of AFE is full, Please use fetch() to retrieve data from the ringbuffer soon to avoid data loss or overwriting!!! 报错并且此时抓包没有数据传输 ,打印日志发现两端均在打印AFE_VC: Ringbuffer of AFE is full, Please use fetch() to retrieve data from the ringbuffer soon to avoid data loss or overwriting!!!

情况2: 在半双工的基础上,当我再接收端加上网络发送和编码的代码时,发现可以正常发送数据,此时我又加了一个板子作为接收端,第三个板子出现了声音的延迟。

情况3: 在半双工的基础上,当我再发送端加上网络接收和解码的代码时,报错
AFE_VC: Ringbuffer of AFE is full, Please use fetch() to retrieve data from the ringbuffer soon to avoid data loss or overwriting!!!
AFE_VC: Ringbuffer of AFE is full, Please use fetch() to retrieve data from the ringbuffer soon to avoid data loss or overwriting!!!
此时无法正常工作了。

@TempoTian
Copy link
Contributor

看样子你编码发送的逻辑是通的。你可以加一下log对比下。正常和NG情况下从AFE读了多少比数据,编码了多少次。log看主要是读慢了。你可以把一些环节注释掉看到底是哪里引起的。比如注释掉发送,注释掉解码等。

@JeremyXXJ
Copy link
Author

看样子你编码发送的逻辑是通的。你可以加一下log对比下。正常和NG情况下从AFE读了多少比数据,编码了多少次。log看主要是读慢了。你可以把一些环节注释掉看到底是哪里引起的。比如注释掉发送,注释掉解码等。

感谢!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants