freeswitch mrcp 源码分析--数据接收(上)
apt_poller_tas.apt_poller_task_run–> mrcp_client_connection.mrcp_client_poller_signal_process–>
sendrecv.apr_socket_recv –>
mrcp_stream.mrcp_parser_run –>
mrcp_client_connection.mrcp_client_message_handler–>
mrcp_client_connection.mrcp_connection_channel_find–>
mrcp_connection_types.mrcp_connection_message_receive–>
mrcp_client.mrcp_client_message_signal–>
mrcp_client.mrcp_client_connection_task_msg_signal–>
apt_task.apt_task_msg_signal–>
apt_consumer_task.apt_consumer_task_msg_signal–>
apr_queue.apr_queue_push
pt_poller_task_run是一个无线循环,会不断调用mrcp_client_poller_signal_process()函数,在mrcp_client_poller_signal_process()中,会通过apr_socket_recv函数在socket上阻塞等待数据,然后通过mrcp_parser_run解析接收到的数据包。
这个函数的实现我在博文freeswitch mrcp 源码分析–数据解析已经进行了详细介绍。
数据解析完成后会调用mrcp_client_message_handler处理接收到的数据,
在mrcp_client_message_handler中先调用mrcp_connection_channel_find通过通道编码找到对应的通道,然后调用mrcp_connection_message_receiv处理接收到的数据。
mrcp_connection_message_receive的代码如下。可以看到主要是调用了vtable->on_receive。
static APR_INLINE apt_bool_t mrcp_connection_message_receive(
const mrcp_connection_event_vtable_t *vtable,
mrcp_control_channel_t *channel,
mrcp_message_t *message)
{
if(vtable && vtable->on_receive) {
return vtable->on_receive(channel,message);
}
return FALSE;
}
vtable是一个mrcp_connection_event_vtable_t对象:
static const mrcp_connection_event_vtable_t connection_method_vtable = {
mrcp_client_channel_add_signal,
mrcp_client_channel_modify_signal,
mrcp_client_channel_remove_signal,
mrcp_client_message_signal,
mrcp_client_disconnect_signal
};
所以会执行mrcp_client_message_signal函数,进而调用mrcp_client_connection_task_msg_signal,简单组装参数后会调用apt_task_msg_signal,
APT_DECLARE(apt_bool_t) apt_task_msg_signal(apt_task_t *task, apt_task_msg_t *msg)
{
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Signal Message to [%s] ["APT_PTR_FMT";%d;%d]",
task->name, msg, msg->type, msg->sub_type);
if(task->vtable.signal_msg) {
if(task->vtable.signal_msg(task,msg) == TRUE) {
return TRUE;
}
}
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Signal Task Message [%s] [0x%x;%d;%d]",
task->name, msg, msg->type, msg->sub_type);
apt_task_msg_release(msg);
return FALSE;
}
所以主要调用了task->vtable.signal_msg函数,这里task是一个apt_task_t结构图,在创建的时候signal_msg被赋值为apt_consumer_task_msg_signal:
APT_DECLARE(apt_consumer_task_t*) apt_consumer_task_create(
void *obj,
apt_task_msg_pool_t *msg_pool,
apr_pool_t *pool)
{
apt_task_vtable_t *vtable;
apt_consumer_task_t *consumer_task = apr_palloc(pool,sizeof(apt_consumer_task_t));
consumer_task->obj = obj;
consumer_task->msg_queue = NULL;
if(apr_queue_create(&consumer_task->msg_queue,1024,pool) != APR_SUCCESS) {
return NULL;
}
consumer_task->base = apt_task_create(consumer_task,msg_pool,pool);
if(!consumer_task->base) {
return NULL;
}
vtable = apt_task_vtable_get(consumer_task->base);
if(vtable) {
vtable->run = apt_consumer_task_run;
vtable->signal_msg = apt_consumer_task_msg_signal;
}
#if APR_HAS_QUEUE_TIMEOUT
consumer_task->timer_queue = apt_timer_queue_create(pool);
#endif
return consumer_task;
}
在apt_consumer_task_msg_signal中会调用apr_queue_push将消息推入队列,并唤醒消费线程去消费。
————————————————
版权声明:本文为CSDN博主「罗自荣」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luozirong/article/details/78875325
freeswitch mrcp 源码分析--数据接收(上)相关推荐
- 【VUE】源码分析 - 数据劫持的基本原理
tips:本系列博客的代码部分(示例等除外),均出自vue源码内容,版本为2.6.14.但是为了增加易读性,会对不相关内容做选择性省略.如果大家想了解完整的源码,建议自行从官方下载.https://g ...
- 基于TCP网络通信的自动升级程序源码分析-客户端接收文件
升级程序客户端接收文件 /// <summary>/// 文件数据缓存 索引是 ConnectionInfo对象 数据包的顺序号 值是数据/// </summary>Dicti ...
- HBase源码分析之HRegion上compact流程分析(三)
在<HBase源码分析之HRegion上compact流程分析(二)>一文中,我们没有讲解真正执行合并的CompactionContext的compact()方法.现在我们来分析下它的具体 ...
- Nginx源码分析--数据对齐posix_memalign和memalign函数
posix_memalign函数() /* * 背景: * 1)POSIX 1003.1d * 2)POSIX 标明了通过malloc( ), calloc( ), 和 re ...
- 风讯dotNETCMS源码分析—数据存取篇
前几天突然对CMS感兴趣,就去下载了风讯dotNETCMS源码.当前版本是dotnetcms1.0 sp5免费版,风讯的官方主页上可以下载. 用Visual Studio 2008打开后,初步分析了它 ...
- 若依前后端分离版源码分析-前端头像上传后传递到后台以及在服务器上存储和数据库存储设计
场景 使用若依前后端分离版本时,分析其头像上传机制. 可作为续参考学习. 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获 ...
- android+小米文件管理器源码,[MediaStore]小米文件管理器android版源码分析——数据来源...
打开小米的文件管理器,我们很快会看到如下图所示的界面: 其中,会把各种文件分类显示.并且显示出每种文件的个数. 这是怎么做到的呢?当然不是每次启动都查询sdcard和应用程序data目录文件啦,那样实 ...
- freeSWITCH detect_speech源码分析
前段时间用detect_speech配合阿里的引擎做了些ASR的测试.涉及到一点源码的改动.这里记录detect_speech的源码.有助于理解FS的ASR实现. 这里的源码基于V1.8.7描述. d ...
- gre tunnel源码分析之接收流程
GRE(Generic Routing Encapsulation,通用路由封装)协议是对某些网络层协议(如IP 和IPX)的数据报文进行封装,使这些被封装的数据报文能够在另一个网络层协议(如IP)中 ...
- galler3d的源码分析——数据来源
我们这里主要讲本地sd卡的数据,pisaca看情况后续再作分析. 数据操作设计的类包括:CacheService,MediaFeed,LocalDataSource,DiskCache,MediaIt ...
最新文章
- BZOJ1747 [Usaco2005 open]Expedition 探险
- 各类木材强度_木材的力学性能
- MySQL设置某一字段默认为0,但是插入数据化却显示为null
- ServletContextListener在Springboot中的使用
- NAT模式下虚拟机与主机网络关系配置
- HTML5 Canvas的基本用法
- python相机拍照显示_从solvePnP获取摄影机姿势
- 菜鸟启动“快递包装换鸡蛋”活动 史上最低碳的一届“双11”来了
- wamp无法访问php,wamp无法访问phpmyadmin怎么办
- hibernate文档
- L298电机驱动原理图+PCB
- win10 任务栏 网络 图标 消失 空白 network location awareness 错误1068
- QDir中mkdir和mkpath的区别
- 台式计算机如何安装摄像头,台式机怎样安装摄像头
- 7-5 jmu-Java-03面向对象基础-05-覆盖 (20 分)
- Type string trivially inferred from a string literal, remove type annotation.eslint@typescript-eslin
- 记录FinalShell退格键
- python 删除文件夹下面的所有文件python删除文件夹下面的所有文件夹及子文件
- unity3dwebgl building之后没有反应_晚会是在考验明星临场反应吗?王源开场无伴奏阿云嘎差点原地跳舞...
- java 判断文件是否存在
热门文章
- 数据分析神经网络模型图,神经网络模型数据处理
- [Android系统原理及开发要点详解
- Android debug时一直处于waiting for debugger解决办法
- 王者荣耀服务器微信怎么和电脑,[技术贴]微信账号与游戏账号独立的终极版教程...
- 重积分定理与计算总结
- 【改变键盘上方向键蹩脚的位置】通过autohotkey脚本实现键盘按键重映射【便利码代码】--以上下左右键映射为capslock与hjkl组合的按键 【附源码】
- 自动化测试八宗罪- 读Test Automation Snake Oil的一点翻译和感想
- javascript中onclick(this)用法和onclick(this.value)用法介绍
- 【阿里云服务器】ECS云服务器新手上路
- 迅捷PDF转换成word转换器