feng 的模块(框架)以及运作过程
来源:互联网 发布:淘宝客怎么推广到qq群 编辑:程序博客网 时间:2024/06/06 17:50
一、feng 的框架:
feng 的网络库
feng 使用是轻量级的事件库libev,
二、feng 是如何处理数据的
1、当处理PLAY请求时,feng 调用函数rtp_session_gslist_resume为每一个媒体(track)恢复播放,rtp_session_resume,在该函数,创建了一个线程池,线程数据为1个,(如果多个如何保存有序),线程池的回调是rtp_session_fill_cb,这个线程就是不停地从文件中读出数据,实际是调用钩子avf_read_packet从文件中读出数据,(暂停不知道读了多少数据),读出以后,调用ret = tr->parser->parse(tr, pkt.data, pkt.size);, 实际是调用h264.c注册的钩子,h264_parse, 分为avc格式和常规格式(avc格式起始码是一帧的长度,常规格式起始码是00000001), 我们先看常规格式,即起始码为00000001。
2、接着1,h264_parse其实就是分片,先找到一个nal(找到下一个起始码即可),判断nal的长度,如果小于一个MTU的大小,调用mparser_buffer_write,将数据写入feng 的bufferqueue,实际相当于一个生产者,(这个在PLAY请求后,创建线程池运行的),这么说,bufferqueue(用于数据的一生产多消费), 放入的是nal,即一个元素是nal,
这个小于MTU的nal直接就是rtp的数据了。
3、在PLAY中我们知道,在创建完线程池后,又创建了一个周期性读的rtp_write,这个函数周期性在rtp_write中,读出数据,这个周期性的写的函数可能是在SETUP,创建会话rtp_session_new创建的, 那么执行写的函数就是rtp_write_cb,在这里有足够的数据了,没有足够数据就等一个足够取到数据的时间,有了足够数据,就调用rtp_packet_send(session, buffer);将数据发出,
三、feng 程序运行过程:
1、在incoming.c中feng 调用feng_bind_port函数,生成主线程的监听fd(套接字),并注册回调rtsp_client_incoming_cb,这里使用的是半同步,半异步的reactor;
2、收到客户端的连接请求后,分别为连接返回的客户端fd, 注册可写,可读,异步断开连接,注册的回调为rtsp_write_cb, rtsp_read_cb, client_ev_disconnect_handler, 分别处理写,读,断开的事件;
3、当收到客户端RTSP请求后,回调rtsp_read_cb执行,通过rtsp_sock_read,将数据读出后,这时是rtsp消息(以两个/r/n/r/n结尾),调用RTSP_handler来处理相应的请求,这里面有这个处理方法的指针数据,比较有意思
enum RTSP_method_token {
RTSP_ID_ERROR = ERR_GENERIC,
RTSP_ID_DESCRIBE,
RTSP_ID_ANNOUNCE,
RTSP_ID_GET_PARAMETERS,
RTSP_ID_OPTIONS,
RTSP_ID_PAUSE,
RTSP_ID_PLAY,
RTSP_ID_RECORD,
RTSP_ID_REDIRECT,
RTSP_ID_SETUP,
RTSP_ID_SET_PARAMETER,
RTSP_ID_TEARDOWN
};
static const rtsp_method_function methods[] = {
[RTSP_ID_DESCRIBE] = RTSP_describe,
[RTSP_ID_SETUP] = RTSP_setup,
[RTSP_ID_TEARDOWN] = RTSP_teardown,
[RTSP_ID_OPTIONS] = RTSP_options,
[RTSP_ID_PLAY] = RTSP_play,
[RTSP_ID_PAUSE] = RTSP_pause
};
调用相应的消息的函数,进行处理methods[req->method_id](rtsp, req);
4、处理DESCRIBE 消息,先调用r_find_demuxer找到相应的文件的分离器(用于将包在一起的媒体分离出来),
在r_find_demuxer执行时,先注册钩子,用于不同的流类型的处理,
static const Demuxer *const demuxers[] = {
#ifdef LIVE_STREAMING
&fnc_demuxer_sd,
#endif
&fnc_demuxer_ds,
&fnc_demuxer_avf,
NULL
};
然后来打开r_open_direct相应的文件,如果是avf类型(可能是文件类型),使用avf_init来初始化。
......
(未完待续)
- feng 的模块(框架)以及运作过程
- AJAX的运作过程
- fork()的运作过程
- 关于EasyUI的combobox的data属性以及它的运作过程
- 关于EasyUI的combobox的data属性以及它的运作过程
- iPhone开发学习笔记——Core Data 框架及运作过程和设计的类
- 基于容错的框架设计以及处理(T模块和S模块)
- SUN的苦苦运作以及微软的“阳谋”
- linux文件系统的运作以及挂载点的意义
- 使用Intent调用其他活动的方法以及运作流程
- 产品开发过程中的IPT的组成与运作模式
- Hadoop-Yarn-框架原理及运作机制(原理篇)
- Spring框架分为哪七大模块以及各模块的主要功能作用
- yii框架的模块(module)配置
- 框架的种子模块
- 风险投资的运作程序
- APQP的运作实务
- WSDL 的内部运作
- uva 10066 - The Twin Towers(动态规划-最长公共子序列)
- .Net下的 ORM框架介紹
- 02-cookie的增删改查
- Windows平台上 Matlab 关于g++下面的编译,成功修改。
- 中断分类
- feng 的模块(框架)以及运作过程
- Hibernate主键生成方式
- 商业智能领域需要了解的数据库优化理论
- iphone/ipad实现自定义的开关UISwitch(continuous,clipsToBounds,userInteractionEnabled属性)
- KVM/QEMU桥接网络设置及kvm资料
- C++实现设计模式: PIMPL IDIOM
- 查看Android的内存
- PHP之文件系统处理_解析目录路径
- 修改mysql最大连接数