pjsip抓取并播放pcm数据
pjsip capture and play pcm data
我有一些默认没有音频设备的嵌入式设备。它们通过 FPGA 相互通信。所以我的问题是,我如何 capture/play 从 pcm 中的 pjsip 返回音频以便 send/receive 使用 FPGA?
我知道有 pjmedia_mem_player_create() 和 pjmedia_mem_capture_create() 但我不能似乎找到了有关使用这些功能的任何有用信息。
我尝试了以下代码,但断言失败,因为函数的参数之一是“空”。
错误:
pjmedia_mem_capture_create: Assertion `pool && buffer && size && clock_rate && channel_count && samples_per_frame && bits_per_sample && p_port' failed.
注意:我主要将 pjsua2 用于其他一切,如注册、传输等。此外,默认音频设置为 null ep.audDevManager().setNullDev(); 如果没有这个,making/receiving 一个调用就会失败?!
void MyCall::onCallMediaState(OnCallMediaStateParam &prm){
CallInfo ci = getInfo();
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
pj_pool_t *pool = pj_pool_create(&cp.factory, "POOLNAME", 2000, 2000, NULL);
void *buffer;
pjmedia_port *prt;
#define CLOCK_RATE 8000
#define CHANELS 1
#define SAMPLES_PER_FRAME 480
#define BITS_PER_SAMPLE 16
pjmedia_mem_capture_create( pool, //Pool
buffer, //Buffer
2000, //Buffer Size
CLOCK_RATE,
CHANELS,
SAMPLES_PER_FRAME,
BITS_PER_SAMPLE,
0, //Options
&prt); //The return port}
更新
断言失败,因为缓冲区变量没有分配给它任何内存。每帧分配两倍数量的样本以具有足够的内存。
buffer = pj_pool_zalloc(pool, 960);
还需要使用 pjmedia_mem_capture_set_eof_cb2()
注册回调(PJSIP 2.10 或更高版本需要最后两个回调)显然可以从那里使用缓冲区。只是我的实现 atm 不执行回调。
看来我找到了解决方案,我已经修改了您的代码并使用 pjsua API 在 C 中编写了一个简单的代码以将每一帧转储到文件中。不好意思乱七八糟的,我对C不精通:
pjsua_call_info ci;
pjsua_call_get_info(call_id, &ci);
pjsua_conf_port_info cpi;
pjsua_conf_get_port_info(ci.conf_slot, &cpi);
pj_pool_t *pool = pjsua_pool_create("POOLNAME", 2000, 2000);
pjmedia_port *prt;
uint buf_size = cpi.bits_per_sample*cpi.samples_per_frame/8;
void *buffer = pj_pool_zalloc(pool, buf_size);
pjsua_conf_port_id port_id;
pjmedia_mem_capture_create( pool,
buffer,
buf_size,
cpi.clock_rate,
cpi.channel_count,
cpi.samples_per_frame,
cpi.bits_per_sample,
0,
&prt);
pjmedia_mem_capture_set_eof_cb(prt, buffer, dump_incoming_frames);
pjsua_conf_add_port(pool, prt, &port_id);
pjsua_conf_connect(ci.conf_slot, port_id); //connect port with conference
///////dumping frames///
static pj_status_t dump_incoming_frames(pjmedia_port * port, void * usr_data){
pj_size_t buf_size = pjmedia_mem_capture_get_size(port);
char * data = usr_data;
...
fwrite(data,sizeof(data[0]),buf_size,fptr);
...
}
文档说 pjmedia_mem_capture_set_eof_cb
已弃用,但我无法完成工作 pjmedia_mem_capture_set_eof_cb2
,buf_size
每次调用 dump_incoming_frames
时都是 0,因此仅保留已弃用的功能。我也用 creating custom port.
成功了同样的结果
希望你能轻松修改成你的C++/pjsua2代码
更新:
我修改了 PJSIP 并将音频输入输出流打包到适当的 PJSUA2/Media 类 中,以便可以从 Python 调用它。完整代码是 here.
我有一些默认没有音频设备的嵌入式设备。它们通过 FPGA 相互通信。所以我的问题是,我如何 capture/play 从 pcm 中的 pjsip 返回音频以便 send/receive 使用 FPGA?
我知道有 pjmedia_mem_player_create() 和 pjmedia_mem_capture_create() 但我不能似乎找到了有关使用这些功能的任何有用信息。
我尝试了以下代码,但断言失败,因为函数的参数之一是“空”。
错误:
pjmedia_mem_capture_create: Assertion `pool && buffer && size && clock_rate && channel_count && samples_per_frame && bits_per_sample && p_port' failed.
注意:我主要将 pjsua2 用于其他一切,如注册、传输等。此外,默认音频设置为 null ep.audDevManager().setNullDev(); 如果没有这个,making/receiving 一个调用就会失败?!
void MyCall::onCallMediaState(OnCallMediaStateParam &prm){
CallInfo ci = getInfo();
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
pj_pool_t *pool = pj_pool_create(&cp.factory, "POOLNAME", 2000, 2000, NULL);
void *buffer;
pjmedia_port *prt;
#define CLOCK_RATE 8000
#define CHANELS 1
#define SAMPLES_PER_FRAME 480
#define BITS_PER_SAMPLE 16
pjmedia_mem_capture_create( pool, //Pool
buffer, //Buffer
2000, //Buffer Size
CLOCK_RATE,
CHANELS,
SAMPLES_PER_FRAME,
BITS_PER_SAMPLE,
0, //Options
&prt); //The return port}
更新
断言失败,因为缓冲区变量没有分配给它任何内存。每帧分配两倍数量的样本以具有足够的内存。
buffer = pj_pool_zalloc(pool, 960);
还需要使用 pjmedia_mem_capture_set_eof_cb2()
注册回调(PJSIP 2.10 或更高版本需要最后两个回调)显然可以从那里使用缓冲区。只是我的实现 atm 不执行回调。
看来我找到了解决方案,我已经修改了您的代码并使用 pjsua API 在 C 中编写了一个简单的代码以将每一帧转储到文件中。不好意思乱七八糟的,我对C不精通:
pjsua_call_info ci;
pjsua_call_get_info(call_id, &ci);
pjsua_conf_port_info cpi;
pjsua_conf_get_port_info(ci.conf_slot, &cpi);
pj_pool_t *pool = pjsua_pool_create("POOLNAME", 2000, 2000);
pjmedia_port *prt;
uint buf_size = cpi.bits_per_sample*cpi.samples_per_frame/8;
void *buffer = pj_pool_zalloc(pool, buf_size);
pjsua_conf_port_id port_id;
pjmedia_mem_capture_create( pool,
buffer,
buf_size,
cpi.clock_rate,
cpi.channel_count,
cpi.samples_per_frame,
cpi.bits_per_sample,
0,
&prt);
pjmedia_mem_capture_set_eof_cb(prt, buffer, dump_incoming_frames);
pjsua_conf_add_port(pool, prt, &port_id);
pjsua_conf_connect(ci.conf_slot, port_id); //connect port with conference
///////dumping frames///
static pj_status_t dump_incoming_frames(pjmedia_port * port, void * usr_data){
pj_size_t buf_size = pjmedia_mem_capture_get_size(port);
char * data = usr_data;
...
fwrite(data,sizeof(data[0]),buf_size,fptr);
...
}
文档说 pjmedia_mem_capture_set_eof_cb
已弃用,但我无法完成工作 pjmedia_mem_capture_set_eof_cb2
,buf_size
每次调用 dump_incoming_frames
时都是 0,因此仅保留已弃用的功能。我也用 creating custom port.
希望你能轻松修改成你的C++/pjsua2代码
更新: 我修改了 PJSIP 并将音频输入输出流打包到适当的 PJSUA2/Media 类 中,以便可以从 Python 调用它。完整代码是 here.