Загрузка данных
#include <pjsua-lib/pjsua.h>
#include <pjsua-lib/pjsua_internal.h> // Обязательно для доступа к pjsua_var
#include <zephyr_i2s_dev.h>
static unsigned current_bridge_rate = 16000;
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;
if (media->type == PJMEDIA_TYPE_AUDIO) {
// 1. Получаем медиа-порт напрямую из внутренней структуры звонка pjsua_var
// Вы присылали структуру pjsua_call_media с полем a.media_port
// Индекс медиа обычно 0 для первого аудио-потока
pjmedia_port *media_port = pjsua_var.calls[call_id].media[0].a.media_port;
if (!media_port) {
printf("[MEDIA] Error: Internal call media port is NULL\n");
return;
}
// 2. Читаем согласованную частоту кодека
unsigned negotiated_codec_rate = media_port->info.fmt.det.aud.clock_rate;
printf("[MEDIA] Negotiated Codec Rate: %u Hz (Current Bridge: %u Hz)\n",
negotiated_codec_rate, current_bridge_rate);
// 3. Перестраиваем мост, если частота изменилась
if (negotiated_codec_rate != current_bridge_rate) {
printf("[MEDIA] Rate mismatch! Restarting subsystems for native %u Hz...\n", negotiated_codec_rate);
// Шаг А: Останавливаем I2S Zephyr
zephyr_i2s_stop(1); // RX
zephyr_i2s_stop(0); // TX
k_msleep(5);
// Шаг Б: Гасим медиа-подсистему вашим методом
pjsua_media_subsys_destroy(0);
// Шаг В: Перестраиваем физические такты i.MX RT1024 и аудиокодека
int ret = zephyr_i2s_set_rate(negotiated_codec_rate);
if (ret < 0) {
printf("[MEDIA] ERROR: Hardware failed to change clocks. Reverting...\n");
zephyr_i2s_set_rate(current_bridge_rate);
// Переподнимаем старую конфигурацию
pjsua_media_subsys_init(&pjsua_var.media_cfg);
pjsua_media_subsys_start();
return;
}
// Шаг Г: Подменяем конфигурацию частоты во внутренней глобальной структуре
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;
// Шаг Д: Запускаем подсистему заново вашими функциями под новый рейт
pj_status_t status = pjsua_media_subsys_init(&media_cfg);
if (status != PJ_SUCCESS) {
printf("[MEDIA] CRITICAL: Subsys init failed: %d\n", status);
return;
}
status = pjsua_media_subsys_start();
if (status != PJ_SUCCESS) {
printf("[MEDIA] CRITICAL: Subsys start failed: %d\n", status);
return;
}
current_bridge_rate = negotiated_codec_rate;
// Перезапрашиваем данные звонка
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 via sub-system hot-swap.\n", current_bridge_rate);
}
}
// Логика DISCONNECTED
else if (call_info.state == PJSUA_CALL_STATE_DISCONNECTED) {
if (current_bridge_rate != 16000) {
printf("[MEDIA] Call ended. Returning sub-systems to idle 16kHz...\n");
zephyr_i2s_stop(1);
zephyr_i2s_stop(0);
pjsua_media_subsys_destroy(0);
zephyr_i2s_set_rate(16000);
current_bridge_rate = 16000;
pjsua_media_config media_cfg;
pjsua_media_config_default(&media_cfg);
media_cfg.clock_rate = 16000;
media_cfg.snd_clock_rate = 16000;
pjsua_media_subsys_init(&media_cfg);
pjsua_media_subsys_start();
}
}
}