about-multimedia

有关多媒体与直播

多媒体知识

基本概念

  • 媒体文件和编码的区别

    文件是既包括视频又包括音频、甚至还带有脚本的一个集合,也可以叫容器;文件当中的视频和音频的压缩算法才是具体的编码。

  • 常见的音频视频编码
    • MPEG 系列:(由ISO[国际标准组织机构]下属的MPEG[运动图象专家组]开发)
      • 视频编码方面主要是Mpeg1(vcd 用的就是它)、Mpeg2(DVD 使用)、Mpeg4(现在的DVDRIP 使用的都是它的变种,如:divx,xvid 等)、Mpeg4 AVC(现在正热门);
      • 音频编码方面主要是MPEG Audio Layer 1/2、MPEG Audio Layer 3(大名鼎鼎的mp3)、MPEG-2 AAC 、MPEG-4 AAC等等。注意:DVD音频没有采用Mpeg
    • H.26X系列(由ITU[国际电传视讯联盟]主导,侧重网络传输,注意:只是视频编码)
      • 包括H261、H262、H263、H263+、H263++、H264(就是MPEG4 AVC-合作的结晶)
    • 微软windows media系列
      • 视频编码有Mpeg-4 v1/v2/v3(基于MPEG4)、Windows Media Video 7/8/9/10
      • 音频编码有Windows Media audeo v1/v2/7/8/9
    • Real Media系列
      • 视频编码有RealVideo G2(早期)、RealVideo 8/9/10
      • 音频编码有RealAudio cook/sipro(早期)、RealAudio AAC/AACPlus等
    • QuickTime系列
      • 视频编码有Sorenson Video 3(用于QT5,成标准了)、Apple MPEG-4、Apple H.264
      • 音频编码有QDesign Music 2、Apple MPEG-4 AAC
  • 常见的文件格式(容器)
    • AVI,音视频交互存储,最常见的音频视频容器。支持的视频音频编码也是最多的;
    • MPG,MPEG编码采用的音频视频容器,具有流的特性,里面又分为PS,TS 等,PS主要用于DVD存储,TS主要用于HDTV;
    • VOB,DVD采用的音频视频容器格式(即视频MPEG-2,音频用AC3 或者DTS),支持多视频多音轨多字幕章节等;
    • MP4,MPEG-4 编码采用的音频视频容器,基于QuickTime MOV开发,具有许多先进特性;
    • 3GP,3GPP 视频采用的格式,主要用于流媒体传送;
    • ASF,Windows Media 采用的音频视频容器,能够用于流传送,还能包容脚本等;
    • RM,RealMedia 采用的音频视频容器,用于流传送;RMVB,是视频编码部分采用可变码率压缩的文件格式(容器);
    • MOV,QuickTime 的音频视频容器;
    • MKV,它能把Windows Media Video,RealVideo,MPEG-4 等视频音频融为一个文件,而且支持多音轨,支持章节字幕等;
    • WAV,一种音频容器(注意:只是音频),大家常说的WAV就是没有压缩的PCM编码,其实WAV里面还可以包括MP3等其他ACM压缩编码;
    • MP3,MPEG Audio Layer 3(Mpeg 1 的音频编码的一种)文件转换(实际上也是编码转换);
  • IBP帧

    帧——就是影像动画中最小单位的单幅影像画面,相当于电影胶片上的每一格镜头。而在实际压缩时,会采取各种算法减少数据的容量,其中IPB就是最常见的。简单地说,I帧是关键帧,属于帧内压缩。P是向前搜索的意思。B是双向搜索。他们都是基于I帧来压缩数据。

    • I frame :帧内编码帧 又称intra picture,关键帧。I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术) 的第一个帧,视频序列中的第一个帧始终都是I帧。经过适度地压缩,I帧可以作为参考点来实现快进、快退以及其它 随机访问功能。帧可以看成是一个图像经过压缩后的产物,你可以理解为这一帧画面的完整保留。解码时只需要本帧 数据就可以完成(因为包含完整画面)。
    • P frame: 前向预测编码帧 又称predictive-frame,也叫预测帧。它表示的是这一帧跟之前的一个关键帧(或P帧) 的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数 据,只有与前一帧的画面差别的数据)
    • B frame: 双向预测内插编码帧 又称bi-directional interpolated prediction frame,也叫双向预测帧;也就 是B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况),换言之,要解码B帧,不仅要取得之前的缓存画面, 还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累~。
    • PTS:Presentation Time Stamp。PTS主要用于度量解码后的视频帧什么时候被显示出来
    • DTS:Decode Time Stamp。DTS主要是标识读入内存中的bit流在什么时候开始送入解码器中进行解码。在没有B帧存在的情况下DTS的顺序和PTS的顺序应该是一样的。
    • DTS和PTS区别:
      • DTS主要用于视频的解码,在解码阶段使用.PTS主要用于视频的同步和输出.在display的时候使用.在没有B frame的情 况下.DTS和PTS的输出顺序是一样的
    • IPB帧的不同
      • I frame:自身可以通过视频解压算法解压成一张单独的完整的图片
      • P frame:需要参考其前面的一个I frame 和/或 P frame来生成一张完整的图片
      • B frame:则要参考其前一个I或者P帧及其后面的一个P帧来生成一张完整的图片
      • 两个I frame之间形成一个GOP,在x264中同时可以通过参数来设定bf的大小,即:I 和p或者两个P之间B的数量。
      • 通过上述基本可以说明如果有B frame存在的情况下一个GOP的最后一个frame一定是P,所以如果视频流只有I和P,解码器可以不管后面的数据,边读边解码,线性前进

