Changeset 4012 for pjproject/trunk


Ignore:
Timestamp:
Apr 3, 2012 10:10:11 AM (13 years ago)
Author:
nanang
Message:

Close #1479: Applied RTCP related enhancements (#1268 & #1440) into video stream.

Location:
pjproject/trunk
Files:
3 edited

Legend:

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

    r3901 r4012  
    115115    pjmedia_vid_codec_param *codec_param; /**< Optional codec param.        */ 
    116116 
     117    pj_bool_t           rtcp_sdes_bye_disabled;  
     118                                    /**< Disable automatic sending of RTCP 
     119                                         SDES and BYE.                      */ 
    117120} pjmedia_vid_stream_info; 
    118121 
     
    333336 
    334337/** 
     338 * Send RTCP SDES for the media stream. 
     339 * 
     340 * @param stream        The media stream. 
     341 * 
     342 * @return              PJ_SUCCESS on success. 
     343 */ 
     344PJ_DECL(pj_status_t) pjmedia_vid_stream_send_rtcp_sdes( 
     345                                                pjmedia_vid_stream *stream); 
     346 
     347 
     348/** 
     349 * Send RTCP BYE for the media stream. 
     350 * 
     351 * @param stream        The media stream. 
     352 * 
     353 * @return              PJ_SUCCESS on success. 
     354 */ 
     355PJ_DECL(pj_status_t) pjmedia_vid_stream_send_rtcp_bye( 
     356                                                pjmedia_vid_stream *stream); 
     357 
     358 
     359/** 
    335360 * @} 
    336361 */ 
  • pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c

    r4010 r4012  
    118118    pj_uint32_t              rtcp_interval; /**< Interval, in timestamp.    */ 
    119119    pj_bool_t                initial_rr;    /**< Initial RTCP RR sent       */ 
     120    pj_bool_t                rtcp_sdes_bye_disabled;/**< Send RTCP SDES/BYE?*/ 
     121    void                    *out_rtcp_pkt;  /**< Outgoing RTCP packet.      */ 
     122    unsigned                 out_rtcp_pkt_size; 
     123                                            /**< Outgoing RTCP packet size. */ 
    120124 
    121125    unsigned                 dec_max_size;  /**< Size of decoded/raw picture*/ 
     
    169173    PJ_LOG(4,(sender, "%s: %s [err:%d]", title, errmsg, status)); 
    170174} 
     175 
     176 
     177static pj_status_t send_rtcp(pjmedia_vid_stream *stream, 
     178                             pj_bool_t with_sdes, 
     179                             pj_bool_t with_bye); 
    171180 
    172181 
     
    400409 
    401410    /* Send RTCP */ 
    402     pjmedia_rtcp_build_rtcp(&stream->rtcp, &pkt, &pkt_len); 
    403     pjmedia_transport_send_rtcp(stream->transport, pkt, pkt_len); 
     411    send_rtcp(stream, PJ_TRUE, PJ_FALSE, PJ_FALSE); 
    404412 
    405413#elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER 
     
    431439 
    432440 
     441static pj_status_t send_rtcp(pjmedia_vid_stream *stream, 
     442                             pj_bool_t with_sdes, 
     443                             pj_bool_t with_bye) 
     444{ 
     445    void *sr_rr_pkt; 
     446    pj_uint8_t *pkt; 
     447    int len, max_len; 
     448    pj_status_t status; 
     449 
     450    /* Build RTCP RR/SR packet */ 
     451    pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); 
     452 
     453    if (with_sdes || with_bye) { 
     454        pkt = (pj_uint8_t*) stream->out_rtcp_pkt; 
     455        pj_memcpy(pkt, sr_rr_pkt, len); 
     456        max_len = stream->out_rtcp_pkt_size; 
     457    } else { 
     458        pkt = sr_rr_pkt; 
     459        max_len = len; 
     460    } 
     461 
     462    /* Build RTCP SDES packet */ 
     463    if (with_sdes) { 
     464        pjmedia_rtcp_sdes sdes; 
     465        pj_size_t sdes_len; 
     466 
     467        pj_bzero(&sdes, sizeof(sdes)); 
     468        sdes.cname = stream->cname; 
     469        sdes_len = max_len - len; 
     470        status = pjmedia_rtcp_build_rtcp_sdes(&stream->rtcp, pkt+len, 
     471                                              &sdes_len, &sdes); 
     472        if (status != PJ_SUCCESS) { 
     473            PJ_PERROR(4,(stream->name.ptr, status, 
     474                                     "Error generating RTCP SDES")); 
     475        } else { 
     476            len += sdes_len; 
     477        } 
     478    } 
     479 
     480    /* Build RTCP BYE packet */ 
     481    if (with_bye) { 
     482        pj_size_t bye_len; 
     483 
     484        bye_len = max_len - len; 
     485        status = pjmedia_rtcp_build_rtcp_bye(&stream->rtcp, pkt+len, 
     486                                             &bye_len, NULL); 
     487        if (status != PJ_SUCCESS) { 
     488            PJ_PERROR(4,(stream->name.ptr, status, 
     489                                     "Error generating RTCP BYE")); 
     490        } else { 
     491            len += bye_len; 
     492        } 
     493    } 
     494 
     495    /* Send! */ 
     496    status = pjmedia_transport_send_rtcp(stream->transport, pkt, len); 
     497 
     498    return status; 
     499} 
     500 
     501 
    433502/** 
    434503 * check_tx_rtcp() 
     
    450519 
    451520    } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) { 
     521        pj_status_t status; 
    452522         
    453         void *rtcp_pkt; 
    454         int len; 
    455  
    456         pjmedia_rtcp_build_rtcp(&stream->rtcp, &rtcp_pkt, &len); 
    457  
    458         pjmedia_transport_send_rtcp(stream->transport, rtcp_pkt, len); 
     523        status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, PJ_FALSE); 
     524        if (status != PJ_SUCCESS) { 
     525            PJ_PERROR(4,(stream->name.ptr, status, 
     526                         "Error sending RTCP")); 
     527        } 
    459528 
    460529        stream->rtcp_last_tx = timestamp; 
    461530    } 
    462 } 
    463  
    464 /* Build RTCP SDES packet */ 
    465 static unsigned create_rtcp_sdes(pjmedia_vid_stream *stream, pj_uint8_t *pkt, 
    466                                  unsigned max_len) 
    467 { 
    468     pjmedia_rtcp_common hdr; 
    469     pj_uint8_t *p = pkt; 
    470  
    471     /* SDES header */ 
    472     hdr.version = 2; 
    473     hdr.p = 0; 
    474     hdr.count = 1; 
    475     hdr.pt = 202; 
    476     hdr.length = 2 + (4+stream->cname.slen+3)/4 - 1; 
    477     if (max_len < (hdr.length << 2)) { 
    478         pj_assert(!"Not enough buffer for SDES packet"); 
    479         return 0; 
    480     } 
    481     hdr.length = pj_htons((pj_uint16_t)hdr.length); 
    482     hdr.ssrc = stream->enc->rtp.out_hdr.ssrc; 
    483     pj_memcpy(p, &hdr, sizeof(hdr)); 
    484     p += sizeof(hdr); 
    485  
    486     /* CNAME item */ 
    487     *p++ = 1; 
    488     *p++ = (pj_uint8_t)stream->cname.slen; 
    489     pj_memcpy(p, stream->cname.ptr, stream->cname.slen); 
    490     p += stream->cname.slen; 
    491  
    492     /* END */ 
    493     *p++ = '\0'; 
    494     *p++ = '\0'; 
    495  
    496     /* Pad to 32bit */ 
    497     while ((p-pkt) % 4) 
    498         *p++ = '\0'; 
    499  
    500     return (p - pkt); 
    501 } 
    502  
    503 /* Build RTCP BYE packet */ 
    504 static unsigned create_rtcp_bye(pjmedia_vid_stream *stream, pj_uint8_t *pkt, 
    505                                 unsigned max_len) 
    506 { 
    507     pjmedia_rtcp_common hdr; 
    508  
    509     /* BYE header */ 
    510     hdr.version = 2; 
    511     hdr.p = 0; 
    512     hdr.count = 1; 
    513     hdr.pt = 203; 
    514     hdr.length = 1; 
    515     if (max_len < (hdr.length << 2)) { 
    516         pj_assert(!"Not enough buffer for SDES packet"); 
    517         return 0; 
    518     } 
    519     hdr.length = pj_htons((pj_uint16_t)hdr.length); 
    520     hdr.ssrc = stream->enc->rtp.out_hdr.ssrc; 
    521     pj_memcpy(pkt, &hdr, sizeof(hdr)); 
    522  
    523     return sizeof(hdr); 
    524531} 
    525532 
     
    717724    /* Send RTCP RR and SDES after we receive some RTP packets */ 
    718725    if (stream->rtcp.received >= 10 && !stream->initial_rr) { 
    719         void *sr_rr_pkt; 
    720         pj_uint8_t *pkt; 
    721         int len; 
    722  
    723         /* Build RR or SR */ 
    724         pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len); 
    725         pkt = (pj_uint8_t*) stream->enc->buf; 
    726         pj_memcpy(pkt, sr_rr_pkt, len); 
    727         pkt += len; 
    728  
    729         /* Append SDES */ 
    730         len = create_rtcp_sdes(stream, (pj_uint8_t*)pkt,  
    731                                stream->enc->buf_size - len); 
    732         if (len > 0) { 
    733             pkt += len; 
    734             len = ((pj_uint8_t*)pkt) - ((pj_uint8_t*)stream->enc->buf); 
    735             pjmedia_transport_send_rtcp(stream->transport,  
    736                                         stream->enc->buf, len); 
    737         } 
    738  
    739         stream->initial_rr = PJ_TRUE; 
     726        status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, 
     727                           PJ_FALSE); 
     728        if (status != PJ_SUCCESS) { 
     729            PJ_PERROR(4,(stream->name.ptr, status, 
     730                     "Error sending initial RTCP RR")); 
     731        } else { 
     732            stream->initial_rr = PJ_TRUE; 
     733        } 
    740734    } 
    741735} 
     
    12871281    pj_pool_t *own_pool = NULL; 
    12881282    pjmedia_vid_stream *stream; 
    1289     unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len; 
     1283    unsigned jb_init, jb_max, jb_min_pre, jb_max_pre; 
    12901284    int frm_ptime, chunks_per_frm; 
    12911285    pjmedia_video_format_detail *vfd_enc, *vfd_dec; 
     
    13581352    stream->rtcp_interval = (PJMEDIA_RTCP_INTERVAL-500 + (pj_rand()%1000)) * 
    13591353                            info->codec_info.clock_rate / 1000; 
     1354    stream->rtcp_sdes_bye_disabled = info->rtcp_sdes_bye_disabled; 
    13601355 
    13611356    stream->jb_last_frm = PJMEDIA_JB_NORMAL_FRAME; 
     
    15081503    } 
    15091504 
     1505    /* Allocate outgoing RTCP buffer, should be enough to hold SR/RR, SDES, 
     1506     * BYE, and XR. 
     1507     */ 
     1508    stream->out_rtcp_pkt_size =  sizeof(pjmedia_rtcp_sr_pkt) + 
     1509                                 sizeof(pjmedia_rtcp_common) + 
     1510                                 (4 + stream->cname.slen) + 
     1511                                 32; 
     1512    if (stream->out_rtcp_pkt_size > PJMEDIA_MAX_MTU) 
     1513        stream->out_rtcp_pkt_size = PJMEDIA_MAX_MTU; 
     1514 
     1515    stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size); 
     1516 
    15101517    /* Only attach transport when stream is ready. */ 
    15111518    status = pjmedia_transport_attach(tp, stream, &info->rem_addr,  
     
    15191526 
    15201527    /* Send RTCP SDES */ 
    1521     len = create_rtcp_sdes(stream, (pj_uint8_t*)stream->enc->buf,  
    1522                            stream->enc->buf_size); 
    1523     if (len != 0) { 
    1524         pjmedia_transport_send_rtcp(stream->transport,  
    1525                                     stream->enc->buf, len); 
     1528    if (!stream->rtcp_sdes_bye_disabled) { 
     1529        pjmedia_vid_stream_send_rtcp_sdes(stream); 
    15261530    } 
    15271531 
     
    15791583PJ_DEF(pj_status_t) pjmedia_vid_stream_destroy( pjmedia_vid_stream *stream ) 
    15801584{ 
    1581     unsigned len; 
    15821585    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL); 
    15831586 
    1584     /* Send RTCP BYE */ 
    1585     if (stream->enc && stream->transport) { 
    1586         len = create_rtcp_bye(stream, (pj_uint8_t*)stream->enc->buf, 
    1587                               stream->enc->buf_size); 
    1588         if (len != 0) { 
    1589             pjmedia_transport_send_rtcp(stream->transport,  
    1590                                         stream->enc->buf, len); 
    1591         } 
     1587    /* Send RTCP BYE (also SDES) */ 
     1588    if (!stream->rtcp_sdes_bye_disabled) { 
     1589        send_rtcp(stream, PJ_TRUE, PJ_TRUE); 
    15921590    } 
    15931591 
     
    18241822} 
    18251823 
     1824 
    18261825/* 
    18271826 * Force stream to send video keyframe. 
     
    18411840 
    18421841 
     1842/* 
     1843 * Send RTCP SDES. 
     1844 */ 
     1845PJ_DEF(pj_status_t) pjmedia_vid_stream_send_rtcp_sdes( 
     1846                                                pjmedia_vid_stream *stream) 
     1847{ 
     1848    PJ_ASSERT_RETURN(stream, PJ_EINVAL); 
     1849 
     1850    return send_rtcp(stream, PJ_TRUE, PJ_FALSE); 
     1851} 
     1852 
     1853 
     1854/* 
     1855 * Send RTCP BYE. 
     1856 */ 
     1857PJ_DEF(pj_status_t) pjmedia_vid_stream_send_rtcp_bye( 
     1858                                                pjmedia_vid_stream *stream) 
     1859{ 
     1860    PJ_ASSERT_RETURN(stream, PJ_EINVAL); 
     1861 
     1862    if (stream->enc && stream->transport) { 
     1863        return send_rtcp(stream, PJ_TRUE, PJ_TRUE); 
     1864    } 
     1865 
     1866    return PJ_SUCCESS; 
     1867} 
     1868 
     1869 
    18431870#endif /* PJMEDIA_HAS_VIDEO */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_vid.c

    r4000 r4012  
    709709    PJ_LOG(4,(THIS_FILE, "Video channel update..")); 
    710710    pj_log_push_indent(); 
     711 
     712    si->rtcp_sdes_bye_disabled = PJ_TRUE; 
    711713 
    712714    /* Check if no media is active */ 
Note: See TracChangeset for help on using the changeset viewer.