Changeset 5825


Ignore:
Timestamp:
Jul 17, 2018 8:11:17 AM (6 years ago)
Author:
nanang
Message:

Re #2126: Implemented incoming RTCP-FB handling, i.e: parse and notify application via PJMEDIA event framework.

Location:
pjproject/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/event.h

    r4815 r5825  
    8383     * Video orientation has been changed event. 
    8484     */ 
    85     PJMEDIA_EVENT_ORIENT_CHANGED = PJMEDIA_FOURCC('O', 'R', 'N', 'T') 
     85    PJMEDIA_EVENT_ORIENT_CHANGED = PJMEDIA_FOURCC('O', 'R', 'N', 'T'), 
     86 
     87    /** 
     88     * RTCP-FB has been received. 
     89     */ 
     90    PJMEDIA_EVENT_RX_RTCP_FB = PJMEDIA_FOURCC('R', 'T', 'F', 'B') 
    8691 
    8792} pjmedia_event_type; 
  • pjproject/trunk/pjmedia/include/pjmedia/rtcp_fb.h

    r5820 r5825  
    4444 
    4545/** 
    46  * Enumeration of RTCP Feedback types. 
     46 * Enumeration of RTCP Feedback types. Each feedback type may have subtypes, 
     47 * which should be specified in feedback parameters. 
    4748 */ 
    4849typedef enum pjmedia_rtcp_fb_type 
    4950{ 
    50     PJMEDIA_RTCP_FB_ACK,     /**< Positive acknowledgement feedbacks.       */ 
    51     PJMEDIA_RTCP_FB_NACK,    /**< Negative acknowledgement feedbacks.       */ 
    52     PJMEDIA_RTCP_FB_TRR_INT, /**< Minimum interval between two regular RTCP 
    53                                   packets.                                  */ 
    54     PJMEDIA_RTCP_FB_OTHER    /**< Other feedback type.                      */ 
     51    /** 
     52     * Positive acknowledgement feedbacks. Sample subtypes are Reference Picture 
     53     * Selection Indication (RPSI) and application layer feedbacks. 
     54     */ 
     55    PJMEDIA_RTCP_FB_ACK, 
     56 
     57    /** 
     58     * Negative acknowledgement feedbacks. Sample subtypes are generic NACK, 
     59     * Picture Loss Indication (PLI), Slice Loss Indication (SLI), Reference 
     60     * Picture Selection Indication (RPSI), and application layer feedbacks. 
     61     */ 
     62    PJMEDIA_RTCP_FB_NACK, 
     63 
     64    /** 
     65     * Minimum interval between two regular RTCP packets. 
     66     */ 
     67    PJMEDIA_RTCP_FB_TRR_INT, 
     68 
     69    /** 
     70     * Other feedback types. 
     71     */ 
     72    PJMEDIA_RTCP_FB_OTHER 
     73 
    5574} pjmedia_rtcp_fb_type; 
    5675 
     
    8099 
    81100    /** 
    82      * Specify the RTCP Feedback parameters. 
     101     * Specify the RTCP Feedback parameters. Feedback subtypes should be 
     102     * specified in this field, e.g: 
     103     * - 'pli' for Picture Loss Indication feedback, 
     104     * - 'sli' for Slice Loss Indication feedback, 
     105     * - 'rpsi' for Reference Picture Selection Indication feedback, 
     106     * - 'app' for specific/proprietary application layer feedback. 
    83107     */ 
    84108    pj_str_t                param; 
     
    135159 
    136160/** 
     161 * This structure declares RTCP Feedback Generic NACK message. 
     162 */ 
     163typedef struct pjmedia_rtcp_fb_nack 
     164{ 
     165    pj_int32_t           pid;           /**< Packet ID (RTP seq)    */ 
     166    pj_uint16_t          blp;           /**< Bitmask of following lost 
     167                                             packets                */ 
     168} pjmedia_rtcp_fb_nack; 
     169 
     170 
     171/** 
     172 * This structure declares RTCP Feedback Slice Loss Indication (SLI) message. 
     173 */ 
     174typedef struct pjmedia_rtcp_fb_sli 
     175{ 
     176    pj_uint16_t          first;         /**< First lost macroblock      */ 
     177    pj_uint16_t          number;        /**< The number of lost macroblocks 
     178                                             packets                    */ 
     179    pj_uint8_t           pict_id;       /**< Picture ID (temporal ref)  */ 
     180} pjmedia_rtcp_fb_sli; 
     181 
     182 
     183/** 
     184 * This structure declares RTCP Feedback Reference Picture Selection 
     185 * Indication (RPSI) message. 
     186 */ 
     187typedef struct pjmedia_rtcp_fb_rpsi 
     188{ 
     189    pj_uint8_t           pt;            /**< Payload Type               */ 
     190    pj_str_t             rpsi;          /**< Native RPSI bit string     */ 
     191    pj_size_t            rpsi_bit_len;  /**< Length of RPSI in bit      */ 
     192} pjmedia_rtcp_fb_rpsi; 
     193 
     194 
     195/** 
     196 * Event data for incoming RTCP Feedback message event 
     197 * (PJMEDIA_EVENT_RX_RTCP_FB). 
     198 */ 
     199typedef struct pjmedia_event_rx_rtcp_fb_data 
     200{ 
     201    pjmedia_rtcp_fb_cap         cap; 
     202    union { 
     203        pjmedia_rtcp_fb_nack    nack; 
     204        pjmedia_rtcp_fb_sli     sli; 
     205        pjmedia_rtcp_fb_rpsi    rpsi; 
     206    } msg; 
     207 
     208} pjmedia_event_rx_rtcp_fb_data; 
     209 
     210 
     211/** 
    137212 * Initialize RTCP Feedback setting with default values. 
    138213 * 
     
    220295 
    221296/** 
    222  * This structure declares RTCP Feedback Generic NACK message. 
    223  */ 
    224 typedef struct pjmedia_rtcp_fb_nack 
    225 { 
    226     pj_int32_t           pid;           /**< Packet ID (RTP seq)    */ 
    227     pj_uint16_t          blp;           /**< Bitmask of following lost 
    228                                              packets                */ 
    229 } pjmedia_rtcp_fb_nack; 
    230  
    231  
    232 /** 
    233297 * Build an RTCP Feedback Generic NACK packet. This packet can be appended to 
    234298 * other RTCP packets, e.g: RTCP RR/SR, to compose a compound RTCP packet. 
     
    273337 
    274338/** 
    275  * This structure declares RTCP Feedback Slice Loss Indication (SLI) message. 
    276  */ 
    277 typedef struct pjmedia_rtcp_fb_sli 
    278 { 
    279     pj_uint16_t          first;         /**< First lost macroblock      */ 
    280     pj_uint16_t          number;        /**< The number of lost macroblocks 
    281                                              packets                    */ 
    282     pj_uint8_t           pict_id;       /**< Picture ID (temporal ref)  */ 
    283 } pjmedia_rtcp_fb_sli; 
    284  
    285  
    286 /** 
    287339 * Build an RTCP Feedback Slice Loss Indication (SLI) packet. This packet can 
    288340 * be appended to other RTCP packets, e.g: RTCP RR/SR, to compose a compound 
     
    308360 
    309361/** 
    310  * This structure declares RTCP Feedback Reference Picture Selection 
    311  * Indication (RPSI) message. 
    312  */ 
    313 typedef struct pjmedia_rtcp_fb_rpsi 
    314 { 
    315     pj_uint8_t           pt;            /**< Payload Type               */ 
    316     pj_str_t             rpsi;          /**< Native RPSI bit string     */ 
    317     pj_size_t            rpsi_bit_len;  /**< Length of RPSI in bit      */ 
    318 } pjmedia_rtcp_fb_rpsi; 
    319  
    320  
    321 /** 
    322362 * Build an RTCP Feedback Reference Picture Selection Indication (RPSI) 
    323363 * packet. This packet can be appended to other RTCP packets, e.g: RTCP RR/SR, 
     
    342382 
    343383/** 
     384 * Check whether the specified payload contains RTCP feedback generic NACK 
     385 * message, and parse the payload if it does. 
     386 * 
     387 * @param buf       The payload buffer. 
     388 * @param length    The payload length. 
     389 * @param nack_cnt  On input, it specifies the maximum number of generic NACK 
     390 *                  messages. 
     391 *                  On output, it specifies the number of parsed generic NACK 
     392 *                  messages. 
     393 * @param nack      The array of RTCP Feedback Generic NACK messages. 
     394 * 
     395 * @return          PJ_SUCCESS if the payload contains generic NACK message 
     396 *                  and has been parsed successfully. 
     397 */ 
     398PJ_DECL(pj_status_t) pjmedia_rtcp_fb_parse_nack( 
     399                                        const void *buf, 
     400                                        pj_size_t length, 
     401                                        unsigned *nack_cnt, 
     402                                        pjmedia_rtcp_fb_nack nack[]); 
     403 
     404 
     405/** 
     406 * Check whether the specified payload contains RTCP feedback Picture Loss 
     407 * Indication (PLI) message. 
     408 * 
     409 * @param buf       The payload buffer. 
     410 * @param length    The payload length. 
     411 * 
     412 * @return          PJ_SUCCESS if the payload contains PLI message. 
     413 */ 
     414PJ_DECL(pj_status_t) pjmedia_rtcp_fb_parse_pli( 
     415                                        const void *buf, 
     416                                        pj_size_t length); 
     417 
     418 
     419/** 
     420 * Check whether the specified payload contains RTCP feedback Slice Loss 
     421 * Indication (SLI) message, and parse the payload if it does. 
     422 * 
     423 * @param buf       The payload buffer. 
     424 * @param length    The payload length. 
     425 * @param sli_cnt   On input, it specifies the maximum number of SLI messages. 
     426 *                  On output, it specifies the number of parsed SLI messages. 
     427 * @param sli       The array of RTCP Feedback SLI messages. 
     428 * 
     429 * @return          PJ_SUCCESS if the payload contains SLI messages and 
     430 *                  has been parsed successfully. 
     431 */ 
     432PJ_DECL(pj_status_t) pjmedia_rtcp_fb_parse_sli( 
     433                                        const void *buf, 
     434                                        pj_size_t length, 
     435                                        unsigned *sli_cnt, 
     436                                        pjmedia_rtcp_fb_sli sli[]); 
     437 
     438 
     439/** 
     440 * Check whether the specified payload contains RTCP feedback Reference 
     441 * Picture Selection Indication (RPSI) message, and parse the payload 
     442 * if it does. 
     443 * 
     444 * @param buf       The payload buffer. 
     445 * @param length    The payload length. 
     446 * @param rpsi      The parsed RTCP Feedback RPSI messages. 
     447 * 
     448 * @return          PJ_SUCCESS if the payload contains SLI messages and 
     449 *                  has been parsed successfully. 
     450 */ 
     451PJ_DECL(pj_status_t) pjmedia_rtcp_fb_parse_rpsi( 
     452                                        const void *buf, 
     453                                        pj_size_t length, 
     454                                        pjmedia_rtcp_fb_rpsi *rpsi); 
     455 
     456 
     457/** 
    344458 * @} 
    345459 */ 
  • pjproject/trunk/pjmedia/src/pjmedia/rtcp.c

    r4712 r5825  
    2020#include <pjmedia/rtcp.h> 
    2121#include <pjmedia/errno.h> 
     22#include <pjmedia/event.h> 
     23#include <pjmedia/rtcp_fb.h> 
    2224#include <pj/assert.h> 
    2325#include <pj/log.h> 
     
    3335#define RTCP_BYE  203 
    3436#define RTCP_XR   207 
     37 
     38/* RTCP Feedbacks */ 
     39#define RTCP_RTPFB      205 
     40#define RTCP_PSFB       206 
    3541 
    3642enum { 
     
    765771 
    766772 
     773static void parse_rtcp_fb(pjmedia_rtcp_session *sess, 
     774                          const void *pkt, 
     775                          pj_size_t size) 
     776{ 
     777    unsigned cnt = 1; 
     778    pjmedia_rtcp_fb_nack nack[1]; 
     779    //pjmedia_rtcp_fb_sli sli[1]; 
     780    //pjmedia_rtcp_fb_rpsi rpsi; 
     781    pjmedia_event ev; 
     782    pjmedia_event_rx_rtcp_fb_data ev_data; 
     783    pj_timestamp ts_now; 
     784 
     785    pj_get_timestamp(&ts_now); 
     786    pj_bzero(&ev_data, sizeof(ev_data)); 
     787 
     788    if (pjmedia_rtcp_fb_parse_nack(pkt, size, &cnt, nack)==PJ_SUCCESS) 
     789    { 
     790        pjmedia_event_init(&ev, PJMEDIA_EVENT_RX_RTCP_FB, &ts_now, sess); 
     791        ev_data.cap.type = PJMEDIA_RTCP_FB_NACK; 
     792        ev_data.msg.nack = nack[0]; 
     793        ev.data.ptr = &ev_data; 
     794 
     795        /* Sync publish, i.e: don't use PJMEDIA_EVENT_PUBLISH_POST_EVENT */ 
     796        pjmedia_event_publish(NULL, sess, &ev, 0); 
     797 
     798        /*  For other FB type implementations later 
     799    } else if (pjmedia_rtcp_fb_parse_pli(pkt, size)==PJ_SUCCESS) 
     800    { 
     801    } else if (pjmedia_rtcp_fb_parse_sli(pkt, size, &cnt, sli)==PJ_SUCCESS) 
     802    { 
     803    } else if (pjmedia_rtcp_fb_parse_rpsi(pkt, size, &rpsi)==PJ_SUCCESS) 
     804    { 
     805        */ 
     806    } else { 
     807        /* Ignore unknown RTCP Feedback */ 
     808        TRACE_((sess->name, "Received unknown RTCP feedback")); 
     809    } 
     810} 
     811 
     812 
    767813PJ_DEF(void) pjmedia_rtcp_rx_rtcp( pjmedia_rtcp_session *sess, 
    768814                                   const void *pkt, 
     
    789835        case RTCP_BYE: 
    790836            parse_rtcp_bye(sess, p, len); 
     837            break; 
     838        case RTCP_RTPFB: 
     839        case RTCP_PSFB: 
     840            parse_rtcp_fb(sess, p, len); 
    791841            break; 
    792842        default: 
  • pjproject/trunk/pjmedia/src/pjmedia/rtcp_fb.c

    r5820 r5825  
    215215{ 
    216216    pj_bzero(opt, sizeof(*opt)); 
    217  
    218     /* == just for test == */ 
    219     opt->cap_count = 4; 
    220  
    221     pj_cstr(&opt->caps[0].codec_id, "*"); 
    222     opt->caps[0].type = PJMEDIA_RTCP_FB_ACK; 
    223      
    224     pj_cstr(&opt->caps[1].codec_id, "speex/16000"); 
    225     opt->caps[1].type = PJMEDIA_RTCP_FB_NACK; 
    226      
    227     pj_cstr(&opt->caps[2].codec_id, "H264"); 
    228     opt->caps[2].type = PJMEDIA_RTCP_FB_NACK; 
    229     pj_cstr(&opt->caps[2].param, "pli"); 
    230  
    231     pj_cstr(&opt->caps[3].codec_id, "pcmu"); 
    232     opt->caps[3].type = PJMEDIA_RTCP_FB_NACK; 
    233     /* == just for test == */ 
    234217 
    235218    return PJ_SUCCESS; 
     
    581564    return PJ_SUCCESS; 
    582565} 
     566 
     567 
     568/* 
     569 * Check whether the specified payload contains RTCP feedback generic NACK 
     570 * message, and parse the payload if it does. 
     571 */ 
     572PJ_DEF(pj_status_t) pjmedia_rtcp_fb_parse_nack( 
     573                                        const void *buf, 
     574                                        pj_size_t length, 
     575                                        unsigned *nack_cnt, 
     576                                        pjmedia_rtcp_fb_nack nack[]) 
     577{ 
     578    pjmedia_rtcp_common *hdr = (pjmedia_rtcp_common*) buf; 
     579    pj_uint8_t *p; 
     580    unsigned cnt, i; 
     581 
     582    PJ_ASSERT_RETURN(buf && nack_cnt && nack, PJ_EINVAL); 
     583    PJ_ASSERT_RETURN(length >= sizeof(pjmedia_rtcp_common), PJ_ETOOSMALL); 
     584 
     585    /* Generic NACK uses pt==RTCP_RTPFB and FMT==1 */ 
     586    if (hdr->pt != RTCP_RTPFB || hdr->count != 1) 
     587        return PJ_ENOTFOUND; 
     588 
     589    cnt = pj_ntohs((pj_uint16_t)hdr->length) - 2; 
     590    if (length < (cnt+3)*4) 
     591        return PJ_ETOOSMALL; 
     592 
     593    *nack_cnt = PJ_MIN(*nack_cnt, cnt); 
     594 
     595    p = (pj_uint8_t*)hdr + sizeof(*hdr); 
     596    for (i = 0; i < *nack_cnt; ++i) { 
     597        pj_uint16_t val; 
     598 
     599        pj_memcpy(&val, p, 2); 
     600        nack[i].pid = pj_ntohs(val); 
     601        pj_memcpy(&val, p+2, 2); 
     602        nack[i].blp = pj_ntohs(val); 
     603        p += 4; 
     604    } 
     605 
     606    return PJ_SUCCESS; 
     607} 
     608 
     609 
     610/* 
     611 * Check whether the specified payload contains RTCP feedback Picture Loss 
     612 * Indication (PLI) message. 
     613 */ 
     614PJ_DEF(pj_status_t) pjmedia_rtcp_fb_parse_pli( 
     615                                        const void *buf, 
     616                                        pj_size_t length) 
     617{ 
     618    pjmedia_rtcp_common *hdr = (pjmedia_rtcp_common*) buf; 
     619 
     620    PJ_ASSERT_RETURN(buf, PJ_EINVAL); 
     621    PJ_ASSERT_RETURN(length >= 12, PJ_ETOOSMALL); 
     622 
     623    /* PLI uses pt==RTCP_PSFB and FMT==1 */ 
     624    if (hdr->pt != RTCP_PSFB || hdr->count != 1) 
     625        return PJ_ENOTFOUND; 
     626 
     627    return PJ_SUCCESS; 
     628} 
     629 
     630 
     631/* 
     632 * Check whether the specified payload contains RTCP feedback Slice Loss 
     633 * Indication (SLI) message, and parse the payload if it does. 
     634 */ 
     635PJ_DEF(pj_status_t) pjmedia_rtcp_fb_parse_sli( 
     636                                        const void *buf, 
     637                                        pj_size_t length, 
     638                                        unsigned *sli_cnt, 
     639                                        pjmedia_rtcp_fb_sli sli[]) 
     640{ 
     641    pjmedia_rtcp_common *hdr = (pjmedia_rtcp_common*) buf; 
     642    pj_uint8_t *p; 
     643    unsigned cnt, i; 
     644 
     645    PJ_ASSERT_RETURN(buf && sli_cnt && sli, PJ_EINVAL); 
     646    PJ_ASSERT_RETURN(length >= sizeof(pjmedia_rtcp_common), PJ_ETOOSMALL); 
     647 
     648    /* PLI uses pt==RTCP_PSFB and FMT==2 */ 
     649    if (hdr->pt != RTCP_PSFB || hdr->count != 2) 
     650        return PJ_ENOTFOUND; 
     651 
     652    cnt = pj_ntohs((pj_uint16_t)hdr->length) - 2; 
     653    if (length < (cnt+3)*4) 
     654        return PJ_ETOOSMALL; 
     655 
     656    *sli_cnt = PJ_MIN(*sli_cnt, cnt); 
     657 
     658    p = (pj_uint8_t*)hdr + sizeof(*hdr); 
     659    for (i = 0; i < *sli_cnt; ++i) { 
     660        /* 'first' takes 13 bit */ 
     661        sli[i].first = (p[0] << 5) + ((p[1] & 0xF8) >> 3); 
     662        /* 'number' takes 13 bit */ 
     663        sli[i].number = ((p[1] & 0x07) << 10) + 
     664                        (p[2] << 2) + 
     665                        ((p[3] & 0xC0) >> 6); 
     666        /* 'pict_id' takes 6 bit */ 
     667        sli[i].pict_id = (p[3] & 0x3F); 
     668        p += 4; 
     669    } 
     670 
     671    return PJ_SUCCESS; 
     672} 
     673 
     674 
     675/* 
     676 * Check whether the specified payload contains RTCP feedback Reference 
     677 * Picture Selection Indication (RPSI) message, and parse the payload 
     678 * if it does. 
     679 */ 
     680PJ_DEF(pj_status_t) pjmedia_rtcp_fb_parse_rpsi( 
     681                                        const void *buf, 
     682                                        pj_size_t length, 
     683                                        pjmedia_rtcp_fb_rpsi *rpsi) 
     684{ 
     685    pjmedia_rtcp_common *hdr = (pjmedia_rtcp_common*) buf; 
     686    pj_uint8_t *p; 
     687    pj_uint8_t padlen; 
     688    pj_size_t rpsi_len; 
     689 
     690    PJ_ASSERT_RETURN(buf && rpsi, PJ_EINVAL); 
     691    PJ_ASSERT_RETURN(length >= sizeof(pjmedia_rtcp_common), PJ_ETOOSMALL); 
     692 
     693    /* RPSI uses pt==RTCP_PSFB and FMT==3 */ 
     694    if (hdr->pt != RTCP_PSFB || hdr->count != 3) 
     695        return PJ_ENOTFOUND; 
     696 
     697    rpsi_len = (pj_ntohs((pj_uint16_t)hdr->length)-2) * 4; 
     698    if (length < rpsi_len + 12) 
     699        return PJ_ETOOSMALL; 
     700 
     701    p = (pj_uint8_t*)hdr + sizeof(*hdr); 
     702    padlen = *p++; 
     703    rpsi->pt = (*p++ & 0x7F); 
     704    rpsi->rpsi_bit_len = rpsi_len*8 - 16 - padlen; 
     705    pj_strset(&rpsi->rpsi, (char*)p, (rpsi->rpsi_bit_len + 7)/8); 
     706 
     707    return PJ_SUCCESS; 
     708} 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r5820 r5825  
    249249 
    250250    /* RTCP Feedback */ 
    251     pj_bool_t                send_rtcp_fb_nack;/**< Should we send NACK?    */ 
    252     pjmedia_rtcp_fb_nack     rtcp_fb_nack;     /**< NACK state.             */ 
     251    pj_bool_t                send_rtcp_fb_nack;     /**< Send NACK?         */ 
     252    pjmedia_rtcp_fb_nack     rtcp_fb_nack;          /**< TX NACK state.     */ 
     253    int                      rtcp_fb_nack_cap_idx;  /**< RX NACK cap idx.   */ 
    253254 
    254255 
     
    17251726    const void *payload; 
    17261727    unsigned payloadlen; 
    1727     pjmedia_rtp_status seq_st = {0}; 
     1728    pjmedia_rtp_status seq_st; 
    17281729    pj_status_t status; 
    17291730    pj_bool_t pkt_discarded = PJ_FALSE; 
     
    17681769 
    17691770    /* Ignore the packet if decoder is paused */ 
     1771    pj_bzero(&seq_st, sizeof(seq_st)); 
    17701772    if (channel->paused) 
    17711773        goto on_return; 
     
    21932195 
    21942196/* 
     2197 * Handle events. 
     2198 */ 
     2199static pj_status_t stream_event_cb(pjmedia_event *event, 
     2200                                   void *user_data) 
     2201{ 
     2202    pjmedia_stream *stream = (pjmedia_stream*)user_data; 
     2203 
     2204    /* Set RTCP FB capability in the event */ 
     2205    if (event->type==PJMEDIA_EVENT_RX_RTCP_FB && 
     2206        event->epub==&stream->rtcp) 
     2207    { 
     2208        pjmedia_event_rx_rtcp_fb_data *data = (pjmedia_event_rx_rtcp_fb_data*) 
     2209                                              event->data.ptr; 
     2210 
     2211        /* Application not configured to listen to NACK, discard this event */ 
     2212        if (stream->rtcp_fb_nack_cap_idx < 0) 
     2213            return PJ_SUCCESS; 
     2214         
     2215        data->cap = stream->si.loc_rtcp_fb.caps[stream->rtcp_fb_nack_cap_idx]; 
     2216    } 
     2217 
     2218    /* Republish events */ 
     2219    return pjmedia_event_publish(NULL, stream, event, 0); 
     2220} 
     2221 
     2222 
     2223/* 
    21952224 * Create media stream. 
    21962225 */ 
     
    25692598            stream->rtcp.stat.rtp_tx_last_ts = info->rtp_ts; 
    25702599        } 
     2600 
     2601        /* Subscribe to RTCP events */ 
     2602        pjmedia_event_subscribe(NULL, &stream_event_cb, stream, 
     2603                                &stream->rtcp); 
    25712604    } 
    25722605 
     
    26652698#endif 
    26662699 
    2667     /* Check if RTCP-FB generic NACK is enabled for this codec */ 
     2700    /* Check if we should send RTCP-FB generic NACK for this codec */ 
    26682701    if (stream->si.rem_rtcp_fb.cap_count) { 
    26692702        pjmedia_rtcp_fb_info *rfi = &stream->si.rem_rtcp_fb; 
     
    26792712            { 
    26802713                stream->send_rtcp_fb_nack = PJ_TRUE; 
     2714                break; 
     2715            } 
     2716        } 
     2717    } 
     2718 
     2719    /* Check if we handle incoming RTCP-FB generic NACK for this codec */ 
     2720    stream->rtcp_fb_nack_cap_idx = -1; 
     2721    if (stream->si.loc_rtcp_fb.cap_count) { 
     2722        pjmedia_rtcp_fb_info *lfi = &stream->si.loc_rtcp_fb; 
     2723        char cid[32]; 
     2724        unsigned i; 
     2725 
     2726        pjmedia_codec_info_to_id(&stream->si.fmt, cid, sizeof(cid)); 
     2727 
     2728        for (i = 0; i < lfi->cap_count; ++i) { 
     2729            if (lfi->caps[i].type == PJMEDIA_RTCP_FB_NACK && 
     2730                (!pj_strcmp2( &lfi->caps[i].codec_id, "*") || 
     2731                 !pj_stricmp2(&lfi->caps[i].codec_id, cid))) 
     2732            { 
     2733                stream->rtcp_fb_nack_cap_idx = i; 
    26812734                break; 
    26822735            } 
     
    27962849        } 
    27972850    } 
     2851 
     2852    /* Unsubscribe from RTCP session events */ 
     2853    pjmedia_event_unsubscribe(NULL, &stream_event_cb, stream, 
     2854                              &stream->rtcp); 
    27982855 
    27992856    /* Detach from transport 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c

    r5792 r5825  
    502502 
    503503    if (strm) { 
     504        /* Unsubscribe from stream events */ 
     505        pjmedia_event_unsubscribe(NULL, &call_media_on_event, call_med, strm); 
     506 
    504507        pjmedia_stream_send_rtcp_bye(strm); 
    505508 
     
    701704            } 
    702705        } 
     706 
     707        /* Subscribe to stream events */ 
     708        pjmedia_event_subscribe(NULL, &call_media_on_event, call_med, 
     709                                call_med->strm.a.stream); 
    703710    } 
    704711 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r5820 r5825  
    110110        goto on_error; 
    111111#endif 
     112 
     113    /* Create event manager (if not yet, e.g: PJMEDIA_HAS_VIDEO==0) */ 
     114    if (!pjmedia_event_mgr_instance()) { 
     115        status = pjmedia_event_mgr_create(pjsua_var.pool,  
     116                                          PJMEDIA_EVENT_MGR_NO_THREAD, NULL); 
     117        if (status != PJ_SUCCESS) { 
     118            PJ_PERROR(1,(THIS_FILE, status, 
     119                         "Error creating PJMEDIA event manager")); 
     120            goto on_error; 
     121        } 
     122    } 
    112123 
    113124    pj_log_pop_indent(); 
Note: See TracChangeset for help on using the changeset viewer.