Changeset 3835
- Timestamp:
- Oct 23, 2011 5:23:55 AM (13 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/config.h
r3671 r3835 1046 1046 1047 1047 /** 1048 * Video stream will discard old picture from the jitter buffer as soon as 1049 * new picture is received, to reduce latency. 1050 * 1051 * Default: 0 1052 */ 1053 #ifndef PJMEDIA_VID_STREAM_SKIP_PACKETS_TO_REDUCE_LATENCY 1054 # define PJMEDIA_VID_STREAM_SKIP_PACKETS_TO_REDUCE_LATENCY 0 1055 #endif 1056 1057 /** 1048 1058 * @} 1049 1059 */ -
pjproject/trunk/pjmedia/include/pjmedia/jbuf.h
r3664 r3835 390 390 unsigned frame_cnt); 391 391 392 /** 393 * Check if the jitter buffer is full. 394 * 395 * @param jb The jitter buffer. 396 * 397 * @return PJ_TRUE if it is full. 398 */ 399 PJ_DECL(pj_bool_t) pjmedia_jbuf_is_full(const pjmedia_jbuf *jb); 400 392 401 393 402 /** -
pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
r3664 r3835 636 636 } 637 637 638 PJ_DEF(pj_bool_t) pjmedia_jbuf_is_full(const pjmedia_jbuf *jb) 639 { 640 return jb->jb_framelist.size == jb->jb_framelist.max_count; 641 } 638 642 639 643 static void jbuf_calculate_jitter(pjmedia_jbuf *jb) -
pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c
r3802 r3835 69 69 #endif 70 70 71 72 71 /** 73 72 * Media channel. … … 82 81 void *buf; /**< Output buffer. */ 83 82 unsigned buf_size; /**< Size of output buffer. */ 84 unsigned buf_len; /**< Length of data in buffer. */85 83 pjmedia_rtp_session rtp; /**< RTP session. */ 86 84 } pjmedia_vid_channel; … … 121 119 pj_uint32_t rtcp_interval; /**< Interval, in timestamp. */ 122 120 pj_bool_t initial_rr; /**< Initial RTCP RR sent */ 121 122 unsigned dec_max_size; /**< Size of decoded/raw picture*/ 123 pjmedia_frame dec_frame; /**< Current decoded frame. */ 123 124 124 125 unsigned frame_size; /**< Size of encoded base frame.*/ … … 150 151 }; 151 152 153 /* Prototypes */ 154 static pj_status_t decode_frame(pjmedia_vid_stream *stream, 155 pjmedia_frame *frame); 152 156 153 157 /* … … 636 640 } 637 641 642 pj_mutex_lock( stream->jb_mutex ); 643 644 /* Quickly see if there may be a full picture in the jitter buffer, and 645 * decode them if so. More thorough check will be done in decode_frame(). 646 */ 647 if ((pj_ntohl(hdr->ts) != stream->dec_frame.timestamp.u32.lo) || hdr->m) { 648 if (PJMEDIA_VID_STREAM_SKIP_PACKETS_TO_REDUCE_LATENCY) { 649 /* Always decode whenever we have picture in jb and 650 * overwrite already decoded picture if necessary 651 */ 652 pj_size_t old_size = stream->dec_frame.size; 653 654 stream->dec_frame.size = stream->dec_max_size; 655 if (decode_frame(stream, &stream->dec_frame) != PJ_SUCCESS) { 656 stream->dec_frame.size = old_size; 657 } 658 } else { 659 /* Only decode if we don't already have decoded one, 660 * unless the jb is full. 661 */ 662 pj_bool_t can_decode = PJ_FALSE; 663 664 if (pjmedia_jbuf_is_full(stream->jb)) { 665 can_decode = PJ_TRUE; 666 } 667 else if (stream->dec_frame.size == 0) { 668 can_decode = PJ_TRUE; 669 } 670 671 if (can_decode) { 672 stream->dec_frame.size = stream->dec_max_size; 673 if (decode_frame(stream, &stream->dec_frame) != PJ_SUCCESS) { 674 stream->dec_frame.size = 0; 675 } 676 } 677 } 678 } 638 679 639 680 /* Put "good" packet to jitter buffer, or reset the jitter buffer 640 681 * when RTP session is restarted. 641 682 */ 642 pj_mutex_lock( stream->jb_mutex );643 683 if (seq_st.status.flag.restart) { 644 684 status = pjmedia_jbuf_reset(stream->jb); … … 816 856 if (stream->send_err_cnt++ == 0) { 817 857 LOGERR_((channel->port.info.name.ptr, 818 "Transport send_rtp() error (repeated %d times)",858 "Transport send_rtp() error", 819 859 status)); 820 if (stream->send_err_cnt > COUNT_TO_REPORT)821 stream->send_err_cnt = 0;822 860 } 861 if (stream->send_err_cnt > COUNT_TO_REPORT) 862 stream->send_err_cnt = 0; 823 863 /* Ignore this error */ 824 864 } … … 874 914 } 875 915 876 static pj_status_t get_frame(pjmedia_port *port, 877 pjmedia_frame *frame) 878 { 879 pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata; 916 /* Decode one image from jitter buffer */ 917 static pj_status_t decode_frame(pjmedia_vid_stream *stream, 918 pjmedia_frame *frame) 919 { 880 920 pjmedia_vid_channel *channel = stream->dec; 881 921 pj_uint32_t last_ts = 0; … … 885 925 pj_status_t status; 886 926 887 /* Return no frame is channel is paused */888 if (channel->paused) {889 frame->type = PJMEDIA_FRAME_TYPE_NONE;890 return PJ_SUCCESS;891 }892 893 927 /* Repeat get payload from the jitter buffer until all payloads with same 894 928 * timestamp are collected. 895 929 */ 896 channel->buf_len = 0;897 898 /* Lock jitter buffer mutex first */899 pj_mutex_lock( stream->jb_mutex );900 930 901 931 /* Check if we got a decodable frame */ … … 928 958 929 959 /* Generate frame bitstream from the payload */ 930 channel->buf_len = 0;931 932 960 if (cnt > stream->rx_frame_cnt) { 933 PJ_LOG(1,( port->info.name.ptr,961 PJ_LOG(1,(channel->port.info.name.ptr, 934 962 "Discarding %u frames because array is full!", 935 963 cnt - stream->rx_frame_cnt)); … … 967 995 frame->size, frame); 968 996 if (status != PJ_SUCCESS) { 969 LOGERR_(( port->info.name.ptr, "codec decode() error",997 LOGERR_((channel->port.info.name.ptr, "codec decode() error", 970 998 status)); 971 999 frame->type = PJMEDIA_FRAME_TYPE_NONE; … … 975 1003 pjmedia_jbuf_remove_frame(stream->jb, cnt); 976 1004 } 977 978 /* Unlock jitter buffer mutex. */979 pj_mutex_unlock( stream->jb_mutex );980 1005 981 1006 /* Learn remote frame rate after successful decoding */ … … 1031 1056 } 1032 1057 1058 return got_frame ? PJ_SUCCESS : PJ_ENOTFOUND; 1059 } 1060 1061 1062 static pj_status_t get_frame(pjmedia_port *port, 1063 pjmedia_frame *frame) 1064 { 1065 pjmedia_vid_stream *stream = (pjmedia_vid_stream*) port->port_data.pdata; 1066 pjmedia_vid_channel *channel = stream->dec; 1067 1068 /* Return no frame is channel is paused */ 1069 if (channel->paused) { 1070 frame->type = PJMEDIA_FRAME_TYPE_NONE; 1071 frame->size = 0; 1072 return PJ_SUCCESS; 1073 } 1074 1075 pj_mutex_lock( stream->jb_mutex ); 1076 1077 if (stream->dec_frame.size == 0) { 1078 /* Don't have frame in buffer, try to decode one */ 1079 if (decode_frame(stream, frame) != PJ_SUCCESS) { 1080 frame->type = PJMEDIA_FRAME_TYPE_NONE; 1081 frame->size = 0; 1082 } 1083 } else { 1084 if (frame->size < stream->dec_frame.size) { 1085 PJ_LOG(4,(stream->dec->port.info.name.ptr, 1086 "Error: not enough buffer for decoded frame " 1087 "(supplied=%d, required=%d)", 1088 (int)frame->size, (int)stream->dec_frame.size)); 1089 frame->type = PJMEDIA_FRAME_TYPE_NONE; 1090 frame->size = 0; 1091 } else { 1092 frame->type = stream->dec_frame.type; 1093 frame->timestamp = stream->dec_frame.timestamp; 1094 frame->size = stream->dec_frame.size; 1095 pj_memcpy(frame->buf, stream->dec_frame.buf, frame->size); 1096 } 1097 1098 stream->dec_frame.size = 0; 1099 } 1100 1101 pj_mutex_unlock( stream->jb_mutex ); 1102 1033 1103 return PJ_SUCCESS; 1034 1104 } 1035 1036 1105 1037 1106 /* … … 1081 1150 1082 1151 /* Allocate buffer for outgoing packet. */ 1083 channel->buf_size = sizeof(pjmedia_rtp_hdr) + stream->frame_size; 1084 1085 /* It should big enough to hold (minimally) RTCP SR with an SDES. */ 1086 min_out_pkt_size = sizeof(pjmedia_rtcp_sr_pkt) + 1087 sizeof(pjmedia_rtcp_common) + 1088 (4 + stream->cname.slen) + 1089 32; 1090 1091 if (channel->buf_size < min_out_pkt_size) 1092 channel->buf_size = min_out_pkt_size; 1093 1094 channel->buf = pj_pool_alloc(pool, channel->buf_size); 1095 PJ_ASSERT_RETURN(channel->buf != NULL, PJ_ENOMEM); 1152 if (dir == PJMEDIA_DIR_ENCODING) { 1153 channel->buf_size = sizeof(pjmedia_rtp_hdr) + stream->frame_size; 1154 1155 /* It should big enough to hold (minimally) RTCP SR with an SDES. */ 1156 min_out_pkt_size = sizeof(pjmedia_rtcp_sr_pkt) + 1157 sizeof(pjmedia_rtcp_common) + 1158 (4 + stream->cname.slen) + 1159 32; 1160 1161 if (channel->buf_size < min_out_pkt_size) 1162 channel->buf_size = min_out_pkt_size; 1163 1164 channel->buf = pj_pool_alloc(pool, channel->buf_size); 1165 PJ_ASSERT_RETURN(channel->buf != NULL, PJ_ENOMEM); 1166 } 1096 1167 1097 1168 /* Create RTP and RTCP sessions: */ … … 1157 1228 unsigned jb_init, jb_max, jb_min_pre, jb_max_pre, len; 1158 1229 int frm_ptime, chunks_per_frm; 1159 pjmedia_video_format_detail *vfd_enc ;1230 pjmedia_video_format_detail *vfd_enc, *vfd_dec; 1160 1231 char *p; 1161 1232 unsigned mtu; … … 1215 1286 vfd_enc = pjmedia_format_get_video_format_detail( 1216 1287 &info->codec_param->enc_fmt, PJ_TRUE); 1288 vfd_dec = pjmedia_format_get_video_format_detail( 1289 &info->codec_param->dec_fmt, PJ_TRUE); 1217 1290 1218 1291 /* Init stream: */ … … 1297 1370 if (status != PJ_SUCCESS) 1298 1371 return status; 1372 1373 /* Create temporary buffer for immediate decoding */ 1374 stream->dec_max_size = vfd_dec->size.w * vfd_dec->size.h * 4; 1375 stream->dec_frame.buf = pj_pool_alloc(pool, stream->dec_max_size); 1299 1376 1300 1377 /* Init jitter buffer parameters: */
Note: See TracChangeset
for help on using the changeset viewer.