Changeset 442 for pjproject/trunk/pjmedia/src/pjmedia/stream.c
- Timestamp:
- May 14, 2006 6:23:34 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r440 r442 41 41 #define TRC_(expr) PJ_LOG(5,expr) 42 42 43 #define BYTES_PER_SAMPLE 2 44 43 45 /** 44 46 * Media channel. … … 55 57 void *out_pkt; /**< Output buffer. */ 56 58 pjmedia_rtp_session rtp; /**< RTP session. */ 59 char last_frm_type; /**< Last frame type from jb */ 57 60 }; 58 61 … … 153 156 pjmedia_stream *stream = port->user_data; 154 157 pjmedia_channel *channel = stream->dec; 155 156 pj_status_t status;157 158 unsigned samples_count, samples_per_frame, samples_required; 158 159 pj_int16_t *p_out_samp; 160 pj_status_t status; 161 159 162 160 163 /* Return no frame is channel is paused */ … … 181 184 samples_count += samples_per_frame) 182 185 { 183 186 char frame_type; 184 187 185 188 /* Get frame from jitter buffer. */ … … 199 202 frame_out.size, 200 203 &frame_out); 204 201 205 } else { 202 206 status = -1; … … 207 211 pjmedia_zero_samples(p_out_samp + samples_count, 208 212 samples_required - samples_count); 213 PJ_LOG(5,(stream->port.info.name.ptr, "Frame lost!")); 214 215 } else { 216 PJ_LOG(5,(stream->port.info.name.ptr, 217 "Lost frame recovered")); 209 218 } 210 219 211 220 } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 212 221 213 /* Jitter buffer is empty, zero the remaining samples and break 214 * the loop. 222 /* Jitter buffer is empty. If this is the first "empty" state, 223 * activate PLC to smoothen the fade-out, otherwise zero 224 * the frame. 215 225 */ 216 pjmedia_zero_samples(p_out_samp + samples_count, 217 samples_required - samples_count); 226 if (frame_type != channel->last_frm_type) { 227 pjmedia_jb_state jb_state; 228 229 /* Activate PLC to smoothen the missing frame */ 230 if (stream->codec->op->recover && 231 stream->codec_param.setting.plc) 232 { 233 pjmedia_frame frame_out; 234 235 do { 236 frame_out.buf = p_out_samp + samples_count; 237 frame_out.size = frame->size - samples_count*2; 238 status = (*stream->codec->op->recover)(stream->codec, 239 frame_out.size, 240 &frame_out); 241 if (status != PJ_SUCCESS) 242 break; 243 samples_count += samples_per_frame; 244 245 } while (samples_count < samples_required); 246 247 } 248 249 /* Report the state of jitter buffer */ 250 pjmedia_jbuf_get_state(stream->jb, &jb_state); 251 PJ_LOG(5,(stream->port.info.name.ptr, 252 "Jitter buffer empty (prefetch=%d)", 253 jb_state.prefetch)); 254 255 } 256 257 if (samples_count < samples_required) { 258 pjmedia_zero_samples(p_out_samp + samples_count, 259 samples_required - samples_count); 260 } 261 262 channel->last_frm_type = frame_type; 218 263 break; 219 264 220 265 } else if (frame_type != PJMEDIA_JB_NORMAL_FRAME) { 266 267 pjmedia_jb_state jb_state; 221 268 222 269 /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */ 223 270 pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME); 224 271 225 /* Zero frame returned. We should zero the PCM buffer then.. */ 226 pjmedia_zero_samples(p_out_samp + samples_count, 227 samples_per_frame); 272 /* Get the state of jitter buffer */ 273 pjmedia_jbuf_get_state(stream->jb, &jb_state); 274 275 /* Always activate PLC when it's available.. */ 276 if (stream->codec->op->recover && 277 stream->codec_param.setting.plc) 278 { 279 pjmedia_frame frame_out; 280 281 do { 282 frame_out.buf = p_out_samp + samples_count; 283 frame_out.size = frame->size - samples_count*2; 284 status = (*stream->codec->op->recover)(stream->codec, 285 frame_out.size, 286 &frame_out); 287 if (status != PJ_SUCCESS) 288 break; 289 samples_count += samples_per_frame; 290 291 } while (samples_count < samples_required); 292 293 PJ_LOG(5,(stream->port.info.name.ptr, 294 "Jitter buffer is bufferring with plc (prefetch=%d)", 295 jb_state.prefetch)); 296 297 } 298 299 if (samples_count < samples_required) { 300 pjmedia_zero_samples(p_out_samp + samples_count, 301 samples_required - samples_count); 302 PJ_LOG(5,(stream->port.info.name.ptr, 303 "Jitter buffer is bufferring (prefetch=%d)..", 304 jb_state.prefetch)); 305 } 306 307 channel->last_frm_type = frame_type; 308 break; 228 309 229 310 } else { … … 237 318 238 319 frame_out.buf = p_out_samp + samples_count; 239 frame_out.size = frame->size - samples_count* 2;320 frame_out.size = frame->size - samples_count*BYTES_PER_SAMPLE; 240 321 status = stream->codec->op->decode( stream->codec, &frame_in, 241 322 frame_out.size, &frame_out); … … 248 329 } 249 330 } 331 332 channel->last_frm_type = frame_type; 250 333 } 251 334 … … 262 345 } else { 263 346 frame->type = PJMEDIA_FRAME_TYPE_AUDIO; 264 frame->size = samples_count * 2;347 frame->size = samples_count * BYTES_PER_SAMPLE; 265 348 frame->timestamp.u64 = 0; 266 349 } … … 498 581 499 582 pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr)); 583 500 584 501 585 /* Send. */ … … 1030 1114 jb_max = info->jb_max; 1031 1115 else 1032 jb_max = 240 / (stream->port.info.samples_per_frame * 1000 / 1033 info->fmt.clock_rate); 1116 jb_max = 360 / stream->codec_param.info.frm_ptime; 1034 1117 1035 1118 if (info->jb_min_pre >= 0) 1036 1119 jb_min_pre = info->jb_min_pre; 1037 1120 else 1038 jb_min_pre = 0;1121 jb_min_pre = 60 / stream->codec_param.info.frm_ptime; 1039 1122 1040 1123 if (info->jb_max_pre > 0) 1041 1124 jb_max_pre = info->jb_max_pre; 1042 1125 else 1043 jb_max_pre = jb_max * 4 / 5;1126 jb_max_pre = 240 / stream->codec_param.info.frm_ptime; 1044 1127 1045 1128 if (info->jb_init >= 0) 1046 1129 jb_init = info->jb_init; 1047 1130 else 1048 jb_init = jb_min_pre;1131 jb_init = (jb_min_pre + jb_max_pre) / 2; 1049 1132 1050 1133 … … 1052 1135 status = pjmedia_jbuf_create(pool, &stream->port.info.name, 1053 1136 stream->frame_size, 1137 stream->codec_param.info.frm_ptime, 1054 1138 jb_max, &stream->jb); 1055 1139 if (status != PJ_SUCCESS)
Note: See TracChangeset
for help on using the changeset viewer.