RTSP协议

  • RTSP+(RTCP/RTP)三者关系

案例一:vlc播放动画片,rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov

  • Wireshark抓取RTSP流+(RTCP/RTP基于UDP)过程

  • RTSP协议交互过程

    OPTIONS rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov RTSP/1.0 CSeq: 2 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28)

    RTSP/1.0 200 OK CSeq: 2 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD, GET_PARAMETER Supported: play.basic, con.persistent

    DESCRIBE rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov RTSP/1.0 CSeq: 3 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Accept: application/sdp

    RTSP/1.0 200 OK CSeq: 3 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Expires: Tue, 26 Mar 2019 02:22:23 UTC Content-Length: 587 Content-Base: rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ Date: Tue, 26 Mar 2019 02:22:23 UTC Content-Type: application/sdp Session: 310018309;timeout=60

    v=0 o=- 310018309 310018309 IN IP4 184.72.239.149 s=BigBuckBunny_115k.mov c=IN IP4 184.72.239.149 t=0 0 a=sdplang:en a=range:npt=0- 596.48 a=control:* m=audio 0 RTP/AVP 96 a=rtpmap:96 mpeg4-generic/12000/2 a=fmtp:96 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1490 a=control:trackID=1 m=video 0 RTP/AVP 97 a=rtpmap:97 H264/90000 a=fmtp:97 packetization-mode=1;profile-level-id=42C01E;sprop-parameter-sets=Z0LAHtkDxWhAAAADAEAAAAwDxYuS,aMuMsg== a=cliprect:0,0,160,240 a=framesize:97 240-160 a=framerate:24.0 a=control:trackID=2 SETUP rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=1 RTSP/1.0 CSeq: 4 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Transport: RTP/AVP;unicast;client_port=54286-54287

    RTSP/1.0 200 OK CSeq: 4 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Expires: Tue, 26 Mar 2019 02:22:23 UTC Transport: RTP/AVP;unicast;client_port=54286-54287;source=184.72.239.149;server_port=8432-8433;ssrc=389A31E5 Date: Tue, 26 Mar 2019 02:22:23 UTC Session: 310018309;timeout=60

    SETUP rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=2 RTSP/1.0 CSeq: 5 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Transport: RTP/AVP;unicast;client_port=54288-54289 Session: 310018309

    RTSP/1.0 200 OK CSeq: 5 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Expires: Tue, 26 Mar 2019 02:22:23 UTC Transport: RTP/AVP;unicast;client_port=54288-54289;source=184.72.239.149;server_port=16626-16627;ssrc=4B70664B Date: Tue, 26 Mar 2019 02:22:23 UTC Session: 310018309;timeout=60

    PLAY rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ RTSP/1.0 CSeq: 6 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Session: 310018309 Range: npt=0.000-

    RTSP/1.0 200 OK RTP-Info: url=rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=1;seq=1;rtptime=0,url=rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=2;seq=1;rtptime=0 CSeq: 6 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Range: npt=0.0-596.48 Session: 310018309;timeout=60

    PAUSE rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ RTSP/1.0 CSeq: 7 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Session: 310018309

    RTSP/1.0 200 OK CSeq: 7 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Session: 310018309;timeout=60

    PLAY rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ RTSP/1.0 CSeq: 8 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Session: 310018309 Range: npt=37.220-

    RTSP/1.0 200 OK RTP-Info: url=rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=1;seq=113;rtptime=445440,url=rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=2;seq=296;rtptime=3340800 CSeq: 8 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Range: npt=37.22-596.48 Session: 310018309;timeout=60

    PAUSE rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ RTSP/1.0 CSeq: 9 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Session: 310018309

    RTSP/1.0 200 OK CSeq: 9 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Session: 310018309;timeout=60

    PLAY rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ RTSP/1.0 CSeq: 10 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Session: 310018309 Range: npt=121.921-

    RTSP/1.0 200 OK RTP-Info: url=rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=1;seq=119;rtptime=1464324,url=rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=2;seq=316;rtptime=10982430 CSeq: 10 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Range: npt=121.921-596.48 Session: 310018309;timeout=60

    PAUSE rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ RTSP/1.0 CSeq: 11 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Session: 310018309

    RTSP/1.0 200 OK CSeq: 11 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Session: 310018309;timeout=60

    PLAY rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ RTSP/1.0 CSeq: 12 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Session: 310018309 Range: npt=197.793-

    RTSP/1.0 200 OK RTP-Info: url=rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=1;seq=143;rtptime=2363388,url=rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/trackID=2;seq=388;rtptime=17725410 CSeq: 12 Server: Wowza Streaming Engine 4.7.5.01 build21752 Cache-Control: no-cache Range: npt=197.793-596.48 Session: 310018309;timeout=60

    TEARDOWN rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov/ RTSP/1.0 CSeq: 13 User-Agent: LibVLC/3.0.6 (LIVE555 Streaming Media v2016.11.28) Session: 310018309

