pjsip 捕获和播放 pcm 数据 [英] pjsip capture and play pcm data

查看:280
本文介绍了pjsip 捕获和播放 pcm 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些默认情况下没有音频设备的嵌入式设备.它们通过 FPGA 相互通信.所以我的问题是,如何从 pcm 中的 pjsip 捕获/播放音频,以便使用 FPGA 发送/接收它?

I have some embedded Devices that have no audio device by default. They communicate with each other via a FPGA. So my question is, how do I capture/play back audio from pjsip in pcm in order to send/receive it with the FPGA?

我知道有 pjmedia_mem_player_create()pjmedia_mem_capture_create() 但我似乎找不到关于使用这些函数的任何好的信息.

I know that there is pjmedia_mem_player_create() and pjmedia_mem_capture_create() but I can't seem to find any good info towards using these functions.

我尝试了以下代码,但断言失败,导致函数的参数之一为空".

I tried the following piece of code, but an assertion failed cause one of the function's parameter is "empty".

错误:

pjmedia_mem_capture_create:断言`pool &&缓冲&&尺寸&&时钟速率&&channel_count &&samples_per_frame &&bits_per_sample &&p_port' 失败.

pjmedia_mem_capture_create: Assertion `pool && buffer && size && clock_rate && channel_count && samples_per_frame && bits_per_sample && p_port' failed.

注意:我主要将 pjsua2 用于其他一切,例如注册、传输等.此外,使用 ep.audDevManager().setNullDev(); 将默认音频设置为 null/em> 如果没有这个,拨打/接听电话就会失败?!

Note: I'm mainly using pjsua2 for everything else like registrations, transports etc. Also the default audio is set to null with ep.audDevManager().setNullDev(); as without this, making/receiving a call would simply fail?!

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}

更新

断言失败导致缓冲区变量没有分配任何内存.每帧分配两倍的样本量以获得足够的内存.

The assertion failed cause the buffer variable doesn't have any memory allocated to it. Allocate with twice the amount of samples per frame to have sufficient memory.

 buffer = pj_pool_zalloc(pool, 960);

还需要使用 pjmedia_mem_capture_set_eof_cb2() 注册回调(PJSIP 2.10 或更高版本需要末尾的两个)显然可以使用缓冲区.只是我的实现 atm 不执行回调.

Also a callback needs to be registered with pjmedia_mem_capture_set_eof_cb2() (The two at the end is necessary for PJSIP 2.10 or later) Apparently from there the buffer can be used. Just that my implementation atm doesn't execute the callback.

推荐答案

看起来我找到了解决方案,我修改了您的代码并使用 pjsua API 用 C 语言编写了一个简单的代码,将每一帧转储到文件中.对不起,我不精通 C:

Looks like I found the solution, I have modified your code and wrote a simple code in C with pjsua API to dump every frame to file. Sorry for mess, I'm not proficient in 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_cb2buf_size 每次调用dump_incoming_frames 所以只留下不推荐使用的功能.我也通过创建自定义端口取得了同样的结果.

Documenation says pjmedia_mem_capture_set_eof_cb is deprecated but I couldn't make work pjmedia_mem_capture_set_eof_cb2, buf_size is 0 for every call of dump_incoming_frames so just left with deprecated function. I also succeed the same result with creating custom port.

我希望你可以轻松地将其修改为你的 C++/pjsua2 代码

I hope you can modify it easily to your C++/pjsua2 code

更新:我已经修改了 PJSIP 并将音频输入输出流打包到适当的 PJSUA2/Media 类中,以便可以从 Python 调用它.完整代码在这里.

UPD: I have modified the PJSIP and packed audio in-out streaming into proper PJSUA2/Media classes so it can be called from Python. Full code is here.

这篇关于pjsip 捕获和播放 pcm 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