自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

专注音视频基础、WebRTC、ffmpeg、流媒体服务器

公众号: 「大话音视频」 ,期待关注~

  • 博客(58)
  • 资源 (1)
  • 收藏
  • 关注

原创 FLV协议

FLV(Flash Video)是Adobe公司推出的⼀种流媒体格式,由于其封装后的⾳视频⽂件体积⼩、封装简单等特点,⾮常适合于互联⽹上使⽤。⽬前主流的视频⽹站基本都⽀持FLV。采⽤FLV格式封装的⽂件后缀为.flv。FLV封装格式是由⼀个⽂件头(file header)和 ⽂件体(file Body)组成。其中,FLV body由⼀对对的(Previous Tag Size字段 + tag)组成。Previous Tag Size字段 排列在Tag之前,占⽤4个字节。Previous Tag Size记

2021-10-03 19:00:00 638

原创 H264协议

简介H.264从1999年开始,到2003年形成草案,最后在2007年定稿有待核实。在ITU的标准⾥称为H.264,在MPEG的标准⾥是MPEG-4的⼀个组成部分–MPEG-4 Part 10,⼜叫Advanced Video Codec,因此常常称为MPEG-4 AVC或直接叫AVC。H264编码原理在⾳视频传输过程中,视频⽂件的传输是⼀个极大的问题;⼀段分辨率为1920*1080,每个像素点为RGB占⽤3个字节,帧率是25的视频,对于传输带宽的要求是:1920*1080*3*25/1024/10

2021-10-03 18:30:00 1380

原创 AAC协议

简介Advanced Audio Coding(高级音频解码),是⼀种由MPEG-4标准定义的有损⾳频压缩格式,由Fraunhofer发展,Dolby, Sony和AT&T是主要的贡献者。ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不能在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进⾏。故这种格式常⽤在磁盘⽂件中。ADTS:Audio Data Transport Stream。是AAC

2021-10-02 22:01:51 1929 1

原创 WebRTC PeerConnection Client源码分析3-Conductor

本文分析的webrtc的版本是:m84 平台:win10WebRTC PeerConnection Client源码分析<1>-main windowWebRTC PeerConnection Client源码分析<2>-PeerConnectionClientWebRTC PeerConnection Client源码分析<3>-Conductor注:下文中所谓的回调函数,实际上是虚函数。把虚函数说成回调函数是为了描述方便。Conductor是Pee

2021-10-02 19:18:36 1342 5

原创 WebRTC PeerConnection Client源码分析2-PeerConnectionClient

本文分析的webrtc的版本是:m84 平台:win10WebRTC PeerConnection Client源码分析<1>-main windowWebRTC PeerConnection Client源码分析<2>-PeerConnectionClientWebRTC PeerConnection Client源码分析<3>-Conductor本文用到的抓包数据,可以从这里下载:PeerConnectionClient用于和信令服务器进行交互,

2021-10-02 19:12:40 1453 8

原创 WebRTC PeerConnection Client源码分析1-main window

本文分析的webrtc的版本是:m84 平台:win10WebRTC PeerConnection Client源码分析1-main windowWebRTC PeerConnection Client源码分析2-PeerConnectionClientWebRTC PeerConnection Client源码分析3-ConductorPeerConnection是WebRTC官方提供的P2P示例,麻雀虽小五脏俱全,这个示例对于学习WebRTC是非常有帮助,下面我们开始详细的分析其代码逻

2021-10-02 19:10:33 1808

原创 srs源码分析6-connect