RTMP协议

RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。RTMP协议是一个互联网五层体系结构中应用层的协议。RTMP协议中基本的数据单元称为消息(Message)。当RTMP协议在互联网中传输数据的时候,消息会被拆分成更小的单元,称为块(Chunk)。

流媒体需要经过以下几个步骤:握手,建立网络连接,建立网络流,播放/发布

  1. RTMP握手

    • 示意图及数据包

  2. 建立网络连接

    • 示意图及数据包

  3. 建立网络流

    • 示意图及数据包

  4. 播放

    • 示意图及数据包

    • 块消息头,由块基本头中的“fmt”字段决定(总四种)
      • 类型0
      • 类型1
      • 类型2
      • 类型3
  • 消息

    • 协议控制消息
      • Set Chunk Size(Message Type ID=1)
      • Abort Message(Message Type ID=2)
      • Acknowledgement(Message Type ID=3)
      • Window Acknowledgement Size(Message Type ID=5)
      • Set Peer Bandwidth(Message Type ID=6)

Wireshark抓取vlc播放香港卫视,rtmp://live.hkstv.hk.lxdns.com/live/hks1

直播技术和SRS开源直播平台

SRS与其他直播平台对比

SRS分析

解析命令选项
  • do_main
    • SrsConfig::parse_options
      • SrsConfig::parse_argv,解析命令行选项
      • parse_file,解析配置文件"listen"、"http_server"、"daemon"、"srs_log_tank"部分
协程管理
  • run_master
    • initialize_st
      • srs_st_init
      • st_set_eventsys
      • st_init
        • _st_io_init,设置信号
          • _st_eventsys->fd_getlimit
        • _st_eventsys->init
        • st_thread_create(_st_idle_thread_start, NULL, 0, 0),创建idle协程,由其负责调度
          • -> _st_idle_thread_start
            • _st_eventsys->dispatch

  • st_netfd_open、st_netfd_open_socket、st_netfd_open、st_open
    • _st_eventsys->fd_new

  • st_netfd_close
    • _st_eventsys->fd_close

  • st_accept、st_connect等函数
    • st_poll
      • _st_eventsys->pollset_add
      • _st_eventsys->pollset_del

  • trd->start <-> SrsSTCoroutine::start
    • st_thread_create(pfn, this, 1, 0)),this是SrsSTCoroutine对象
      • trd->start = SrsSTCoroutine::pfn
      • trd->arg = this
      • _st_thread_main
        • _st_thread_t *trd = _ST_CURRENT_THREAD(),得到当前协程
        • (*trd->start)(trd->arg),执行协程
          • p->cycle(),执行SrsSTCoroutine对象的cycle函数
