• webrtc fec


    转自:http://www.cnblogs.com/webrtc/p/7402570.html

    WebRTC::FEC

    [TOC]

    Tags: WebRTC FEC

    1. WebRTC中的 FEC 实现分为 UlpFEC 和 FlexFEC
      ulpfec:rfc 5109
      FlexFEC还在实现中, 相关标准也还是 RFC草案.详见:FlexFex
    1. WebRTC对FEC进行恢复处理的动作对RTCP的统计是透明的.
    1. WebRTC对FEC的冗余度计算是动态的, 会根据丢包情况和网络带宽估计(BWE)的结果动态调整冗余度,
      内部会维护一个静态的冗余度表. 冗余度范围: 0-255.(255相当于100%冗余度)

    ULPFEC

    ULPFEC: Uneven Level Protection FEC.

    将需要保护的媒体流按照重要性分成若干区域(section),
    不同的区域使用不同的保护级别(levels),每个ulpfec可以携带多个级别的保护区域。

             Packet A          #####################
                                      :        :
             Packet B          ############### :
                                      :        :
             ULP FEC Packet    #1 @@@@@        :
                                      :        :
             Packet C          ###########     :
                                      :        :
             Packet D          ###################################
                                      :        :
             ULP FEC Packet    #2 @@@@@@@@@@@@@@
                               :      :        :
                               :<-L0->:<--L1-->:
    
                   Figure 1: Unequal Level Protection
    
             Payload packet #  |  ULP FEC packet that protects at level
                               |          L0             L1
          ---------------------+---------------------------------------
                    A          |          #1             #2
                    B          |          #1             #2
                    C          |          #2             #2
                    D          |          #2             #2

    FEC Packet Structure

       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                RTP Header (12 octets or more)                 |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                    FEC Header (10 octets)                     |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                      FEC Level 0 Header                       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                     FEC Level 0 Payload                       |
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                      FEC Level 1 Header                       |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                     FEC Level 1 Payload                       |
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                            Cont.                              |
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
                        Figure 2: FEC Packet Structure

    FEC Header

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |E|L|P|X|  CC   |M| PT recovery |            SN base            |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                          TS recovery                          |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |        length recovery        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    E(Extension):0

    L(Long Mask):使用使用long mask,0:16 bits mask、1:48 bits mask

    P、X、CC、M、PT (Recovery field):对主流的RTP header使用保护算法计算后得到

    SN base:被保护的主流的RTP包中最小的序号,通过结合 level header中的mask来表示该fec保护的主流的包的序号

    TS recovery:对主流的RTP header中的 TS使用保护算法计算后得到

    Length recovery:用于验证恢复的包的payload长度,由被保护的rtp包的长度使用保护算法计算后得到

    ULP Level Header:

        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |       Protection Length       |             mask              |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |              mask cont. (present only when L = 1)             |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    fec level header长度为 4字节(L=0)或8字节(L=1)

    Proctection Length:fec level 负载的长度

    Mask:bit i = 1 则该fec保护的包的序号包括 SN base + i,mask决定了该levle 保护了主流的哪些包。

    设置原则:

    • 一个媒体包只能被大于0的level 保护一次,可以被level 0保护多次。(多重保护的开销太大)
    • 一个媒体包被 level p 保护,那么肯定的也会被 level p-1 保护,且 levle p 与 p-1 可能不是同一个fec包。(含有不同levle 的fec包)
    • 一个fec包如果有 levle p 保护区,那么也肯定有 levle =p-1 且 level p 与 p-1 可能保护着不同的packet(变长媒体包)

    FEC的两种传输方式:

    (1) 以分开的一路流传输

    使用另外一路 M 行来表示 fec, 并使用 mid 和 group 来绑定 FEC 流和被保护的流

           v=0
           o=adam 289083124 289083124 IN IP4 host.example.com
           s=ULP FEC Seminar
           t=0 0
           c=IN IP4 224.2.17.12/127
           a=group:FEC 1 2
           a=group:FEC 3 4
           m=audio 30000 RTP/AVP 0
           a=mid:1
           m=application 30002 RTP/AVP 100
           a=rtpmap:100 ulpfec/8000
           a=mid:2
           m=video 30004 RTP/AVP 31
           a=mid:3
           m=application 30004 RTP/AVP 101
           c=IN IP4 224.2.17.13/127
           a=rtpmap:101 ulpfec/8000
           a=mid:4

    (2) FEC 作为冗余编码传输(Chrome)

    使用RED封装 被保护的主流和 FEC 流.

          m=audio 12345 RTP/AVP 121 0 5 100
          a=rtpmap:121 red/8000/1
          a=rtpmap:100 ulpfec/8000
          a=fmtp:121 0/5/100

    平时的主流使用 RED+RTP封装, 当产生FEC时可使用 RED + FEC封装格式传输FEC流. FEC 流跟在Marker后面, 使用跟Marker一样的TS.

    FLEXFEC

    flexible 主要体现在可以自由选择对行还是列(RTP包组成的数组)来生成fec包, 也可以选择直接重传某个包.

    也体现在保护的源RTP包个数没有ulpfec中的 Long Mask = 1 (48bit)的限制, flexfec可以使用 f bit来表示使用变长的mask bit,还是固定长度mask

    (即使是固定长度mask bit, 也是可自定义 M(column), N(raw))

    1-D Parity FEC protection

    非交错 1-D 失败的情况(连续丢包):
    
                         +---+                +---+  +===+
                         | 1 |    X      X    | 4 |  |R_1|
                         +---+                +---+  +===+
    
                         +---+  +---+  +---+  +---+  +===+
                         | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                         +---+  +---+  +---+  +---+  +===+
    
                         +---+  +---+  +---+  +---+  +===+
                         | 9 |  | 10|  | 11|  | 12|  |R_3|
                         +---+  +---+  +---+  +---+  +===+
    
    
    交错 1-D 失败的情况(定时丢包):
                            +---+         +---+  +---+
                            | 1 |    X    | 3 |  | 4 |
                            +---+         +---+  +---+
    
                            +---+         +---+  +---+
                            | 5 |    X    | 7 |  | 8 |
                            +---+         +---+  +---+
    
                            +---+  +---+  +---+  +---+
                            | 9 |  | 10|  | 11|  | 12|
                            +---+  +---+  +---+  +---+
    
                            +===+  +===+  +===+  +===+
                            |C_1|  |C_2|  |C_3|  |C_4|
                            +===+  +===+  +===+  +===+
    

    2-D Parity FEC protection:

                                       +---+  +---+  +===+
                           X      X    | 3 |  | 4 |  |R_1|
                                       +---+  +---+  +===+
    
                         +---+  +---+  +---+  +---+  +===+
                         | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                         +---+  +---+  +---+  +---+  +===+
    
                         +---+                +---+  +===+
                         | 9 |    X      X    | 12|  |R_3|
                         +---+                +---+  +===+
    
                         +===+  +===+  +===+  +===+
                         |C_1|  |C_2|  |C_3|  |C_4|
                         +===+  +===+  +===+  +===+
    
    
    2-D 失败的情况(特定定时连续丢包)
    
                         +---+                +---+  +===+
                         | 1 |    X      X    | 4 |  |R_1|
                         +---+                +---+  +===+
    
                         +---+  +---+  +---+  +---+  +===+
                         | 5 |  | 6 |  | 7 |  | 8 |  |R_2|
                         +---+  +---+  +---+  +---+  +===+
    
                         +---+                +---+  +===+
                         | 9 |    X      X    | 12|  |R_3|
                         +---+                +---+  +===+
    
                         +===+  +===+  +===+  +===+
                         |C_1|  |C_2|  |C_3|  |C_4|
                         +===+  +===+  +===+  +===+

    FlexFEC Header

            0                   1                   2                   3
            0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |R|F| P|X|  CC   |M| PT recovery |         length recovery      |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                          TS recovery                          |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |   SSRCCount   |                    reserved                   |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                             SSRC_i                            |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |           SN base_i           |k|          Mask [0-14]        |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |k|                   Mask [15-45] (optional)                   |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |k|                                                             |
           +-+                   Mask [46-108] (optional)                  |
           |                                                               |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                     ... next in SSRC_i ...                    |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    R:0:repair packet、1:retransmision
    F:0:flexible mask、1:offset M and N

    P、X、CC、M、PT (Recovery field):对主流的RTP header使用保护算法计算后得到

    Length recovery:用于验证恢复的包的payload长度,由被保护的rtp包的长度使用保护算法计算后得到、TS recovery:对主流的RTP header中的 TS使用保护算法计算后得到

    SSRCCount:被fec保护的SSRC 个数,0:非法
    Reserved: 0
    SSRC_i、SN base_i: 分别描述fec 所保护的包的 SSRC、SN base

    如果 F = 1 则使用固定长度描述被保护的包信息

            0                   1                   2                   3
            0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |1|0| P|X|  CC  |M| PT recovery |         length recovery       |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                          TS recovery                          |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |   SSRCCount   |                    reserved                   |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                             SSRC_i                            |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |           SN base_i           |  M (columns)  |    N (rows)   |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                     ... next in SSRC_i ...                    |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    M > 0 and N = 0 Row Fec

    M > 0 and N = 1 Row Fec + colum FEC follow

    M > 0 and N > 1 Column FEC

    如果 R=1 、F=1 则表示使用 Retransmision

            0                   1                   2                   3
            0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |1|1| P|X|  CC  |M| PT recovery |        sequence number        |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                           timestamp                           |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                              SSRC                             |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |                         Retransmission                        |
           :                            payload                            :
           |                                                               |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    FlexFEC in Offer、Answer

    multiplexed on different SSRCs

    Required
    rate: RTP timestamp clock rate
    repair-window: 主流与fec包的时间跨度
    
    Optional:
    L: columns
    D:rows
    ToP:   0:1-D interleaved FEC   1:1-D non-interleaved FEC  2:2-D parity FEC 3:reserved
    
    
            v=0
            o=ali 1122334455 1122334466 IN IP4 fec.example.com
            s=2-D Parity FEC with no in band signalling Example
            t=0 0
            m=video 30000 RTP/AVP 100 110
            c=IN IP4 233.252.0.1/127
            a=rtpmap:100 MP2T/90000
            a=rtpmap:110 flexfec/90000
            a=fmtp:110 L:5; D:10; ToP:2; repair-window:200000
            a=ssrc:1234
            a=ssrc:2345
            a=ssrc-group:FEC-FR 1234 2345

    ssrc-group:FEC-FR定义在 RFC 5956 (FEC grouping semantics in the SDP)

    用于描述 source 和 repair 的对应关系.

    Encode ulpfec

    modules/rtp_rtcp/source/ulpfec_genrator.h
    class UlpfecGenerator 中定义了ulpfec的编码实现

    设置 fec相关参数:

    WebRTC 中对视频帧类型为 KeyFrame 和 DeltaFrame 分开设置 FEC 相关参数, 均使用 FecProtectionParams 结构

    // Struct containing forward error correction settings.
    struct FecProtectionParams {
      int fec_rate;//fec的冗余度, The range is between 0 and 255, 
                   //where 255 corresponds to 100% overhead
      int max_fec_frames;//fec保护的码流的最大帧数
                         //(比如视频时max_fec_frames = 30表示在30帧时必须生成fec包)
      FecMaskType fec_mask_type;//fec的mask bitflag 使用模式, 分为随机和突发模式.
    };

    编码FEC包

    使用 AddRtpPacketAndGenerateFec 传入需要保护的packet.
    然后使用emphasized text 获取生成的 fec包数量
    然后使用 GetUlpfecPacketsAsRed 可获取 RED封装的FEC包

    内部细节:

        传入的 RTP 的包数量最多为ulpfec的最大bitflag长度(48), 内部会检测RTP的Marker位用于检测保护的流的帧数
        生成fec的条件:
        
        1) marker = 1
        2) 保护的帧数达到了 params中的max_fec_frames 或者 fec的开销和最小媒体包数量达到要求
        生成的 fec 存放在 generated_fec_packets_ , 使用  NumAvailableFecPackets 可获取其数量

    PS:

    ulpfecGenerator 内部使用的是 ForwarErrorCorrection对象 fec_ 来实现 ulpfec

    modules tp_rtcpsourceforward_error_correction.h 这里是fec更底层的实现,

    fec_.EnbcodeFec 可以指定更多的编码参数。

    • fec_factor, 也就是创建Generator时指定的 fec_rate(0-255), 255表示100%冗余度, 即多少个包就用多少个fec

    • num_important_packets, 用于指定这一帧中重要的包的个数(前面多少个包较重要),

    当使用UEP(Unequal Protection)时使用, 这些包会使用level比较高的保护

    • use_unequal_protection, 是否使用 UEP(Generator中就默认不使用UEP)

    • fec_mask_type, (这里同Generato中的 mask type)

    Decode ulpfec


    class UlpfecReceiver 定义了 ulpfec 接收和恢复相关接口, 具体实现在子类 calss UlpfecReceiverImpl 中.
    modules tp_rtcpincludeulpfec_receiver.h
    modules tp_rtcpsourceulpfec_receiver_impl.h

    基本步骤

    1. 创建ulpfec receiver, UlpfecReceiver::Create()
      这里可以指定一个 基类为RtpData(defined in rtp_rtcp_defines.h)的对象, 内部定义了回调接口OnRecoveredPacket当媒体包得到恢复时会回调上来.
    2. 将收到的 RED 包(包括媒体包和FEC包)传入 UlpfecReceiver::AddReceivedRedPacket
    3. 使用 UlpfecReceiver::ProcessReceivedFec() 进行恢复处理, 然后使用 UlpfecReceiver::GetPacketCounter 可获取 receiver 中的媒体包/fec/恢复的包 的个数.恢复的包会使用创建 Receiver 时指定的 RtpData的回调到上层

    动态 FEC 冗余度

    详见 VideoCoding::protection_bitrate_calculator 用于动态计算 FEC / NACK 可使用的发送 bitrate

    WebRTC 中将 NACK 和 FEC 的动态发送bitrate 处理逻辑放在一起实现, 相关类包括: ProtectionBitrateCalculator

    为了动态得到FEC/NACK的发送bitrate, 跟其相关的参数一共包括如下. 这些参数有些是直接从对端信令得到, 比如丢包率, RTT等信息,有些是自己根据本端实际发送数据得到, 比如实际发送 framerate, BitRatePerFrame, PacektNumPerFrame 等等.

    1.struct VCMProtectionParameters {
    2.  int64_t rtt;
    3.  float lossPr;
    4.  float bitRate;
    5.  float packetsPerFrame;
    6.  float packetsPerFrameKey;
    7.  float frameRate;
    8.  float keyFrameSize;
    9.  uint8_t fecRateDelta;
    10.  uint8_t fecRateKey;
    11.  uint16_t codecWidth;
    12.  uint16_t codecHeight;
    13.  int numLayers;
    14.};

    当使用 Nack 和 Fec 混合模式时有如下逻辑:

    1.// Thresholds for hybrid NACK/FEC
    2.// common to media optimization and the jitter buffer.
    3.const int64_t kLowRttNackMs = 20;

    当前 RTT < kLowRttNackMs = 20ms, 使用 NACK, 此时FEC仅用于保护 关键帧.
    当前 RTT > kHightRttNackMs 时仅使用 FEC, 关闭 NACK ( WebRTC 暂时未启用 )
    当前 RTT > kLowRttNackMs =20ms, 混合使用 NACK 和 FEC.
    当前每帧画面平均发送的BitRate 太低则会关闭 FEC, 此时不关心当前丢包率. 相关的几个阈值如下:

    1.  enum { kUpperLimitFramesFec = 6 };
    2.  // Thresholds values for the bytes/frame and round trip time, below which we
    3.  // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|.
    4.  // Max bytes/frame for VGA, corresponds to ~140k at 25fps.
    5.  enum { kMaxBytesPerFrameForFec = 700 };
    6.  // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps.
    7.  enum { kMaxBytesPerFrameForFecLow = 400 };
    8.  // Max bytes/frame for frame size larger than VGA, ~200k at 25fps.
    9.  enum { kMaxBytesPerFrameForFecHigh = 1000 };
    单位为 kb/s, 并且这个 每帧平均bitrate 有自己的计算方法.

    关键帧和非关键帧使用分开的 FEC 冗余度, 并且根据 effective rate(bits/frame) 每帧平均bitrate 和 丢包率 一起决定查表索引,静态表定义如下:

    1.// Table for Protection factor (code rate) of delta frames, for the XOR FEC.
    2.// Input is the packet loss and an effective rate (bits/frame).
    3.// Output is array kFecRateTable[k], where k = rate_i*129 + loss_j;
    4.// loss_j = 0,1,..128, and rate_i varies over some range.
    5.
    6.static const int kFecRateTableSize = 6450;
    7.static const unsigned char kFecRateTable[kFecRateTableSize]

    表中最大冗余度为 127, 相当于 WebRTC 最大FEC冗余为 50%, 255相当于100%冗余度.
    关键帧的 FEC 冗余度还与 关键帧的每帧平均包数 跟 非关键帧的每帧平均包数的比值相关,
    会重新计算查表索引得到自己的冗余度

    由于每个参数都会经过一些数学算法计算, 但是本人无法看出这么处理的意义, 就不详细讲其处理算法了.
    上述逻辑源码位置:
    modulesvideo_codingprotection_bitrate_calculator.cc
    modulesvideo_codingmedia_opt_util.cc

    FlexFEC in WebRTC

    FlexFEC 跟 UlpFEC实现有较大区别.

    ulpfec 是在 VideoReceiveStream 中解析RED后判断 PT 再 将 RTP 包添加到UlpfecReceiver 中,
    处理完再回调回来(分别使用 AddReceivedPacket OnRecoveredPackt).

    FlexFEC 是新建一个类似VideoReceiveStream的流: FlexfecReceiveStream. 处理完成后将恢复的包再通过VideoReceiveStream::OnRtpPacket进行处理.

    创建 FlexfecReceiveStream

      FlexfecReceiveStream* Call::CreateFlexfecReceiveStream(const FlexfecReceiveStream::Config& config)
      
      receive_stream = new FlexfecReceiveStreamImpl(
            &video_receiver_controller_, config, recovered_packet_receiver,
            call_stats_->rtcp_rtt_stats(), module_process_thread_.get());
    
      RecoveredPacketReceiver* recovered_packet_receiver = this;

    在 webrtcvideoengine.cc 中判断flexfec是否开启后再创建并启动 FlexfecReceiveStream

    recovered_packet_receiver用于传入 FlexfecReceiveStreamImpl 中, 某个包恢复之后用于回调到 Call 这层.

    创建 FlexfecReceiver

    在 FlexfecReceiveStream 中会创建 FlexfecReceiver(属于RtpRtcp模块), 也会创建自己的 RtpRtcp 实例.

    FlexfecReceiver 用于处理处理收到的 flexfec 包.

    增加 Sink 到 RtpStreamReceiverController

    会使用 RtpStreamReceiverController创建 Receiver, 同时将 this( FlexfecReceiveStream::OnPacket)作为

    Sink 传入 controller, 在sink中收到 RTP 包后传入 FlexfecReceiver 中处理.

    controller 增加sink时也会传入 SSRC, 可以收取指定ssrc的 rtp 包.

    在FlexfecReceiver 中处理 flexfec 包

    通过 Sink::OnPacket 传入到 FlexfecReceiver::OnPacket后在

    在 FlexfecReceiver::AddReceivedPacket 中判断包的负载长度要求以及ssrc

    flexfec负载要求最小长度为 20byte.

    最后使用 FlexfecReceiver::ProcessReceivedPackets进行flexfec 解码获取恢复出来的包

    然后使用 recovered_packet_receiver::OnRecoveredPacket 回调到上层(Call).

  • 相关阅读:
    Nginx的状态统计、目录保护、访问控制
    nginx如何解析php?
    CentOS6 搭建LNMP环境
    nginx的工作原理和工作模式
    shell脚本--逐行读取文件内容
    nginx配置文件中的的逻辑关系
    SecureCRT 拷贝时弹出 "Could not open clipboard: Assess is denied"
    Markdown的超链接由新窗口打开
    nginx查找模块、配置指令
    nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
  • 原文地址:https://www.cnblogs.com/x_wukong/p/8193290.html
Copyright © 2020-2023  润新知