SRS4.0源码分析
文章平均质量分 76
Loken2020
音视频工程师,《FFmpeg原理》作者
展开
-
ST源码分析-协程局部变量
《ST源码分析-st_thread_create》跟 《ST源码分析-内存保护》两篇文章,讲解了,协程函数的栈内存就是下图的区域,如下:下面就来验证一下协程函数的局部变量是不是真的存储到这块内存区域。还是用lookupdns做演示。首先,在st_thread_create()函数加上以上代码。stack->sp = sp - _ST_STACK_PAD_SIZE;//下面是调试代码。printf("stack->stk_bottom is %p \r\n",stack...原创 2022-05-09 14:22:32 · 720 阅读 · 0 评论 -
ST源码分析-内存保护
st_thread_create()创建协程的时候,会调_st_stack_new()来申请一块内存,_st_stack_new()里面额外申请了2*REDZONE的内存,在我的电脑上 一个REDZONE是 4096 字节。这个 两个REDZONE是一个在栈顶,一个在栈底。,如下图:如上图代码所示,棕色的内存块2*REDZONE被 函数mprotect()保护起来了。mprotect()函数可以修改调用进程内存页的保护属性,如果调用进程尝试以违反保护属性的方...原创 2022-05-09 14:20:57 · 546 阅读 · 0 评论 -
ST源码分析-st_thread_join
本文主要讲解,st_thread_join()函数的使用 ,参考文档《st_thread_join》。下面用一个小的示例代码,演示一下st_thread_join()函数 的使用。#include <stdio.h>#include <memory.h>#include "st.h"#include "../common.h"#include <stdlib.h>int do_something(void *arg) { st_utim...原创 2022-05-09 14:19:56 · 534 阅读 · 0 评论 -
ST源码分析-协程通信
在讲解之前,推荐阅读 State-thread 的官方文章,每个函数的使用在文档都有讲解。《State-thread函数使用文档》在 Linux 系统使用 多线程的时候,线程间通信,可以使用条件变量以及互斥锁。例如 线程 A 是生产者,不断写入任务到队列,线程 B 是消费者,不断从队列读取任务,没有任务的时候,线程B会阻塞,等待 线程A通知。这个通知就需要用到条件变量以及互斥锁。pthread_mutex_lock()以及pthread_cond_wait()ST 的协程 跟线程...原创 2022-05-09 14:19:11 · 787 阅读 · 0 评论 -
ST源码分析-st_usleep
由于 ST 库是单线程程序,如果使用了unistd.h里面的sleep()或者usleep()函数,就会阻塞所有协程函数的执行。但是有时候,某个协程确实要sleep休眠一些时间,那怎么办?ST 库提供了st_usleep()函数,使用这个函数,就可以让某个协程休眠一段时间,但是又不会阻塞其他的协程函数的执行。下面就用一小段代码演示一下st_usleep()的用法,代码如下,为了简洁,省略了错误处理。#include <stdio.h>#include "st....原创 2022-05-09 14:18:35 · 807 阅读 · 0 评论 -
ST源码分析-退出处理
在文章《ST源码分析-st_thread_exit》分析lookupdns的时候,当时没有仔细讲解lookupdns的退出处理。主要有两个退出处理。1,do_resolve()普通协程函数的退出处理。2,main(),始祖协程函数的退出处理。do_resolve()的流程图如下:如上图所示,会阻塞在st_recvfrom()。最后return NULL,但是有一个问题,st_thread_create()创建协程函数do_resolve()的时候,使用了_st_...原创 2022-05-09 14:18:04 · 685 阅读 · 0 评论 -
ST源码分析-server
本文主要讲解,ST 提供的示例程序server,make编译之后,会在obj目录生成server可执行文件,如下:server是一个 简单的http服务器,访问之后输出一个 简单的html页面,使用命令如下:./obj/server -l ./ -b 192.168.0.122:8888在刚开始调试的时候,推荐加上-i选项,可以防止server在后台运行。server流程图如下:上面流程几个比较简单的函数,我简单过一遍:1,parse_ar...原创 2022-05-09 14:17:11 · 841 阅读 · 0 评论 -
ST源码分析-proxy
本文主要讲解,ST 提供的示例程序proxy,make编译之后,会在obj目录生成proxy可执行文件,如下:proxy是一个流量代理程序,可以把TCP流量转发给远程服务器,使用命令如下:用 -X 是只开启一个进程,简单起见,先讲解单进程的逻辑。./obj/proxy -X -l 192.168.0.122:8999 -r 124.223.94.246:80上面的命令,会把所有访问192.168.0.122机器的8999端口的TCP流量,全部转发给124....原创 2022-05-09 13:48:52 · 395 阅读 · 0 评论 -
ST源码分析-运行协程
本文 基于 命令./obj/lookupdns www.xianwaizhiyin.net www.baidu.com做讲解,查询两个个域名。lookupdns里面的do_resolve()函数前面的执行步奏如下:本文 主要 讲解do_resolve()函数的逻辑,以及它里面使用的st_recvfrom()为何不会阻塞另一个协程的do_resolve()的运行。do_resolve()里面一些 域名相关的 API 函数的调用,本文不过多讲解。do_resolve()...原创 2022-04-24 00:22:46 · 609 阅读 · 0 评论 -
ST源码分析-st_thread_exit
本文 基于 命令./obj/lookupdns www.xianwaizhiyin.net做讲解,只查询一个域名。本文 主要分析st_thread_exit()函数的内部实现。请看下图:st_thread_exit()第一次只会执行_ST_SWITCH_CONTEXT(thread);这个代码。其他逻辑先不管,第一次不会跑进去,最后面有一个递归调用的。下面详细讲解_ST_SWITCH_CONTEXT()函数的实现,定义如下:/* * Switch away from ...原创 2022-04-24 00:21:03 · 405 阅读 · 0 评论 -
ST源码分析-st_thread_create
本文 主要分析st_thread_create()函数的内部实现。st_thread_create流程图如下:现在开始一行一行代码分析st_thread_create _st_thread_t *thread; _st_stack_t *stack; void **ptds; char *sp;上面代码声明了 4 个变量 ,变量ptds的全称应该是 pthread_data_register(线程的寄存器缓存),sp 的全称 是 stack point。...原创 2022-04-23 09:28:54 · 1155 阅读 · 0 评论 -
ST源码分析-st_init
在上一篇文章《ST源码分析-lookupdns》里,已经通过一个简单的域名查询程序演示了 ST 协程的使用。本文 主要分析st_init()函数的内部实现。lookupdns流程图如下:在讲代码逻辑,流程之前,贴一张主要的数据结构关系图,方便大家参考:全局变量如下:st_init()函数的流程图如下:先说一下我自己的环境,我的电脑是 Ubuntu 16,CPU 是 X86-64 ,我的 ST 用的是_st_select_eventsys调度器,不是_st...原创 2022-04-23 09:27:10 · 373 阅读 · 0 评论 -
ST源码分析-lookupdns
lookupdns只有 300 行代码,但是却演示了 如何使用 协程 并发请求dns。lookupdns的流程图如下:编译之后,运行以下命令:./obj/lookupdns www.xianwaizhiyin.net www.baidu.com上面两个命令 用协程 查询了两个域名,wireshark抓包如下:从数据包上看,两个udp查询,是并发的,第二个请求并没有被第一个请求阻塞。st_recvfrom()函数只会阻塞当前的协程,并不会阻塞第二个协程。而且 这两个...原创 2022-04-23 09:26:35 · 741 阅读 · 0 评论 -
ST源码分析-setjmp
C语言中的goto实现的是函数内部的跳转,也就是local jump。但是 C 标准库还有setjmp()跟longjmp()实现不同函数的跳转。这种不同函数的跳转叫做long jump。下面就来介绍 C标准库 的setjmp()跟longjmp()函数的使用。请阅读文章,《C语言中 setjmp 和 longjmp》。示例代码:#include <setjmp.h>#include <stdio.h>int main(){ jmp...原创 2022-04-23 09:25:55 · 402 阅读 · 0 评论 -
ST源码分析-Clion调试
lookupdns是 ST 的一个示例程序,由于 ST 是makefile的项目,并没有提供CMake文件,所以先演示 一下 如何使用Clion来调试Makefile的项目。也可以使用gdb调试,不过我个人习惯 用Clion。注意,Clion也只是把众多的 命令工具 集成在一起,即使是CMake的项目,CLion也是把 可执行文件build出来,然后调gdb来调试,只是Clion把这些东西界面化了。所以 举一反三 只要用Makefile编译出可执行文件...原创 2022-04-23 09:24:26 · 3046 阅读 · 0 评论 -
ST源码分析-makefile
项目的核心文件如下图:在 linux 系统下,执行以下命令即可编译 state-thread 项目make linux-debugstate-thread 库的 编译规则非常简单,不需要过多分析了,主要有以下重点。重点一:CC = cc在 linux 项目里面经常简单gcc跟cc,其实 cc 是 Unix 系统的命令,linux 为了兼容 Unix 的makefile搞了一个快捷方式,在 linux 里面,cc其实就是gcc重点二:...原创 2022-04-23 09:22:20 · 378 阅读 · 0 评论 -
ST源码分析-前言
ST 是 state-thread 的缩写。state-thread 是一个 C 语言实现的协程库,这个库是 8年前的,《state-thread 官网文档》。ST 协程优势有以下几点:1,从性能上来说,ST和传统的EDSM实现几乎一样快。也就是用 ST 跟用 单线程 epoll 一样高效。2,在内存方面,ST几乎和传统的EDSM一样高效。也就是用 ST 跟用 epoll 一样高效。3,因为单线程非阻塞epoll的架构 会把请求跟回调分离,这种请求跟回调分离 的架构 ,...原创 2022-04-23 09:21:08 · 499 阅读 · 0 评论 -
SRS4.0源码分析-RTMP延迟
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github本文主要对 SRS RTMP 直播做延迟测试,然后介绍如何优化 RTMP 的延迟。为了不嵌套界面,介绍一下ffmpeg如何抓取某个应用屏幕。先下载一个秒表程序,ledcount,运行界面如下:FFmpeg 抓取 某个 窗口的命令如下:ffmpeg.exe -f gdigrab -framerate 6 -i "title=abcds" out2.flv由于 FFmpeg 不支持中文的窗口名称,所以需要 下载...原创 2022-04-12 14:17:50 · 3729 阅读 · 0 评论 -
SRS4.0源码分析-推流总结
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github本文主要对前面的文章做下总结。《SRS4.0源码分析-main》,《SRS4.0源码分析-RTMP入口》,《SRS4.0源码分析-创建RTMP协程》,《SRS4.0源码分析-SrsRtmpConn::cycle》,《SRS4.0源码分析-SrsRtmpConn::stream_service_cycle》,《SRS4.0源码分析-SrsRecvThread::cycle》。上面 7 篇 文章从 RTMP 入口,一直追踪到 推流数原创 2022-04-12 14:17:08 · 2019 阅读 · 0 评论 -
SRS4.0源码分析-SrsRecvThread::cycle
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github从《SRS4.0源码分析-SrsRtmpConn::stream_service_cycle》 得知 ,真正接受客户端音视频流数据的地方是SrsRecvThread::cycle()。那客户端推视频流来之后,服务器有没缓存?服务器缓存多少秒?怎么配置 SRS 让 RTMP 直播的延迟降低?带着这些疑问,开始研究。SrsRecvThread::cycle()函数 的 代码如下:上面的变量pumper是SrsP...原创 2022-04-12 14:16:43 · 506 阅读 · 0 评论 -
SRS4.0源码分析-SrsRtmpConn::stream_service_cycle
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github本文讲解SrsRtmpConn::stream_service_cycle()函数的实现原理。流程图如下:上面的流程图中有几个重点:重点1,这里插个题 在调stream_service_cycle()之前,调了trd->pull(),trd->pull()在很多地方都出现,应该是个重点函数,具体另起一篇文章分析。本文暂时跳过。stream_service_cycle() 开头有一些 RTMP e...原创 2022-04-12 14:15:26 · 411 阅读 · 0 评论 -
SRS4.0源码分析-SrsRtmpConn::cycle
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github本文讲解SrsRtmpConn::cycle()函数的实现原理。流程图如下:上面我只画了流程图,不贴代码了,主要讲下重点:1,RTMP 的握手逻辑 S0,S1,CS 全部在rtmp->handshake()里面,SRS 的 RTMP 服务器实现,是先尝试复杂握手,不行再切换成简单握手。RTMP 握手在这里不太过多讲解,请看《RTMP协议分析-handshake》2,请看下图上面do_cycle()...原创 2022-04-12 14:14:49 · 363 阅读 · 0 评论 -
SRS4.0源码分析-创建RTMP协程
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github《SRS4.0源码分析-RTMP入口》 讲解了 建立 RTMP 的入口是在SrsServer::fd_to_resource()函数,现在就来验证一下是不是真的在那里,断点调试很重要,有时候看代码会看错,现在就在 fd_to_resource() 函数打个断点,如下图:果然,有 RTMP 请求来的时候,SRS代码就会跑进去new SrsRtmpConn(),所以之前的分析没有错误。本文 就来分析SrsRtmpCo...原创 2022-04-12 14:14:00 · 540 阅读 · 0 评论 -
SRS4.0源码分析-RTMP入口
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github上篇文章《SRS4.0源码分析-main》讲解了 SRS main 函数的基本流程,但是可能有些朋友还是比较懵逼。说实话,其实对于SRS的具体逻辑流程,我现在也是比较懵逼。在这里,分享一个研究开源项目源码的经验,怎么快速跳出这种懵逼的状态。首先,研究一个项目的源码,需要有一个目标。例如之前《RTMP协议分析》的系列文章,已经讲解了一个RTMP客户端的实现,我研究 SRS 的源码就是为了看一下RTMP服务器端是如何实现的。...原创 2022-04-11 19:54:55 · 2253 阅读 · 0 评论 -
SRS4.0源码分析-main
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github本文开始讲解 SRS 的入口文件。SRS 源码里 其实有 3 个main()函数,分别在srs_main_ingest_hls.cpp,srs_main_mp4_parser.cpp,srs_main_server.cpp3 个文件里面,如图:不过srs可执行文件,是srs_main_server.cpp生成的,所以先分析srs_main_server.cpp,其他两个文件不管。main()函数的流程图如...原创 2022-04-11 19:52:25 · 842 阅读 · 0 评论 -
SRS4.0源码分析-state-thread
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github由于 SRS 主要使用的 是state-thread协程库,这个库是 8年前的,《state-thread 官网文档》。从 git 记录看出来,杨成立 对这个库做了一些改进。如下:1,支持 龙芯 架构。2,ST 最后的版本 1.9 ,使用的是 glibc 的结构体 jmpbuf,这需要知道这个结构体的布局。glibc 后面版本如果改变了布局,就不能用了。所以杨成立直接修改了 ST 的_st_md_cxt_save跟...原创 2022-04-11 19:51:39 · 425 阅读 · 0 评论 -
SRS4.0源码分析-makefile
本文采用的 SRS 版本是 4.0-b8 , 下载地址:githubmakefile语法请看《跟我一起写Makefile》,SRS 的makefile是configureshell 脚本生成的。为了方便读者对着代码行数,我的 makefile 下载地址,百度网盘,提取码:5n9w虽然makefile是代码生成的,但是并没有做太多的封装,抽象,所以还是比较容易阅读的。SRS 的makefile总共 150 行左右,依赖非常清晰。开始分析 makefile 。因为...原创 2022-04-11 19:51:10 · 2389 阅读 · 0 评论 -
SRS4.0源码分析-configure
本文采用的 SRS 版本是 4.0-b8 , 下载地址:githubSRS4.0源码分析-CMake讲了 SRS 在Clion里面的调试 中使用的CMake 的逻辑。但是实际编译的时候,通常 使用 configure 跟 makefile。对于一个 开源项目来说,理解了 configure 跟 makefile ,基本上就理解了这个开源项目的50%。何时阅读 configure 跟 makefile ?这个问题不好说,我看开源项目,有时候是调试,理解完他的大部分代码逻辑,才开始看 conf...原创 2022-04-11 19:50:34 · 941 阅读 · 0 评论 -
SRS4.0源码分析-CMake
本文采用的 SRS 版本是 4.0-b8 , 下载地址:github《SRS4.0源码分析-调试环境搭建》 讲了 SRS 在Clion里面的调试,本文主要讲解srs-4.0-b8\trunk\ide\srs_clion目录下 的CMakeLists.txt文件的编译逻辑。CMake是对makefile的一种封装,CMake最后会生成makefile文件,再执行make命令。makefile可以看 左耳朵耗子的《跟我一起写Makefile》。CMake能找到的简...原创 2022-04-11 19:49:14 · 1210 阅读 · 0 评论 -
SRS4.0源码分析-调试环境搭建
本本文采用的 SRS 版本是 4.0-b8 , 下载地址:githubSRS4.0可以很方便地在clion软件下面断点调试,查看函数调用,堆栈。SRS的作者杨成立很贴心,在源码里放置了一个 适合Clion使用的CMake文件,如图:杨成立还在 B 站做了个教程,讲解如何 在 Clion 调试 SRS,教程地址:SRS-028-IDE高效调试_哔哩哔哩_bilibili目前 SRS 可以 在 MAC ,Ubuntu 的 Clion 里面调试。由于笔者的水平有限, 加之编写...原创 2022-04-11 19:47:17 · 3838 阅读 · 0 评论 -
SRS4.0源码分析-序言
《SRS4.0源码分析》专栏,会从 configure(配置),makefile(编译规则),main (入口函数), 带你一步一步了解 SRS 的主干代码逻辑。这里分享一个本人阅读开源项目源码的技巧,大部分比较好的开源项目 模块划分都比较完善,初学者开始只需要了解主干逻辑,其他各个模块的细节用到的时候再仔细研究即可,不需要一开始就把全部的代码逻辑吃透,下面是ffmpeg项目的主干逻辑以及各个模块的分布。开源项目动辄几十万行代码,如果没有好的模块划分,会很难维护,在早期就会死掉,所以一般活下..原创 2022-04-11 19:46:13 · 2509 阅读 · 0 评论