信号管理
监听管理
连接管理
关键流程
  • run_master

    • SrsServer::listen
      • listen_rtmp,推流(rtmp)到srs
        • 创建SrsBufferListener对象,并listen
          • 创建SrsTcpListener对象,并listen
            • 调用套接口监听
            • 创建“tcp” SrsSTCoroutine对象
            • 调用start
              • st_thread_create,启动协程SrsSTCoroutine::pfn
              • SrsSTCoroutine::pfn,独立协程
                • SrsSTCoroutine::cycle
                  • handler->cycle(),此处handler为SrsTcpListener对象,实际调用SrsTcpListener::cycle
                    • handler->on_tcp_client,此处handler为SrsBufferListener对象,实际调用SrsBufferListener::on_tcp_client
                    • server->accept_client,实际调用SrsServer::accept_client
                    • fd2conn
                    • type == SrsListenerRtmpStream,创建SrsRtmpConn对象
                    • conn->start,实际调用SrsRtmpConn父类SrsConnection::start
                    • trd->start,实际调用SrsSTCoroutine::start
                    • SrsConnection::cycle
                    • SrsRtmpConn::do_cycle,rtmp协议处理
    • SrsServer::ingest
      • SrsIngester::start
        • 创建“tcp” SrsSTCoroutine对象
        • 调用start
          • st_thread_create,启动协程SrsSTCoroutine::pfn
          • SrsSTCoroutine::pfn,独立协程
            • SrsSTCoroutine::cycle
              • handler->cycle(),此处handler为SrsIngester对象,实际调用SrsIngester::cycle
                • SrsIngester::do_cycle
                  • SrsIngester::parse,解析配置文件
                    • SrsIngester::parse_ingesters,遍历所有vhost,并调用该函数解析配置文件“ingest”部分
                    • 如果“enabled”部分“off”则退出,否则继续;
                    • 如果“ffmpeg”为空退出,否则继续;
                    • SrsIngester::parse_engines,遍历所有“engine”,根据“engine”是否为空,创建不同的ingester采集器对象(属于SrsIngesterFFMPEG类)
                    • SrsIngester::initialize_ffmpeg,解析配置文件“engine”、“input”部分,为ffmpeg做准备同时根据vhost,port信息生成完整的rtmp地址
                  • 遍历所有的ingest对象
                    • SrsIngesterFFMPEG::start,拼接命令选项并创建进程
                    • SrsFFMPEG::start
                    • SrsProcess::initialize,拼接采集器命令选项
                    • SrsProcess::start,创建采集器进程
                    • SrsIngesterFFMPEG::cycle,收集采集器运行状态
                    • SrsFFMPEG::cycle
                    • SrsProcess::cycle,获取采集器状态
    • SrsServer::cycle
      • SrsServer::do_cycle
        • handler->on_cycle,循环调用
    • listen_http_api
    • listen_http_stream
    • listen_stream_caster,推流(非rtmp)到srs,输出rtmp,对应配置文件“stream_caster”和“caster”部分
      • rtsp caster(Push RTSP to SRS
        • 创建SrsRtspListener对象(内部创建SrsRtspCaster对象,赋给caster)
          • 创建SrsTcpListener对象,并listen
            • 调用套接口监听
            • 创建“tcp” SrsSTCoroutine对象
            • 调用start
              • st_thread_create,启动协程SrsSTCoroutine::pfn
                • SrsSTCoroutine::pfn,独立协程
                  • p->cycle,实际调用SrsTcpListener::cycle
                    • handler->on_tcp_client,实际调用SrsRtspListener::on_tcp_client
                    • caster->on_tcp_client,实际调用SrsRtspCaster::on_tcp_client
                    • 创建SrsRtspConn对象,并serve
                    • SrsConnection::cycle
                    • SrsRtspConn::cycle
                    • SrsRtspConn::do_cycle,rtsp协议处理
      • flv caster(Push HTTP FLV to SRS
        • 创建SrsHttpFlvListener对象(内部创建SrsAppCasterFlv对象,赋给caster)
          • 创建SrsTcpListener对象,并listen
            • 调用套接口监听
            • 创建“tcp” SrsSTCoroutine对象
            • 调用start
              • st_thread_create,启动协程SrsSTCoroutine::pfn
                • SrsSTCoroutine::pfn,独立协程
                  • p->cycle,实际调用SrsTcpListener::cycle
                    • handler->on_tcp_client,实际调用SrsHttpFlvListener::on_tcp_client
                    • caster->on_tcp_client,实际调用SrsAppCasterFlv::on_tcp_client
                    • 创建SrsDynamicHttpConn对象
                    • 调用start
                    • conn->start,实际调用SrsDynamicHttpConn父类SrsConnection::start
                    • trd->start,实际调用SrsSTCoroutine::start
                    • SrsConnection::cycle
                    • SrsHttpConn::do_cycle,http协议处理
                    • on_got_http_message
                    • SrsAppCasterFlv::serve_http
      • mpegts_over_udp(Push MPEG-TS over UDP
        • 创建SrsUdpCasterListener对象(内部创建SrsMpegtsOverUdp对象)
          • 创建SrsUdpListener对象,并listen
            • 创建套接口
            • 创建“udp” SrsSTCoroutine对象
            • 调用start
            • st_thread_create,启动协程SrsSTCoroutine::pfn - SrsSTCoroutine::pfn,独立协程 - p->cycle,实际调用SrsUdpListener::cycle - handler->on_udp_packet,实际调用SrsMpegtsOverUdp::on_udp_packet - context->decode,解码ts包

Ingest采集方式

采集(Ingest)指的是将文件(flv,mp4,mkv,avi,rmvb等等),流(RTMP,RTMPT,RTMPS,RTSP,HTTP,HLS等等),设备等的数据,转封装为RTMP流(若编码不是h264/aac则需要转码),推送到SRS

采集的主要应用场景包括:

  1. 虚拟直播:
    将文件编码为直播流。可以指定多个文件后,SRS会循环播放。

  2. RTSP摄像头对接: 以前安防摄像头都支持访问RTSP地址,RTSP无法在互联网播放。 可以将RTSP采集后,以RTMP推送到SRS,后面的东西就不用讲了。

  3. 直接采集设备:
    SRS采集功能可以作为编码器采集设备上的未压缩图像数据, 譬如video4linux和alsa设备,编码为h264/aac后输出RTMP到SRS。

  4. 将HTTP流采集为RTMP: 有些老的设备,能输出HTTP的ts或FLV流,可以采集后转封装为RTMP,支持HLS输出。

总之,采集的应用场景主要是“SRS拉流”;能拉任意的流,只要ffmpeg支持;不是h264/aac都没有关系,ffmpeg能转码。

DVR视频录制

关键流程
  • SrsSource::on_publish,上接rtmp服务器-流转发

    • SrsOriginHub::on_publish,录制dvr、dash、hls文件,这里以dvr为例
      • SrsDvr::on_publish
        • SrsDvrSegmentPlan::on_publish,按segment方式录制
          • SrsDvrSegmenter::open,创建视频文件,打印dvr stream %s to file %s
  • SrsRecvThread::cycle

    • SrsRecvThread::do_cycle
      • while (true) {
        • trd->pull()
        • pumper->interrupted <-> SrsPublishRecvThread::interrupted
        • rtmp->recv_message <-> SrsRtmpServer::recv_message
          • protocol->recv_message <->
        • pumper->consume <-> SrsPublishRecvThread::consume
          • SrsRtmpConn::handle_publish_message
            • SrsRtmpConn::process_publish_message
              • SrsSource::on_video
                • SrsSource::on_video_imp
                  • SrsOriginHub::on_video
                    • SrsDvr::on_video
                    • SrsDvrSegmentPlan::on_video
                    • SrsDvrPlan::on_video
                    • SrsDvrSegmenter::write_video
                    • SrsDvrFlvSegmenter::encode_video
        • trd->interrupt
      • }

rtmp服务器

  • SrsServer::accept_client,收受客户
    • SrsServer::fd2conn,创建了SrsRtmpConn、SrsHttpApi、SrsResponseOnlyHttpConn对象,这里以SrsRtmpConn对象为例
    • conns.push_back(conn),保存连接对象
    • conn->start(),实际执行SrsRtmpConn::do_cycle函数
      • SrsRtmpConn::do_cycle
        • SrsRtmpConn::service_cycle
          • SrsRtmpConn::stream_service_cycle
            • rtmp->identify_client,确认客户类型,由SrsRtmpConnType标识(播放 or 发布),rtmp为SrsRtmpServer对象
            • srs_discovery_tc_url,分析rtmp地址
            • check_vhost,核对vhost
            • rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS),设置超时时间
            • rtmp->set_send_timeout(SRS_CONSTS_RTMP_TMMS)
            • SrsSource::fetch_or_create,创建SrsSource对象,如果存在直接返回pool中的SrsSource对象
            • 根据客户类型,调用rtmp对象的不同函数
              • 如果是播放,调用playing
              • 如果是发布,调用publishing

流播放(作为rtmp server角色)

流发布,Forward集群模式(作为rtmp client角色)

master节点发送流
  • SrsRtmpConn::publishing,上接“rtmp服务器”
    • http_hooks_on_publish,发布publish消息

    • acquire_publish

      • source->on_publish
        • hub->on_publish,SrsOriginHub对象
          • SrsOriginHub::create_forwarders,根据配置文件中的forwarder所带slave地址个数来创建SrsForwarder对象,1个source(流):N个forwarder(slave地址个数),系统中M个流需要M*N个SrsForwarder对象
            • forwarder->initialize
            • forwarder->on_publish
              • new SrsSTCoroutine("forward", this)
                • SrsForwarder::cycle
                  • SrsForwarder::do_cycle
                    • srs_parse_hostport,解析ip和port
                    • srs_generate_rtmp_url,生成rtmp地址
                    • sdk = new SrsSimpleRtmpClient,创建rtmp客户端
                    • sdk->connect,内部创建了tcp对象和rtmp对象
                    • client->handshake,跟Slave握手
                    • connect_app,建立连接
                    • client->create_stream,创建流
                    • sdk->publish
                    • hub->on_forwarder_start,缓存音视频数据
                    • SrsForwarder::forward,真正发送音视频数据给slave
    • SrsPublishRecvThread rtrd,创建接收消息对象,其包含

    • do_publishing

      • SrsPublishRecvThread
    • rtrd.stop

Edge集群模式

有关Nginx高性能服务器

资料汇总

  1. ONVIF 2.0 Service Operation Index
  2. rfc2326 - Real Time Streaming Protocol (RTSP)
  3. rfc3550 - RTP: A Transport Protocol for Real-Time Applications
  4. rfc3551 - RTP Profile for Audio and Video Conferences with Minimal Control
  5. rfc3611 - RTP Control Protocol Extended Reports (RTCP XR)
  6. rfc3711 - The Secure Real-time Transport Protocol (SRTP)
  7. rfc4585 - Extended RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback (RTP/AVPF)
  8. rfc4566 - SDP: Session Description Protocol
  9. rfc5104 - Codec Control Messages in the RTP Audio-Visual Profile with Feedback (AVPF)
  10. rfc5124 - Extended Secure RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback (RTP/SAVPF)
  11. rfc5450 - Transmission Time Offsets in RTP Streams
  12. rfc6184 - RTP Payload Format for H.264 Video
  13. rfc7741 - RTP Payload Format for VP8 Video
  14. rfc8216 - HTTP Live Streaming
  15. RTMP WIKI
  16. rtmp specification v1.0
  17. HLS WIKI
  18. 北京大学,视频编码算法研究室
  19. 流媒体加密
  20. 使用flv.js做直播
  21. 雷霄骅 - RGB、YUV像素数据处理
  22. 雷霄骅 - H.264视频码流解析
  23. 雷霄骅 - h264_analysis
  24. 雷霄骅 - PCM音频采样数据处理
  25. 雷霄骅 - AAC音频码流解析
  26. 雷霄骅 - FLV封装格式解析
  27. 雷霄骅 - UDP-RTP协议解析
  28. 雷霄骅 - ffmpeg源码简析(一)结构总览