现在根据抓包信息,分析connect的过程。int SrsClient::do_cycle(){... /*handshake成功后,进行connect。*/ if ((ret = rtmp->connect_app(req)) != ERROR_SUCCESS) { srs_error("rtmp connect vhost/app failed. ret=%d", ret); return ret; } srs_verbose("rtmp connect app succe.

2021-10-02 18:52:12 652

原创 srs源码分析5-handshake

要建立一个有效的RTMP Connect连接,首先需要进行握手,客户端要向服务器发送C0、C1、C2(按序)三个chunk,服务器向客户端发送S0、S1、S2(按序)三个chunk,然后才能进行有效的信息传输。RTMP协议本身并没有规定这6个Message的具体传输顺序,但RTMP协议的实现者需要保证这几点:客户端要等收到S1之后才能发送C2客户端要等收到S2之后才能发送其他信息(控制信息和真实⾳视频等数据)服务端要等到收到C0之后发送S1服务端必须等到收到C1之后才能发送S2服务端必须等到收

2021-10-02 18:45:27 507

原创 srs源码分析4-客户端的连接

void SrsListener::listen_cycle(){... while (loop) { ... /*当有客户端连接srs时,listen协程会从此函数返回。*/ st_netfd_t client_stfd = st_accept(stfd, NULL, NULL, ST_UTIME_NO_TIMEOUT); ... /*通知SrsServer,有新的客户端连接进来了。*/ if ((ret = server->accept_cl

2021-10-02 18:42:30 419

原创 srs源码分析3-srs的启动

先从main函数开始分析,分析srs的启动过程。int main(int argc, char** argv){ int ret = ERROR_SUCCESS; /*注册SIGHUB信号处理函数,用于重载配置文件。*/ signal(SIGNAL_RELOAD, handler); /*解析命令行参数,解析配置文件。*/ if ((ret = config->parse_options(argc, argv)) != ERROR_SUCCESS) { return ret;

2021-10-02 18:41:47 1350

原创 srs源码分析2-浅析state_threads

srs是基于协程开发的,底层使用了state_threads协程库。为了更好的理解srs,所以需要先熟悉state_threads。这里并不会介绍协程的相关概念,只是简单的介绍一下state_threads的核心逻辑。以下state_thread会被简称为st。使用示例-echo server使用st实现了一个简单的echo服务器,以下代码写的很简单,重点是理解st的使用。#include <arpa/inet.h>#include <errno.h>#include &

2021-10-02 18:39:59 1257 1

原创 srs源码分析1-搭建环境

在搭建srs-0.6.0时,总是提示各种错误,为了简化搭建,我直接使用CMake重新组织了一下构建方式,目前至只支持rtmp。平台:Ubuntu 18.04先安装state_threads:cd stmake linux-debugcd ./objcp libst.a /usr/local/lib/cp st.h /usr/local/include/然后安装srs:mkdir build && cd buildcmake ../make运行srs:./srs

2021-10-02 18:32:33 411

原创 ffmpeg编程示例-解码h264

提供一个可以运行的ffmpeg工程:https://gitee.com/qiuguolu1108/ffmpeg-studyffmpeg -i Jasmine.flv -vcodec libx264 -an -f h264 Jasmine.h264进入工程中的player目录,使用上述命令,生成待处理的Jasmine.h264文件。#include "spdlog/spdlog.h"extern "C" {#include "libavcodec/avcodec.h"}#define IN

2021-09-14 21:39:39 1012

原创 ffmpeg编程示例-解码aac

提供一个可以运行的ffmpeg工程:https://gitee.com/qiuguolu1108/ffmpeg-studyffmpeg -i Jasmine.flv -acodec copy -vn Jasmine.aac进入工程中的player目录,使用上述命令,生成待处理的Jasmine.aac文件。#include "spdlog/spdlog.h"extern "C" {#include "libavcodec/avcodec.h"#include "libavutil/frame.

2021-09-14 21:34:26 620

原创 ffmpeg编程示例-提取h264

提供一个可以运行的ffmpeg工程:https://gitee.com/qiuguolu1108/ffmpeg-study#include "spdlog/spdlog.h"extern "C" {#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"}char error[1024];int main(int argc, char** argv) { const char file_name[] = "Jas

2021-09-14 21:27:41 498

原创 ffmpeg编程示例-提取aac

提供一个可以运行的ffmpeg工程:https://gitee.com/qiuguolu1108/ffmpeg-study#include "spdlog/spdlog.h"extern "C" {#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"}#define ADTS_HEADER_LEN 7char error[1024];const int sampling_frequencies[] = {

2021-09-14 21:25:10 370

原创 ffmpeg编程示例-音频重采样

提供一个可以运行的ffmpeg工程:https://gitee.com/qiuguolu1108/ffmpeg-studyffmpeg -i Jasmine.mp4 -vn -ar 48000 -ac 2 -f f32le Jasmine.pcm进入player目录,使用上述命令生成待处理的pcm文件。源pcm文件的采样率为48000,采样格式为float,经过重采样后,pcm文件的采样率为44100,采样格式为s16。#include "spdlog/spdlog.h"extern "C" {

2021-09-14 21:21:24 442 2

原创 ffmpeg编程示例-采集音频

提供一个可以运行的ffmpeg工程:https://gitee.com/qiuguolu1108/ffmpeg-studyffmpeg -list_devices true -f dshow -i dummy使用上面的命令获取本机上的音频设备名称$ ffmpeg -list_devices true -f dshow -i dummy[dshow @ 04df42c0] DirectShow video devices (some may be both video and audio devic

2021-09-14 21:12:13 903

原创 licode源码分析-媒体数据的处理流程

本文主要分析licode C++部分对视频流的处理流程。主要介绍licode从发送客户端接收视频流,然后经过内部的处理,再将视频流发送到接收客户端。licode虽然是MCU模型,但提供的主要功能还是SFU,它不能将同一个房间内的音视频进行混合,仅提供了单路视频流的转码功能。现在先假设licode和一个发送客户端、一个接收客户端相连并转发视频流。这是licode从网络接收发送客户端视频数据,经过内部流转,再通过网络发送至接收客户端的总览图。使用nICEr库接收网络数据licode使用nICEr

2021-04-06 13:06:47 2360

原创 mediasoup源码分析-初始化、建立连接及媒体数据的处理流程

mediasoup中的Transport有多种类型,以下只分析WebRtcTransport,且只分析音频、视频的传输。线程模型mediasoup使用的是多进程模型,服务器上有多个少CPU核,就启动多少个Worker进程。每个Worker进程采用单线程,运行一个事件循环,所有数据的处理,都是通过事件触发的。MediaSoup的应用层和媒体处理层分别运行在不同的进程内,它们之间通过管道进行通信。注意:应用进程和Worker进程之间可以使用普通的管道,也可以使用socketpair,这个部分的代码应该在

2021-03-31 22:33:05 5142 11

原创 proc文件系统

不定期更新~~~

2021-03-31 22:15:38 131

原创 使用shared_ptr实现copy-on-write

本文内容的核心思想不是博主的,本文是《Linux多线程服务端编程》中P52 "2.8借shared_ptr实现copy-on-write"的读后感。感谢陈硕老师分享这么优秀的文章。欢迎大家阅读陈硕老师的原文,原文写的相当精彩。《Linux多线程服务端编程》https://book.douban.com/subject/20471211/多线程对临界区的访问class Connection /*表示与客户端的连接句柄*/{public: /*向客户端发送数据*/ void

2021-03-28 19:25:15 833

原创 TCP快速打开-TCP Fast Open

假设我们有一台服务器,它的作用是将接收到数据转成大写后,返回给客户端。如果客户端每次建立连接只发送一次数据,就断开连接,再次发送数据时,重新建立连接。这样每次在连接时,都需要三次握手。并且在第二次建立握手时,客户端发送SYN时,是不可以携带数据的。而使用TFP(Tcp Fast Open)后,除了第一次的完整握手,之后的握手,在SYN中就可以携带数据,这样的好处是可以减少一个RTT。抓取的网络包可以到这个连接下载:链接:https://pan.baidu.com/s/1hqJzcbIYTf6MapHg

2021-03-28 15:12:21 1898

原创 LwIP之UDP协议的实现

2021-03-26 13:05:28 191

原创 licode源码分析-线程模型

licode源码分析-线程模型服务器一般都会服务于大量的用户,所以服务端程序的性能往往决定服务用户的多少。现在服务器上的CPU都是多核的,服务端程序为了充分发挥CPU的性能,会使用多进程或多线程。而使用多线程会造成资源的竞争,一般情况下都会使用锁了解决资源竞争。在使用锁时,应该尽可能的减小临界区,以提高程序的并发性能。在流媒体服务器中,往往要处理数据量是巨大的,若锁使用不当,会造成服务器性能低下。MediaSoup使用的是多进程单线程模型,进程间通过管道和socket进行通信,并不需要使用锁。licod

2021-03-17 18:53:59 941 1

原创 客户端-服务器通信抓包分析

抓包数据在这里下载:链接:https://pan.baidu.com/s/1P1qx9wTrijmpkDl7FRYQWg提取码:0hs2

2021-03-17 18:41:27 337

原创 窥视C++细节-虚函数实现原理

文章目录环境类对象内有指向虚函数表的指针虚函数表创建时机及位置内容使用虚函数表指针调用虚函数为类对象初始化虚函数表指针虚函数调用过程动多态形成的实现机制环境在运行测试代码时,使用了如下环境:linux使用的是ubuntu 18,在ubuntu上使用的是g++,版本如下:root@learner:~# g++ --versiong++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0https://godbolt.org/,这个网站可以方便的将C++代码编译成汇编,同时使用

2021-03-16 20:09:00 370 1

原创 窥视C++细节-为什么成员初始化列表更快

文章目录环境必须使用成员初始化列表的情况成员变量是引用类型成员变量是const类型有参基类的构造器有参类类型数据成员构造器应注意的问题初始化列表快的原因定义一个用于测试的类不使用初始列表使用初始化列表总结环境在运行测试代码时,使用了如下环境:linux使用的是ubuntu 18,在ubuntu上使用的是g++,版本如下:root@learner:~# g++ --versiong++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0必须使用成员初始化列表的情况成员变量是

2021-03-16 20:08:42 1005

原创 窥视C++细节-STL使用萃取机提高性能

本文分析使用的SGI版的STL。其可读性非常高,提供一个下载链接:迭代器的种类STL中有五种迭代器:输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机迭代器。struct input_iterator_tag {};struct output_iterator_tag {};struct forward_iterator_tag : public input_iterator_tag {};struct bidirectional_iterator_tag : public forward_i

2021-03-16 20:08:27 295

原创 窥视C++细节-编译器帮助合成默认构造器的情况

文章目录环境编译器并没有帮助合成默认构造器类内数据成员是类对象父类有默认构造器类内有虚函数有虚继承一般的C++书籍上会告诉你,当一个类没有声明任何构造函数时,编译器会自动的生成默认构造函数。但实际的情况好像不是这样的,当一个类没有声明任何构造函数,且在必要的时候编译器才会帮助合成默认构造器,在一些非必要的时候,编译是不会帮助合成默认构造器的。下面通过把C++编译成汇编的方式,分析哪四种常见情况下,编译器会帮助合成默认构造器。环境https://godbolt.org/,这个网站可以方便的将C++代码

2021-03-16 20:08:03 167

原创 窥视C++细节-使用移动构造和右值引用优化函数返回值

文章目录环境定义一个用于测试的类没有右值引用和移动构造ubuntu运行结果分析visual studio运行结果分析ubuntu中关闭返回值优化添加移动构造使用const引用接收返回值使用右值引用接收返回值总结本文不是介绍右值引用和移动语义的,在阅读本文前,假设读者已经知道了什么是右值引用和移动语义。右值分为:纯右值和将亡值,本文主要介绍纯右值,并不涉及将亡值。环境在运行测试代码时,使用了如下环境:linux使用的是ubuntu 18,在ubuntu上使用的是g++,版本如下:root@lear

2021-03-16 20:07:36 1290 2

原创 窥视C++细节-父类为什么要虚析构

文章目录环境单继承下的虚析构析构的顺序子类没有发生析构将父类析构器置为虚函数多继承下的虚析构this指针的调整多继承下的虚析构原理本文将分析,父类的析构函数为什么必须为虚函数,如果不是虚函数会造成什么问题?在没有使用多态时,是否还需要将父类的析构器置为虚函数?同时也会分析多继承下的虚析构问题。环境https://godbolt.org/,这个网站可以方便的将C++代码编译成汇编,同时使用颜色标识某条C++语句对应的汇编代码。在使用之前需要可以根据自己的习惯配置一下。使用的gcc版本是10.2-

2021-03-16 20:07:04 1368

原创 窥视C++细节-类成员函数的隐式参数this

文章目录环境栈帧-示例类成员函数的调用类成员函数的汇编代码环境https://godbolt.org/,这个网站可以方便的将C++代码编译成汇编,同时使用颜色标识某条C++语句对应的汇编代码。在使用之前需要可以根据自己的习惯配置一下。使用的gcc版本是10.2-m32:将C++代码编译成32位的汇编-O0:不要进行编译优化Intel asm syntax:编译成intel格式的汇编,默认是AT&T格式的汇编。Demangle identifiers:反命名倾轧,在汇编代码中使用C+

2021-03-16 20:06:31 865

原创 窥视C++细节-为资源管理类提供swap函数的原因

文章目录环境定义一个用于测试的类使用std::swap函数类内有移动构造和移动赋值运算符类内没有移动构造和移动赋值运算符提供自己的swap函数总结在有资源的类中,使用swap函数交换两个对象时,如果没有正确的使用swap函数,则会造成资源的拷贝和释放,导致性能降低。环境在运行测试代码时,使用了如下环境:linux使用的是ubuntu 18,在ubuntu上使用的g++版本如下:root@learner:~# g++ --versiong++ (Ubuntu 7.5.0-3ubuntu1~18.0

2021-03-16 20:05:56 310

原创 窥视C++细节-使用tie函数解包pair对象的原理

文章目录示例std::tie函数std::ignorestd::pair和std::tuple互转解包pair返回值示例这是http://www.cplusplus.com/reference/tuple/tie/?kw=tie中的一个std::tie()函数的示例。#include <iostream> // std::cout#include <tuple> // std::tuple, std::make_tuple, std::tieint

2021-03-16 20:05:33 1626 1

原创 浅析vector容器(3)-使用移动语义提高性能

文章目录定义一个用于测试的类没有移动构造时构造vector对象向vector中推入对象a提供移动构造时构造vector对象向vector中推入对象a移动构造必须加上noexcept在上一篇文章中,我们可知,在vector进行扩容或缩容的时候,元素的拷贝是不可避免的。既然拷贝是不可避免的,那么能不能较低拷贝的开销哪?C++11中很大的一个特性是移动语义,移动语义可以将资源“偷”过来,避免了资源的拷贝和释放。在类有很大的资源时,使用移动语义可以大幅的提升类构造和赋值的性能。接下来分析一下,移动语义是如何提

2021-03-16 20:04:36 3224

原创 WebRTC源码分析之模块的执行-Module

文章目录Module使用示例工程示例Module源码分析类关系图ProcessThread类Module类QueuedTask类ProcessThreadImpl类ModuleCallback类数据成员构造器与析构器模块处理线程的创建与销毁模块的注册与注销投递任务执行指定模块模块的处理小结WebRTC中将某些功能划分了模块,现在介绍一下模块是如何执行的。WebRTC中会创建一个线程用于执行模块和异步的任务,模块生成以后注册到线程中,模块执行时会计算下次需要执行的时间,线程根据模块提供的时间会按照指定的时间

2021-03-15 19:19:45 809 1

原创 WebRTC源码分析之任务队列-TaskQueue

文章目录TaskQueue使用示例工程示例TaskQueue源码分析类关系图TaskQueueBase类声明CurrentTaskQueueSetter类TaskQueueStdlib类数据成员任务队列的创建销毁任务队列唤醒任务处理线程投递任务任务处理线程处理任务QueuedTask类TaskQueue类声明工厂模式创建任务队列对象TaskQueueDeleter类TaskQueueFactory类TaskQueueStdlibFactory类CreateTaskQueueStdlibFactory函数创建

2021-03-14 18:24:13 2195 2

原创 WebRTC源码分析之平台线程-PlatformThread

文章目录PlatformThread使用示例示例-创建执行一次的线程示例-创建可以执行多次的线程示例-高优先级线程先运行PlatformThread源码分析数据成员构造器和析构器设置线程的属性线程的入口函数创建线程回收线程小结WebRTC是跨多种平台的,为了方便线程的使用,把各个平台的线程封装成了PlatformThread类。PlatformThread封装的线程是有优先级的,线程的执行并不是按时间片轮询执行的,而是高优先级的线程会一直在CPU中执行,直到有更高优先级的线程到来或主动让出CPU。Pla

2021-03-14 18:23:56 1166

原创 WebRTC源码分析之配置信息-FlagList

文章目录FlagList使用示例工程示例-定义标记示例-标记的额外信息示例-显示所有的标记示例-显示指定文件中的标记示例-解析命令行参数示例-解析命令行参数并删除命令行中的标记FlagList源码分析FlagValue类Flag类FlagList类WEBRTC_DEFINE_string宏函数宏函数原型宏函数的使用WEBRTC_DECLARE_string宏函数宏函数原型宏函数的使用小结FlagList是一个全局链表,用于保存所有的标记,这些标记一般都是WebRTC的配置信息。标记都有两个值,一个是默认值

2021-03-14 18:23:40 384 4

计算机系统基础——袁春风老师

此书和《深入理解计算机系统》有些类似,但是更容易阅读,可以先看此书再去看《深入理解计算机系统》。此书也是MOOC上袁春风老师的《计算机系统基础》的配套教材,可以结合袁老师的视频来看此书。看完视频和此书再去看《深入理解计算机系统》这样效果会更好。

2017-11-30

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除