static void on_call_media_state(pjsua_call_id call_id)
{
pjsua_call_info call_info;
pjsua_call_get_info(call_id, &call_info);
if (call_info.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
pjsua_call_media_info *media = &call_info.media; // Из вашей структуры pjsua_call_media_info
if (media->type == PJMEDIA_TYPE_AUDIO) {
pjmedia_port *media_port = NULL;
pj_status_t status;
// 1. Получаем указатель на медиа-порт текущего звонка
status = pjsua_call_get_media_port(call_id, &media_port);
if (status != PJ_SUCCESS || !media_port) {
printf("[MEDIA] Error: Failed to get call media port\n");
return;
}
// 2. Идем строго по цепочке ваших структур: info -> fmt -> det.aud.clock_rate
unsigned negotiated_codec_rate = media_port->info.fmt.det.aud.clock_rate;
printf("[MEDIA] Negotiated Codec Sample Rate: %u Hz (Current: %u Hz)\n",
negotiated_codec_rate, current_bridge_rate);
// 3. Если частота кодека отличается от текущей — делаем горячую пересборку
if (negotiated_codec_rate != current_bridge_rate) {
printf("[MEDIA] Rate mismatch! Reconfiguring bridge and i.MX RT hardware...\n");
// Останавливаем низкоуровневые DMA потоки Zephyr
zephyr_i2s_stop(1); // RX
zephyr_i2s_stop(0); // TX
k_msleep(5);
// Полностью уничтожаем старый мост
pjsua_media_destroy();
// Перестраиваем тактирование кодека и I2S на i.MX RT1024
int ret = zephyr_i2s_set_rate(negotiated_codec_rate);
if (ret < 0) {
printf("[MEDIA] ERROR: Hardware failed to set rate to %u. Reverting...\n", negotiated_codec_rate);
zephyr_i2s_set_rate(current_bridge_rate);
return;
}
// Поднимаем НОВЫЙ мост PJSIP на "родной" частоте кодека
pjsua_media_config media_cfg;
pjsua_media_config_default(&media_cfg);
media_cfg.clock_rate = negotiated_codec_rate;
media_cfg.snd_clock_rate = negotiated_codec_rate;
status = pjsua_media_init(&media_cfg);
if (status != PJ_SUCCESS) {
printf("[MEDIA] CRITICAL ERROR: pjsua_media_init failed: %d\n", status);
return;
}
current_bridge_rate = negotiated_codec_rate;
// Перезапрашиваем call_info, так как порты пересоздались
pjsua_call_get_info(call_id, &call_info);
}
// 4. Коммутируем порты в новом мосту (Сеть <-> Звуковая карта)
pjsua_conf_port_id conf_slot = pjsua_call_get_conf_port_id(call_id);
pjsua_conf_connect(conf_slot, 0);
pjsua_conf_connect(0, conf_slot);
printf("[MEDIA] Audio bridged natively at %u Hz. Software resampling bypassed.\n", current_bridge_rate);
}
}
// Логика отключения (DISCONNECTED) остается без изменений...
}