Changeset 6005 for pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c
- Timestamp:
- May 26, 2019 1:18:02 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c
r5982 r6005 1 1 /* $Id$ */ 2 /* 2 /* 3 3 * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com) 4 4 * … … 15 15 * You should have received a copy of the GNU General Public License 16 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 19 #include <pjmedia/vid_stream.h> … … 75 75 #define MIN_CHUNKS_PER_FRM 30 76 76 77 /* Number of send error before repeat the report. */ 78 #define SEND_ERR_COUNT_TO_REPORT 50 77 79 78 80 /** … … 115 117 116 118 pjmedia_transport *transport; /**< Stream transport. */ 117 unsigned send_err_cnt; /**< Send error count. */118 119 119 120 pj_mutex_t *jb_mutex; … … 137 138 pjmedia_event fmt_event; /**< Buffered fmt_changed event 138 139 to avoid deadlock */ 139 pjmedia_event miss_keyframe_event; 140 pjmedia_event miss_keyframe_event; 140 141 /**< Buffered missing keyframe 141 142 event for delayed republish*/ … … 148 149 frame assembly. */ 149 150 pj_bool_t force_keyframe;/**< Forced to encode keyframe? */ 150 unsigned num_keyframe; /**< The number of keyframe needed 151 unsigned num_keyframe; /**< The number of keyframe needed 151 152 to be sent, after the stream 152 153 is created. */ 153 pj_timestamp last_keyframe_tx; 154 /**< Timestamp of the last 154 pj_timestamp last_keyframe_tx; 155 /**< Timestamp of the last 155 156 keyframe. */ 156 157 … … 172 173 pj_uint32_t last_dec_ts; /**< Last decoded timestamp. */ 173 174 int last_dec_seq; /**< Last decoded sequence. */ 174 pj_status_t rtp_rx_last_err; /**< Last RTP recv() error. */ 175 pj_uint32_t rtp_tx_err_cnt;/**< The number of RTP 176 send() error */ 177 pj_uint32_t rtcp_tx_err_cnt;/**< The number of RTCP 178 send() error */ 175 179 176 180 pj_timestamp ts_freq; /**< Timestamp frequency. */ … … 178 182 pj_sockaddr rem_rtp_addr; /**< Remote RTP address */ 179 183 unsigned rem_rtp_flag; /**< Indicator flag about 180 packet from this addr. 181 0=no pkt, 1=good ssrc pkts, 184 packet from this addr. 185 0=no pkt, 1=good ssrc pkts, 182 186 2=bad ssrc pkts */ 183 187 pj_sockaddr rtp_src_addr; /**< Actual packet src addr. */ … … 203 207 204 208 static void on_rx_rtcp( void *data, 205 void *pkt, 209 void *pkt, 206 210 pj_ssize_t bytes_read); 207 211 … … 233 237 } 234 238 235 PJ_INLINE(int) trace_jb_print_state(pjmedia_vid_stream *stream, 239 PJ_INLINE(int) trace_jb_print_state(pjmedia_vid_stream *stream, 236 240 char **buf, pj_ssize_t len) 237 241 { … … 405 409 } 406 410 411 /** 412 * Publish transport error event. 413 */ 414 static void publish_tp_event(pjmedia_event_type event_type, 415 pj_status_t status, 416 pj_bool_t is_rtp, 417 pjmedia_dir dir, 418 pjmedia_vid_stream *stream) 419 { 420 pjmedia_event ev; 421 pj_timestamp ts_now; 422 423 pj_get_timestamp(&ts_now); 424 pj_bzero(&ev.data.med_tp_err, sizeof(ev.data.med_tp_err)); 425 426 /* Publish event. */ 427 pjmedia_event_init(&ev, event_type, 428 &ts_now, stream); 429 ev.data.med_tp_err.type = PJMEDIA_TYPE_VIDEO; 430 ev.data.med_tp_err.is_rtp = is_rtp; 431 ev.data.med_tp_err.dir = dir; 432 ev.data.med_tp_err.status = status; 433 434 pjmedia_event_publish(NULL, stream, &ev, 0); 435 } 436 407 437 #if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0 408 438 /* … … 462 492 463 493 #else 464 494 465 495 PJ_UNUSED_ARG(stream); 466 496 … … 478 508 int len, max_len; 479 509 pj_status_t status; 510 pjmedia_vid_channel *channel = stream->enc; 480 511 481 512 /* Build RTCP RR/SR packet */ … … 526 557 /* Send! */ 527 558 status = pjmedia_transport_send_rtcp(stream->transport, pkt, len); 528 559 if (status != PJ_SUCCESS) { 560 if (stream->rtcp_tx_err_cnt++ == 0) { 561 LOGERR_((channel->port.info.name.ptr, status, 562 "Error sending RTCP")); 563 } 564 if (stream->rtcp_tx_err_cnt > SEND_ERR_COUNT_TO_REPORT) { 565 stream->rtcp_tx_err_cnt = 0; 566 } 567 } 529 568 return status; 530 569 } … … 539 578 static void check_tx_rtcp(pjmedia_vid_stream *stream, pj_uint32_t timestamp) 540 579 { 541 /* Note that timestamp may represent local or remote timestamp, 580 /* Note that timestamp may represent local or remote timestamp, 542 581 * depending on whether this function is called from put_frame() 543 582 * or get_frame(). … … 546 585 547 586 if (stream->rtcp_last_tx == 0) { 548 587 549 588 stream->rtcp_last_tx = timestamp; 550 589 551 590 } else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) { 552 591 pj_status_t status; 553 592 554 593 status = send_rtcp(stream, !stream->rtcp_sdes_bye_disabled, PJ_FALSE); 555 594 if (status != PJ_SUCCESS) { … … 591 630 /* 592 631 * This callback is called by stream transport on receipt of packets 593 * in the RTP socket. 632 * in the RTP socket. 594 633 */ 595 634 static void on_rx_rtp( pjmedia_tp_cb_param *param) … … 612 651 return; 613 652 } 614 if (stream->rtp_rx_last_err != status) { 615 char errmsg[PJ_ERR_MSG_SIZE]; 616 pj_strerror(status, errmsg, sizeof(errmsg)); 617 PJ_LOG(4,(channel->port.info.name.ptr, 618 "Unable to receive RTP packet, recv() returned %d: %s", 619 status, errmsg)); 620 stream->rtp_rx_last_err = status; 653 654 LOGERR_((channel->port.info.name.ptr, status, 655 "Unable to receive RTP packet")); 656 657 if (status == PJ_ESOCKETSTOP) { 658 /* Publish receive error event. */ 659 publish_tp_event(PJMEDIA_EVENT_MEDIA_TP_ERR, status, PJ_TRUE, 660 PJMEDIA_DIR_DECODING, stream); 621 661 } 622 662 return; 623 } else {624 stream->rtp_rx_last_err = PJ_SUCCESS;625 663 } 626 664 … … 653 691 pjmedia_rtp_session_update2(&channel->rtp, hdr, &seq_st, PJ_TRUE); 654 692 if (seq_st.status.value) { 655 TRC_ ((channel->port.info.name.ptr, 693 TRC_ ((channel->port.info.name.ptr, 656 694 "RTP status: badpt=%d, badssrc=%d, dup=%d, " 657 "outorder=%d, probation=%d, restart=%d", 695 "outorder=%d, probation=%d, restart=%d", 658 696 seq_st.status.flag.badpt, 659 697 seq_st.status.flag.badssrc, … … 691 729 } 692 730 693 /* See if source address of RTP packet is different than the 731 /* See if source address of RTP packet is different than the 694 732 * configured address, and check if we need to tell the 695 733 * media transport to switch RTP remote address. … … 705 743 } else { 706 744 stream->rtp_src_cnt++; 707 745 708 746 if (stream->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) { 709 747 if (stream->rem_rtp_flag == 1 || … … 718 756 pkt_discarded = PJ_TRUE; 719 757 goto on_return; 720 } 758 } 721 759 if (stream->info.has_rem_ssrc && !seq_st.status.flag.badssrc 722 760 && stream->rem_rtp_flag != 1) … … 793 831 } else { 794 832 /* Just put the payload into jitter buffer */ 795 pjmedia_jbuf_put_frame3(stream->jb, payload, payloadlen, 0, 833 pjmedia_jbuf_put_frame3(stream->jb, payload, payloadlen, 0, 796 834 pj_ntohs(hdr->seq), pj_ntohl(hdr->ts), NULL); 797 835 … … 844 882 /* 845 883 * This callback is called by stream transport on receipt of packets 846 * in the RTCP socket. 884 * in the RTCP socket. 847 885 */ 848 886 static void on_rx_rtcp( void *data, 849 void *pkt, 887 void *pkt, 850 888 pj_ssize_t bytes_read) 851 889 { 852 890 pjmedia_vid_stream *stream = (pjmedia_vid_stream*) data; 891 pj_status_t status; 853 892 854 893 /* Check for errors */ 855 894 if (bytes_read < 0) { 856 if (bytes_read != -PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) { 857 LOGERR_((stream->cname.ptr, (pj_status_t)-bytes_read, 858 "RTCP recv() error")); 895 status = (pj_status_t)-bytes_read; 896 if (status == PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK)) { 897 return; 898 } 899 LOGERR_((stream->cname.ptr, status, "Unable to receive RTCP packet")); 900 if (status == PJ_ESOCKETSTOP) { 901 /* Publish receive error event. */ 902 publish_tp_event(PJMEDIA_EVENT_MEDIA_TP_ERR, status, PJ_FALSE, 903 PJMEDIA_DIR_DECODING, stream); 859 904 } 860 905 return; … … 889 934 pj_uint32_t dtx_duration; 890 935 891 dtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent, 936 dtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent, 892 937 &frame->timestamp); 893 938 … … 922 967 923 968 /* Check if need to send keyframe. */ 924 if (stream->num_keyframe && 925 (pj_cmp_timestamp(&null_ts, &stream->last_keyframe_tx) != 0)) 926 { 969 if (stream->num_keyframe && 970 (pj_cmp_timestamp(&null_ts, &stream->last_keyframe_tx) != 0)) 971 { 927 972 unsigned elapse_time; 928 973 pj_timestamp now; … … 935 980 { 936 981 stream->force_keyframe = PJ_TRUE; 937 --stream->num_keyframe; 982 --stream->num_keyframe; 938 983 } 939 984 } … … 965 1010 return status; 966 1011 } 967 1012 968 1013 pj_get_timestamp(&initial_time); 969 1014 970 if ((stream->num_keyframe) && 971 ((frame_out.bit_info & PJMEDIA_VID_FRM_KEYFRAME) 972 == PJMEDIA_VID_FRM_KEYFRAME)) 1015 if ((stream->num_keyframe) && 1016 ((frame_out.bit_info & PJMEDIA_VID_FRM_KEYFRAME) 1017 == PJMEDIA_VID_FRM_KEYFRAME)) 973 1018 { 974 1019 stream->last_keyframe_tx = initial_time; … … 1003 1048 sizeof(pjmedia_rtp_hdr)); 1004 1049 if (status != PJ_SUCCESS) { 1005 enum { COUNT_TO_REPORT = 20 }; 1006 if (stream->send_err_cnt++ == 0) { 1050 if (stream->rtp_tx_err_cnt++ == 0) { 1007 1051 LOGERR_((channel->port.info.name.ptr, status, 1008 " Transport send_rtp() error"));1052 "Error sending RTP")); 1009 1053 } 1010 if (stream-> send_err_cnt > COUNT_TO_REPORT)1011 stream-> send_err_cnt = 0;1012 /* Ignore this error */1054 if (stream->rtp_tx_err_cnt > SEND_ERR_COUNT_TO_REPORT) { 1055 stream->rtp_tx_err_cnt = 0; 1056 } 1013 1057 } 1014 1015 1058 pjmedia_rtcp_tx_rtp(&stream->rtcp, (unsigned)frame_out.size); 1016 1059 total_sent += frame_out.size; … … 1082 1125 #endif 1083 1126 1084 /* Check if now is the time to transmit RTCP SR/RR report. 1127 /* Check if now is the time to transmit RTCP SR/RR report. 1085 1128 * We only do this when stream direction is not "decoding only", because 1086 1129 * when it is, check_tx_rtcp() will be handled by get_frame(). … … 1244 1287 1245 1288 ts_diff = frm_ts - stream->last_dec_ts; 1246 1289 1247 1290 /* Calculate new FPS based on RTP timestamp diff */ 1248 1291 if (stream->info.codec_info.clock_rate % ts_diff == 0) { … … 1273 1316 pjmedia_jbuf_get_state(stream->jb, &jb_state); 1274 1317 1275 stream->dec_delay_cnt = 1318 stream->dec_delay_cnt = 1276 1319 ((PJMEDIA_VID_STREAM_DECODE_MIN_DELAY_MSEC * 1277 1320 vfd->fps.num) + … … 1425 1468 char fourcc_name[5]; 1426 1469 pjmedia_port_info *pi; 1427 1470 1428 1471 pj_assert(info->type == PJMEDIA_TYPE_VIDEO); 1429 1472 pj_assert(dir == PJMEDIA_DIR_DECODING || dir == PJMEDIA_DIR_ENCODING); … … 1450 1493 channel->paused = 1; 1451 1494 channel->pt = pt; 1452 1495 1453 1496 /* Allocate buffer for outgoing packet. */ 1454 1497 if (dir == PJMEDIA_DIR_ENCODING) { … … 1553 1596 /* Init stream/port name */ 1554 1597 stream->name.ptr = (char*) pj_pool_alloc(pool, M); 1555 stream->name.slen = pj_ansi_snprintf(stream->name.ptr, M, 1598 stream->name.slen = pj_ansi_snprintf(stream->name.ptr, M, 1556 1599 "vstrm%p", stream); 1557 1600 1558 1601 /* Create and initialize codec: */ 1559 status = pjmedia_vid_codec_mgr_alloc_codec(stream->codec_mgr, 1602 status = pjmedia_vid_codec_mgr_alloc_codec(stream->codec_mgr, 1560 1603 &info->codec_info, 1561 1604 &stream->codec); … … 1567 1610 pjmedia_vid_codec_param def_param; 1568 1611 1569 status = pjmedia_vid_codec_mgr_get_default_param(stream->codec_mgr, 1612 status = pjmedia_vid_codec_mgr_get_default_param(stream->codec_mgr, 1570 1613 &info->codec_info, 1571 1614 &def_param); … … 1642 1685 stream->frame_size = vfd_enc->max_bps/8 * vfd_enc->fps.denum / 1643 1686 vfd_enc->fps.num; 1644 1687 1645 1688 /* As the maximum frame_size is not represented directly by maximum bps 1646 1689 * (which includes intra and predicted frames), let's increase the … … 1651 1694 1652 1695 /* Validate the frame size */ 1653 if (stream->frame_size == 0 || 1696 if (stream->frame_size == 0 || 1654 1697 stream->frame_size > PJMEDIA_MAX_VIDEO_ENC_FRAME_SIZE) 1655 1698 { … … 1686 1729 1687 1730 /* Create decoder channel */ 1688 status = create_channel( pool, stream, PJMEDIA_DIR_DECODING, 1731 status = create_channel( pool, stream, PJMEDIA_DIR_DECODING, 1689 1732 info->rx_pt, info, &stream->dec); 1690 1733 if (status != PJ_SUCCESS) … … 1692 1735 1693 1736 /* Create encoder channel */ 1694 status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING, 1737 status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING, 1695 1738 info->tx_pt, info, &stream->enc); 1696 1739 if (status != PJ_SUCCESS) … … 1793 1836 pj_sockaddr_cp(&stream->rem_rtp_addr, &info->rem_addr); 1794 1837 if (info->rtcp_mux) { 1795 pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_addr); 1838 pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_addr); 1796 1839 } else if (pj_sockaddr_has_addr(&info->rem_rtcp.addr)) { 1797 1840 pj_sockaddr_cp(&att_param.rem_rtcp, &info->rem_rtcp); 1798 } 1841 } 1799 1842 att_param.addr_len = pj_sockaddr_get_len(&info->rem_addr); 1800 1843 att_param.rtp_cb2 = &on_rx_rtp; … … 1824 1867 pj_ssize_t len; 1825 1868 1826 pj_ansi_snprintf(trace_name, sizeof(trace_name), 1869 pj_ansi_snprintf(trace_name, sizeof(trace_name), 1827 1870 TRACE_JB_PATH_PREFIX "%s.csv", 1828 1871 channel->port.info.name.ptr); … … 1832 1875 stream->trace_jb_fd = TRACE_JB_INVALID_FD; 1833 1876 PJ_PERROR(3,(THIS_FILE, status, 1834 "Failed creating RTP trace file '%s'", 1877 "Failed creating RTP trace file '%s'", 1835 1878 trace_name)); 1836 1879 } else { … … 1876 1919 1877 1920 total_time = pj_elapsed_msec(&stream->tx_start, &stream->tx_end); 1878 PJ_LOG(5, (stream->name.ptr, 1921 PJ_LOG(5, (stream->name.ptr, 1879 1922 "RC stat: pkt_cnt=%.2f/image, sleep=%.2fms/s, fps=%.2f", 1880 1923 stream->rc_total_pkt*1.0/stream->rc_total_img, … … 1889 1932 } 1890 1933 1891 /* Detach from transport 1934 /* Detach from transport 1892 1935 * MUST NOT hold stream mutex while detaching from transport, as 1893 1936 * it may cause deadlock. See ticket #460 for the details. … … 1913 1956 1914 1957 /* Free mutex */ 1915 1958 1916 1959 if (stream->jb_mutex) { 1917 1960 pj_mutex_destroy(stream->jb_mutex);
Note: See TracChangeset
for help on using the changeset viewer.