- Timestamp:
- Sep 19, 2018 8:26:41 AM (6 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/config.h
r5820 r5887 1494 1494 #endif 1495 1495 1496 1496 1497 /** 1497 1498 * Specify the number of keyframe needed to be sent after the stream is … … 1504 1505 #endif 1505 1506 1507 1506 1508 /** 1507 1509 * Specify the interval to send keyframe after the stream is created, in msec. … … 1515 1517 1516 1518 /** 1519 * Specify minimum delay of video decoding, in milliseconds. Lower value may 1520 * degrade video quality significantly in a bad network environment (e.g: 1521 * with persistent late and out-of-order RTP packets). Note that the value 1522 * must be lower than jitter buffer maximum delay (configurable via 1523 * pjmedia_stream_info.jb_max or pjsua_media_config.jb_max). 1524 * 1525 * Default : 100 1526 */ 1527 #ifndef PJMEDIA_VID_STREAM_DECODE_MIN_DELAY_MSEC 1528 # define PJMEDIA_VID_STREAM_DECODE_MIN_DELAY_MSEC 100 1529 #endif 1530 1531 1532 1533 /** 1517 1534 * @} 1518 1535 */ -
pjproject/trunk/pjmedia/include/pjmedia/jbuf.h
r5803 r5887 103 103 unsigned min_prefetch; /**< Minimum allowed prefetch, in frms. */ 104 104 unsigned max_prefetch; /**< Maximum allowed prefetch, in frms. */ 105 unsigned max_count; /**< Jitter buffer capacity, in frames. */ 105 106 106 107 /* Status */ -
pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
r5803 r5887 1161 1161 state->min_prefetch = jb->jb_min_prefetch; 1162 1162 state->max_prefetch = jb->jb_max_prefetch; 1163 state->max_count = jb->jb_max_count; 1163 1164 1164 1165 state->burst = jb->jb_eff_level; -
pjproject/trunk/pjmedia/src/pjmedia/vid_stream.c
r5788 r5887 140 140 pjmedia_ratio dec_max_fps; /**< Max fps of decoding dir. */ 141 141 pjmedia_frame dec_frame; /**< Current decoded frame. */ 142 unsigned dec_delay_cnt; /**< Decoding delay (in frames).*/ 142 143 pjmedia_event fmt_event; /**< Buffered fmt_changed event 143 144 to avoid deadlock */ … … 1128 1129 { 1129 1130 pjmedia_vid_channel *channel = stream->dec; 1130 pj_uint32_t last_ts = 0 ;1131 pj_uint32_t last_ts = 0, frm_ts = 0; 1131 1132 int frm_first_seq = 0, frm_last_seq = 0; 1132 1133 pj_bool_t got_frame = PJ_FALSE; 1133 unsigned cnt ;1134 unsigned cnt, frm_pkt_cnt = 0, frm_cnt = 0; 1134 1135 pj_status_t status; 1135 1136 … … 1139 1140 1140 1141 /* Check if we got a decodable frame */ 1141 for (cnt=0; ; ++cnt) {1142 for (cnt=0; ; ) { 1142 1143 char ptype; 1143 1144 pj_uint32_t ts; … … 1148 1149 &ptype, NULL, &ts, &seq); 1149 1150 if (ptype == PJMEDIA_JB_NORMAL_FRAME) { 1151 if (stream->last_dec_ts == ts) { 1152 /* Remove any late packet (the frame has been decoded) */ 1153 pjmedia_jbuf_remove_frame(stream->jb, 1); 1154 continue; 1155 } 1156 1150 1157 if (last_ts == 0) { 1151 1158 last_ts = ts; 1159 1160 /* Init timestamp and first seq of the first frame */ 1161 frm_ts = ts; 1152 1162 frm_first_seq = seq; 1153 1163 } 1154 1164 if (ts != last_ts) { 1155 got_frame = PJ_TRUE; 1156 break; 1165 last_ts = ts; 1166 if (frm_pkt_cnt == 0) 1167 frm_pkt_cnt = cnt; 1168 1169 /* Is it time to decode? Check with minimum delay setting */ 1170 if (++frm_cnt == stream->dec_delay_cnt) { 1171 got_frame = PJ_TRUE; 1172 break; 1173 } 1157 1174 } 1158 frm_last_seq = seq;1159 1175 } else if (ptype == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 1160 1176 /* No more packet in the jitter buffer */ 1161 1177 break; 1162 1178 } 1179 1180 ++cnt; 1163 1181 } 1164 1182 … … 1166 1184 unsigned i; 1167 1185 1168 /* Generate frame bitstream from the payload */ 1169 if (cnt > stream->rx_frame_cnt) { 1186 /* Exclude any MISSING frames in the end of the packets array, as 1187 * it may be part of the next video frame (late packets). 1188 */ 1189 for (; frm_pkt_cnt > 1; --frm_pkt_cnt) { 1190 char ptype; 1191 pjmedia_jbuf_peek_frame(stream->jb, frm_pkt_cnt, NULL, NULL, &ptype, 1192 NULL, NULL, NULL); 1193 if (ptype == PJMEDIA_JB_NORMAL_FRAME) 1194 break; 1195 } 1196 1197 /* Check if the packet count for this frame exceeds the limit */ 1198 if (frm_pkt_cnt > stream->rx_frame_cnt) { 1170 1199 PJ_LOG(1,(channel->port.info.name.ptr, 1171 1200 "Discarding %u frames because array is full!", 1172 cnt - stream->rx_frame_cnt)); 1173 pjmedia_jbuf_remove_frame(stream->jb, cnt - stream->rx_frame_cnt); 1174 cnt = stream->rx_frame_cnt; 1175 } 1176 1177 for (i = 0; i < cnt; ++i) { 1201 frm_pkt_cnt - stream->rx_frame_cnt)); 1202 pjmedia_jbuf_remove_frame(stream->jb, 1203 frm_pkt_cnt - stream->rx_frame_cnt); 1204 frm_pkt_cnt = stream->rx_frame_cnt; 1205 } 1206 1207 /* Generate frame bitstream from the payload */ 1208 for (i = 0; i < frm_pkt_cnt; ++i) { 1178 1209 char ptype; 1179 1210 1180 1211 stream->rx_frames[i].type = PJMEDIA_FRAME_TYPE_VIDEO; 1181 stream->rx_frames[i].timestamp.u64 = last_ts;1212 stream->rx_frames[i].timestamp.u64 = frm_ts; 1182 1213 stream->rx_frames[i].bit_info = 0; 1183 1214 … … 1188 1219 (const void**)&stream->rx_frames[i].buf, 1189 1220 &stream->rx_frames[i].size, &ptype, 1190 NULL, NULL, NULL);1221 NULL, NULL, &frm_last_seq); 1191 1222 1192 1223 if (ptype != PJMEDIA_JB_NORMAL_FRAME) { … … 1200 1231 1201 1232 /* Decode */ 1202 status = pjmedia_vid_codec_decode(stream->codec, cnt,1233 status = pjmedia_vid_codec_decode(stream->codec, frm_pkt_cnt, 1203 1234 stream->rx_frames, 1204 1235 (unsigned)frame->size, frame); … … 1210 1241 } 1211 1242 1212 pjmedia_jbuf_remove_frame(stream->jb, cnt);1243 pjmedia_jbuf_remove_frame(stream->jb, frm_pkt_cnt); 1213 1244 } 1214 1245 1215 1246 /* Learn remote frame rate after successful decoding */ 1216 if ( frame->type == PJMEDIA_FRAME_TYPE_VIDEO && frame->size)1247 if (got_frame && frame->type == PJMEDIA_FRAME_TYPE_VIDEO && frame->size) 1217 1248 { 1218 1249 /* Only check remote frame rate when timestamp is not wrapping and 1219 1250 * sequence is increased by 1. 1220 1251 */ 1221 if ( last_ts > stream->last_dec_ts &&1252 if (frm_ts > stream->last_dec_ts && 1222 1253 frm_first_seq - stream->last_dec_seq == 1) 1223 1254 { … … 1225 1256 pjmedia_video_format_detail *vfd; 1226 1257 1227 ts_diff = last_ts - stream->last_dec_ts;1258 ts_diff = frm_ts - stream->last_dec_ts; 1228 1259 vfd = pjmedia_format_get_video_format_detail( 1229 1260 &channel->port.info.fmt, PJ_TRUE); … … 1242 1273 /* Update stream info */ 1243 1274 stream->info.codec_param->dec_fmt.det.vid.fps = vfd->fps; 1275 1276 /* Update the decoding delay as FPS updated */ 1277 { 1278 pjmedia_jb_state jb_state; 1279 pjmedia_jbuf_get_state(stream->jb, &jb_state); 1280 1281 stream->dec_delay_cnt = 1282 ((PJMEDIA_VID_STREAM_DECODE_MIN_DELAY_MSEC * 1283 vfd->fps.num) + 1284 (1000 * vfd->fps.denum) - 1) / 1285 (1000 * vfd->fps.denum); 1286 if (stream->dec_delay_cnt < 1) 1287 stream->dec_delay_cnt = 1; 1288 if (stream->dec_delay_cnt > jb_state.max_count * 4/5) 1289 stream->dec_delay_cnt = jb_state.max_count * 4/5; 1290 } 1244 1291 1245 1292 /* Publish PJMEDIA_EVENT_FMT_CHANGED event if frame rate … … 1275 1322 /* Update last frame seq and timestamp */ 1276 1323 stream->last_dec_seq = frm_last_seq; 1277 stream->last_dec_ts = last_ts;1324 stream->last_dec_ts = frm_ts; 1278 1325 } 1279 1326 … … 1694 1741 else 1695 1742 jb_init = 0; 1743 1744 /* Calculate the decoding delay (in number of frames) based on FPS */ 1745 stream->dec_delay_cnt = ((PJMEDIA_VID_STREAM_DECODE_MIN_DELAY_MSEC * 1746 vfd_dec->fps.num) + 1747 (1000 * vfd_dec->fps.denum) - 1) / 1748 (1000 * vfd_dec->fps.denum); 1749 if (stream->dec_delay_cnt < 1) 1750 stream->dec_delay_cnt = 1; 1751 if (stream->dec_delay_cnt > jb_max * 4/5) 1752 stream->dec_delay_cnt = jb_max * 4/5; 1696 1753 1697 1754 /* Allocate array for temporary storage for assembly of incoming
Note: See TracChangeset
for help on using the changeset viewer.